Commits

Takayuki Shimizukawa committed 0de9fa0 Merge

Merged in tk0miya/sphinx (pull request #268)

Fix numbering section does not work at singlehtml mode (adhoc)

Comments (0)

Files changed (6)

sphinx/builders/html.py

         self.fix_refuris(tree)
         return tree
 
+    def assemble_toc_secnumbers(self):
+        # Assemble toc_secnumbers to resolve section numbers on SingleHTML.
+        # Merge all secnumbers to single secnumber.
+        #
+        # Note: current Sphinx has refid confliction in singlehtml mode.
+        #       To avoid the problem, it replaces key of secnumbers to
+        #       tuple of docname and refid.
+        #
+        #       There are related codes in inline_all_toctres() and
+        #       HTMLTranslter#add_secnumber().
+        new_secnumbers = {}
+        for docname, secnums in iteritems(self.env.toc_secnumbers):
+            for id, secnum in iteritems(secnums):
+                new_secnumbers[(docname, id)] = secnum
+
+        return {self.config.master_doc: new_secnumbers}
+
     def get_doc_context(self, docname, body, metatags):
         # no relation links...
         toc = self.env.get_toctree_for(self.config.master_doc, self, False)
 
         self.info(bold('assembling single document... '), nonl=True)
         doctree = self.assemble_doctree()
+        self.env.toc_secnumbers = self.assemble_toc_secnumbers()
         self.info()
         self.info(bold('writing... '), nonl=True)
         self.write_doc_serialized(self.config.master_doc, doctree)

sphinx/util/nodes.py

             else:
                 sof = addnodes.start_of_file(docname=includefile)
                 sof.children = subtree.children
+                for sectionnode in sof.traverse(nodes.section):
+                    if 'docname' not in sectionnode:
+                        sectionnode['docname'] = includefile
                 newnodes.append(sof)
         toctreenode.parent.replace(toctreenode, newnodes)
     return tree

sphinx/writers/html.py

             self.body.append('.'.join(map(str, node['secnumber'])) +
                              self.secnumber_suffix)
         elif isinstance(node.parent, nodes.section):
-            anchorname = '#' + node.parent['ids'][0]
-            if anchorname not in self.builder.secnumbers:
-                anchorname = ''  # try first heading which has no anchor
+            if self.builder.name == 'singlehtml':
+                docname = node.parent.get('docname')
+                anchorname = '#' + node.parent['ids'][0]
+                if (docname, anchorname) not in self.builder.secnumbers:
+                    anchorname = (docname, '')  # try first heading which has no anchor
+                else:
+                    anchorname = (docname, anchorname)
+            else:
+                anchorname = '#' + node.parent['ids'][0]
+                if anchorname not in self.builder.secnumbers:
+                    anchorname = ''  # try first heading which has no anchor
             if self.builder.secnumbers.get(anchorname):
                 numbers = self.builder.secnumbers[anchorname]
                 self.body.append('.'.join(map(str, numbers)) +

tests/roots/test-tocdepth/bar.rst

 
 should be 2.1
 
-Bar A1
-------
+.. toctree::
 
-should be 2.1.1
+   baz
 
 Bar B
 =====

tests/roots/test-tocdepth/baz.rst

+Baz A
+-----
+
+should be 2.1.1
+

tests/test_build_html.py

         'bar.html': [
             (".//h1", '2. Bar', True),
             (".//h2", '2.1. Bar A', True),
-            (".//h3", '2.1.1. Bar A1', True),
             (".//h2", '2.2. Bar B', True),
             (".//h3", '2.2.1. Bar B1', True),
         ],
+        'baz.html': [
+            (".//h1", '2.1.1. Baz A', True),
+        ],
     }
 
     for fname, paths in iteritems(expects):
 
         for xpath, check, be_found in paths:
             yield check_xpath, etree, fname, xpath, check, be_found
+
+
+@gen_with_app(buildername='singlehtml', srcdir=(test_roots / 'test-tocdepth'))
+def test_tocdepth_singlehtml(app):
+    app.builder.build_all()
+
+    expects = {
+        'index.html': [
+            (".//li[@class='toctree-l3']/a", '1.1.1. Foo A1', True),
+            (".//li[@class='toctree-l3']/a", '1.2.1. Foo B1', True),
+            (".//li[@class='toctree-l3']/a", '2.1.1. Bar A1', False),
+            (".//li[@class='toctree-l3']/a", '2.2.1. Bar B1', False),
+
+            # index.rst
+            (".//h1", 'test-tocdepth', True),
+
+            # foo.rst
+            (".//h2", '1. Foo', True),
+            (".//h3", '1.1. Foo A', True),
+            (".//h4", '1.1.1. Foo A1', True),
+            (".//h3", '1.2. Foo B', True),
+            (".//h4", '1.2.1. Foo B1', True),
+
+            # bar.rst
+            (".//h2", '2. Bar', True),
+            (".//h3", '2.1. Bar A', True),
+            (".//h3", '2.2. Bar B', True),
+            (".//h4", '2.2.1. Bar B1', True),
+
+            # baz.rst
+            (".//h4", '2.1.1. Baz A', True),
+        ],
+    }
+
+    for fname, paths in iteritems(expects):
+        parser = NslessParser()
+        parser.entity.update(html_entities.entitydefs)
+        fp = open(os.path.join(app.outdir, fname), 'rb')
+        try:
+            etree = ET.parse(fp, parser)
+        finally:
+            fp.close()
+
+        for xpath, check, be_found in paths:
+            yield check_xpath, etree, fname, xpath, check, be_found