How to display sections of the Sphinx root document in the sidebar - python-sphinx

I'm using Sphinx's HTML builder with the Read The Docs theme.
I'm trying to build a technical documentation for a project where each page corresponds to a "component", and each "component" may link to "subcomponents" hierarchically, making the whole documentation recursive:
Component 1
***********
Subcomponents
=============
.. toctree::
component_2
component_3
Section A
=========
Subsection a
^^^^^^^^^^^^
Subsubsection i
~~~~~~~~~~~~~~~
However, Sphinx more or less expects the root document to be a dumb ToC, so it gives me the following sidebar structure:
Component 2
Subcomponents
Section A
Subsection a
Subsubsection i
Component 3
Subcomponents
Section A
Subsection a
Subsubsection i
Instead of the one I'd like:
Subcomponents
Component 2
Subcomponents
Section A
Subsection a
Subsubsection i
Component 3
Subcomponents
Section A
Subsection a
Subsubsection i
Section A
Subsection a
Subsubsection i
Edit: For this MWE, I have used a flat directory structure:
_static
conf.py
component_1.rst # root_doc
component_2.rst
component_3.rst
For completeness' sake, I have also tried a directory structure that matches the logical structure (updating toctree links as required), with the same result:
_static
conf.py
index.rst # component_1, root_doc
component_2
`-index.rst # component_2
component_3
`-index.rst # component_3
So far, I have tried a few workarounds, none of which is entirely satisfying:
Dummy root document
I tried creating a dummy root document containing:
.. toctree::
component_1
This approach has the following drawbacks:
The home page of my documentation is now the equivalent of a sitemap.
The existence of a dummy root document alters the navigation of the documentation (back/forward buttons and top breadcrumbs), so I can't really hide the home page away.
The sidebar structure is still not exactly the one I want:
Component 1
Subcomponents
Component 2
Subcomponents
Section A
Subsection a
Subsubsection i
Component 3
Subcomponents
Section A
Subsection a
Subsubsection i
Section A
Subsection a
Subsubsection i
I can improve things somewhat by running sed on the HTML output to replace all links to the root document (e.g. the link under the project icon) to links to Component 1 and erase the first level of the sidebar hierarchy, but the navigation issues remain.
Hidden toctrees
I tried using hidden toctrees to build the document hierarchy, and inserting the links manually to get the result I wanted.
The manual toctree technique is inspired from the Read The Docs manual itself.
The relative links masquerading as absolute ones is taken from the answer to another StackOverflow question, with a helping of sed to remove the #http:// anchors afterwards.
The root document ends up modified as follows:
Component 1
***********
Subcomponents
=============
.. toctree::
:hidden:
:caption: Subcomponents
component_2
component_3
:doc:`component_2`
:doc:`component_3`
Section A
=========
.. toctree::
:hidden:
:caption: Section A
Subsection a <#subsection-a#http://>
Subsubsection i <#subsubsection-i#http://>
Subsection a
^^^^^^^^^^^^
Subsubsection i
~~~~~~~~~~~~~~~
This approach has the following drawbacks:
I can't reuse the same template for the root document as for the other documents.
The document body looks identical, but as the underlying classes are all different, I'm one bad CSS update away from breaking my root document.
The sidebar structure is not the one I want, either. I can live with the top-level sections (actually the caption of the toctrees) not being clickable, but losing the indentation and the "you are here" highlighting is a dealbreaker:
Subcomponents (not clickable)
Component 2
Subcomponents
Section A
Subsection a
Subsubsection i
Component 3
Subcomponents
Section A
Subsection a
Subsubsection i
Section A (not clickable)
Subsection a
Subsubsection i (not indented)
My question, therefore, is: is there a better workaround to get the result I want, or should I take my chances with a feature request for Sphinx?

Related

Make the heading levels of documents automatically dependent of the depth's levels of the (sub(sub(...)))folders they belong to

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?
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.

Global toctree shared across pages

