[Zope-Checkins] CVS: Zope/lib/python/third_party/docutils/tools - buildhtml.py:1.1.2.1 docutils.conf:1.1.2.1 pep-html-template:1.1.2.1 pep.py:1.1.2.1 quicktest.py:1.1.2.1 rst2html.py:1.1.2.1 rst2latex.py:1.1.2.1 rst2pseudoxml.py:1.1.2.1 rst2xml.py:1.1.2.1 unicode2rstsubs.py:1.1.2.1

Andreas Jung andreas at andreas-jung.com
Fri Oct 29 14:24:56 EDT 2004


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

Added Files:
      Tag: ajung-docutils-cleanup-branch
	buildhtml.py docutils.conf pep-html-template pep.py 
	quicktest.py rst2html.py rst2latex.py rst2pseudoxml.py 
	rst2xml.py unicode2rstsubs.py 
Log Message:
moved


=== Added File Zope/lib/python/third_party/docutils/tools/buildhtml.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
Generates .html from all the .txt files in a directory.

Ordinary .txt files are understood to be standalone reStructuredText.
Files named ``pep-*.txt`` are interpreted as reStructuredText PEPs.
"""
# Once PySource is here, build .html from .py as well.

__docformat__ = 'reStructuredText'


try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

import sys
import os
import os.path
import copy
import docutils
from docutils import ApplicationError
from docutils import core, frontend
from docutils.parsers import rst
from docutils.readers import standalone, pep
from docutils.writers import html4css1, pep_html


usage = '%prog [options] [<directory> ...]'
description = ('Generates .html from all the reStructuredText .txt files '
               '(including PEPs) in each <directory> '
               '(default is the current directory).')


class SettingsSpec(docutils.SettingsSpec):

    """
    Runtime settings & command-line options for the front end.
    """

    # Can't be included in OptionParser below because we don't want to
    # override the base class.
    settings_spec = (
        'Build-HTML Options',
        None,
        (('Recursively scan subdirectories for files to process.  This is '
          'the default.',
          ['--recurse'],
          {'action': 'store_true', 'default': 1,
           'validator': frontend.validate_boolean}),
         ('Do not scan subdirectories for files to process.',
          ['--local'], {'dest': 'recurse', 'action': 'store_false'}),
         ('Do not process files in <directory>.  This option may be used '
          'more than once to specify multiple directories.',
          ['--prune'],
          {'metavar': '<directory>', 'action': 'append',
           'validator': frontend.validate_colon_separated_string_list}),
         ('Work silently (no progress messages).  Independent of "--quiet".',
          ['--silent'],
          {'action': 'store_true', 'validator': frontend.validate_boolean}),))

    relative_path_settings = ('prune',)
    config_section = 'buildhtml application'
    config_section_dependencies = ('applications',)


class OptionParser(frontend.OptionParser):

    """
    Command-line option processing for the ``buildhtml.py`` front end.
    """

    def check_values(self, values, args):
        frontend.OptionParser.check_values(self, values, args)
        values._source = None
        return values

    def check_args(self, args):
        source = destination = None
        if args:
            self.values._directories = args
        else:
            self.values._directories = [os.getcwd()]
        return source, destination


class Struct:

    """Stores data attributes for dotted-attribute access."""

    def __init__(self, **keywordargs):
        self.__dict__.update(keywordargs)


class Builder:

    def __init__(self):
        self.publishers = {
            '': Struct(components=(pep.Reader, rst.Parser, pep_html.Writer,
                                   SettingsSpec)),
            '.txt': Struct(components=(rst.Parser, standalone.Reader,
                                       html4css1.Writer, SettingsSpec),
                           reader_name='standalone',
                           writer_name='html'),
            'PEPs': Struct(components=(rst.Parser, pep.Reader,
                                       pep_html.Writer, SettingsSpec),
                           reader_name='pep',
                           writer_name='pep_html')}
        """Publisher-specific settings.  Key '' is for the front-end script
        itself.  ``self.publishers[''].components`` must contain a superset of
        all components used by individual publishers."""

        self.setup_publishers()

    def setup_publishers(self):
        """
        Manage configurations for individual publishers.

        Each publisher (combination of parser, reader, and writer) may have
        its own configuration defaults, which must be kept separate from those
        of the other publishers.  Setting defaults are combined with the
        config file settings and command-line options by
        `self.get_settings()`.
        """
        for name, publisher in self.publishers.items():
            option_parser = OptionParser(
                components=publisher.components, read_config_files=1,
                usage=usage, description=description)
            publisher.option_parser = option_parser
            publisher.setting_defaults = option_parser.get_default_values()
            frontend.make_paths_absolute(publisher.setting_defaults.__dict__,
                                         option_parser.relative_path_settings)
            publisher.config_settings = (
                option_parser.get_standard_config_settings())
        self.settings_spec = self.publishers[''].option_parser.parse_args(
            values=frontend.Values())   # no defaults; just the cmdline opts
        self.initial_settings = self.get_settings('')

    def get_settings(self, publisher_name, directory=None):
        """
        Return a settings object, from multiple sources.

        Copy the setting defaults, overlay the startup config file settings,
        then the local config file settings, then the command-line options.
        Assumes the current directory has been set.
        """
        publisher = self.publishers[publisher_name]
        settings = frontend.Values(publisher.setting_defaults.__dict__)
        settings.update(publisher.config_settings, publisher.option_parser)
        if directory:
            local_config = publisher.option_parser.get_config_file_settings(
                os.path.join(directory, 'docutils.conf'))
            frontend.make_paths_absolute(
                local_config, publisher.option_parser.relative_path_settings,
                directory)
            settings.update(local_config, publisher.option_parser)
        settings.update(self.settings_spec.__dict__, publisher.option_parser)
        return settings

    def run(self, directory=None, recurse=1):
        recurse = recurse and self.initial_settings.recurse
        if directory:
            self.directories = [directory]
        elif self.settings_spec._directories:
            self.directories = self.settings_spec._directories
        else:
            self.directories = [os.getcwd()]
        for directory in self.directories:
            os.path.walk(directory, self.visit, recurse)

    def visit(self, recurse, directory, names):
        settings = self.get_settings('', directory)
        if settings.prune and (os.path.abspath(directory) in settings.prune):
            print >>sys.stderr, '/// ...Skipping directory (pruned):', directory
            sys.stderr.flush()
            names[:] = []
            return
        if not self.initial_settings.silent:
            print >>sys.stderr, '/// Processing directory:', directory
            sys.stderr.flush()
        prune = 0
        for name in names:
            if name.endswith('.txt'):
                prune = self.process_txt(directory, name)
                if prune:
                    break
        if not recurse:
            del names[:]

    def process_txt(self, directory, name):
        if name.startswith('pep-'):
            publisher = 'PEPs'
        else:
            publisher = '.txt'
        settings = self.get_settings(publisher, directory)
        pub_struct = self.publishers[publisher]
        if settings.prune and (directory in settings.prune):
            return 1
        settings._source = os.path.normpath(os.path.join(directory, name))
        settings._destination = settings._source[:-4]+'.html'
        if not self.initial_settings.silent:
            print >>sys.stderr, '    ::: Processing:', name
            sys.stderr.flush()
        try:
            core.publish_file(source_path=settings._source,
                              destination_path=settings._destination,
                              reader_name=pub_struct.reader_name,
                              parser_name='restructuredtext',
                              writer_name=pub_struct.writer_name,
                              settings=settings)
        except ApplicationError, error:
            print >>sys.stderr, ('        Error (%s): %s'
                                 % (error.__class__.__name__, error))


if __name__ == "__main__":
    Builder().run()


=== Added File Zope/lib/python/third_party/docutils/tools/docutils.conf ===
[general]
# These entries affect all processing:
source-link: yes
datestamp: %Y-%m-%d %H:%M UTC
generator: on

[html4css1 writer]
# These entries affect HTML output:
stylesheet-path: stylesheets/default.css
footnote-references: brackets

[pep_html writer]
# These entries affect reStructuredText-style PEPs:
template: pep-html-template
stylesheet-path: stylesheets/pep.css
python-home: http://www.python.org
no-random: true


=== Added File Zope/lib/python/third_party/docutils/tools/pep-html-template ===
<?xml version="1.0" encoding="%(encoding)s" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<!--
This HTML is auto-generated.  DO NOT EDIT THIS FILE!  If you are writing a new
PEP, see http://www.python.org/peps/pep-0001.html for instructions and links
to templates.  DO NOT USE THIS HTML FILE AS YOUR TEMPLATE!
-->
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=%(encoding)s" />
  <meta name="generator" content="Docutils %(version)s: http://docutils.sourceforge.net/" />
  <title>PEP %(pep)s -- %(title)s</title>
  %(stylesheet)s</head>
<body bgcolor="white">
<table class="navigation" cellpadding="0" cellspacing="0"
       width="100%%" border="0">
<tr><td class="navicon" width="150" height="35">
<a href="%(pyhome)s/" title="Python Home Page">
<img src="%(pyhome)s/pics/PyBanner%(banner)03d.gif" alt="[Python]"
 border="0" width="150" height="35" /></a></td>
<td class="textlinks" align="left">
[<b><a href="%(pyhome)s/">Python Home</a></b>]
[<b><a href="%(pepindex)s">PEP Index</a></b>]
[<b><a href="%(pephome)s/pep-%(pepnum)s.txt">PEP Source</a></b>]
</td></tr></table>
%(body)s
%(body_suffix)s


=== Added File Zope/lib/python/third_party/docutils/tools/pep.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing HTML from PEP
(Python Enhancement Proposal) documents.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates (X)HTML from reStructuredText-format PEP files.  '
               + default_description)

publish_cmdline(reader_name='pep', writer_name='pep_html',
                description=description)


=== Added File Zope/lib/python/third_party/docutils/tools/quicktest.py ===
#!/usr/bin/env python

# Author: Garth Kidd
# Contact: garth at deadlybloodyserious.com
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

import sys
import os
import getopt
import docutils
from docutils.frontend import OptionParser
from docutils.utils import new_document
from docutils.parsers.rst import Parser


usage_header = """\
quicktest.py: quickly test the restructuredtext parser.

