Conditional words in the Sphinx

I want to make several versions of the documentation that differ in the sections that are included. For this, I usually used either the only directive or ifconfig . However, I cannot use any of them in combination with the toctree directive.

Basically I want something like this:

.. toctree:: :maxdepth: 2 intro strings datatypes numeric .. only:: university complex 

Is there any way to do this?

+6
source share
4 answers

As far as I know, you cannot do what you want. I struggled with the same problem, see https://github.com/sphinx-doc/sphinx/issues/1717 .

The reason is that Sphinx treats all lines contained in node text as pure text.

I see two alternatives:

  • you can write your own toctree directive;
  • you can extend toctree, including an option that contains an expression to evaluate

     .. toctree: :condition: expression file1 

and then you set up a doctree permission event.

  1. You can use textual substitutions in the source code by defining your own tags. you can do this by implementing an event handler for the source read event. For example, $$condition$$ may contain a condition for evaluation, and $$$ end of the block, i.e.

     .. toctree: file1 $$mycondition$$ file2 $$$ 

Depending on mycondition you can remove the following string lines.

Number 3 is pretty simple, and to me number 2 is the most elegant.

+3
source

My solution is to place the conditional content in a separate "intern" directory and use the "internal" tag.

In conf.py, I added the lines

 if tags.has('internal'): exclude_patters = ['_build'] else: exclude_patterns = ['_build', 'intern*'] 

Now, when I pass the "internal" flag on the command line, I get everything, otherwise everything except the contents in the intern directory.

The internal tag can only be used in combination.

ToC contains links to intern / somedoc, and they are included or skipped as needed. I get a few warnings about missing pages, but they can be disabled.

+1
source

A very simple solution is to maintain two separate index files under different names. You can specify which index file to use by default in conf.py and override it for special builds using -D master_doc=alternate-index on the sphinx-build command line.

+1
source

My previous answer fails if you have a table of contents hierarchy, so I wrote a simple toctree-filt directive that can filter records based on the prefix to the record. For example, given the toctree-filt type

 .. toctree-filt:: :maxdepth: 1 user-manual :internal:supervisor-api :draft:new-feature :erik:erik-maths api 

and setting the exception list to ['draft','erik'] will result in an efficient toctree that looks like

 .. toctree-filt:: :maxdepth: 1 user-manual supervisor-api api 

Add the following lines to conf.py :

 sys.path.append(os.path.abspath('../sphinx-ext/')) extensions = ['toctree_filter'] toc_filter_exclude = ['draft','erik'] 

Put the following code in /sphinx_ext next to your /source directory:

 import re from sphinx.directives.other import TocTree def setup(app): app.add_config_value('toc_filter_exclude', [], 'html') app.add_directive('toctree-filt', TocTreeFilt) return {'version': '1.0.0'} class TocTreeFilt(TocTree): """ Directive to notify Sphinx about the hierarchical structure of the docs, and to include a table-of-contents like tree in the current document. This version filters the entries based on a list of prefixes. We simply filter the content of the directive and call the super version of run. The list of exclusions is stored in the **toc_filter_exclusion** list. Any table of content entry prefixed by one of these strings will be excluded. If `toc_filter_exclusion=['secret','draft']` then all toc entries of the form `:secret:ultra-api` or `:draft:new-features` will be excuded from the final table of contents. Entries without a prefix are always included. """ hasPat = re.compile('^\s*:(.+):(.+)$') # Remove any entries in the content that we dont want and strip # out any filter prefixes that we want but obviously don't want the # prefix to mess up the file name. def filter_entries(self, entries): excl = self.state.document.settings.env.config.toc_filter_exclude filtered = [] for e in entries: m = self.hasPat.match(e) if m != None: if not m.groups()[0] in excl: filtered.append(m.groups()[1]) else: filtered.append(e) return filtered def run(self): # Remove all TOC entries that should not be on display self.content = self.filter_entries(self.content) return super().run() 

Now just change your existing toctree directives to toctree-filt and you have a good ride. Please note that Sphinx will post errors because it will find files that are not included in the document. Not sure how to fix it.

+1
source

All Articles