Skip to content

Commit 662106f

Browse files
committed
[FIX] make heading level dynamic
The heading level of markdown documents is not strictly 1 based. Some documents are starting with a random heading. Before those documents were rendered empty. This change fixes that behavior, headings to not longer start at level 1.
1 parent 63b9b78 commit 662106f

File tree

5 files changed

+103
-5
lines changed

5 files changed

+103
-5
lines changed

packages/guides/src/Compiler/NodeTransformers/SectionCreationTransformer.php

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ final class SectionCreationTransformer implements NodeTransformer
3131
{
3232
/** @var SectionNode[] $sectionStack */
3333
private array $sectionStack = [];
34+
private int $firstLevel = 1;
3435

3536
public function enterNode(Node $node, CompilerContextInterface $compilerContext): Node
3637
{
3738
if ($node instanceof DocumentNode) {
39+
$this->firstLevel = 1;
3840
$this->sectionStack = [];
3941
}
4042

@@ -68,7 +70,7 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext)
6870

6971
if (count($this->sectionStack) > 0 && $compilerContext->getShadowTree()->isLastChildOfParent()) {
7072
$lastSection = end($this->sectionStack);
71-
while ($lastSection?->getTitle()->getLevel() > 1) {
73+
while ($lastSection?->getTitle()->getLevel() > $this->firstLevel) {
7274
$lastSection = array_pop($this->sectionStack);
7375
}
7476

@@ -92,17 +94,17 @@ public function leaveNode(Node $node, CompilerContextInterface $compilerContext)
9294
end($this->sectionStack)->addChildNode($newSection);
9395
}
9496

95-
$this->sectionStack[] = $newSection;
97+
$this->pushNewSectionToStack($newSection);
9698

97-
return $lastSection?->getTitle()->getLevel() === 1 ? $lastSection : null;
99+
return $lastSection?->getTitle()->getLevel() <= $this->firstLevel ? $lastSection : null;
98100
}
99101

100102
$newSection = new SectionNode($node);
101103
if ($lastSection instanceof SectionNode) {
102104
$lastSection->addChildNode($newSection);
103105
}
104106

105-
$this->sectionStack[] = $newSection;
107+
$this->pushNewSectionToStack($newSection);
106108

107109
return null;
108110
}
@@ -117,4 +119,21 @@ public function getPriority(): int
117119
// Should run as first transformer
118120
return PHP_INT_MAX;
119121
}
122+
123+
/**
124+
* Pushes the new section to the stack.
125+
*
126+
* The stack is used to track the current level of nodes and adding child
127+
* nodes to the section. As not all documentation formats are using the
128+
* correct level of title nodes we need to track the level of the first
129+
* title node to determine the correct level of the section.
130+
*/
131+
private function pushNewSectionToStack(SectionNode $newSection): void
132+
{
133+
if (count($this->sectionStack) === 0) {
134+
$this->firstLevel = $newSection?->getTitle()->getLevel() ?? 1;
135+
}
136+
137+
$this->sectionStack[] = $newSection;
138+
}
120139
}

packages/guides/src/Nodes/DocumentNode.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public function getPageTitle(): string|null
121121
public function getTitle(): TitleNode|null
122122
{
123123
foreach ($this->value as $node) {
124-
if ($node instanceof SectionNode && $node->getTitle()->getLevel() === 1) {
124+
if ($node instanceof SectionNode) {
125125
return $node->getTitle();
126126
}
127127

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!-- content start -->
2+
3+
<div class="section" id="introduction">
4+
<h2>Introduction</h2>
5+
6+
<p>This is a sample Markdown document demonstrating sections and subsections.</p>
7+
8+
</div>
9+
<div class="section" id="section-1">
10+
<h2>Section 1</h2>
11+
12+
<p>This is the first section of the document.</p>
13+
14+
<div class="section" id="subsection-1-1">
15+
<h3>Subsection 1.1</h3>
16+
17+
<p>This is a subsection under Section 1.</p>
18+
19+
</div>
20+
<div class="section" id="subsection-1-2">
21+
<h3>Subsection 1.2</h3>
22+
23+
<p>Another subsection under Section 1.</p>
24+
25+
</div>
26+
</div>
27+
<div class="section" id="section-2">
28+
<h2>Section 2</h2>
29+
30+
<p>Moving on to the second section of the document.</p>
31+
32+
<div class="section" id="subsection-2-1">
33+
<h3>Subsection 2.1</h3>
34+
35+
<p>A subsection under Section 2.</p>
36+
37+
</div>
38+
</div>
39+
<div class="section" id="conclusion">
40+
<h2>Conclusion</h2>
41+
42+
<p>In conclusion, this is a simple example of a Markdown document with various sections and subsections.</p>
43+
44+
</div>
45+
<!-- content end -->
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<guides xmlns="https://www.phpdoc.org/guides"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="https://www.phpdoc.org/guides packages/guides-cli/resources/schema/guides.xsd"
5+
input-format="md"
6+
>
7+
</guides>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## Introduction
2+
3+
This is a sample Markdown document demonstrating sections and subsections.
4+
5+
## Section 1
6+
7+
This is the first section of the document.
8+
9+
### Subsection 1.1
10+
11+
This is a subsection under Section 1.
12+
13+
### Subsection 1.2
14+
15+
Another subsection under Section 1.
16+
17+
## Section 2
18+
19+
Moving on to the second section of the document.
20+
21+
### Subsection 2.1
22+
23+
A subsection under Section 2.
24+
25+
## Conclusion
26+
27+
In conclusion, this is a simple example of a Markdown document with various sections and subsections.

0 commit comments

Comments
 (0)