~ubuntu-branches/ubuntu/saucy/python-docutils/saucy

« back to all changes in this revision

Viewing changes to .pc/17_revert_buildhtml.diff/tools/buildhtml.py

  • Committer: Bazaar Package Importer
  • Author(s): Jakub Wilk
  • Date: 2011-06-28 20:43:04 UTC
  • mfrom: (12 sid)
  • mto: (20.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: james.westby@ubuntu.com-20110628204304-isclppvx326b1gjt
Tags: 0.7-3
* Drop 14_distutils_setup.diff and build-dependency on python-setuptools, no
  longer needed.
  + Add postinst snippet do deal with a python-support bug (it cannot
    replace directory with a regular file).
* Bump standards version to 3.9.2, no changes needed.
* Strip debian/tmp prefix from debian/*.install files; in compat
  dh_install will fall back to looking into debian/tmp anyway.
* Drop preinst scripts to remove python-central leftovers; not needed
  anymore.
* Fix patch headers to be in line with DEP-3.
* Remove files created by the test suite in the clean target.
* Drop obsolete recommendation of python-elementtree.
* Drop obsolete conflict with zope3.
* Drop obsolete conflicts with docutils-writer-manpage and rst2man.
* Drop unused virtual packages: python-odtwriter, rst2odt,
  docutils-writer-odt.
* Move all data files to /usr/share/docutils/.
  + Add patch not to use __file__ directly.
  + In debian/rules, check if all uses of __file__ are guarded by our
    wrapper function, i.e. the patch is still up-to-date.
* New binary package: docutils-common, containing data files, configuration
  files and manual pages.
* New binary package: docutils-doc, containing documentation.
  + Conflict with previous versions python-docutils
  + /usr/share/doc/python-docutils/docs used to be a directory, but is now a
    symlink. Conflict with older versions of python-docutils, so that dpkg
    can replace one with the other. Add lintian override.
* New binary package: python3-docutils (closes: #577725).
  + Build-depend on python3-all.
  + Add two patches to fix incompatibilities with Python 3.2
    (python3.2-configparser.diff, python3.2-elementtree.diff).
  + Both python-docutils and python3-docutils provides rst* scripts, managed
    by alternatives.
  + Conflict with other packages shipping /usr/bin/rst2* binaries, so that
    alternatives can be correctly installed. Add lintian override for
    conflicts-with-version.
  + This package does not include the docutils.readers.python, which is no
    longer maintained and does not work with Python 3.
* New virtual package: docutils, provided by both python-docutils and
  python3-docutils.
* New binary package: python3-roman.
* Reword package descriptions of all packages. Thanks to Stefano Rivera for
  proof-reading.
* Simplify debian/rules.
* Merge both debian/*.copyright into a single debian/copryight (as per
  Policy 4.5). Update it.
* Add build-arch and build-indep target to debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/env python
2
 
 
3
 
# $Id: buildhtml.py 5741 2008-12-01 07:21:03Z grubert $
4
 
# Author: David Goodger <goodger@python.org>
5
 
# Copyright: This module has been placed in the public domain.
6
 
 
7
 
"""
8
 
Generates .html from all the .txt files in a directory.
9
 
 
10
 
Ordinary .txt files are understood to be standalone reStructuredText.
11
 
Files named ``pep-*.txt`` are interpreted as reStructuredText PEPs.
12
 
"""
13
 
# Once PySource is here, build .html from .py as well.
14
 
 
15
 
__docformat__ = 'reStructuredText'
16
 
 
17
 
 
18
 
try:
19
 
    import locale
20
 
    locale.setlocale(locale.LC_ALL, '')
21
 
except:
22
 
    pass
23
 
 
24
 
import sys
25
 
import os
26
 
import os.path
27
 
import copy
28
 
from fnmatch import fnmatch
29
 
import docutils
30
 
from docutils import ApplicationError
31
 
from docutils import core, frontend, utils
32
 
from docutils.parsers import rst
33
 
from docutils.readers import standalone, pep
34
 
from docutils.writers import html4css1, pep_html
35
 
 
36
 
 
37
 
usage = '%prog [options] [<directory> ...]'
38
 
description = ('Generates .html from all the reStructuredText .txt files '
39
 
               '(including PEPs) in each <directory> '
40
 
               '(default is the current directory).')
41
 
 
42
 
 
43
 
class SettingsSpec(docutils.SettingsSpec):
44
 
 
45
 
    """
46
 
    Runtime settings & command-line options for the front end.
47
 
    """
48
 
 
49
 
    # Can't be included in OptionParser below because we don't want to
50
 
    # override the base class.
51
 
    settings_spec = (
52
 
        'Build-HTML Options',
53
 
        None,
54
 
        (('Recursively scan subdirectories for files to process.  This is '
55
 
          'the default.',
56
 
          ['--recurse'],
57
 
          {'action': 'store_true', 'default': 1,
58
 
           'validator': frontend.validate_boolean}),
59
 
         ('Do not scan subdirectories for files to process.',
60
 
          ['--local'], {'dest': 'recurse', 'action': 'store_false'}),
61
 
         ('Do not process files in <directory>.  This option may be used '
62
 
          'more than once to specify multiple directories.',
63
 
          ['--prune'],
64
 
          {'metavar': '<directory>', 'action': 'append',
65
 
           'validator': frontend.validate_colon_separated_string_list}),
66
 
         ('Recursively ignore files or directories matching any of the given '
67
 
          'wildcard (shell globbing) patterns (separated by colons).  '
68
 
          'Default: ".svn:CVS"',
69
 
          ['--ignore'],
70
 
          {'metavar': '<patterns>', 'action': 'append',
71
 
           'default': ['.svn', 'CVS'],
72
 
           'validator': frontend.validate_colon_separated_string_list}),
73
 
         ('Work silently (no progress messages).  Independent of "--quiet".',
74
 
          ['--silent'],
75
 
          {'action': 'store_true', 'validator': frontend.validate_boolean}),))
76
 
 
77
 
    relative_path_settings = ('prune',)
78
 
    config_section = 'buildhtml application'
79
 
    config_section_dependencies = ('applications',)
80
 
 
81
 
 
82
 
class OptionParser(frontend.OptionParser):
83
 
 
84
 
    """
85
 
    Command-line option processing for the ``buildhtml.py`` front end.
86
 
    """
87
 
 
88
 
    def check_values(self, values, args):
89
 
        frontend.OptionParser.check_values(self, values, args)
90
 
        values._source = None
91
 
        return values
92
 
 
93
 
    def check_args(self, args):
94
 
        source = destination = None
95
 
        if args:
96
 
            self.values._directories = args
97
 
        else:
98
 
            self.values._directories = [os.getcwd()]
99
 
        return source, destination
100
 
 
101
 
 
102
 
class Struct:
103
 
 
104
 
    """Stores data attributes for dotted-attribute access."""
105
 
 
106
 
    def __init__(self, **keywordargs):
107
 
        self.__dict__.update(keywordargs)
108
 
 
109
 
 
110
 
class Builder:
111
 
 
112
 
    def __init__(self):
113
 
        self.publishers = {
114
 
            '': Struct(components=(pep.Reader, rst.Parser, pep_html.Writer,
115
 
                                   SettingsSpec)),
116
 
            '.txt': Struct(components=(rst.Parser, standalone.Reader,
117
 
                                       html4css1.Writer, SettingsSpec),
118
 
                           reader_name='standalone',
119
 
                           writer_name='html'),
120
 
            'PEPs': Struct(components=(rst.Parser, pep.Reader,
121
 
                                       pep_html.Writer, SettingsSpec),
122
 
                           reader_name='pep',
123
 
                           writer_name='pep_html')}
124
 
        """Publisher-specific settings.  Key '' is for the front-end script
125
 
        itself.  ``self.publishers[''].components`` must contain a superset of
126
 
        all components used by individual publishers."""
127
 
 
128
 
        self.setup_publishers()
129
 
 
130
 
    def setup_publishers(self):
131
 
        """
132
 
        Manage configurations for individual publishers.
133
 
 
134
 
        Each publisher (combination of parser, reader, and writer) may have
135
 
        its own configuration defaults, which must be kept separate from those
136
 
        of the other publishers.  Setting defaults are combined with the
137
 
        config file settings and command-line options by
138
 
        `self.get_settings()`.
139
 
        """
140
 
        for name, publisher in self.publishers.items():
141
 
            option_parser = OptionParser(
142
 
                components=publisher.components, read_config_files=1,
143
 
                usage=usage, description=description)
144
 
            publisher.option_parser = option_parser
145
 
            publisher.setting_defaults = option_parser.get_default_values()
146
 
            frontend.make_paths_absolute(publisher.setting_defaults.__dict__,
147
 
                                         option_parser.relative_path_settings)
148
 
            publisher.config_settings = (
149
 
                option_parser.get_standard_config_settings())
150
 
        self.settings_spec = self.publishers[''].option_parser.parse_args(
151
 
            values=frontend.Values())   # no defaults; just the cmdline opts
152
 
        self.initial_settings = self.get_settings('')
153
 
 
154
 
    def get_settings(self, publisher_name, directory=None):
155
 
        """
156
 
        Return a settings object, from multiple sources.
157
 
 
158
 
        Copy the setting defaults, overlay the startup config file settings,
159
 
        then the local config file settings, then the command-line options.
160
 
        Assumes the current directory has been set.
161
 
        """
162
 
        publisher = self.publishers[publisher_name]
163
 
        settings = frontend.Values(publisher.setting_defaults.__dict__)
164
 
        settings.update(publisher.config_settings, publisher.option_parser)
165
 
        if directory:
166
 
            local_config = publisher.option_parser.get_config_file_settings(
167
 
                os.path.join(directory, 'docutils.conf'))
168
 
            frontend.make_paths_absolute(
169
 
                local_config, publisher.option_parser.relative_path_settings,
170
 
                directory)
171
 
            settings.update(local_config, publisher.option_parser)
172
 
        settings.update(self.settings_spec.__dict__, publisher.option_parser)
173
 
        return settings
174
 
 
175
 
    def run(self, directory=None, recurse=1):
176
 
        recurse = recurse and self.initial_settings.recurse
177
 
        if directory:
178
 
            self.directories = [directory]
179
 
        elif self.settings_spec._directories:
180
 
            self.directories = self.settings_spec._directories
181
 
        else:
182
 
            self.directories = [os.getcwd()]
183
 
        for directory in self.directories:
184
 
            try:
185
 
                for root, dirs, files in os.walk(directory):
186
 
                    self.visit(recurse, root, dirs+files)
187
 
            except (AttributeError): # python2.2 does not have os.walk
188
 
                print "no os.walk"
189
 
                os.path.walk(directory, self.visit, recurse)
190
 
 
191
 
    def visit(self, recurse, directory, names):
192
 
        settings = self.get_settings('', directory)
193
 
        if settings.prune and (os.path.abspath(directory) in settings.prune):
194
 
            print >>sys.stderr, '/// ...Skipping directory (pruned):', directory
195
 
            sys.stderr.flush()
196
 
            names[:] = []
197
 
            return
198
 
        if not self.initial_settings.silent:
199
 
            print >>sys.stderr, '/// Processing directory:', directory
200
 
            sys.stderr.flush()
201
 
        # settings.ignore grows many duplicate entries as we recurse
202
 
        # if we add patterns in config files or on the command line.
203
 
        for pattern in utils.uniq(settings.ignore):
204
 
            for i in range(len(names) - 1, -1, -1):
205
 
                if fnmatch(names[i], pattern):
206
 
                    # Modify in place!
207
 
                    del names[i]
208
 
        prune = 0
209
 
        for name in names:
210
 
            if name.endswith('.txt'):
211
 
                prune = self.process_txt(directory, name)
212
 
                if prune:
213
 
                    break
214
 
        if not recurse:
215
 
            del names[:]
216
 
 
217
 
    def process_txt(self, directory, name):
218
 
        if name.startswith('pep-'):
219
 
            publisher = 'PEPs'
220
 
        else:
221
 
            publisher = '.txt'
222
 
        settings = self.get_settings(publisher, directory)
223
 
        pub_struct = self.publishers[publisher]
224
 
        if settings.prune and (directory in settings.prune):
225
 
            return 1
226
 
        settings._source = os.path.normpath(os.path.join(directory, name))
227
 
        settings._destination = settings._source[:-4]+'.html'
228
 
        if not self.initial_settings.silent:
229
 
            print >>sys.stderr, '    ::: Processing:', name
230
 
            sys.stderr.flush()
231
 
        try:
232
 
            core.publish_file(source_path=settings._source,
233
 
                              destination_path=settings._destination,
234
 
                              reader_name=pub_struct.reader_name,
235
 
                              parser_name='restructuredtext',
236
 
                              writer_name=pub_struct.writer_name,
237
 
                              settings=settings)
238
 
        except ApplicationError, error:
239
 
            print >>sys.stderr, ('        Error (%s): %s'
240
 
                                 % (error.__class__.__name__, error))
241
 
 
242
 
 
243
 
if __name__ == "__main__":
244
 
    Builder().run()