[Python-checkins] r63840 - in doctools/trunk: CHANGES sphinx/__init__.py sphinx/builder.py sphinx/environment.py sphinx/htmlhelp.py

georg.brandl python-checkins at python.org
Sun Jun 1 00:52:43 CEST 2008


Author: georg.brandl
Date: Sun Jun  1 00:52:42 2008
New Revision: 63840

Log:
More logical "next"/"previous" links.


Modified:
   doctools/trunk/CHANGES
   doctools/trunk/sphinx/__init__.py
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/environment.py
   doctools/trunk/sphinx/htmlhelp.py

Modified: doctools/trunk/CHANGES
==============================================================================
--- doctools/trunk/CHANGES	(original)
+++ doctools/trunk/CHANGES	Sun Jun  1 00:52:42 2008
@@ -33,6 +33,9 @@
 
 * Add document metadata to the values in the default template context.
 
+* Let the "previous" and "next" to more logical documents, so that always
+  selecting "next" lets you visit every document in the tree.
+
 Bugs fixed
 ----------
 

Modified: doctools/trunk/sphinx/__init__.py
==============================================================================
--- doctools/trunk/sphinx/__init__.py	(original)
+++ doctools/trunk/sphinx/__init__.py	Sun Jun  1 00:52:42 2008
@@ -135,6 +135,11 @@
             app.builder.build_update()
     except KeyboardInterrupt:
         # catches BaseExceptions in 2.5 -- SystemExit, KeyboardInterrupt
+        if use_pdb:
+            import pdb
+            print >>sys.stderr, darkred('Interrupted while building, starting debugger:')
+            traceback.print_exc()
+            pdb.post_mortem(sys.exc_info()[2])
         return 1
     except SystemExit:
         return 0

Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Sun Jun  1 00:52:42 2008
@@ -302,9 +302,6 @@
     def prepare_writing(self, docnames):
         from sphinx.search import IndexBuilder
 
-        self.info(bold('creating index...'))
-        self.env.create_index(self)
-
         self.indexer = IndexBuilder()
         self.load_indexer(docnames)
         self.docwriter = HTMLWriter(self)
@@ -326,6 +323,8 @@
         if not isinstance(self.config.html_use_opensearch, basestring):
             self.warn('html_use_opensearch config value must now be a string')
 
