Skip to content

Commit d430aa5

Browse files
committed
[TASK] Move section creation to the first compiler phase
1 parent 3739af2 commit d430aa5

File tree

18 files changed

+213
-86
lines changed

18 files changed

+213
-86
lines changed

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

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,38 +16,33 @@
1616
use phpDocumentor\Guides\Compiler\CompilerContext;
1717
use phpDocumentor\Guides\Compiler\NodeTransformer;
1818
use phpDocumentor\Guides\Nodes\DocumentNode;
19-
use phpDocumentor\Guides\Nodes\DocumentTree\SectionEntryNode;
2019
use phpDocumentor\Guides\Nodes\Node;
21-
use phpDocumentor\Guides\Nodes\ProjectNode;
2220
use phpDocumentor\Guides\Nodes\SectionNode;
23-
2421
use phpDocumentor\Guides\Nodes\TitleNode;
22+
2523
use function array_pop;
26-
use function assert;
2724
use function count;
2825
use function end;
2926

27+
use const PHP_INT_MAX;
28+
3029
/** @implements NodeTransformer<Node> */
3130
final class SectionCreationTransformer implements NodeTransformer
3231
{
3332
/** @var SectionNode[] $sectionStack */
3433
private array $sectionStack = [];
3534

36-
3735
public function enterNode(Node $node, CompilerContext $compilerContext): Node
3836
{
3937
if (!$compilerContext->getShadowTree()->getParent()?->getNode() instanceof DocumentNode) {
4038
return $node;
4139
}
42-
if ($node instanceof TitleNode) {
43-
if (count($this->sectionStack) === 0) {
44-
$this->sectionStack[] = new SectionNode($node);
45-
}
46-
}
4740

48-
$lastSection = end($this->sectionStack);
49-
if ($lastSection instanceof SectionNode) {
50-
$lastSection->addChildNode($node);
41+
if (!$node instanceof TitleNode) {
42+
$lastSection = end($this->sectionStack);
43+
if ($lastSection instanceof SectionNode) {
44+
$lastSection->addChildNode($node);
45+
}
5146
}
5247

5348
return $node;
@@ -58,18 +53,50 @@ public function leaveNode(Node $node, CompilerContext $compilerContext): Node|nu
5853
if (!$compilerContext->getShadowTree()->getParent()?->getNode() instanceof DocumentNode) {
5954
return $node;
6055
}
61-
// Try removing all nodes...
62-
return null;
63-
/*
64-
if (count($this->sectionStack) === 0) {
56+
57+
if ($node instanceof SectionNode) {
6558
return $node;
6659
}
60+
61+
if (count($this->sectionStack) === 0 && !$node instanceof TitleNode) {
62+
return $node;
63+
}
64+
65+
if (count($this->sectionStack) > 0 && $compilerContext->getShadowTree()->isLastChildOfParent()) {
66+
$lastSection = end($this->sectionStack);
67+
while ($lastSection?->getTitle()->getLevel() > 1) {
68+
$lastSection = array_pop($this->sectionStack);
69+
}
70+
71+
return $lastSection;
72+
}
73+
6774
if ($node instanceof TitleNode) {
68-
return array_pop($this->sectionStack);
75+
$lastSection = end($this->sectionStack);
76+
if ($lastSection instanceof SectionNode && $node !== $lastSection->getTitle() && $node->getLevel() <= $lastSection->getTitle()->getLevel()) {
77+
while (end($this->sectionStack) instanceof SectionNode && $node !== end($this->sectionStack)->getTitle() && $node->getLevel() <= end($this->sectionStack)->getTitle()->getLevel()) {
78+
$lastSection = array_pop($this->sectionStack);
79+
}
80+
81+
$newSection = new SectionNode($node);
82+
if (end($this->sectionStack) instanceof SectionNode) {
83+
end($this->sectionStack)->addChildNode($newSection);
84+
}
85+
86+
$this->sectionStack[] = $newSection;
87+
88+
return $lastSection?->getTitle()->getLevel() === 1 ? $lastSection : null;
89+
} else {
90+
$newSection = new SectionNode($node);
91+
if ($lastSection instanceof SectionNode) {
92+
$lastSection->addChildNode($newSection);
93+
}
94+
95+
$this->sectionStack[] = $newSection;
96+
}
6997
}
7098

7199
return null;
72-
*/
73100
}
74101

75102
public function supports(Node $node): bool
@@ -79,7 +106,7 @@ public function supports(Node $node): bool
79106

80107
public function getPriority(): int
81108
{
82-
// Before SectionEntryRegistrationTransformer
83-
return 1;
109+
// Should run as first transformer
110+
return PHP_INT_MAX;
84111
}
85112
}

packages/guides/src/Compiler/ShadowTree/TreeNode.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
use function array_unshift;
2222
use function array_values;
23+
use function count;
2324

2425
/** @template-covariant TNode of Node */
2526
final class TreeNode
@@ -198,4 +199,13 @@ public function findPosition(Node $node): int|null
198199

199200
return null;
200201
}
202+
203+
public function isLastChildOfParent(): bool
204+
{
205+
if ($this->parent === null) {
206+
return false;
207+
}
208+
209+
return $this->parent->findPosition($this->node) === count($this->parent->getChildren()) - 1;
210+
}
201211
}
Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
<!-- content start -->
2-
<h1>Markdown Blockquotes</h1>
2+
<div class="section" id="markdown-blockquotes">
3+
<h1>Markdown Blockquotes</h1>
34