Lets say I have two .rst files, a welcome page (the index) and an API page. I would like them both to have identical toctrees, so it is easy to navigate from the one page to the other.
index.rst:
Welcome!
========
Welcome to these awesome docs!
api.rst:
API
===
Here is some API stuff...
I tried adding a toctree to index.rst, something like this:
.. toctree::
:hidden:
index
api
However then my toctree gets nested:
I do not only want to add
.. toctree::
:hidden:
api
to index.rst and
.. toctree::
:hidden:
index
to api.rst, since that means that the sidebar is different between pages.
How do I add a global index to my project? One that is the same no matter which page I am on?

Managing Sphinx toctrees combined with inline sections

I'm trying to learn how I can manage a toctree element that is located in the same file as other content.
Suppose I have a thingamajig.rst chapter that looks like this:
Thingamajigs
============
.. toctree::
:maxdepth: 2
foo
bar
baz
Overview
++++++++
Thingamajigs are fun
When I render it --- foo/bar/baz have their own .rst files --- it looks like this:
But if I move the Overview section before the toctree, then it pushes the toctree down into the Overview section:
Thingamajigs
============
Overview
++++++++
Thingamajigs are fun
.. toctree::
:maxdepth: 2
foo
bar
baz
Is there any way to have my toctree after the Overview section, but located under the Thingamajigs section?
Alternatively, can I do something like this?
Thingamajigs
============
.. toctree::
:maxdepth: 2
Overview <-- refers to Overview section in same file
foo
bar
baz
Overview
++++++++
Thingamajigs are fun
The exact specification given in the question can be satisfied, but not without significant issues that require workarounds.
Is there any way to have my toctree after the Overview section, but located under the Thingamajigs section?
By placing a toctree inside the Overview section your are placing all of that toctree's "Entries" (.rst files) inside that section and thus below that level in the section hierarchy.
However, a document must be consistent in its use of section titles: once a hierarchy of title styles is established, sections must use that hierarchy.
Pacing a toctree outside its pretended section will impact 1) "navigation", 2) "numbering" and 3) "depth".
First step of the workaround:
You can declare a toctree with the :hidden: option exactly where you want it -inside the Thingamajigs section- thus having 1), 2) and 3) working as intended. Sphinx will process the entries in the first toctree declaration, so afterwards the toctree declared inside Overview won't affect 1), 2) and 3) because the .rst entries were already processed.
The result:
Corresponding thingamajigs.rst:
Thingamajigs
============
.. toctree::
:hidden:
foo
bar
baz
Overview
++++++++
Thingamajigs are fun
.. toctree::
foo
bar
baz
The above satisfies the problem exactly as it was specified in the question.
(Sphinx will issue warnings because the same .rst file was included in more than one toctree, but they aren't errors just warnings.)
Second step of the workaround:
However, now comes a surprise! If you go one level up, to the .rst containing the toctree that has thingamajigs.rst as an entry, you'll find the :hidden: toctree wasn't rendered, and instead the visible toctree is rendered "in place" (out of order):
The result:
Corresponding level_2_toctree.rst:
***************
Level_2_toctree
***************
.. toctree::
fill_tree1
fill_tree2
fill_tree3
fill_tree4
thingamajigs
Although 1), 2) and 3) are working (in terms of the toctrees retaining their functionality), this leaves us with a problem: fixing the rendering order in parent toctrees. The obvious solution is to repeat the original lower level toctree "as is" inside a bullet list and adding references targeting the sections:
The result:
Corresponding level_2_toctree.rst:
***************
Level_2_toctree
***************
.. toctree::
fill_tree1
fill_tree2
fill_tree3
fill_tree4
.. toctree::
:hidden:
thingamajigs
- :ref:`5.5. Thingamajigs <target_thingamajigs>`
.. toctree::
foo
bar
baz
- :ref:`5.5.4. Item Overview <target>`
.. toctree::
foo2
bar2
Notice you would have to add hyperlink targets to the original thingamajigs.rst.
.. _target_thingamajigs:
Thingamajigs
============
.. toctree::
:hidden:
foo
bar
baz
.. _target:
Overview
++++++++
Thingamajigs are fun
.. toctree::
foo
bar
baz
Third step of the workaround:
But this has another problem, the HTML theme may have different CSS styles for bullet lists and toctrees, both are processed as different HTML elements (examine the source).
One solution would be to wrap the block including the 2 delimiting references in a reST directive (a container) that allows for custom styling as to make the block "blend in" with the remaining toctree. However, you would have to propagate this customizing at every step of ascending the toctree chain.
This does provide a general solution as "proof of concept" for having a "portable toctree" placed out of context. The two main drawbacks are having to manually refactor the hyperlink numbering, and the overhead and expertise required to customizing the CSS.
No more workarounds:
Consider the Sphinx toctree directive and the reStructuredText contents directive are very different. While the whole point of the toctree is chaining .rst files together, the aim of the contents directive is providing a nice table of contents of the .rst file (or the section) it is in.
Try the useful :backlinks: option of the contents directive, by clicking back and forth between the upper index and the corresponding section of its documentation.
"Ideally" the best way to avoid workarounds is using the right tool for the job at hand.
The third option that's a complement to the above two is using a bullet list made of hyperlink targets. It's flexible and allows to mix links both internal and external to the .rst file containing the bullet list. Plus it doesn't interfere with the automatisms of the toctree or the contents directives - which depend on sections. The second step of the workaround includes both of the bullet lists' essential elements.
I'm trying to learn how I can manage a toctree element that is located in the same file as other content.
Looking at toctrees in the official Python documentation one example, or another example you see the "Flat, Simple, Special cases..." from the Zen of Python reflected. Most prominent documentations I've seen chose simple toctree layouts.
Without changing the specified presentation, the most efficient solution is using a bullet list of references to hyperlink targets inside Overview instead of the toctree.
The section headings hierarchy is simply the order as encountered. So your ==== underline sets the title ("H1") and ++++ underline sets the subtitle ("H2") for this page only. Depending what layout you're after...
A. Maybe you wanted a "Table of contents" section as a sibling of the "Overview" section (both within "Thingamajigs" parent), so insert a new H2 section heading:
Thingamajigs
============
Overview
++++++++
Thingamajigs are fun
Table of contents
+++++++++++++++++
.. toctree::
:maxdepth: 2
foo
bar
baz
B. Or maybe you don't want "Overview" in the section headings hierarchy at all, so highlight it by a different means:
Thingamajigs
============
.. admonition:: Overview
Thingamajigs are fun
.. toctree::
:maxdepth: 2
foo
bar
baz
C. Or list the headings hierarchy within this page, separately from external pages:
.. contents:: In this page
:local:
.. beware, that contents directive must appear before any heading hierarchy
Thingamajigs
============
.. toctree::
:maxdepth: 2
:caption: In other pages
foo
bar
baz
D. Or do exactly what your last example showed: move the "Overview" content out to a separate ReST document and include its name in the toctree directive body.
Others have commented about toctree and contents, so I won't repeat them.
You can do a hack with the raw directive.
Thingamajigs
============
.. raw:: html
<h2><span class="section-number">1.1. </span>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
.. Overview
.. ++++++++
Thingamajigs are fun
.. toctree::
:maxdepth: 2
foo
bar
baz
To get the HTML that I used in the raw directive, I started with "Overview" and its underline to generate the HTML. Next I copied it from the generated HTML and pasted it as you see above, indenting it under the raw directive. Finally I commented out "Overview" and its underline. You can season your raw HTML to taste.
Personally, however, I do not see the point of having both a title, immediately followed by an "Overview" or "Introduction" heading, immediately followed by the content of the overview or introduction. I would remove the heading and simply display the desired content. It's obvious what it is, so why does it need a heading?

