Skip to content

Commit 4db1f1c

Browse files
committed
[FEATURE] Add local option to contents directive
resolves #901
1 parent ff4ce84 commit 4db1f1c

File tree

7 files changed

+146
-7
lines changed

7 files changed

+146
-7
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ public function process(
5050

5151
return (new ContentMenuNode([new SectionMenuEntryNode($absoluteUrl)]))
5252
->withOptions($this->optionsToArray($options))
53-
->withCaption($directive->getDataNode());
53+
->withCaption($directive->getDataNode())
54+
->withLocal($directive->hasOption('local'));
5455
}
5556
}

packages/guides/src/Compiler/NodeTransformers/MenuNodeTransformers/ContentsMenuEntryNodeTransformer.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
namespace phpDocumentor\Guides\Compiler\NodeTransformers\MenuNodeTransformers;
1515

1616
use phpDocumentor\Guides\Compiler\CompilerContext;
17+
use phpDocumentor\Guides\Nodes\DocumentTree\SectionEntryNode;
1718
use phpDocumentor\Guides\Nodes\Menu\ContentMenuNode;
1819
use phpDocumentor\Guides\Nodes\Menu\MenuEntryNode;
1920
use phpDocumentor\Guides\Nodes\Menu\MenuNode;
2021
use phpDocumentor\Guides\Nodes\Menu\SectionMenuEntryNode;
2122
use phpDocumentor\Guides\Nodes\Node;
23+
use phpDocumentor\Guides\Nodes\SectionNode;
2224

2325
use function assert;
2426

@@ -45,12 +47,36 @@ protected function handleMenuEntry(MenuNode $currentMenu, MenuEntryNode $entryNo
4547
assert($entryNode instanceof SectionMenuEntryNode);
4648
$depth = (int) $currentMenu->getOption('depth', self::DEFAULT_MAX_LEVELS - 1) + 1;
4749
$documentEntry = $compilerContext->getDocumentNode()->getDocumentEntry();
48-
$newEntryNode = new SectionMenuEntryNode(
49-
$documentEntry->getFile(),
50-
$entryNode->getValue() ?? $documentEntry->getTitle(),
51-
1,
52-
);
53-
$this->addSubSectionsToMenuEntries($documentEntry, $newEntryNode, $depth);
50+
if ($currentMenu->isLocal()) {
51+
$sectionNode = $compilerContext->getShadowTree()->getParent()?->getParent()?->getNode();
52+
if (!$sectionNode instanceof SectionNode) {
53+
$this->logger->error('Section of contents directive not found. ', $compilerContext->getLoggerInformation());
54+
55+
return [];
56+
}
57+
58+
$sectionEntry = $documentEntry->findSectionEntry($sectionNode);
59+
if (!$sectionEntry instanceof SectionEntryNode) {
60+
$this->logger->error('Section of contents directive not found. ', $compilerContext->getLoggerInformation());
61+
62+
return [];
63+
}
64+
65+
$newEntryNode = new SectionMenuEntryNode(
66+
$documentEntry->getFile(),
67+
$entryNode->getValue() ?? $sectionEntry->getTitle(),
68+
1,
69+
$sectionEntry->getId(),
70+
);
71+
$this->addSubSections($newEntryNode, $sectionEntry, $documentEntry, 1, $depth);
72+
} else {
73+
$newEntryNode = new SectionMenuEntryNode(
74+
$documentEntry->getFile(),
75+
$entryNode->getValue() ?? $documentEntry->getTitle(),
76+
1,
77+
);
78+
$this->addSubSectionsToMenuEntries($documentEntry, $newEntryNode, $depth);
79+
}
5480

5581
return $newEntryNode->getSections();
5682
}

packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php

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

1414
namespace phpDocumentor\Guides\Nodes\DocumentTree;
1515

16+
use phpDocumentor\Guides\Nodes\SectionNode;
1617
use phpDocumentor\Guides\Nodes\TitleNode;
1718