+        self.relations = self.env.collect_relations()
+
         self.globalcontext = dict(
             project = self.config.project,
             release = self.config.release,
@@ -350,28 +349,29 @@
         # find out relations
         prev = next = None
         parents = []
-        related = self.env.toctree_relations.get(docname)
+        related = self.relations.get(docname)
         titles = self.env.titles
-        if related:
+        if related and related[1]:
             try:
                 prev = {'link': self.get_relative_uri(docname, related[1]),
                         'title': self.render_partial(titles[related[1]])['title']}
             except KeyError:
                 # the relation is (somehow) not in the TOC tree, handle that gracefully
                 prev = None
+        if related and related[2]:
             try:
                 next = {'link': self.get_relative_uri(docname, related[2]),
                         'title': self.render_partial(titles[related[2]])['title']}
             except KeyError:
                 next = None
-        while related:
+        while related and related[0]:
             try:
                 parents.append(
                     {'link': self.get_relative_uri(docname, related[0]),
                      'title': self.render_partial(titles[related[0]])['title']})
             except KeyError:
                 pass
-            related = self.env.toctree_relations.get(related[0])
+            related = self.relations.get(related[0])
         if parents:
             parents.pop() # remove link to the master file; we have a generic
                           # "back to index" link already
@@ -420,13 +420,14 @@
         if self.config.html_use_index:
             # the total count of lines for each index letter, used to distribute
             # the entries into two columns
+            genindex = self.env.create_index(self)
             indexcounts = []
-            for _, entries in self.env.index:
+            for _, entries in genindex:
                 indexcounts.append(sum(1 + len(subitems)
                                        for _, (_, subitems) in entries))
 
             genindexcontext = dict(
-                genindexentries = self.env.index,
+                genindexentries = genindex,
                 genindexcounts = indexcounts,
             )
             self.info(' genindex', nonl=1)

Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py	(original)
+++ doctools/trunk/sphinx/environment.py	Sun Jun  1 00:52:42 2008
@@ -15,10 +15,10 @@
 import heapq
 import types
 import difflib
-import itertools
 import cPickle as pickle
 from os import path
 from string import uppercase
+from itertools import izip, groupby
 try:
     import hashlib
     md5 = hashlib.md5
@@ -58,7 +58,7 @@
 
 # This is increased every time an environment attribute is added
 # or changed to properly invalidate pickle files.
-ENV_VERSION = 21
+ENV_VERSION = 22
 
 
 default_substitutions = set([
@@ -225,8 +225,7 @@
         self.toc_num_entries = {}   # docname -> number of real entries
                                     # used to determine when to show the TOC in a sidebar
                                     # (don't show if it's only one item)
-        self.toctree_relations = {} # docname -> ["parent", "previous", "next"] docname
-                                    # for navigating in the toctree
+        self.toctree_includes = {}  # docname -> list of toctree includefiles
         self.files_to_rebuild = {}  # docname -> set of files (containing its TOCs)
                                     # to rebuild too
 
@@ -280,11 +279,14 @@
             self.titles.pop(docname, None)
             self.tocs.pop(docname, None)
             self.toc_num_entries.pop(docname, None)
+            self.toctree_includes.pop(docname, None)
             self.filemodules.pop(docname, None)
             self.indexentries.pop(docname, None)
 
-            for subfn, fnset in self.files_to_rebuild.iteritems():
+            for subfn, fnset in self.files_to_rebuild.items():
                 fnset.discard(docname)
+                if not fnset:
+                    del self.files_to_rebuild[subfn]
             for fullname, (fn, _) in self.descrefs.items():
                 if fn == docname:
                     del self.descrefs[fullname]
@@ -590,17 +592,11 @@
         """Note a TOC tree directive in a document and gather information about
            file relations from it."""
         includefiles = toctreenode['includefiles']
-        includefiles_len = len(includefiles)
-        for i, includefile in enumerate(includefiles):
-            # the "previous" file for the first toctree item is the parent
-            previous = i > 0 and includefiles[i-1] or docname
-            # the "next" file for the last toctree item is the parent again
-            next = i < includefiles_len-1 and includefiles[i+1] or docname
-            self.toctree_relations[includefile] = [docname, previous, next]
+        for includefile in includefiles:
             # note that if the included file is rebuilt, this one must be
             # too (since the TOC of the included file could have changed)
             self.files_to_rebuild.setdefault(includefile, set()).add(docname)
-
+        self.toctree_includes.setdefault(docname, []).extend(includefiles)
 
     def build_toc_from(self, docname, document):
         """Build a TOC from the doctree and store it in the inventory."""
@@ -998,14 +994,49 @@
             else:
                 # get all other symbols under one heading
                 return 'Symbols'
-        self.index = [(key, list(group)) for (key, group) in
-                      itertools.groupby(newlist, keyfunc)]
+        return [(key, list(group)) for (key, group) in groupby(newlist, keyfunc)]
+
+    def collect_relations(self):
+        relations = {}
+        getinc = self.toctree_includes.get
+        def collect(parents, docname, previous, next):
+            includes = getinc(docname)
+            # previous
+            if not previous:
+                previous = parents[0][0]
+            else:
+                while 1:
+                    previncs = getinc(previous)
+                    if previncs:
+                        previous = previncs[-1]
+                    else:
+                        break
+            # next
+            if includes:
+                next = includes[0]
+            elif next:
+                pass
+            else:
+                for parname, parindex in parents:
+                    parincs = getinc(parname)
+                    if parincs and parindex + 1 < len(parincs):
+                        next = parincs[parindex+1]
+                        break
+                # else it will stay None
+            # same for children
+            if includes:
+                for subindex, args in enumerate(izip(includes, [None] + includes,
+                                                     includes[1:] + [None])):
+                    collect([(docname, subindex)] + parents, *args)
+            relations[docname] = [parents[0][0], previous, next]
+        collect([(None, 0)], self.config.master_doc, None, None)
+        return relations
 
     def check_consistency(self):
         """Do consistency checks."""
 
         for docname in self.all_docs:
-            if docname not in self.toctree_relations:
+            if docname not in self.files_to_rebuild:
                 if docname == self.config.master_doc:
                     # the master file is not included anywhere ;)
                     continue

Modified: doctools/trunk/sphinx/htmlhelp.py
==============================================================================
--- doctools/trunk/sphinx/htmlhelp.py	(original)
+++ doctools/trunk/sphinx/htmlhelp.py	Sun Jun  1 00:52:42 2008
@@ -184,6 +184,7 @@
         f.close()
 
     builder.info('writing index file...')
+    index = builder.env.create_index(builder)
     f = open(path.join(outdir, outname+'.hhk'), 'w')
     try:
         f.write('<UL>\n')
@@ -199,7 +200,7 @@
                 for subitem in subitems:
                     write_index(subitem[0], subitem[1], [])
                 f.write('</UL>')
-        for (key, group) in builder.env.index:
+        for (key, group) in index:
             for title, (refs, subitems) in group:
                 write_index(title, refs, subitems)
         f.write('</UL>\n')


More information about the Python-checkins mailing list