mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Patch from Stefan Seefeld: make local toctree collapsible.
This commit is contained in:
parent
2d76170b9c
commit
394282223b
@ -164,6 +164,10 @@ class StandaloneHTMLBuilder(Builder):
|
||||
)
|
||||
self.globalcontext.update(self.config.html_context)
|
||||
|
||||
def _get_local_toctree(self, docname):
|
||||
return self.render_partial(self.env.get_toctree_for(
|
||||
docname, self, self.config.html_collapse_toctree))['fragment']
|
||||
|
||||
def get_doc_context(self, docname, body, metatags):
|
||||
"""Collect items for the template context of a page."""
|
||||
# find out relations
|
||||
@ -219,8 +223,6 @@ class StandaloneHTMLBuilder(Builder):
|
||||
metatags = metatags,
|
||||
rellinks = rellinks,
|
||||
sourcename = sourcename,
|
||||
toctree = self.render_partial(self.env.get_toctree_for(
|
||||
docname, self))['fragment'],
|
||||
toc = self.render_partial(self.env.get_toc_for(docname))['fragment'],
|
||||
# only display a TOC if there's more than one item to show
|
||||
display_toc = (self.env.toc_num_entries[docname] > 1),
|
||||
@ -474,6 +476,7 @@ class StandaloneHTMLBuilder(Builder):
|
||||
ctx['pathto'] = pathto
|
||||
ctx['hasdoc'] = lambda name: name in self.env.all_docs
|
||||
ctx['customsidebar'] = self.config.html_sidebars.get(pagename)
|
||||
ctx['toctree'] = self._get_local_toctree(pagename)
|
||||
ctx.update(addctx)
|
||||
|
||||
self.app.emit('html-page-context', pagename, templatename, ctx, event_arg)
|
||||
|
@ -66,6 +66,7 @@ class Config(object):
|
||||
html_use_smartypants = (True, False),
|
||||
html_translator_class = (None, False),
|
||||
html_sidebars = ({}, False),
|
||||
html_collapse_toctree = (False, False),
|
||||
html_additional_pages = ({}, False),
|
||||
html_use_modindex = (True, False),
|
||||
html_add_permalinks = (True, False),
|
||||
|
@ -14,7 +14,7 @@ from docutils.parsers.rst import directives
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.locale import pairindextypes
|
||||
from sphinx.util import patfilter, ws_re, caption_ref_re, docname_join
|
||||
from sphinx.util import patfilter, ws_re, caption_ref_re, url_re, docname_join
|
||||
from sphinx.util.compat import make_admonition
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ def toctree_directive(name, arguments, options, content, lineno,
|
||||
docname = docname[:-len(suffix)]
|
||||
# absolutize filenames
|
||||
docname = docname_join(env.docname, docname)
|
||||
if ref.startswith('http://'): # FIXME: generalize to arbitrary xrefs
|
||||
if url_re.match(ref):
|
||||
entries.append((title, ref))
|
||||
elif docname not in env.found_docs:
|
||||
ret.append(state.document.reporter.warning(
|
||||
|
@ -44,7 +44,7 @@ from docutils.transforms.parts import ContentsFilter
|
||||
|
||||
from sphinx import addnodes
|
||||
from sphinx.util import movefile, get_matching_docs, SEP, ustrftime, \
|
||||
docname_join, FilenameUniqDict
|
||||
docname_join, FilenameUniqDict, url_re
|
||||
from sphinx.directives import additional_xref_types
|
||||
|
||||
default_settings = {
|
||||
@ -830,12 +830,12 @@ class BuildEnvironment:
|
||||
node['refuri'] = node['anchorname']
|
||||
return toc
|
||||
|
||||
def get_toctree_for(self, docname, builder):
|
||||
def get_toctree_for(self, docname, builder, collapse):
|
||||
"""Return the global TOC nodetree."""
|
||||
doctree = self.get_doctree(self.config.master_doc)
|
||||
for toctreenode in doctree.traverse(addnodes.toctree):
|
||||
result = self.resolve_toctree(docname, builder, toctreenode,
|
||||
prune=True)
|
||||
prune=True, collapse=collapse)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
@ -909,7 +909,7 @@ class BuildEnvironment:
|
||||
return doctree
|
||||
|
||||
def resolve_toctree(self, docname, builder, toctree, prune=True, maxdepth=0,
|
||||
titles_only=False):
|
||||
titles_only=False, collapse=False):
|
||||
"""
|
||||
Resolve a *toctree* node into individual bullet lists with titles
|
||||
as items, returning None (if no containing titles are found) or
|
||||
@ -919,6 +919,8 @@ class BuildEnvironment:
|
||||
to the value of the *maxdepth* option on the *toctree* node.
|
||||
If *titles_only* is True, only toplevel document titles will be in the
|
||||
resulting tree.
|
||||
If *collapse* is True, all branches not containing docname will
|
||||
be collapsed.
|
||||
"""
|
||||
if toctree.get('hidden', False):
|
||||
return None
|
||||
@ -935,13 +937,30 @@ class BuildEnvironment:
|
||||
else:
|
||||
_walk_depth(subnode, depth+1, maxdepth)
|
||||
|
||||
# cull sub-entries whose parents aren't 'current'
|
||||
if (collapse and
|
||||
depth > 1 and
|
||||
'current' not in subnode.parent['classes']):
|
||||
subnode.parent.remove(subnode)
|
||||
|
||||
elif isinstance(subnode, nodes.reference):
|
||||
# Identify the toc entry pointing to the current document.
|
||||
if subnode['refuri'] == docname and not subnode['anchorname']:
|
||||
# tag the whole branch as 'current'
|
||||
# (We can't use traverse here as 'ascend' un-intuitively
|
||||
# implies 'siblings'.)
|
||||
p = subnode
|
||||
while p:
|
||||
p['classes'].append('current')
|
||||
p = p.parent
|
||||
|
||||
def _entries_from_toctree(toctreenode, separate=False, subtree=False):
|
||||
"""Return TOC entries for a toctree node."""
|
||||
refs = [(e[0], str(e[1])) for e in toctreenode['entries']]
|
||||
entries = []
|
||||
for (title, ref) in refs:
|
||||
try:
|
||||
if ref.startswith('http://'): # FIXME: (see directives/other.py)
|
||||
if url_re.match(ref):
|
||||
reference = nodes.reference('', '', refuri=ref, anchorname='',
|
||||
*[nodes.Text(title)])
|
||||
para = addnodes.compact_paragraph('', '', reference)
|
||||
@ -1001,11 +1020,13 @@ class BuildEnvironment:
|
||||
|
||||
newnode = addnodes.compact_paragraph('', '', *tocentries)
|
||||
newnode['toctree'] = True
|
||||
|
||||
# prune the tree to maxdepth and replace titles, also set level classes
|
||||
_walk_depth(newnode, 1, prune and maxdepth or 0)
|
||||
|
||||
# set the target paths in the toctrees (they are not known at TOC generation time)
|
||||
for refnode in newnode.traverse(nodes.reference):
|
||||
if not refnode['refuri'].startswith('http://'): # FIXME: see above
|
||||
if not url_re.match(refnode['refuri']):
|
||||
refnode['refuri'] = builder.get_relative_uri(
|
||||
docname, refnode['refuri']) + refnode['anchorname']
|
||||
return newnode
|
||||
|
@ -23,7 +23,7 @@ from os import path
|
||||
# Generally useful regular expressions.
|
||||
ws_re = re.compile(r'\s+')
|
||||
caption_ref_re = re.compile(r'^([^<]+?)\s*<(.+)>$')
|
||||
|
||||
url_re = re.compile(r'(?P<schema>.+)://.*')
|
||||
|
||||
# SEP separates path elements in the canonical file names
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user