#460: Allow limiting the depth of section numbers for HTML.

This commit is contained in:
Georg Brandl 2010-08-25 09:59:53 +00:00
parent 8ef21acf9b
commit 2e520e5e7b
5 changed files with 44 additions and 16 deletions

View File

@ -8,6 +8,8 @@ Release 1.1 (in development)
* Added the ``websupport`` library. * Added the ``websupport`` library.
* #460: Allow limiting the depth of section numbers for HTML.
* #443: Allow referencing external graphviz files. * #443: Allow referencing external graphviz files.

View File

@ -41,6 +41,8 @@ tables of contents. The ``toctree`` directive is the central element.
document, the library index. From this information it generates "next document, the library index. From this information it generates "next
chapter", "previous chapter" and "parent chapter" links. chapter", "previous chapter" and "parent chapter" links.
**Entries**
Document titles in the :rst:dir:`toctree` will be automatically read from the Document titles in the :rst:dir:`toctree` will be automatically read from the
title of the referenced document. If that isn't what you want, you can title of the referenced document. If that isn't what you want, you can
specify an explicit title and target using a similar syntax to reST specify an explicit title and target using a similar syntax to reST
@ -59,8 +61,10 @@ tables of contents. The ``toctree`` directive is the central element.
You can also add external links, by giving an HTTP URL instead of a document You can also add external links, by giving an HTTP URL instead of a document
name. name.
**Section numbering**
If you want to have section numbers even in HTML output, give the toctree a If you want to have section numbers even in HTML output, give the toctree a
``numbered`` flag option. For example:: ``numbered`` option. For example::
.. toctree:: .. toctree::
:numbered: :numbered:
@ -71,6 +75,11 @@ tables of contents. The ``toctree`` directive is the central element.
Numbering then starts at the heading of ``foo``. Sub-toctrees are Numbering then starts at the heading of ``foo``. Sub-toctrees are
automatically numbered (don't give the ``numbered`` flag to those). automatically numbered (don't give the ``numbered`` flag to those).
Numbering up to a specific depth is also possible, by giving the depth as a
numeric argument to ``numbered``.
**Additional options**
If you want only the titles of documents in the tree to show up, not other If you want only the titles of documents in the tree to show up, not other
headings of the same level, you can use the ``titlesonly`` option:: headings of the same level, you can use the ``titlesonly`` option::
@ -133,6 +142,9 @@ tables of contents. The ``toctree`` directive is the central element.
.. versionchanged:: 1.0 .. versionchanged:: 1.0
Added "titlesonly" option. Added "titlesonly" option.
.. versionchanged:: 1.1
Added numeric argument to "numbered".
Special names Special names
------------- -------------

View File

@ -20,6 +20,12 @@ from sphinx.util.compat import make_admonition
from sphinx.util.matching import patfilter from sphinx.util.matching import patfilter
def int_or_nothing(argument):
if not argument:
return 999
return int(argument)
class TocTree(Directive): class TocTree(Directive):
""" """
Directive to notify Sphinx about the hierarchical structure of the docs, Directive to notify Sphinx about the hierarchical structure of the docs,
@ -34,7 +40,7 @@ class TocTree(Directive):
'maxdepth': int, 'maxdepth': int,
'glob': directives.flag, 'glob': directives.flag,
'hidden': directives.flag, 'hidden': directives.flag,
'numbered': directives.flag, 'numbered': int_or_nothing,
'titlesonly': directives.flag, 'titlesonly': directives.flag,
} }
@ -98,7 +104,7 @@ class TocTree(Directive):
subnode['maxdepth'] = self.options.get('maxdepth', -1) subnode['maxdepth'] = self.options.get('maxdepth', -1)
subnode['glob'] = glob subnode['glob'] = glob
subnode['hidden'] = 'hidden' in self.options subnode['hidden'] = 'hidden' in self.options
subnode['numbered'] = 'numbered' in self.options subnode['numbered'] = self.options.get('numbered', 0)
subnode['titlesonly'] = 'titlesonly' in self.options subnode['titlesonly'] = 'titlesonly' in self.options
wrappernode = nodes.compound(classes=['toctree-wrapper']) wrappernode = nodes.compound(classes=['toctree-wrapper'])
wrappernode.append(subnode) wrappernode.append(subnode)

View File

