~ubuntu-branches/ubuntu/karmic/python-docutils/karmic

« back to all changes in this revision

Viewing changes to docutils/core.py

  • Committer: Bazaar Package Importer
  • Author(s): martin f. krafft
  • Date: 2006-07-10 11:45:05 UTC
  • mfrom: (2.1.4 edgy)
  • Revision ID: james.westby@ubuntu.com-20060710114505-otkhqcslevewxmz5
Tags: 0.4-3
Added build dependency on python-central (closes: #377580).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Authors: David Goodger
2
 
# Contact: goodger@users.sourceforge.net
3
 
# Revision: $Revision: 1.39 $
4
 
# Date: $Date: 2004/04/03 14:03:25 $
 
2
# Contact: goodger@python.org
 
3
# Revision: $Revision: 4208 $
 
4
# Date: $Date: 2005-12-14 03:12:00 +0100 (Wed, 14 Dec 2005) $
5
5
# Copyright: This module has been placed in the public domain.
6
6
 
7
7
"""
9
9
`Publisher` object) with component names will result in default
10
10
behavior.  For custom behavior (setting component options), create
11
11
custom component objects first, and pass *them* to
12
 
``publish_*``/`Publisher`.
 
12
``publish_*``/`Publisher`.  See `The Docutils Publisher`_.
 
13
 
 
14
.. _The Docutils Publisher: http://docutils.sf.net/docs/api/publisher.html
13
15
"""
14
16
 
15
17
__docformat__ = 'reStructuredText'
16
18
 
17
19
import sys
18
 
from docutils import __version__, Component, SettingsSpec
19
 
from docutils import frontend, io, utils, readers, parsers, writers
 
20
import pprint
 
21
from types import StringType
 
22
from docutils import __version__, __version_details__, SettingsSpec
 
23
from docutils import frontend, io, utils, readers, writers
20
24
from docutils.frontend import OptionParser
 
25
from docutils.transforms import Transformer
 
26
import docutils.readers.doctree
21
27
 
22
28
 
23
29
class Publisher:
36
42
        a component name (`set_reader` sets the parser as well).
37
43
        """
38
44
 
 
45
        self.document = None
 
46
        """The document tree (`docutils.nodes` objects)."""
 
47
 
39
48
        self.reader = reader
40
 
        """A `readers.Reader` instance."""
 
49
        """A `docutils.readers.Reader` instance."""
41
50
 
42
51
        self.parser = parser
43
 
        """A `parsers.Parser` instance."""
 
52
        """A `docutils.parsers.Parser` instance."""
44
53
 
45
54
        self.writer = writer
46
 
        """A `writers.Writer` instance."""
 
55
        """A `docutils.writers.Writer` instance."""
 
56
 
 
57
        for component in 'reader', 'parser', 'writer':
 
58
            assert not isinstance(getattr(self, component), StringType), \
 
59
                   ('passed string as "%s" parameter; use "%s_name" instead'
 
60
                    % (getattr(self, component), component, component))
47
61
 
48
62
        self.source = source
49
 
        """The source of input data, an `io.Input` instance."""
 
63
        """The source of input data, a `docutils.io.Input` instance."""
50
64
 
51
65
        self.source_class = source_class
52
66
        """The class for dynamically created source objects."""
53
67
 
54
68
        self.destination = destination
55
 
        """The destination for docutils output, an `io.Output` instance."""
 
69
        """The destination for docutils output, a `docutils.io.Output`
 
70
        instance."""
56
71
 
57
72
        self.destination_class = destination_class
58
73
        """The class for dynamically created destination objects."""
85
100
    def setup_option_parser(self, usage=None, description=None,
86
101
                            settings_spec=None, config_section=None,
87
102
                            **defaults):
88
 
        if config_section and not settings_spec:
89
 
            settings_spec = SettingsSpec()
 
103
        if config_section:
 
104
            if not settings_spec:
 
105
                settings_spec = SettingsSpec()
90
106
            settings_spec.config_section = config_section
91
107
            parts = config_section.split()
92
108
            if len(parts) > 1 and parts[-1] == 'application':
112
128
        self.settings = option_parser.get_default_values()
113
129
        return self.settings
114
130
 
 
131
    def process_programmatic_settings(self, settings_spec,
 
132
                                      settings_overrides,
 
133
                                      config_section):
 
134
        if self.settings is None:
 
135
            defaults = (settings_overrides or {}).copy()
 
136
            # Propagate exceptions by default when used programmatically:
 
137
            defaults.setdefault('traceback', 1)
 
138
            self.get_settings(settings_spec=settings_spec,
 
139
                              config_section=config_section,
 
140
                              **defaults)
 
141
 
115
142
    def process_command_line(self, argv=None, usage=None, description=None,
116
143
                             settings_spec=None, config_section=None,
117
144
                             **defaults):
122
149
        Set components first (`self.set_reader` & `self.set_writer`).
123
150
        """
124
151
        option_parser = self.setup_option_parser(
125
 
            usage, description, settings_spec, config_section,**defaults)
 
152
            usage, description, settings_spec, config_section, **defaults)
