diff options
-rw-r--r-- | sphinx/builders/html.py | 1 | ||||
-rw-r--r-- | sphinx/builders/websupport.py | 1 | ||||
-rw-r--r-- | sphinx/environment.py | 66 | ||||
-rw-r--r-- | sphinx/transforms.py | 23 | ||||
-rw-r--r-- | sphinx/writers/html.py | 10 |
5 files changed, 97 insertions, 4 deletions
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index c2c308937..d4bbefe49 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -424,6 +424,7 @@ class StandaloneHTMLBuilder(Builder): doctree.settings = self.docsettings self.secnumbers = self.env.toc_secnumbers.get(docname, {}) + self.fignumbers = self.env.toc_fignumbers.get(docname, {}) self.imgpath = relative_uri(self.get_target_uri(docname), '_images') self.dlpath = relative_uri(self.get_target_uri(docname), '_downloads') self.current_docname = docname diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py index 7b0e6f724..ed913945c 100644 --- a/sphinx/builders/websupport.py +++ b/sphinx/builders/websupport.py @@ -58,6 +58,7 @@ class WebSupportBuilder(PickleHTMLBuilder): doctree.settings = self.docsettings self.secnumbers = self.env.toc_secnumbers.get(docname, {}) + self.fignumbers = self.env.toc_fignumbers.get(docname, {}) self.imgpath = '/' + posixpath.join(self.virtual_staticdir, '_images') self.dlpath = '/' + posixpath.join(self.virtual_staticdir, '_downloads') self.current_docname = docname diff --git a/sphinx/environment.py b/sphinx/environment.py index 1ce284f64..84149718e 100644 --- a/sphinx/environment.py +++ b/sphinx/environment.py @@ -48,7 +48,7 @@ from sphinx.errors import SphinxError, ExtensionError from sphinx.locale import _ from sphinx.versioning import add_uids, merge_doctrees from sphinx.transforms import DefaultSubstitutions, MoveModuleTargets, \ - HandleCodeBlocks, SortIds, CitationReferences, Locale, \ + HandleCodeBlocks, AutoNumbering, SortIds, CitationReferences, Locale, \ RemoveTranslatableInline, SphinxContentsFilter @@ -98,7 +98,7 @@ class SphinxStandaloneReader(standalone.Reader): Add our own transforms. """ transforms = [Locale, CitationReferences, DefaultSubstitutions, - MoveModuleTargets, HandleCodeBlocks, SortIds, + MoveModuleTargets, HandleCodeBlocks, AutoNumbering, SortIds, RemoveTranslatableInline] def get_transforms(self): @@ -234,6 +234,7 @@ class BuildEnvironment: # used to determine when to show the TOC # in a sidebar (don't show if it's only one item) self.toc_secnumbers = {} # docname -> dict of sectionid -> number + self.toc_fignumbers = {} # docname -> dict of figureid -> number self.toctree_includes = {} # docname -> list of toctree includefiles self.files_to_rebuild = {} # docname -> set of files @@ -635,8 +636,8 @@ class BuildEnvironment: self._warnfunc(*warning) def check_dependents(self, already): - to_rewrite = self.assign_section_numbers() - for docname in to_rewrite: + to_rewrite = self.assign_section_numbers() + self.assign_figure_numbers() + for docname in set(to_rewrite): if docname not in already: yield docname @@ -1693,6 +1694,63 @@ class BuildEnvironment: return rewrite_needed + def assign_figure_numbers(self): + """Assign a figure number to each figure under a numbered toctree.""" + + rewrite_needed = [] + + old_fignumbers = self.toc_fignumbers + self.toc_fignumbers = {} + fignum_counter = {} + + def get_section_number(docname, section): + anchorname = '#' + section['ids'][0] + secnumbers = self.toc_secnumbers.get(docname, {}) + if anchorname in secnumbers: + secnum = secnumbers.get(anchorname) + else: + secnum = secnumbers.get('') + + return secnum or tuple() + + def get_next_figure_number(secnum): + secnum = secnum[:1] + fignum_counter[secnum] = fignum_counter.get(secnum, 0) + 1 + return secnum + (fignum_counter[secnum],) + + def _walk_doctree(docname, doctree, secnum): + fignums = self.toc_fignumbers.setdefault(docname, {}) + for subnode in doctree.children: + if isinstance(subnode, nodes.section): + next_secnum = get_section_number(docname, subnode) + if next_secnum: + _walk_doctree(docname, subnode, next_secnum) + else: + _walk_doctree(docname, subnode, secnum) + continue + elif isinstance(subnode, addnodes.toctree): + for title, subdocname in subnode['entries']: + _walk_doc(subdocname, secnum) + + continue + + if isinstance(subnode, nodes.figure): + figure_id = subnode['ids'][0] + fignums[figure_id] = get_next_figure_number(secnum) + + _walk_doctree(docname, subnode, secnum) + + def _walk_doc(docname, secnum): + doctree = self.get_doctree(docname) + _walk_doctree(docname, doctree, secnum) + + _walk_doc(self.config.master_doc, tuple()) + for docname, fignums in iteritems(self.toc_fignumbers): + if fignums != old_fignumbers.get(docname): + rewrite_needed.append(docname) + + return rewrite_needed + def create_index(self, builder, group_entries=True, _fixre=re.compile(r'(.*) ([(][^()]*[)])')): """Create the real index from the collected index entries.""" diff --git a/sphinx/transforms.py b/sphinx/transforms.py index 42abea588..e4806092f 100644 --- a/sphinx/transforms.py +++ b/sphinx/transforms.py @@ -101,6 +101,29 @@ class HandleCodeBlocks(Transform): # del node.parent[parindex+1] +class AutoNumbering(Transform): + """ + Register IDs of tables, figures and literal_blocks to assign numbers. + """ + default_priority = 210 + + def apply(self): + def has_child(node, cls): + for child in node: + if isinstance(child, cls): + return True + + return False + + for node in self.document.traverse(nodes.Element): + if isinstance(node, nodes.figure): + if has_child(node, nodes.caption): + self.document.note_implicit_target(node) + elif isinstance(node, nodes.image): + if has_child(node.parent, nodes.caption): + self.document.note_implicit_target(node.parent) + + class SortIds(Transform): """ Sort secion IDs so that the "id[0-9]+" one comes last. diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 56657ee72..dea591922 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -250,6 +250,15 @@ class HTMLTranslator(BaseTranslator): self.body.append('.'.join(map(str, numbers)) + self.secnumber_suffix) + def add_fignumber(self, node): + if node.get('fignumber'): + self.body.append('Fig.' + '.'.join(map(str, node['fignumber']))) + elif isinstance(node.parent, nodes.figure): + figure_id = node.parent['ids'][0] + if self.builder.fignumbers.get(figure_id): + numbers = self.builder.fignumbers[figure_id] + self.body.append('Fig.' + '.'.join(map(str, numbers))) + # overwritten to avoid emitting empty <ul></ul> def visit_bullet_list(self, node): if len(node) == 1 and node[0].tagname == 'toctree': @@ -291,6 +300,7 @@ class HTMLTranslator(BaseTranslator): self.body.append(self.starttag(node, 'div', '', CLASS='code-block-caption')) else: BaseTranslator.visit_caption(self, node) + self.add_fignumber(node) def depart_caption(self, node): if isinstance(node.parent, nodes.container) and node.parent.get('literal_block'): |