1819
use function array_filter;
@@ -81,4 +82,22 @@ public function isRoot(): bool
8182
{
8283
return $this->isRoot;
8384
}
85+
86+
public function findSectionEntry(SectionNode $sectionNode): SectionEntryNode|null
87+
{
88+
foreach ($this->sections as $sectionEntryNode) {
89+
if ($sectionNode->getId() === $sectionEntryNode->getId()) {
90+
return $sectionEntryNode;
91+
}
92+
}
93+
94+
foreach ($this->sections as $sectionEntryNode) {
95+
$subsection = $sectionEntryNode->findSectionEntry($sectionNode);
96+
if ($subsection !== null) {
97+
return $subsection;
98+
}
99+
}
100+
101+
return null;
102+
}
84103
}

packages/guides/src/Nodes/DocumentTree/SectionEntryNode.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace phpDocumentor\Guides\Nodes\DocumentTree;
1515

1616
use phpDocumentor\Guides\Nodes\DocumentNode;
17+
use phpDocumentor\Guides\Nodes\SectionNode;
1718
use phpDocumentor\Guides\Nodes\TitleNode;
1819

1920
/** @extends EntryNode<DocumentNode> */
@@ -46,4 +47,22 @@ public function getChildren(): array
4647
{
4748
return $this->children;
4849
}
50+
51+
public function findSectionEntry(SectionNode $sectionNode): SectionEntryNode|null
52+
{
53+
foreach ($this->children as $sectionEntryNode) {
54+
if ($sectionNode->getId() === $sectionEntryNode->getId()) {
55+
return $sectionEntryNode;
56+
}
57+
}
58+
59+
foreach ($this->children as $sectionEntryNode) {
60+
$subsection = $sectionEntryNode->findSectionEntry($sectionNode);
61+
if ($subsection !== null) {
62+
return $subsection;
63+
}
64+
}
65+
66+
return null;
67+
}
4968
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
/** @link https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#table-of-contents */
1919
final class ContentMenuNode extends MenuNode
2020
{
21+
private bool $local = false;
22+
2123
public function getDepth(): int
2224
{
2325
if ($this->hasOption('depth') && is_scalar($this->getOption('depth'))) {
@@ -31,4 +33,17 @@ public function isPageLevelOnly(): bool
3133
{
3234
return false;
3335
}
36+
37+
public function isLocal(): bool
38+
{
39+
return $this->local;
40+
}
41+
42+
public function withLocal(bool $local): ContentMenuNode
43+
{
44+
$that = clone $this;
45+
$that->local = $local;
46+
47+
return $that;
48+
}
3449
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<!-- content start -->
2+
<div class="section" id="title">
3+
<h1>Title</h1>
4+
5+
<p>Some Text</p>
6+
7+
<div class="section" id="properties">
8+
<h2>Properties</h2>
9+
<div class="contents">
10+
<ul class="menu-level">
11+
<li class="toc-item">
12+
<a href="/index.html#additionalpreviewlanguages">additionalPreviewLanguages</a>
13+
14+
15+
</li>
16+
<li class="toc-item">
17+
<a href="/index.html#alertpopups">alertPopups</a>
18+
19+
20+
</li>
21+
</ul>
22+
</div>
23+
<div class="section" id="additionalpreviewlanguages">
24+
<h3>additionalPreviewLanguages</h3>
25+
26+
<p>some text</p>
27+
28+
</div>
29+
<div class="section" id="alertpopups">
30+
<h3>alertPopups</h3>
31+
32+
<p>another text</p>
33+
34+
</div>
35+
</div>
36+
</div>
37+
<!-- content end -->
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=====
2+
Title
3+
=====
4+
5+
Some Text
6+
7+
Properties
8+
==========
9+
10+
.. contents::
11+
:depth: 2
12+
:local:
13+
14+
additionalPreviewLanguages
15+
--------------------------
16+
17+
some text
18+
19+
alertPopups
20+
-----------
21+
22+
another text

0 commit comments

Comments
 (0)