126
153
        if argv is None:
127
154
            argv = sys.argv[1:]
128
155
        self.settings = option_parser.parse_args(argv)
152
179
            encoding=self.settings.output_encoding,
153
180
            error_handler=self.settings.output_encoding_error_handler)
154
181
 
155
 
    def apply_transforms(self, document):
156
 
        document.transformer.populate_from_components(
 
182
    def apply_transforms(self):
 
183
        self.document.transformer.populate_from_components(
157
184
            (self.source, self.reader, self.reader.parser, self.writer,
158
185
             self.destination))
159
 
        document.transformer.apply_transforms()
 
186
        self.document.transformer.apply_transforms()
160
187
 
161
188
    def publish(self, argv=None, usage=None, description=None,
162
189
                settings_spec=None, settings_overrides=None,
163
 
                config_section=None, enable_exit=None):
 
190
                config_section=None, enable_exit_status=None):
164
191
        """
165
192
        Process command line options and arguments (if `self.settings` not
166
193
        already set), run `self.reader` and then `self.writer`.  Return
167
194
        `self.writer`'s output.
168
195
        """
169
 
        if self.settings is None:
170
 
            self.process_command_line(
171
 
                argv, usage, description, settings_spec, config_section,
172
 
                **(settings_overrides or {}))
173
 
        elif settings_overrides:
174
 
            self.settings._update(settings_overrides, 'loose')
175
 
        self.set_io()
176
196
        exit = None
177
 
        document = None
178
197
        try:
179
 
            document = self.reader.read(self.source, self.parser,
180
 
                                        self.settings)
181
 
            self.apply_transforms(document)
182
 
            output = self.writer.write(document, self.destination)
 
198
            if self.settings is None:
 
199
                self.process_command_line(
 
200
                    argv, usage, description, settings_spec, config_section,
 
201
                    **(settings_overrides or {}))
 
202
            self.set_io()
 
203
            self.document = self.reader.read(self.source, self.parser,
 
204
                                             self.settings)
 
205
            self.apply_transforms()
 
206
            output = self.writer.write(self.document, self.destination)
183
207
            self.writer.assemble_parts()
184
 
        except utils.SystemMessage, error:
185
 
            if self.settings.traceback:
186
 
                raise
187
 
            print >>sys.stderr, ('Exiting due to level-%s (%s) system message.'
188
 
                                 % (error.level,
189
 
                                    utils.Reporter.levels[error.level]))
 
208
        except SystemExit, error:
190
209
            exit = 1
 
210
            exit_status = error.code
191
211
        except Exception, error:
192
 
            if self.settings.traceback:
193
 
                raise
194
 
            print >>sys.stderr, error
195
 
            print >>sys.stderr, ("""\
196
 
Exiting due to error.  Use "--traceback" to diagnose.
197
 
Please report errors to <docutils-users@lists.sf.net>.
198
 
Include "--traceback" output, Docutils version (%s),
199
 
Python version (%s), your OS type & version, and the
200
 
command line used.""" % (__version__, sys.version.split()[0]))
 
212
            if not self.settings:       # exception too early to report nicely
 
213
                raise
 
214
            if self.settings.traceback: # Propagate exceptions?
 
215
                self.debugging_dumps()
 
216
                raise
 
217
            self.report_Exception(error)
201
218
            exit = 1
 
219
            exit_status = 1
 
220
        self.debugging_dumps()
 
221
        if (enable_exit_status and self.document
 
222
            and (self.document.reporter.max_level
 
223
                 >= self.settings.exit_status_level)):
 
224
            sys.exit(self.document.reporter.max_level + 10)
 
225
        elif exit:
 
226
            sys.exit(exit_status)
 
227
        return output
 
228
 
 
229
    def debugging_dumps(self):
 
230
        if not self.document:
 
231
            return
202
232
        if self.settings.dump_settings:
203
 
            from pprint import pformat
204
233
            print >>sys.stderr, '\n::: Runtime settings:'
205
 
            print >>sys.stderr, pformat(self.settings.__dict__)
206
 
        if self.settings.dump_internals and document:
207
 
            from pprint import pformat
 