Set toctree structure one at a time in document, then display full toctree on same document

I want to be able to set toctree documents one at a time in my document, then on the same document redisplay the toctree. Textually, my question is hard to understand, so just refer to my example.
This is my current document called project-structure.rst:
project-structure.rst
This is what the code looks like:
https://pastebin.com/dzWhZwzm
Briefly, this is what I do in the code:
Description of build folder...
.. toctree::
:maxdepth: 3
Description of src folder...
.. toctree::
:maxdepth: 3
Basically, I add 6 documents to the toctree with six toctree statements so I can comment about every document in the toctree.
I want to display the toctree of project-structure.rst at the very bottom of project-structure.rst once again at the bottom without having comments describing each document. Is there a way to do this? I would rather not do links because I still want to be able to show depth levels of the documents.

Adding subsections of self in the toctree

I am having an issue with getting the table of contents (TOC) to display subsections of the front page of my documentation.
I have a number of sections on my front page, and I would like these to be displayed in the TOC. The display of subsection works fine for every other page included in the TOC, but not self.
My index.rst code:
=====
Title
=====
Subsection
----------
Some documentation.
Contents
--------
.. toctree::
:maxdepth: 2
self
development
What I would expect to see in the TOC is this:
Title
Subsection
Contents
Development
Subsection
Instead what I get is this:
Title
Development
Subsection
I have found one solution so far, but it is not really satisfactory. I can put all the content in a separate page, then include the content in index.rst using an .. include: directive, and put the separate page in the TOC. This makes the TOC look right, but creates a duplicate page, which is now included in the navigation (previous/next page).
You could use the TOC directive from reStructuredText directly:
.. contents::
See http://docutils.sourceforge.net/docs/ref/rst/directives.html#table-of-contents
There are several issues with the section layout in the question:
Instead what I get is this:
Title
Development
Subsection
Using self as a toctree entry makes the outermost section title of the containing .rst file be included in that line of the toctree entry. The self entry will not render sub-sections or sibling sections, only the outermost section title. This goes against the usual properties of toctree entries.
Two resulting consequences of the above can immediately be noticed in the example from the question:
title and development are incorrectly rendered as being on the same level in the section hierarchy. When a .rst file is included in a toctree, its sections are placed below in the section hierarchy to the section the toctree directive is declared in.
title will be repeated twice, as being on different levels, if the containing .rst is placed in an exterior toctree.
Corresponding title.rst:
=====
Title
=====
Subsection
----------
Some documentation.
Contents
--------
.. toctree::
:maxdepth: 2
self
development
Corresponding development.rst:
development
===========
some text
Subsection inside development.rst
---------------------------------
Corresponding exterior.rst:
Exterior
========
.. toctree::
:maxdepth: 4
title
It's not a good design choice to aim for a section structure that works against the properties of the toctree directive. From the specification in the question, the simplest and conceptually soundest solution is to use the contents directive to list the sections within one given .rst document.
What I would expect to see in the TOC is this:
Title
Subsection
Contents
Development
Subsection
The easiest choice is using separate files title.rst and development.rst putting them in the same level in the index.rst toctree.
Corresponding index.rst:
Exterior
========
.. toctree::
title
development
To achieve tree of references both internal and external to a given .rst file the best solution is to use a simple bullet list of hyperlink targets.
Corresponding title.rst:
.. _target_title:
=====
Title
=====
.. _target_subsection_title:
Subsection inside title.rst
---------------------------
Some documentation.
.. _target_contents:
Contents
--------
text
- :ref:`Title <target_title>`
- :ref:`Subsection <target_subsection_title>`
- :ref:`Contents <target_contents>`
- :ref:`Development <target_development>`
- :ref:`Subsection <target_subsection_development>`
Corresponding development.rst:
.. _target_development:
development
===========
some text
.. _target_subsection_development:
Subsection inside development.rst
---------------------------------
Corresponding exterior.rst:
Exterior
========
.. toctree::
:maxdepth: 4
title
development
then include the content in index.rst using an .. include: directive
Use of the .. include:: directive would only change the place of the toctree problems without entirely solving them.

Resources