[Python-checkins] r59608 - in doctools/trunk: TODO sphinx/__init__.py sphinx/builder.py sphinx/directives.py sphinx/environment.py sphinx/latexwriter.py sphinx/roles.py sphinx/search.py sphinx/style/default.css sphinx/templates/rstsource.html sphinx/templates/sidebar.html sphinx/templates/versionchanges.html sphinx/templates/versionchanges_frameset.html sphinx/texinputs/howto.cls sphinx/texinputs/manual.cls sphinx/texinputs/python.sty sphinx/texinputs/sphinx.sty sphinx/web/admin.py sphinx/web/antispam.py sphinx/web/application.py sphinx/web/util.py

georg.brandl python-checkins at python.org
Sat Dec 29 11:58:11 CET 2007


Author: georg.brandl
Date: Sat Dec 29 11:58:10 2007
New Revision: 59608

Added:
   doctools/trunk/sphinx/templates/rstsource.html
   doctools/trunk/sphinx/templates/versionchanges.html
   doctools/trunk/sphinx/templates/versionchanges_frameset.html
   doctools/trunk/sphinx/texinputs/sphinx.sty
Removed:
   doctools/trunk/sphinx/texinputs/python.sty
Modified:
   doctools/trunk/TODO
   doctools/trunk/sphinx/__init__.py
   doctools/trunk/sphinx/builder.py
   doctools/trunk/sphinx/directives.py
   doctools/trunk/sphinx/environment.py
   doctools/trunk/sphinx/latexwriter.py
   doctools/trunk/sphinx/roles.py
   doctools/trunk/sphinx/search.py
   doctools/trunk/sphinx/style/default.css
   doctools/trunk/sphinx/templates/sidebar.html
   doctools/trunk/sphinx/texinputs/howto.cls
   doctools/trunk/sphinx/texinputs/manual.cls
   doctools/trunk/sphinx/web/admin.py
   doctools/trunk/sphinx/web/antispam.py
   doctools/trunk/sphinx/web/application.py
   doctools/trunk/sphinx/web/util.py
Log:
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


Modified: doctools/trunk/TODO
==============================================================================
--- doctools/trunk/TODO	(original)
+++ doctools/trunk/TODO	Sat Dec 29 11:58:10 2007
@@ -4,18 +4,18 @@
 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)

Modified: doctools/trunk/sphinx/__init__.py
==============================================================================
--- doctools/trunk/sphinx/__init__.py	(original)
+++ doctools/trunk/sphinx/__init__.py	Sat Dec 29 11:58:10 2007
@@ -35,6 +35,7 @@
          -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.
@@ -43,7 +44,7 @@
 
 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.'
@@ -69,7 +70,7 @@
         return 1
 
     builder = all_files = None
-    opt_help = freshenv = False
+    opt_help = freshenv = use_pdb = False
     status = sys.stdout
     options = {}
     confoverrides = {}
@@ -111,6 +112,8 @@
             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
@@ -128,17 +131,23 @@
             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__':

Modified: doctools/trunk/sphinx/builder.py
==============================================================================
--- doctools/trunk/sphinx/builder.py	(original)
+++ doctools/trunk/sphinx/builder.py	Sat Dec 29 11:58:10 2007
@@ -19,6 +19,7 @@
 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
@@ -33,7 +34,7 @@
 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
@@ -194,66 +195,74 @@
     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)
-
-        # global actions
-        self.msg('checking consistency...')
-        self.env.check_consistency()
+        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()
 
         # 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)
@@ -595,7 +604,8 @@
 
         # 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)
 
@@ -652,8 +662,7 @@
         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':
@@ -677,9 +686,7 @@
                          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"]:
@@ -695,8 +702,8 @@
                 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
@@ -743,9 +750,119 @@
                                 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,
 }

Modified: doctools/trunk/sphinx/directives.py
==============================================================================
--- doctools/trunk/sphinx/directives.py	(original)
+++ doctools/trunk/sphinx/directives.py	Sat Dec 29 11:58:10 2007
@@ -428,7 +428,7 @@
     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)

Modified: doctools/trunk/sphinx/environment.py
==============================================================================
--- doctools/trunk/sphinx/environment.py	(original)
+++ doctools/trunk/sphinx/environment.py	Sat Dec 29 11:58:10 2007
@@ -52,7 +52,7 @@
 
 # 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):
@@ -222,7 +222,7 @@
         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
@@ -383,7 +383,8 @@
 
         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)
@@ -528,9 +529,9 @@
         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 ------------------------------
@@ -603,6 +604,8 @@
 
             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(
@@ -620,6 +623,20 @@
                             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:
@@ -656,10 +673,12 @@
                             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:

Modified: doctools/trunk/sphinx/latexwriter.py
==============================================================================
--- doctools/trunk/sphinx/latexwriter.py	(original)
+++ doctools/trunk/sphinx/latexwriter.py	Sat Dec 29 11:58:10 2007
@@ -25,6 +25,7 @@
 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}
@@ -408,7 +409,7 @@
         # 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
 

Modified: doctools/trunk/sphinx/roles.py
==============================================================================
--- doctools/trunk/sphinx/roles.py	(original)
+++ doctools/trunk/sphinx/roles.py	Sat Dec 29 11:58:10 2007
@@ -23,7 +23,6 @@
     'dfn' : nodes.emphasis,
     'guilabel' : nodes.strong,
     'kbd' : nodes.literal,
-    'keyword' : nodes.literal,
     'mailheader' : addnodes.literal_emphasis,
     'makevar' : nodes.Text,
     'manpage' : addnodes.literal_emphasis,
@@ -172,6 +171,7 @@
 
     'mod' : xfileref_role,
 
+    'keyword': xfileref_role,
     'ref': xfileref_role,
     'token' : xfileref_role,
     'term': xfileref_role,

