Skip to content

Commit

Permalink
Fix TOC links that are escaped, also handle uniqueness, fixes #461
Browse files Browse the repository at this point in the history
  • Loading branch information
onigoetz committed May 18, 2017
1 parent 171a8b2 commit 885cc1f
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 12 deletions.
44 changes: 35 additions & 9 deletions libs/Format/HTML/ContentTypes/Markdown/TOC/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public function processDocument(Document $document)

$headings = [];

$document->heading_ids = [];
$walker = $document->walker();
while ($event = $walker->next()) {
$node = $event->getNode();
Expand All @@ -55,7 +56,7 @@ public function processDocument(Document $document)
continue;
}

$this->ensureHeadingHasId($node);
$this->ensureHeadingHasId($document, $node);
$headings[] = new Entry($node);
}

Expand All @@ -72,21 +73,49 @@ public function processDocument(Document $document)
}
}

protected function escaped($url) {
$url = trim($url);
$url = preg_replace('~[^\\pL0-9_]+~u', '-', $url);
$url = trim($url, "-");
$url = iconv("utf-8", "us-ascii//TRANSLIT", $url);
$url = preg_replace('~[^-a-zA-Z0-9_]+~', '', $url);

return $url;
}

protected function getUniqueId(Document $document, $proposed) {
if ($proposed == "page_") {
$proposed = "page_section_" . (count($document->heading_ids) + 1);
}

// Quick path, it's a unique ID
if (!in_array($proposed, $document->heading_ids)) {
$document->heading_ids[] = $proposed;
return $proposed;
}

$extension = 1; // Initialize the variable at one, so on the first iteration we have 2
do {
$extension++;
} while (in_array("$proposed-$extension", $document->heading_ids));

return "$proposed-$extension";
}

/**
* @param Heading $node
*/
protected function ensureHeadingHasId(Heading $node)
protected function ensureHeadingHasId(Document $document, Heading $node)
{
// If the node has an ID, no need to generate it
// If the node has an ID, no need to generate it, just check it's unique
$attributes = $node->getData('attributes', []);
if (array_key_exists('id', $attributes) && !empty($attributes['id'])) {
// TODO :: check for uniqueness
$node->data['attributes']['id'] = $this->getUniqueId($document, $attributes['id']);

return;
}

// Well, seems we have to generate an ID

$walker = $node->walker();
$inside = [];
while ($event = $walker->next()) {
Expand All @@ -106,10 +135,7 @@ protected function ensureHeadingHasId(Heading $node)
}
}

$text = 'page_' . urlencode(trim($text));

// TODO :: check for uniqueness
$node->data['attributes']['id'] = $text;
$node->data['attributes']['id'] = $this->getUniqueId($document,'page_'. $this->escaped($text));
}

/**
Expand Down
48 changes: 45 additions & 3 deletions tests/Format/HTML/TableOfContentsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,56 @@ function testTOCToken() {
function testUnicodeTOC() {
$converter = new CommonMarkConverter(['daux' => new MainConfig]);

$source = "[TOC]\n# 基础操作";
$source = "[TOC]\n# 基础操作\n# 操作基础";
$expected = <<<EXPECTED
<ul class="TableOfContents">
<li>
<p><a href="#page_%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C">基础操作</a></p>
<p><a href="#page_section_1">基础操作</a></p>
</li>
<li>
<p><a href="#page_section_2">操作基础</a></p>
</li>
</ul>
<h1 id="page_section_1">基础操作</h1>
<h1 id="page_section_2">操作基础</h1>
EXPECTED;

$this->assertEquals($expected, $converter->convertToHtml($source));
}

function testDuplicatedTOC() {
$converter = new CommonMarkConverter(['daux' => new MainConfig]);

$source = "[TOC]\n# Test\n# Test";
$expected = <<<EXPECTED
<ul class="TableOfContents">
<li>
<p><a href="#page_Test">Test</a></p>
</li>
<li>
<p><a href="#page_Test-2">Test</a></p>
</li>
</ul>
<h1 id="page_Test">Test</h1>
<h1 id="page_Test-2">Test</h1>
EXPECTED;

$this->assertEquals($expected, $converter->convertToHtml($source));
}

function testEscapedTOC() {
$converter = new CommonMarkConverter(['daux' => new MainConfig]);

$source = "[TOC]\n# TEST : Test";
$expected = <<<EXPECTED
<ul class="TableOfContents">
<li>
<p><a href="#page_TEST-Test">TEST : Test</a></p>
</li>
</ul>
<h1 id="page_%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C">基础操作</h1>
<h1 id="page_TEST-Test">TEST : Test</h1>
EXPECTED;

Expand Down

0 comments on commit 885cc1f

Please sign in to comment.