Usage::

    quicktest.py [options] [<source> [<destination>]]

``source`` is the name of the file to use as input (default is stdin).
``destination`` is the name of the file to create as output (default is
stdout).

Options:
"""

options = [('pretty', 'p',
            'output pretty pseudo-xml: no "&abc;" entities (default)'),
           ('test', 't', 'output test-ready data (input & expected output, '
            'ready to be copied to a parser test module)'),
           ('rawxml', 'r', 'output raw XML'),
           ('styledxml=', 's', 'output raw XML with XSL style sheet '
            'reference (filename supplied in the option argument)'),
           ('xml', 'x', 'output pretty XML (indented)'),
           ('attributes', 'A', 'dump document attributes after processing'),
           ('debug', 'd', 'debug mode (lots of output)'),
           ('version', 'V', 'show Docutils version then exit'),
           ('help', 'h', 'show help text then exit')]
"""See ``distutils.fancy_getopt.FancyGetopt.__init__`` for a description of
the data structure: (long option, short option, description)."""

def usage():
    print usage_header
    for longopt, shortopt, description in options:
        if longopt[-1:] == '=':
            opts = '-%s arg, --%sarg' % (shortopt, longopt)
        else:
            opts = '-%s, --%s' % (shortopt, longopt)
        print '%-15s' % opts,
        if len(opts) > 14:
            print '%-16s' % '\n',
        while len(description) > 60:
            limit = description.rindex(' ', 0, 60)
            print description[:limit].strip()
            description = description[limit + 1:]
            print '%-15s' % ' ',
        print description

def _pretty(input, document, optargs):
    return document.pformat()

def _rawxml(input, document, optargs):
    return document.asdom().toxml()

def _styledxml(input, document, optargs):
    docnode = document.asdom().childNodes[0]
    return '%s\n%s\n%s' % (
          '<?xml version="1.0" encoding="ISO-8859-1"?>',
          '<?xml-stylesheet type="text/xsl" href="%s"?>'
          % optargs['styledxml'], docnode.toxml())

def _prettyxml(input, document, optargs):
    return document.asdom().toprettyxml('    ', '\n')

def _test(input, document, optargs):
    tq = '"""'
    output = document.pformat()         # same as _pretty()
    return """\
    totest['change_this_test_name'] = [
[%s\\
%s
%s,
%s\\
%s
%s],
]
""" % ( tq, escape(input.rstrip()), tq, tq, escape(output.rstrip()), tq )

