diff --git a/src/Renderers/TitleNodeRenderer.php b/src/Renderers/TitleNodeRenderer.php
new file mode 100644
index 00000000..2012be65
--- /dev/null
+++ b/src/Renderers/TitleNodeRenderer.php
@@ -0,0 +1,55 @@
+
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace SymfonyDocsBuilder\Renderers;
+
+use Doctrine\RST\Environment;
+use Doctrine\RST\Nodes\TitleNode;
+use Doctrine\RST\Renderers\NodeRenderer;
+use Doctrine\RST\Templates\TemplateRenderer;
+
+class TitleNodeRenderer implements NodeRenderer
+{
+ /** @var TitleNode */
+ private $titleNode;
+
+ /** @var TemplateRenderer */
+ private $templateRenderer;
+
+ private static $idUsagesCountByFilename = [];
+
+ public function __construct(TitleNode $titleNode, TemplateRenderer $templateRenderer)
+ {
+ $this->titleNode = $titleNode;
+ $this->templateRenderer = $templateRenderer;
+ }
+
+ public function render(): string
+ {
+ $filename = $this->titleNode->getEnvironment()->getCurrentFileName();
+ $id = $this->titleNode->getId();
+
+ $idUsagesCount = self::$idUsagesCountByFilename[$filename][$id] ?? 0;
+
+ if (0 === $idUsagesCount) {
+ $computedId = $this->titleNode->getId();
+ } else {
+ $computedId = Environment::slugify($this->titleNode->getValue()->getText().'-'.$idUsagesCount);
+ }
+
+ self::$idUsagesCountByFilename[$filename][$id] = $idUsagesCount + 1;
+
+ return $this->templateRenderer->render('header-title.html.twig', [
+ 'titleNode' => $this->titleNode,
+ 'id' => $computedId,
+ ]);
+ }
+}
diff --git a/src/SymfonyHTMLFormat.php b/src/SymfonyHTMLFormat.php
index 6dcb04b5..fd7f35fe 100644
--- a/src/SymfonyHTMLFormat.php
+++ b/src/SymfonyHTMLFormat.php
@@ -14,6 +14,7 @@
use Doctrine\RST\Formats\Format;
use Doctrine\RST\Nodes\CodeNode;
use Doctrine\RST\Nodes\SpanNode;
+use Doctrine\RST\Nodes\TitleNode;
use Doctrine\RST\Renderers\CallableNodeRendererFactory;
use Doctrine\RST\Renderers\NodeRendererFactory;
use Doctrine\RST\Templates\TemplateRenderer;
@@ -77,6 +78,15 @@ function (SpanNode $node) {
}
);
+ $nodeRendererFactories[TitleNode::class] = new CallableNodeRendererFactory(
+ function (TitleNode $node) {
+ return new Renderers\TitleNodeRenderer(
+ $node,
+ $this->templateRenderer
+ );
+ }
+ );
+
return $nodeRendererFactories;
}
}
diff --git a/src/Templates/default/html/header-title.html.twig b/src/Templates/default/html/header-title.html.twig
index 05247263..0ffbc460 100644
--- a/src/Templates/default/html/header-title.html.twig
+++ b/src/Templates/default/html/header-title.html.twig
@@ -1 +1 @@
-
+
diff --git a/src/Templates/rtd/html/header-title.html.twig b/src/Templates/rtd/html/header-title.html.twig
index f91e3706..fe2b810e 100644
--- a/src/Templates/rtd/html/header-title.html.twig
+++ b/src/Templates/rtd/html/header-title.html.twig
@@ -1,4 +1,4 @@
-
+
{{ titleNode.value.render()|raw }}
-
+
diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php
index ccc5a495..ca97f976 100644
--- a/tests/IntegrationTest.php
+++ b/tests/IntegrationTest.php
@@ -17,9 +17,19 @@
use Symfony\Component\Finder\Finder;
use SymfonyDocsBuilder\DocBuilder;
use SymfonyDocsBuilder\KernelFactory;
+use SymfonyDocsBuilder\Renderers\TitleNodeRenderer;
class IntegrationTest extends AbstractIntegrationTest
{
+ public static function setUpBeforeClass(): void
+ {
+ $reflection = new \ReflectionClass(TitleNodeRenderer::class);
+ $property = $reflection->getProperty('idUsagesCountByFilename');
+ $property->setAccessible(true);
+
+ $property->setValue([]);
+ }
+
/**
* @dataProvider integrationProvider
*/
diff --git a/tests/fixtures/expected/blocks/nodes/title.html b/tests/fixtures/expected/blocks/nodes/title.html
index 5ba7a4bb..2106a603 100644
--- a/tests/fixtures/expected/blocks/nodes/title.html
+++ b/tests/fixtures/expected/blocks/nodes/title.html
@@ -10,5 +10,8 @@