234
            print >>sys.stderr, pprint.pformat(self.settings.__dict__)
 
235
        if self.settings.dump_internals:
208
236
            print >>sys.stderr, '\n::: Document internals:'
209
 
            print >>sys.stderr, pformat(document.__dict__)
210
 
        if self.settings.dump_transforms and document:
211
 
            from pprint import pformat
 
237
            print >>sys.stderr, pprint.pformat(self.document.__dict__)
 
238
        if self.settings.dump_transforms:
212
239
            print >>sys.stderr, '\n::: Transforms applied:'
213
 
            print >>sys.stderr, pformat(document.transformer.applied)
214
 
        if self.settings.dump_pseudo_xml and document:
 
240
            print >>sys.stderr, (' (priority, transform class, '
 
241
                                 'pending node details, keyword args)')
 
242
            print >>sys.stderr, pprint.pformat(
 
243
                [(priority, '%s.%s' % (xclass.__module__, xclass.__name__),
 
244
                  pending and pending.details, kwargs)
 
245
                 for priority, xclass, pending, kwargs
 
246
                 in self.document.transformer.applied])
 
247
        if self.settings.dump_pseudo_xml:
215
248
            print >>sys.stderr, '\n::: Pseudo-XML:'
216
 
            print >>sys.stderr, document.pformat().encode(
 
249
            print >>sys.stderr, self.document.pformat().encode(
217
250
                'raw_unicode_escape')
218
 
        if enable_exit and document and (document.reporter.max_level
219
 
                                         >= self.settings.exit_level):
220
 
            sys.exit(document.reporter.max_level + 10)
221
 
        elif exit:
222
 
            sys.exit(1)
223
 
        return output
224
 
 
 
251
 
 
252
    def report_Exception(self, error):
 
253
        if isinstance(error, utils.SystemMessage):
 
254
            self.report_SystemMessage(error)
 
255
        elif isinstance(error, UnicodeError):
 
256
            self.report_UnicodeError(error)
 
257
        else:
 
258
            print >>sys.stderr, '%s: %s' % (error.__class__.__name__, error)
 
259
            print >>sys.stderr, ("""\
 
260
Exiting due to error.  Use "--traceback" to diagnose.
 
261
Please report errors to <docutils-users@lists.sf.net>.
 
262
Include "--traceback" output, Docutils version (%s [%s]),
 
263
Python version (%s), your OS type & version, and the
 
264
command line used.""" % (__version__, __version_details__,
 
265
                         sys.version.split()[0]))
 
266
 
 
267
    def report_SystemMessage(self, error):
 
268
        print >>sys.stderr, ('Exiting due to level-%s (%s) system message.'
 
269
                             % (error.level,
 
270
                                utils.Reporter.levels[error.level]))
 
271
 
 
272
    def report_UnicodeError(self, error):
 
273
        sys.stderr.write(
 
274
            '%s: %s\n'
 
275
            '\n'
 
276
            'The specified output encoding (%s) cannot\n'
 
277
            'handle all of the output.\n'
 
278
            'Try setting "--output-encoding-error-handler" to\n'
 
279
            '\n'
 
280
            '* "xmlcharrefreplace" (for HTML & XML output);\n'
 
281
            % (error.__class__.__name__, error,
 
282
               self.settings.output_encoding))
 
283
        try:
 
284
            data = error.object[error.start:error.end]
 
285
            sys.stderr.write(
 
286
                '  the output will contain "%s" and should be usable.\n'
 
287
                '* "backslashreplace" (for other output formats, Python 2.3+);\n'
 
288
                '  look for "%s" in the output.\n'
 
289
                % (data.encode('ascii', 'xmlcharrefreplace'),
 
290
                   data.encode('ascii', 'backslashreplace')))
 
291
        except AttributeError:
 
292
            sys.stderr.write('  the output should be usable as-is.\n')
 
293
        sys.stderr.write(
 
294
            '* "replace"; look for "?" in the output.\n'
 
295
            '\n'
 
296
            '"--output-encoding-error-handler" is currently set to "%s".\n'
 
297
            '\n'
 
298
            'Exiting due to error.  Use "--traceback" to diagnose.\n'
 
299
            'If the advice above doesn\'t eliminate the error,\n'
 
300
            'please report it to <docutils-users@lists.sf.net>.\n'
 
301
            'Include "--traceback" output, Docutils version (%s),\n'
 
302
            'Python version (%s), your OS type & version, and the\n'
 
303
            'command line used.\n'
 
304
            % (self.settings.output_encoding_error_handler,
 
305
               __version__, sys.version.split()[0]))
225
306
 
226
307
default_usage = '%prog [options] [<source> [<destination>]]'
227
308
default_description = ('Reads from <source> (default is stdin) and writes to '
232
313
                    writer=None, writer_name='pseudoxml',
233
314
                    settings=None, settings_spec=None,
234
315
                    settings_overrides=None, config_section=None,
235
 
                    enable_exit=1, argv=None,
 
316
                    enable_exit_status=1, argv=None,
236
317
                    usage=default_usage, description=default_description):
237
318
    """
238
 
    Set up & run a `Publisher`.  For command-line front ends.
239
 
 
240
 
    Parameters:
241
 
 
242
 
    - `reader`: A `docutils.readers.Reader` object.
243
 
    - `reader_name`: Name or alias of the Reader class to be instantiated if
244
 
      no `reader` supplied.
245
 
    - `parser`: A `docutils.parsers.Parser` object.
246
 
    - `parser_name`: Name or alias of the Parser class to be instantiated if
247
 
      no `parser` supplied.
248
 
    - `writer`: A `docutils.writers.Writer` object.
249
 
    - `writer_name`: Name or alias of the Writer class to be instantiated if
250
 
      no `writer` supplied.
251
 
    - `settings`: Runtime settings object.
252
 
    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
253
 
      subclass.  Used only if no `settings` specified.
254
 
    - `settings_overrides`: A dictionary containing program-specific overrides
255
 
      of component settings.
256
 
    - `config_section`: Name of configuration file section for application.
257
 
      Used only if no `settings` or `settings_spec` specified.
258
 
    - `enable_exit`: Boolean; enable exit status at end of processing?
 
319
    Set up & run a `Publisher` for command-line-based file I/O (input and
 
320
    output file paths taken automatically from the command line).  Return the
 
321
    encoded string output also.
 
322
 
 
323
    Parameters: see `publish_programmatically` for the remainder.
 
324
 
259
325
    - `argv`: Command-line argument list to use instead of ``sys.argv[1:]``.
260
326
    - `usage`: Usage string, output if there's a problem parsing the command
261
327
      line.
264
330
    """
265
331
    pub = Publisher(reader, parser, writer, settings=settings)
266
332
    pub.set_components(reader_name, parser_name, writer_name)
267
 
    pub.publish(argv, usage, description, settings_spec, settings_overrides,
268
 
                config_section=config_section, enable_exit=enable_exit)
 
333
    output = pub.publish(
 
334
        argv, usage, description, settings_spec, settings_overrides,
 
335
        config_section=config_section, enable_exit_status=enable_exit_status)
 
336
    return output
269
337
 
270
338
def publish_file(source=None, source_path=None,
271
339
                 destination=None, destination_path=None,
273
341
                 parser=None, parser_name='restructuredtext',
274
342
                 writer=None, writer_name='pseudoxml',
275
343
                 settings=None, settings_spec=None, settings_overrides=None,
276
 
                 config_section=None, enable_exit=None):
277
 
    """
278
 
    Set up & run a `Publisher`.  For programmatic use with file-like I/O.
279
 
 
280
 
    Parameters:
281
 
 
282
 
    - `source`: A file-like object (must have "read" and "close" methods).
283
 
    - `source_path`: Path to the input file.  Opened if no `source` supplied.
284
 
      If neither `source` nor `source_path` are supplied, `sys.stdin` is used.
285
 
    - `destination`: A file-like object (must have "write" and "close"
286
 
      methods).
287
 
    - `destination_path`: Path to the input file.  Opened if no `destination`
288
 
      supplied.  If neither `destination` nor `destination_path` are supplied,
289
 
      `sys.stdout` is used.
290
 
    - `reader`: A `docutils.readers.Reader` object.
291
 
    - `reader_name`: Name or alias of the Reader class to be instantiated if
292
 
      no `reader` supplied.
293
 
    - `parser`: A `docutils.parsers.Parser` object.
294
 
    - `parser_name`: Name or alias of the Parser class to be instantiated if
295
 
      no `parser` supplied.
296
 
    - `writer`: A `docutils.writers.Writer` object.
297
 
    - `writer_name`: Name or alias of the Writer class to be instantiated if
298
 
      no `writer` supplied.
299
 
    - `settings`: Runtime settings object.
300
 
    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
301
 
      subclass.  Used only if no `settings` specified.
302
 
    - `settings_overrides`: A dictionary containing program-specific overrides
303
 
      of component settings.
304
 
    - `config_section`: Name of configuration file section for application.
305
 
      Used only if no `settings` or `settings_spec` specified.
306
 
    - `enable_exit`: Boolean; enable exit status at end of processing?
307
 
    """
308
 
    pub = Publisher(reader, parser, writer, settings=settings)
309
 
    pub.set_components(reader_name, parser_name, writer_name)
310
 
    if settings is None:
311
 
        settings = pub.get_settings(settings_spec=settings_spec,
312
 
                                    config_section=config_section)
313
 
    if settings_overrides:
314
 
        settings._update(settings_overrides, 'loose')
315
 
    pub.set_source(source, source_path)
316
 
    pub.set_destination(destination, destination_path)
317
 
    pub.publish(enable_exit=enable_exit)
318
 
 
319
 
def publish_string(source, source_path=None, destination_path=None, 
 
344
                 config_section=None, enable_exit_status=None):
 
345
    """
 
346
    Set up & run a `Publisher` for programmatic use with file-like I/O.
 
347
    Return the encoded string output also.
 
348
 
 
349
    Parameters: see `publish_programmatically`.
 
350
    """
 
351
    output, pub = publish_programmatically(
 
352
        source_class=io.FileInput, source=source, source_path=source_path,
 
353
        destination_class=io.FileOutput,
 
354
        destination=destination, destination_path=destination_path,
 
355
        reader=reader, reader_name=reader_name,
 
356
        parser=parser, parser_name=parser_name,
 
357
        writer=writer, writer_name=writer_name,
 
358
        settings=settings, settings_spec=settings_spec,
 
359
        settings_overrides=settings_overrides,
 
360
        config_section=config_section,
 
361
        enable_exit_status=enable_exit_status)
 
362
    return output
 
363
 
 
364
def publish_string(source, source_path=None, destination_path=None,
320
365
                   reader=None, reader_name='standalone',
321
366
                   parser=None, parser_name='restructuredtext',
322
367
                   writer=None, writer_name='pseudoxml',
323
368
                   settings=None, settings_spec=None,
324
369
                   settings_overrides=None, config_section=None,
325
 
                   enable_exit=None):
 
370
                   enable_exit_status=None):