Modified: doctools/trunk/sphinx/search.py
==============================================================================
--- doctools/trunk/sphinx/search.py	(original)
+++ doctools/trunk/sphinx/search.py	Sat Dec 29 11:58:10 2007
@@ -10,9 +10,10 @@
 """
 import re
 import pickle
-
 from collections import defaultdict
+
 from docutils.nodes import Text, NodeVisitor
+
 from .util.stemmer import PorterStemmer
 from .util.json import dump_json, load_json
 

Modified: doctools/trunk/sphinx/style/default.css
==============================================================================
--- doctools/trunk/sphinx/style/default.css	(original)
+++ doctools/trunk/sphinx/style/default.css	Sat Dec 29 11:58:10 2007
@@ -154,7 +154,6 @@
 div.modulecloud {
     margin: -5px 10px 5px 10px;
     padding: 10px;
-    font-size: 110%;
     line-height: 160%;
     border: 1px solid #cbe7e5;
     background-color: #f2fbfd;
@@ -708,6 +707,7 @@
 tt {
     background-color: #ecf0f3;
     padding: 0 1px 0 1px;
+    font-size: 0.95em;
 }
 
 tt.descname {

Added: doctools/trunk/sphinx/templates/rstsource.html
==============================================================================
--- (empty file)
+++ doctools/trunk/sphinx/templates/rstsource.html	Sat Dec 29 11:58:10 2007
@@ -0,0 +1,15 @@
+<!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>
\ No newline at end of file

Modified: doctools/trunk/sphinx/templates/sidebar.html
==============================================================================
--- doctools/trunk/sphinx/templates/sidebar.html	(original)
+++ doctools/trunk/sphinx/templates/sidebar.html	Sat Dec 29 11:58:10 2007
@@ -54,6 +54,9 @@
               <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>

Added: doctools/trunk/sphinx/templates/versionchanges.html
==============================================================================
--- (empty file)
+++ doctools/trunk/sphinx/templates/versionchanges.html	Sat Dec 29 11:58:10 2007
@@ -0,0 +1,33 @@
+{% 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>
\ No newline at end of file

Added: doctools/trunk/sphinx/templates/versionchanges_frameset.html
==============================================================================
--- (empty file)
+++ doctools/trunk/sphinx/templates/versionchanges_frameset.html	Sat Dec 29 11:58:10 2007
@@ -0,0 +1,11 @@
+<!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>
\ No newline at end of file

Modified: doctools/trunk/sphinx/texinputs/howto.cls
==============================================================================
--- doctools/trunk/sphinx/texinputs/howto.cls	(original)
+++ doctools/trunk/sphinx/texinputs/howto.cls	Sat Dec 29 11:58:10 2007
@@ -1,5 +1,5 @@
 %
-% howto.cls for the Python documentation
+% howto.cls for Sphinx
 %
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
@@ -34,7 +34,7 @@
 % 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.

Modified: doctools/trunk/sphinx/texinputs/manual.cls
==============================================================================
--- doctools/trunk/sphinx/texinputs/manual.cls	(original)
+++ doctools/trunk/sphinx/texinputs/manual.cls	Sat Dec 29 11:58:10 2007
@@ -1,5 +1,5 @@
 %
-% manual.cls for the Python documentation
+% manual.cls for Sphinx
 %
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
@@ -43,9 +43,9 @@
 % 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}
 

Deleted: /doctools/trunk/sphinx/texinputs/python.sty
==============================================================================
--- /doctools/trunk/sphinx/texinputs/python.sty	Sat Dec 29 11:58:10 2007
+++ (empty file)
@@ -1,1344 +0,0 @@
-%
-% 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 at parindent=\noindent
-
-% for PDF output, use maximal compression & a lot of other stuff
-% (test for PDF recommended by Tanmoy Bhattacharya <tanmoy at qcd.lanl.gov>)
-%
-\newif\ifpy at doing@page at targets
-\py at doing@page at targetsfalse
-
-\newif\ifpdf\pdffalse
-\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
-\else
-  \pdftrue
-  \input{pdfcolor}
-  \let\py at LinkColor=\NavyBlue
-  \let\py at 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 at targetno}[1]{\ifnum#1<100 0\fi\ifnum#1<10 0\fi#1}
-  \newcommand{\py at pageno}{\py at 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 at 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 at parindent here is a hack -- we're forcing pdfTeX into
-  % horizontal mode since \pdfstartlink requires that.
-  \def\py at pdfstartlink{%
-    \ifvmode\py at 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 at linkToName}[2]{%
-    \py at pdfstartlink attr{/Border [0 0 0]} goto name{#1}%
-      \py at LinkColor#2\py at 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 at pageno{\py at targetno{#3}}%
-    \py at OldContentsline{#1}{\py at linkToName{page\my at pageno}{#2}}{#3}%
-  }
-  \AtEndDocument{
-    \def\_{\string_}
-    \InputIfFileExists{\jobname.bkm}{\pdfcatalog{/PageMode /UseOutlines}}{}
-  }
-  \newcommand{\py at target}[1]{%
-    \ifpy at doing@page at targets%
-      {\pdfdest name{#1} xyz}%
-    \fi%
-  }
-  \let\py at OldLabel=\label
-  \renewcommand{\label}[1]{%
-    \py at OldLabel{#1}%
-    \py at 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 at old@thehead\@thehead
-       \global\def\@foo{\py at target{page\py at pageno}}%
-     \expandafter\ifx\expandafter\@empty\H at old@thehead
-       \def\H at old@thehead{\hfil}\fi
-    \def\@thehead{\@foo\relax\H at 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 at HeaderFamily}{\sffamily}
-
-% Set up abstract ways to get the normal and smaller font sizes that
-% work even in footnote context.
-\newif\ifpy at infootnote \py at infootnotefalse
-\let\py at oldmakefntext\@makefntext
-\def\@makefntext#1{%
-  \bgroup%
-    \py at infootnotetrue
-    \py at oldmakefntext{#1}%
-  \egroup%
-}
-\def\py at defaultsize{%
-  \ifpy at infootnote\footnotesize\else\normalsize\fi%
-}
-\def\py at smallsize{%
-  \ifpy at 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 at HeaderFamily\thepage}}
-    \fancyfoot[LO]{{\py at HeaderFamily\nouppercase{\rightmark}}}
-    \fancyfoot[RE]{{\py at 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 at 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 at openright \ifodd\c at page\else
-      \hbox{}
-      \thispagestyle{plain}
-      \newpage
-      \if at 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 at OldVerbatim=\verbatim
-\let\py at OldEndVerbatim=\endverbatim
-\RequirePackage{verbatim}
-\let\py at OldVerbatimInput=\verbatiminput
-
-% Variable used by begin code command
-\newlength{\py at codewidth}
-
-\renewcommand{\verbatim}{%
-  \setlength{\parindent}{1cm}%
-  % Calculate the text width for the minipage:
-  \setlength{\py at codewidth}{\linewidth}%
-  \addtolength{\py at codewidth}{-\parindent}%
-  %
-  \par\indent%
-  \begin{minipage}[t]{\py at codewidth}%
-    \small%
-    \py at OldVerbatim%
-}
-\renewcommand{\endverbatim}{%
-    \py at OldEndVerbatim%
-  \end{minipage}%
-}
-\renewcommand{\verbatiminput}[1]{%
-  {\setlength{\parindent}{1cm}%
-   % Calculate the text width for the minipage:
-   \setlength{\py at codewidth}{\linewidth}%
-   \addtolength{\py at codewidth}{-\parindent}%
-   %
-   \small%
-   \begin{list}{}{\setlength{\leftmargin}{1cm}}
-     \item%
-     \py at OldVerbatimInput{#1}%
-   \end{list}
-  }%
-}
-
-% This does a similar thing for the {alltt} environment:
-\RequirePackage{alltt}
-\let\py at OldAllTT=\alltt
-\let\py at OldEndAllTT=\endalltt
-
-\renewcommand{\alltt}{%
-  \setlength{\parindent}{1cm}%
-  % Calculate the text width for the minipage:
-  \setlength{\py at codewidth}{\linewidth}%
-  \addtolength{\py at codewidth}{-\parindent}%
-  \let\e=\textbackslash%
-  %
-  \par\indent%
-  \begin{minipage}[t]{\py at codewidth}%
-    \small%
-    \py at OldAllTT%
-}
-\renewcommand{\endalltt}{%
-    \py at OldEndAllTT%
-  \end{minipage}%
-}
-
-
-\newcommand{\py at 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 at idxcode}[1]{\texttt{#1}}
-%\renewcommand{\py at 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 at idxcode{#1}}}}
-\newcommand{\stindex}[1]{\indexii{statement}{#1@{\py at idxcode{#1}}}}
-\newcommand{\opindex}[1]{\indexii{operator}{#1@{\py at idxcode{#1}}}}
-\newcommand{\exindex}[1]{\indexii{exception}{#1@{\py at idxcode{#1}}}}
-\newcommand{\obindex}[1]{\indexii{object}{#1}}
-\newcommand{\bifuncindex}[1]{%
-  \index{#1@{\py at idxcode{#1()}} (built-in function)}}
-
-% Add an index entry for a module
-\newcommand{\py at refmodule}[2]{\index{#1@{\py at idxcode{#1}} (#2module)}}
-\newcommand{\refmodindex}[1]{\py at refmodule{#1}{}}
-\newcommand{\refbimodindex}[1]{\py at refmodule{#1}{built-in }}
-\newcommand{\refexmodindex}[1]{\py at refmodule{#1}{extension }}
-\newcommand{\refstmodindex}[1]{\py at 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 at modulebadkey]{%
-    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
-    \py at linkToName{label-module-\py at modulekey}{\module{#2}}%
-  }
-\else
-  \newcommand{\refmodule}[2][\py at modulebadkey]{\module{#2}}
-\fi
-
-% support for the module index
-\newif\ifpy at UseModuleIndex
-\py at UseModuleIndexfalse
-
-\newcommand{\makemodindex}{
-  \newwrite\modindexfile
-  \openout\modindexfile=mod\jobname.idx
-  \py at UseModuleIndextrue
-}
-
-\newcommand{\printmodindex}{
-  \@input@{mod\jobname.ind}
-}
-
-% Add the defining entry for a module
-\newcommand{\py at modindex}[2]{%
-  \renewcommand{\py at thismodule}{#1}
-  \setindexsubitem{(in module #1)}%
-  \index{#1@{\py at idxcode{#1}} (#2module)|textbf}%
-  \ifpy at UseModuleIndex%
-    \@ifundefined{py at modplat@\py at thismodulekey}{
-      \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}}{\thepage}}%
-    }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1} %
-        \emph{(\py at platformof[\py at thismodulekey]{})}}}{\thepage}}%
-    }
-  \fi%
-}
-
-% *** XXX *** THE NEXT FOUR MACROS ARE NOW OBSOLETE !!! ***
-
-% built-in & Python modules in the main distribution
-\newcommand{\bimodindex}[1]{\py at modindex{#1}{built-in }%
-  \typeout{*** MACRO bimodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-\newcommand{\stmodindex}[1]{\py at modindex{#1}{standard }%
-  \typeout{*** MACRO stmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-
-% Python & extension modules outside the main distribution
-\newcommand{\modindex}[1]{\py at modindex{#1}{}%
-  \typeout{*** MACRO modindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-\newcommand{\exmodindex}[1]{\py at modindex{#1}{extension }%
-  \typeout{*** MACRO exmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
-
-% Additional string for an index entry
-\newif\ifpy at usingsubitem\py at usingsubitemfalse
-\newcommand{\py at indexsubitem}{}
-\newcommand{\setindexsubitem}[1]{\renewcommand{\py at indexsubitem}{ #1}%
-                                 \py at usingsubitemtrue}
-\newcommand{\ttindex}[1]{%
-  \ifpy at usingsubitem
-    \index{#1@{\py at idxcode{#1}}\py at indexsubitem}%
-  \else%
-    \index{#1@{\py at idxcode{#1}}}%
-  \fi%
-}
-\newcommand{\withsubitem}[2]{%
-  \begingroup%
-    \def\ttindex##1{\index{##1@{\py at idxcode{##1}} #1}}%
-    #2%
-  \endgroup%
-}
-
-
-% Module synopsis processing -----------------------------------------------
-%
-\newcommand{\py at thisclass}{}
-\newcommand{\py at thismodule}{}
-\newcommand{\py at thismodulekey}{}
-\newcommand{\py at thismoduletype}{}
-
-\newcommand{\py at standardIndexModule}[1]{\py at modindex{#1}{standard }}
-\newcommand{\py at builtinIndexModule}[1]{\py at modindex{#1}{built-in }}
-\newcommand{\py at extensionIndexModule}[1]{\py at modindex{#1}{extension }}
-\newcommand{\py at IndexModule}[1]{\py at modindex{#1}{}}
-
-\newif\ifpy at HaveModSynopsis       \py at HaveModSynopsisfalse
-\newif\ifpy at ModSynopsisFileIsOpen \py at ModSynopsisFileIsOpenfalse
-\newif\ifpy at HaveModPlatform       \py at HaveModPlatformfalse
-
-% \declaremodule[key]{type}{name}
-\newcommand{\declaremodule}[3][\py at modulebadkey]{
-  \py at openModSynopsisFile
-  \renewcommand{\py at thismoduletype}{#2}
-  \ifx\py at modulebadkey#1
-    \renewcommand{\py at thismodulekey}{#3}
-  \else
-    \renewcommand{\py at thismodulekey}{#1}
-  \fi
-  \@ifundefined{py@#2IndexModule}{%
-    \typeout{*** MACRO declaremodule called with unknown module type: `#2'}
-    \py at IndexModule{#3}%
-  }{%
-    \csname py@#2IndexModule\endcsname{#3}%
-  }
-  \label{module-\py at thismodulekey}
-}
-\newif\ifpy at ModPlatformFileIsOpen \py at ModPlatformFileIsOpenfalse
-\newcommand{\py at ModPlatformFilename}{\jobname.pla}
-\newcommand{\platform}[1]{
-  \ifpy at ModPlatformFileIsOpen\else
-    \newwrite\py at ModPlatformFile
-    \openout\py at ModPlatformFile=\py at ModPlatformFilename
-    \py at ModPlatformFileIsOpentrue
-  \fi
-}
-\InputIfFileExists{\jobname.pla}{}{}
-\newcommand{\py at platformof}[2][\py at modulebadkey]{%
-  \ifx\py at modulebadkey#1 \def\py at key{#2}%
-  \else \def\py at key{#1}%
-  \fi%
-  \csname py at modplat@\py at key\endcsname%
-}
-\newcommand{\ignorePlatformAnnotation}[1]{}
-
-% \moduleauthor{name}{email}
-\newcommand{\moduleauthor}[2]{}
-
-% \sectionauthor{name}{email}
-\newcommand{\sectionauthor}[2]{}
-
-
-\newcommand{\py at defsynopsis}{Module has no synopsis.}
-\newcommand{\py at modulesynopsis}{\py at defsynopsis}
-\newcommand{\modulesynopsis}[1]{
-  \py at HaveModSynopsistrue
-  \renewcommand{\py at modulesynopsis}{#1}
-}
-
-% define the file
-\newwrite\py at ModSynopsisFile
-
-% hacked from \addtocontents from latex.ltx:
-\long\def\py at writeModSynopsisFile#1{%
-  \protected at write\py at ModSynopsisFile%
-      {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
-      {\string#1}%
-}
-\newcommand{\py at closeModSynopsisFile}{
-  \ifpy at ModSynopsisFileIsOpen
-    \closeout\py at ModSynopsisFile
-    \py at ModSynopsisFileIsOpenfalse
-  \fi
-}
-\newcommand{\py at openModSynopsisFile}{
-  \ifpy at ModSynopsisFileIsOpen\else
-    \openout\py at ModSynopsisFile=\py at ModSynopsisFilename
-    \py at ModSynopsisFileIsOpentrue
-  \fi
-}
-
-\newcommand{\py at ProcessModSynopsis}{
-  \ifpy at HaveModSynopsis
-    \py at writeModSynopsisFile{\modulesynopsis%
-      {\py at thismodulekey}{\py at thismodule}%
-      {\py at thismoduletype}{\py at modulesynopsis}}%
-    \py at HaveModSynopsisfalse
-  \fi
-  \renewcommand{\py at modulesynopsis}{\py at defsynopsis}
-}
-\AtEndDocument{\py at ProcessModSynopsis\py at closeModSynopsisFile}
-
-
-\long\def\py at writeModPlatformFile#1{%
-  \protected at write\py at ModPlatformFile%
-    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
-    {\string#1}%
-}
-
-
-\newcommand{\localmoduletable}{
-  \IfFileExists{\py at ModSynopsisFilename}{
-    \begin{synopsistable}
-      \input{\py at ModSynopsisFilename}
-    \end{synopsistable}
-  }{}
-}
-
-\ifpdf
-  \newcommand{\py at ModSynopsisSummary}[4]{%
-    \py at linkToName{label-module-#1}{\bfcode{#2}} & #4\\
-  }
-\else
-  \newcommand{\py at ModSynopsisSummary}[4]{\bfcode{#2} & #4\\}
-\fi
-\newenvironment{synopsistable}{
-  % key, name, type, synopsis
-  \let\modulesynopsis=\py at ModSynopsisSummary
-  \begin{tabular}{ll}
-}{
-  \end{tabular}
-}
-%
-% --------------------------------------------------------------------------
-
-
-\newcommand{\py at reset}{
-  \py at usingsubitemfalse
-  \py at ProcessModSynopsis
-  \renewcommand{\py at thisclass}{}
-  \renewcommand{\py at thismodule}{}
-  \renewcommand{\py at thismodulekey}{}
-  \renewcommand{\py at thismoduletype}{}
-}
-
-% Augment the sectioning commands used to get our own font family in place,
-% and reset some internal data items:
-\renewcommand{\section}{\py at reset%
-                        \@startsection{section}{1}{\z@}%
-                                    {-3.5ex \@plus -1ex \@minus -.2ex}%
-                                    {2.3ex \@plus.2ex}%
-                                    {\reset at font\Large\py at HeaderFamily}}
-\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
-                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
-                                    {1.5ex \@plus .2ex}%
-                                    {\reset at font\large\py at HeaderFamily}}
-\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
-                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
-                                    {1.5ex \@plus .2ex}%
-                                    {\reset at font\normalsize\py at HeaderFamily}}
-\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
-                                    {3.25ex \@plus1ex \@minus.2ex}%
-                                    {-1em}%
-                                    {\reset at font\normalsize\py at HeaderFamily}}
-\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}%
-                                    {3.25ex \@plus1ex \@minus .2ex}%
-                                    {-1em}%
-                                    {\reset at font\normalsize\py at 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 at 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 at 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 at 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 at 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 at unspecified}{...}
-
-
-\newlength{\py at argswidth}
-\newcommand{\py at sigparams}[1]{%
-  \parbox[t]{\py at argswidth}{\py at varvars{#1}\code{)}}}
-\newcommand{\py at sigline}[2]{%
-  \settowidth{\py at argswidth}{#1\code{(}}%
-  \addtolength{\py at argswidth}{-2\py at argswidth}%
-  \addtolength{\py at argswidth}{\textwidth}%
-  \item[#1\code{(}\py at 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 at sigline{\code{#1 \bfcode{#2}}}{#3}%
-  \index{#2@{\py at idxcode{#2()}}}
-}
-\newenvironment{cfuncdesc}[4][\py at 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 at idxcode{#2}}}]
-}{\end{fulllineitems}}
-
-% C data types -----------------------------------------------------------
-% \begin{ctypedesc}[index name]{typedef name}
-\newenvironment{ctypedesc}[2][\py at badkey]{
-  \begin{fulllineitems}
-    \item[\bfcode{#2}%
-    \ifx\@undefined#1\relax%
-      \index{#2@{\py at idxcode{#2}} (C type)}
-    \else%
-      \index{#2@{\py at 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 at 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 at idxcode{#1}} (macro)}]
-}{\end{fulllineitems}}
-
-% simple functions (not methods) -----------------------------------------
-% \begin{funcdesc}{name}{args}
-\newcommand{\funcline}[2]{%
-  \funclineni{#1}{#2}%
-  \index{#1@{\py at idxcode{#1()}} (in module \py at 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 at sigline{\bfcode{#1}}{#2}}
-\newenvironment{funcdescni}[2]{
-  \begin{fulllineitems}
-    \funclineni{#1}{#2}
-}{\end{fulllineitems}}
-
-% classes ----------------------------------------------------------------
-% \begin{classdesc}{name}{constructor args}
-\newcommand{\classline}[2]{
-  \py at sigline{\strong{class }\bfcode{#1}}{#2}%
-  \index{#1@{\py at idxcode{#1}} (class in \py at thismodule)}}
-\newenvironment{classdesc}[2]{
-  % Using \renewcommand doesn't work for this, for unknown reasons:
-  \global\def\py at 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 at thisclass{#1}
-  \begin{fulllineitems}
-    \item[\strong{class }\code{\bfcode{#1}}%
-      \index{#1@{\py at idxcode{#1}} (class in \py at 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 at thisclass{#1}
-  \begin{fulllineitems}
-    \py at sigline{\strong{exception }\bfcode{#1}}{#2}%
-    \index{#1@{\py at idxcode{#1}} (exception in \py at thismodule)}
-}{\end{fulllineitems}}
-
-% There is no corresponding {excclassdesc*} environment.  To describe
-% a class exception without parameters, use the {excdesc} environment.
-
-
-\let\py at classbadkey=\@undefined
-
-% object method ----------------------------------------------------------
-% \begin{methoddesc}[classname]{methodname}{args}
-\newcommand{\methodline}[3][\@undefined]{
-  \methodlineni{#2}{#3}
-  \ifx\@undefined#1\relax
-    \index{#2@{\py at idxcode{#2()}} (\py at thisclass\ method)}
-  \else
-    \index{#2@{\py at idxcode{#2()}} (#1 method)}
-  \fi
-}
-\newenvironment{methoddesc}[3][\@undefined]{
-  \begin{fulllineitems}
-    \ifx\@undefined#1\relax
-      \methodline{#2}{#3}
-    \else
-      \def\py at 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 at classbadkey]{%
-  \py at sigline{\bfcode{#2}}{#3}}
-\newenvironment{methoddescni}[3][\py at classbadkey]{
-  \begin{fulllineitems}
-    \methodlineni{#2}{#3}
-}{\end{fulllineitems}}
-
-% object data attribute --------------------------------------------------
-% \begin{memberdesc}[classname]{membername}
-\newcommand{\memberline}[2][\py at classbadkey]{%
-  \ifx\@undefined#1\relax
-    \memberlineni{#2}
-    \index{#2@{\py at idxcode{#2}} (\py at thisclass\ attribute)}
-  \else
-    \memberlineni{#2}
-    \index{#2@{\py at idxcode{#2}} (#1 attribute)}
-  \fi
-}
-\newenvironment{memberdesc}[2][\py at classbadkey]{
-  \begin{fulllineitems}
-    \ifx\@undefined#1\relax
-      \memberline{#2}
-    \else
-      \def\py at 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 at classbadkey]{\item[\bfcode{#2}]}
-\newenvironment{memberdescni}[2][\py at 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 at idxcode{#1}} (exception in \py at thismodule)}]
-}{\end{fulllineitems}}
-
-% Module data or constants: ----------------------------------------------
-% \begin{datadesc}{name}
-\newcommand{\dataline}[1]{%
-  \datalineni{#1}\index{#1@{\py at idxcode{#1}} (data in \py at 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 at defaultsize\textrm{\textit{#1\/}}}%
-  \else%
-    \py at 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 at 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 at pdfstartlink%
-%    attr{ /Border [0 0 0] }%
-%    user{%
-%      /Subtype/Link%
-%      /A<<%
-%      /Type/Action%
-%      /S/URI%
-%      /URI(#1)%
-%      >>%
-%    }%
-%    \py at LinkColor%                      color of the link text
-%    \py at smallsize\sf #1%
-%    \py at 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 at smallsize\textsf{#1}}}
-%\fi
-\newcommand{\email}[1]{{\py at smallsize\textsf{#1}}}
-\newcommand{\newsgroup}[1]{{\py at smallsize\textsf{#1}}}
-
-\newcommand{\py at varvars}[1]{{%
-  {\let\unspecified=\py at unspecified%
-   \let\moreargs=\py at 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 at smallsize\textsf{#1:}}}
-\newcommand{\mimetype}[1]{{\py at smallsize\textsf{#1}}}
-% The \! is a "negative thin space" in math mode.
-\newcommand{\regexp}[1]{%
-  {\tiny$^{^\lceil}\!\!$%
-   {\py at 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 at pdfstartlink%
-    attr{ /Border [0 0 0] }%
-    user{%
-      /Subtype/Link%
-      /A<<%
-      /Type/Action%
-      /S/URI%
-      /URI(#2)%
-      >>%
-    }%
-    \py at LinkColor%                              color of the link text
-    #1%
-    \py at 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 at modulebadkey]{%
-    \ifx\py at 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 at 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 at noticelength}
-
-\newcommand{\py at heavybox}{
-  \setlength{\fboxrule}{1pt}
-  \setlength{\fboxsep}{7pt}
-  \setlength{\py at noticelength}{\linewidth}
-  \addtolength{\py at noticelength}{-2\fboxsep}
-  \addtolength{\py at noticelength}{-2\fboxrule}
-  \setlength{\shadowsize}{3pt}
-  \Sbox
-  \minipage{\py at noticelength}
-}
-\newcommand{\py at endheavybox}{
-  \endminipage
-  \endSbox
-  \fbox{\TheSbox}
-}
-
-% a 'note' is as plain as it gets:
-\newcommand{\py at noticelabel@note}{Note:}
-\newcommand{\py at noticestart@note}{}
-\newcommand{\py at noticeend@note}{}
-
-% a 'warning' gets more visible distinction:
-\newcommand{\py at noticelabel@warning}{Warning:}
-\newcommand{\py at noticestart@warning}{\py at heavybox}
-\newcommand{\py at noticeend@warning}{\py at endheavybox}
-
-\newenvironment{notice}[1][note]{
-  \def\py at noticetype{#1}
-  \csname py at noticestart@#1\endcsname
-  \par\strong{\csname py at noticelabel@#1\endcsname}
-}{\csname py at noticeend@\py at noticetype\endcsname}
-\newcommand{\note}[1]{\strong{\py at noticelabel@note} #1}
-\newcommand{\warning}[1]{\strong{\py at 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 at badkey]{%
-  \ifx\@undefined#1\relax%
-    {  New in version #2.  }%
-  \else%
-    {  New in version #2:\ #1  }%
-  \fi%
-}
-\newcommand{\versionchanged}[2][\py at 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 at tablenotescounter}
-\newenvironment{tablenotes}{%
-  \noindent Notes:
-  \par
-  \setcounter{py at tablenotescounter}{0}
-  \begin{list}{(\arabic{py at tablenotescounter})}%
-              {\usecounter{py at 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 at seemodule}[3][\py at modulebadkey]{%
-    \par%
-    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
-    \begin{fulllineitems}
-      \item[\py at linkToName{label-module-\py at modulekey}{Module \module{#2}}
-            (section \ref{module-\py at modulekey}):]
-      #3
-    \end{fulllineitems}
-  }
-\else
-  \newcommand{\py at seemodule}[3][\py at modulebadkey]{%
-    \par%
-    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
-    \begin{fulllineitems}
-      \item[Module \module{#2} (section \ref{module-\py at modulekey}):]
-      #3
-    \end{fulllineitems}
-  }
-\fi
-
-% \seelink{url}{link text}{why it's interesting}
-\newcommand{\py at seelink}[3]{%
-  \par
-  \begin{fulllineitems}
-    \item[\ulink{#2}{#1}]
-    #3
-  \end{fulllineitems}
-}
-% \seetitle[url]{title}{why it's interesting}
-\newcommand{\py at seetitle}[3][\py at modulebadkey]{%
-  \par
-  \begin{fulllineitems}
-    \item[\citetitle{#2}]
-    \ifx\py at modulebadkey#1\else
-      \item[{\small{(\url{#1})}}]
-    \fi
-    #3
-  \end{fulllineitems}
-}
-% \seepep{number}{title}{why it's interesting}
-\newcommand{\py at seepep}[3]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\pep{#1}, ``\emph{#2}'']
-    #3
-  \end{fulllineitems}
-}
-% \seerfc{number}{title}{why it's interesting}
-\newcommand{\py at seerfc}[3]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\rfc{#1}, ``\emph{#2}'']
-    #3
-  \end{fulllineitems}
-}
-% \seeurl{url}{why it's interesting}
-\newcommand{\py at seeurl}[2]{%
-  \par%
-  \begin{fulllineitems}
-    \item[\url{#1}]
-    #2
-  \end{fulllineitems}
-}
-
-\newenvironment{seealso*}{
-  \par
-  \def\seetext##1{\par{##1}}
-  \let\seemodule=\py at seemodule
-  \let\seepep=\py at seepep
-  \let\seerfc=\py at seerfc
-  \let\seetitle=\py at seetitle
-  \let\seeurl=\py at seeurl
-  \let\seelink=\py at seelink
-}{\par}
-\newenvironment{seealso}{
-  \par
-  \strong{See Also:}
-  \par
-  \def\seetext##1{\par{##1}}
-  \let\seemodule=\py at seemodule
-  \let\seepep=\py at seepep
-  \let\seerfc=\py at seerfc
-  \let\seetitle=\py at seetitle
-  \let\seeurl=\py at seeurl
-  \let\seelink=\py at 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 at release}{}
-\newcommand{\version}{}
-\newcommand{\shortversion}{}
-\newcommand{\releaseinfo}{}
-\newcommand{\releasename}{Release}
-\newcommand{\release}[1]{%
-  \renewcommand{\py at 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 at authoraddress}{}
-\newcommand{\authoraddress}[1]{\renewcommand{\py at 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 at HeaderFamily}
-  \ChNumVar{\raggedleft \bfseries\Large\py at HeaderFamily}
-  \ChTitleVar{\raggedleft \rm\Huge\py at HeaderFamily}
-  % This creates chapter heads without the leading \vspace*{}:
-  \def\@makechapterhead#1{%
-    {\parindent \z@ \raggedright \normalfont
-      \ifnum \c at secnumdepth >\m at 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}

Added: doctools/trunk/sphinx/texinputs/sphinx.sty
==============================================================================
--- (empty file)
+++ doctools/trunk/sphinx/texinputs/sphinx.sty	Sat Dec 29 11:58:10 2007
@@ -0,0 +1,1260 @@
+%
+% 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 at parindent=\noindent
+
+% for PDF output, use maximal compression & a lot of other stuff
+% (test for PDF recommended by Tanmoy Bhattacharya <tanmoy at qcd.lanl.gov>)
+%
+\newif\ifpy at doing@page at targets
+\py at doing@page at targetsfalse
+
+\newif\ifpdf\pdffalse
+\ifx\pdfoutput\undefined\else\ifcase\pdfoutput
+\else
+  \pdftrue
+  \input{pdfcolor}
+  \let\py at LinkColor=\NavyBlue
+  \let\py at 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 at targetno}[1]{\ifnum#1<100 0\fi\ifnum#1<10 0\fi#1}
+  \newcommand{\py at pageno}{\py at 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 at 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 at parindent here is a hack -- we're forcing pdfTeX into
+  % horizontal mode since \pdfstartlink requires that.
+  \def\py at pdfstartlink{%
+    \ifvmode\py at 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 at linkToName}[2]{%
+    \py at pdfstartlink attr{/Border [0 0 0]} goto name{#1}%
+      \py at LinkColor#2\py at 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 at pageno{\py at targetno{#3}}%
+    \py at OldContentsline{#1}{\py at linkToName{page\my at pageno}{#2}}{#3}%
+  }
+  \AtEndDocument{
+    \def\_{\string_}
+    \InputIfFileExists{\jobname.bkm}{\pdfcatalog{/PageMode /UseOutlines}}{}
+  }
+  \newcommand{\py at target}[1]{%
+    \ifpy at doing@page at targets%
+      {\pdfdest name{#1} xyz}%
+    \fi%
+  }
+  \let\py at OldLabel=\label
+  \renewcommand{\label}[1]{%
+    \py at OldLabel{#1}%
+    \py at 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 at old@thehead\@thehead
+       \global\def\@foo{\py at target{page\py at pageno}}%
+     \expandafter\ifx\expandafter\@empty\H at old@thehead
+       \def\H at old@thehead{\hfil}\fi
+    \def\@thehead{\@foo\relax\H at 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 at HeaderFamily}{\sffamily}
+
+% Set up abstract ways to get the normal and smaller font sizes that
+% work even in footnote context.
+\newif\ifpy at infootnote \py at infootnotefalse
+\let\py at oldmakefntext\@makefntext
+\def\@makefntext#1{%
+  \bgroup%
+    \py at infootnotetrue
+    \py at oldmakefntext{#1}%
+  \egroup%
+}
+\def\py at defaultsize{%
+  \ifpy at infootnote\footnotesize\else\normalsize\fi%
+}
+\def\py at smallsize{%
+  \ifpy at 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 at HeaderFamily\thepage}}
+    \fancyfoot[LO]{{\py at HeaderFamily\nouppercase{\rightmark}}}
+    \fancyfoot[RE]{{\py at 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 at 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 at openright \ifodd\c at page\else
+      \hbox{}
+      \thispagestyle{plain}
+      \newpage
+      \if at 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 at OldVerbatim=\verbatim
+\let\py at OldEndVerbatim=\endverbatim
+\RequirePackage{verbatim}
+\let\py at OldVerbatimInput=\verbatiminput
+
+% Variable used by begin code command
+\newlength{\py at codewidth}
+
+\renewcommand{\verbatim}{%
+  \setlength{\parindent}{1cm}%
+  % Calculate the text width for the minipage:
+  \setlength{\py at codewidth}{\linewidth}%
+  \addtolength{\py at codewidth}{-\parindent}%
+  %
+  \par\indent%
+  \begin{minipage}[t]{\py at codewidth}%
+    \small%
+    \py at OldVerbatim%
+}
+\renewcommand{\endverbatim}{%
+    \py at OldEndVerbatim%
+  \end{minipage}%
+}
+\renewcommand{\verbatiminput}[1]{%
+  {\setlength{\parindent}{1cm}%
+   % Calculate the text width for the minipage:
+   \setlength{\py at codewidth}{\linewidth}%
+   \addtolength{\py at codewidth}{-\parindent}%
+   %
+   \small%
+   \begin{list}{}{\setlength{\leftmargin}{1cm}}
+     \item%
+     \py at OldVerbatimInput{#1}%
+   \end{list}
+  }%
+}
+
+% This does a similar thing for the {alltt} environment:
+\RequirePackage{alltt}
+\let\py at OldAllTT=\alltt
+\let\py at OldEndAllTT=\endalltt
+
+\renewcommand{\alltt}{%
+  \setlength{\parindent}{1cm}%
+  % Calculate the text width for the minipage:
+  \setlength{\py at codewidth}{\linewidth}%
+  \addtolength{\py at codewidth}{-\parindent}%
+  \let\e=\textbackslash%
+  %
+  \par\indent%
+  \begin{minipage}[t]{\py at codewidth}%
+    \small%
+    \py at OldAllTT%
+}
+\renewcommand{\endalltt}{%
+    \py at OldEndAllTT%
+  \end{minipage}%
+}
+
+
+\newcommand{\py at 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 at idxcode}[1]{\texttt{#1}}
+%\renewcommand{\py at 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 at idxcode{#1}}}}
+\newcommand{\stindex}[1]{\indexii{statement}{#1@{\py at idxcode{#1}}}}
+\newcommand{\opindex}[1]{\indexii{operator}{#1@{\py at idxcode{#1}}}}
+\newcommand{\exindex}[1]{\indexii{exception}{#1@{\py at idxcode{#1}}}}
+\newcommand{\obindex}[1]{\indexii{object}{#1}}
+\newcommand{\bifuncindex}[1]{%
+  \index{#1@{\py at idxcode{#1()}} (built-in function)}}
+
+% Add an index entry for a module
+\newcommand{\py at refmodule}[2]{\index{#1@{\py at idxcode{#1}} (#2module)}}
+\newcommand{\refmodindex}[1]{\py at refmodule{#1}{}}
+\newcommand{\refbimodindex}[1]{\py at refmodule{#1}{built-in }}
+\newcommand{\refexmodindex}[1]{\py at refmodule{#1}{extension }}
+\newcommand{\refstmodindex}[1]{\py at refmodule{#1}{standard }}
+
+% support for the module index
+\newif\ifpy at UseModuleIndex
+\py at UseModuleIndexfalse
+
+\newcommand{\makemodindex}{
+  \newwrite\modindexfile
+  \openout\modindexfile=mod\jobname.idx
+  \py at UseModuleIndextrue
+}
+
+\newcommand{\printmodindex}{
+  \@input@{mod\jobname.ind}
+}
+
+% Add the defining entry for a module
+\newcommand{\py at modindex}[2]{%
+  \renewcommand{\py at thismodule}{#1}
+  \setindexsubitem{(in module #1)}%
+  \index{#1@{\py at idxcode{#1}} (#2module)|textbf}%
+  \ifpy at UseModuleIndex%
+    \@ifundefined{py at modplat@\py at thismodulekey}{
+      \write\modindexfile{\protect\indexentry{#1@{\texttt{#1}}}{\thepage}}%
+    }{\write\modindexfile{\protect\indexentry{#1@{\texttt{#1} %
+        \emph{(\py at platformof[\py at thismodulekey]{})}}}{\thepage}}%
+    }
+  \fi%
+}
+
+% *** XXX *** THE NEXT FOUR MACROS ARE NOW OBSOLETE !!! ***
+
+% built-in & Python modules in the main distribution
+\newcommand{\bimodindex}[1]{\py at modindex{#1}{built-in }%
+  \typeout{*** MACRO bimodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+\newcommand{\stmodindex}[1]{\py at modindex{#1}{standard }%
+  \typeout{*** MACRO stmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+
+% Python & extension modules outside the main distribution
+\newcommand{\modindex}[1]{\py at modindex{#1}{}%
+  \typeout{*** MACRO modindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+\newcommand{\exmodindex}[1]{\py at modindex{#1}{extension }%
+  \typeout{*** MACRO exmodindex IS OBSOLETE -- USE declaremodule INSTEAD!}}
+
+% Additional string for an index entry
+\newif\ifpy at usingsubitem\py at usingsubitemfalse
+\newcommand{\py at indexsubitem}{}
+\newcommand{\setindexsubitem}[1]{\renewcommand{\py at indexsubitem}{ #1}%
+                                 \py at usingsubitemtrue}
+\newcommand{\ttindex}[1]{%
+  \ifpy at usingsubitem
+    \index{#1@{\py at idxcode{#1}}\py at indexsubitem}%
+  \else%
+    \index{#1@{\py at idxcode{#1}}}%
+  \fi%
+}
+\newcommand{\withsubitem}[2]{%
+  \begingroup%
+    \def\ttindex##1{\index{##1@{\py at idxcode{##1}} #1}}%
+    #2%
+  \endgroup%
+}
+
+
+% Module synopsis processing -----------------------------------------------
+%
+\newcommand{\py at thisclass}{}
+\newcommand{\py at thismodule}{}
+\newcommand{\py at thismodulekey}{}
+\newcommand{\py at thismoduletype}{}
+
+\newcommand{\py at standardIndexModule}[1]{\py at modindex{#1}{standard }}
+\newcommand{\py at builtinIndexModule}[1]{\py at modindex{#1}{built-in }}
+\newcommand{\py at extensionIndexModule}[1]{\py at modindex{#1}{extension }}
+\newcommand{\py at IndexModule}[1]{\py at modindex{#1}{}}
+
+\newif\ifpy at HaveModSynopsis       \py at HaveModSynopsisfalse
+\newif\ifpy at ModSynopsisFileIsOpen \py at ModSynopsisFileIsOpenfalse
+\newif\ifpy at HaveModPlatform       \py at HaveModPlatformfalse
+
+% \declaremodule[key]{type}{name}
+\newcommand{\declaremodule}[3][\py at modulebadkey]{
+  \py at openModSynopsisFile
+  \renewcommand{\py at thismoduletype}{#2}
+  \ifx\py at modulebadkey#1
+    \renewcommand{\py at thismodulekey}{#3}
+  \else
+    \renewcommand{\py at thismodulekey}{#1}
+  \fi
+  \@ifundefined{py@#2IndexModule}{%
+    \typeout{*** MACRO declaremodule called with unknown module type: `#2'}
+    \py at IndexModule{#3}%
+  }{%
+    \csname py@#2IndexModule\endcsname{#3}%
+  }
+  \label{module-\py at thismodulekey}
+}
+\newif\ifpy at ModPlatformFileIsOpen \py at ModPlatformFileIsOpenfalse
+\newcommand{\py at ModPlatformFilename}{\jobname.pla}
+\newcommand{\platform}[1]{
+  \ifpy at ModPlatformFileIsOpen\else
+    \newwrite\py at ModPlatformFile
+    \openout\py at ModPlatformFile=\py at ModPlatformFilename
+    \py at ModPlatformFileIsOpentrue
+  \fi
+}
+\InputIfFileExists{\jobname.pla}{}{}
+\newcommand{\py at platformof}[2][\py at modulebadkey]{%
+  \ifx\py at modulebadkey#1 \def\py at key{#2}%
+  \else \def\py at key{#1}%
+  \fi%
+  \csname py at modplat@\py at key\endcsname%
+}
+\newcommand{\ignorePlatformAnnotation}[1]{}
+
+% \moduleauthor{name}{email}
+\newcommand{\moduleauthor}[2]{}
+
+% \sectionauthor{name}{email}
+\newcommand{\sectionauthor}[2]{}
+
+
+\newcommand{\py at defsynopsis}{Module has no synopsis.}
+\newcommand{\py at modulesynopsis}{\py at defsynopsis}
+\newcommand{\modulesynopsis}[1]{
+  \py at HaveModSynopsistrue
+  \renewcommand{\py at modulesynopsis}{#1}
+}
+
+% define the file
+\newwrite\py at ModSynopsisFile
+
+% hacked from \addtocontents from latex.ltx:
+\long\def\py at writeModSynopsisFile#1{%
+  \protected at write\py at ModSynopsisFile%
+      {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
+      {\string#1}%
+}
+\newcommand{\py at closeModSynopsisFile}{
+  \ifpy at ModSynopsisFileIsOpen
+    \closeout\py at ModSynopsisFile
+    \py at ModSynopsisFileIsOpenfalse
+  \fi
+}
+\newcommand{\py at openModSynopsisFile}{
+  \ifpy at ModSynopsisFileIsOpen\else
+    \openout\py at ModSynopsisFile=\py at ModSynopsisFilename
+    \py at ModSynopsisFileIsOpentrue
+  \fi
+}
+
+\newcommand{\py at ProcessModSynopsis}{
+  \ifpy at HaveModSynopsis
+    \py at writeModSynopsisFile{\modulesynopsis%
+      {\py at thismodulekey}{\py at thismodule}%
+      {\py at thismoduletype}{\py at modulesynopsis}}%
+    \py at HaveModSynopsisfalse
+  \fi
+  \renewcommand{\py at modulesynopsis}{\py at defsynopsis}
+}
+\AtEndDocument{\py at ProcessModSynopsis\py at closeModSynopsisFile}
+
+
+\long\def\py at writeModPlatformFile#1{%
+  \protected at write\py at ModPlatformFile%
+    {\let\label\@gobble \let\index\@gobble \let\glossary\@gobble}%
+    {\string#1}%
+}
+
+
+\newcommand{\localmoduletable}{
+  \IfFileExists{\py at ModSynopsisFilename}{
+    \begin{synopsistable}
+      \input{\py at ModSynopsisFilename}
+    \end{synopsistable}
+  }{}
+}
+
+\ifpdf
+  \newcommand{\py at ModSynopsisSummary}[4]{%
+    \py at linkToName{label-module-#1}{\bfcode{#2}} & #4\\
+  }
+\else
+  \newcommand{\py at ModSynopsisSummary}[4]{\bfcode{#2} & #4\\}
+\fi
+\newenvironment{synopsistable}{
+  % key, name, type, synopsis
+  \let\modulesynopsis=\py at ModSynopsisSummary
+  \begin{tabular}{ll}
+}{
+  \end{tabular}
+}
+%
+% --------------------------------------------------------------------------
+
+
+\newcommand{\py at reset}{
+  \py at usingsubitemfalse
+  \py at ProcessModSynopsis
+  \renewcommand{\py at thisclass}{}
+  \renewcommand{\py at thismodule}{}
+  \renewcommand{\py at thismodulekey}{}
+  \renewcommand{\py at thismoduletype}{}
+}
+
+% Augment the sectioning commands used to get our own font family in place,
+% and reset some internal data items:
+\renewcommand{\section}{\py at reset%
+                        \@startsection{section}{1}{\z@}%
+                                    {-3.5ex \@plus -1ex \@minus -.2ex}%
+                                    {2.3ex \@plus.2ex}%
+                                    {\reset at font\Large\py at HeaderFamily}}
+\renewcommand{\subsection}{\@startsection{subsection}{2}{\z@}%
+                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
+                                    {1.5ex \@plus .2ex}%
+                                    {\reset at font\large\py at HeaderFamily}}
+\renewcommand{\subsubsection}{\@startsection{subsubsection}{3}{\z@}%
+                                    {-3.25ex\@plus -1ex \@minus -.2ex}%
+                                    {1.5ex \@plus .2ex}%
+                                    {\reset at font\normalsize\py at HeaderFamily}}
+\renewcommand{\paragraph}{\@startsection{paragraph}{4}{\z@}%
+                                    {3.25ex \@plus1ex \@minus.2ex}%
+                                    {-1em}%
+                                    {\reset at font\normalsize\py at HeaderFamily}}
+\renewcommand{\subparagraph}{\@startsection{subparagraph}{5}{\parindent}%
+                                    {3.25ex \@plus1ex \@minus .2ex}%
+                                    {-1em}%
+                                    {\reset at font\normalsize\py at 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 at 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 at 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 at 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 at 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 at unspecified}{...}
+
+
+\newlength{\py at argswidth}
+\newcommand{\py at sigparams}[1]{%
+  \parbox[t]{\py at argswidth}{\py at varvars{#1}\code{)}}}
+\newcommand{\py at sigline}[2]{%
+  \settowidth{\py at argswidth}{#1\code{(}}%
+  \addtolength{\py at argswidth}{-2\py at argswidth}%
+  \addtolength{\py at argswidth}{\textwidth}%
+  \item[#1\code{(}\py at 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 at sigline{\code{#1 \bfcode{#2}}}{#3}%
+  \index{#2@{\py at idxcode{#2()}}}
+}
+\newenvironment{cfuncdesc}[4][\py at 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 at idxcode{#2}}}]
+}{\end{fulllineitems}}
+
+% C data types -----------------------------------------------------------
+% \begin{ctypedesc}[index name]{typedef name}
+\newenvironment{ctypedesc}[2][\py at badkey]{
+  \begin{fulllineitems}
+    \item[\bfcode{#2}%
+    \ifx\@undefined#1\relax%
+      \index{#2@{\py at idxcode{#2}} (C type)}
+    \else%
+      \index{#2@{\py at 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 at 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 at idxcode{#1}} (macro)}]
+}{\end{fulllineitems}}
+
+% simple functions (not methods) -----------------------------------------
+% \begin{funcdesc}{name}{args}
+\newcommand{\funcline}[2]{%
+  \funclineni{#1}{#2}%
+  \index{#1@{\py at idxcode{#1()}} (in module \py at 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 at sigline{\bfcode{#1}}{#2}}
+\newenvironment{funcdescni}[2]{
+  \begin{fulllineitems}
+    \funclineni{#1}{#2}
+}{\end{fulllineitems}}
+
+% classes ----------------------------------------------------------------
+% \begin{classdesc}{name}{constructor args}
+\newcommand{\classline}[2]{
+  \py at sigline{\strong{class }\bfcode{#1}}{#2}%
+  \index{#1@{\py at idxcode{#1}} (class in \py at thismodule)}}
+\newenvironment{classdesc}[2]{
+  % Using \renewcommand doesn't work for this, for unknown reasons:
+  \global\def\py at 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 at thisclass{#1}
+  \begin{fulllineitems}
+    \item[\strong{class }\code{\bfcode{#1}}%
+      \index{#1@{\py at idxcode{#1}} (class in \py at 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 at thisclass{#1}
+  \begin{fulllineitems}
+    \py at sigline{\strong{exception }\bfcode{#1}}{#2}%
+    \index{#1@{\py at idxcode{#1}} (exception in \py at thismodule)}
+}{\end{fulllineitems}}
+
+% There is no corresponding {excclassdesc*} environment.  To describe
+% a class exception without parameters, use the {excdesc} environment.
+
+
+\let\py at classbadkey=\@undefined
+
+% object method ----------------------------------------------------------
+% \begin{methoddesc}[classname]{methodname}{args}
+\newcommand{\methodline}[3][\@undefined]{
+  \methodlineni{#2}{#3}
+  \ifx\@undefined#1\relax
+    \index{#2@{\py at idxcode{#2()}} (\py at thisclass\ method)}
+  \else
+    \index{#2@{\py at idxcode{#2()}} (#1 method)}
+  \fi
+}
+\newenvironment{methoddesc}[3][\@undefined]{
+  \begin{fulllineitems}
+    \ifx\@undefined#1\relax
+      \methodline{#2}{#3}
+    \else
+      \def\py at 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 at classbadkey]{%
+  \py at sigline{\bfcode{#2}}{#3}}
+\newenvironment{methoddescni}[3][\py at classbadkey]{
+  \begin{fulllineitems}
+    \methodlineni{#2}{#3}
+}{\end{fulllineitems}}
+
+% object data attribute --------------------------------------------------
+% \begin{memberdesc}[classname]{membername}
+\newcommand{\memberline}[2][\py at classbadkey]{%
+  \ifx\@undefined#1\relax
+    \memberlineni{#2}
+    \index{#2@{\py at idxcode{#2}} (\py at thisclass\ attribute)}
+  \else
+    \memberlineni{#2}
+    \index{#2@{\py at idxcode{#2}} (#1 attribute)}
+  \fi
+}
+\newenvironment{memberdesc}[2][\py at classbadkey]{
+  \begin{fulllineitems}
+    \ifx\@undefined#1\relax
+      \memberline{#2}
+    \else
+      \def\py at 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 at classbadkey]{\item[\bfcode{#2}]}
+\newenvironment{memberdescni}[2][\py at 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 at idxcode{#1}} (exception in \py at thismodule)}]
+}{\end{fulllineitems}}
+
+% Module data or constants: ----------------------------------------------
+% \begin{datadesc}{name}
+\newcommand{\dataline}[1]{%
+  \datalineni{#1}\index{#1@{\py at idxcode{#1}} (data in \py at 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"!
+
+\newcommand{\code}[1]{\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 at defaultsize\textrm{\textit{#1\/}}}%
+  \else%
+    \py at 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 at smallsize\textsf{\let\e=\textbackslash#1}}}
+
+\newcommand{\email}[1]{{\py at smallsize\textsf{#1}}}
+\newcommand{\newsgroup}[1]{{\py at smallsize\textsf{#1}}}
+
+\newcommand{\py at varvars}[1]{{%
+  {\let\unspecified=\py at unspecified%
+   \let\moreargs=\py at moreargs%
+   \var{#1}}}}
+
+% 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 at smallsize\textsf{#1:}}}
+\newcommand{\mimetype}[1]{{\py at smallsize\textsf{#1}}}
+% The \! is a "negative thin space" in math mode.
+\newcommand{\regexp}[1]{%
+  {\tiny$^{^\lceil}\!\!$%
+   {\py at 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}}
+
+% cited titles:  \citetitle{Title of Work}
+%       online:  \citetitle[url-to-resource]{Title of Work}
+\ifpdf
+  \newcommand{\citetitle}[2][\py at modulebadkey]{%
+    \ifx\py at 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 at 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 at noticelength}
+
+\newcommand{\py at heavybox}{
+  \setlength{\fboxrule}{1pt}
+  \setlength{\fboxsep}{7pt}
+  \setlength{\py at noticelength}{\linewidth}
+  \addtolength{\py at noticelength}{-2\fboxsep}
+  \addtolength{\py at noticelength}{-2\fboxrule}
+  \setlength{\shadowsize}{3pt}
+  \Sbox
+  \minipage{\py at noticelength}
+}
+\newcommand{\py at endheavybox}{
+  \endminipage
+  \endSbox
+  \fbox{\TheSbox}
+}
+
+% a 'note' is as plain as it gets:
+\newcommand{\py at noticelabel@note}{Note:}
+\newcommand{\py at noticestart@note}{}
+\newcommand{\py at noticeend@note}{}
+
+% a 'warning' gets more visible distinction:
+\newcommand{\py at noticelabel@warning}{Warning:}
+\newcommand{\py at noticestart@warning}{\py at heavybox}
+\newcommand{\py at noticeend@warning}{\py at endheavybox}
+
+\newenvironment{notice}[1][note]{
+  \def\py at noticetype{#1}
+  \csname py at noticestart@#1\endcsname
+  \par\strong{\csname py at noticelabel@#1\endcsname}
+}{\csname py at noticeend@\py at noticetype\endcsname}
+\newcommand{\note}[1]{\strong{\py at noticelabel@note} #1}
+\newcommand{\warning}[1]{\strong{\py at 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 at badkey]{%
+  \ifx\@undefined#1\relax%
+    {  New in version #2.  }%
+  \else%
+    {  New in version #2:\ #1  }%
+  \fi%
+}
+\newcommand{\versionchanged}[2][\py at 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}%
+}
+
+% 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 at seemodule}[3][\py at modulebadkey]{%
+    \par%
+    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
+    \begin{fulllineitems}
+      \item[\py at linkToName{label-module-\py at modulekey}{Module \module{#2}}
+            (section \ref{module-\py at modulekey}):]
+      #3
+    \end{fulllineitems}
+  }
+\else
+  \newcommand{\py at seemodule}[3][\py at modulebadkey]{%
+    \par%
+    \ifx\py at modulebadkey#1\def\py at modulekey{#2}\else\def\py at modulekey{#1}\fi%
+    \begin{fulllineitems}
+      \item[Module \module{#2} (section \ref{module-\py at modulekey}):]
+      #3
+    \end{fulllineitems}
+  }
+\fi
+
+% \seelink{url}{link text}{why it's interesting}
+\newcommand{\py at seelink}[3]{%
+  \par
+  \begin{fulllineitems}
+    \item[\ulink{#2}{#1}]
+    #3
+  \end{fulllineitems}
+}
+% \seetitle[url]{title}{why it's interesting}
+\newcommand{\py at seetitle}[3][\py at modulebadkey]{%
+  \par
+  \begin{fulllineitems}
+    \item[\citetitle{#2}]
+    \ifx\py at modulebadkey#1\else
+      \item[{\small{(\url{#1})}}]
+    \fi
+    #3
+  \end{fulllineitems}
+}
+% \seepep{number}{title}{why it's interesting}
+\newcommand{\py at seepep}[3]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\pep{#1}, ``\emph{#2}'']
+    #3
+  \end{fulllineitems}
+}
+% \seerfc{number}{title}{why it's interesting}
+\newcommand{\py at seerfc}[3]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\rfc{#1}, ``\emph{#2}'']
+    #3
+  \end{fulllineitems}
+}
+% \seeurl{url}{why it's interesting}
+\newcommand{\py at seeurl}[2]{%
+  \par%
+  \begin{fulllineitems}
+    \item[\url{#1}]
+    #2
+  \end{fulllineitems}
+}
+
+\newenvironment{seealso*}{
+  \par
+  \def\seetext##1{\par{##1}}
+  \let\seemodule=\py at seemodule
+  \let\seepep=\py at seepep
+  \let\seerfc=\py at seerfc
+  \let\seetitle=\py at seetitle
+  \let\seeurl=\py at seeurl
+  \let\seelink=\py at seelink
+}{\par}
+\newenvironment{seealso}{
+  \par
+  \strong{See Also:}
+  \par
+  \def\seetext##1{\par{##1}}
+  \let\seemodule=\py at seemodule
+  \let\seepep=\py at seepep
+  \let\seerfc=\py at seerfc
+  \let\seetitle=\py at seetitle
+  \let\seeurl=\py at seeurl
+  \let\seelink=\py at 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 at release}{}
+\newcommand{\version}{}
+\newcommand{\shortversion}{}
+\newcommand{\releaseinfo}{}
+\newcommand{\releasename}{Release}
+\newcommand{\release}[1]{%
+  \renewcommand{\py at 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 at authoraddress}{}
+\newcommand{\authoraddress}[1]{\renewcommand{\py at 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 at HeaderFamily}
+  \ChNumVar{\raggedleft \bfseries\Large\py at HeaderFamily}
+  \ChTitleVar{\raggedleft \rm\Huge\py at HeaderFamily}
+  % This creates chapter heads without the leading \vspace*{}:
+  \def\@makechapterhead#1{%
+    {\parindent \z@ \raggedright \normalfont
+      \ifnum \c at secnumdepth >\m at 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}

Modified: doctools/trunk/sphinx/web/admin.py
==============================================================================
--- doctools/trunk/sphinx/web/admin.py	(original)
+++ doctools/trunk/sphinx/web/admin.py	Sat Dec 29 11:58:10 2007
@@ -88,7 +88,7 @@
         Log the user out.
         """
         req.logout()