def escape(text):
    """
    Return `text` in triple-double-quoted Python string form.
    """
    text = text.replace('\\', '\\\\')   # escape backslashes
    text = text.replace('"""', '""\\"') # break up triple-double-quotes
    text = text.replace(' \n', ' \\n\\\n') # protect trailing whitespace
    return text

_outputFormatters = {
    'rawxml': _rawxml,
    'styledxml': _styledxml,
    'xml': _prettyxml,
    'pretty' : _pretty,
    'test': _test
    }

def format(outputFormat, input, document, optargs):
    formatter = _outputFormatters[outputFormat]
    return formatter(input, document, optargs)

def getArgs():
    if os.name == 'mac' and len(sys.argv) <= 1:
        return macGetArgs()
    else:
        return posixGetArgs(sys.argv[1:])

def posixGetArgs(argv):
    outputFormat = 'pretty'
    # convert fancy_getopt style option list to getopt.getopt() arguments
    shortopts = ''.join([option[1] + ':' * (option[0][-1:] == '=')
                         for option in options if option[1]])
    longopts = [option[0] for option in options if option[0]]
    try:
        opts, args = getopt.getopt(argv, shortopts, longopts)
    except getopt.GetoptError:
        usage()
        sys.exit(2)
    optargs = {'debug': 0, 'attributes': 0}
    for o, a in opts:
        if o in ['-h', '--help']:
            usage()
            sys.exit()
        elif o in ['-V', '--version']:
            print >>sys.stderr, ('quicktest.py (Docutils %s)'
                                 % docutils.__version__)
            sys.exit()
        elif o in ['-r', '--rawxml']:
            outputFormat = 'rawxml'
        elif o in ['-s', '--styledxml']:
            outputFormat = 'styledxml'
            optargs['styledxml'] = a
        elif o in ['-x', '--xml']:
            outputFormat = 'xml'
        elif o in ['-p', '--pretty']:
            outputFormat = 'pretty'
        elif o in ['-t', '--test']:
            outputFormat = 'test'
        elif o == '--attributes':
            optargs['attributes'] = 1
        elif o in ['-d', '--debug']:
            optargs['debug'] = 1
        else:
            raise getopt.GetoptError, "getopt should have saved us!"
    if len(args) > 2:
        print 'Maximum 2 arguments allowed.'
        usage()
        sys.exit(1)
    inputFile = sys.stdin
    outputFile = sys.stdout
    if args:
        inputFile = open(args.pop(0))
    if args:
        outputFile = open(args.pop(0), 'w')
    return inputFile, outputFile, outputFormat, optargs

