Commits

georg.brandl  committed 29ebaaa

Checkin my holiday work:
- Add "changes" builder to quickly get an overview over all "versionadded/changed/deprecated" directives for a certain version
- Cross-reference keywords
- Fix some problems in the webapp and the latex writer

  • Participants
  • Parent commits c796bc4

Comments (0)

Files changed (21)

 Sphinx
 ******
 
-- section numbers
-- split the general index
+- HTML section numbers?
+- split the general index?
 - add OpenSearch
 - "seealso" links to external examples, see http://svn.python.org/projects/sandbox/trunk/seealso/ and http://effbot.org/zone/idea-seealso.htm
-- write a "printable" builder (export to latex, most probably)
 - "often used" combo box in sidebar
-- link to keywords
 - source file cross-references?
 
 Web App
 *******
 
+- fix /download
+
 - discuss and debug comments system
 - prepare for databases other than sqlite for comments
 - add search via Xapian or Nucular (Python indexer - nucular.sf.net)

File sphinx/__init__.py

          -D <setting=value> -- override a setting in sourcedir/conf.py
          -N        -- do not do colored output
          -q        -- no output on stdout, just warnings on stderr
+         -P        -- run Pdb on exception
 modi:
 * without -a and without filenames, write new and changed files.
 * with -a, write all files.
 
 def main(argv):
     try:
-        opts, args = getopt.getopt(argv[1:], 'ab:d:O:D:NEq')
+        opts, args = getopt.getopt(argv[1:], 'ab:d:O:D:NEqP')
         srcdirname = path.abspath(args[0])
         if not path.isdir(srcdirname):
             print >>sys.stderr, 'Error: Cannot find source directory.'
         return 1
 
     builder = all_files = None
-    opt_help = freshenv = False
+    opt_help = freshenv = use_pdb = False
     status = sys.stdout
     options = {}
     confoverrides = {}
             freshenv = True
         elif opt == '-q':
             status = StringIO()
+        elif opt == '-P':
+            use_pdb = True
 
     if not sys.stdout.isatty() or sys.platform == 'win32':
         # Windows' cmd box doesn't understand ANSI sequences
             print ' * %s: %s' % (optname, description)
         return 0
 
-    builderobj = builderobj(srcdirname, outdirname, doctreedir, options,
-                            status_stream=status,
-                            warning_stream=sys.stderr,
-                            confoverrides=confoverrides,
-                            freshenv=freshenv)
-    if all_files:
-        builderobj.build_all()
-    elif filenames:
-        builderobj.build_specific(filenames)
-    else:
-        builderobj.build_update()
+    try:
+        builderobj = builderobj(srcdirname, outdirname, doctreedir, options,
+                                status_stream=status,
+                                warning_stream=sys.stderr,
+                                confoverrides=confoverrides,
+                                freshenv=freshenv)
+        if all_files:
+            builderobj.build_all()
+        elif filenames:
+            builderobj.build_specific(filenames)
+        else:
+            builderobj.build_update()
+    except:
+        if not use_pdb:
+            raise
+        import pdb
+        pdb.post_mortem(sys.exc_info()[2])
 
 
 if __name__ == '__main__':

File sphinx/builder.py

 import cPickle as pickle
 import cStringIO as StringIO
 from os import path
+from cgi import escape
 
 from docutils.io import StringOutput, FileOutput, DocTreeInput
 from docutils.core import publish_parts
 from .htmlwriter import HTMLWriter
 from .latexwriter import LaTeXWriter
 from .environment import BuildEnvironment, NoUri
-from .highlighting import pygments, get_stylesheet
+from .highlighting import pygments, highlight_block, get_stylesheet
 from .util.console import bold, purple, green
 
 from . import addnodes
     def build_update(self):
         """Only rebuild files changed or added since last build."""
         self.load_env()
-        to_build = list(self.get_outdated_files())
+        to_build = self.get_outdated_files()
         if not to_build:
             self.msg('no target files are out of date, exiting.')
             return
-        self.build(to_build,
-                   summary='targets for %d source files that are '
-                   'out of date' % len(to_build))
+        if isinstance(to_build, str):
+            self.build([], to_build)
+        else:
+            to_build = list(to_build)
+            self.build(to_build,
+                       summary='targets for %d source files that are '
+                       'out of date' % len(to_build))
 
     def build(self, filenames, summary=None):
         if summary:
             self.msg('building [%s]:' % self.name, nonl=1)
             self.msg(summary, nobold=1)
 
+        updated_filenames = []
         # while reading, collect all warnings from docutils
         with collect_env_warnings(self):
             self.msg('reading, updating environment:', nonl=1)
             iterator = self.env.update(self.config)
-            self.msg(iterator.next(), nobold=1)
+            self.msg(iterator.next(), nonl=1, nobold=1)
             for filename in iterator:
+                if not updated_filenames:
+                    self.msg('')
+                updated_filenames.append(filename)
                 self.msg(purple(filename), nonl=1, nobold=1)
             self.msg()
 
-        # save the environment
-        self.msg('pickling the env...', nonl=True)
-        self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME))
-        self.msg('done', nobold=True)
+        if updated_filenames:
+            # save the environment
+            self.msg('pickling the env...', nonl=True)
+            self.env.topickle(path.join(self.doctreedir, ENV_PICKLE_FILENAME))
+            self.msg('done', nobold=True)
 
-        # global actions
-        self.msg('checking consistency...')
-        self.env.check_consistency()
+            # global actions
+            self.msg('checking consistency...')
+            self.env.check_consistency()
 
         # another indirection to support methods which don't build files
         # individually
-        self.write(filenames)
+        self.write(filenames, updated_filenames)
 
         # finish (write style files etc.)
         self.msg('finishing...')
         self.finish()
         self.msg('done!')
 
-    def write(self, filenames):
+    def write(self, build_filenames, updated_filenames):
+        if build_filenames is None: # build_all
+            build_filenames = self.env.all_files
+        filenames = set(build_filenames) | set(updated_filenames)
+
+        # add all toctree-containing files that may have changed
+        for filename in list(filenames):
+            for tocfilename in self.env.files_to_rebuild.get(filename, []):
+                filenames.add(tocfilename)
+        filenames.add('contents.rst')
+
         self.msg('creating index...')
         self.env.create_index(self)
-        if filenames:
-            # add all TOC files that may have changed
-            filenames_set = set(filenames)
-            for filename in filenames:
-                for tocfilename in self.env.files_to_rebuild.get(filename, []):
-                    filenames_set.add(tocfilename)
-            filenames_set.add('contents.rst')
-        else:
-            # build all
-            filenames_set = set(self.env.all_files)
-
-        self.prepare_writing(filenames_set)
+        self.prepare_writing(filenames)
 
         # write target files
         with collect_env_warnings(self):
             self.msg('writing output...')
-            for filename in status_iterator(sorted(filenames_set), green,
+            for filename in status_iterator(sorted(filenames), green,
                                             stream=self.status_stream):
                 doctree = self.env.get_and_resolve_doctree(filename, self)
                 self.write_file(filename, doctree)
 
         # if there is a source file, copy the source file for the "show source" link
         if context.get('sourcename'):
-            source_name = path.join(self.outdir, 'sources', os_path(context['sourcename']))
+            source_name = path.join(self.outdir, 'sources',
+                                    os_path(context['sourcename']))
             ensuredir(path.dirname(source_name))
             shutil.copyfile(path.join(self.srcdir, os_path(filename)), source_name)
 
         self.filenames = []
 
     def get_outdated_files(self):
-        # XXX always rebuild everything for now
-        return ['dummy']
+        return 'all documents' # for now
 
     def get_target_uri(self, source_filename, typ=None):
         if typ == 'token':
                          and not fn.endswith('index.rst')]:
             yield (howto, 'howto-'+howto[6:-4]+'.tex', 'howto')
 
-    def write(self, filenames):
-        # "filenames" is ignored here...
-
+    def write(self, *ignored):
         # first, assemble the "special" docs that are in every PDF
         specials = []
         for fname in ["glossary", "about", "license", "copyright"]:
                 destination_path=path.join(self.outdir, targetname),
                 encoding='utf-8')
             print "processing", targetname + "...",
-            doctree = self.assemble_doctree(sourcename,
-                                            specials=(docclass == 'manual') and specials or [])
+            doctree = self.assemble_doctree(
+                sourcename, specials=(docclass == 'manual') and specials or [])
             print "writing...",
             doctree.settings = docsettings
             doctree.settings.filename = sourcename
                                 path.join(self.outdir, filename))
 
 