4-
<blockquote><p>This is a blockquote.It can span multiple lines.</p></blockquote>
5+
<blockquote><p>This is a blockquote.It can span multiple lines.</p></blockquote>
56

6-
<h2>Blockquotes with Multiple Paragraphs</h2>
7+
<div class="section" id="blockquotes-with-multiple-paragraphs">
8+
<h2>Blockquotes with Multiple Paragraphs</h2>
79

8-
<blockquote><p>Dorothy followed her through many of the beautiful rooms in her castle.</p><p>The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.</p></blockquote>
10+
<blockquote><p>Dorothy followed her through many of the beautiful rooms in her castle.</p><p>The Witch bade her clean the pots and kettles and sweep the floor and keep the fire fed with wood.</p></blockquote>
911

10-
<h2>Blockquotes with Other Elements</h2>
12+
</div>
1113

12-
<blockquote><p>The quarterly results look great!</p>
14+
<div class="section" id="blockquotes-with-other-elements">
15+
<h2>Blockquotes with Other Elements</h2>
16+
17+
<blockquote><p>The quarterly results look great!</p>
1318

1419
<ul>
1520
<li class="dash"><p>Revenue was off the chart.</p></li>
@@ -19,10 +24,17 @@ <h2>Blockquotes with Other Elements</h2>
1924
</ul>
2025
<p><em>Everything</em> is going according to <strong>plan</strong>.</p></blockquote>
2126

22-
<h2>Blockquotes Best Practices</h2>
27+
</div>
28+
29+
<div class="section" id="blockquotes-best-practices">
30+
<h2>Blockquotes Best Practices</h2>
31+
32+
<p>Try to put a blank line before...</p>
33+
<blockquote><p>This is a blockquote</p></blockquote>
34+
35+
<p>...and after a blockquote.</p>
36+
</div>
2337

24-
<p>Try to put a blank line before...</p>
25-
<blockquote><p>This is a blockquote</p></blockquote>
38+
</div>
2639

27-
<p>...and after a blockquote.</p>
2840
<!-- content end -->
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
11
<!-- content start -->
2-
<h1>Markdown with Code Blocks</h1>
2+
<div class="section" id="markdown-with-code-blocks">
3+
<h1>Markdown with Code Blocks</h1>
34

4-
<pre><code class="language-">&lt;html&gt;
5+
<pre><code class="language-">&lt;html&gt;
56
&lt;head&gt;
67
&lt;/head&gt;
78
&lt;/html&gt;
89
</code></pre>
9-
<h2>Fenced Code Blocks</h2>
10+
<div class="section" id="fenced-code-blocks">
11+
<h2>Fenced Code Blocks</h2>
1012