326
371
    """
327
 
    Set up & run a `Publisher`, and return the string output.
328
 
    For programmatic use with string I/O.
 
372
    Set up & run a `Publisher` for programmatic use with string I/O.  Return
 
373
    the encoded string or Unicode string output.
329
374
 
330
 
    For encoded string output, be sure to set the "output_encoding" setting to
331
 
    the desired encoding.  Set it to "unicode" for unencoded Unicode string
332
 
    output.  Here's how::
 
375
    For encoded string output, be sure to set the 'output_encoding' setting to
 
376
    the desired encoding.  Set it to 'unicode' for unencoded Unicode string
 
377
    output.  Here's one way::
333
378
 
334
379
        publish_string(..., settings_overrides={'output_encoding': 'unicode'})
335
380
 
337
382
 
338
383
        publish_string(..., settings_overrides={'input_encoding': 'unicode'})
339
384
 
340
 
    Parameters:
341
 
 
342
 
    - `source`: An input string; required.  This can be an encoded 8-bit
343
 
      string (set the "input_encoding" setting to the correct encoding) or a
344
 
      Unicode string (set the "input_encoding" setting to "unicode").
345
 
    - `source_path`: Path to the file or object that produced `source`;
346
 
      optional.  Only used for diagnostic output.
347
 
    - `destination_path`: Path to the file or object which will receive the
348
 
      output; optional.  Used for determining relative paths (stylesheets,
349
 
      source links, etc.).
350
 
    - `reader`: A `docutils.readers.Reader` object.
351
 
    - `reader_name`: Name or alias of the Reader class to be instantiated if
352
 
      no `reader` supplied.
353
 
    - `parser`: A `docutils.parsers.Parser` object.
354
 
    - `parser_name`: Name or alias of the Parser class to be instantiated if
355
 
      no `parser` supplied.
356
 
    - `writer`: A `docutils.writers.Writer` object.
357
 
    - `writer_name`: Name or alias of the Writer class to be instantiated if
358
 
      no `writer` supplied.
359
 
    - `settings`: Runtime settings object.
360
 
    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
361
 
      subclass.  Used only if no `settings` specified.
362
 
    - `settings_overrides`: A dictionary containing program-specific overrides
363
 
      of component settings.
364
 
    - `config_section`: Name of configuration file section for application.
365
 
      Used only if no `settings` or `settings_spec` specified.
366
 
    - `enable_exit`: Boolean; enable exit status at end of processing?
 
385
    Parameters: see `publish_programmatically`.
367
386
    """
