[Python-checkins] r59538 - in doctools/trunk/sphinx: builder.py environment.py latexwriter.py roles.py texinputs/python.sty

georg.brandl python-checkins at python.org
Mon Dec 17 00:14:24 CET 2007


Author: georg.brandl
Date: Mon Dec 17 00:14:24 2007
New Revision: 59538

Modified:
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/environment.py
   doctools/trunk/sphinx/latexwriter.py
   doctools/trunk/sphinx/roles.py
   doctools/trunk/sphinx/texinputs/python.sty
Log:
Further fixes. All produced latex documents now run through pdflatex without errors.


Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Mon Dec 17 00:14:24 2007
@@ -59,14 +59,13 @@
 class collect_env_warnings(object):
     def __init__(self, builder):
         self.builder = builder
+        self.warnings = []
     def __enter__(self):
-        self.stream = StringIO.StringIO()
-        self.builder.env.set_warning_stream(self.stream)
+        self.builder.env.set_warnfunc(self.warnings.append)
     def __exit__(self, *args):
-        self.builder.env.set_warning_stream(self.builder.warning_stream)
-        warnings = self.stream.getvalue()
-        if warnings:
-            print >>self.builder.warning_stream, warnings
+        self.builder.env.set_warnfunc(self.builder.warn)
+        for warning in self.warnings:
+            self.builder.warn(warning)
 
 
 class Builder(object):
@@ -90,6 +89,9 @@
         self.options = attrdict(options)
         self.validate_options()
 
+        self.status_stream = status_stream or sys.stdout
+        self.warning_stream = warning_stream or sys.stderr
+
         # probably set in load_env()
         self.env = env
 
@@ -108,17 +110,13 @@
                 version, release = get_version_info(srcdirname)
             except (IOError, OSError):
                 version, release = get_sys_version_info()
-                print >>warning_stream, 'WARNING: Can\'t get version info from ' \
-                      'Include/patchlevel.h, using version of this ' \
-                      'interpreter (%s).' % release
+                self.warn('Can\'t get version info from Include/patchlevel.h, '
+                          'using version of this interpreter (%s).' % release)
             if self.config['version'] == 'auto':
                 self.config['version'] = version
             if self.config['release'] == 'auto':
                 self.config['release'] = release
 
-        self.status_stream = status_stream or sys.stdout
-        self.warning_stream = warning_stream or sys.stderr
-
         self.init()
 
     # helper methods
@@ -139,6 +137,9 @@
             print >>self.status_stream, message
         self.status_stream.flush()
 
+    def warn(self, message):
+        print >>self.warning_stream, 'WARNING:', message
+
     def init(self):
         """Load necessary templates and perform initialization."""
         raise NotImplementedError
@@ -527,7 +528,7 @@
             with codecs.open(outfilename, 'w', 'utf-8') as fp:
                 fp.write(output)
         except (IOError, OSError), err:
-            print >>self.warning_stream, "Error writing file %s: %s" % (outfilename, err)
+            self.warn("Error writing file %s: %s" % (outfilename, err))
         if self.copysource and context.get('sourcename'):
             # copy the source file for the "show source" link
             shutil.copyfile(path.join(self.srcdir, os_path(filename)),
@@ -707,7 +708,7 @@
         self.filenames = set([indexfile, 'glossary.rst', 'about.rst',
                               'license.rst', 'copyright.rst'])
         print green(indexfile),
-        def process_tree(tree):
+        def process_tree(filename, tree):
             #tree = tree.deepcopy() XXX
             for toctreenode in tree.traverse(addnodes.toctree):
                 newnodes = []
@@ -715,16 +716,17 @@
                 for includefile in includefiles:
                     try:
                         print green(includefile),
-                        subtree = process_tree(self.env.get_doctree(includefile))
+                        subtree = process_tree(includefile,
+                                               self.env.get_doctree(includefile))
                         self.filenames.add(includefile)
                     except:
-                        print >>self.warning_stream, 'WARNING: %s: toctree contains ' \
-                              'ref to nonexisting file %r' % (filename, includefile)
+                        self.warn('%s: toctree contains ref to nonexisting file %r' %
+                                  (filename, includefile))
                     else:
                         newnodes.extend(subtree.children)
                 toctreenode.parent.replace(toctreenode, newnodes)
             return tree
-        largetree = process_tree(self.env.get_doctree(indexfile))
+        largetree = process_tree(indexfile, self.env.get_doctree(indexfile))
         largetree.extend(specials)
         print
         print "resolving references..."

Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py	(original)
+++ doctools/trunk/sphinx/environment.py	Mon Dec 17 00:14:24 2007
@@ -74,6 +74,11 @@
 ])
 
 
