Skip to content

Commit

Permalink
Merge pull request #139 from nikophil/fix/toc-no-url-fragment
Browse files Browse the repository at this point in the history
Toctree: don't add url fragment for h1
  • Loading branch information
greg0ire authored Mar 15, 2021
2 parents 7907706 + 31c29e6 commit 9034374
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 28 deletions.
26 changes: 16 additions & 10 deletions lib/HTML/Renderers/TocNodeRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function render(): string

$url = $this->environment->relativeUrl($reference->getUrl());

$this->buildLevel($url, $reference->getTitles(), 1, $tocItems);
$this->buildLevel($url, $reference->getTitles(), 1, $tocItems, $file);
}

return $this->templateRenderer->render('toc.html.twig', [
Expand All @@ -66,14 +66,18 @@ private function buildLevel(
?string $url,
array $titles,
int $level,
array &$tocItems
array &$tocItems,
string $file
): void {
$html = '';

foreach ($titles as $k => $entry) {
[$title, $children] = $entry;

[$title, $target] = $this->generateTarget($url, $title);
[$title, $target] = $this->generateTarget(
$url,
$title,
// don't add anchor for first h1 in a different file (link directly to the file)
! ($level === 1 && $k === 0 && $file !== '/' . $this->environment->getCurrentFileName())
);

$tocItem = [
'targetId' => $this->generateTargetId($target),
Expand All @@ -85,7 +89,7 @@ private function buildLevel(

// render children until we hit the configured maxdepth
if (count($children) > 0 && $level < $this->tocNode->getDepth()) {
$this->buildLevel($url, $children, $level + 1, $tocItem['children']);
$this->buildLevel($url, $children, $level + 1, $tocItem['children'], $file);
}

$tocItems[] = $tocItem;
Expand All @@ -102,11 +106,13 @@ private function generateTargetId(string $target): string
*
* @return mixed[]
*/
private function generateTarget(?string $url, $title): array
private function generateTarget(?string $url, $title, bool $withAnchor): array
{
$anchor = $this->generateAnchorFromTitle($title);

$target = $url . '#' . $anchor;
$target = $url;
if ($withAnchor) {
$anchor = $this->generateAnchorFromTitle($title);
$target .= '#' . $anchor;
}

if (is_array($title)) {
[$title, $target] = $title;
Expand Down
34 changes: 22 additions & 12 deletions tests/Builder/BuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,36 +158,46 @@ public function testToctreeGlob(): void
{
$contents = $this->getFileContents($this->targetFile('toc-glob.html'));

self::assertStringContainsString('magic-link.html#another-page', $contents);
self::assertStringContainsString('introduction.html#introduction-page', $contents);
self::assertStringContainsString('subdirective.html', $contents);
// links to first <h1> tag of other pages must not contain a url fragment
self::assertStringContainsString('magic-link.html"', $contents);
self::assertStringContainsString('introduction.html"', $contents);
self::assertStringContainsString('subdirective.html"', $contents);
self::assertStringContainsString('subdir/file.html"', $contents);

// links to other <h1> tags should contain a url fragment
self::assertStringContainsString('index.html#another-h1', $contents);

// links to other headings contain a url fragment
self::assertStringContainsString('subdir/test.html#subdirectory', $contents);
self::assertStringContainsString('subdir/file.html#heading-1', $contents);
self::assertStringContainsString('subdir/file.html#heading-2', $contents);

// link to <h1> inside the same page contains a url fragment
self::assertStringContainsString('toc-glob.html#toc-glob', $contents);
}

public function testToctreeGlobOrder(): void
{
$contents = $this->getFileContents($this->targetFile('toc-glob.html'));

// assert `index` is first since it is defined first in toc-glob.rst
self::assertStringContainsString('<div class="toc"><ul><li id="index-html-summary" class="toc-item"><a href="index.html#summary">Summary</a></li>', $contents);
self::assertStringContainsString('<div class="toc"><ul><li id="index-html" class="toc-item"><a href="index.html">Summary</a></li>', $contents);

// assert `index` is not included and duplicated by the glob
self::assertStringNotContainsString('</ul><li id="index-html-summary" class="toc-item"><a href="index.html#summary">Summary</a></li>', $contents);
self::assertStringNotContainsString('</ul><li id="index-html" class="toc-item"><a href="index.html">Summary</a></li>', $contents);

// assert `introduction` is at the end after the glob since it is defined last in toc-glob.rst
self::assertStringContainsString('<a href="introduction.html#introduction-page">Introduction page</a></li></ul></div>', $contents);
self::assertStringContainsString('<a href="introduction.html">Introduction page</a></li></ul></div>', $contents);
}

public function testToctreeInSubdirectory(): void
{
$contents = $this->getFileContents($this->targetFile('subdir/toc.html'));

self::assertStringContainsString('../introduction.html#introduction-page', $contents);
self::assertStringContainsString('../subdirective.html#sub-directives', $contents);
self::assertStringContainsString('../magic-link.html#another-page', $contents);
self::assertStringContainsString('test.html#subdirectory', $contents);
self::assertStringContainsString('file.html#heading-1', $contents);
self::assertStringContainsString('../introduction.html"', $contents);
self::assertStringContainsString('../subdirective.html"', $contents);
self::assertStringContainsString('../magic-link.html"', $contents);
self::assertStringContainsString('"test.html"', $contents);
self::assertStringContainsString('file.html"', $contents);
}

public function testAnchors(): void
Expand Down
3 changes: 3 additions & 0 deletions tests/Builder/input/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ Link to :ref:`Subdirectory Child Level 3 Test <subdirectory-child-level-3>`

.. note::
:ref:`Reference in directory <introduction>`

Another h1
==========
12 changes: 6 additions & 6 deletions tests/BuilderUrl/BuilderUrlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ public function testBaseUrl(): void
);

self::assertStringContainsString(
'<li id="index-html-base-url" class="toc-item"><a href="https://www.domain.com/directory/index.html#base-url">Base URL</a></li>',
'<li id="index-html" class="toc-item"><a href="https://www.domain.com/directory/index.html">Base URL</a></li>',
$contents
);

self::assertStringContainsString(
'<li id="file-html-subdirectory-file" class="toc-item"><a href="https://www.domain.com/directory/subdir/file.html#subdirectory-file">Subdirectory File</a></li>',
'<li id="file-html" class="toc-item"><a href="https://www.domain.com/directory/subdir/file.html">Subdirectory File</a></li>',
$contents
);
}
Expand Down Expand Up @@ -91,12 +91,12 @@ public function testBaseUrlEnabledCallable(): void
);

self::assertStringContainsString(
'<li id="index-html-base-url" class="toc-item"><a href="https://www.domain.com/directory/index.html#base-url">Base URL</a></li>',
'<li id="index-html" class="toc-item"><a href="https://www.domain.com/directory/index.html">Base URL</a></li>',
$contents
);

self::assertStringContainsString(
'<li id="file-html-subdirectory-file" class="toc-item"><a href="file.html#subdirectory-file">Subdirectory File</a></li>',
'<li id="file-html" class="toc-item"><a href="file.html">Subdirectory File</a></li>',
$contents
);
}
Expand Down Expand Up @@ -125,12 +125,12 @@ public function testRelativeUrl(): void
);

self::assertStringContainsString(
'<li id="index-html-base-url" class="toc-item"><a href="../index.html#base-url">Base URL</a></li>',
'<li id="index-html" class="toc-item"><a href="../index.html">Base URL</a></li>',
$contents
);

self::assertStringContainsString(
'<li id="file-html-subdirectory-file" class="toc-item"><a href="file.html#subdirectory-file">Subdirectory File</a></li>',
'<li id="file-html" class="toc-item"><a href="file.html">Subdirectory File</a></li>',
$contents
);
}
Expand Down

0 comments on commit 9034374

Please sign in to comment.