12

Does anyone know any option to order toctree in descending order of the filenames? In case of ascending order, we can use :glob: option like this:

.. toctree:
   :glob:

   2011*

This would be handy for daily notes written in restructured text that should be reported within a Sphinx document.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Philipp der Rautenberg
  • 2,212
  • 3
  • 25
  • 39

3 Answers3

13

There is no simple option to reverse-sort the toctree. But you can do it by modifying the document structure before it is written to file. Here is a suggestion. Add the following code to conf.py:

def reverse_toctree(app, doctree, docname):
    """Reverse the order of entries in the root toctree if 'glob' is used."""
    if docname == "index":
        for node in doctree.traverse():
            if node.tagname == "toctree" and node.get("glob"):
                node["entries"].reverse()
                break

def setup(app):
    app.connect("doctree-resolved", reverse_toctree)

The reverse_toctree() callback function is called when the doctree-resolved event is fired. The function locates the toctree node in the document tree and changes it in-place.

More details about Sphinx and Docutils APIs:

bad_coder
  • 11,289
  • 20
  • 44
  • 72
mzjn
  • 48,958
  • 13
  • 128
  • 248
  • Nice. Wouldn't this reverse every toctree though? You can probably add a check for a `:reversed: parameter to the toctree node to control this behavior, no? – Kevin Horn Dec 24 '11 at 02:18
  • @Kevin Horn: The code reverses the toctree in the "index" (root) document if the :glob: option is used. The OP has not specified any detailed requirements, and I did not intend this answer to be more than a humble suggestion. I am sure that there are many ways to tweak it. Thanks for the comment and the upvote! – mzjn Dec 24 '11 at 11:14
  • 4
    But this doesn't reverse the ToC in the sidebar. – Adobe Nov 16 '12 at 08:22
12

This adds a reversed option to toctree.

from sphinx.directives import TocTree
from docutils.parsers.rst import directives

class NewTocTree(TocTree):
    option_spec = dict(TocTree.option_spec,
                       reversed=directives.flag)

    def run(self):
        rst = super(NewTocTree, self).run()
        if 'reversed' in self.options:
            rst[0][0]['entries'].reverse()
        return rst

def setup(app):
    app.add_directive('toctree', NewTocTree)

Which lets you do:

Contents:

.. toctree::
   :maxdepth: 2
   :reversed:
   :glob:

   20*
bad_coder
  • 11,289
  • 20
  • 44
  • 72
Wraithan
  • 1,237
  • 2
  • 11
  • 14
5

As of Sphinx 1.5+ there is a built-in :reversed: flag you can add to a toctree:

.. toctree::
   :glob:
   :reversed:

   2011*

For more information, see the Sphinx documentation.

brunston
  • 1,244
  • 1
  • 10
  • 18
  • The feature was added in Sphinx 1.5 (1.5a2): http://www.sphinx-doc.org/en/stable/changes.html#id30. – mzjn Jan 30 '18 at 18:38