Skip to content

Commit 1c29d1d

Browse files
linawolfjaapio
authored andcommitted
Introduce Transformer for Content Menus
This reintroduces the contents directive which was destroyed by switching to transformers
1 parent 288150d commit 1c29d1d

23 files changed

+207
-370
lines changed

packages/guides-restructured-text/src/RestructuredText/Directives/ContentsDirective.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace phpDocumentor\Guides\RestructuredText\Directives;
66

7-
use phpDocumentor\Guides\Nodes\ContentMenuNode;
7+
use phpDocumentor\Guides\Nodes\Menu\ContentMenuNode;
88
use phpDocumentor\Guides\Nodes\Node;
99
use phpDocumentor\Guides\RestructuredText\Parser\Directive;
1010
use phpDocumentor\Guides\RestructuredText\Parser\DocumentParserContext;
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace phpDocumentor\Guides\Compiler\NodeTransformers;
6+
7+
use phpDocumentor\Guides\Compiler\CompilerContext;
8+
use phpDocumentor\Guides\Compiler\NodeTransformer;
9+
use phpDocumentor\Guides\Nodes\DocumentTree\DocumentEntryNode;
10+
use phpDocumentor\Guides\Nodes\DocumentTree\SectionEntryNode;
11+
use phpDocumentor\Guides\Nodes\Menu\ContentMenuNode;
12+
use phpDocumentor\Guides\Nodes\Menu\MenuEntryNode;
13+
use phpDocumentor\Guides\Nodes\Menu\TocNode;
14+
use phpDocumentor\Guides\Nodes\Node;
15+
16+
use function assert;
17+
18+
use const PHP_INT_MAX;
19+
20+
/** @implements NodeTransformer<TocNode> */
21+
class ContentMenuNodeWithSectionEntryTransformer implements NodeTransformer
22+
{
23+
public function enterNode(Node $node, CompilerContext $compilerContext): Node
24+
{
25+
return $node;
26+
}
27+
28+
public function leaveNode(Node $node, CompilerContext $compilerContext): Node|null
29+
{
30+
if (!$node instanceof ContentMenuNode) {
31+
return $node;
32+
}
33+
34+
$depth = (int) $node->getOption('depth', PHP_INT_MAX);
35+
$documentEntry = $compilerContext->getDocumentNode()->getDocumentEntry();
36+
37+
$menuEntries = [];
38+
foreach ($documentEntry->getSections() as $section) {
39+
// We do not add the main section as it repeats the document title
40+
foreach ($section->getChildren() as $subSectionEntryNode) {
41+
assert($subSectionEntryNode instanceof SectionEntryNode);
42+
$sectionMenuEntry = new MenuEntryNode(
43+
$documentEntry->getFile(),
44+
$subSectionEntryNode->getTitle(),
45+
[],
46+
false,
47+
1,
48+
$subSectionEntryNode->getId(),
49+
);
50+
$menuEntries[] = $sectionMenuEntry;
51+
$this->addSubSections($sectionMenuEntry, $subSectionEntryNode, $documentEntry, 1, $depth);
52+
}
53+
}
54+
55+
$node = $node->withMenuEntries($menuEntries);
56+
57+
return $node;
58+
}
59+
60+
private function addSubSections(
61+
MenuEntryNode $sectionMenuEntry,
62+
SectionEntryNode $sectionEntryNode,
63+
DocumentEntryNode $documentEntry,
64+
int $currentLevel,
65+
int $maxLevel,
66+
): void {
67+
if ($currentLevel >= $maxLevel) {
68+
return;
69+
}
70+
71+
foreach ($sectionEntryNode->getChildren() as $subSectionEntryNode) {
72+
$subSectionMenuEntry = new MenuEntryNode(
73+
$documentEntry->getFile(),
74+
$subSectionEntryNode->getTitle(),
75+
[],
76+
false,
77+
$currentLevel,
78+
$subSectionEntryNode->getId(),
79+
);
80+
$sectionMenuEntry->addSection($subSectionMenuEntry);
81+
$this->addSubSections(
82+
$subSectionMenuEntry,
83+
$subSectionEntryNode,
84+
$documentEntry,
85+
$currentLevel + 1,
86+
$maxLevel,
87+
);
88+
}
89+
}
90+
91+
public function supports(Node $node): bool
92+
{
93+
return $node instanceof ContentMenuNode;
94+
}
95+
96+
public function getPriority(): int
97+
{
98+
// After DocumentEntryTransformer
99+
return 4500;
100+
}
101+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function leaveNode(Node $node, CompilerContext $compilerContext): Node|nu
3838
$entry = new DocumentEntryNode($node->getFilePath(), $node->getTitle() ?? TitleNode::emptyNode());
3939
$compilerContext->getProjectNode()->addDocumentEntry($entry);
4040

41-
return $node->withDocumentEntry($entry);
41+
return $node->setDocumentEntry($entry);
4242
}
4343