+class RedirStream(object):
+    def __init__(self, write):
+        self.write = write
+
+
 class NoUri(Exception):
     """Raised by get_relative_uri if there is no URI available."""
     pass
@@ -159,12 +164,12 @@
 
     def topickle(self, filename):
         # remove unpicklable attributes
-        wstream = self.warning_stream
-        self.set_warning_stream(None)
+        warnfunc = self._warnfunc
+        self.set_warnfunc(None)
         with open(filename, 'wb') as picklefile:
             pickle.dump(self, picklefile, pickle.HIGHEST_PROTOCOL)
         # reset stream
-        self.set_warning_stream(wstream)
+        self.set_warnfunc(warnfunc)
 
     # --------- ENVIRONMENT INITIALIZATION -------------------------------------
 
@@ -181,8 +186,8 @@
         self.settings = default_settings.copy()
         self.settings['env'] = self
 
-        # the stream to write warning messages to
-        self.warning_stream = None
+        # the function to write warning messages with
+        self._warnfunc = None
 
         # this is to invalidate old pickles
         self.version = ENV_VERSION
@@ -227,9 +232,9 @@
         self.index_num = 0          # autonumber for index targets
         self.gloss_entries = set()  # existing definition labels
 
-    def set_warning_stream(self, stream):
-        self.warning_stream = stream
-        self.settings['warning_stream'] = stream
+    def set_warnfunc(self, func):
+        self._warnfunc = func
+        self.settings['warnfunc'] = func
 
     def clear_file(self, filename):
         """Remove all traces of a source file in the inventory."""
@@ -367,7 +372,7 @@
         doctree.reporter = None
         doctree.transformer = None
         doctree.settings.env = None
-        doctree.settings.warning_stream = None
+        doctree.settings.warnfunc = None
 
         # cleanup
         self.filename = None
@@ -429,9 +434,8 @@
                 continue
             sectname = node[0].astext() # node[0] == title node
             if name in self.labels:
-                print >>self.warning_stream, \
-                      ('WARNING: duplicate label %s, ' % name +
-                       'in %s and %s' % (self.labels[name][0], filename))
+                self._warnfunc('duplicate label %s, ' % name +
+                               'in %s and %s' % (self.labels[name][0], filename))
             self.labels[name] = filename, labelid, sectname
 
     def note_toctree(self, filename, toctreenode):
@@ -509,9 +513,8 @@
     #
     def note_descref(self, fullname, desctype):
         if fullname in self.descrefs:
-            print >>self.warning_stream, \
-                  ('WARNING: duplicate canonical description name %s, ' % fullname +
-                   'in %s and %s' % (self.descrefs[fullname][0], self.filename))
+            self._warnfunc('duplicate canonical description name %s, ' % fullname +
+                           'in %s and %s' % (self.descrefs[fullname][0], self.filename))
         self.descrefs[fullname] = (self.filename, desctype)
 
     def note_module(self, modname, synopsis, platform, deprecated):
@@ -537,7 +540,7 @@
         doctree_filename = path.join(self.doctreedir, os_path(filename)[:-3] + 'doctree')
         with file(doctree_filename, 'rb') as f:
             doctree = pickle.load(f)
-        doctree.reporter = Reporter(filename, 2, 4, stream=self.warning_stream)
+        doctree.reporter = Reporter(filename, 2, 4, stream=RedirStream(self._warnfunc))
         return doctree
 
     def get_and_resolve_doctree(self, filename, builder, doctree=None):
@@ -560,8 +563,8 @@
                     toc = self.tocs[includefile].deepcopy()
                 except KeyError, err:
                     # this is raised if the included file does not exist
