toctree_filter.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. # Based on https://stackoverflow.com/a/46600038 with some modifications
  2. import re
  3. from sphinx.directives.other import TocTree
  4. def setup(app):
  5. app.add_directive('toctree', TocTreeFilt, override=True)
  6. return {'parallel_read_safe': True, 'parallel_write_safe': True, 'version': '0.1'}
  7. class TocTreeFilt(TocTree):
  8. """
  9. Override normal toctree directive to support clauses of the kind
  10. :filter: Name <link>
  11. Where the :filter: part becomes selective to only include the document if
  12. one of the provided tags is set, same as the logic used by the "only" directive.
  13. If no :filter: is supplied, works the same as default Sphinx :toctree:
  14. Note that excluding via filter doesn't prevent Sphinx from finding these .rst files
  15. when it scan the src/ directory, so it's also necessary to make sure that the files
  16. are covered by the exclude_patterns list in conf.py
  17. """
  18. RE_PATTERN = re.compile(r'^\s*:(.+?):\s*(.+)$')
  19. def run(self):
  20. # Remove all TOC entries that should not be on display
  21. env = self.state.document.settings.env
  22. self.content = [self.filter_entry(env, e) for e in self.content if e is not None]
  23. return super(TocTreeFilt, self).run()
  24. def filter_entry(self, env, entry):
  25. m = self.RE_PATTERN.match(entry)
  26. if m is not None:
  27. tag_filter, entry = m.groups()
  28. if not env.app.builder.tags.eval_condition(tag_filter):
  29. return None
  30. return entry