4444
public function supports(Node $node): bool

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

Lines changed: 0 additions & 128 deletions
This file was deleted.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function enterNode(Node $node, CompilerContext $compilerContext): Node
2929

3030
$sectionEntryNode = new SectionEntryNode($node->getTitle());
3131
if (count($this->sectionStack) === 0) {
32-
$compilerContext->getDocumentNode()->getDocumentEntry()?->addSection($sectionEntryNode);
32+
$compilerContext->getDocumentNode()->getDocumentEntry()->addSection($sectionEntryNode);
3333
} else {
3434
$parentSection = end($this->sectionStack);
3535
assert($parentSection instanceof SectionEntryNode);

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ public function leaveNode(Node $node, CompilerContext $compilerContext): Node|nu
8080
private function addSubSections(MenuEntryNode $sectionMenuEntry, SectionEntryNode $sectionEntryNode, DocumentEntryNode $documentEntry, int $currentLevel): void
8181
{
8282
foreach ($sectionEntryNode->getChildren() as $subSectionEntryNode) {
83-
$sectionMenuEntry = new MenuEntryNode($documentEntry->getFile(), $subSectionEntryNode->getTitle(), [], false, $currentLevel, $subSectionEntryNode->getId());
84-
$sectionMenuEntry->addSection($sectionMenuEntry);
83+
$subSectionMenuEntry = new MenuEntryNode($documentEntry->getFile(), $subSectionEntryNode->getTitle(), [], false, $currentLevel + 1, $subSectionEntryNode->getId());
84+
$sectionMenuEntry->addSection($subSectionMenuEntry);
8585
}
8686
}
8787

8888
public function supports(Node $node): bool
8989
{
90-
return $node instanceof MenuNode;
90+
return $node instanceof TocNode;
9191
}
9292

9393
public function getPriority(): int

packages/guides/src/NodeRenderers/Html/MenuNodeRenderer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
namespace phpDocumentor\Guides\NodeRenderers\Html;
1515

1616
use phpDocumentor\Guides\NodeRenderers\NodeRenderer;
17-
use phpDocumentor\Guides\Nodes\ContentMenuNode;
17+
use phpDocumentor\Guides\Nodes\Menu\ContentMenuNode;
1818
use phpDocumentor\Guides\Nodes\Menu\MenuNode;
1919
use phpDocumentor\Guides\Nodes\Menu\TocNode;
2020
use phpDocumentor\Guides\Nodes\Node;

packages/guides/src/Nodes/DocumentNode.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace phpDocumentor\Guides\Nodes;
1515

16+
use Exception;
1617
use phpDocumentor\Guides\Meta\FootnoteTarget;
1718
use phpDocumentor\Guides\Nodes\DocumentTree\DocumentEntryNode;
1819
use phpDocumentor\Guides\Nodes\DocumentTree\SectionEntryNode;
@@ -245,17 +246,20 @@ public function getFootnoteTargetAnonymous(): FootnoteTarget|null
245246
return null;
246247
}
247248

248-
public function getDocumentEntry(): DocumentEntryNode|null
249+
public function getDocumentEntry(): DocumentEntryNode
249250
{
251+
if ($this->documentEntry === null) {
252+
throw new Exception('DocumentEntry may not be accessed before initialization');
253+
}
254+
250255
return $this->documentEntry;
251256
}
252257

253-
public function withDocumentEntry(DocumentEntryNode $documentEntry): DocumentNode
258+
public function setDocumentEntry(DocumentEntryNode $documentEntry): DocumentNode
254259
{
255-
$node = clone$this;
256-
$node->documentEntry = $documentEntry;
260+
$this->documentEntry = $documentEntry;
257261

258-
return $node;
262+
return $this;
259263
}
260264

261265
public function getRootSectionEntry(): SectionEntryNode|null

packages/guides/src/Nodes/ContentMenuNode.php renamed to packages/guides/src/Nodes/Menu/ContentMenuNode.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
* @link https://phpdoc.org
1212
*/
1313

14-
namespace phpDocumentor\Guides\Nodes;
15-
16-
use phpDocumentor\Guides\Nodes\Menu\MenuNode;
14+
namespace phpDocumentor\Guides\Nodes\Menu;
1715

1816
use function is_scalar;
1917

0 commit comments

Comments
 (0)