def macGetArgs():
    import EasyDialogs
    EasyDialogs.Message("""\
Use the next dialog to build a command line:

1. Choose an output format from the [Option] list 
2. Click [Add]
3. Choose an input file: [Add existing file...]
4. Save the output: [Add new file...]
5. [OK]""")
    optionlist = [(longopt, description)
                  for (longopt, shortopt, description) in options]
    argv = EasyDialogs.GetArgv(optionlist=optionlist, addfolder=0)
    return posixGetArgs(argv)

def main():
    # process cmdline arguments:
    inputFile, outputFile, outputFormat, optargs = getArgs()
    settings = OptionParser(components=(Parser,)).get_default_values()
    settings.debug = optargs['debug']
    parser = Parser()
    input = inputFile.read()
    document = new_document(inputFile.name, settings)
    parser.parse(input, document)
    output = format(outputFormat, input, document, optargs)
    outputFile.write(output)
    if optargs['attributes']:
        import pprint
        pprint.pprint(document.__dict__)


if __name__ == '__main__':
    sys.stderr = sys.stdout
    main()


=== Added File Zope/lib/python/third_party/docutils/tools/rst2html.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at python.org
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing HTML.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates (X)HTML documents from standalone reStructuredText '
               'sources.  ' + default_description)

publish_cmdline(writer_name='html', description=description)


