diff --git a/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php b/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php index 9b1e17784..3204b0efd 100644 --- a/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php +++ b/packages/guides-restructured-text/src/RestructuredText/Directives/ToctreeDirective.php @@ -32,6 +32,43 @@ * which could be resolved by using https://github.com/phpDocumentor/guides/pull/21? * * @link https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#table-of-contents + * + * Parameters: + * + * :caption: + * (Text with inline markup) + * Caption to be displayed above the menu + * + * :depth: + * (integer) + * Maximum depth of the menu to display. Does not affect other menus. + * + * :glob: + * (bool) + * If true glob patterns containing stars are considered during menu building. + * The entries are added to the Document Tree. Orphans are ignored + * + * :globExclude: + * (comma separated string list) + * paths to be excluded from the glob patterns + * + * :hidden: + * (bool) + * The menu will not be displayed within the content and is only used to + * change the global document tree. + * + * :reversed: + * (bool) + * Display documents in reversed order. They are also added to the document + * tree in reversed order and will be displayed in that order where ever a menu + * is displayed + * + * :titlesonly: + * Do not display the headlines of the current or sub documents, only display + * page titles. + * + * :maxdepth: + * Synonym of :depth:, depth prevails if both are set. */ final class ToctreeDirective extends BaseDirective { @@ -76,6 +113,10 @@ public function process( $tocNode = $tocNode->withCaption($inlineNode); } + if ($directive->getOptionBool('reversed')) { + $tocNode = $tocNode->withReversed(true); + } + return $tocNode; } } diff --git a/packages/guides/src/Compiler/NodeTransformers/MenuNodeTransformers/ToctreeSortingTransformer.php b/packages/guides/src/Compiler/NodeTransformers/MenuNodeTransformers/ToctreeSortingTransformer.php new file mode 100644 index 000000000..a77f700cb --- /dev/null +++ b/packages/guides/src/Compiler/NodeTransformers/MenuNodeTransformers/ToctreeSortingTransformer.php @@ -0,0 +1,65 @@ + */ +final class ToctreeSortingTransformer implements NodeTransformer +{ + public function getPriority(): int + { + return 3200; + } + + public function enterNode(Node $node, CompilerContext $compilerContext): Node + { + if (!$node instanceof TocNode) { + return $node; + } + + if (!$node->isReversed()) { + return $node; + } + + $entries = $node->getValue(); + $documentEntry = $compilerContext->getDocumentNode()->getDocumentEntry(); + $documentMenuEntries = $documentEntry->getMenuEntries(); + if (is_array($entries)) { + $entries = array_reverse($entries); + $documentMenuEntries = array_reverse($documentMenuEntries); + } + + $documentEntry->setMenuEntries($documentMenuEntries); + $node->setValue($entries); + + return $node; + } + + public function leaveNode(Node $node, CompilerContext $compilerContext): Node|null + { + return $node; + } + + public function supports(Node $node): bool + { + return $node instanceof TocNode; + } +} diff --git a/packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php b/packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php index 715f9ca90..d0e538662 100644 --- a/packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php +++ b/packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php @@ -66,6 +66,12 @@ public function getMenuEntries(): array return $this->entries; } + /** @param array $entries */ + public function setMenuEntries(array $entries): void + { + $this->entries = $entries; + } + /** @return SectionEntryNode[] */ public function getSections(): array { diff --git a/packages/guides/src/Nodes/Menu/MenuNode.php b/packages/guides/src/Nodes/Menu/MenuNode.php index ab3023b75..c19dd656d 100644 --- a/packages/guides/src/Nodes/Menu/MenuNode.php +++ b/packages/guides/src/Nodes/Menu/MenuNode.php @@ -26,6 +26,7 @@ abstract class MenuNode extends CompoundNode { private InlineCompoundNode|null $caption = null; + private bool $reversed = false; protected const DEFAULT_DEPTH = PHP_INT_MAX; /** @param MenuEntryNode[] $menuEntries */ @@ -56,4 +57,17 @@ public function withCaption(InlineCompoundNode|null $caption): static return $that; } + + public function isReversed(): bool + { + return $this->reversed; + } + + public function withReversed(bool $reversed): MenuNode + { + $that = clone $this; + $that->reversed = $reversed; + + return $that; + } } diff --git a/tests/Integration/tests/toctree/toctree-glob-reverse/expected/index.html b/tests/Integration/tests/toctree/toctree-glob-reverse/expected/index.html new file mode 100644 index 000000000..9615ddfd7 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-glob-reverse/expected/index.html @@ -0,0 +1,22 @@ + +
+

Document Title

+ +

Lorem Ipsum Dolor.

