Skip to content

[FEATURE] Support :reversed: option for toctrees #1219

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -76,6 +113,10 @@ public function process(
$tocNode = $tocNode->withCaption($inlineNode);
}

if ($directive->getOptionBool('reversed')) {
$tocNode = $tocNode->withReversed(true);
}

return $tocNode;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

/**
* This file is part of phpDocumentor.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*
* @link https://phpdoc.org
*/

namespace phpDocumentor\Guides\Compiler\NodeTransformers\MenuNodeTransformers;

use phpDocumentor\Guides\Compiler\CompilerContext;
use phpDocumentor\Guides\Compiler\NodeTransformer;
use phpDocumentor\Guides\Nodes\Menu\TocNode;
use phpDocumentor\Guides\Nodes\Node;

use function array_reverse;
use function is_array;

/** @implements NodeTransformer<TocNode> */
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;
}
}
6 changes: 6 additions & 0 deletions packages/guides/src/Nodes/DocumentTree/DocumentEntryNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ public function getMenuEntries(): array
return $this->entries;
}

/** @param array<DocumentEntryNode|ExternalEntryNode> $entries */
public function setMenuEntries(array $entries): void
{
$this->entries = $entries;
}

/** @return SectionEntryNode[] */
public function getSections(): array
{
Expand Down
14 changes: 14 additions & 0 deletions packages/guides/src/Nodes/Menu/MenuNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!-- content start -->
<div class="section" id="document-title">
<h1>Document Title</h1>

<p>Lorem Ipsum Dolor.</p>

<div class="toc">
<ul class="menu-level">
<li class="toc-item">
<a href="/page2.html#page-2">Page 2</a>


</li>
<li class="toc-item">
<a href="/page1.html#page-1">Page 1</a>


</li>
</ul>
</div>
</div>
<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
:orphan:

Do not Include in menu
======================

This is an orphan an must be ignored by glob patterns
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
==============
Document Title
==============

Lorem Ipsum Dolor.

.. toctree::
:glob:
:titlesonly:
:reversed:

*
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
======
Page 1
======

Lorem Ipsum Dolor.

Page 1 Level 2
--------------

Page 1 Level 3
~~~~~~~~~~~~~~

Page 1 Level 4
""""""""""""""
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
======
Page 2
======

Lorem Ipsum Dolor.

Page 2 Level 2
--------------

Page 2 Level 3
~~~~~~~~~~~~~~

Page 2 Level 4
""""""""""""""
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!-- content start -->
<div class="section" id="document-title">
<h1>Document Title</h1>

<p>Lorem Ipsum Dolor.</p>

<div class="toc">
<ul class="menu-level">
<li class="toc-item">
<a href="/subfolder2/index.html#subfolder-2-menu-not-reversed">Subfolder 2 Menu not reversed</a>
<ul class="menu-level-1">
<li class="toc-item">
<a href="/subfolder2/subpage1.html#subpage-1">Subpage 1</a>


</li>
<li class="toc-item">
<a href="/subfolder2/subpage2.html#subpage-2">Subpage 2</a>


</li>
</ul>

</li>
<li class="toc-item">
<a href="/subfolder/index.html#subfolder-with-reversed-menu">Subfolder with reversed menu</a>
<ul class="menu-level-1">
<li class="toc-item">
<a href="/subfolder/subpage2.html#subpage-2">Subpage 2</a>


</li>
<li class="toc-item">
<a href="/subfolder/subpage1.html#subpage-1">Subpage 1</a>


</li>
</ul>

</li>
<li class="toc-item">
<a href="/page2.html#page-2">Page 2</a>


</li>
<li class="toc-item">
<a href="/page1.html#page-1">Page 1</a>


</li>
</ul>
</div>
</div>
<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- content start -->
<div class="section" id="subfolder-with-reversed-menu">
<h1>Subfolder with reversed menu</h1>

<p>Lorem Ipsum Dolor.</p>

<dl>
<dt>A Definition List</dt>

<dd>Some definition.</dd>
</dl>
<div class="toc">
<ul class="menu-level">
<li class="toc-item">
<a href="/subfolder/subpage2.html#subpage-2">Subpage 2</a>


</li>
<li class="toc-item">
<a href="/subfolder/subpage1.html#subpage-1">Subpage 1</a>


</li>
</ul>
</div>
</div>
<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!-- content start -->
<div class="section" id="subfolder-2-menu-not-reversed">
<h1>Subfolder 2 Menu not reversed</h1>
<div class="toc">
<ul class="menu-level">
<li class="toc-item">
<a href="/subfolder2/subpage1.html#subpage-1">Subpage 1</a>


</li>
<li class="toc-item">
<a href="/subfolder2/subpage2.html#subpage-2">Subpage 2</a>


</li>
</ul>
</div>
</div>
<!-- content end -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
==============
Document Title
==============

Lorem Ipsum Dolor.


.. toctree::
:glob:
:titlesonly:
:reversed:

page1
page2
subfolder/index
subfolder2/index
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
======
Page 1
======

Lorem Ipsum Dolor.

Page 1 Level 2
--------------

Page 1 Level 3
~~~~~~~~~~~~~~

Page 1 Level 4
""""""""""""""
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
======
Page 2
======

Lorem Ipsum Dolor.

Page 2 Level 2
--------------

Page 2 Level 3
~~~~~~~~~~~~~~

Page 2 Level 4
""""""""""""""
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
============================
Subfolder with reversed menu
============================

Lorem Ipsum Dolor.

A Definition List
Some definition.

.. toctree::
:glob:
:titlesonly:
:reversed:

*
Loading
Loading