2

Suppose I have:

  • a foo0.rst file at the root (source) of my sphinx-doc source folder,
  • a foo1.rst file in a subfolder subfolder1 of source,
  • a foo2.rst file in a subfolder subfolder2 of subfolder1,

that is:

$ tree source
source
├── foo0.rst
└── subfolder1
    ├── foo1.rst
    └── subfolder2
        └── foo2.rst

all with the same content:

This a title
============

Now, if the index.rst contains:

Welcome to Test's documentation!
================================

.. toctree::
   :maxdepth: 3
   :caption: Contents:

   foo0
   subfolder1/foo1
   subfolder1/subfolder2/foo2

make html gives:

Welcome to Test’s documentation!

Contents:

    • This a title
    • This a title
    • This a title

that is all the headings are sections.

What I would like to get instead is the following:

Welcome to Test’s documentation!

Contents:

    • This a title
      ◦ This a title
        ▪ This a title

that is the heading of:

  • foo0.rst being a section,
  • subfolder1/foo1.rst being a subsection (and not a section),
  • subfolder1/subfolder2/foo2.rst being a subsubsection (and not a section).

My question is therefore: is it possible to make the heading levels of documents belonging to (sub(sub(...)))folders automatically depend on the depth's levels of the folders they belong to?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Denis Bitouzé
  • 520
  • 6
  • 18
  • My answer was writing thinking about generating HTML output not LaTeX...I don't know how Sphinx translates the toctree to LaTeX. But if the toctree gives you too much trouble the easiest solution is still building a reST bullet list with links and cross-references where you structure the levels exactly as you want. – bad_coder Dec 04 '20 at 14:20
  • 1
    No, there is not. – Steve Piercy Dec 05 '20 at 04:57

1 Answers1

3

The style applied to the toctree entries is dependent on the theme you are using. The theme's CSS will apply a style to the entries that Sphinx translated into <ul> and <li> depending both on their place within the "document hierarchy" given how you chain the toctrees and how your section structure in the individual .rst files is organized.

For example, inspect the HTML elements Sphinx generates. The toctree will be a div class="toctree-wrapper compound" with each level of sections being named <li class="toctree-l1"> then <li class="toctree-l2">, etc...

One way to achieve what you want would be to surround a given toctree using a .. class:: directive (as show here) and apply a custom style. But that would then impact the style of any other .rst files you want to include as entries in that toctree.

In any case, you will incur in extra work and potentially loose automatism if you refactor your project.

There is also one possible workaround, using the :hidden: option together with the :include: directive. If you declare a hidden toctree before a visible toctree the "document hierarchy" can fix the position of an entry for you in the hierarchy. Afterwards the visible toctree without the :hidden: option will render .rst file entries as a <li> element having a fixed position in the hierarchy. (A thorough example can be seen in this post).

It can be done, but you will be working against the characteristics of the toctree.

The prevalent solution is writing your .rst files and sections depending on how you want the toctree to display. (This approach has all the advantages with the only drawback of putting restrictions on how you write the .rst files). It's probably the preferable solution rather than trying to adapt the CSS styles or using workarounds.


EDIT:

What I wrote before is valid, but probably too general. So I'll give one possible solution to the example. If you want the following:

Contents:

    • This a title (foo0)
      ◦ This a title (foo1)
        ▪ This a title (foo2)

A simple option is using a chain of toctrees. You can hide the toctree's that are lower in the document hierarchy if you don't want to see them.

index.rst

.. toctree::
   :maxdepth: 3

   foo0

and in foo0.rst

.. toctree::
   :maxdepth: 3
   :hidden:

   subfolder1/foo1

and in subfolder1/foo1.rst

.. toctree::
   :maxdepth: 3
   :hidden:

   subfolder1/subfolder2/foo2

The result will be as you specified.

