[Zope-Checkins] CVS: Zope/lib/python/docutils - __init__.py:1.2 core.py:1.2 frontend.py:1.2 io.py:1.2 nodes.py:1.2 optik.py:1.2 roman.py:1.2 statemachine.py:1.2 urischemes.py:1.2 utils.py:1.2

Andreas Jung andreas@andreas-jung.com
Sat, 1 Feb 2003 04:26:35 -0500


Update of /cvs-repository/Zope/lib/python/docutils
In directory cvs.zope.org:/tmp/cvs-serv18056/docutils

Added Files:
	__init__.py core.py frontend.py io.py nodes.py optik.py 
	roman.py statemachine.py urischemes.py utils.py 
Log Message:
merge from ajung-restructuredtext-integration-branch


=== Zope/lib/python/docutils/__init__.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:33 2003
+++ Zope/lib/python/docutils/__init__.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,130 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+This is the Docutils (Python Documentation Utilities) package.
+
+Package Structure
+=================
+
+Modules:
+
+- __init__.py: Contains the package docstring only (this text).
+
+- core.py: Contains the ``Publisher`` class and ``publish()`` convenience
+  function.
+
+- frontend.py: Command-line and common processing for Docutils front-ends.
+
+- io.py: Provides a uniform API for low-level input and output.
+
+- nodes.py: Docutils document tree (doctree) node class library.
+
+- optik.py: Option parsing and command-line help; from Greg Ward's
+  http://optik.sf.net/ project, included for convenience.
+
+- roman.py: Conversion to and from Roman numerals. Courtesy of Mark
+  Pilgrim (http://diveintopython.org/).
+
+- statemachine.py: A finite state machine specialized for
+  regular-expression-based text filters.
+
+- urischemes.py: Contains a complete mapping of known URI addressing
+  scheme names to descriptions.
+
+- utils.py: Contains the ``Reporter`` system warning class and miscellaneous
+  utilities.
+
+Subpackages:
+
+- languages: Language-specific mappings of terms.
+
+- parsers: Syntax-specific input parser modules or packages.
+
+- readers: Context-specific input handlers which understand the data
+  source and manage a parser.
+
+- transforms: Modules used by readers and writers to modify DPS
+  doctrees.
+
+- writers: Format-specific output translators.
+"""
+
+__docformat__ = 'reStructuredText'
+
+__version__ = '0.2.8'
+"""``major.minor.micro`` version number.  The micro number is bumped any time
+there's a change in the API incompatible with one of the front ends.  The
+minor number is bumped whenever there is a project release.  The major number
+will be bumped when the project is complete, and perhaps if there is a major
+change in the design."""
+
+
+class ApplicationError(StandardError): pass
+class DataError(ApplicationError): pass
+
+
+class SettingsSpec:
+
+    """
+    Runtime setting specification base class.
+
+    SettingsSpec subclass objects used by `docutils.frontend.OptionParser`.
+    """
+
+    settings_spec = ()
+    """Runtime settings specification.  Override in subclasses.
+
+    Specifies runtime settings and associated command-line options, as used by
+    `docutils.frontend.OptionParser`.  This tuple contains one or more sets of
+    option group title, description, and a list/tuple of tuples: ``('help
+    text', [list of option strings], {keyword arguments})``.  Group title
+    and/or description may be `None`; no group title implies no group, just a
+    list of single options.  Runtime settings names are derived implicitly
+    from long option names ("--a-setting" becomes ``settings.a_setting``) or
+    explicitly from the "destination" keyword argument."""
+
+    settings_default_overrides = None
+    """A dictionary of auxiliary defaults, to override defaults for settings
+    defined in other components.  Override in subclasses."""
+
+    relative_path_settings = ()
+    """Settings containing filesystem paths.  Override in subclasses.
+
+    Settings listed here are to be interpreted relative to the current working
+    directory."""
+
+
+class TransformSpec:
+
+    """
+    Runtime transform specification base class.
+
+    TransformSpec subclass objects used by `docutils.transforms.Transformer`.
+    """
+
+    default_transforms = ()
+    """Transforms required by this class.  Override in subclasses."""
+
+
+class Component(SettingsSpec, TransformSpec):
+
+    """Base class for Docutils components."""
+
+    component_type = None
+    """Override in subclasses."""
+
+    supported = ()
+    """Names for this component.  Override in subclasses."""
+
+    def supports(self, format):
+        """
+        Is `format` supported by this component?
+
+        To be used by transforms to ask the dependent component if it supports
+        a certain input context or output format.
+        """
+        return format in self.supported


=== Zope/lib/python/docutils/core.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:33 2003
+++ Zope/lib/python/docutils/core.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,326 @@
+# Authors: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+Calling the ``publish_*`` convenience functions (or instantiating a
+`Publisher` object) with component names will result in default
+behavior.  For custom behavior (setting component options), create
+custom component objects first, and pass *them* to
+``publish_*``/`Publisher`.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+from docutils import Component
+from docutils import frontend, io, readers, parsers, writers
+from docutils.frontend import OptionParser, ConfigParser
+
+
+class Publisher:
+
+    """
+    A facade encapsulating the high-level logic of a Docutils system.
+    """
+
+    def __init__(self, reader=None, parser=None, writer=None,
+                 source=None, source_class=io.FileInput,
+                 destination=None, destination_class=io.FileOutput,
+                 settings=None):
+        """
+        Initial setup.  If any of `reader`, `parser`, or `writer` are not
+        specified, the corresponding ``set_...`` method should be called with
+        a component name (`set_reader` sets the parser as well).
+        """
+
+        self.reader = reader
+        """A `readers.Reader` instance."""
+
+        self.parser = parser
+        """A `parsers.Parser` instance."""
+
+        self.writer = writer
+        """A `writers.Writer` instance."""
+
+        self.source = source
+        """The source of input data, an `io.Input` instance."""
+
+        self.source_class = source_class
+        """The class for dynamically created source objects."""
+
+        self.destination = destination
+        """The destination for docutils output, an `io.Output` instance."""
+
+        self.destination_class = destination_class
+        """The class for dynamically created destination objects."""
+
+        self.settings = settings
+        """An object containing Docutils settings as instance attributes.
+        Set by `self.process_command_line()` or `self.get_settings()`."""
+
+    def set_reader(self, reader_name, parser, parser_name):
+        """Set `self.reader` by name."""
+        reader_class = readers.get_reader_class(reader_name)
+        self.reader = reader_class(parser, parser_name)
+        self.parser = self.reader.parser
+
+    def set_writer(self, writer_name):
+        """Set `self.writer` by name."""
+        writer_class = writers.get_writer_class(writer_name)
+        self.writer = writer_class()
+
+    def set_components(self, reader_name, parser_name, writer_name):
+        if self.reader is None:
+            self.set_reader(reader_name, self.parser, parser_name)
+        if self.parser is None:
+            if self.reader.parser is None:
+                self.reader.set_parser(parser_name)
+            self.parser = self.reader.parser
+        if self.writer is None:
+            self.set_writer(writer_name)
+
+    def setup_option_parser(self, usage=None, description=None,
+                            settings_spec=None, **defaults):
+        #@@@ Add self.source & self.destination to components in future?
+        option_parser = OptionParser(
+            components=(settings_spec, self.parser, self.reader, self.writer),
+            usage=usage, description=description)
+        config = ConfigParser()
+        config.read_standard_files()
+        config_settings = config.get_section('options')
+        frontend.make_paths_absolute(config_settings,
+                                     option_parser.relative_path_settings)
+        defaults.update(config_settings)
+        option_parser.set_defaults(**defaults)
+        return option_parser
+
+    def get_settings(self, usage=None, description=None,
+                     settings_spec=None, **defaults):
+        """
+        Set and return default settings (overrides in `defaults` keyword
+        argument).
+
+        Set components first (`self.set_reader` & `self.set_writer`).
+        Explicitly setting `self.settings` disables command line option
+        processing from `self.publish()`.
+        """
+        option_parser = self.setup_option_parser(usage, description,
+                                                 settings_spec, **defaults)
+        self.settings = option_parser.get_default_values()
+        return self.settings
+
+    def process_command_line(self, argv=None, usage=None, description=None,
+                             settings_spec=None, **defaults):
+        """
+        Pass an empty list to `argv` to avoid reading `sys.argv` (the
+        default).
+
+        Set components first (`self.set_reader` & `self.set_writer`).
+        """
+        option_parser = self.setup_option_parser(usage, description,
+                                                 settings_spec, **defaults)
+        if argv is None:
+            argv = sys.argv[1:]
+        self.settings = option_parser.parse_args(argv)
+
+    def set_io(self, source_path=None, destination_path=None):
+        if self.source is None:
+            self.set_source(source_path=source_path)
+        if self.destination is None:
+            self.set_destination(destination_path=destination_path)
+
+    def set_source(self, source=None, source_path=None):
+        if source_path is None:
+            source_path = self.settings._source
+        else:
+            self.settings._source = source_path
+        self.source = self.source_class(
+            source=source, source_path=source_path,
+            encoding=self.settings.input_encoding)
+
+    def set_destination(self, destination=None, destination_path=None):
+        if destination_path is None:
+            destination_path = self.settings._destination
+        else:
+            self.settings._destination = destination_path
+        self.destination = self.destination_class(
+            destination=destination, destination_path=destination_path,
+            encoding=self.settings.output_encoding)
+
+    def apply_transforms(self, document):
+        document.transformer.populate_from_components(
+            (self.source, self.reader, self.reader.parser, self.writer,
+             self.destination))
+        document.transformer.apply_transforms()
+
+    def publish(self, argv=None, usage=None, description=None,
+                settings_spec=None, settings_overrides=None):
+        """
+        Process command line options and arguments (if `self.settings` not
+        already set), run `self.reader` and then `self.writer`.  Return
+        `self.writer`'s output.
+        """
+        if self.settings is None:
+            self.process_command_line(argv, usage, description, settings_spec,
+                                      **(settings_overrides or {}))
+        elif settings_overrides:
+            self.settings._update(settings_overrides, 'loose')
+        self.set_io()
+        document = self.reader.read(self.source, self.parser, self.settings)
+        self.apply_transforms(document)
+        output = self.writer.write(document, self.destination)
+        if self.settings.dump_settings:
+            from pprint import pformat
+            print >>sys.stderr, '\n::: Runtime settings:'
+            print >>sys.stderr, pformat(self.settings.__dict__)
+        if self.settings.dump_internals:
+            from pprint import pformat
+            print >>sys.stderr, '\n::: Document internals:'
+            print >>sys.stderr, pformat(document.__dict__)
+        if self.settings.dump_transforms:
+            from pprint import pformat
+            print >>sys.stderr, '\n::: Transforms applied:'
+            print >>sys.stderr, pformat(document.transformer.applied)
+        if self.settings.dump_pseudo_xml:
+            print >>sys.stderr, '\n::: Pseudo-XML:'
+            print >>sys.stderr, document.pformat().encode(
+                'raw_unicode_escape')
+        return output
+
+
+default_usage = '%prog [options] [<source> [<destination>]]'
+default_description = ('Reads from <source> (default is stdin) and writes to '
+                       '<destination> (default is stdout).')
+
+def publish_cmdline(reader=None, reader_name='standalone',
+                    parser=None, parser_name='restructuredtext',
+                    writer=None, writer_name='pseudoxml',
+                    settings=None, settings_spec=None,
+                    settings_overrides=None, argv=None,
+                    usage=default_usage, description=default_description):
+    """
+    Set up & run a `Publisher`.  For command-line front ends.
+
+    Parameters:
+
+    - `reader`: A `docutils.readers.Reader` object.
+    - `reader_name`: Name or alias of the Reader class to be instantiated if
+      no `reader` supplied.
+    - `parser`: A `docutils.parsers.Parser` object.
+    - `parser_name`: Name or alias of the Parser class to be instantiated if
+      no `parser` supplied.
+    - `writer`: A `docutils.writers.Writer` object.
+    - `writer_name`: Name or alias of the Writer class to be instantiated if
+      no `writer` supplied.
+    - `settings`: Runtime settings object.
+    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
+      subclass.  Used only if no `settings` specified.
+    - `settings_overrides`: A dictionary containing program-specific overrides
+      of component settings.
+    - `argv`: Command-line argument list to use instead of ``sys.argv[1:]``.
+    - `usage`: Usage string, output if there's a problem parsing the command
+      line.
+    - `description`: Program description, output for the "--help" option
+      (along with command-line option descriptions).
+    """
+    pub = Publisher(reader, parser, writer, settings=settings)
+    pub.set_components(reader_name, parser_name, writer_name)
+    pub.publish(argv, usage, description, settings_spec, settings_overrides)
+
+def publish_file(source=None, source_path=None,
+                 destination=None, destination_path=None,
+                 reader=None, reader_name='standalone',
+                 parser=None, parser_name='restructuredtext',
+                 writer=None, writer_name='pseudoxml',
+                 settings=None, settings_spec=None, settings_overrides=None):
+    """
+    Set up & run a `Publisher`.  For programmatic use with file-like I/O.
+
+    Parameters:
+
+    - `source`: A file-like object (must have "read" and "close" methods).
+    - `source_path`: Path to the input file.  Opened if no `source` supplied.
+      If neither `source` nor `source_path` are supplied, `sys.stdin` is used.
+    - `destination`: A file-like object (must have "write" and "close"
+      methods).
+    - `destination_path`: Path to the input file.  Opened if no `destination`
+      supplied.  If neither `destination` nor `destination_path` are supplied,
+      `sys.stdout` is used.
+    - `reader`: A `docutils.readers.Reader` object.
+    - `reader_name`: Name or alias of the Reader class to be instantiated if
+      no `reader` supplied.
+    - `parser`: A `docutils.parsers.Parser` object.
+    - `parser_name`: Name or alias of the Parser class to be instantiated if
+      no `parser` supplied.
+    - `writer`: A `docutils.writers.Writer` object.
+    - `writer_name`: Name or alias of the Writer class to be instantiated if
+      no `writer` supplied.
+    - `settings`: Runtime settings object.
+    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
+      subclass.  Used only if no `settings` specified.
+    - `settings_overrides`: A dictionary containing program-specific overrides
+      of component settings.
+    """
+    pub = Publisher(reader, parser, writer, settings=settings)
+    pub.set_components(reader_name, parser_name, writer_name)
+    if settings is None:
+        settings = pub.get_settings(settings_spec=settings_spec)
+    if settings_overrides:
+        settings._update(settings_overrides, 'loose')
+    pub.set_source(source, source_path)
+    pub.set_destination(destination, destination_path)
+    pub.publish()
+
+def publish_string(source, source_path=None, destination_path=None, 
+                   reader=None, reader_name='standalone',
+                   parser=None, parser_name='restructuredtext',
+                   writer=None, writer_name='pseudoxml',
+                   settings=None, settings_spec=None,
+                   settings_overrides=None):
+    """
+    Set up & run a `Publisher`, and return the string output.
+    For programmatic use with string I/O.
+
+    For encoded string output, be sure to set the "output_encoding" setting to
+    the desired encoding.  Set it to "unicode" for unencoded Unicode string
+    output.
+
+    Parameters:
+
+    - `source`: An input string; required.  This can be an encoded 8-bit
+      string (set the "input_encoding" setting to the correct encoding) or a
+      Unicode string (set the "input_encoding" setting to "unicode").
+    - `source_path`: Path to the file or object that produced `source`;
+      optional.  Only used for diagnostic output.
+    - `destination_path`: Path to the file or object which will receive the
+      output; optional.  Used for determining relative paths (stylesheets,
+      source links, etc.).
+    - `reader`: A `docutils.readers.Reader` object.
+    - `reader_name`: Name or alias of the Reader class to be instantiated if
+      no `reader` supplied.
+    - `parser`: A `docutils.parsers.Parser` object.
+    - `parser_name`: Name or alias of the Parser class to be instantiated if
+      no `parser` supplied.
+    - `writer`: A `docutils.writers.Writer` object.
+    - `writer_name`: Name or alias of the Writer class to be instantiated if
+      no `writer` supplied.
+    - `settings`: Runtime settings object.
+    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
+      subclass.  Used only if no `settings` specified.
+    - `settings_overrides`: A dictionary containing program-specific overrides
+      of component settings.
+    """
+    pub = Publisher(reader, parser, writer, settings=settings,
+                    source_class=io.StringInput,
+                    destination_class=io.StringOutput)
+    pub.set_components(reader_name, parser_name, writer_name)
+    if settings is None:
+        settings = pub.get_settings(settings_spec=settings_spec)
+    if settings_overrides:
+        settings._update(settings_overrides, 'loose')
+    pub.set_source(source, source_path)
+    pub.set_destination(destination_path=destination_path)
+    return pub.publish()


=== Zope/lib/python/docutils/frontend.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/frontend.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,310 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+Command-line and common processing for Docutils front-end tools.
+
+Exports the following classes:
+
+- `OptionParser`: Standard Docutils command-line processing.
+- `Values`: Runtime settings; objects are simple structs
+  (``object.attribute``).
+- `ConfigParser`: Standard Docutils config file processing.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import os
+import os.path
+import ConfigParser as CP
+import docutils
+from docutils import optik
+from docutils.optik import Values
+
+
+def store_multiple(option, opt, value, parser, *args, **kwargs):
+    """
+    Store multiple values in `parser.values`.  (Option callback.)
+    
+    Store `None` for each attribute named in `args`, and store the value for
+    each key (attribute name) in `kwargs`.
+    """
+    for attribute in args:
+        setattr(parser.values, attribute, None)
+    for key, value in kwargs.items():
+        setattr(parser.values, key, value)
+
+def read_config_file(option, opt, value, parser):
+    """
+    Read a configuration file during option processing.  (Option callback.)
+    """
+    config_parser = ConfigParser()
+    config_parser.read(value)
+    settings = config_parser.get_section('options')
+    make_paths_absolute(settings, parser.relative_path_settings,
+                        os.path.dirname(value))
+    parser.values.__dict__.update(settings)
+
+def make_paths_absolute(pathdict, keys, base_path=None):
+    """
+    Interpret filesystem path settings relative to the `base_path` given.
+
+    Paths are values in `pathdict` whose keys are in `keys`.  Get `keys` from
+    `OptionParser.relative_path_settings`.
+    """
+    if base_path is None:
+        base_path = os.getcwd()
+    for key in keys:
+        if pathdict.has_key(key) and pathdict[key]:
+            pathdict[key] = os.path.normpath(
+                os.path.abspath(os.path.join(base_path, pathdict[key])))
+
+
+class OptionParser(optik.OptionParser, docutils.SettingsSpec):
+
+    """
+    Parser for command-line and library use.  The `settings_spec`
+    specification here and in other Docutils components are merged to build
+    the set of command-line options and runtime settings for this process.
+
+    Common settings (defined below) and component-specific settings must not
+    conflict.  Short options are reserved for common settings, and components
+    are restrict to using long options.
+    """
+
+    threshold_choices = 'info 1 warning 2 error 3 severe 4 none 5'.split()
+    """Possible inputs for for --report and --halt threshold values."""
+
+    thresholds = {'info': 1, 'warning': 2, 'error': 3, 'severe': 4, 'none': 5}
+    """Lookup table for --report and --halt threshold values."""
+
+    settings_spec = (
+        'General Docutils Options',
+        None,
+        (('Include a "Generated by Docutils" credit and link at the end '
+          'of the document.',
+          ['--generator', '-g'], {'action': 'store_true'}),
+         ('Do not include a generator credit.',
+          ['--no-generator'], {'action': 'store_false', 'dest': 'generator'}),
+         ('Include the date at the end of the document (UTC).',
+          ['--date', '-d'], {'action': 'store_const', 'const': '%Y-%m-%d',
+                             'dest': 'datestamp'}),
+         ('Include the time & date at the end of the document (UTC).',
+          ['--time', '-t'], {'action': 'store_const',
+                             'const': '%Y-%m-%d %H:%M UTC',
+                             'dest': 'datestamp'}),
+         ('Do not include a datestamp of any kind.',
+          ['--no-datestamp'], {'action': 'store_const', 'const': None,
+                               'dest': 'datestamp'}),
+         ('Include a "View document source" link (relative to destination).',
+          ['--source-link', '-s'], {'action': 'store_true'}),
+         ('Use the supplied <URL> verbatim for a "View document source" '
+          'link; implies --source-link.',
+          ['--source-url'], {'metavar': '<URL>'}),
+         ('Do not include a "View document source" link.',
+          ['--no-source-link'],
+          {'action': 'callback', 'callback': store_multiple,
+           'callback_args': ('source_link', 'source_url')}),
+         ('Enable backlinks from section headers to table of contents '
+          'entries.  This is the default.',
+          ['--toc-entry-backlinks'],
+          {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'entry',
+           'default': 'entry'}),
+         ('Enable backlinks from section headers to the top of the table of '
+          'contents.',
+          ['--toc-top-backlinks'],
+          {'dest': 'toc_backlinks', 'action': 'store_const', 'const': 'top'}),
+         ('Disable backlinks to the table of contents.',
+          ['--no-toc-backlinks'],
+          {'dest': 'toc_backlinks', 'action': 'store_false'}),
+         ('Enable backlinks from footnotes and citations to their '
+          'references.  This is the default.',
+          ['--footnote-backlinks'],
+          {'action': 'store_true', 'default': 1}),
+         ('Disable backlinks from footnotes and citations.',
+          ['--no-footnote-backlinks'],
+          {'dest': 'footnote_backlinks', 'action': 'store_false'}),
+         ('Set verbosity threshold; report system messages at or higher than '
+          '<level> (by name or number: "info" or "1", warning/2, error/3, '
+          'severe/4; also, "none" or "5").  Default is 2 (warning).',
+          ['--report', '-r'], {'choices': threshold_choices, 'default': 2,
+                               'dest': 'report_level', 'metavar': '<level>'}),
+         ('Report all system messages, info-level and higher.  (Same as '
+          '"--report=info".)',
+          ['--verbose', '-v'], {'action': 'store_const', 'const': 'info',
+                                'dest': 'report_level'}),
+         ('Do not report any system messages.  (Same as "--report=none".)',
+          ['--quiet', '-q'], {'action': 'store_const', 'const': 'none',
+                              'dest': 'report_level'}),
+         ('Set the threshold (<level>) at or above which system messages are '
+          'converted to exceptions, halting execution immediately.  Levels '
+          'as in --report.  Default is 4 (severe).',
+          ['--halt'], {'choices': threshold_choices, 'dest': 'halt_level',
+                       'default': 4, 'metavar': '<level>'}),
+         ('Same as "--halt=info": halt processing at the slightest problem.',
+          ['--strict'], {'action': 'store_const', 'const': 'info',
+                         'dest': 'halt_level'}),
+         ('Report debug-level system messages.',
+          ['--debug'], {'action': 'store_true'}),
+         ('Do not report debug-level system messages.',
+          ['--no-debug'], {'action': 'store_false', 'dest': 'debug'}),
+         ('Send the output of system messages (warnings) to <file>.',
+          ['--warnings'], {'dest': 'warning_stream', 'metavar': '<file>'}),
+         ('Specify the encoding of input text.  Default is locale-dependent.',
+          ['--input-encoding', '-i'], {'metavar': '<name>'}),
+         ('Specify the encoding for output.  Default is UTF-8.',
+          ['--output-encoding', '-o'],
+          {'metavar': '<name>', 'default': 'utf-8'}),
+         ('Specify the language of input text (ISO 639 2-letter identifier).'
+          '  Default is "en" (English).',
+          ['--language', '-l'], {'dest': 'language_code', 'default': 'en',
+                                 'metavar': '<name>'}),
+         ('Read configuration settings from <file>, if it exists.',
+          ['--config'], {'metavar': '<file>', 'type': 'string',
+                         'action': 'callback', 'callback': read_config_file}),
+         ("Show this program's version number and exit.",
+          ['--version', '-V'], {'action': 'version'}),
+         ('Show this help message and exit.',
+          ['--help', '-h'], {'action': 'help'}),
+         # Hidden options, for development use only:
+         (optik.SUPPRESS_HELP,
+          ['--dump-settings'],
+          {'action': 'store_true'}),
+         (optik.SUPPRESS_HELP,
+          ['--dump-internals'],
+          {'action': 'store_true'}),
+         (optik.SUPPRESS_HELP,
+          ['--dump-transforms'],
+          {'action': 'store_true'}),
+         (optik.SUPPRESS_HELP,
+          ['--dump-pseudo-xml'],
+          {'action': 'store_true'}),
+         (optik.SUPPRESS_HELP,
+          ['--expose-internal-attribute'],
+          {'action': 'append', 'dest': 'expose_internals'}),))
+    """Runtime settings and command-line options common to all Docutils front
+    ends.  Setting specs specific to individual Docutils components are also
+    used (see `populate_from_components()`)."""
+
+    relative_path_settings = ('warning_stream',)
+
+    version_template = '%%prog (Docutils %s)' % docutils.__version__
+    """Default version message."""
+
+    def __init__(self, components=(), *args, **kwargs):
+        """
+        `components` is a list of Docutils components each containing a
+        ``.settings_spec`` attribute.  `defaults` is a mapping of setting
+        default overrides.
+        """
+        optik.OptionParser.__init__(
+            self, help=None,
+            format=optik.Titled(),
+            # Needed when Optik is updated (replaces above 2 lines):
+            #self, add_help=None,
+            #formatter=optik.TitledHelpFormatter(width=78),
+            *args, **kwargs)
+        if not self.version:
+            self.version = self.version_template
+        # Internal settings with no defaults from settings specifications;
+        # initialize manually:
+        self.set_defaults(_source=None, _destination=None)
+        # Make an instance copy (it will be modified):
+        self.relative_path_settings = list(self.relative_path_settings)
+        self.populate_from_components(tuple(components) + (self,))
+
+    def populate_from_components(self, components):
+        for component in components:
+            if component is None:
+                continue
+            i = 0
+            settings_spec = component.settings_spec
+            self.relative_path_settings.extend(
+                component.relative_path_settings)
+            while i < len(settings_spec):
+                title, description, option_spec = settings_spec[i:i+3]
+                if title:
+                    group = optik.OptionGroup(self, title, description)
+                    self.add_option_group(group)
+                else:
+                    group = self        # single options
+                for (help_text, option_strings, kwargs) in option_spec:
+                    group.add_option(help=help_text, *option_strings,
+                                     **kwargs)
+                i += 3
+        for component in components:
+            if component and component.settings_default_overrides:
+                self.defaults.update(component.settings_default_overrides)
+
+    def check_values(self, values, args):
+        if hasattr(values, 'report_level'):
+            values.report_level = self.check_threshold(values.report_level)
+        if hasattr(values, 'halt_level'):
+            values.halt_level = self.check_threshold(values.halt_level)
+        values._source, values._destination = self.check_args(args)
+        make_paths_absolute(values.__dict__, self.relative_path_settings,
+                            os.getcwd())
+        return values
+
+    def check_threshold(self, level):
+        try:
+            return int(level)
+        except ValueError:
+            try:
+                return self.thresholds[level.lower()]
+            except (KeyError, AttributeError):
+                self.error('Unknown threshold: %r.' % level)
+
+    def check_args(self, args):
+        source = destination = None
+        if args:
+            source = args.pop(0)
+        if args:
+            destination = args.pop(0)
+        if args:
+            self.error('Maximum 2 arguments allowed.')
+        if source and source == destination:
+            self.error('Do not specify the same file for both source and '
+                       'destination.  It will clobber the source file.')
+        return source, destination
+
+
+class ConfigParser(CP.ConfigParser):
+
+    standard_config_files = (
+        '/etc/docutils.conf',               # system-wide
+        './docutils.conf',                  # project-specific
+        os.path.expanduser('~/.docutils'))  # user-specific
+    """Docutils configuration files, using ConfigParser syntax (section
+    'options').  Later files override earlier ones."""
+
+    def read_standard_files(self):
+        self.read(self.standard_config_files)
+
+    def optionxform(self, optionstr):
+        """
+        Transform '-' to '_' so the cmdline form of option names can be used.
+        """
+        return optionstr.lower().replace('-', '_')
+
+    def get_section(self, section, raw=0, vars=None):
+        """
+        Return a given section as a dictionary (empty if the section
+        doesn't exist).
+
+        All % interpolations are expanded in the return values, based on the
+        defaults passed into the constructor, unless the optional argument
+        `raw` is true.  Additional substitutions may be provided using the
+        `vars` argument, which must be a dictionary whose contents overrides
+        any pre-existing defaults.
+
+        The section DEFAULT is special.
+        """
+        section_dict = {}
+        if self.has_section(section):
+            for option in self.options(section):
+                section_dict[option] = self.get(section, option, raw, vars)
+        return section_dict


=== Zope/lib/python/docutils/io.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/io.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,291 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+I/O classes provide a uniform API for low-level input and output.  Subclasses
+will exist for a variety of input/output mechanisms.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+import locale
+from docutils import TransformSpec
+
+
+class Input(TransformSpec):
+
+    """
+    Abstract base class for input wrappers.
+    """
+
+    component_type = 'input'
+
+    default_source_path = None
+
+    def __init__(self, settings=None, source=None, source_path=None,
+                 encoding=None):
+        self.encoding = encoding
+        """The character encoding for the input source."""
+
+        if settings:
+            if not encoding:
+                self.encoding = settings.input_encoding
+            import warnings, traceback
+            warnings.warn(
+                'Setting input encoding via a "settings" struct is '
+                'deprecated; send encoding directly instead.\n%s'
+                % ''.join(traceback.format_list(traceback.extract_stack()
+                                                [-3:-1])))
+
+        self.source = source
+        """The source of input data."""
+
+        self.source_path = source_path
+        """A text reference to the source."""
+
+        if not source_path:
+            self.source_path = self.default_source_path
+
+    def __repr__(self):
+        return '%s: source=%r, source_path=%r' % (self.__class__, self.source,
+                                                  self.source_path)
+
+    def read(self):
+        raise NotImplementedError
+
+    def decode(self, data):
+        """
+        Decode a string, `data`, heuristically.
+        Raise UnicodeError if unsuccessful.
+
+        The client application should call ``locale.setlocale`` at the
+        beginning of processing::
+
+            locale.setlocale(locale.LC_ALL, '')
+        """
+        if self.encoding and self.encoding.lower() == 'unicode':
+            return unicode(data)
+        encodings = [self.encoding, 'utf-8']
+        try:
+            encodings.append(locale.nl_langinfo(locale.CODESET))
+        except:
+            pass
+        try:
+            encodings.append(locale.getlocale()[1])
+        except:
+            pass
+        try:
+            encodings.append(locale.getdefaultlocale()[1])
+        except:
+            pass
+        encodings.append('latin-1')
+        for enc in encodings:
+            if not enc:
+                continue
+            try:
+                decoded = unicode(data, enc)
+                return decoded
+            except (UnicodeError, LookupError):
+                pass
+        raise UnicodeError(
+            'Unable to decode input data.  Tried the following encodings: %s.'
+            % ', '.join([repr(enc) for enc in encodings if enc]))
+
+
+class Output(TransformSpec):
+
+    """
+    Abstract base class for output wrappers.
+    """
+
+    component_type = 'output'
+
+    default_destination_path = None
+
+    def __init__(self, settings=None, destination=None, destination_path=None,
+                 encoding=None):
+        self.encoding = encoding
+        """The character encoding for the output destination."""
+
+        if settings:
+            if not encoding:
+                self.encoding = settings.output_encoding
+            import warnings, traceback
+            warnings.warn(
+                'Setting output encoding via a "settings" struct is '
+                'deprecated; send encoding directly instead.\n%s'
+                % ''.join(traceback.format_list(traceback.extract_stack()
+                                                [-3:-1])))
+
+        self.destination = destination
+        """The destination for output data."""
+
+        self.destination_path = destination_path
+        """A text reference to the destination."""
+
+        if not destination_path:
+            self.destination_path = self.default_destination_path
+
+    def __repr__(self):
+        return ('%s: destination=%r, destination_path=%r'
+                % (self.__class__, self.destination, self.destination_path))
+
+    def write(self, data):
+        raise NotImplementedError
+
+    def encode(self, data):
+        if self.encoding and self.encoding.lower() == 'unicode':
+            return data
+        else:
+            return data.encode(self.encoding or '')
+
+
+class FileInput(Input):
+
+    """
+    Input for single, simple file-like objects.
+    """
+
+    def __init__(self, settings=None, source=None, source_path=None,
+                 encoding=None, autoclose=1):
+        """
+        :Parameters:
+            - `source`: either a file-like object (which is read directly), or
+              `None` (which implies `sys.stdin` if no `source_path` given).
+            - `source_path`: a path to a file, which is opened and then read.
+            - `autoclose`: close automatically after read (boolean); always
+              false if `sys.stdin` is the source.
+        """
+        Input.__init__(self, settings, source, source_path, encoding)
+        self.autoclose = autoclose
+        if source is None:
+            if source_path:
+                self.source = open(source_path)
+            else:
+                self.source = sys.stdin
+                self.autoclose = None
+        if not source_path:
+            try:
+                self.source_path = self.source.name
+            except AttributeError:
+                pass
+
+    def read(self):
+        """Read and decode a single file and return the data."""
+        data = self.source.read()
+        if self.autoclose:
+            self.close()
+        return self.decode(data)
+
+    def close(self):
+        self.source.close()
+
+
+class FileOutput(Output):
+
+    """
+    Output for single, simple file-like objects.
+    """
+
+    def __init__(self, settings=None, destination=None, destination_path=None,
+                 encoding=None, autoclose=1):
+        """
+        :Parameters:
+            - `destination`: either a file-like object (which is written
+              directly) or `None` (which implies `sys.stdout` if no
+              `destination_path` given).
+            - `destination_path`: a path to a file, which is opened and then
+              written.
+            - `autoclose`: close automatically after write (boolean); always
+              false if `sys.stdout` is the destination.
+        """
+        Output.__init__(self, settings, destination, destination_path,
+                        encoding)
+        self.opened = 1
+        self.autoclose = autoclose
+        if destination is None:
+            if destination_path:
+                self.opened = None
+            else:
+                self.destination = sys.stdout
+                self.autoclose = None
+        if not destination_path:
+            try:
+                self.destination_path = self.destination.name
+            except AttributeError:
+                pass
+
+    def open(self):
+        self.destination = open(self.destination_path, 'w')
+        self.opened = 1
+
+    def write(self, data):
+        """Encode `data`, write it to a single file, and return it."""
+        output = self.encode(data)
+        if not self.opened:
+            self.open()
+        self.destination.write(output)
+        if self.autoclose:
+            self.close()
+        return output
+
+    def close(self):
+        self.destination.close()
+        self.opened = None
+
+
+class StringInput(Input):
+
+    """
+    Direct string input.
+    """
+
+    default_source_path = '<string>'
+
+    def read(self):
+        """Decode and return the source string."""
+        return self.decode(self.source)
+
+
+class StringOutput(Output):
+
+    """
+    Direct string output.
+    """
+
+    default_destination_path = '<string>'
+
+    def write(self, data):
+        """Encode `data`, store it in `self.destination`, and return it."""
+        self.destination = self.encode(data)
+        return self.destination
+
+
+class NullInput(Input):
+
+    """
+    Degenerate input: read nothing.
+    """
+
+    default_source_path = 'null input'
+
+    def read(self):
+        """Return a null string."""
+        return u''
+
+
+class NullOutput(Output):
+
+    """
+    Degenerate output: write nothing.
+    """
+
+    default_destination_path = 'null output'
+
+    def write(self, data):
+        """Do nothing ([don't even] send data to the bit bucket)."""
+        pass


=== Zope/lib/python/docutils/nodes.py 1.1 => 1.2 === (1330/1430 lines abridged)
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/nodes.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,1427 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+Docutils document tree element class library.
+
+Classes in CamelCase are abstract base classes or auxiliary classes. The one
+exception is `Text`, for a text (PCDATA) node; uppercase is used to
+differentiate from element classes.  Classes in lower_case_with_underscores
+are element classes, matching the XML element generic identifiers in the DTD_.
+
+The position of each node (the level at which it can occur) is significant and
+is represented by abstract base classes (`Root`, `Structural`, `Body`,
+`Inline`, etc.).  Certain transformations will be easier because we can use
+``isinstance(node, base_class)`` to determine the position of the node in the
+hierarchy.
+
+.. _DTD: http://docutils.sourceforge.net/spec/docutils.dtd
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+import os
+import re
+import xml.dom.minidom
+from types import IntType, SliceType, StringType, UnicodeType, \
+     TupleType, ListType
+from UserString import UserString
+
+
+# ==============================
+#  Functional Node Base Classes
+# ==============================
+
+class Node:
+
+    """Abstract base class of nodes in a document tree."""
+
+    parent = None
+    """Back-reference to the Node immediately containing this Node."""
+
+    document = None
+    """The `document` node at the root of the tree containing this Node."""

[-=- -=- -=- 1330 lines omitted -=- -=- -=-]

+    """
+
+    pass
+
+
+def make_id(string):
+    """
+    Convert `string` into an identifier and return it.
+
+    Docutils identifiers will conform to the regular expression
+    ``[a-z][-a-z0-9]*``. For CSS compatibility, identifiers (the "class" and
+    "id" attributes) should have no underscores, colons, or periods. Hyphens
+    may be used.
+
+    - The `HTML 4.01 spec`_ defines identifiers based on SGML tokens:
+
+          ID and NAME tokens must begin with a letter ([A-Za-z]) and may be
+          followed by any number of letters, digits ([0-9]), hyphens ("-"),
+          underscores ("_"), colons (":"), and periods (".").
+
+    - However the `CSS1 spec`_ defines identifiers based on the "name" token,
+      a tighter interpretation ("flex" tokenizer notation; "latin1" and
+      "escape" 8-bit characters have been replaced with entities)::
+
+          unicode     \\[0-9a-f]{1,4}
+          latin1      [&iexcl;-&yuml;]
+          escape      {unicode}|\\[ -~&iexcl;-&yuml;]
+          nmchar      [-a-z0-9]|{latin1}|{escape}
+          name        {nmchar}+
+
+    The CSS1 "nmchar" rule does not include underscores ("_"), colons (":"),
+    or periods ("."), therefore "class" and "id" attributes should not contain
+    these characters. They should be replaced with hyphens ("-"). Combined
+    with HTML's requirements (the first character must be a letter; no
+    "unicode", "latin1", or "escape" characters), this results in the
+    ``[a-z][-a-z0-9]*`` pattern.
+
+    .. _HTML 4.01 spec: http://www.w3.org/TR/html401
+    .. _CSS1 spec: http://www.w3.org/TR/REC-CSS1
+    """
+    id = _non_id_chars.sub('-', ' '.join(string.lower().split()))
+    id = _non_id_at_ends.sub('', id)
+    return str(id)
+
+_non_id_chars = re.compile('[^a-z0-9]+')
+_non_id_at_ends = re.compile('^[-0-9]+|-+$')
+
+def dupname(node):
+    node['dupname'] = node['name']
+    del node['name']


=== Zope/lib/python/docutils/optik.py 1.1 => 1.2 === (1257/1357 lines abridged)
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/optik.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,1354 @@
+# This is *not* the official distribution of Optik.  See
+# http://optik.sourceforge.net/ for the official distro.
+#
+# This combined module was converted from the "optik" package for Docutils use
+# by David Goodger (2002-06-12).  Optik is slated for inclusion in the Python
+# standard library as OptionParser.py.  Once Optik itself becomes a single
+# module, Docutils will include the official module and kill off this
+# temporary fork.
+
+"""optik
+
+A powerful, extensible, and easy-to-use command-line parser for Python.
+
+By Greg Ward <gward@python.net>
+
+See http://optik.sourceforge.net/
+"""
+
+# Copyright (c) 2001 Gregory P. Ward.  All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#   * Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer.
+#
+#   * Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution.
+#
+#   * Neither the name of the author nor the names of its
+#     contributors may be used to endorse or promote products derived from
+#     this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+

[-=- -=- -=- 1257 lines omitted -=- -=- -=-]

+
+    def format_usage(self, usage):
+        return "Usage: %s\n" % usage
+
+    def format_heading(self, heading):
+        return "%*s%s:\n" % (self.current_indent, "", heading)
+
+
+class Titled(HelpFormat):
+
+    """Formats help with underlined section headers."""
+
+    def __init__(self, indent_increment=0, max_help_position=24, width=78,
+                 short_first=None):
+        HelpFormat.__init__(self, indent_increment, max_help_position, width,
+                            short_first)
+
+    def format_usage(self, usage):
+        return "%s  %s\n" % (self.format_heading("Usage"), usage)
+
+    def format_heading(self, heading):
+        return "%s\n%s\n" % (heading, "=-"[self.level] * len(heading))
+
+
+def _match_abbrev (s, wordmap):
+    """_match_abbrev(s : string, wordmap : {string : Option}) -> string
+
+    Return the string key in 'wordmap' for which 's' is an unambiguous
+    abbreviation.  If 's' is found to be ambiguous or doesn't match any of
+    'words', raise BadOptionError.
+    """
+    # Is there an exact match?
+    if wordmap.has_key(s):
+        return s
+    else:
+        # Isolate all words with s as a prefix.
+        possibilities = [word for word in wordmap.keys()
+                         if word.startswith(s)]
+        # No exact match, so there had better be just one possibility.
+        if len(possibilities) == 1:
+            return possibilities[0]
+        elif not possibilities:
+            raise BadOptionError("no such option: %s" % s)
+        else:
+            # More than one possible completion: ambiguous prefix.
+            raise BadOptionError("ambiguous option: %s (%s?)"
+                                 % (s, ", ".join(possibilities)))
+
+def get_prog_name ():
+    return os.path.basename(sys.argv[0])


=== Zope/lib/python/docutils/roman.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/roman.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,81 @@
+"""Convert to and from Roman numerals"""
+
+__author__ = "Mark Pilgrim (f8dy@diveintopython.org)"
+__version__ = "1.4"
+__date__ = "8 August 2001"
+__copyright__ = """Copyright (c) 2001 Mark Pilgrim
+
+This program is part of "Dive Into Python", a free Python tutorial for
+experienced programmers.  Visit http://diveintopython.org/ for the
+latest version.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the Python 2.1.1 license, available at
+http://www.python.org/2.1.1/license.html
+"""
+
+import re
+
+#Define exceptions
+class RomanError(Exception): pass
+class OutOfRangeError(RomanError): pass
+class NotIntegerError(RomanError): pass
+class InvalidRomanNumeralError(RomanError): pass
+
+#Define digit mapping
+romanNumeralMap = (('M',  1000),
+                   ('CM', 900),
+                   ('D',  500),
+                   ('CD', 400),
+                   ('C',  100),
+                   ('XC', 90),
+                   ('L',  50),
+                   ('XL', 40),
+                   ('X',  10),
+                   ('IX', 9),
+                   ('V',  5),
+                   ('IV', 4),
+                   ('I',  1))
+
+def toRoman(n):
+    """convert integer to Roman numeral"""
+    if not (0 < n < 5000):
+        raise OutOfRangeError, "number out of range (must be 1..4999)"
+    if int(n) <> n:
+        raise NotIntegerError, "decimals can not be converted"
+
+    result = ""
+    for numeral, integer in romanNumeralMap:
+        while n >= integer:
+            result += numeral
+            n -= integer
+    return result
+
+#Define pattern to detect valid Roman numerals
+romanNumeralPattern = re.compile('''
+    ^                   # beginning of string
+    M{0,4}              # thousands - 0 to 4 M's
+    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
+                        #            or 500-800 (D, followed by 0 to 3 C's)
+    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
+                        #        or 50-80 (L, followed by 0 to 3 X's)
+    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
+                        #        or 5-8 (V, followed by 0 to 3 I's)
+    $                   # end of string
+    ''' ,re.VERBOSE)
+
+def fromRoman(s):
+    """convert Roman numeral to integer"""
+    if not s:
+        raise InvalidRomanNumeralError, 'Input can not be blank'
+    if not romanNumeralPattern.search(s):
+        raise InvalidRomanNumeralError, 'Invalid Roman numeral: %s' % s
+
+    result = 0
+    index = 0
+    for numeral, integer in romanNumeralMap:
+        while s[index:index+len(numeral)] == numeral:
+            result += integer
+            index += len(numeral)
+    return result
+


=== Zope/lib/python/docutils/statemachine.py 1.1 => 1.2 === (1353/1453 lines abridged)
--- /dev/null	Sat Feb  1 04:26:34 2003
+++ Zope/lib/python/docutils/statemachine.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,1450 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+A finite state machine specialized for regular-expression-based text filters,
+this module defines the following classes:
+
+- `StateMachine`, a state machine
+- `State`, a state superclass
+- `StateMachineWS`, a whitespace-sensitive version of `StateMachine`
+- `StateWS`, a state superclass for use with `StateMachineWS`
+- `SearchStateMachine`, uses `re.search()` instead of `re.match()`
+- `SearchStateMachineWS`, uses `re.search()` instead of `re.match()`
+- `ViewList`, extends standard Python lists.
+- `StringList`, string-specific ViewList.
+
+Exception classes:
+
+- `StateMachineError`
+- `UnknownStateError`
+- `DuplicateStateError`
+- `UnknownTransitionError`
+- `DuplicateTransitionError`
+- `TransitionPatternNotFound`
+- `TransitionMethodNotFound`
+- `UnexpectedIndentationError`
+- `TransitionCorrection`: Raised to switch to another transition.
+- `StateCorrection`: Raised to switch to another state & transition.
+
+Functions:
+
+- `string2lines()`: split a multi-line string into a list of one-line strings
+
+
+How To Use This Module
+======================
+(See the individual classes, methods, and attributes for details.)
+
+1. Import it: ``import statemachine`` or ``from statemachine import ...``.
+   You will also need to ``import re``.
+
+2. Derive a subclass of `State` (or `StateWS`) for each state in your state
+   machine::
+

[-=- -=- -=- 1353 lines omitted -=- -=- -=-]

+    Raise from within a transition method to switch to another transition.
+
+    Raise with one argument, the new transition name.
+    """
+
+
+class StateCorrection(Exception):
+
+    """
+    Raise from within a transition method to switch to another state.
+
+    Raise with one or two arguments: new state name, and an optional new
+    transition name.
+    """
+
+
+def string2lines(astring, tab_width=8, convert_whitespace=0,
+                 whitespace=re.compile('[\v\f]')):
+    """
+    Return a list of one-line strings with tabs expanded and no newlines.
+
+    Each tab is expanded with between 1 and `tab_width` spaces, so that the
+    next character's index becomes a multiple of `tab_width` (8 by default).
+
+    Parameters:
+
+    - `astring`: a multi-line string.
+    - `tab_width`: the number of columns between tab stops.
+    - `convert_whitespace`: convert form feeds and vertical tabs to spaces?
+    """
+    if convert_whitespace:
+        astring = whitespace.sub(' ', astring)
+    return [s.expandtabs(tab_width) for s in astring.splitlines()]
+
+def _exception_data():
+    """
+    Return exception information:
+
+    - the exception's class name;
+    - the exception object;
+    - the name of the file containing the offending code;
+    - the line number of the offending code;
+    - the function name of the offending code.
+    """
+    type, value, traceback = sys.exc_info()
+    while traceback.tb_next:
+        traceback = traceback.tb_next
+    code = traceback.tb_frame.f_code
+    return (type.__name__, value, code.co_filename, traceback.tb_lineno,
+            code.co_name)


=== Zope/lib/python/docutils/urischemes.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:35 2003
+++ Zope/lib/python/docutils/urischemes.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,105 @@
+"""
+`schemes` is a dictionary with lowercase URI addressing schemes as
+keys and descriptions as values. It was compiled from the index at
+http://www.w3.org/Addressing/schemes.html (revised 2001-08-20).
+"""
+
+# Many values are blank and should be filled in with useful descriptions.
+
+schemes = {
+      'about': 'provides information on Navigator',
+      'acap': 'Application Configuration Access Protocol',
+      'addbook': "To add vCard entries to Communicator's Address Book",
+      'afp': 'Apple Filing Protocol',
+      'afs': 'Andrew File System global file names',
+      'aim': 'AOL Instant Messenger',
+      'callto': 'for NetMeeting links',
+      'castanet': 'Castanet Tuner URLs for Netcaster',
+      'chttp': 'cached HTTP supported by RealPlayer',
+      'cid': 'content identifier',
+      'data': ('allows inclusion of small data items as "immediate" data; '
+               'RFC 2397'),
+      'dav': 'Distributed Authoring and Versioning Protocol; RFC 2518',
+      'dns': 'Domain Name System resources',
+      'eid': ('External ID; non-URL data; general escape mechanism to allow '
+              'access to information for applications that are too '
+              'specialized to justify their own schemes'),
+      'fax': ('a connection to a terminal that can handle telefaxes '
+              '(facsimiles); RFC 2806'),
+      'file': 'Host-specific file names',
+      'finger': '',
+      'freenet': '',
+      'ftp': 'File Transfer Protocol',
+      'gopher': 'The Gopher Protocol',
+      'gsm-sms': ('Global System for Mobile Communications Short Message '
+                  'Service'),
+      'h323': 'video (audiovisual) communication on local area networks',
+      'h324': ('video and audio communications over low bitrate connections '
+               'such as POTS modem connections'),
+      'hdl': 'CNRI handle system',
+      'hnews': 'an HTTP-tunneling variant of the NNTP news protocol',
+      'http': 'Hypertext Transfer Protocol',
+      'https': 'HTTP over SSL',
+      'iioploc': 'Internet Inter-ORB Protocol Location?',
+      'ilu': 'Inter-Language Unification',
+      'imap': 'Internet Message Access Protocol',
+      'ior': 'CORBA interoperable object reference',
+      'ipp': 'Internet Printing Protocol',
+      'irc': 'Internet Relay Chat',
+      'jar': 'Java archive',
+      'javascript': ('JavaScript code; evaluates the expression after the '
+                     'colon'),
+      'jdbc': '',
+      'ldap': 'Lightweight Directory Access Protocol',
+      'lifn': '',
+      'livescript': '',
+      'lrq': '',
+      'mailbox': 'Mail folder access',
+      'mailserver': 'Access to data available from mail servers',
+      'mailto': 'Electronic mail address',
+      'md5': '',
+      'mid': 'message identifier',
+      'mocha': '',
+      'modem': ('a connection to a terminal that can handle incoming data '
+                'calls; RFC 2806'),
+      'news': 'USENET news',
+      'nfs': 'Network File System protocol',
+      'nntp': 'USENET news using NNTP access',
+      'opaquelocktoken': '',
+      'phone': '',
+      'pop': 'Post Office Protocol',
+      'pop3': 'Post Office Protocol v3',
+      'printer': '',
+      'prospero': 'Prospero Directory Service',
+      'res': '',
+      'rtsp': 'real time streaming protocol',
+      'rvp': '',
+      'rwhois': '',
+      'rx': 'Remote Execution',
+      'sdp': '',
+      'service': 'service location',
+      'shttp': 'secure hypertext transfer protocol',
+      'sip': 'Session Initiation Protocol',
+      'smb': '',
+      'snews': 'For NNTP postings via SSL',
+      't120': 'real time data conferencing (audiographics)',
+      'tcp': '',
+      'tel': ('a connection to a terminal that handles normal voice '
+              'telephone calls, a voice mailbox or another voice messaging '
+              'system or a service that can be operated using DTMF tones; '
+              'RFC 2806.'),
+      'telephone': 'telephone',
+      'telnet': 'Reference to interactive sessions',
+      'tip': 'Transaction Internet Protocol',
+      'tn3270': 'Interactive 3270 emulation sessions',
+      'tv': '',
+      'urn': 'Uniform Resource Name',
+      'uuid': '',
+      'vemmi': 'versatile multimedia interface',
+      'videotex': '',
+      'view-source': 'displays HTML code that was generated with JavaScript',
+      'wais': 'Wide Area Information Servers',
+      'whodp': '',
+      'whois++': 'Distributed directory service.',
+      'z39.50r': 'Z39.50 Retrieval',
+      'z39.50s': 'Z39.50 Session',}


=== Zope/lib/python/docutils/utils.py 1.1 => 1.2 ===
--- /dev/null	Sat Feb  1 04:26:35 2003
+++ Zope/lib/python/docutils/utils.py	Sat Feb  1 04:26:00 2003
@@ -0,0 +1,435 @@
+# Author: David Goodger
+# Contact: goodger@users.sourceforge.net
+# Revision: $Revision$
+# Date: $Date$
+# Copyright: This module has been placed in the public domain.
+
+"""
+Miscellaneous utilities for the documentation utilities.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+import os
+import os.path
+from types import StringType, UnicodeType
+from docutils import ApplicationError, DataError
+from docutils import frontend, nodes
+
+
+class SystemMessage(ApplicationError):
+
+    def __init__(self, system_message):
+        Exception.__init__(self, system_message.astext())
+
+
+class Reporter:
+
+    """
+    Info/warning/error reporter and ``system_message`` element generator.
+
+    Five levels of system messages are defined, along with corresponding
+    methods: `debug()`, `info()`, `warning()`, `error()`, and `severe()`.
+
+    There is typically one Reporter object per process.  A Reporter object is
+    instantiated with thresholds for reporting (generating warnings) and
+    halting processing (raising exceptions), a switch to turn debug output on
+    or off, and an I/O stream for warnings.  These are stored in the default
+    reporting category, '' (zero-length string).
+
+    Multiple reporting categories [#]_ may be set, each with its own reporting
+    and halting thresholds, debugging switch, and warning stream
+    (collectively a `ConditionSet`).  Categories are hierarchical dotted-name
+    strings that look like attribute references: 'spam', 'spam.eggs',
+    'neeeow.wum.ping'.  The 'spam' category is the ancestor of
+    'spam.bacon.eggs'.  Unset categories inherit stored conditions from their
+    closest ancestor category that has been set.
+
+    When a system message is generated, the stored conditions from its
+    category (or ancestor if unset) are retrieved.  The system message level
+    is compared to the thresholds stored in the category, and a warning or
+    error is generated as appropriate.  Debug messages are produced iff the
+    stored debug switch is on.  Message output is sent to the stored warning
+    stream.
+
+    The default category is '' (empty string).  By convention, Writers should
+    retrieve reporting conditions from the 'writer' category (which, unless
+    explicitly set, defaults to the conditions of the default category).
+
+    The Reporter class also employs a modified form of the "Observer" pattern
+    [GoF95]_ to track system messages generated.  The `attach_observer` method
+    should be called before parsing, with a bound method or function which
+    accepts system messages.  The observer can be removed with
+    `detach_observer`, and another added in its place.
+
+    .. [#] The concept of "categories" was inspired by the log4j project:
+       http://jakarta.apache.org/log4j/.
+
+    .. [GoF95] Gamma, Helm, Johnson, Vlissides. *Design Patterns: Elements of
+       Reusable Object-Oriented Software*. Addison-Wesley, Reading, MA, USA,
+       1995.
+    """
+
+    levels = 'DEBUG INFO WARNING ERROR SEVERE'.split()
+    """List of names for system message levels, indexed by level."""
+
+    def __init__(self, source, report_level, halt_level, stream=None,
+                 debug=0):
+        """
+        Initialize the `ConditionSet` forthe `Reporter`'s default category.
+
+        :Parameters:
+
+            - `source`: The path to or description of the source data.
+            - `report_level`: The level at or above which warning output will
+              be sent to `stream`.
+            - `halt_level`: The level at or above which `SystemMessage`
+              exceptions will be raised, halting execution.
+            - `debug`: Show debug (level=0) system messages?
+            - `stream`: Where warning output is sent.  Can be file-like (has a
+              ``.write`` method), a string (file name, opened for writing), or
+              `None` (implies `sys.stderr`; default).
+        """
+        self.source = source
+        """The path to or description of the source data."""
+        
+        if stream is None:
+            stream = sys.stderr
+        elif type(stream) in (StringType, UnicodeType):
+            raise NotImplementedError('This should open a file for writing.')
+
+        self.categories = {'': ConditionSet(debug, report_level, halt_level,
+                                            stream)}
+        """Mapping of category names to conditions. Default category is ''."""
+
+        self.observers = []
+        """List of bound methods or functions to call with each system_message
+        created."""
+
+    def set_conditions(self, category, report_level, halt_level,
+                       stream=None, debug=0):
+        if stream is None:
+            stream = sys.stderr
+        self.categories[category] = ConditionSet(debug, report_level,
+                                                 halt_level, stream)
+
+    def unset_conditions(self, category):
+        if category and self.categories.has_key(category):
+            del self.categories[category]
+
+    __delitem__ = unset_conditions
+
+    def get_conditions(self, category):
+        while not self.categories.has_key(category):
+            category = category[:category.rfind('.') + 1][:-1]
+        return self.categories[category]
+
+    __getitem__ = get_conditions
+
+    def attach_observer(self, observer):
+        """
+        The `observer` parameter is a function or bound method which takes one
+        argument, a `nodes.system_message` instance.
+        """
+        self.observers.append(observer)
+
+    def detach_observer(self, observer):
+        self.observers.remove(observer)
+
+    def notify_observers(self, message):
+        for observer in self.observers:
+            observer(message)
+
+    def system_message(self, level, message, *children, **kwargs):
+        """
+        Return a system_message object.
+
+        Raise an exception or generate a warning if appropriate.
+        """
+        attributes = kwargs.copy()
+        category = kwargs.get('category', '')
+        if kwargs.has_key('category'):
+            del attributes['category']
+        if kwargs.has_key('base_node'):
+            source, line = get_source_line(kwargs['base_node'])
+            del attributes['base_node']
+            if source is not None:
+                attributes.setdefault('source', source)
+            if line is not None:
+                attributes.setdefault('line', line)
+        attributes.setdefault('source', self.source)
+        msg = nodes.system_message(message, level=level,
+                                   type=self.levels[level],
+                                   *children, **attributes)
+        debug, report_level, halt_level, stream = self[category].astuple()
+        if level >= report_level or debug and level == 0:
+            if category:
+                print >>stream, msg.astext(), '[%s]' % category
+            else:
+                print >>stream, msg.astext()
+        if level >= halt_level:
+            raise SystemMessage(msg)
+        if level > 0 or debug:
+            self.notify_observers(msg)
+        return msg
+
+    def debug(self, *args, **kwargs):
+        """
+        Level-0, "DEBUG": an internal reporting issue. Typically, there is no
+        effect on the processing. Level-0 system messages are handled
+        separately from the others.
+        """
+        return self.system_message(0, *args, **kwargs)
+
+    def info(self, *args, **kwargs):
+        """
+        Level-1, "INFO": a minor issue that can be ignored. Typically there is
+        no effect on processing, and level-1 system messages are not reported.
+        """
+        return self.system_message(1, *args, **kwargs)
+
+    def warning(self, *args, **kwargs):
+        """
+        Level-2, "WARNING": an issue that should be addressed. If ignored,
+        there may be unpredictable problems with the output.
+        """
+        return self.system_message(2, *args, **kwargs)
+
+    def error(self, *args, **kwargs):
+        """
+        Level-3, "ERROR": an error that should be addressed. If ignored, the
+        output will contain errors.
+        """
+        return self.system_message(3, *args, **kwargs)
+
+    def severe(self, *args, **kwargs):
+        """
+        Level-4, "SEVERE": a severe error that must be addressed. If ignored,
+        the output will contain severe errors. Typically level-4 system
+        messages are turned into exceptions which halt processing.
+        """
+        return self.system_message(4, *args, **kwargs)
+
+
+class ConditionSet:
+
+    """
+    A set of two thresholds (`report_level` & `halt_level`), a switch
+    (`debug`), and an I/O stream (`stream`), corresponding to one `Reporter`
+    category.
+    """
+
+    def __init__(self, debug, report_level, halt_level, stream):
+        self.debug = debug
+        self.report_level = report_level
+        self.halt_level = halt_level
+        self.stream = stream
+
+    def astuple(self):
+        return (self.debug, self.report_level, self.halt_level,
+                self.stream)
+
+
+class ExtensionOptionError(DataError): pass
+class BadOptionError(ExtensionOptionError): pass
+class BadOptionDataError(ExtensionOptionError): pass
+class DuplicateOptionError(ExtensionOptionError): pass
+
+
+def extract_extension_options(field_list, options_spec):
+    """
+    Return a dictionary mapping extension option names to converted values.
+
+    :Parameters:
+        - `field_list`: A flat field list without field arguments, where each
+          field body consists of a single paragraph only.
+        - `options_spec`: Dictionary mapping known option names to a
+          conversion function such as `int` or `float`.
+
+    :Exceptions:
+        - `KeyError` for unknown option names.
+        - `ValueError` for invalid option values (raised by the conversion
+           function).
+        - `DuplicateOptionError` for duplicate options.
+        - `BadOptionError` for invalid fields.
+        - `BadOptionDataError` for invalid option data (missing name,
+          missing data, bad quotes, etc.).
+    """
+    option_list = extract_options(field_list)
+    option_dict = assemble_option_dict(option_list, options_spec)
+    return option_dict
+
+def extract_options(field_list):
+    """
+    Return a list of option (name, value) pairs from field names & bodies.
+
+    :Parameter:
+        `field_list`: A flat field list, where each field name is a single
+        word and each field body consists of a single paragraph only.
+
+    :Exceptions:
+        - `BadOptionError` for invalid fields.
+        - `BadOptionDataError` for invalid option data (missing name,
+          missing data, bad quotes, etc.).
+    """
+    option_list = []
+    for field in field_list:
+        if len(field[0].astext().split()) != 1:
+            raise BadOptionError(
+                'extension option field name may not contain multiple words')
+        name = str(field[0].astext().lower())
+        body = field[1]
+        if len(body) == 0:
+            data = None
+        elif len(body) > 1 or not isinstance(body[0], nodes.paragraph) \
+              or len(body[0]) != 1 or not isinstance(body[0][0], nodes.Text):
+            raise BadOptionDataError(
+                  'extension option field body may contain\n'
+                  'a single paragraph only (option "%s")' % name)
+        else:
+            data = body[0][0].astext()
+        option_list.append((name, data))
+    return option_list
+
+def assemble_option_dict(option_list, options_spec):
+    """
+    Return a mapping of option names to values.
+
+    :Parameters:
+        - `option_list`: A list of (name, value) pairs (the output of
+          `extract_options()`).
+        - `options_spec`: Dictionary mapping known option names to a
+          conversion function such as `int` or `float`.
+
+    :Exceptions:
+        - `KeyError` for unknown option names.
+        - `DuplicateOptionError` for duplicate options.
+        - `ValueError` for invalid option values (raised by conversion
+           function).
+    """
+    options = {}
+    for name, value in option_list:
+        convertor = options_spec[name]       # raises KeyError if unknown
+        if options.has_key(name):
+            raise DuplicateOptionError('duplicate option "%s"' % name)
+        try:
+            options[name] = convertor(value)
+        except (ValueError, TypeError), detail:
+            raise detail.__class__('(option: "%s"; value: %r)\n%s'
+                                   % (name, value, detail))
+    return options
+
+
+class NameValueError(DataError): pass
+
+
+def extract_name_value(line):
+    """
+    Return a list of (name, value) from a line of the form "name=value ...".
+
+    :Exception:
+        `NameValueError` for invalid input (missing name, missing data, bad
+        quotes, etc.).
+    """
+    attlist = []
+    while line:
+        equals = line.find('=')
+        if equals == -1:
+            raise NameValueError('missing "="')
+        attname = line[:equals].strip()
+        if equals == 0 or not attname:
+            raise NameValueError(
+                  'missing attribute name before "="')
+        line = line[equals+1:].lstrip()
+        if not line:
+            raise NameValueError(
+                  'missing value after "%s="' % attname)
+        if line[0] in '\'"':
+            endquote = line.find(line[0], 1)
+            if endquote == -1:
+                raise NameValueError(
+                      'attribute "%s" missing end quote (%s)'
+                      % (attname, line[0]))
+            if len(line) > endquote + 1 and line[endquote + 1].strip():
+                raise NameValueError(
+                      'attribute "%s" end quote (%s) not followed by '
+                      'whitespace' % (attname, line[0]))
+            data = line[1:endquote]
+            line = line[endquote+1:].lstrip()
+        else:
+            space = line.find(' ')
+            if space == -1:
+                data = line
+                line = ''
+            else:
+                data = line[:space]
+                line = line[space+1:].lstrip()
+        attlist.append((attname.lower(), data))
+    return attlist
+
+def normalize_name(name):
+    """Return a case- and whitespace-normalized name."""
+    return ' '.join(name.lower().split())
+
+def new_document(source, settings=None):
+    """
+    Return a new empty document object.
+
+    :Parameters:
+        `source` : string
+            The path to or description of the source text of the document.
+        `settings` : optparse.Values object
+            Runtime settings.  If none provided, a default set will be used.
+    """
+    if settings is None:
+        settings = frontend.OptionParser().get_default_values()
+    reporter = Reporter(source, settings.report_level, settings.halt_level,
+                        settings.warning_stream, settings.debug)
+    document = nodes.document(settings, reporter, source=source)
+    document.note_source(source, -1)
+    return document
+
+def clean_rcs_keywords(paragraph, keyword_substitutions):
+    if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text):
+        textnode = paragraph[0]
+        for pattern, substitution in keyword_substitutions:
+            match = pattern.match(textnode.data)
+            if match:
+                textnode.data = pattern.sub(substitution, textnode.data)
+                return
+
+def relative_path(source, target):
+    """
+    Build and return a path to `target`, relative to `source`.
+
+    If there is no common prefix, return the absolute path to `target`.
+    """
+    source_parts = os.path.abspath(source or 'dummy_file').split(os.sep)
+    target_parts = os.path.abspath(target).split(os.sep)
+    # Check first 2 parts because '/dir'.split('/') == ['', 'dir']:
+    if source_parts[:2] != target_parts[:2]:
+        # Nothing in common between paths.
+        # Return absolute path, using '/' for URLs:
+        return '/'.join(target_parts)
+    source_parts.reverse()
+    target_parts.reverse()
+    while (source_parts and target_parts
+           and source_parts[-1] == target_parts[-1]):
+        # Remove path components in common:
+        source_parts.pop()
+        target_parts.pop()
+    target_parts.reverse()
+    parts = ['..'] * (len(source_parts) - 1) + target_parts
+    return '/'.join(parts)
+
+def get_source_line(node):
+    """
+    Return the "source" and "line" attributes from the `node` given or from
+    it's closest ancestor.
+    """
+    while node:
+        if node.source or node.line:
+            return node.source, node.line
+        node = node.parent
+    return None, None