+ +
+ +
+
+ diff --git a/tests/Integration/tests/toctree/toctree-glob-reverse/input/doNotInclude.rst b/tests/Integration/tests/toctree/toctree-glob-reverse/input/doNotInclude.rst new file mode 100644 index 000000000..a513f2e2e --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-glob-reverse/input/doNotInclude.rst @@ -0,0 +1,6 @@ +:orphan: + +Do not Include in menu +====================== + +This is an orphan an must be ignored by glob patterns \ No newline at end of file diff --git a/tests/Integration/tests/toctree/toctree-glob-reverse/input/index.rst b/tests/Integration/tests/toctree/toctree-glob-reverse/input/index.rst new file mode 100644 index 000000000..93f8c3e90 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-glob-reverse/input/index.rst @@ -0,0 +1,12 @@ +============== +Document Title +============== + +Lorem Ipsum Dolor. + +.. toctree:: + :glob: + :titlesonly: + :reversed: + + * diff --git a/tests/Integration/tests/toctree/toctree-glob-reverse/input/page1.rst b/tests/Integration/tests/toctree/toctree-glob-reverse/input/page1.rst new file mode 100644 index 000000000..9a1df3ce9 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-glob-reverse/input/page1.rst @@ -0,0 +1,14 @@ +====== +Page 1 +====== + +Lorem Ipsum Dolor. + +Page 1 Level 2 +-------------- + +Page 1 Level 3 +~~~~~~~~~~~~~~ + +Page 1 Level 4 +"""""""""""""" diff --git a/tests/Integration/tests/toctree/toctree-glob-reverse/input/page2.rst b/tests/Integration/tests/toctree/toctree-glob-reverse/input/page2.rst new file mode 100644 index 000000000..cdd19d739 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-glob-reverse/input/page2.rst @@ -0,0 +1,14 @@ +====== +Page 2 +====== + +Lorem Ipsum Dolor. + +Page 2 Level 2 +-------------- + +Page 2 Level 3 +~~~~~~~~~~~~~~ + +Page 2 Level 4 +"""""""""""""" diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/index.html b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/index.html new file mode 100644 index 000000000..71cf06f1f --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/index.html @@ -0,0 +1,54 @@ + +
+

Document Title

+ +

Lorem Ipsum Dolor.

+ +
+ +
+
+ diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder/index.html b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder/index.html new file mode 100644 index 000000000..fa92849d2 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder/index.html @@ -0,0 +1,27 @@ + +
+

Subfolder with reversed menu

+ +

Lorem Ipsum Dolor.

+ +
+
A Definition List
+ +
Some definition.
+
+
+ +
+
+ diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder2/index.html b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder2/index.html new file mode 100644 index 000000000..a1ccf9f37 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/expected/subfolder2/index.html @@ -0,0 +1,19 @@ + +
+

Subfolder 2 Menu not reversed

+
+ +
+
+ diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/index.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/index.rst new file mode 100644 index 000000000..071848a6c --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/index.rst @@ -0,0 +1,16 @@ +============== +Document Title +============== + +Lorem Ipsum Dolor. + + +.. toctree:: + :glob: + :titlesonly: + :reversed: + + page1 + page2 + subfolder/index + subfolder2/index diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page1.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page1.rst new file mode 100644 index 000000000..9a1df3ce9 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page1.rst @@ -0,0 +1,14 @@ +====== +Page 1 +====== + +Lorem Ipsum Dolor. + +Page 1 Level 2 +-------------- + +Page 1 Level 3 +~~~~~~~~~~~~~~ + +Page 1 Level 4 +"""""""""""""" diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page2.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page2.rst new file mode 100644 index 000000000..cdd19d739 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/page2.rst @@ -0,0 +1,14 @@ +====== +Page 2 +====== + +Lorem Ipsum Dolor. + +Page 2 Level 2 +-------------- + +Page 2 Level 3 +~~~~~~~~~~~~~~ + +Page 2 Level 4 +"""""""""""""" diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/index.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/index.rst new file mode 100644 index 000000000..992d182e7 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/index.rst @@ -0,0 +1,15 @@ +============================ +Subfolder with reversed menu +============================ + +Lorem Ipsum Dolor. + +A Definition List + Some definition. + +.. toctree:: + :glob: + :titlesonly: + :reversed: + + * diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage1.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage1.rst new file mode 100644 index 000000000..a9ba21452 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage1.rst @@ -0,0 +1,5 @@ +========= +Subpage 1 +========= + +Lorem Ipsum Dolor. diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage2.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage2.rst new file mode 100644 index 000000000..baff4cff7 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder/subpage2.rst @@ -0,0 +1,5 @@ +========= +Subpage 2 +========= + +Lorem Ipsum Dolor. diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/index.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/index.rst new file mode 100644 index 000000000..43e98e5b9 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/index.rst @@ -0,0 +1,9 @@ +============================= +Subfolder 2 Menu not reversed +============================= + +.. toctree:: + :glob: + :titlesonly: + + * diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage1.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage1.rst new file mode 100644 index 000000000..a9ba21452 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage1.rst @@ -0,0 +1,5 @@ +========= +Subpage 1 +========= + +Lorem Ipsum Dolor. diff --git a/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage2.rst b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage2.rst new file mode 100644 index 000000000..baff4cff7 --- /dev/null +++ b/tests/Integration/tests/toctree/toctree-level-2-reversed/input/subfolder2/subpage2.rst @@ -0,0 +1,5 @@ +========= +Subpage 2 +========= + +Lorem Ipsum Dolor.