368
 
    pub = Publisher(reader, parser, writer, settings=settings,
369
 
                    source_class=io.StringInput,
370
 
                    destination_class=io.StringOutput)
371
 
    pub.set_components(reader_name, parser_name, writer_name)
372
 
    if settings is None:
373
 
        settings = pub.get_settings(settings_spec=settings_spec,
374
 
                                    config_section=config_section)
375
 
    if settings_overrides:
376
 
        settings._update(settings_overrides, 'loose')
377
 
    pub.set_source(source, source_path)
378
 
    pub.set_destination(destination_path=destination_path)
379
 
    return pub.publish(enable_exit=enable_exit)
 
387
    output, pub = publish_programmatically(
 
388
        source_class=io.StringInput, source=source, source_path=source_path,
 
389
        destination_class=io.StringOutput,
 
390
        destination=None, destination_path=destination_path,
 
391
        reader=reader, reader_name=reader_name,
 
392
        parser=parser, parser_name=parser_name,
 
393
        writer=writer, writer_name=writer_name,
 
394
        settings=settings, settings_spec=settings_spec,
 
395
        settings_overrides=settings_overrides,
 
396
        config_section=config_section,
 
397
        enable_exit_status=enable_exit_status)
 
398
    return output
380
399
 
381
 
def publish_parts(source, source_path=None, destination_path=None, 
 
400
def publish_parts(source, source_path=None, source_class=io.StringInput,
 
401
                  destination_path=None,
382
402
                  reader=None, reader_name='standalone',
383
403
                  parser=None, parser_name='restructuredtext',
384
404
                  writer=None, writer_name='pseudoxml',
385
405
                  settings=None, settings_spec=None,
386
406
                  settings_overrides=None, config_section=None,
387
 
                  enable_exit=None):
 
407
                  enable_exit_status=None):