-                    print >>self.warning_stream, 'WARNING: %s: toctree contains ' \
-                          'ref to nonexisting file %r' % (filename, includefile)
+                    self._warnfunc('%s: toctree contains ref to nonexisting '
+                                   'file %r' % (filename, includefile))
                 else:
                     for toctreenode in toc.traverse(addnodes.toctree):
                         toctreenode.parent.replace_self(
@@ -604,8 +607,7 @@
                     if not filename:
                         newnode = doctree.reporter.system_message(
                             2, 'undefined label: %s' % target)
-                        print >>self.warning_stream, \
-                              '%s: undefined label: %s' % (docfilename, target)
+                        self._warnfunc('%s: undefined label: %s' % (docfilename, target))
                     else:
                         newnode = nodes.reference('', '')
                         innernode = nodes.emphasis(sectname, sectname)
@@ -622,8 +624,8 @@
                     filename, labelid = self.reftargets.get((typ, target), ('', ''))
                     if not filename:
                         if typ == 'term':
-                            print >>self.warning_stream, \
-                                  '%s: term not in glossary: %s' % (docfilename, target)
+                            self._warnfunc('%s: term not in glossary: %s' %
+                                           (docfilename, target))
                         newnode = contnode
                     else:
                         newnode = nodes.reference('', '')
@@ -714,8 +716,7 @@
                     add_entry(string, 'built-in function')
                     add_entry('built-in function', string)
                 else:
-                    print >>self.warning_stream, \
-                          "unknown index entry type %r in %s" % (type, fn)
+                    self._warnfunc("unknown index entry type %r in %s" % (type, fn))
 
         newlist = new.items()
         newlist.sort(key=lambda t: t[0].lower())
@@ -769,8 +770,7 @@
                 if filename == 'contents.rst':
                     # the master file is not included anywhere ;)
                     continue
-                self.warning_stream.write(
-                    'WARNING: %s isn\'t included in any toctree\n' % filename)
+                self._warnfunc('%s isn\'t included in any toctree' % filename)
 
     # --------- QUERYING -------------------------------------------------------
 

Modified: doctools/trunk/sphinx/latexwriter.py
==============================================================================
--- doctools/trunk/sphinx/latexwriter.py	(original)
+++ doctools/trunk/sphinx/latexwriter.py	Mon Dec 17 00:14:24 2007
@@ -25,7 +25,7 @@
 HEADER = r'''%% Generated by Sphinx.
 \documentclass[%(papersize)s,%(pointsize)s]{%(docclass)s}
 \usepackage[utf8]{inputenc}
-\usepackage[colorlinks]{hyperref}
+\usepackage[colorlinks,breaklinks]{hyperref}
 \title{%(title)s}
 \date{%(date)s}
 \release{%(release)s}
@@ -200,8 +200,7 @@
             raise nodes.SkipNode
         elif self.this_is_the_title:
             if len(node.children) != 1 and not isinstance(node.children[0], Text):
-                print >>self.builder.warning_stream, 'WARNING: document title ' \
-                      'is not a single Text node'
+                self.builder.warn('document title is not a single Text node')
             self.options['title'] = node.astext()
             self.this_is_the_title = 0
             raise nodes.SkipNode
@@ -212,8 +211,7 @@
             self.body.append(r'\textbf{')
             self.context.append('}\n\n\medskip\n\n')
         else:
-            print >>self.builder.warning_stream, 'WARNING: encountered title node ' \
-                  'not in section, topic or sidebar'
+            self.builder.warn('encountered title node not in section, topic or sidebar')
             self.body.append('\\textbf{')
             self.context.append('}')
         self.in_title = 1
@@ -323,8 +321,8 @@
     def visit_rubric(self, node):
         if len(node.children) == 1 and node.children[0].astext() == 'Footnotes':
             raise nodes.SkipNode
-        print >>self.builder.warning_stream, 'WARNING: encountered rubric node' \
-              'not used for footnotes, content will be lost'
+        self.builder.warn('encountered rubric node not used for footnotes, '
+                          'content will be lost')
 
     def visit_footnote(self, node):
         # XXX not optimal, footnotes are at section end
@@ -358,8 +356,7 @@
         elif columnCount == 5:
             self.body.append('\\begin{tablev}{l|l|l|l|l}{textrm}')
         else:
-            print >>self.builder.warning_stream, 'WARNING: table with too ' \
-                  'many columns, ignoring'
+            self.builder.warn('table with too many columns, ignoring')
             raise nodes.SkipNode
     def depart_tgroup(self, node):
         if self.tableSpec.columnCount == 2:
@@ -548,6 +545,7 @@
         self.body.append(self.context.pop())
 
     indextype_map = {
+        'module': 'refmodindex',
         'keyword': 'kwindex',
         'operator': 'opindex',
         'object': 'obindex',
@@ -567,15 +565,11 @@
             elif type == 'triple':
                 parts = tuple(self.encode(x.strip()) for x in string.split(';', 2))
                 self.body.append(r'\indexiii{%s}{%s}{%s}' % parts)
-            elif type == 'module':
-                self.body.append(r'\refmodindex[%s]{%s}' % (string.replace('_', ''),
-                                                            self.encode(string)))
             elif type in self.indextype_map:
                 self.body.append(r'\%s{%s}' % (self.indextype_map[type],
                                                self.encode(string)))
             else:
-                print >>self.builder.warning_stream, 'WARNING: unknown index entry ' \
-                      'type %s found' % type
+                self.builder.warn('unknown index entry type %s found' % type)
         raise nodes.SkipNode
 
     def visit_reference(self, node):
@@ -595,8 +589,7 @@
                 self.body.append('\\grammartoken{')
             self.context.append('}')
         else:
-            print self.builder.warning_stream, 'WARNING: malformed reference ' \
-                  'target found: %s' % uri
+            self.builder.warn('malformed reference target found: %s' % uri)
             self.context.append('')
     def depart_reference(self, node):
         self.body.append(self.context.pop())
@@ -645,6 +638,8 @@
     def depart_literal_block(self, node):
         hlcode = highlighting.highlight_block(self.verbatim.rstrip('\n'),
                                               self.highlightlang, 'latex')
+        # workaround for Unicode issue
+        hlcode = hlcode.replace(u'€', u'@texteuro[]')
         # workaround for Pygments bug
         hlcode = hlcode.replace('\n\\end{Verbatim}', '\\end{Verbatim}')
         self.body.append('\n' + hlcode)

Modified: doctools/trunk/sphinx/roles.py
==============================================================================
--- doctools/trunk/sphinx/roles.py	(original)
+++ doctools/trunk/sphinx/roles.py	Mon Dec 17 00:14:24 2007
@@ -42,22 +42,26 @@
     text = utils.unescape(text)
     targetid = 'index-%s' % env.index_num
     env.index_num += 1
+    indexnode = addnodes.index()
     targetnode = nodes.target('', '', ids=[targetid])
     inliner.document.note_explicit_target(targetnode)
     if typ == 'envvar':
-        env.note_index_entry('single', '%s' % text,
-                             targetid, text)
+        env.note_index_entry('single', text, targetid, text)
         env.note_index_entry('single', 'environment variable; %s' % text,
                              targetid, text)
-        #textnode = nodes.strong(text, text)
+        indexnode['entries'] = [('single', text, targetid, text),
+                                ('single', 'environment variable; %s' % text,
+                                 targetid, text)]
         pnode = addnodes.pending_xref(rawtext)
         pnode['reftype'] = 'envvar'
         pnode['reftarget'] = text
         pnode += nodes.strong(text, text, classes=['xref'])
-        return [targetnode, pnode], []
+        return [indexnode, targetnode, pnode], []
     elif typ == 'pep':
         env.note_index_entry('single', 'Python Enhancement Proposals!PEP %s' % text,
                              targetid, 'PEP %s' % text)
+        indexnode['entries'] = [('single', 'Python Enhancement Proposals!PEP %s' % text,
+                                 targetid, 'PEP %s' % text)]
         try:
             pepnum = int(text)
         except ValueError:
@@ -68,10 +72,12 @@
         sn = nodes.strong('PEP '+text, 'PEP '+text)
         rn = nodes.reference('', '', refuri=ref)
         rn += sn
-        return [targetnode, rn], []
+        return [indexnode, targetnode, rn], []
     elif typ == 'rfc':
-        env.note_index_entry('single', 'RFC!RFC %s' % text,
+        env.note_index_entry('single', 'RFC; RFC %s' % text,
                              targetid, 'RFC %s' % text)
+        indexnode['entries'] = [('single', 'RFC; RFC %s' % text,
+                                 targetid, 'RFC %s' % text)]
         try:
             rfcnum = int(text)
         except ValueError:
@@ -82,7 +88,7 @@
         sn = nodes.strong('RFC '+text, 'RFC '+text)
         rn = nodes.reference('', '', refuri=ref)
         rn += sn
-        return [targetnode, rn], []
+        return [indexnode, targetnode, rn], []
 
 roles.register_canonical_role('envvar', indexmarkup_role)
 roles.register_local_role('pep', indexmarkup_role)

Modified: doctools/trunk/sphinx/texinputs/python.sty
==============================================================================
--- doctools/trunk/sphinx/texinputs/python.sty	(original)
+++ doctools/trunk/sphinx/texinputs/python.sty	Mon Dec 17 00:14:24 2007
@@ -6,6 +6,7 @@
 \ProvidesPackage{python}
              [1998/01/11 LaTeX package (Python markup)]
 
+\RequirePackage{textcomp}
 \RequirePackage{longtable}
 \RequirePackage{times}
 \RequirePackage{fancyvrb}
@@ -808,9 +809,12 @@
 }{\end{fulllineitems}}
 
 % generic description ----------------------------------------------------
+\newcommand{\descline}[1]{%
+  \item[\bfcode{#1}]\nopagebreak%
+}
 \newenvironment{describe}[1]{
   \begin{fulllineitems}
-    \item[\bfcode{#1}]\nopagebreak
+    \descline{#1}
 }{\end{fulllineitems}}
 
 \newcommand{\nodename}[1]{\label{#1}}


More information about the Python-checkins mailing list