@ -1426,46 +1426,54 @@ class BuildEnvironment:
old_secnumbers = self.toc_secnumbers old_secnumbers = self.toc_secnumbers
self.toc_secnumbers = {} self.toc_secnumbers = {}
def _walk_toc(node, secnums, titlenode=None): def _walk_toc(node, secnums, depth, titlenode=None):
# titlenode is the title of the document, it will get assigned a # titlenode is the title of the document, it will get assigned a
# secnumber too, so that it shows up in next/prev/parent rellinks # secnumber too, so that it shows up in next/prev/parent rellinks
for subnode in node.children: for subnode in node.children:
if isinstance(subnode, nodes.bullet_list): if isinstance(subnode, nodes.bullet_list):
numstack.append(0) numstack.append(0)
_walk_toc(subnode, secnums, titlenode) _walk_toc(subnode, secnums, depth-1, titlenode)
numstack.pop() numstack.pop()
titlenode = None titlenode = None
elif isinstance(subnode, nodes.list_item): elif isinstance(subnode, nodes.list_item):
_walk_toc(subnode, secnums, titlenode) _walk_toc(subnode, secnums, depth, titlenode)
titlenode = None titlenode = None
elif isinstance(subnode, addnodes.compact_paragraph): elif isinstance(subnode, addnodes.compact_paragraph):
numstack[-1] += 1 numstack[-1] += 1
if depth > 0:
number = tuple(numstack)
else:
number = None
secnums[subnode[0]['anchorname']] = \ secnums[subnode[0]['anchorname']] = \
subnode[0]['secnumber'] = tuple(numstack) subnode[0]['secnumber'] = number
if titlenode: if titlenode:
titlenode['secnumber'] = tuple(numstack) titlenode['secnumber'] = number
titlenode = None titlenode = None
elif isinstance(subnode, addnodes.toctree): elif isinstance(subnode, addnodes.toctree):
_walk_toctree(subnode) _walk_toctree(subnode, depth)
def _walk_toctree(toctreenode): def _walk_toctree(toctreenode, depth):
if depth == 0:
return
for (title, ref) in toctreenode['entries']: for (title, ref) in toctreenode['entries']:
if url_re.match(ref) or ref == 'self': if url_re.match(ref) or ref == 'self':
# don't mess with those # don't mess with those
continue continue
if ref in self.tocs: if ref in self.tocs:
secnums = self.toc_secnumbers[ref] = {} secnums = self.toc_secnumbers[ref] = {}
_walk_toc(self.tocs[ref], secnums, self.titles.get(ref)) _walk_toc(self.tocs[ref], secnums, depth,
self.titles.get(ref))
if secnums != old_secnumbers.get(ref): if secnums != old_secnumbers.get(ref):
rewrite_needed.append(ref) rewrite_needed.append(ref)
for docname in self.numbered_toctrees: for docname in self.numbered_toctrees:
doctree = self.get_doctree(docname) doctree = self.get_doctree(docname)
for toctreenode in doctree.traverse(addnodes.toctree): for toctreenode in doctree.traverse(addnodes.toctree):
if toctreenode.get('numbered'): depth = toctreenode.get('numbered', 0)
if depth:
# every numbered toctree gets new numbering # every numbered toctree gets new numbering
numstack = [0] numstack = [0]
_walk_toctree(toctreenode) _walk_toctree(toctreenode, depth)
return rewrite_needed return rewrite_needed

View File

@ -180,7 +180,7 @@ class HTMLTranslator(BaseTranslator):
atts['title'] = node['reftitle'] atts['title'] = node['reftitle']
self.body.append(self.starttag(node, 'a', '', **atts)) self.body.append(self.starttag(node, 'a', '', **atts))
if node.hasattr('secnumber'): if node.get('secnumber'):
self.body.append(('%s' + self.secnumber_suffix) % self.body.append(('%s' + self.secnumber_suffix) %
'.'.join(map(str, node['secnumber']))) '.'.join(map(str, node['secnumber'])))
@ -202,14 +202,14 @@ class HTMLTranslator(BaseTranslator):
self.depart_admonition(node) self.depart_admonition(node)
def add_secnumber(self, node): def add_secnumber(self, node):
if node.hasattr('secnumber'): if node.get('secnumber'):
self.body.append('.'.join(map(str, node['secnumber'])) + self.body.append('.'.join(map(str, node['secnumber'])) +
self.secnumber_suffix) self.secnumber_suffix)
elif isinstance(node.parent, nodes.section): elif isinstance(node.parent, nodes.section):
anchorname = '#' + node.parent['ids'][0] anchorname = '#' + node.parent['ids'][0]
if anchorname not in self.builder.secnumbers: if anchorname not in self.builder.secnumbers:
anchorname = '' # try first heading which has no anchor anchorname = '' # try first heading which has no anchor
if anchorname in self.builder.secnumbers: if self.builder.secnumbers.get(anchorname):
numbers = self.builder.secnumbers[anchorname] numbers = self.builder.secnumbers[anchorname]
self.body.append('.'.join(map(str, numbers)) + self.body.append('.'.join(map(str, numbers)) +
self.secnumber_suffix) self.secnumber_suffix)