388
408
    """
389
409
    Set up & run a `Publisher`, and return a dictionary of document parts.
390
410
    Dictionary keys are the names of parts, and values are Unicode strings;
391
411
    encoding is up to the client.  For programmatic use with string I/O.
392
412
 
393
 
    For encoded string input, be sure to set the "input_encoding" setting to
394
 
    the desired encoding.  Set it to "unicode" for unencoded Unicode string
 
413
    For encoded string input, be sure to set the 'input_encoding' setting to
 
414
    the desired encoding.  Set it to 'unicode' for unencoded Unicode string
395
415
    input.  Here's how::
396
416
 
397
 
        publish_string(..., settings_overrides={'input_encoding': 'unicode'})
398
 
 
399
 
    Parameters:
400
 
 
401
 
    - `source`: An input string; required.  This can be an encoded 8-bit
402
 
      string (set the "input_encoding" setting to the correct encoding) or a
403
 
      Unicode string (set the "input_encoding" setting to "unicode").
404
 
    - `source_path`: Path to the file or object that produced `source`;
405
 
      optional.  Only used for diagnostic output.
406
 
    - `destination_path`: Path to the file or object which will receive the
407
 
      output; optional.  Used for determining relative paths (stylesheets,
408
 
      source links, etc.).
409
 
    - `reader`: A `docutils.readers.Reader` object.
410
 
    - `reader_name`: Name or alias of the Reader class to be instantiated if
411
 
      no `reader` supplied.
412
 
    - `parser`: A `docutils.parsers.Parser` object.
413
 
    - `parser_name`: Name or alias of the Parser class to be instantiated if
414
 
      no `parser` supplied.
415
 
    - `writer`: A `docutils.writers.Writer` object.
416
 
    - `writer_name`: Name or alias of the Writer class to be instantiated if
417
 
      no `writer` supplied.
418
 
    - `settings`: Runtime settings object.
419
 
    - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
420
 
      subclass.  Used only if no `settings` specified.
421
 
    - `settings_overrides`: A dictionary containing program-specific overrides
422
 
      of component settings.
423
 
    - `config_section`: Name of configuration file section for application.
424
 
      Used only if no `settings` or `settings_spec` specified.
425
 
    - `enable_exit`: Boolean; enable exit status at end of processing?
 
417
        publish_parts(..., settings_overrides={'input_encoding': 'unicode'})
 
418
 
 
419
    Parameters: see `publish_programmatically`.
426
420
    """