=== Added File Zope/lib/python/third_party/docutils/tools/rst2latex.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing LaTeX.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates LaTeX documents from standalone reStructuredText '
			   'sources.  ' + default_description)

publish_cmdline(writer_name='latex', description=description)


=== Added File Zope/lib/python/third_party/docutils/tools/rst2pseudoxml.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing pseudo-XML.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates pseudo-XML from standalone reStructuredText '
               'sources (for testing purposes).  ' + default_description)

publish_cmdline(description=description)


=== Added File Zope/lib/python/third_party/docutils/tools/rst2xml.py ===
#!/usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This module has been placed in the public domain.

"""
A minimal front end to the Docutils Publisher, producing Docutils XML.
"""

try:
    import locale
    locale.setlocale(locale.LC_ALL, '')
except:
    pass

from docutils.core import publish_cmdline, default_description


description = ('Generates Docutils-native XML from standalone '
               'reStructuredText sources.  ' + default_description)

publish_cmdline(writer_name='xml', description=description)


=== Added File Zope/lib/python/third_party/docutils/tools/unicode2rstsubs.py ===
#! /usr/bin/env python

# Author: David Goodger
# Contact: goodger at users.sourceforge.net
# Revision: $Revision: 1.1.2.1 $
# Date: $Date: 2004/10/29 18:24:56 $
# Copyright: This program has been placed in the public domain.

"""
unicode2subfiles.py -- produce character entity files (reSructuredText
substitutions) from the MathML master unicode.xml file.

This program extracts character entity and entity set information from a
unicode.xml file and produces multiple reStructuredText files (in the current
directory) containing substitutions.  Entity sets are from ISO 8879 & ISO
9573-13 (combined), MathML, and HTML4.  One or two files are produced for each
entity set; a second file with a "-wide.txt" suffix is produced if there are
wide-Unicode characters in the set.

The input file, unicode.xml, is maintained as part of the MathML 2
Recommentation XML source, and is available at
<http://www.w3.org/Math/characters/unicode.xml> (as of 2003-06-22).
"""

import sys
import os
import optparse
import re
from xml.parsers.expat import ParserCreate


usage_msg = """Usage: %s [unicode.xml]"""

def usage(prog, status=0, msg=None):
    print >>sys.stderr, usage_msg % prog
    if msg:
        print >>sys.stderr, msg
    sys.exit(status)

def main(argv=None):
    if argv is None:
        argv = sys.argv
    if len(argv) == 2:
        inpath = argv[1]
    elif len(argv) > 2:
        usage(argv[0], 2,
              'Too many arguments (%s): only 1 expected.' % (len(argv) - 1))
    else:
        inpath = 'unicode.xml'
    if not os.path.isfile(inpath):
        usage(argv[0], 1, 'No such file: "%s".' % inpath)
    infile = open(inpath)
    process(infile)

def process(infile):
    grouper = CharacterEntitySetExtractor(infile)
    grouper.group()
    grouper.write_sets()