-        return RedirectResponse('admin/login/')
+        return RedirectResponse('@admin/login/')
 
     def do_change_password(self, req):
         """

Modified: doctools/trunk/sphinx/web/antispam.py
==============================================================================
--- doctools/trunk/sphinx/web/antispam.py	(original)
+++ doctools/trunk/sphinx/web/antispam.py	Sat Dec 29 11:58:10 2007
@@ -43,13 +43,16 @@
             else:
                 lines = [l.strip() for l in data.splitlines()
                               if not l.startswith('#')]
-                f = file(bad_content_file, 'w')
-                f.write('\n'.join(lines))
+                with file(bad_content_file, 'w') as f:
+                    f.write('\n'.join(lines))
                 last_change = int(time.time())
 
         if lines is None:
-            with file(bad_content_file) as f:
-                lines = [l.strip() for l in f]
+            try:
+                with file(bad_content_file) as f:
+                    lines = [l.strip() for l in f]
+            except:
+                lines = []
         self.rules = [re.compile(rule) for rule in lines if rule]
 
     def is_spam(self, fields):

Modified: doctools/trunk/sphinx/web/application.py
==============================================================================
--- doctools/trunk/sphinx/web/application.py	(original)
+++ doctools/trunk/sphinx/web/application.py	Sat Dec 29 11:58:10 2007
@@ -28,8 +28,7 @@
 
 from .feed import Feed
 from .mail import Email
-from .util import render_template, render_simple_template, get_target_uri, \
-     blackhole_dict, striptags
+from .util import render_template, get_target_uri, blackhole_dict, striptags
 from .admin import AdminPanel
 from .userdb import UserDatabase
 from .robots import robots_txt
@@ -39,9 +38,9 @@
 from .wsgiutil import Request, Response, RedirectResponse, \
      JSONResponse, SharedDataMiddleware, NotFound, get_base_uri
 
-from ..util import relative_uri, shorten_result
+from ..util import relative_uri
 from ..search import SearchFrontend
-from ..writer import HTMLWriter
+from ..htmlwriter import HTMLWriter
 from ..builder import LAST_BUILD_FILENAME, ENV_PICKLE_FILENAME
 
 from docutils.io import StringOutput
@@ -88,6 +87,7 @@
 class MockBuilder(object):
     def get_relative_uri(self, from_, to):
         return ''
+    name = 'web'
 
 
 NoCache = object()
@@ -139,8 +139,7 @@
 
 
     def load_env(self, new_mtime):
-        env_lock.acquire()
-        try:
+        with env_lock:
             if self.buildmtime == new_mtime:
                 # happens if another thread already reloaded the env
                 return
@@ -153,8 +152,6 @@
                 self.search_frontend = SearchFrontend(pickle.load(f))
             self.buildmtime = new_mtime
             self.cache.clear()
-        finally:
-            env_lock.release()
 
 
     def search(self, req):
@@ -209,9 +206,11 @@
         warning_stream = StringIO.StringIO()
         env2 = copy.deepcopy(self.env)
         destination = StringOutput(encoding='utf-8')
-        writer = HTMLWriter(env2.config)
+        builder = MockBuilder()
+        builder.config = env2.config
+        writer = HTMLWriter(builder)
         doctree = env2.read_file(page_id, pathname, save_parsed=False)
-        doctree = env2.get_and_resolve_doctree(page_id, MockBuilder(), doctree)
+        doctree = env2.get_and_resolve_doctree(page_id, builder, doctree)
         doctree.settings = OptionParser(defaults=env2.settings,
                                         components=(writer,)).get_default_values()
         doctree.reporter = Reporter(page_id, 2, 4, stream=warning_stream)

Modified: doctools/trunk/sphinx/web/util.py
==============================================================================
--- doctools/trunk/sphinx/web/util.py	(original)
+++ doctools/trunk/sphinx/web/util.py	Sat Dec 29 11:58:10 2007
@@ -71,11 +71,6 @@
     return tmpl.render(context)
 
 
-def render_simple_template(template_name, context):
-    tmpl = jinja_env.get_template(template_name)
-    return tmpl.render(context)
-
-
 class lazy_property(object):
     """
     Descriptor implementing a "lazy property", i.e. the function


More information about the Python-checkins mailing list