427
 
    pub = Publisher(reader, parser, writer, settings=settings,
 
421
    output, pub = publish_programmatically(
 
422
        source=source, source_path=source_path, source_class=source_class,
 
423
        destination_class=io.StringOutput,
 
424
        destination=None, destination_path=destination_path,
 
425
        reader=reader, reader_name=reader_name,
 
426
        parser=parser, parser_name=parser_name,
 
427
        writer=writer, writer_name=writer_name,
 
428
        settings=settings, settings_spec=settings_spec,
 
429
        settings_overrides=settings_overrides,
 
430
        config_section=config_section,
 
431
        enable_exit_status=enable_exit_status)
 
432
    return pub.writer.parts
 
433
 
 
434
def publish_doctree(source, source_path=None,
428
435
                    source_class=io.StringInput,
 
436
                    reader=None, reader_name='standalone',
 
437
                    parser=None, parser_name='restructuredtext',
 
438
                    settings=None, settings_spec=None,
 
439
                    settings_overrides=None, config_section=None,
 
440
                    enable_exit_status=None):
 
441
    """
 
442
    Set up & run a `Publisher` for programmatic use with string I/O.
 
443
    Return the document tree.
 
444
 
 
445
    For encoded string input, be sure to set the 'input_encoding' setting to
 
446
    the desired encoding.  Set it to 'unicode' for unencoded Unicode string
 
447
    input.  Here's one way::
 
448
 
 
449
        publish_doctree(..., settings_overrides={'input_encoding': 'unicode'})
 
450
 
 
451
    Parameters: see `publish_programmatically`.
 
452
    """
 
453
    pub = Publisher(reader=reader, parser=parser, writer=None,
 
454
                    settings=settings,
 
455
                    source_class=source_class,
429
456
                    destination_class=io.NullOutput)
 
457
    pub.set_components(reader_name, parser_name, 'null')
 
458
    pub.process_programmatic_settings(
 
459
        settings_spec, settings_overrides, config_section)
 
460
    pub.set_source(source, source_path)
 
461
    pub.set_destination(None, None)
 
462
    output = pub.publish(enable_exit_status=enable_exit_status)
 
463
    return pub.document
 
464
 
 
465
def publish_from_doctree(document, destination_path=None,
 
466
                         writer=None, writer_name='pseudoxml',
 
467
                         settings=None, settings_spec=None,
 
468
                         settings_overrides=None, config_section=None,
 
469
                         enable_exit_status=None):
 
470
    """
 
471
    Set up & run a `Publisher` to render from an existing document tree data
 
472
    structure, for programmatic use with string I/O.  Return a pair of encoded
 
473
    string output and document parts.
 
474
 
 
475
    Note that document.settings is overridden; if you want to use the settings
 
476
    of the original `document`, pass settings=document.settings.
 
477
 
 
478
    Also, new document.transformer and document.reporter objects are
 
479
    generated.
 
480
 
 
481
    For encoded string output, be sure to set the 'output_encoding' setting to
 
482
    the desired encoding.  Set it to 'unicode' for unencoded Unicode string
 
483
    output.  Here's one way::
 
484
 
 
485
        publish_from_doctree(
 
486
            ..., settings_overrides={'output_encoding': 'unicode'})
 
487
 
 
488
    Parameters: `document` is a `docutils.nodes.document` object, an existing
 
489
    document tree.
 
490
 
 
491
    Other parameters: see `publish_programmatically`.
 
492
    """
 
493
    reader = docutils.readers.doctree.Reader(parser_name='null')
 
494
    pub = Publisher(reader, None, writer,
 
495
                    source=io.DocTreeInput(document),
 
496
                    destination_class=io.StringOutput, settings=settings)
 
497
    if not writer and writer_name:
 
498
        pub.set_writer(writer_name)
 
499
    pub.process_programmatic_settings(
 
500
        settings_spec, settings_overrides, config_section)
 
501
    pub.set_destination(None, destination_path)
 
502
    return pub.publish(enable_exit_status=enable_exit_status)
 
503
 
 
504
def publish_programmatically(source_class, source, source_path,
 
505
                             destination_class, destination, destination_path,
 
506
                             reader, reader_name,
 
507
                             parser, parser_name,
 
508
                             writer, writer_name,
 
509
                             settings, settings_spec,
 
510
                             settings_overrides, config_section,
 
511
                             enable_exit_status):
 
512
    """
 
513
    Set up & run a `Publisher` for custom programmatic use.  Return the
 
514
    encoded string output and the Publisher object.
 
515
 
 
516
    Applications should not need to call this function directly.  If it does
 
517
    seem to be necessary to call this function directly, please write to the
 
518
    Docutils-develop mailing list
 
519
    <http://docutils.sf.net/docs/user/mailing-lists.html#docutils-develop>.
 
520
 
 
521
    Parameters:
 
522
 
 
523
    * `source_class` **required**: The class for dynamically created source
 
524
      objects.  Typically `io.FileInput` or `io.StringInput`.
 
525
 
 
526
    * `source`: Type depends on `source_class`:
 
527
 
 
528
      - If `source_class` is `io.FileInput`: Either a file-like object
 
529
        (must have 'read' and 'close' methods), or ``None``
 
530
        (`source_path` is opened).  If neither `source` nor
 
531
        `source_path` are supplied, `sys.stdin` is used.
 
532
 
 
533
      - If `source_class` is `io.StringInput` **required**: The input
 
534
        string, either an encoded 8-bit string (set the
 
535
        'input_encoding' setting to the correct encoding) or a Unicode
 
536
        string (set the 'input_encoding' setting to 'unicode').
 
537
 
 
538
    * `source_path`: Type depends on `source_class`:
 
539
 
 
540
      - `io.FileInput`: Path to the input file, opened if no `source`
 
541
        supplied.
 
542
 
 
543
      - `io.StringInput`: Optional.  Path to the file or object that produced
 
544
        `source`.  Only used for diagnostic output.
 
545
 
 
546
    * `destination_class` **required**: The class for dynamically created
 
547
      destination objects.  Typically `io.FileOutput` or `io.StringOutput`.
 
548
 
 
549
    * `destination`: Type depends on `destination_class`:
 
550
 
 
551
      - `io.FileOutput`: Either a file-like object (must have 'write' and
 
552
        'close' methods), or ``None`` (`destination_path` is opened).  If
 
553
        neither `destination` nor `destination_path` are supplied,
 
554
        `sys.stdout` is used.
 
555
 
 
556
      - `io.StringOutput`: Not used; pass ``None``.
 
557
 
 
558
    * `destination_path`: Type depends on `destination_class`:
 
559
 
 
560
      - `io.FileOutput`: Path to the output file.  Opened if no `destination`
 
561
        supplied.
 
562
 
 
563
      - `io.StringOutput`: Path to the file or object which will receive the
 
564
        output; optional.  Used for determining relative paths (stylesheets,
 
565
        source links, etc.).
 
566
 
 
567
    * `reader`: A `docutils.readers.Reader` object.
 
568
 
 
569
    * `reader_name`: Name or alias of the Reader class to be instantiated if
 
570
      no `reader` supplied.
 
571
 
 
572
    * `parser`: A `docutils.parsers.Parser` object.
 
573
 
 
574
    * `parser_name`: Name or alias of the Parser class to be instantiated if
 
575
      no `parser` supplied.
 
576
 
 
577
    * `writer`: A `docutils.writers.Writer` object.
 
578
 
 
579
    * `writer_name`: Name or alias of the Writer class to be instantiated if
 
580
      no `writer` supplied.
 
581
 
 
582
    * `settings`: A runtime settings (`docutils.frontend.Values`) object, for
 
583
      dotted-attribute access to runtime settings.  It's the end result of the
 
584
      `SettingsSpec`, config file, and option processing.  If `settings` is
 
585
      passed, it's assumed to be complete and no further setting/config/option
 
586
      processing is done.
 
587
 
 
588
    * `settings_spec`: A `docutils.SettingsSpec` subclass or object.  Provides
 
589
      extra application-specific settings definitions independently of
 
590
      components.  In other words, the application becomes a component, and
 
591
      its settings data is processed along with that of the other components.
 
592
      Used only if no `settings` specified.
 
593
 
 
594
    * `settings_overrides`: A dictionary containing application-specific
 
595
      settings defaults that override the defaults of other components.
 
596
      Used only if no `settings` specified.
 
597
 
 
598
    * `config_section`: A string, the name of the configuration file section
 
599
      for this application.  Overrides the ``config_section`` attribute
 
600
      defined by `settings_spec`.  Used only if no `settings` specified.
 
601
 
 
602
    * `enable_exit_status`: Boolean; enable exit status at end of processing?
 
603
    """
 
604
    pub = Publisher(reader, parser, writer, settings=settings,
 
605
                    source_class=source_class,
 
606
                    destination_class=destination_class)
430
607
    pub.set_components(reader_name, parser_name, writer_name)
431
 
    if settings is None:
432
 
        settings = pub.get_settings(settings_spec=settings_spec,
433
 
                                    config_section=config_section)
434
 
    if settings_overrides:
435
 
        settings._update(settings_overrides, 'loose')
 
608
    pub.process_programmatic_settings(
 
609
        settings_spec, settings_overrides, config_section)
436
610
    pub.set_source(source, source_path)
437
 
    pub.set_destination(destination_path=destination_path)
438
 
    pub.publish(enable_exit=enable_exit)
439
 
    return pub.writer.parts
 
611
    pub.set_destination(destination, destination_path)
 
612
    output = pub.publish(enable_exit_status=enable_exit_status)
 
613
    return output, pub