11-
<pre><code class="language-">{
13+
<pre><code class="language-">{
1214
&quot;firstName&quot;: &quot;John&quot;,
1315
&quot;lastName&quot;: &quot;Smith&quot;,
1416
&quot;age&quot;: 25
1517
}
1618
</code></pre>
17-
<h2>Fenced Code Block with caption</h2>
19+
</div>
1820

19-
<pre><code class="language-">procedure startSwinging(swing, child)
21+
<div class="section" id="fenced-code-block-with-caption">
22+
<h2>Fenced Code Block with caption</h2>
23+
24+
<pre><code class="language-">procedure startSwinging(swing, child)
2025
while child.isComfortable()
2126
swing.giveGentlePush()
2227
waitForNextIteration()
2328
end while
2429
end procedure
2530
</code></pre>
31+
</div>
32+
33+
</div>
34+
2635
<!-- content end -->
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<!-- content start -->
2-
<h1>Markdown with emphasis</h1>
2+
<div class="section" id="markdown-with-emphasis">
3+
<h1>Markdown with emphasis</h1>
4+
5+
<p><em>Italic</em> or <em>Italic</em><strong>Bold</strong> or <strong>Bold</strong></p>
6+
</div>
37

4-
<p><em>Italic</em> or <em>Italic</em><strong>Bold</strong> or <strong>Bold</strong></p>
58
<!-- content end -->
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<!-- content start -->
2-
<h1>Markdown with html</h1>
2+
<div class="section" id="markdown-with-html">
3+
<h1>Markdown with html</h1>
4+
5+
<p>In files of text, where words take flight,Markdown weaves its magic, bold and bright.Hashes and stars, a simple code,A poet&#039;s playground, where stories unfold. &lt;BR&gt;</p>
6+
</div>
37

4-
<p>In files of text, where words take flight,Markdown weaves its magic, bold and bright.Hashes and stars, a simple code,A poet&#039;s playground, where stories unfold. &lt;BR&gt;</p>
58
<!-- content end -->
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
<!-- content start -->
2-
<h1>Markdown with html</h1>
2+
<div class="section" id="markdown-with-html">
3+
<h1>Markdown with html</h1>
34

4-
<p>&lt;div align=&quot;center&quot;&gt;
5+
<p>&lt;div align=&quot;center&quot;&gt;
56
In files of text, where words take flight,
67
Markdown weaves its magic, bold and bright.
78
Hashes and stars, a simple code,
89
A poet&#039;s playground, where stories unfold.
910
&lt;/div&gt;</p>
11+
</div>
12+
1013
<!-- content end -->
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<!-- content start -->
2-
<h1>Images with and without alt text</h1>
2+
<div class="section" id="images-with-and-without-alt-text">
3+
<h1>Images with and without alt text</h1>
4+
5+
<p><img src="https://example.org/example.png" alt="with alt Text"/></p>
6+
<p><img src="https://example.org/example2.png" alt=""/></p>
7+
</div>
38

4-
<p><img src="https://example.org/example.png" alt="with alt Text"/></p>
5-
<p><img src="https://example.org/example2.png" alt=""/></p>
69
<!-- content end -->
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<!-- content start -->
2-
<h1>Markdown Image</h1>
2+
<div class="section" id="markdown-image">
3+
<h1>Markdown Image</h1>
4+
5+
<p><img src="hero-illustration.svg" alt="Hero Illustrations"/></p>
6+
</div>
37

4-
<p><img src="hero-illustration.svg" alt="Hero Illustrations"/></p>
58
<!-- content end -->
Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
<!-- content start -->
2-
<h1>Markdown Example</h1>
2+
<div class="section" id="markdown-example">
3+
<h1>Markdown Example</h1>
34

4-
<p>This is a Markdown document with some basic formatting.</p>
5-
<h2>Headings</h2>
5+
<p>This is a Markdown document with some basic formatting.</p>
6+
<div class="section" id="headings">
7+
<h2>Headings</h2>
8+
9+
<p>You can create headings using hash symbols.</p>
10+
<p>This text is part of a paragraph under the &quot;Headings&quot; heading.</p>
11+
</div>
12+
13+
</div>
614

7-
<p>You can create headings using hash symbols.</p>
8-
<p>This text is part of a paragraph under the &quot;Headings&quot; heading.</p>
915
<!-- content end -->

0 commit comments

Comments
 (0)