From 4ea6abb8f41511dc4e78967713a42d82ce5f3328 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Thu, 25 Feb 2016 04:42:26 -0500 Subject: [PATCH] Allow explicit markup in toctree directives This adds support for :ref:`` text in toctree listings in particular, but is reasonably generic. My website, for example, now contains something like .. toctree:: _ :ref:`foo ` baz which renders as one might expect. --- sphinx/directives/other.py | 17 +++++++++++++++-- sphinx/environment.py | 12 +++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 51294570ce8..dee958e7c27 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -13,6 +13,7 @@ from docutils.parsers.rst.directives.admonitions import BaseAdmonition from docutils.parsers.rst.directives.misc import Class from docutils.parsers.rst.directives.misc import Include as BaseInclude +from docutils.statemachine import ViewList from sphinx import addnodes from sphinx.locale import versionlabels, _ @@ -57,8 +58,14 @@ def run(self): self.options.setdefault('name', nodes.fully_normalize_name(caption)) ret = [] + # Children of the internal toctree node; these will be rewritten by + # traversals (and so having other references into these will also + # get rewritten) but, nicely, are not rendered directly due to the + # way that the environment code deals with toctrees. + others = [] # (title, ref) pairs, where ref may be a document, or an external link, - # and title may be None if the document's title is to be used + # or a node. title may be None if the document's title is to be used + # and must be None if a node is given as a ref. entries = [] includefiles = [] all_docnames = env.found_docs.copy() @@ -67,7 +74,12 @@ def run(self): for entry in self.content: if not entry: continue - if glob and ('*' in entry or '?' in entry or '[' in entry): + if entry.startswith("_ "): + node = nodes.paragraph() + self.state.nested_parse(ViewList([entry[2:]]), 0, node) + others.append(node) + entries.append((None, node)) + elif glob and ('*' in entry or '?' in entry or '[' in entry): patname = docname_join(env.docname, entry) docnames = sorted(patfilter(all_docnames, patname)) for docname in docnames: @@ -119,6 +131,7 @@ def run(self): subnode['includehidden'] = 'includehidden' in self.options subnode['numbered'] = self.options.get('numbered', 0) subnode['titlesonly'] = 'titlesonly' in self.options + subnode.children = others set_source_info(self, subnode) wrappernode = nodes.compound(classes=['toctree-wrapper']) wrappernode.append(subnode) diff --git a/sphinx/environment.py b/sphinx/environment.py index b8b40b8e65c..d05b5b24c1b 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -1355,7 +1355,14 @@ def _entries_from_toctree(toctreenode, parents, for (title, ref) in refs: try: refdoc = None - if url_re.match(ref): + if isinstance(ref, nodes.Node): + # Strip off the outer paragraph and stuff its + # children into a compact one here. + para = addnodes.compact_paragraph('', '') + para.children = ref.children[0].children + item = nodes.list_item('', para) + toc = nodes.bullet_list('', item) + elif url_re.match(ref): if title is None: title = ref reference = nodes.reference('', '', internal=False, @@ -1466,6 +1473,9 @@ def _entries_from_toctree(toctreenode, parents, # set the target paths in the toctrees (they are not known at TOC # generation time) for refnode in newnode.traverse(nodes.reference): + if 'anchorname' not in refnode: + # This one is already resolved; just leave it be + continue if not url_re.match(refnode['refuri']): refnode['refuri'] = builder.get_relative_uri( docname, refnode['refuri']) + refnode['anchorname']