bad_coder
  • 11,289
  • 20
  • 44
  • 72
  • The trouble, at least with the second solution, is I have about a thousand files that are currently included in the main `index.rst` file. So I would have to edit all of them to write the `toctree` directive and the path of the right subfile to include: rather impossible. – Denis Bitouzé Dec 04 '20 at 16:33
  • 1
    The `toctree` directive is meant to list `.rst` files and sections (only!) Your aim is to expand functionality so that for every directory level an implicit section level be *"somehow"* included. The `toctree` directive doesn't have that functionality. There are a couple of *"relatively low-effort"* ways to achieve the result you want, but they still require extra work and will become a constraint of the overall organization of your project. There is no magic solution for this that avoids drawbacks, adds constraints, and requires extra work. I have to ask: Why not write extra `.rst` files? – bad_coder Dec 04 '20 at 22:24
  • @DenisBitouzé are [the underlines](https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#sections) of the reST sections in the subdirectories all the same? Or did you use different underlines as the directories went into deeper levels? – bad_coder Dec 05 '20 at 06:57
  • Sorry but I don't see the point of the "extra `.rst` files": do you mean extra "root" files in each directory? About the underlines, they are all the same. My use case is a `DokuWiki` site I'd like to export as a `Sphinx-doc` one, the `DokuWiki `source files being exported thanks to `pandoc` – Denis Bitouzé Dec 05 '20 at 10:11
  • This is an interessting use case I hadn't seen before, just to confirm you export `DocuWiki` -> `Pandoc` -> `reStructuredText` using the converters [in this list](https://github.com/jgm/pandoc). That's why you end up with lots of `.rst` files... Afterwards the final step is generating `reStructuredText` -> `Sphinx` -> [one of the several output formats in this list](https://www.sphinx-doc.org/en/master/usage/builders/index.html)? – bad_coder Dec 05 '20 at 10:29
  • 1
    @DenisBitouzé There are several possible solutions for this problem. The easiest would be 1 `.rst` per directory using a toctree with a glob pattern [one example](https://stackoverflow.com/a/51955585) and [another example](https://stackoverflow.com/a/28774689) and chaining those toctrees up to the one in `index.rst`. The documentation doesn't say if Sphinx would recognize a [recursion glob](https://stackoverflow.com/a/14798263), I tried looking at [the source code](https://github.com/sphinx-doc/sphinx/blob/3.x/sphinx/directives/other.py#L42) but can't figure it out (I'd have to test it). – bad_coder Dec 05 '20 at 11:04
  • 1
    @DenisBitouzé another solution -because `pandoc` gives you a toctree with a full list of the `.rst` files- is to write a simple `for` loop (in whatever language) where you convert that list of paths from a `.txt` to a nested [reStructuredText bullet list](https://docutils.sourceforge.io/docs/ref/rst/restructuredtext.html#bullet-lists) with a [document reference](https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#role-doc) to each file. Then use the `:hidden:` option in the toctree and simply copy-past the nested bullet-list of references. – bad_coder Dec 05 '20 at 11:20
  • Indeed, the route I'm using is `DocuWiki` → `Pandoc` → `reStructuredText`. The final step is `reStructuredText` → `Sphinx` → `html`. – Denis Bitouzé Dec 05 '20 at 11:22
  • 1
    @DenisBitouzé The above solutions are relativly easy and low-effort. The best solution depends on your aim. Do you simply want an export/migration of the existing wiki without development/refactoring happening in the future? (Sphinx has many applications, the usual is to document a code project under development.) Deciding the best course of action depends on what application you'll be using the Sphinx project for, and where you'll deploy the docs. (For example, on ReadTheDocs the toctree is tied to the sidebar so you'd want to make an effort to conserve it.) – bad_coder Dec 05 '20 at 11:34
  • 1
    I'll have a deeper look at these solutions later (too busy right now): thanks! At some point, the `DokuWiki` site should be migrated and closed so no development/refactoring would happen in the future. This site is a LaTeX FAQ and should be deployed on GitLab pages. – Denis Bitouzé Dec 05 '20 at 13:39
  • I guess at the end of your answer, `subfolder1/subfolder2/foo2` should be `subfolder2/foo2`. – Denis Bitouzé Dec 17 '20 at 15:11
  • @DenisBitouzé ["This directive inserts a “TOC tree” at the current location, using the individual TOCs (including “sub-TOC trees”) of the documents given in the directive body. Relative document names (not beginning with a slash) are relative to the document the directive occurs in, absolute names are relative to the source directory. (...)"](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-toctree) I'll have to think about it later and possibly revise the detail, right now I can't spare the attention. Thank you for the warning. – bad_coder Dec 17 '20 at 15:20
  • About "convert that list of paths from a .txt to a nested `reStructuredText` bullet list with a document reference to each file", do you mean a bullet list as nested as the file in the corresponding path? – Denis Bitouzé Dec 17 '20 at 15:28
  • 1
    @DenisBitouzé yes that is exactly what I mean. The nested bullet list solution has the advantage of being easy to implement programmatically if you are generating from a fixed (and very large but complete) list of links. (N could be in the thousands, so solving it with 1 `for` cycle might not be elegant/minimalistic, but it gets the job done easily.) – bad_coder Dec 17 '20 at 15:32
  • The trouble with this conversion into a nested `rst` bullet list with a document reference to each file is that the table of contents is empty. – Denis Bitouzé Dec 17 '20 at 16:01
  • @DenisBitouzé there are 2 directives sometimes called *"table of contents"*, one is the `toctree` the other is the [reST TOC](https://docutils.sourceforge.io/docs/ref/rst/directives.html#table-of-contents). By constructing the bullet list, it becomes the "table of contents" (there wouldn't be much sense to having 2 TOC's). So exactly what TOC do you mean in what context? – bad_coder Dec 17 '20 at 16:21
  • I mean the ToC in the sidebar. – Denis Bitouzé Dec 17 '20 at 16:27
  • 1
    @DenisBitouzé as I had said, the ToC in the sidebar is connected programmatically to the `toctree` (but not all themes use a ToC in the sidebar, and you hadn't specified if you wanted it). In that case using the solution that preserves the toctrees should be followed. – bad_coder Dec 17 '20 at 17:15