+class ChangesBuilder(Builder):
+    """
+    Write a summary with all versionadded/changed directives.
+    """
+    name = 'changes'
+
+    def init(self):
+        from ._jinja import Environment, FileSystemLoader
+        templates_path = path.join(path.dirname(__file__), 'templates')
+        jinja_env = Environment(loader=FileSystemLoader(templates_path),
+                                # disable traceback, more likely that something in the
+                                # application is broken than in the templates
+                                friendly_traceback=False)
+        self.ftemplate = jinja_env.get_template('versionchanges_frameset.html')
+        self.vtemplate = jinja_env.get_template('versionchanges.html')
+        self.stemplate = jinja_env.get_template('rstsource.html')
+
+    def get_outdated_files(self):
+        return self.outdir
+
+    typemap = {
+        'versionadded': 'added',
+        'versionchanged': 'changed',
+        'deprecated': 'deprecated',
+    }
+
+    def write(self, *ignored):
+        ver = self.config['version']
+        libchanges = {}
+        apichanges = []
+        otherchanges = {}
+        self.msg('writing summary file...')
+        for type, filename, lineno, module, descname, content in \
+                self.env.versionchanges[ver]:
+            ttext = self.typemap[type]
+            context = content.replace('\n', ' ')
+            if descname and filename.startswith('c-api'):
+                if not descname:
+                    continue
+                if context:
+                    entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
+                else:
+                    entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
+                apichanges.append((entry, filename, lineno))
+            elif descname or module:
+                if not module:
+                    module = 'Builtins'
+                if not descname:
+                    descname = 'Module level'
+                if context:
+                    entry = '<b>%s</b>: <i>%s:</i> %s' % (descname, ttext, context)
+                else:
+                    entry = '<b>%s</b>: <i>%s</i>.' % (descname, ttext)
+                libchanges.setdefault(module, []).append((entry, filename, lineno))
+            else:
+                if not context:
+                    continue
+                entry = '<i>%s:</i> %s' % (ttext.capitalize(), context)
+                title = self.env.titles[filename].astext()
+                otherchanges.setdefault((filename, title), []).append(
+                    (entry, filename, lineno))
+
+        ctx = {
+            'version': ver,
+            'libchanges': sorted(libchanges.iteritems()),
+            'apichanges': sorted(apichanges),
+            'otherchanges': sorted(otherchanges.iteritems()),
+        }
+        with open(path.join(self.outdir, 'index.html'), 'w') as f:
+            f.write(self.ftemplate.render(ctx))
+        with open(path.join(self.outdir, 'changes.html'), 'w') as f:
+            f.write(self.vtemplate.render(ctx))
+
+        hltext = ['.. versionadded:: %s' % ver,
+                  '.. versionchanged:: %s' % ver,
+                  '.. deprecated:: %s' % ver]
+
+        def hl(no, line):
+            line = '<a name="L%s"> </a>' % no + escape(line)
+            for x in hltext:
+                if x in line:
+                    line = '<span class="hl">%s</span>' % line
+                    break
+            return line
+
+        self.msg('copying source files...')
+        for filename in self.env.all_files:
+            with open(path.join(self.srcdir, os_path(filename))) as f:
+                lines = f.readlines()
+            targetfn = path.join(self.outdir, 'rst', os_path(filename)) + '.html'
+            ensuredir(path.dirname(targetfn))
+            with codecs.open(targetfn, 'w', 'utf8') as f:
+                text = ''.join(hl(i+1, line) for (i, line) in enumerate(lines))
+                ctx = {'filename': filename, 'text': text}
+                f.write(self.stemplate.render(ctx))
+        shutil.copyfile(path.join(path.dirname(__file__), 'style', 'default.css'),
+                        path.join(self.outdir, 'default.css'))
+
+    def hl(self, text, ver):
+        text = escape(text)
+        for directive in ['versionchanged', 'versionadded', 'deprecated']:
+            text = text.replace('.. %s:: %s' % (directive, ver),
+                                '<b>.. %s:: %s</b>' % (directive, ver))
+        return text
+
+    def finish(self):
+        pass
+
+
 builders = {
     'html': StandaloneHTMLBuilder,
     'web': WebHTMLBuilder,
     'htmlhelp': HTMLHelpBuilder,
     'latex': LaTeXBuilder,
+    'changes': ChangesBuilder,
 }

File sphinx/directives.py

     else:
         ret = [node]
     env = state.document.settings.env
-    env.note_versionchange(node['type'], node['version'], node)
+    env.note_versionchange(node['type'], node['version'], node, lineno)
     return ret
 
 version_directive.arguments = (1, 1, 1)

File sphinx/environment.py

 
 # This is increased every time a new environment attribute is added
 # to properly invalidate pickle files.
-ENV_VERSION = 13
+ENV_VERSION = 14
 
 
 def walk_depth(node, depth, maxdepth):
         self.indexentries = {}      # filename -> list of
                                     # (type, string, target, aliasname)
         self.versionchanges = {}    # version -> list of
-                                    # (type, filename, module, descname, content)
+                                    # (type, filename, lineno, module, descname, content)
 
         # These are set while parsing a file
         self.filename = None        # current file name
 
         if save_parsed:
             # save the parsed doctree
-            doctree_filename = path.join(self.doctreedir, os_path(filename)[:-3] + 'doctree')
+            doctree_filename = path.join(self.doctreedir,
+                                         os_path(filename)[:-3] + 'doctree')
             dirname = path.dirname(doctree_filename)
             if not path.isdir(dirname):
                 os.makedirs(dirname)
         self.indexentries.setdefault(self.filename, []).append(
             (type, string, targetid, aliasname))
 
-    def note_versionchange(self, type, version, node):
+    def note_versionchange(self, type, version, node, lineno):
         self.versionchanges.setdefault(version, []).append(
-            (type, self.filename, self.currmodule, self.currdesc, node.deepcopy()))
+            (type, self.filename, lineno, self.currmodule, self.currdesc, node.astext()))
     # -------
 
     # --------- RESOLVING REFERENCES AND TOCTREES ------------------------------
 
             try:
                 if typ == 'ref':
+                    # reference to the named label; the final node will contain the
+                    # section name after the label
                     filename, labelid, sectname = self.labels.get(target, ('','',''))
                     if not filename:
                         newnode = doctree.reporter.system_message(
                             newnode['refuri'] = builder.get_relative_uri(
                                 docfilename, filename) + '#' + labelid
                         newnode.append(innernode)
+                elif typ == 'keyword':
+                    # keywords are referenced by named labels
+                    filename, labelid, _ = self.labels.get(target, ('','',''))
+                    if not filename:
+                        self._warnfunc('%s: unknown keyword: %s' % (docfilename, target))
+                        newnode = contnode
+                    else:
+                        newnode = nodes.reference('', '')
+                        if filename == docfilename:
+                            newnode['refid'] = labelid
+                        else:
+                            newnode['refuri'] = builder.get_relative_uri(
+                                docfilename, filename) + '#' + labelid
+                        newnode.append(contnode)
                 elif typ in ('token', 'term', 'envvar', 'option'):
                     filename, labelid = self.reftargets.get((typ, target), ('', ''))
                     if not filename:
                             synopsis, (' (deprecated)' if deprecated else ''))
                         newnode.append(contnode)
                 else:
+                    # "descrefs"
                     modname = node['modname']
                     clsname = node['classname']
                     searchorder = 1 if node.hasattr('refspecific') else 0
-                    name, desc = self.find_desc(modname, clsname, target, typ, searchorder)
+                    name, desc = self.find_desc(modname, clsname,
+                                                target, typ, searchorder)
                     if not desc:
                         newnode = contnode
                     else:

File sphinx/latexwriter.py

 HEADER = r'''%% Generated by Sphinx.
 \documentclass[%(papersize)s,%(pointsize)s]{%(docclass)s}
 \usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
 \usepackage[colorlinks,breaklinks]{hyperref}
 \title{%(title)s}
 \date{%(date)s}
         # this is a list in the source, but should be rendered as a
         # comma-separated list here
         self.body.append('\n\n')
-        self.body.append(', '.join(n.astext() for n in node.children[0].children))
+        self.body.append(', '.join(n.astext() for n in node.children[0].children) + '.')
         self.body.append('\n\n')
         raise nodes.SkipNode
 

File sphinx/roles.py

     'dfn' : nodes.emphasis,
     'guilabel' : nodes.strong,
     'kbd' : nodes.literal,
-    'keyword' : nodes.literal,
     'mailheader' : addnodes.literal_emphasis,
     'makevar' : nodes.Text,
     'manpage' : addnodes.literal_emphasis,
 
     'mod' : xfileref_role,
 
+    'keyword': xfileref_role,
     'ref': xfileref_role,
     'token' : xfileref_role,
     'term': xfileref_role,

File sphinx/search.py

 """
 import re
 import pickle
+from collections import defaultdict
 
-from collections import defaultdict
 from docutils.nodes import Text, NodeVisitor
+
 from .util.stemmer import PorterStemmer
 from .util.json import dump_json, load_json
 

File sphinx/style/default.css

 div.modulecloud {
     margin: -5px 10px 5px 10px;
     padding: 10px;
-    font-size: 110%;
     line-height: 160%;
     border: 1px solid #cbe7e5;
     background-color: #f2fbfd;
 tt {
     background-color: #ecf0f3;
     padding: 0 1px 0 1px;
+    font-size: 0.95em;
 }
 
 tt.descname {

File sphinx/templates/rstsource.html

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+  "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+  <head>
+    <title>{{ filename }} &mdash; Python Documentation</title>
+    <style type="text/css">
+      .hl { background-color: yellow }
+    </style>
+  </head>
+  <body style="font-size: 90%">
+    <pre>
+      {{ text }}
+    </pre>
+  </body>
+</html>

File sphinx/templates/sidebar.html

               <input type="hidden" name="check_keywords" value="yes">
               <input type="hidden" name="area" value="default">
             </form>
+            {% if builder == 'web' %}
+            <p style="font-size: 90%">Enter a module, class or function name.</p>
+            {% endif %}
           {% endif %}
         </div>
       </div>

File sphinx/templates/versionchanges.html

+{% macro entries changes %}
+<ul>{% for entry, filename, lineno in changes %}
+<li><a href="rst/{{ filename }}.html#L{{ lineno-10 }}" target="src">{{ entry }}</a></li>
+{% endfor %}</ul>
+{% endmacro -%}
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+  "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+  <head>
+    <link rel="stylesheet" href="default.css">
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <title>Changes in Version {{ version }} &mdash; Python Documentation</title>
+  </head>
+  <body>
+    <div class="document">
+      <div class="body">
+    <h1>Automatically generated list of changes in version {{ version }}</h1>
+    <h2>Library changes</h2>
+    {% for modname, changes in libchanges %}
+    <h4>{{ modname }}</h4>
+    {{ entries(changes) }}
+    {% endfor %}
+    <h2>C API changes</h2>
+    {{ entries(apichanges) }}
+    <h2>Other changes</h2>
+    {% for (fn, title), changes in otherchanges %}
+    <h4>{{ title }} <span style="font-size: 50%">({{ fn }})</span></h4>
+    {{ entries(changes) }}
+    {% endfor %}
+      </div>
+    </div>
+  </body>
+</html>

File sphinx/templates/versionchanges_frameset.html

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
+  "http://www.w3.org/TR/html4/frameset.dtd">
+<html>
+  <head>
+    <title>Changes in Version {{ version }} &mdash; Python Documentation</title>
+  </head>
+  <frameset cols="45%,*">
+    <frame name="main" src="changes.html">
+    <frame name="src" src="about:blank">
+  </frameset>
+</html>

File sphinx/texinputs/howto.cls

 %
-% howto.cls for the Python documentation
+% howto.cls for Sphinx
 %
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 % This gives us all the Python-specific markup that we really want.
 % This should come last.  Do not change this.
 %
-\RequirePackage{python}
+\RequirePackage{sphinx}
 
 % This comes after python.sty because it otherwise defines its own
 % "seealso" command.

File sphinx/texinputs/manual.cls

 %
-% manual.cls for the Python documentation
+% manual.cls for Sphinx
 %
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 % This gives us all the Python-specific markup that we really want.
 % This should come last.  Do not change this.
 %
-\RequirePackage{python}
+\RequirePackage{sphinx}
 
-% This comes after python.sty because it otherwise defines its own
+% This comes after sphinx.sty because it otherwise defines its own
 % "seealso" command.
 \RequirePackage{makeidx}
 

File sphinx/texinputs/python.sty

-%
-% python.sty for the Python docummentation  [works only with Latex2e]
-%
-
-\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesPackage{python}
-             [1998/01/11 LaTeX package (Python markup)]
-
-\RequirePackage{textcomp}
-\RequirePackage{longtable}
-\RequirePackage{times}
-\RequirePackage{fancyvrb}
-\renewcommand{\sfdefault}{cmbr}
-
-% Uncomment these two lines to ignore the paper size and make the page 
-% size more like a typical published manual.
-%\renewcommand{\paperheight}{9in}
-%\renewcommand{\paperwidth}{8.5in}   % typical squarish manual
-%\renewcommand{\paperwidth}{7in}     % O'Reilly ``Programmming Python''
-
-% These packages can be used to add marginal annotations which indicate
-% index entries and labels; useful for reviewing this messy documentation!
-%
-%\RequirePackage{showkeys}
-%\RequirePackage{showidx}
-
-% If we ever want to indent paragraphs, this needs to be changed.
-% This is used inside the macros defined here instead of coding
-% \noindent directly.
-\let\py@parindent=\noindent
-
-% for PDF output, use maximal compression & a lot of other stuff
-% (test for PDF recommended by Tanmoy Bhattacharya <tanmoy@qcd.lanl.gov>)
-%
-\newif\ifpy@doing@page@targets
-\py@doing@page@targetsfalse
-
-\newif\ifpdf\pdffalse
-\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
-\else
-  \pdftrue
-  \input{pdfcolor}
-  \let\py@LinkColor=\NavyBlue
-  \let\py@NormalColor=\Black
-  \pdfcompresslevel=9
-  \pdfpagewidth=\paperwidth    % page width of PDF output
-  \pdfpageheight=\paperheight  % page height of PDF output
-  %
-  % Pad the number with '0' to 3 digits wide so no page name is a prefix
-  % of any other.
-  %
-  \newcommand{\py@targetno}[1]{\ifnum#1<100 0\fi\ifnum#1<10 0\fi#1}
-  \newcommand{\py@pageno}{\py@targetno\thepage}
-  %
-  % This definition allows the entries in the page-view of the ToC to be
-  % active links.  Some work, some don't.
-  %
-  \let\py@OldContentsline=\contentsline
-  %
-  % Backward compatibility hack: pdfTeX 0.13 defined \pdfannotlink,
-  % but it changed to \pdfstartlink in 0.14.  This let's us use either
-  % version and still get useful behavior.
-  %
-  \@ifundefined{pdfstartlink}{
-    \let\pdfstartlink=\pdfannotlink
-  }{}
-  %
-  % The \py@parindent here is a hack -- we're forcing pdfTeX into
-  % horizontal mode since \pdfstartlink requires that.
-  \def\py@pdfstartlink{%
-    \ifvmode\py@parindent\fi%
-    \pdfstartlink%
-  }
-  %
-  % Macro that takes two args: the name to link to and the content of
-  % the link.  This takes care of the PDF magic, getting the colors
-  % the same for each link, and avoids having lots of garbage all over 
-  % this style file.
-  \newcommand{\py@linkToName}[2]{%
-    \py@pdfstartlink attr{/Border [0 0 0]} goto name{#1}%
-      \py@LinkColor#2\py@NormalColor%
-    \pdfendlink%
-  }
-  % Compute the padded page number separately since we end up with a pair of
-  % \relax tokens; this gets the right string computed and works.
-  \renewcommand{\contentsline}[3]{%
-    \def\my@pageno{\py@targetno{#3}}%
-    \py@OldContentsline{#1}{\py@linkToName{page\my@pageno}{#2}}{#3}%
-  }
-  \AtEndDocument{
-    \def\_{\string_}
-    \InputIfFileExists{\jobname.bkm}{\pdfcatalog{/PageMode /UseOutlines}}{}
-  }
-  \newcommand{\py@target}[1]{%
-    \ifpy@doing@page@targets%
-      {\pdfdest name{#1} xyz}%
-    \fi%
-  }
-  \let\py@OldLabel=\label
-  \renewcommand{\label}[1]{%
-    \py@OldLabel{#1}%
-    \py@target{label-#1}%
-  }
-  % This stuff adds a page# destination to every PDF page, where # is three
-  % digits wide, padded with leading zeros.  This doesn't really help with
-  % the frontmatter, but does fine with the body.
-  %
-  % This is *heavily* based on the hyperref package.
-  %
-  \def\@begindvi{%
-    \unvbox \@begindvibox
-    \@hyperfixhead
-  }
-  \def\@hyperfixhead{%
-   \let\H@old@thehead\@thehead
-       \global\def\@foo{\py@target{page\py@pageno}}%
-     \expandafter\ifx\expandafter\@empty\H@old@thehead
-       \def\H@old@thehead{\hfil}\fi
-    \def\@thehead{\@foo\relax\H@old@thehead}%
-  }
-\fi\fi
-
-% Increase printable page size (copied from fullpage.sty)
-\topmargin 0pt
-\advance \topmargin by -\headheight
-\advance \topmargin by -\headsep
-
-% attempt to work a little better for A4 users
-\textheight \paperheight
-\advance\textheight by -2in
-
-\oddsidemargin 0pt
-\evensidemargin 0pt
-%\evensidemargin -.25in  % for ``manual size'' documents
-\marginparwidth 0.5in
-
-\textwidth \paperwidth
-\advance\textwidth by -2in
-
-
-% Style parameters and macros used by most documents here
-\raggedbottom
-\sloppy
-\parindent = 0mm
-\parskip = 2mm
-\hbadness = 5000                % don't print trivial gripes
-
-\pagestyle{empty}               % start this way; change for
-\pagenumbering{roman}           % ToC & chapters
-
-% Use this to set the font family for headers and other decor:
-\newcommand{\py@HeaderFamily}{\sffamily}
-
-% Set up abstract ways to get the normal and smaller font sizes that
-% work even in footnote context.
-\newif\ifpy@infootnote \py@infootnotefalse
-\let\py@oldmakefntext\@makefntext
-\def\@makefntext#1{%
-  \bgroup%
-    \py@infootnotetrue
-    \py@oldmakefntext{#1}%
-  \egroup%
-}
-\def\py@defaultsize{%
-  \ifpy@infootnote\footnotesize\else\normalsize\fi%
-}
-\def\py@smallsize{%
-  \ifpy@infootnote\scriptsize\else\small\fi%
-}
-
-% Redefine the 'normal' header/footer style when using "fancyhdr" package:
-\@ifundefined{fancyhf}{}{
-  % Use \pagestyle{normal} as the primary pagestyle for text.
-  \fancypagestyle{normal}{
-    \fancyhf{}
-    \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}}
-    \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}}
-    \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}}
-    \renewcommand{\headrulewidth}{0pt}
-    \renewcommand{\footrulewidth}{0.4pt}
-  }
-  % Update the plain style so we get the page number & footer line,
-  % but not a chapter or section title.  This is to keep the first
-  % page of a chapter and the blank page between chapters `clean.'
-  \fancypagestyle{plain}{
-    \fancyhf{}
-    \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}}
-    \renewcommand{\headrulewidth}{0pt}
-    \renewcommand{\footrulewidth}{0.4pt}
-  }
-  % Redefine \cleardoublepage so that the blank page between chapters
-  % gets the plain style and not the fancy style.  This is described
-  % in the documentation for the fancyhdr package by Piet von Oostrum.
-  \@ifundefined{chapter}{}{
-    \renewcommand{\cleardoublepage}{
-      \clearpage\if@openright \ifodd\c@page\else
-      \hbox{}
-      \thispagestyle{plain}
-      \newpage
-      \if@twocolumn\hbox{}\newpage\fi\fi\fi
-    }
-  }
-}
-
-% This sets up the {verbatim} environment to be indented and a minipage,
-% and to have all the other mostly nice properties that we want for
-% code samples.
-
-\let\py@OldVerbatim=\verbatim
-\let\py@OldEndVerbatim=\endverbatim
-\RequirePackage{verbatim}
-\let\py@OldVerbatimInput=\verbatiminput
-
-% Variable used by begin code command
-\newlength{\py@codewidth}
-
-\renewcommand{\verbatim}{%
-  \setlength{\parindent}{1cm}%
-  % Calculate the text width for the minipage:
-  \setlength{\py@codewidth}{\linewidth}%
-  \addtolength{\py@codewidth}{-\parindent}%
-  %
-  \par\indent%
-  \begin{minipage}[t]{\py@codewidth}%
-    \small%
-    \py@OldVerbatim%
-}
-\renewcommand{\endverbatim}{%
-    \py@OldEndVerbatim%
-  \end{minipage}%
-}
-\renewcommand{\verbatiminput}[1]{%
-  {\setlength{\parindent}{1cm}%
-   % Calculate the text width for the minipage:
-   \setlength{\py@codewidth}{\linewidth}%
-   \addtolength{\py@codewidth}{-\parindent}%
-   %
-   \small%
-   \begin{list}{}{\setlength{\leftmargin}{1cm}}
-     \item%
-     \py@OldVerbatimInput{#1}%
-   \end{list}
-  }%
-}
-
-% This does a similar thing for the {alltt} environment:
-\RequirePackage{alltt}
-\let\py@OldAllTT=\alltt
-\let\py@OldEndAllTT=\endalltt
-
-\renewcommand{\alltt}{%
-  \setlength{\parindent}{1cm}%
-  % Calculate the text width for the minipage:
-  \setlength{\py@codewidth}{\linewidth}%
-  \addtolength{\py@codewidth}{-\parindent}%
-  \let\e=\textbackslash%
-  %
-  \par\indent%
-  \begin{minipage}[t]{\py@codewidth}%
-    \small%
-    \py@OldAllTT%
-}
-\renewcommand{\endalltt}{%
-    \py@OldEndAllTT%
-  \end{minipage}%
-}
-
-
-\newcommand{\py@modulebadkey}{{--just-some-junk--}}
-
-
-%%  Lots of index-entry generation support.
-
-% Command to wrap around stuff that refers to function / module /
-% attribute names  in the index.  Default behavior: like \code{}.  To
-% just keep the index entries in the roman font, uncomment the second
-% definition; it matches O'Reilly style more.
-%
-\newcommand{\py@idxcode}[1]{\texttt{#1}}
-%\renewcommand{\py@idxcode}[1]{#1}
-
-% Command to generate two index entries (using subentries)
-\newcommand{\indexii}[2]{\index{#1!#2}\index{#2!#1}}
-
-% And three entries (using only one level of subentries)
-\newcommand{\indexiii}[3]{\index{#1!#2 #3}\index{#2!#3, #1}\index{#3!#1 #2}}
-
-% And four (again, using only one level of subentries)
-\newcommand{\indexiv}[4]{
-\index{#1!#2 #3 #4}
-\index{#2!#3 #4, #1}
-\index{#3!#4, #1 #2}
-\index{#4!#1 #2 #3}
-}
-
-% Command to generate a reference to a function, statement, keyword,
-% operator.
-\newcommand{\kwindex}[1]{\indexii{keyword}{#1@{\py@idxcode{#1}}}}
-\newcommand{\stindex}[1]{\indexii{statement}{#1@{\py@idxcode{#1}}}}
-\newcommand{\opindex}[1]{\indexii{operator}{#1@{\py@idxcode{#1}}}}
-\newcommand{\exindex}[1]{\indexii{exception}{#1@{\py@idxcode{#1}}}}
-\newcommand{\obindex}[1]{\indexii{object}{#1}}
-\newcommand{\bifuncindex}[1]{%
-  \index{#1@{\py@idxcode{#1()}} (built-in function)}}
-
-% Add an index entry for a module
-\newcommand{\py@refmodule}[2]{\index{#1@{\py@idxcode{#1}} (#2module)}}
-\newcommand{\refmodindex}[1]{\py@refmodule{#1}{}}
-\newcommand{\refbimodindex}[1]{\py@refmodule{#1}{built-in }}
-\newcommand{\refexmodindex}[1]{\py@refmodule{#1}{extension }}
-\newcommand{\refstmodindex}[1]{\py@refmodule{#1}{standard }}
-
-% Refer to a module's documentation using a hyperlink of the module's
-% name, at least if we're building PDF:
-\ifpdf
-  \newcommand{\refmodule}[2][\py@modulebadkey]{%
-    \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi%
-    \py@linkToName{label-module-\py@modulekey}{\module{#2}}%
-  }
-\else
-  \newcommand{\refmodule}[2][\py@modulebadkey]{\module{#2}}
-\fi
-
-% support for the module index
-\newif\ifpy@UseModuleIndex
-\py@UseModuleIndexfalse
-
-\newcommand{\makemodindex}{
-  \newwrite\modindexfile
-  \openout\modindexfile=mod\jobname.idx
-  \py@UseModuleIndextrue
-}
-
-\newcommand{\printmodindex}{
-  \@input@{mod\jobname.ind}
-}
-
-% Add the defining entry for a module
-\newcommand{\py@modindex}[2]{%
-  \renewcommand{\py@thismodule}{#1}
-  \setindexsubitem{(in module #1)}%
-  \index{#1@{\py@idxcode{#1}} (#2module)|textbf}%
-  \ifpy@UseModuleIndex%
-    \@ifundefined{py@modplat@\py@thismodulekey}{
-      \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}}{\thepage}}%
-    }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1} %
-        \emph{(\py@platformof[\py@thismodulekey]{})}}}{\thepage}}%
-    }
-  \fi%
-}
-
-% *** XXX *** THE NEXT FOUR MACROS ARE NOW OBSOLETE !!! ***
-
-% built-in & Python modules in the main distribution
-\newcommand{\bimodindex}[1]{\py@modindex{#1}{built-in }%
-  \typeout{*** MACRO bimodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-\newcommand{\stmodindex}[1]{\py@modindex{#1}{standard }%
-  \typeout{*** MACRO stmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-
-% Python & extension modules outside the main distribution
-\newcommand{\modindex}[1]{\py@modindex{#1}{}%
-  \typeout{*** MACRO modindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-\newcommand{\exmodindex}[1]{\py@modindex{#1}{extension }%
-  \typeout{*** MACRO exmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-
-% Additional string for an index entry
-\newif\ifpy@usingsubitem\py@usingsubitemfalse
-\newcommand{\py@indexsubitem}{}
-\newcommand{\setindexsubitem}[1]{\renewcommand{\py@indexsubitem}{ #1}%
-                                 \py@usingsubitemtrue}
-\newcommand{\ttindex}[1]{%
-  \ifpy@usingsubitem
-    \index{#1@{\py@idxcode{#1}}\py@indexsubitem}%
-  \else%
-    \index{#1@{\py@idxcode{#1}}}%
-  \fi%
-}
-\newcommand{\withsubitem}[2]{%
-  \begingroup%
-    \def\ttindex##1{\index{##1@{\py@idxcode{##1}} #1}}%
-    #2%
-  \endgroup%
-}
-
-
-% Module synopsis processing -----------------------------------------------
-%
-\newcommand{\py@thisclass}{}
-\newcommand{\py@thismodule}{}
-\newcommand{\py@thismodulekey}{}
-\newcommand{\py@thismoduletype}{}
-
-\newcommand{\py@standardIndexModule}[1]{\py@modindex{#1}{standard }}
-\newcommand{\py@builtinIndexModule}[1]{\py@modindex{#1}{built-in }}
-\newcommand{\py@extensionIndexModule}[1]{\py@modindex{#1}{extension }}
-\newcommand{\py@IndexModule}[1]{\py@modindex{#1}{}}
-
-\newif\ifpy@HaveModSynopsis       \py@HaveModSynopsisfalse
-\newif\ifpy@ModSynopsisFileIsOpen \py@ModSynopsisFileIsOpenfalse
-\newif\ifpy@HaveModPlatform       \py@HaveModPlatformfalse
-
-% \declaremodule[key]{type}{name}
-\newcommand{\declaremodule}[3][\py@modulebadkey]{
-  \py@openModSynopsisFile
-  \renewcommand{\py@thismoduletype}{#2}
-  \ifx\py@modulebadkey#1
-    \renewcommand{\py@thismodulekey}{#3}
-  \else
-    \renewcommand{\py@thismodulekey}{#1}
-  \fi
-  \@ifundefined{py@#2IndexModule}{%
-    \typeout{*** MACRO declaremodule called with unknown module type: `#2'}
-    \py@IndexModule{#3}%
-  }{%
-    \csname py@#2IndexModule\endcsname{#3}%
-  }
-  \label{module-\py@thismodulekey}
-}
-\newif\ifpy@ModPlatformFileIsOpen \py@ModPlatformFileIsOpenfalse
-\newcommand{\py@ModPlatformFilename}{\jobname.pla}
-\newcommand{\platform}[1]{
-  \ifpy@ModPlatformFileIsOpen\else
-    \newwrite\py@ModPlatformFile
-    \openout\py@ModPlatformFile=\py@ModPlatformFilename
-    \py@ModPlatformFileIsOpentrue
-  \fi
-}
-\InputIfFileExists{\jobname.pla}{}{}
-\newcommand{\py@platformof}[2][\py@modulebadkey]{%
-  \ifx\py@modulebadkey#1 \def\py@key{#2}%
-  \else \def\py@key{#1}%
-  \fi%
-  \csname py@modplat@\py@key\endcsname%
-}
-\newcommand{\ignorePlatformAnnotation}[1]{}
-
-% \moduleauthor{name}{email}
-\newcommand{\moduleauthor}[2]{}
-
-% \sectionauthor{name}{email}
-\newcommand{\sectionauthor}[2]{}
-
-
-\newcommand{\py@defsynopsis}{Module has no synopsis.}
-\newcommand{\py@modulesynopsis}{\py@defsynopsis}
-\newcommand{\modulesynopsis}[1]{
-  \py@HaveModSynopsistrue
-  \renewcommand{\py@modulesynopsis}{#1}
-}
-
-% define the file
-\newwrite\py@ModSynopsisFile
-
-% hacked from \addtocontents from latex.ltx:
-\long\def\py@writeModSynopsisFile#1{%
-  \protected@write\py@ModSynopsisFile%
-      {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
-      {\string#1}%
-}
-\newcommand{\py@closeModSynopsisFile}{
-  \ifpy@ModSynopsisFileIsOpen
-    \closeout\py@ModSynopsisFile
-    \py@ModSynopsisFileIsOpenfalse
-  \fi
-}
-\newcommand{\py@openModSynopsisFile}{
-  \ifpy@ModSynopsisFileIsOpen\else
-    \openout\py@ModSynopsisFile=\py@ModSynopsisFilename
-    \py@ModSynopsisFileIsOpentrue
-  \fi
-}
-
-\newcommand{\py@ProcessModSynopsis}{
-  \ifpy@HaveModSynopsis
-    \py@writeModSynopsisFile{\modulesynopsis%
-      {\py@thismodulekey}{\py@thismodule}%
-      {\py@thismoduletype}{\py@modulesynopsis}}%
-    \py@HaveModSynopsisfalse
-  \fi
-  \renewcommand{\py@modulesynopsis}{\py@defsynopsis}
-}
-\AtEndDocument{\py@ProcessModSynopsis\py@closeModSynopsisFile}
-
-
-\long\def\py@writeModPlatformFile#1{%
-  \protected@write\py@ModPlatformFile%
-    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
-    {\string#1}%
-}
-
-
-\newcommand{\localmoduletable}{
-  \IfFileExists{\py@ModSynopsisFilename}{
-    \begin{synopsistable}
-      \input{\py@ModSynopsisFilename}
-    \end{synopsistable}
-  }{}
-}
-
-\ifpdf
-  \newcommand{\py@ModSynopsisSummary}[4]{%
-    \py@linkToName{label-module-#1}{\bfcode{#2}} & #4\\
-  }
-\else
-  \newcommand{\py@ModSynopsisSummary}[4]{\bfcode{#2} & #4\\}
-\fi
-\newenvironment{synopsistable}{
-  % key, name, type, synopsis
-  \let\modulesynopsis=\py@ModSynopsisSummary
-  \begin{tabular}{ll}
-}{
-  \end{tabular}
-}
-%
-% --------------------------------------------------------------------------
-
-
-\newcommand{\py@reset}{
-  \py@usingsubitemfalse
-  \py@ProcessModSynopsis
-  \renewcommand{\py@thisclass}{}
-  \renewcommand{\py@thismodule}{}
-  \renewcommand{\py@thismodulekey}{}
-  \renewcommand{\py@thismoduletype}{}
-}
-
-% Augment the sectioning commands used to get our own font family in place,
-% and reset some internal data items:
-\renewcommand{\section}{\py@reset%
-                        \@startsection{section}{1}{\z@}%
-                                    {-3.5ex \@plus -1ex \@minus -.2ex}%
-                                    {2.3ex \@plus.2ex}%
-                                    {\reset@font\Large\py@HeaderFamily}}
-\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
-                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
-                                    {1.5ex \@plus .2ex}%
-                                    {\reset@font\large\py@HeaderFamily}}
-\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
-                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
-                                    {1.5ex \@plus .2ex}%
-                                    {\reset@font\normalsize\py@HeaderFamily}}
-\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
-                                    {3.25ex \@plus1ex \@minus.2ex}%
-                                    {-1em}%
-                                    {\reset@font\normalsize\py@HeaderFamily}}
-\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}%
-                                    {3.25ex \@plus1ex \@minus .2ex}%
-                                    {-1em}%
-                                    {\reset@font\normalsize\py@HeaderFamily}}
-
-
-% Now for a lot of semantically-loaded environments that do a ton of magical
-% things to get the right formatting and index entries for the stuff in
-% Python modules and C API.
-
-
-% {fulllineitems} is used in one place in libregex.tex, but is really for
-% internal use in this file.
-%
-\newcommand{\py@itemnewline}[1]{%
-  \@tempdima\linewidth%
-  \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}%
-}
-
-\newenvironment{fulllineitems}{
-  \begin{list}{}{\labelwidth \leftmargin \labelsep 0pt
-                 \rightmargin 0pt \topsep -\parskip \partopsep \parskip
-                 \itemsep -\parsep
-                 \let\makelabel=\py@itemnewline}
-}{\end{list}}
-
-% \optional is mostly for use in the arguments parameters to the various
-% {*desc} environments defined below, but may be used elsewhere.  Known to
-% be used in the debugger chapter.
-%
-% Typical usage:
-%
-%     \begin{funcdesc}{myfunc}{reqparm\optional{, optparm}}
-%                                    ^^^       ^^^
-%                          No space here       No space here
-%
-% When a function has multiple optional parameters, \optional should be
-% nested, not chained.  This is right:
-%
-%     \begin{funcdesc}{myfunc}{\optional{parm1\optional{, parm2}}}
-%
-\let\py@badkey=\@undefined
-
-\newcommand{\optional}[1]{%
-  {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}}
-
-% This can be used when a function or method accepts an varying number 
-% of arguments, such as by using the *args syntax in the parameter list.
-\newcommand{\py@moreargs}{...}
-
-% This can be used when you don't want to document the parameters to a 
-% function or method, but simply state that it's an alias for
-% something else.
-\newcommand{\py@unspecified}{...}
-
-
-\newlength{\py@argswidth}
-\newcommand{\py@sigparams}[1]{%
-  \parbox[t]{\py@argswidth}{\py@varvars{#1}\code{)}}}
-\newcommand{\py@sigline}[2]{%
-  \settowidth{\py@argswidth}{#1\code{(}}%
-  \addtolength{\py@argswidth}{-2\py@argswidth}%
-  \addtolength{\py@argswidth}{\textwidth}%
-  \item[#1\code{(}\py@sigparams{#2}]}
-
-% C functions ------------------------------------------------------------
-% \begin{cfuncdesc}[refcount]{type}{name}{arglist}
-% Note that the [refcount] slot should only be filled in by
-% tools/anno-api.py; it pulls the value from the refcounts database.
-\newcommand{\cfuncline}[3]{
-  \py@sigline{\code{#1 \bfcode{#2}}}{#3}%
-  \index{#2@{\py@idxcode{#2()}}}
-}
-\newenvironment{cfuncdesc}[4][\py@badkey]{
-  \begin{fulllineitems}
-    \cfuncline{#2}{#3}{#4}
-    \ifx\@undefined#1\relax\else%
-      \emph{Return value: \textbf{#1}.}\\
-    \fi
-}{\end{fulllineitems}}
-
-% C variables ------------------------------------------------------------
-% \begin{cvardesc}{type}{name}
-\newenvironment{cvardesc}[2]{
-  \begin{fulllineitems}
-    \item[\code{#1 \bfcode{#2}}\index{#2@{\py@idxcode{#2}}}]
-}{\end{fulllineitems}}
-
-% C data types -----------------------------------------------------------
-% \begin{ctypedesc}[index name]{typedef name}
-\newenvironment{ctypedesc}[2][\py@badkey]{
-  \begin{fulllineitems}
-    \item[\bfcode{#2}%
-    \ifx\@undefined#1\relax%
-      \index{#2@{\py@idxcode{#2}} (C type)}
-    \else%
-      \index{#2@{\py@idxcode{#1}} (C type)}
-    \fi]
-}{\end{fulllineitems}}
-
-% C type fields ----------------------------------------------------------
-% \begin{cmemberdesc}{container type}{ctype}{membername}
-\newcommand{\cmemberline}[3]{
-  \item[\code{#2 \bfcode{#3}}]
-  \index{#3@{\py@idxcode{#3}} (#1 member)}
-}
-\newenvironment{cmemberdesc}[3]{
-  \begin{fulllineitems}
-    \cmemberline{#1}{#2}{#3}
-}{\end{fulllineitems}}
-
-% Funky macros -----------------------------------------------------------
-% \begin{csimplemacrodesc}{name}
-% -- "simple" because it has no args; NOT for constant definitions!
-\newenvironment{csimplemacrodesc}[1]{
-  \begin{fulllineitems}
-    \item[\bfcode{#1}\index{#1@{\py@idxcode{#1}} (macro)}]
-}{\end{fulllineitems}}
-
-% simple functions (not methods) -----------------------------------------
-% \begin{funcdesc}{name}{args}
-\newcommand{\funcline}[2]{%
-  \funclineni{#1}{#2}%
-  \index{#1@{\py@idxcode{#1()}} (in module \py@thismodule)}}
-\newenvironment{funcdesc}[2]{
-  \begin{fulllineitems}
-    \funcline{#1}{#2}
-}{\end{fulllineitems}}
-
-% similar to {funcdesc}, but doesn't add to the index
-\newcommand{\funclineni}[2]{%
-  \py@sigline{\bfcode{#1}}{#2}}
-\newenvironment{funcdescni}[2]{
-  \begin{fulllineitems}
-    \funclineni{#1}{#2}
-}{\end{fulllineitems}}
-
-% classes ----------------------------------------------------------------
-% \begin{classdesc}{name}{constructor args}
-\newcommand{\classline}[2]{
-  \py@sigline{\strong{class }\bfcode{#1}}{#2}%
-  \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)}}
-\newenvironment{classdesc}[2]{
-  % Using \renewcommand doesn't work for this, for unknown reasons:
-  \global\def\py@thisclass{#1}
-  \begin{fulllineitems}
-    \classline{#1}{#2}
-}{\end{fulllineitems}}
-
-% \begin{classdesc*}{name}
-\newenvironment{classdesc*}[1]{
-  % Using \renewcommand doesn't work for this, for unknown reasons:
-  \global\def\py@thisclass{#1}
-  \begin{fulllineitems}
-    \item[\strong{class }\code{\bfcode{#1}}%
-      \index{#1@{\py@idxcode{#1}} (class in \py@thismodule)}]
-}{\end{fulllineitems}}
-
-% \begin{excclassdesc}{name}{constructor args}
-% but indexes as an exception
-\newenvironment{excclassdesc}[2]{
-  % Using \renewcommand doesn't work for this, for unknown reasons:
-  \global\def\py@thisclass{#1}
-  \begin{fulllineitems}
-    \py@sigline{\strong{exception }\bfcode{#1}}{#2}%
-    \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)}
-}{\end{fulllineitems}}
-
-% There is no corresponding {excclassdesc*} environment.  To describe
-% a class exception without parameters, use the {excdesc} environment.
-
-
-\let\py@classbadkey=\@undefined
-
-% object method ----------------------------------------------------------
-% \begin{methoddesc}[classname]{methodname}{args}
-\newcommand{\methodline}[3][\@undefined]{
-  \methodlineni{#2}{#3}
-  \ifx\@undefined#1\relax
-    \index{#2@{\py@idxcode{#2()}} (\py@thisclass\ method)}
-  \else
-    \index{#2@{\py@idxcode{#2()}} (#1 method)}
-  \fi
-}
-\newenvironment{methoddesc}[3][\@undefined]{
-  \begin{fulllineitems}
-    \ifx\@undefined#1\relax
-      \methodline{#2}{#3}
-    \else
-      \def\py@thisclass{#1}
-      \methodline{#2}{#3}
-    \fi
-}{\end{fulllineitems}}
-
-% similar to {methoddesc}, but doesn't add to the index
-% (never actually uses the optional argument)
-\newcommand{\methodlineni}[3][\py@classbadkey]{%
-  \py@sigline{\bfcode{#2}}{#3}}
-\newenvironment{methoddescni}[3][\py@classbadkey]{
-  \begin{fulllineitems}
-    \methodlineni{#2}{#3}
-}{\end{fulllineitems}}
-
-% object data attribute --------------------------------------------------
-% \begin{memberdesc}[classname]{membername}
-\newcommand{\memberline}[2][\py@classbadkey]{%
-  \ifx\@undefined#1\relax
-    \memberlineni{#2}
-    \index{#2@{\py@idxcode{#2}} (\py@thisclass\ attribute)}
-  \else
-    \memberlineni{#2}
-    \index{#2@{\py@idxcode{#2}} (#1 attribute)}
-  \fi
-}
-\newenvironment{memberdesc}[2][\py@classbadkey]{
-  \begin{fulllineitems}
-    \ifx\@undefined#1\relax
-      \memberline{#2}
-    \else
-      \def\py@thisclass{#1}
-      \memberline{#2}
-    \fi
-}{\end{fulllineitems}}
-
-% similar to {memberdesc}, but doesn't add to the index
-% (never actually uses the optional argument)
-\newcommand{\memberlineni}[2][\py@classbadkey]{\item[\bfcode{#2}]}
-\newenvironment{memberdescni}[2][\py@classbadkey]{
-  \begin{fulllineitems}
-    \memberlineni{#2}
-}{\end{fulllineitems}}
-
-% For exceptions: --------------------------------------------------------
-% \begin{excdesc}{name}
-%  -- for constructor information, use excclassdesc instead
-\newenvironment{excdesc}[1]{
-  \begin{fulllineitems}
-    \item[\strong{exception }\bfcode{#1}%
-          \index{#1@{\py@idxcode{#1}} (exception in \py@thismodule)}]
-}{\end{fulllineitems}}
-
-% Module data or constants: ----------------------------------------------
-% \begin{datadesc}{name}
-\newcommand{\dataline}[1]{%
-  \datalineni{#1}\index{#1@{\py@idxcode{#1}} (data in \py@thismodule)}}
-\newenvironment{datadesc}[1]{
-  \begin{fulllineitems}
-    \dataline{#1}
-}{\end{fulllineitems}}
-
-% similar to {datadesc}, but doesn't add to the index
-\newcommand{\datalineni}[1]{\item[\bfcode{#1}]\nopagebreak}
-\newenvironment{datadescni}[1]{
-  \begin{fulllineitems}
-    \datalineni{#1}
-}{\end{fulllineitems}}
-
-% bytecode instruction ---------------------------------------------------
-% \begin{opcodedesc}{name}{var}
-% -- {var} may be {}
-\newenvironment{opcodedesc}[2]{
-  \begin{fulllineitems}
-    \item[\bfcode{#1}\quad\var{#2}]
-}{\end{fulllineitems}}
-
-% generic description ----------------------------------------------------
-\newcommand{\descline}[1]{%
-  \item[\bfcode{#1}]\nopagebreak%
-}
-\newenvironment{describe}[1]{
-  \begin{fulllineitems}
-    \descline{#1}
-}{\end{fulllineitems}}
-
-\newcommand{\nodename}[1]{\label{#1}}
-
-% For these commands, use \command{} to get the typography right, not 
-% {\command}.  This works better with the texinfo translation.
-\newcommand{\ABC}{{\sc abc}}
-\newcommand{\UNIX}{{\sc Unix}}
-\newcommand{\POSIX}{POSIX}
-\newcommand{\ASCII}{{\sc ascii}}
-\newcommand{\Cpp}{C\protect\raisebox{.18ex}{++}}
-\newcommand{\C}{C}
-\newcommand{\EOF}{{\sc eof}}
-\newcommand{\NULL}{\constant{NULL}}
-\newcommand{\infinity}{\ensuremath{\infty}}
-\newcommand{\plusminus}{\ensuremath{\pm}}
-
-% \guilabel{Start}
-\newcommand{\guilabel}[1]{\textsf{#1}}
-% \menuselection{Start \sub Programs \sub Python}
-\newcommand{\menuselection}[1]{\guilabel{{\def\sub{ \ensuremath{>} }#1}}}
-
-% Also for consistency: spell Python "Python", not "python"!
-
-% code is the most difficult one...
-\newcommand{\code}[1]{\textrm{\@vobeyspaces\@noligs\def\{{\char`\{}\def\}{\char`\}}\def\~{\char`\~}\def\^{\char`\^}\def\e{\char`\\}\def\${\char`\$}\def\#{\char`\#}\def\&{\char`\&}\def\%{\char`\%}%
-\texttt{#1}}}
-
-\newcommand{\bfcode}[1]{\code{\bfseries#1}} % bold-faced code font
-\newcommand{\csimplemacro}[1]{\code{#1}}
-\newcommand{\kbd}[1]{\code{#1}}
-\newcommand{\samp}[1]{`\code{#1}'}
-\newcommand{\var}[1]{%
-  \ifmmode%
-    \hbox{\py@defaultsize\textrm{\textit{#1\/}}}%
-  \else%
-    \py@defaultsize\textrm{\textit{#1\/}}%
-  \fi%
-}
-\renewcommand{\emph}[1]{{\em #1}}
-\newcommand{\dfn}[1]{\emph{#1}}
-\newcommand{\strong}[1]{{\bf #1}}
-% let's experiment with a new font:
-\newcommand{\file}[1]{`\filenq{#1}'}
-\newcommand{\filenq}[1]{{\py@smallsize\textsf{\let\e=\textbackslash#1}}}
-
-% Use this def/redef approach for \url{} since hyperref defined this already,
-% but only if we actually used hyperref:
-%\ifpdf
-%  \newcommand{\url}[1]{{%
-%    \py@pdfstartlink%
-%    attr{ /Border [0 0 0] }%
-%    user{%
-%      /Subtype/Link%
-%      /A<<%
-%      /Type/Action%
-%      /S/URI%
-%      /URI(#1)%
-%      >>%
-%    }%
-%    \py@LinkColor%                      color of the link text
-%    \py@smallsize\sf #1%
-%    \py@NormalColor%                    Turn it back off; these are declarative
-%    \pdfendlink}%                       and don't appear bound to the current
-%  }%                                    formatting "box".
-%\else
-%  \newcommand{\url}[1]{\mbox{\py@smallsize\textsf{#1}}}
-%\fi
-\newcommand{\email}[1]{{\py@smallsize\textsf{#1}}}
-\newcommand{\newsgroup}[1]{{\py@smallsize\textsf{#1}}}
-
-\newcommand{\py@varvars}[1]{{%
-  {\let\unspecified=\py@unspecified%
-   \let\moreargs=\py@moreargs%
-   \var{#1}}}}
-
-% I'd really like to get rid of this!
-\newif\iftexi\texifalse
-
-% This is used to get l2h to put the copyright and abstract on
-% a separate HTML page.
-\newif\ifhtml\htmlfalse
-
-
-% These should be used for all references to identifiers which are
-% used to refer to instances of specific language constructs.  See the
-% names for specific semantic assignments.
-%
-% For now, don't do anything really fancy with them; just use them as
-% logical markup.  This might change in the future.
-%
-\newcommand{\module}[1]{\texttt{#1}}
-\newcommand{\keyword}[1]{\texttt{#1}}
-\newcommand{\exception}[1]{\texttt{#1}}
-\newcommand{\class}[1]{\texttt{#1}}
-\newcommand{\function}[1]{\texttt{#1}}
-\newcommand{\member}[1]{\texttt{#1}}
-\newcommand{\method}[1]{\texttt{#1}}
-
-\newcommand{\pytype}[1]{#1}             % built-in Python type
-
-\newcommand{\cfunction}[1]{\texttt{#1}}
-\newcommand{\ctype}[1]{\texttt{#1}}     % C struct or typedef name
-\newcommand{\cdata}[1]{\texttt{#1}}     % C variable, typically global
-
-\newcommand{\mailheader}[1]{{\py@smallsize\textsf{#1:}}}
-\newcommand{\mimetype}[1]{{\py@smallsize\textsf{#1}}}
-% The \! is a "negative thin space" in math mode.
-\newcommand{\regexp}[1]{%
-  {\tiny$^{^\lceil}\!\!$%
-   {\py@defaultsize\code{#1}}%
-   $\!\rfloor\!$%
-  }}
-\newcommand{\envvar}[1]{%
-  #1%
-  \index{#1}%
-  \index{environment variables!{#1}}%
-}
-\newcommand{\makevar}[1]{#1}            % variable in a Makefile
-\newcommand{\character}[1]{\samp{#1}}
-
-% constants defined in Python modules or C headers, not language constants:
-\newcommand{\constant}[1]{\code{#1}}    % manifest constant, not syntactic
-
-\newcommand{\manpage}[2]{{\emph{#1}(#2)}}
-\newcommand{\pep}[1]{PEP #1\index{Python Enhancement Proposals!PEP #1}}
-\newcommand{\rfc}[1]{RFC #1\index{RFC!RFC #1}}
-\newcommand{\program}[1]{\strong{#1}}
-\newcommand{\programopt}[1]{\strong{#1}}
-% Note that \longprogramopt provides the '--'!
-\newcommand{\longprogramopt}[1]{\strong{-{}-#1}}
-
-% \ulink{link text}{URL}
-\ifpdf
-  \newcommand{\ulink}[2]{{%
-    % For PDF, we *should* only generate a link when the URL is absolute.
-    \py@pdfstartlink%
-    attr{ /Border [0 0 0] }%
-    user{%
-      /Subtype/Link%
-      /A<<%
-      /Type/Action%
-      /S/URI%
-      /URI(#2)%
-      >>%
-    }%
-    \py@LinkColor%                              color of the link text
-    #1%
-    \py@NormalColor%                    Turn it back off; these are declarative
-    \pdfendlink}%                       and don't appear bound to the current
-  }%                                    formatting "box".
-\else
-  \newcommand{\ulink}[2]{#1}
-\fi
-
-% cited titles:  \citetitle{Title of Work}
-%       online:  \citetitle[url-to-resource]{Title of Work}
-\ifpdf
-  \newcommand{\citetitle}[2][\py@modulebadkey]{%
-    \ifx\py@modulebadkey#1\emph{#2}\else\ulink{\emph{#2}}{#1}\fi%
-  }
-\else
-  \newcommand{\citetitle}[2][URL]{\emph{#2}}
-\fi
-
-
-
-% This version is being checked in for the historical record; it shows
-% how I've managed to get some aspects of this to work.  It will not
-% be used in practice, so a subsequent revision will change things
-% again.  This version has problems, but shows how to do something
-% that proved more tedious than I'd expected, so I don't want to lose
-% the example completely.
-%
-\newcommand{\grammartoken}[1]{\texttt{#1}}
-\newenvironment{productionlist}[1][\py@badkey]{
-  \def\optional##1{{\Large[}##1{\Large]}}
-  \def\production##1##2{\code{##1}&::=&\code{##2}\\}
-  \def\productioncont##1{& &\code{##1}\\}
-  \def\token##1{##1}
-  \let\grammartoken=\token
-  \parindent=2em
-  \indent
-  \begin{tabular}{lcl}
-}{%
-  \end{tabular}
-}
-
-\newlength{\py@noticelength}
-
-\newcommand{\py@heavybox}{
-  \setlength{\fboxrule}{1pt}
-  \setlength{\fboxsep}{7pt}
-  \setlength{\py@noticelength}{\linewidth}
-  \addtolength{\py@noticelength}{-2\fboxsep}
-  \addtolength{\py@noticelength}{-2\fboxrule}
-  \setlength{\shadowsize}{3pt}
-  \Sbox
-  \minipage{\py@noticelength}
-}
-\newcommand{\py@endheavybox}{
-  \endminipage
-  \endSbox
-  \fbox{\TheSbox}
-}
-
-% a 'note' is as plain as it gets:
-\newcommand{\py@noticelabel@note}{Note:}
-\newcommand{\py@noticestart@note}{}
-\newcommand{\py@noticeend@note}{}
-
-% a 'warning' gets more visible distinction:
-\newcommand{\py@noticelabel@warning}{Warning:}
-\newcommand{\py@noticestart@warning}{\py@heavybox}
-\newcommand{\py@noticeend@warning}{\py@endheavybox}
-
-\newenvironment{notice}[1][note]{
-  \def\py@noticetype{#1}
-  \csname py@noticestart@#1\endcsname
-  \par\strong{\csname py@noticelabel@#1\endcsname}
-}{\csname py@noticeend@\py@noticetype\endcsname}
-\newcommand{\note}[1]{\strong{\py@noticelabel@note} #1}
-\newcommand{\warning}[1]{\strong{\py@noticelabel@warning} #1}
-
-% Deprecation stuff.
-% Should be extended to allow an index / list of deprecated stuff.  But
-% there's a lot of stuff that needs to be done to make that automatable.
-%
-% First parameter is the release number that deprecates the feature, the
-% second is the action the should be taken by users of the feature.
-%
-% Example:
-%  \deprecated{1.5.1}{Use \method{frobnicate()} instead.}
-%
-\newcommand{\deprecated}[2]{%
-  \strong{Deprecated since release #1.}  #2\par}
-
-% New stuff.
-% This should be used to mark things which have been added to the
-% development tree but that aren't in the release, but are documented.
-% This allows release of documentation that already includes updated
-% descriptions.  Place at end of descriptor environment.
-%
-% Example:
-%  \versionadded{1.5.2}
-%  \versionchanged[short explanation]{2.0}
-%
-\newcommand{\versionadded}[2][\py@badkey]{%
-  \ifx\@undefined#1\relax%
-    {  New in version #2.  }%
-  \else%
-    {  New in version #2:\ #1  }%
-  \fi%
-}
-\newcommand{\versionchanged}[2][\py@badkey]{%
-  \ifx\@undefined#1\relax%
-    {  Changed in version #2.  }%
-  \else%
-    {  Changed in version #2:\ #1  }%
-  \fi%
-}
-
-
-% Tables.
-%
-\newenvironment{tableii}[4]{%
-  \begin{center}%
-    \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}%
-    \begin{tabular}{#1}\strong{#3}&\strong{#4} \\* \hline%
-}{%
-    \end{tabular}%
-  \end{center}%
-}
-
-\newenvironment{longtableii}[4]{%
-  \begin{center}%
-    \def\lineii##1##2{\csname#2\endcsname{##1}&##2\\}%
-    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4} \\* \hline\endhead%
-}{%
-    \end{longtable}%
-  \end{center}%
-}
-
-\newenvironment{tableiii}[5]{%
-  \begin{center}%
-    \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}%
-    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5} \\%
-      \hline%
-}{%
-    \end{tabular}%
-  \end{center}%
-}
-
-\newenvironment{longtableiii}[5]{%
-  \begin{center}%
-    \def\lineiii##1##2##3{\csname#2\endcsname{##1}&##2&##3\\}%
-    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5} \\%
-      \hline\endhead%
-}{%
-    \end{longtable}%
-  \end{center}%
-}
-
-\newenvironment{tableiv}[6]{%
-  \begin{center}%
-    \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}%
-    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6} \\%
-      \hline%
-}{%
-    \end{tabular}%
-  \end{center}%
-}
-
-\newenvironment{longtableiv}[6]{%
-  \begin{center}%
-    \def\lineiv##1##2##3##4{\csname#2\endcsname{##1}&##2&##3&##4\\}%
-    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}%
-      \\%
-      \hline\endhead%
-}{%
-    \end{longtable}%
-  \end{center}%
-}
-
-\newenvironment{tablev}[7]{%
-  \begin{center}%
-    \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}%
-    \begin{tabular}{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7} \\%
-      \hline%
-}{%
-    \end{tabular}%
-  \end{center}%
-}
-
-\newenvironment{longtablev}[7]{%
-  \begin{center}%
-    \def\linev##1##2##3##4##5{\csname#2\endcsname{##1}&##2&##3&##4&##5\\}%
-    \begin{longtable}[c]{#1}\strong{#3}&\strong{#4}&\strong{#5}&\strong{#6}&\strong{#7}%
-      \\%
-      \hline\endhead%
-}{%
-    \end{longtable}%
-  \end{center}%
-}
-
-% XXX Don't think we can use this yet, though it cleans up some
-% tedious markup.  There's no equivalent for the HTML transform yet,
-% and that needs to exist.  I don't know how to write it.
-%
-% This should really have something that makes it easier to bind a
-% table's ``Notes'' column and an associated tablenotes environment,
-% and generates the right magic for getting the numbers right in the
-% table.
-%
-% So this is quite incomplete.
-%
-\newcounter{py@tablenotescounter}
-\newenvironment{tablenotes}{%
-  \noindent Notes:
-  \par
-  \setcounter{py@tablenotescounter}{0}
-  \begin{list}{(\arabic{py@tablenotescounter})}%
-              {\usecounter{py@tablenotescounter}}
-}{\end{list}}
-
-
-% Cross-referencing (AMK, new impl. FLD)
-% Sample usage:
-%  \begin{seealso}
-%    \seemodule{rand}{Uniform random number generator.}; % Module xref
-%    \seetext{\emph{Encyclopedia Britannica}}.           % Ref to a book
-% 
-%    % A funky case: module name contains '_'; have to supply an optional key
-%    \seemodule[copyreg]{copy_reg}{Interface constructor registration for
-%                                  \module{pickle}.}
-%  \end{seealso}
-%
-% Note that the last parameter for \seemodule and \seetext should be complete
-% sentences and be terminated with the proper punctuation.
-
-\ifpdf
-  \newcommand{\py@seemodule}[3][\py@modulebadkey]{%
-    \par%
-    \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi%
-    \begin{fulllineitems}
-      \item[\py@linkToName{label-module-\py@modulekey}{Module \module{#2}}
-            (section \ref{module-\py@modulekey}):]
-      #3
-    \end{fulllineitems}
-  }
-\else
-  \newcommand{\py@seemodule}[3][\py@modulebadkey]{%
-    \par%
-    \ifx\py@modulebadkey#1\def\py@modulekey{#2}\else\def\py@modulekey{#1}\fi%
-    \begin{fulllineitems}
-      \item[Module \module{#2} (section \ref{module-\py@modulekey}):]
-      #3
-    \end{fulllineitems}
-  }
-\fi
-
-% \seelink{url}{link text}{why it's interesting}
-\newcommand{\py@seelink}[3]{%
-  \par
-  \begin{fulllineitems}
-    \item[\ulink{#2}{#1}]
-    #3
-  \end{fulllineitems}
-}
-% \seetitle[url]{title}{why it's interesting}
-\newcommand{\py@seetitle}[3][\py@modulebadkey]{%
-  \par
-  \begin{fulllineitems}
-    \item[\citetitle{#2}]
-    \ifx\py@modulebadkey#1\else
-      \item[{\small{(\url{#1})}}]
-    \fi
-    #3
-  \end{fulllineitems}
-}
-% \seepep{number}{title}{why it's interesting}
-\newcommand{\py@seepep}[3]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\pep{#1}, ``\emph{#2}'']
-    #3
-  \end{fulllineitems}
-}
-% \seerfc{number}{title}{why it's interesting}
-\newcommand{\py@seerfc}[3]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\rfc{#1}, ``\emph{#2}'']
-    #3
-  \end{fulllineitems}
-}
-% \seeurl{url}{why it's interesting}
-\newcommand{\py@seeurl}[2]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\url{#1}]
-    #2
-  \end{fulllineitems}
-}
-
-\newenvironment{seealso*}{
-  \par
-  \def\seetext##1{\par{##1}}
-  \let\seemodule=\py@seemodule
-  \let\seepep=\py@seepep
-  \let\seerfc=\py@seerfc
-  \let\seetitle=\py@seetitle
-  \let\seeurl=\py@seeurl
-  \let\seelink=\py@seelink
-}{\par}
-\newenvironment{seealso}{
-  \par
-  \strong{See Also:}
-  \par
-  \def\seetext##1{\par{##1}}
-  \let\seemodule=\py@seemodule
-  \let\seepep=\py@seepep
-  \let\seerfc=\py@seerfc
-  \let\seetitle=\py@seetitle
-  \let\seeurl=\py@seeurl
-  \let\seelink=\py@seelink
-}{\par}
-
-% Allow the Python release number to be specified independently of the
-% \date{}.  This allows the date to reflect the document's date and
-% release to specify the Python release that is documented.
-%
-\newcommand{\py@release}{}
-\newcommand{\version}{}
-\newcommand{\shortversion}{}
-\newcommand{\releaseinfo}{}
-\newcommand{\releasename}{Release}
-\newcommand{\release}[1]{%
-  \renewcommand{\py@release}{\releasename\space\version}%
-  \renewcommand{\version}{#1}}
-\newcommand{\setshortversion}[1]{%
-  \renewcommand{\shortversion}{#1}}
-\newcommand{\setreleaseinfo}[1]{%
-  \renewcommand{\releaseinfo}{#1}}
-
-% Allow specification of the author's address separately from the
-% author's name.  This can be used to format them differently, which
-% is a good thing.
-%
-\newcommand{\py@authoraddress}{}
-\newcommand{\authoraddress}[1]{\renewcommand{\py@authoraddress}{#1}}
-\let\developersaddress=\authoraddress
-\let\developer=\author
-\let\developers=\author
-
-% This sets up the fancy chapter headings that make the documents look
-% at least a little better than the usual LaTeX output.
-%
-\@ifundefined{ChTitleVar}{}{
-  \ChNameVar{\raggedleft\normalsize\py@HeaderFamily}
-  \ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily}
-  \ChTitleVar{\raggedleft \rm\Huge\py@HeaderFamily}
-  % This creates chapter heads without the leading \vspace*{}:
-  \def\@makechapterhead#1{%
-    {\parindent \z@ \raggedright \normalfont
-      \ifnum \c@secnumdepth >\m@ne
-        \DOCH
-      \fi
-      \interlinepenalty\@M
-      \DOTI{#1}
-    }
-  }
-}
-
-
-% Definition lists; requested by AMK for HOWTO documents.  Probably useful
-% elsewhere as well, so keep in in the general style support.
-%
-\newenvironment{definitions}{%
-  \begin{description}%
-  \def\term##1{\item[##1]\mbox{}\\*[0mm]}
-}{%
-  \end{description}%
-}
-
-% Tell TeX about pathological hyphenation cases:
-\hyphenation{Base-HTTP-Re-quest-Hand-ler}

File sphinx/texinputs/sphinx.sty

+%
+% sphinx.sty
+%
+% Adapted from the old python.sty, mostly written by Fred Drake,
+% by Georg Brandl.
+%
+
+\NeedsTeXFormat{LaTeX2e}[1995/12/01]
+\ProvidesPackage{sphinx}
+             [2007/12/30 LaTeX package (Sphinx markup)]
+
+\RequirePackage{textcomp}
+\RequirePackage{longtable}
+\RequirePackage{times}
+\RequirePackage{fancyvrb}
+\renewcommand{\sfdefault}{cmbr}
+
+% Uncomment these two lines to ignore the paper size and make the page 
+% size more like a typical published manual.
+%\renewcommand{\paperheight}{9in}
+%\renewcommand{\paperwidth}{8.5in}   % typical squarish manual
+%\renewcommand{\paperwidth}{7in}     % O'Reilly ``Programmming Python''
+
+% These packages can be used to add marginal annotations which indicate
+% index entries and labels; useful for reviewing this messy documentation!
+%
+%\RequirePackage{showkeys}
+%\RequirePackage{showidx}
+
+% If we ever want to indent paragraphs, this needs to be changed.
+% This is used inside the macros defined here instead of coding
+% \noindent directly.
+\let\py@parindent=\noindent
+
+% for PDF output, use maximal compression & a lot of other stuff
+% (test for PDF recommended by Tanmoy Bhattacharya <tanmoy@qcd.lanl.gov>)
+%
+\newif\ifpy@doing@page@targets
+\py@doing@page@targetsfalse
+
+\newif\ifpdf\pdffalse
+\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
+\else
+  \pdftrue
+  \input{pdfcolor}
+  \let\py@LinkColor=\NavyBlue
+  \let\py@NormalColor=\Black
+  \pdfcompresslevel=9
+  \pdfpagewidth=\paperwidth    % page width of PDF output
+  \pdfpageheight=\paperheight  % page height of PDF output
+  %
+  % Pad the number with '0' to 3 digits wide so no page na