class CharacterEntitySetExtractor:

    """
    Extracts character entity information from unicode.xml file, groups it by
    entity set, and writes out reStructuredText substitution files.
    """

    unwanted_entity_sets = ['stix',     # unknown, buggy set
                            'predefined']

    def __init__(self, infile):
        self.infile = infile
        """Input unicode.xml file."""

        self.parser = self.setup_parser()
        """XML parser."""

        self.elements = []
        """Stack of element names.  Last is current element."""

        self.sets = {}
        """Mapping of charent set name to set dict."""

        self.charid = None
        """Current character's "id" attribute value."""

        self.descriptions = {}
        """Mapping of character ID to description."""

    def setup_parser(self):
        parser = ParserCreate()
        parser.StartElementHandler = self.StartElementHandler
        parser.EndElementHandler = self.EndElementHandler
        parser.CharacterDataHandler = self.CharacterDataHandler
        return parser

    def group(self):
        self.parser.ParseFile(self.infile)

    def StartElementHandler(self, name, attributes):
        self.elements.append(name)
        handler = name + '_start'
        if hasattr(self, handler):
            getattr(self, handler)(name, attributes)

    def EndElementHandler(self, name):
        assert self.elements[-1] == name, \
               'unknown end-tag %r (%r)' % (name, self.element)
        self.elements.pop()
        handler = name + '_end'
        if hasattr(self, handler):
            getattr(self, handler)(name)

    def CharacterDataHandler(self, data):
        handler = self.elements[-1] + '_data'
        if hasattr(self, handler):
            getattr(self, handler)(data)

    def character_start(self, name, attributes):
        self.charid = attributes['id']

    def entity_start(self, name, attributes):
        set = self.entity_set_name(attributes['set'])
        if not set:
            return
        if not self.sets.has_key(set):
            print 'bad set: %r' % set
            return
        entity = attributes['id']
        assert (not self.sets[set].has_key(entity)
                or self.sets[set][entity] == self.charid), \
                ('sets[%r][%r] == %r (!= %r)'
                 % (set, entity, self.sets[set][entity], self.charid))
        self.sets[set][entity] = self.charid

    def description_data(self, data):
        self.descriptions.setdefault(self.charid, '')
        self.descriptions[self.charid] += data

    entity_set_name_pat = re.compile(r'[0-9-]*(.+)$')
    """Pattern to strip ISO numbers off the beginning of set names."""

    def entity_set_name(self, name):
        """
        Return lowcased and standard-number-free entity set name.
        Return ``None`` for unwanted entity sets.
        """
        match = self.entity_set_name_pat.match(name)
        name = match.group(1).lower()
        if name in self.unwanted_entity_sets:
            return None
        self.sets.setdefault(name, {})
        return name

    def write_sets(self):
        sets = self.sets.keys()
        sets.sort()
        for set_name in sets:
            self.write_set(set_name)

    def write_set(self, set_name, wide=None):
        if wide:
            outname = set_name + '-wide.txt'
        else:
            outname = set_name + '.txt'
        outfile = open(outname, 'w')
        print 'writing file "%s"' % outname
        set = self.sets[set_name]
        entities = [(e.lower(), e) for e in set.keys()]
        entities.sort()
        longest = 0
        for _, entity_name in entities:
            longest = max(longest, len(entity_name))
        has_wide = None
        for _, entity_name in entities:
            has_wide = self.write_entity(
                set, set_name, entity_name, outfile, longest, wide) or has_wide
        if has_wide and not wide:
            self.write_set(set_name, 1)

    def write_entity(self, set, set_name, entity_name, outfile, longest,
                     wide=None):
        charid = set[entity_name]
        if not wide:
            for code in charid[1:].split('-'):
                if int(code, 16) > 0xFFFF:
                    return 1            # wide-Unicode character
        codes = ' '.join(['U+%s' % code for code in charid[1:].split('-')])
        print >>outfile, ('.. %-*s unicode:: %s .. %s'
                          % (longest + 2, '|' + entity_name + '|',
                             codes, self.descriptions[charid]))


if __name__ == '__main__':
    sys.exit(main())



More information about the Zope-Checkins mailing list