diff --git a/src/CommonMark/Extensions/HeadingPermalink/HeadingPermalinkRenderer.php b/src/CommonMark/Extensions/HeadingPermalink/HeadingPermalinkRenderer.php new file mode 100644 index 000000000..74ef9dca6 --- /dev/null +++ b/src/CommonMark/Extensions/HeadingPermalink/HeadingPermalinkRenderer.php @@ -0,0 +1,77 @@ +set('name', $slug);` line inside the `render` method. + * Cannot be extended since is declared as final. + */ +final class HeadingPermalinkRenderer implements NodeRendererInterface, XmlNodeRendererInterface, ConfigurationAwareInterface +{ + public const DEFAULT_SYMBOL = 'ΒΆ'; + + private ConfigurationInterface $config; + + public function setConfiguration(ConfigurationInterface $configuration): void + { + $this->config = $configuration; + } + + public function render(Node $node, ChildNodeRendererInterface $childRenderer): \Stringable + { + HeadingPermalink::assertInstanceOf($node); + + $slug = $node->getSlug(); + + $idPrefix = (string) $this->config->get('heading_permalink/id_prefix'); + if ($idPrefix !== '') { + $idPrefix .= '-'; + } + + $fragmentPrefix = (string) $this->config->get('heading_permalink/fragment_prefix'); + if ($fragmentPrefix !== '') { + $fragmentPrefix .= '-'; + } + + $attrs = $node->data->getData('attributes'); + $attrs->set('id', $idPrefix . $slug); + // This line is the only difference from the original `league/commonmark` + // renderer + $attrs->set('name', $slug); + $attrs->set('href', '#' . $fragmentPrefix . $slug); + $attrs->append('class', $this->config->get('heading_permalink/html_class')); + $attrs->set('aria-hidden', 'true'); + $attrs->set('title', $this->config->get('heading_permalink/title')); + + $symbol = $this->config->get('heading_permalink/symbol'); + \assert(\is_string($symbol)); + + return new HtmlElement('a', $attrs->export(), \htmlspecialchars($symbol), false); + } + + public function getXmlTagName(Node $node): string + { + return 'heading_permalink'; + } + + public function getXmlAttributes(Node $node): array + { + HeadingPermalink::assertInstanceOf($node); + + return [ + 'slug' => $node->getSlug(), + ]; + } +} diff --git a/src/Providers/CommonMarkServiceProvider.php b/src/Providers/CommonMarkServiceProvider.php index 693e96be0..c7a9055f6 100644 --- a/src/Providers/CommonMarkServiceProvider.php +++ b/src/Providers/CommonMarkServiceProvider.php @@ -4,6 +4,7 @@ namespace ARKEcosystem\Foundation\Providers; +use ARKEcosystem\Foundation\CommonMark\Extensions\HeadingPermalink\HeadingPermalinkRenderer; use ARKEcosystem\Foundation\CommonMark\Extensions\Highlighter\FencedCodeRenderer; use ARKEcosystem\Foundation\CommonMark\Extensions\Highlighter\IndentedCodeRenderer; use ARKEcosystem\Foundation\CommonMark\Extensions\Image\ImageRenderer; @@ -49,15 +50,13 @@ use League\CommonMark\Extension\CommonMark\Renderer\Inline\EmphasisRenderer; use League\CommonMark\Extension\CommonMark\Renderer\Inline\HtmlInlineRenderer; use League\CommonMark\Extension\CommonMark\Renderer\Inline\StrongRenderer; -use League\CommonMark\Extension\ExternalLink\ExternalLinkExtension; -use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension; +use League\CommonMark\Extension\HeadingPermalink\HeadingPermalink; use League\CommonMark\MarkdownConverterInterface; use League\CommonMark\Node\Block\Document; use League\CommonMark\Node\Block\Paragraph; use League\CommonMark\Node\Inline\Newline; use League\CommonMark\Node\Inline\Text; use League\CommonMark\Normalizer\SlugNormalizer; -use League\CommonMark\Parser\Block\ParagraphParser; use League\CommonMark\Parser\Inline\NewlineParser; use League\CommonMark\Renderer\Block\DocumentRenderer; use League\CommonMark\Renderer\Block\ParagraphRenderer; @@ -143,6 +142,7 @@ private function registerCommonMarkEnvironment(): void $environment = app(MarkdownConverterInterface::class)->getEnvironment(); $environment->addRenderer(FencedCode::class, new FencedCodeRenderer()); + $environment->addRenderer(HeadingPermalink::class, new HeadingPermalinkRenderer()); $environment->addBlockStartParser(new BlockQuoteStartParser(), 70); $environment->addBlockStartParser(new HeadingStartParser(), 60);