mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Added a toctree variable to the templates, and the ability to
include external links in toctrees. Patch by Stefan Seefeld.
This commit is contained in:
parent
62222ca5a1
commit
e974741c74
1
AUTHORS
1
AUTHORS
@ -12,6 +12,7 @@ Other contributors, listed alphabetically, are:
|
||||
* Dave Kuhlman -- original LaTeX writer
|
||||
* Thomas Lamb -- linkcheck builder
|
||||
* Benjamin Peterson -- unittests
|
||||
* Stefan Seefeld -- toctree improvements
|
||||
* Antonio Valentino -- qthelp builder
|
||||
* Pauli Virtanen -- autodoc improvements
|
||||
* Sebastian Wiesner -- image handling, distutils support
|
||||
|
3
CHANGES
3
CHANGES
@ -49,6 +49,9 @@ New features added
|
||||
- #23: Added a ``classmethod`` directive along with ``method``
|
||||
and ``staticmethod``.
|
||||
|
||||
- Added a toctree variable to the templates, and the ability to
|
||||
include external links in toctrees.
|
||||
|
||||
* Configuration:
|
||||
|
||||
- The new ``html_add_permalinks`` config value can be used to
|
||||
|
@ -71,6 +71,9 @@ tables of contents. The ``toctree`` directive is the central element.
|
||||
The second line above will link to the ``strings`` document, but will use the
|
||||
title "All about strings" instead of the title of the ``strings`` document.
|
||||
|
||||
You can also add external links, by giving an HTTP URL instead of a document
|
||||
name.
|
||||
|
||||
You can use "globbing" in toctree directives, by giving the ``glob`` flag
|
||||
option. All entries are then matched against the list of available
|
||||
documents, and matches are inserted into the list alphabetically. Example::
|
||||
@ -113,7 +116,7 @@ tables of contents. The ``toctree`` directive is the central element.
|
||||
Added "globbing" option.
|
||||
|
||||
.. versionchanged:: 0.6
|
||||
Added "hidden" option.
|
||||
Added "hidden" option and external links.
|
||||
|
||||
|
||||
Special names
|
||||
|
@ -221,8 +221,12 @@ in the future.
|
||||
|
||||
.. data:: builder
|
||||
|
||||
The name of the builder (for builtin builders, ``html``, ``htmlhelp``, or
|
||||
``web``).
|
||||
The name of the builder (e.g. ``html`` or ``htmlhelp``).
|
||||
|
||||
.. data:: embedded
|
||||
|
||||
True if the built HTML is supposed to be embedded in some application that
|
||||
handles navigation, e.g. HTML Help or Qt Help.
|
||||
|
||||
.. data:: next
|
||||
|
||||
@ -239,3 +243,18 @@ in the future.
|
||||
.. data:: prev
|
||||
|
||||
Like :data:`next`, but for the previous page.
|
||||
|
||||
|
||||
In documents that are created from source files (as opposed to
|
||||
automatically-generated files like the module index, or documents that already
|
||||
are in HTML form), these variables are also available:
|
||||
|
||||
.. data:: toc
|
||||
|
||||
The local table of contents for the current page, rendered as HTML bullet
|
||||
lists.
|
||||
|
||||
.. data:: toctree
|
||||
|
||||
The global TOC tree containing the current page, rendered as HTML bullet
|
||||
lists.
|
||||
|
@ -219,6 +219,8 @@ 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),
|
||||
|
@ -27,6 +27,9 @@ def toctree_directive(name, arguments, options, content, lineno,
|
||||
glob = 'glob' in options
|
||||
|
||||
ret = []
|
||||
# (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
|
||||
entries = []
|
||||
includefiles = []
|
||||
includetitles = {}
|
||||
all_docnames = env.found_docs.copy()
|
||||
@ -39,33 +42,39 @@ def toctree_directive(name, arguments, options, content, lineno,
|
||||
# look for explicit titles and documents ("Some Title <document>").
|
||||
m = caption_ref_re.match(entry)
|
||||
if m:
|
||||
docname = m.group(2)
|
||||
includetitles[docname] = m.group(1)
|
||||
ref = m.group(2)
|
||||
title = m.group(1)
|
||||
docname = ref
|
||||
else:
|
||||
docname = entry
|
||||
ref = docname = entry
|
||||
title = None
|
||||
# remove suffixes (backwards compatibility)
|
||||
if docname.endswith(suffix):
|
||||
docname = docname[:-len(suffix)]
|
||||
# absolutize filenames
|
||||
docname = docname_join(env.docname, docname)
|
||||
if docname not in env.found_docs:
|
||||
if ref.startswith('http://'): # FIXME: generalize to arbitrary xrefs
|
||||
entries.append((title, ref))
|
||||
elif docname not in env.found_docs:
|
||||
ret.append(state.document.reporter.warning(
|
||||
'toctree references unknown document %r' % docname, line=lineno))
|
||||
else:
|
||||
entries.append((title, ref))
|
||||
includefiles.append(docname)
|
||||
else:
|
||||
patname = docname_join(env.docname, entry)
|
||||
docnames = sorted(patfilter(all_docnames, patname))
|
||||
for docname in docnames:
|
||||
all_docnames.remove(docname) # don't include it again
|
||||
entries.append((None, docname))
|
||||
includefiles.append(docname)
|
||||
if not docnames:
|
||||
ret.append(state.document.reporter.warning(
|
||||
'toctree glob pattern %r didn\'t match any documents' % entry,
|
||||
line=lineno))
|
||||
subnode = addnodes.toctree()
|
||||
subnode['entries'] = entries
|
||||
subnode['includefiles'] = includefiles
|
||||
subnode['includetitles'] = includetitles
|
||||
subnode['maxdepth'] = options.get('maxdepth', -1)
|
||||
subnode['glob'] = glob
|
||||
subnode['hidden'] = 'hidden' in options
|
||||
|
@ -828,6 +828,17 @@ class BuildEnvironment:
|
||||
node['refuri'] = node['anchorname']
|
||||
return toc
|
||||
|
||||
def get_toctree_for(self, docname, builder):
|
||||
"""Return the global TOC nodetree."""
|
||||
|
||||
# XXX why master_doc?
|
||||
doctree = self.get_doctree(self.config.master_doc)
|
||||
for toctreenode in doctree.traverse(addnodes.toctree):
|
||||
result = self.resolve_toctree(docname, builder, toctreenode,
|
||||
prune=True)
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
# -------
|
||||
# these are called from docutils directives and therefore use self.docname
|
||||
#
|
||||
@ -912,35 +923,46 @@ class BuildEnvironment:
|
||||
if toctree.get('hidden', False):
|
||||
return None
|
||||
|
||||
def _walk_depth(node, depth, maxdepth, titleoverrides):
|
||||
def _walk_depth(node, depth, maxdepth):
|
||||
"""Utility: Cut a TOC at a specified depth."""
|
||||
for subnode in node.children[:]:
|
||||
if isinstance(subnode, (addnodes.compact_paragraph, nodes.list_item)):
|
||||
subnode['classes'].append('toctree-l%d' % (depth-1))
|
||||
_walk_depth(subnode, depth, maxdepth, titleoverrides)
|
||||
_walk_depth(subnode, depth, maxdepth)
|
||||
elif isinstance(subnode, nodes.bullet_list):
|
||||
if maxdepth > 0 and depth > maxdepth:
|
||||
subnode.parent.replace(subnode, [])
|
||||
else:
|
||||
_walk_depth(subnode, depth+1, maxdepth, titleoverrides)
|
||||
_walk_depth(subnode, depth+1, maxdepth)
|
||||
|
||||
def _entries_from_toctree(toctreenode, separate=False, subtree=False):
|
||||
"""Return TOC entries for a toctree node."""
|
||||
includefiles = map(str, toctreenode['includefiles'])
|
||||
|
||||
refs = [(e[0], str(e[1])) for e in toctreenode['entries']]
|
||||
entries = []
|
||||
for includefile in includefiles:
|
||||
for (title, ref) in refs:
|
||||
try:
|
||||
toc = self.tocs[includefile].deepcopy()
|
||||
if ref.startswith('http://'): # FIXME: (see directives/other.py)
|
||||
reference = nodes.reference('', '', refuri=ref, anchorname='',
|
||||
*[nodes.Text(title)])
|
||||
para = addnodes.compact_paragraph('', '', reference)
|
||||
item = nodes.list_item('', para)
|
||||
toc = nodes.bullet_list('', item)
|
||||
else:
|
||||
toc = self.tocs[ref].deepcopy()
|
||||
if title and toc.children and len(toc.children) == 1:
|
||||
for refnode in toc.children[0].traverse(nodes.reference):
|
||||
if refnode['refuri'] == ref and not refnode['anchorname']:
|
||||
refnode.children = [nodes.Text(title)]
|
||||
if not toc.children:
|
||||
# empty toc means: no titles will show up in the toctree
|
||||
self.warn(docname, 'toctree contains reference to document '
|
||||
'%r that doesn\'t have a title: no link will be '
|
||||
'generated' % includefile)
|
||||
'generated' % ref)
|
||||
|
||||
except KeyError:
|
||||
# this is raised if the included file does not exist
|
||||
self.warn(docname, 'toctree contains reference to nonexisting '
|
||||
'document %r' % includefile)
|
||||
'document %r' % ref)
|
||||
else:
|
||||
# if titles_only is given, only keep the main title and
|
||||
# sub-toctrees
|
||||
@ -969,7 +991,6 @@ class BuildEnvironment:
|
||||
return entries
|
||||
|
||||
maxdepth = maxdepth or toctree.get('maxdepth', -1)
|
||||
titleoverrides = toctree.get('includetitles', {})
|
||||
|
||||
# NOTE: previously, this was separate=True, but that leads to artificial
|
||||
# separation when two or more toctree entries form a logical unit, so
|
||||
@ -981,14 +1002,9 @@ 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, titleoverrides)
|
||||
# replace titles, if needed, and set the target paths in the
|
||||
# toctrees (they are not known at TOC generation time)
|
||||
_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 titleoverrides and not refnode['anchorname'] \
|
||||
and refnode['refuri'] in titleoverrides:
|
||||
newtitle = titleoverrides[refnode['refuri']]
|
||||
refnode.children = [nodes.Text(newtitle)]
|
||||
refnode['refuri'] = builder.get_relative_uri(
|
||||
docname, refnode['refuri']) + refnode['anchorname']
|
||||
return newnode
|
||||
|
Loading…
Reference in New Issue
Block a user