'strip', 'heading_permalink' => [ 'apply_id_to_heading' => true, 'id_prefix' => '', 'insert' => 'before', 'aria_hidden' => true, ], ]); $converter->getEnvironment()->addExtension(new HeadingPermalinkExtension()); $html = $converter->convert($markdown)->getContent(); preg_match_all('/assertSame('Licence CC', $toc[0]['label']); } public function testBoldMarkupIsStrippedFromLabel(): void { $toc = MarkdownHelper::extractToc('## **Gros** gras'); $this->assertSame('Gros gras', $toc[0]['label']); } public function testInlineCodeMarkupIsStrippedFromLabel(): void { $toc = MarkdownHelper::extractToc('## `code` inline'); $this->assertSame('code inline', $toc[0]['label']); } public function testLinkKeepsLabelTextNotUrl(): void { $toc = MarkdownHelper::extractToc('## [lien](http://x) ici'); $this->assertSame('lien ici', $toc[0]['label']); } public function testNestedMarkupIsFullyStripped(): void { $toc = MarkdownHelper::extractToc('## *[lien](http://x)* et `code`'); $this->assertSame('lien et code', $toc[0]['label']); } public function testNoMarkdownSyntaxLeaksIntoAnyLabel(): void { $markdown = "## *Italique*\n\n## **Gras**\n\n## `Code`\n\n## [Lien](http://x)\n"; $labels = array_column(MarkdownHelper::extractToc($markdown), 'label'); foreach ($labels as $label) { $this->assertDoesNotMatchRegularExpression('/[*`]|\[|\]\(/', $label); } } // ── Hrefs match rendered heading ids ────────────────────────────────────── public function testHrefsMatchRenderedHeadingIdsForInlineMarkup(): void { $markdown = "## *Licence* CC\n\n## **Gros** gras\n\n## `code` inline\n\n## [lien](http://x) ici\n"; $toc = MarkdownHelper::extractToc($markdown); $headingIds = $this->renderedHeadingIds($markdown); foreach ($toc as $index => $item) { $this->assertSame('#' . $headingIds[$index], $item['href'], "TOC href mismatch at index {$index}"); } } public function testHrefsMatchRenderedHeadingIdsForAccents(): void { $markdown = "## Été accents\n\n## Emoji 🎉 fin\n"; $toc = MarkdownHelper::extractToc($markdown); $headingIds = $this->renderedHeadingIds($markdown); foreach ($toc as $index => $item) { $this->assertSame('#' . $headingIds[$index], $item['href'], "TOC href mismatch at index {$index}"); } } // ── Levels and structure ────────────────────────────────────────────────── public function testLevelsAreCapturedFromHashes(): void { $markdown = "# Un\n\n## Deux\n\n### Trois\n"; $toc = MarkdownHelper::extractToc($markdown); $this->assertSame([1, 2, 3], array_column($toc, 'level')); } public function testHeadingsDeeperThanThreeAreIgnored(): void { $toc = MarkdownHelper::extractToc("# Un\n\n#### Quatre\n"); $this->assertCount(1, $toc); } public function testContentWithoutHeadingsYieldsEmptyToc(): void { $this->assertSame([], MarkdownHelper::extractToc("Juste du texte.\n\nEt un paragraphe.")); } public function testEmptyContentYieldsEmptyToc(): void { $this->assertSame([], MarkdownHelper::extractToc('')); } }