diff --git a/packages/guides/src/Compiler/NodeTransformers/SectionCreationTransformer.php b/packages/guides/src/Compiler/NodeTransformers/SectionCreationTransformer.php index 4bd481b16..4542f3cc9 100644 --- a/packages/guides/src/Compiler/NodeTransformers/SectionCreationTransformer.php +++ b/packages/guides/src/Compiler/NodeTransformers/SectionCreationTransformer.php @@ -31,10 +31,12 @@ final class SectionCreationTransformer implements NodeTransformer { /** @var SectionNode[] $sectionStack */ private array $sectionStack = []; + private int $firstLevel = 1; public function enterNode(Node $node, CompilerContextInterface $compilerContext): Node { if ($node instanceof DocumentNode) { + $this->firstLevel = 1; $this->sectionStack = []; } @@ -68,7 +70,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) if (count($this->sectionStack) > 0 && $compilerContext->getShadowTree()->isLastChildOfParent()) { $lastSection = end($this->sectionStack); - while ($lastSection?->getTitle()->getLevel() > 1) { + while ($lastSection?->getTitle()->getLevel() > $this->firstLevel) { $lastSection = array_pop($this->sectionStack); } @@ -92,9 +94,9 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) end($this->sectionStack)->addChildNode($newSection); } - $this->sectionStack[] = $newSection; + $this->pushNewSectionToStack($newSection); - return $lastSection?->getTitle()->getLevel() === 1 ? $lastSection : null; + return $lastSection?->getTitle()->getLevel() <= $this->firstLevel ? $lastSection : null; } $newSection = new SectionNode($node); @@ -102,7 +104,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext) $lastSection->addChildNode($newSection); } - $this->sectionStack[] = $newSection; + $this->pushNewSectionToStack($newSection); return null; } @@ -117,4 +119,21 @@ public function getPriority(): int // Should run as first transformer return PHP_INT_MAX; } + + /** + * Pushes the new section to the stack. + * + * The stack is used to track the current level of nodes and adding child + * nodes to the section. As not all documentation formats are using the + * correct level of title nodes we need to track the level of the first + * title node to determine the correct level of the section. + */ + private function pushNewSectionToStack(SectionNode $newSection): void + { + if (count($this->sectionStack) === 0) { + $this->firstLevel = $newSection->getTitle()->getLevel(); + } + + $this->sectionStack[] = $newSection; + } } diff --git a/packages/guides/src/Nodes/DocumentNode.php b/packages/guides/src/Nodes/DocumentNode.php index 05f89745d..fad13d235 100644 --- a/packages/guides/src/Nodes/DocumentNode.php +++ b/packages/guides/src/Nodes/DocumentNode.php @@ -121,7 +121,7 @@ public function getPageTitle(): string|null public function getTitle(): TitleNode|null { foreach ($this->value as $node) { - if ($node instanceof SectionNode && $node->getTitle()->getLevel() === 1) { + if ($node instanceof SectionNode) { return $node->getTitle(); } diff --git a/tests/Integration/tests/markdown/sections-no-level-1-md/expected/index.html b/tests/Integration/tests/markdown/sections-no-level-1-md/expected/index.html new file mode 100644 index 000000000..c4de8e63d --- /dev/null +++ b/tests/Integration/tests/markdown/sections-no-level-1-md/expected/index.html @@ -0,0 +1,45 @@ + + +
+

Introduction

+ +

This is a sample Markdown document demonstrating sections and subsections.

+ +
+
+

Section 1

+ +

This is the first section of the document.

+ +
+

Subsection 1.1

+ +

This is a subsection under Section 1.

+ +
+
+

Subsection 1.2

+ +

Another subsection under Section 1.

+ +
+
+
+

Section 2

+ +

Moving on to the second section of the document.

+ +
+

Subsection 2.1

+ +

A subsection under Section 2.

+ +
+
+
+

Conclusion

+ +

In conclusion, this is a simple example of a Markdown document with various sections and subsections.

+ +
+ diff --git a/tests/Integration/tests/markdown/sections-no-level-1-md/input/guides.xml b/tests/Integration/tests/markdown/sections-no-level-1-md/input/guides.xml new file mode 100644 index 000000000..5f86f007a --- /dev/null +++ b/tests/Integration/tests/markdown/sections-no-level-1-md/input/guides.xml @@ -0,0 +1,7 @@ + + + diff --git a/tests/Integration/tests/markdown/sections-no-level-1-md/input/index.md b/tests/Integration/tests/markdown/sections-no-level-1-md/input/index.md new file mode 100644 index 000000000..7b616c554 --- /dev/null +++ b/tests/Integration/tests/markdown/sections-no-level-1-md/input/index.md @@ -0,0 +1,27 @@ +## Introduction + +This is a sample Markdown document demonstrating sections and subsections. + +## Section 1 + +This is the first section of the document. + +### Subsection 1.1 + +This is a subsection under Section 1. + +### Subsection 1.2 + +Another subsection under Section 1. + +## Section 2 + +Moving on to the second section of the document. + +### Subsection 2.1 + +A subsection under Section 2. + +## Conclusion + +In conclusion, this is a simple example of a Markdown document with various sections and subsections.