first commit

This commit is contained in:
Yura 2024-09-15 15:12:16 +03:00
commit 417e54da96
5696 changed files with 900003 additions and 0 deletions

View file

@ -0,0 +1,291 @@
# $Id: __init__.py 9649 2024-04-23 18:54:26Z grubert $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This is the Docutils (Python Documentation Utilities) package.
Package Structure
=================
Modules:
- __init__.py: Contains component base classes, exception classes, and
Docutils version information.
- core.py: Contains the ``Publisher`` class and ``publish_*()`` convenience
functions.
- frontend.py: Runtime settings (command-line interface, configuration files)
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.
- statemachine.py: A finite state machine specialized for
regular-expression-based text filters.
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
the Docutils document tree.
- utils: Contains the ``Reporter`` system warning class and miscellaneous
utilities used by readers, writers, and transforms.
utils/urischemes.py: Contains a complete mapping of known URI addressing
scheme names to descriptions.
- utils/math: Contains functions for conversion of mathematical notation
between different formats (LaTeX, MathML, text, ...).
- writers: Format-specific output translators.
"""
from collections import namedtuple
__docformat__ = 'reStructuredText'
__version__ = '0.21.2'
"""Docutils version identifier (complies with PEP 440)::
major.minor[.micro][releaselevel[serial]][.dev]
For version comparison operations, use `__version_info__` (see, below)
rather than parsing the text of `__version__`.
https://docutils.sourceforge.io/docs/dev/policies.html#version-identification
"""
__version_details__ = ''
"""Optional extra version details (e.g. 'snapshot 2005-05-29, r3410').
For development and release status, use `__version__ and `__version_info__`.
"""
class VersionInfo(namedtuple('VersionInfo',
'major minor micro releaselevel serial release')):
def __new__(cls, major=0, minor=0, micro=0,
releaselevel='final', serial=0, release=True):
releaselevels = ('alpha', 'beta', 'candidate', 'final')
if releaselevel not in releaselevels:
raise ValueError('releaselevel must be one of %r.'
% (releaselevels, ))
if releaselevel == 'final':
if not release:
raise ValueError('releaselevel "final" must not be used '
'with development versions (leads to wrong '
'version ordering of the related __version__')
# cf. https://peps.python.org/pep-0440/#summary-of-permitted-suffixes-and-relative-ordering # noqa
if serial != 0:
raise ValueError('"serial" must be 0 for final releases')
return super().__new__(cls, major, minor, micro,
releaselevel, serial, release)
def __lt__(self, other):
if isinstance(other, tuple):
other = VersionInfo(*other)
return tuple.__lt__(self, other)
def __gt__(self, other):
if isinstance(other, tuple):
other = VersionInfo(*other)
return tuple.__gt__(self, other)
def __le__(self, other):
if isinstance(other, tuple):
other = VersionInfo(*other)
return tuple.__le__(self, other)
def __ge__(self, other):
if isinstance(other, tuple):
other = VersionInfo(*other)
return tuple.__ge__(self, other)
__version_info__ = VersionInfo(
major=0,
minor=21,
micro=2,
releaselevel='final', # one of 'alpha', 'beta', 'candidate', 'final'
serial=0, # pre-release number (0 for final releases and snapshots)
release=True # True for official releases and pre-releases
)
"""Comprehensive version information tuple.
https://docutils.sourceforge.io/docs/dev/policies.html#version-identification
"""
class ApplicationError(Exception): pass
class DataError(ApplicationError): pass
class SettingsSpec:
"""
Runtime setting specification base class.
SettingsSpec subclass objects used by `docutils.frontend.OptionParser`.
"""
# TODO: replace settings_specs with a new data structure
# Backwards compatiblity:
# Drop-in components:
# Sphinx supplies settings_spec in the current format in some places
# Myst parser provides a settings_spec tuple
#
# Sphinx reads a settings_spec in order to set a default value
# in writers/html.py:59
# https://github.com/sphinx-doc/sphinx/blob/4.x/sphinx/writers/html.py
# This should be changed (before retiring the old format)
# to use `settings_default_overrides` instead.
settings_spec = ()
"""Runtime settings specification. Override in subclasses.
Defines runtime settings and associated command-line options, as used by
`docutils.frontend.OptionParser`. This is a tuple of:
- Option group title (string or `None` which implies no group, just a list
of single options).
- Description (string or `None`).
- A sequence of option tuples. Each consists of:
- Help text (string)
- List of option strings (e.g. ``['-Q', '--quux']``).
- Dictionary of keyword arguments sent to the OptionParser/OptionGroup
``add_option`` method.
Runtime setting names are derived implicitly from long option names
('--a-setting' becomes ``settings.a_setting``) or explicitly from the
'dest' keyword argument.
Most settings will also have a 'validator' keyword & function. The
validator function validates setting values (from configuration files
and command-line option arguments) and converts them to appropriate
types. For example, the ``docutils.frontend.validate_boolean``
function, **required by all boolean settings**, converts true values
('1', 'on', 'yes', and 'true') to 1 and false values ('0', 'off',
'no', 'false', and '') to 0. Validators need only be set once per
setting. See the `docutils.frontend.validate_*` functions.
See the optparse docs for more details.
- More triples of group title, description, options, as many times as
needed. Thus, `settings_spec` tuples can be simply concatenated.
"""
settings_defaults = None
"""A dictionary of defaults for settings not in `settings_spec` (internal
settings, intended to be inaccessible by command-line and config file).
Override in subclasses."""
settings_default_overrides = None
"""A dictionary of auxiliary defaults, to override defaults for settings
defined in other components' `setting_specs`. 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."""
config_section = None
"""The name of the config file section specific to this component
(lowercase, no brackets). Override in subclasses."""
config_section_dependencies = None
"""A list of names of config file sections that are to be applied before
`config_section`, in order (from general to specific). In other words,
the settings in `config_section` are to be overlaid on top of the settings
from these sections. The "general" section is assumed implicitly.
Override in subclasses."""
class TransformSpec:
"""
Runtime transform specification base class.
Provides the interface to register "transforms" and helper functions
to resolve references with a `docutils.transforms.Transformer`.
https://docutils.sourceforge.io/docs/ref/transforms.html
"""
def get_transforms(self):
"""Transforms required by this class. Override in subclasses."""
if self.default_transforms != ():
import warnings
warnings.warn('TransformSpec: the "default_transforms" attribute '
'will be removed in Docutils 2.0.\n'
'Use get_transforms() method instead.',
DeprecationWarning)
return list(self.default_transforms)
return []
# Deprecated; for compatibility.
default_transforms = ()
unknown_reference_resolvers = ()
"""List of functions to try to resolve unknown references.
Unknown references have a 'refname' attribute which doesn't correspond
to any target in the document. Called when the transforms in
`docutils.transforms.references` are unable to find a correct target.
The list should contain functions which will try to resolve unknown
references, with the following signature::
def reference_resolver(node):
'''Returns boolean: true if resolved, false if not.'''
If the function is able to resolve the reference, it should also remove
the 'refname' attribute and mark the node as resolved::
del node['refname']
node.resolved = 1
Each function must have a "priority" attribute which will affect the order
the unknown_reference_resolvers are run::
reference_resolver.priority = 100
This hook is provided for 3rd party extensions.
Example use case: the `MoinMoin - ReStructured Text Parser`
in ``sandbox/mmgilbe/rst.py``.
"""
class Component(SettingsSpec, TransformSpec):
"""Base class for Docutils components."""
component_type = None
"""Name of the component type ('reader', 'parser', 'writer'). Override in
subclasses."""
supported = ()
"""Name and aliases 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

View file

@ -0,0 +1,96 @@
#!/usr/bin/env python3
# :Copyright: © 2020, 2022 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
#
# Revision: $Revision: 9107 $
# Date: $Date: 2022-07-06 15:59:57 +0200 (Mi, 06. Jul 2022) $
"""Generic command line interface for the `docutils` package.
See also
https://docs.python.org/3/library/__main__.html#main-py-in-python-packages
"""
import argparse
import locale
import sys
import docutils
from docutils.core import Publisher, publish_cmdline, default_description
class CliSettingsSpec(docutils.SettingsSpec):
"""Runtime settings & command-line options for the generic CLI.
Configurable reader, parser, and writer components.
The "--writer" default will change to 'html' in Docutils 2.0
when 'html' becomes an alias for the current value 'html5'.
"""
settings_spec = (
'Docutils Application Options',
'Reader, writer, and parser settings influence the available options. '
' Example: use `--help --writer=latex` to see LaTeX writer options. ',
# options: ('help text', [<option strings>], {<keyword arguments>})
(('Reader name (currently: "%default").',
['--reader'], {'default': 'standalone', 'metavar': '<reader>'}),
('Parser name (currently: "%default").',
['--parser'], {'default': 'rst', 'metavar': '<parser>'}),
('Writer name (currently: "%default").',
['--writer'], {'default': 'html5', 'metavar': '<writer>'}),
)
)
config_section = 'docutils application'
config_section_dependencies = ('docutils-cli application', # back-compat
'applications')
def main():
"""Generic command line interface for the Docutils Publisher.
"""
locale.setlocale(locale.LC_ALL, '')
description = ('Convert documents into useful formats. '
+ default_description)
# Update component selection from config file(s)
components = Publisher().get_settings(settings_spec=CliSettingsSpec)
# Update component selection from command-line
argparser = argparse.ArgumentParser(add_help=False, allow_abbrev=False)
argparser.add_argument('--reader', default=components.reader)
argparser.add_argument('--parser', default=components.parser)
argparser.add_argument('--writer', default=components.writer)
# other options are parsed in a second pass via `publish_cmdline()`
(args, remainder) = argparser.parse_known_args()
# Ensure the current component selections are shown in help:
CliSettingsSpec.settings_default_overrides = args.__dict__
try:
publish_cmdline(reader_name=args.reader,
parser_name=args.parser,
writer_name=args.writer,
settings_spec=CliSettingsSpec,
description=description,
argv=remainder)
except ImportError as error:
print('%s.' % error, file=sys.stderr)
if '--traceback' in remainder:
raise
else:
print('Use "--traceback" to show details.')
if __name__ == '__main__':
if sys.argv[0].endswith('__main__.py'):
# fix "usage" message
sys.argv[0] = '%s -m docutils' % sys.executable
main()

View file

@ -0,0 +1,780 @@
# $Id: core.py 9369 2023-05-02 23:04:27Z milde $
# Author: David Goodger <goodger@python.org>
# 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`. See `The Docutils Publisher`_.
.. _The Docutils Publisher:
https://docutils.sourceforge.io/docs/api/publisher.html
"""
__docformat__ = 'reStructuredText'
import locale
import pprint
import os
import sys
import warnings
from docutils import (__version__, __version_details__, SettingsSpec,
io, utils, readers, writers)
from docutils.frontend import OptionParser
from docutils.readers import doctree
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, ``set_components()`` or the corresponding ``set_...()``
method should be called with component names
(`set_reader` sets the parser as well).
"""
self.document = None
"""The document tree (`docutils.nodes` objects)."""
self.reader = reader
"""A `docutils.readers.Reader` instance."""
self.parser = parser
"""A `docutils.parsers.Parser` instance."""
self.writer = writer
"""A `docutils.writers.Writer` instance."""
for component in 'reader', 'parser', 'writer':
assert not isinstance(getattr(self, component), str), (
'passed string "%s" as "%s" parameter; pass an instance, '
'or use the "%s_name" parameter instead (in '
'docutils.core.publish_* convenience functions).'
% (getattr(self, component), component, component))
self.source = source
"""The source of input data, a `docutils.io.Input` instance."""
self.source_class = source_class
"""The class for dynamically created source objects."""
self.destination = destination
"""The destination for docutils output, a `docutils.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()`."""
self._stderr = io.ErrorOutput()
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, config_section=None,
**defaults):
warnings.warn('Publisher.setup_option_parser is deprecated, '
'and will be removed in Docutils 0.21.',
DeprecationWarning, stacklevel=2)
if config_section:
if not settings_spec:
settings_spec = SettingsSpec()
settings_spec.config_section = config_section
parts = config_section.split()
if len(parts) > 1 and parts[-1] == 'application':
settings_spec.config_section_dependencies = ['applications']
# @@@ Add self.source & self.destination to components in future?
return OptionParser(
components=(self.parser, self.reader, self.writer, settings_spec),
defaults=defaults, read_config_files=True,
usage=usage, description=description)
def _setup_settings_parser(self, *args, **kwargs):
# Provisional: will change (docutils.frontend.OptionParser will
# be replaced by a parser based on arparse.ArgumentParser)
# and may be removed later.
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
return self.setup_option_parser(*args, **kwargs)
def get_settings(self, usage=None, description=None,
settings_spec=None, config_section=None, **defaults):
"""
Return settings from components and config files.
Please set components first (`self.set_reader` & `self.set_writer`).
Use keyword arguments to override component defaults
(before updating from configuration files).
Calling this function also sets `self.settings` which makes
`self.publish()` skip parsing command line options.
"""
option_parser = self._setup_settings_parser(
usage, description, settings_spec, config_section, **defaults)
self.settings = option_parser.get_default_values()
return self.settings
def process_programmatic_settings(self, settings_spec,
settings_overrides,
config_section):
if self.settings is None:
defaults = settings_overrides.copy() if settings_overrides else {}
# Propagate exceptions by default when used programmatically:
defaults.setdefault('traceback', True)
self.get_settings(settings_spec=settings_spec,
config_section=config_section,
**defaults)
def process_command_line(self, argv=None, usage=None, description=None,
settings_spec=None, config_section=None,
**defaults):
"""
Parse command line arguments and set ``self.settings``.
Pass an empty sequence to `argv` to avoid reading `sys.argv`
(the default behaviour).
Set components first (`self.set_reader` & `self.set_writer`).
"""
option_parser = self._setup_settings_parser(
usage, description, settings_spec, config_section, **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,
error_handler=self.settings.input_encoding_error_handler)
def set_destination(self, destination=None, destination_path=None):
if destination_path is None:
if (self.settings.output and self.settings._destination
and self.settings.output != self.settings._destination):
raise SystemExit('The positional argument <destination> is '
'obsoleted by the --output option. '
'You cannot use them together.')
if self.settings.output == '-': # means stdout
self.settings.output = None
destination_path = (self.settings.output
or self.settings._destination)
self.settings._destination = destination_path
self.destination = self.destination_class(
destination=destination,
destination_path=destination_path,
encoding=self.settings.output_encoding,
error_handler=self.settings.output_encoding_error_handler)
def apply_transforms(self):
self.document.transformer.populate_from_components(
(self.source, self.reader, self.reader.parser, self.writer,
self.destination))
self.document.transformer.apply_transforms()
def publish(self, argv=None, usage=None, description=None,
settings_spec=None, settings_overrides=None,
config_section=None, enable_exit_status=False):
"""
Process command line options and arguments (if `self.settings` not
already set), run `self.reader` and then `self.writer`. Return
`self.writer`'s output.
"""
exit = None
try:
if self.settings is None:
self.process_command_line(
argv, usage, description, settings_spec, config_section,
**(settings_overrides or {}))
self.set_io()
self.prompt()
self.document = self.reader.read(self.source, self.parser,
self.settings)
self.apply_transforms()
output = self.writer.write(self.document, self.destination)
self.writer.assemble_parts()
except SystemExit as error:
exit = True
exit_status = error.code
except Exception as error:
if not self.settings: # exception too early to report nicely
raise
if self.settings.traceback: # Propagate exceptions?
self.debugging_dumps()
raise
self.report_Exception(error)
exit = True
exit_status = 1
self.debugging_dumps()
if (enable_exit_status and self.document
and (self.document.reporter.max_level
>= self.settings.exit_status_level)):
sys.exit(self.document.reporter.max_level + 10)
elif exit:
sys.exit(exit_status)
return output
def debugging_dumps(self):
if not self.document:
return
if self.settings.dump_settings:
print('\n::: Runtime settings:', file=self._stderr)
print(pprint.pformat(self.settings.__dict__), file=self._stderr)
if self.settings.dump_internals:
print('\n::: Document internals:', file=self._stderr)
print(pprint.pformat(self.document.__dict__), file=self._stderr)
if self.settings.dump_transforms:
print('\n::: Transforms applied:', file=self._stderr)
print(' (priority, transform class, pending node details, '
'keyword args)', file=self._stderr)
print(pprint.pformat(
[(priority, '%s.%s' % (xclass.__module__, xclass.__name__),
pending and pending.details, kwargs)
for priority, xclass, pending, kwargs
in self.document.transformer.applied]), file=self._stderr)
if self.settings.dump_pseudo_xml:
print('\n::: Pseudo-XML:', file=self._stderr)
print(self.document.pformat().encode(
'raw_unicode_escape'), file=self._stderr)
def prompt(self):
"""Print info and prompt when waiting for input from a terminal."""
try:
if not (self.source.isatty() and self._stderr.isatty()):
return
except AttributeError:
return
eot_key = 'Ctrl+Z' if os.name == 'nt' else 'Ctrl+D'
in_format = ''
out_format = 'useful formats'
try:
in_format = self.parser.supported[0]
out_format = self.writer.supported[0]
except (AttributeError, IndexError):
pass
print(f'Docutils {__version__} <https://docutils.sourceforge.io>\n'
f'converting "{in_format}" into "{out_format}".\n'
f'Call with option "--help" for more info.\n'
f'.. Waiting for source text (finish with {eot_key} '
'on an empty line):',
file=self._stderr)
def report_Exception(self, error):
if isinstance(error, utils.SystemMessage):
self.report_SystemMessage(error)
elif isinstance(error, UnicodeEncodeError):
self.report_UnicodeError(error)
elif isinstance(error, io.InputError):
self._stderr.write('Unable to open source file for reading:\n'
' %s\n' % io.error_string(error))
elif isinstance(error, io.OutputError):
self._stderr.write(
'Unable to open destination file for writing:\n'
' %s\n' % io.error_string(error))
else:
print('%s' % io.error_string(error), file=self._stderr)
print(f"""\
Exiting due to error. Use "--traceback" to diagnose.
Please report errors to <docutils-users@lists.sourceforge.net>.
Include "--traceback" output, Docutils version ({__version__}\
{f' [{__version_details__}]' if __version_details__ else ''}),
Python version ({sys.version.split()[0]}), your OS type & version, \
and the command line used.""", file=self._stderr)
def report_SystemMessage(self, error):
print('Exiting due to level-%s (%s) system message.' % (
error.level, utils.Reporter.levels[error.level]),
file=self._stderr)
def report_UnicodeError(self, error):
data = error.object[error.start:error.end]
self._stderr.write(
'%s\n'
'\n'
'The specified output encoding (%s) cannot\n'
'handle all of the output.\n'
'Try setting "--output-encoding-error-handler" to\n'
'\n'
'* "xmlcharrefreplace" (for HTML & XML output);\n'
' the output will contain "%s" and should be usable.\n'
'* "backslashreplace" (for other output formats);\n'
' look for "%s" in the output.\n'
'* "replace"; look for "?" in the output.\n'
'\n'
'"--output-encoding-error-handler" is currently set to "%s".\n'
'\n'
'Exiting due to error. Use "--traceback" to diagnose.\n'
'If the advice above doesn\'t eliminate the error,\n'
'please report it to <docutils-users@lists.sourceforge.net>.\n'
'Include "--traceback" output, Docutils version (%s),\n'
'Python version (%s), your OS type & version, and the\n'
'command line used.\n'
% (io.error_string(error),
self.settings.output_encoding,
data.encode('ascii', 'xmlcharrefreplace'),
data.encode('ascii', 'backslashreplace'),
self.settings.output_encoding_error_handler,
__version__, sys.version.split()[0]))
default_usage = '%prog [options] [<source> [<destination>]]'
default_description = (
'Reads from <source> (default is stdin) '
'and writes to <destination> (default is stdout). '
'See https://docutils.sourceforge.io/docs/user/config.html '
'for a detailed settings reference.')
# TODO: or not to do? cf. https://clig.dev/#help
#
# Display output on success, but keep it brief.
# Provide a -q option to suppress all non-essential output.
#
# Chain several args as input and use --output or redirection for output:
# argparser.add_argument('source', nargs='+')
#
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, config_section=None,
enable_exit_status=True, argv=None,
usage=default_usage, description=default_description):
"""
Set up & run a `Publisher` for command-line-based file I/O (input and
output file paths taken automatically from the command line).
Also return the output as `str` or `bytes` (for binary output document
formats).
Parameters: see `publish_programmatically()` for the remainder.
- `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).
"""
publisher = Publisher(reader, parser, writer, settings=settings)
publisher.set_components(reader_name, parser_name, writer_name)
output = publisher.publish(
argv, usage, description, settings_spec, settings_overrides,
config_section=config_section, enable_exit_status=enable_exit_status)
return output
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,
config_section=None, enable_exit_status=False):
"""
Set up & run a `Publisher` for programmatic use with file-like I/O.
Also return the output as `str` or `bytes` (for binary output document
formats).
Parameters: see `publish_programmatically()`.
"""
output, publisher = publish_programmatically(
source_class=io.FileInput, source=source, source_path=source_path,
destination_class=io.FileOutput,
destination=destination, destination_path=destination_path,
reader=reader, reader_name=reader_name,
parser=parser, parser_name=parser_name,
writer=writer, writer_name=writer_name,
settings=settings, settings_spec=settings_spec,
settings_overrides=settings_overrides,
config_section=config_section,
enable_exit_status=enable_exit_status)
return output
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, config_section=None,
enable_exit_status=False):
"""
Set up & run a `Publisher` for programmatic use with string I/O.
Accepts a `bytes` or `str` instance as `source`.
The output is encoded according to the `output_encoding`_ setting;
the return value is a `bytes` instance (unless `output_encoding`_ is
"unicode", cf. `docutils.io.StringOutput.write()`).
Parameters: see `publish_programmatically()`.
This function is provisional because in Python 3 name and behaviour
no longer match.
.. _output_encoding:
https://docutils.sourceforge.io/docs/user/config.html#output-encoding
"""
output, publisher = publish_programmatically(
source_class=io.StringInput, source=source, source_path=source_path,
destination_class=io.StringOutput,
destination=None, destination_path=destination_path,
reader=reader, reader_name=reader_name,
parser=parser, parser_name=parser_name,
writer=writer, writer_name=writer_name,
settings=settings, settings_spec=settings_spec,
settings_overrides=settings_overrides,
config_section=config_section,
enable_exit_status=enable_exit_status)
return output
def publish_parts(source, source_path=None, source_class=io.StringInput,
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, config_section=None,
enable_exit_status=False):
"""
Set up & run a `Publisher`, and return a dictionary of document parts.
Dictionary keys are the names of parts.
Dictionary values are `str` instances; encoding is up to the client,
e.g.::
parts = publish_parts(...)
body = parts['body'].encode(parts['encoding'], parts['errors'])
See the `API documentation`__ for details on the provided parts.
Parameters: see `publish_programmatically()`.
__ https://docutils.sourceforge.io/docs/api/publisher.html#publish-parts
"""
output, publisher = publish_programmatically(
source=source, source_path=source_path, source_class=source_class,
destination_class=io.StringOutput,
destination=None, destination_path=destination_path,
reader=reader, reader_name=reader_name,
parser=parser, parser_name=parser_name,
writer=writer, writer_name=writer_name,
settings=settings, settings_spec=settings_spec,
settings_overrides=settings_overrides,
config_section=config_section,
enable_exit_status=enable_exit_status)
return publisher.writer.parts
def publish_doctree(source, source_path=None,
source_class=io.StringInput,
reader=None, reader_name='standalone',
parser=None, parser_name='restructuredtext',
settings=None, settings_spec=None,
settings_overrides=None, config_section=None,
enable_exit_status=False):
"""
Set up & run a `Publisher` for programmatic use. Return a document tree.
Parameters: see `publish_programmatically()`.
"""
_output, publisher = publish_programmatically(
source=source, source_path=source_path,
source_class=source_class,
destination=None, destination_path=None,
destination_class=io.NullOutput,
reader=reader, reader_name=reader_name,
parser=parser, parser_name=parser_name,
writer=None, writer_name='null',
settings=settings, settings_spec=settings_spec,
settings_overrides=settings_overrides, config_section=config_section,
enable_exit_status=enable_exit_status)
return publisher.document
def publish_from_doctree(document, destination_path=None,
writer=None, writer_name='pseudoxml',
settings=None, settings_spec=None,
settings_overrides=None, config_section=None,
enable_exit_status=False):
"""
Set up & run a `Publisher` to render from an existing document tree
data structure. For programmatic use with string output
(`bytes` or `str`, cf. `publish_string()`).
Note that ``document.settings`` is overridden; if you want to use the
settings of the original `document`, pass ``settings=document.settings``.
Also, new `document.transformer` and `document.reporter` objects are
generated.
Parameters: `document` is a `docutils.nodes.document` object, an existing
document tree.
Other parameters: see `publish_programmatically()`.
This function is provisional because in Python 3 name and behaviour
of the `io.StringOutput` class no longer match.
"""
reader = doctree.Reader(parser_name='null')
publisher = Publisher(reader, None, writer,
source=io.DocTreeInput(document),
destination_class=io.StringOutput,
settings=settings)
if not writer and writer_name:
publisher.set_writer(writer_name)
publisher.process_programmatic_settings(
settings_spec, settings_overrides, config_section)
publisher.set_destination(None, destination_path)
return publisher.publish(enable_exit_status=enable_exit_status)
def publish_cmdline_to_binary(reader=None, reader_name='standalone',
parser=None, parser_name='restructuredtext',
writer=None, writer_name='pseudoxml',
settings=None,
settings_spec=None,
settings_overrides=None,
config_section=None,
enable_exit_status=True,
argv=None,
usage=default_usage,
description=default_description,
destination=None,
destination_class=io.BinaryFileOutput):
"""
Set up & run a `Publisher` for command-line-based file I/O (input and
output file paths taken automatically from the command line).
Also return the output as `bytes`.
This is just like publish_cmdline, except that it uses
io.BinaryFileOutput instead of io.FileOutput.
Parameters: see `publish_programmatically()` for the remainder.
- `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).
"""
publisher = Publisher(reader, parser, writer, settings=settings,
destination_class=destination_class)
publisher.set_components(reader_name, parser_name, writer_name)
output = publisher.publish(
argv, usage, description, settings_spec, settings_overrides,
config_section=config_section, enable_exit_status=enable_exit_status)
return output
def publish_programmatically(source_class, source, source_path,
destination_class, destination, destination_path,
reader, reader_name,
parser, parser_name,
writer, writer_name,
settings, settings_spec,
settings_overrides, config_section,
enable_exit_status):
"""
Set up & run a `Publisher` for custom programmatic use.
Return the output (as `str` or `bytes`, depending on `destination_class`,
writer, and the "output_encoding" setting) and the Publisher object.
Applications should not need to call this function directly. If it does
seem to be necessary to call this function directly, please write to the
Docutils-develop mailing list
<https://docutils.sourceforge.io/docs/user/mailing-lists.html#docutils-develop>.
Parameters:
* `source_class` **required**: The class for dynamically created source
objects. Typically `io.FileInput` or `io.StringInput`.
* `source`: Type depends on `source_class`:
- If `source_class` is `io.FileInput`: Either a file-like object
(must have 'read' and 'close' methods), or ``None``
(`source_path` is opened). If neither `source` nor
`source_path` are supplied, `sys.stdin` is used.
- If `source_class` is `io.StringInput` **required**:
The input as either a `bytes` object (ensure the 'input_encoding'
setting matches its encoding) or a `str` object.
* `source_path`: Type depends on `source_class`:
- `io.FileInput`: Path to the input file, opened if no `source`
supplied.
- `io.StringInput`: Optional. Path to the file or name of the
object that produced `source`. Only used for diagnostic output.
* `destination_class` **required**: The class for dynamically created
destination objects. Typically `io.FileOutput` or `io.StringOutput`.
* `destination`: Type depends on `destination_class`:
- `io.FileOutput`: Either a file-like object (must have 'write' and
'close' methods), or ``None`` (`destination_path` is opened). If
neither `destination` nor `destination_path` are supplied,
`sys.stdout` is used.
- `io.StringOutput`: Not used; pass ``None``.
* `destination_path`: Type depends on `destination_class`:
- `io.FileOutput`: Path to the output file. Opened if no `destination`
supplied.
- `io.StringOutput`: 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`: A runtime settings (`docutils.frontend.Values`) object, for
dotted-attribute access to runtime settings. It's the end result of the
`SettingsSpec`, config file, and option processing. If `settings` is
passed, it's assumed to be complete and no further setting/config/option
processing is done.
* `settings_spec`: A `docutils.SettingsSpec` subclass or object. Provides
extra application-specific settings definitions independently of
components. In other words, the application becomes a component, and
its settings data is processed along with that of the other components.
Used only if no `settings` specified.
* `settings_overrides`: A dictionary containing application-specific
settings defaults that override the defaults of other components.
Used only if no `settings` specified.
* `config_section`: A string, the name of the configuration file section
for this application. Overrides the ``config_section`` attribute
defined by `settings_spec`. Used only if no `settings` specified.
* `enable_exit_status`: Boolean; enable exit status at end of processing?
"""
publisher = Publisher(reader, parser, writer, settings=settings,
source_class=source_class,
destination_class=destination_class)
publisher.set_components(reader_name, parser_name, writer_name)
publisher.process_programmatic_settings(
settings_spec, settings_overrides, config_section)
publisher.set_source(source, source_path)
publisher.set_destination(destination, destination_path)
output = publisher.publish(enable_exit_status=enable_exit_status)
return output, publisher
# "Entry points" with functionality of the "tools/rst2*.py" scripts
# cf. https://packaging.python.org/en/latest/specifications/entry-points/
def rst2something(writer, documenttype, doc_path=''):
# Helper function for the common parts of rst2...
# writer: writer name
# documenttype: output document type
# doc_path: documentation path (relative to the documentation root)
description = (
f'Generate {documenttype} documents '
'from standalone reStructuredText sources '
f'<https://docutils.sourceforge.io/docs/{doc_path}>. '
+ default_description)
locale.setlocale(locale.LC_ALL, '')
publish_cmdline(writer_name=writer, description=description)
def rst2html():
rst2something('html', 'HTML', 'user/html.html#html')
def rst2html4():
rst2something('html4', 'XHTML 1.1', 'user/html.html#html4css1')
def rst2html5():
rst2something('html5', 'HTML5', 'user/html.html#html5-polyglot')
def rst2latex():
rst2something('latex', 'LaTeX', 'user/latex.html')
def rst2man():
rst2something('manpage', 'Unix manual (troff)', 'user/manpage.html')
def rst2odt():
rst2something('odt', 'OpenDocument text (ODT)', 'user/odt.html')
def rst2pseudoxml():
rst2something('pseudoxml', 'pseudo-XML (test)', 'ref/doctree.html')
def rst2s5():
rst2something('s5', 'S5 HTML slideshow', 'user/slide-shows.html')
def rst2xetex():
rst2something('xetex', 'LaTeX (XeLaTeX/LuaLaTeX)', 'user/latex.html')
def rst2xml():
rst2something('xml', 'Docutils-native XML', 'ref/doctree.html')

View file

@ -0,0 +1,5 @@
# This configuration file is to prevent tools/buildhtml.py from
# processing text files in and below this directory.
[buildhtml application]
prune: .

View file

@ -0,0 +1,99 @@
# $Id: examples.py 9026 2022-03-04 15:57:13Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This module contains practical examples of Docutils client code.
Importing this module from client code is not recommended; its contents are
subject to change in future Docutils releases. Instead, it is recommended
that you copy and paste the parts you need into your own code, modifying as
necessary.
"""
from docutils import core, io
def html_parts(input_string, source_path=None, destination_path=None,
input_encoding='unicode', doctitle=True,
initial_header_level=1):
"""
Given an input string, returns a dictionary of HTML document parts.
Dictionary keys are the names of parts, and values are Unicode strings;
encoding is up to the client.
Parameters:
- `input_string`: A multi-line text string; required.
- `source_path`: Path to the source file or object. Optional, but useful
for diagnostic output (system messages).
- `destination_path`: Path to the file or object which will receive the
output; optional. Used for determining relative paths (stylesheets,
source links, etc.).
- `input_encoding`: The encoding of `input_string`. If it is an encoded
8-bit string, provide the correct encoding. If it is a Unicode string,
use "unicode", the default.
- `doctitle`: Disable the promotion of a lone top-level section title to
document title (and subsequent section title to document subtitle
promotion); enabled by default.
- `initial_header_level`: The initial level for header elements (e.g. 1
for "<h1>").
"""
overrides = {'input_encoding': input_encoding,
'doctitle_xform': doctitle,
'initial_header_level': initial_header_level}
parts = core.publish_parts(
source=input_string, source_path=source_path,
destination_path=destination_path,
writer_name='html', settings_overrides=overrides)
return parts
def html_body(input_string, source_path=None, destination_path=None,
input_encoding='unicode', output_encoding='unicode',
doctitle=True, initial_header_level=1):
"""
Given an input string, returns an HTML fragment as a string.
The return value is the contents of the <body> element.
Parameters (see `html_parts()` for the remainder):
- `output_encoding`: The desired encoding of the output. If a Unicode
string is desired, use the default value of "unicode" .
"""
parts = html_parts(
input_string=input_string, source_path=source_path,
destination_path=destination_path,
input_encoding=input_encoding, doctitle=doctitle,
initial_header_level=initial_header_level)
fragment = parts['html_body']
if output_encoding != 'unicode':
fragment = fragment.encode(output_encoding)
return fragment
def internals(input_string, source_path=None, destination_path=None,
input_encoding='unicode', settings_overrides=None):
"""
Return the document tree and publisher, for exploring Docutils internals.
Parameters: see `html_parts()`.
"""
if settings_overrides:
overrides = settings_overrides.copy()
else:
overrides = {}
overrides['input_encoding'] = input_encoding
output, pub = core.publish_programmatically(
source_class=io.StringInput, source=input_string,
source_path=source_path,
destination_class=io.NullOutput, destination=None,
destination_path=destination_path,
reader=None, reader_name='standalone',
parser=None, parser_name='restructuredtext',
writer=None, writer_name='null',
settings=None, settings_spec=None, settings_overrides=overrides,
config_section=None, enable_exit_status=None)
return pub.writer.document, pub

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,637 @@
# $Id: io.py 9427 2023-07-07 06:50:09Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
I/O classes provide a uniform API for low-level input and output. Subclasses
exist for a variety of input/output mechanisms.
"""
__docformat__ = 'reStructuredText'
import codecs
import locale
import os
import re
import sys
import warnings
from docutils import TransformSpec
# Guess the locale's preferred encoding.
# If no valid guess can be made, _locale_encoding is set to `None`:
#
# TODO: check whether this is set correctly with every OS and Python version
# or whether front-end tools need to call `locale.setlocale()`
# before importing this module
try:
# Return locale encoding also in UTF-8 mode
with warnings.catch_warnings():
warnings.simplefilter("ignore")
_locale_encoding = (locale.getlocale()[1]
or locale.getdefaultlocale()[1])
_locale_encoding = _locale_encoding.lower()
except: # noqa any other problems determining the locale -> use None
_locale_encoding = None
try:
codecs.lookup(_locale_encoding)
except (LookupError, TypeError):
_locale_encoding = None
class InputError(OSError): pass
class OutputError(OSError): pass
def check_encoding(stream, encoding):
"""Test, whether the encoding of `stream` matches `encoding`.
Returns
:None: if `encoding` or `stream.encoding` are not a valid encoding
argument (e.g. ``None``) or `stream.encoding is missing.
:True: if the encoding argument resolves to the same value as `encoding`,
:False: if the encodings differ.
"""
try:
return codecs.lookup(stream.encoding) == codecs.lookup(encoding)
except (LookupError, AttributeError, TypeError):
return None
def error_string(err):
"""Return string representation of Exception `err`.
"""
return f'{err.__class__.__name__}: {err}'
class Input(TransformSpec):
"""
Abstract base class for input wrappers.
Docutils input objects must provide a `read()` method that
returns the source, typically as `str` instance.
Inheriting `TransformSpec` allows input objects to add
"transforms" and "unknown_reference_resolvers" to the "Transformer".
(Optional for custom input objects since Docutils 0.19.)
"""
component_type = 'input'
default_source_path = None
def __init__(self, source=None, source_path=None, encoding=None,
error_handler='strict'):
self.encoding = encoding
"""Text encoding for the input source."""
self.error_handler = error_handler
"""Text decoding error handler."""
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
self.successful_encoding = None
"""The encoding that successfully decoded the source data."""
def __repr__(self):
return '%s: source=%r, source_path=%r' % (self.__class__, self.source,
self.source_path)
def read(self):
"""Return input as `str`. Define in subclasses."""
raise NotImplementedError
def decode(self, data):
"""
Decode `data` if required.
Return Unicode `str` instances unchanged (nothing to decode).
If `self.encoding` is None, determine encoding from data
or try UTF-8 and the locale's preferred encoding.
The client application should call ``locale.setlocale()`` at the
beginning of processing::
locale.setlocale(locale.LC_ALL, '')
Raise UnicodeError if unsuccessful.
Provisional: encoding detection will be removed in Docutils 1.0.
"""
if self.encoding and self.encoding.lower() == 'unicode':
assert isinstance(data, str), ('input encoding is "unicode" '
'but `data` is no `str` instance')
if isinstance(data, str):
# nothing to decode
return data
if self.encoding:
# We believe the user/application when the encoding is
# explicitly given.
encoding_candidates = [self.encoding]
else:
data_encoding = self.determine_encoding_from_data(data)
if data_encoding:
# `data` declares its encoding with "magic comment" or BOM,
encoding_candidates = [data_encoding]
else:
# Apply heuristics if the encoding is not specified.
# Start with UTF-8, because that only matches
# data that *IS* UTF-8:
encoding_candidates = ['utf-8']
# If UTF-8 fails, fall back to the locale's preferred encoding:
fallback = locale.getpreferredencoding(do_setlocale=False)
if fallback and fallback.lower() != 'utf-8':
encoding_candidates.append(fallback)
for enc in encoding_candidates:
try:
decoded = str(data, enc, self.error_handler)
self.successful_encoding = enc
return decoded
except (UnicodeError, LookupError) as err:
# keep exception instance for use outside of the "for" loop.
error = err
raise UnicodeError(
'Unable to decode input data. Tried the following encodings: '
f'{", ".join(repr(enc) for enc in encoding_candidates)}.\n'
f'({error_string(error)})')
coding_slug = re.compile(br"coding[:=]\s*([-\w.]+)")
"""Encoding declaration pattern."""
byte_order_marks = ((codecs.BOM_UTF32_BE, 'utf-32'),
(codecs.BOM_UTF32_LE, 'utf-32'),
(codecs.BOM_UTF8, 'utf-8-sig'),
(codecs.BOM_UTF16_BE, 'utf-16'),
(codecs.BOM_UTF16_LE, 'utf-16'),
)
"""Sequence of (start_bytes, encoding) tuples for encoding detection.
The first bytes of input data are checked against the start_bytes strings.
A match indicates the given encoding."""
def determine_encoding_from_data(self, data):
"""
Try to determine the encoding of `data` by looking *in* `data`.
Check for a byte order mark (BOM) or an encoding declaration.
"""
# check for a byte order mark:
for start_bytes, encoding in self.byte_order_marks:
if data.startswith(start_bytes):
return encoding
# check for an encoding declaration pattern in first 2 lines of file:
for line in data.splitlines()[:2]:
match = self.coding_slug.search(line)
if match:
return match.group(1).decode('ascii')
return None
def isatty(self):
"""Return True, if the input source is connected to a TTY device."""
try:
return self.source.isatty()
except AttributeError:
return False
class Output(TransformSpec):
"""
Abstract base class for output wrappers.
Docutils output objects must provide a `write()` method that
expects and handles one argument (the output).
Inheriting `TransformSpec` allows output objects to add
"transforms" and "unknown_reference_resolvers" to the "Transformer".
(Optional for custom output objects since Docutils 0.19.)
"""
component_type = 'output'
default_destination_path = None
def __init__(self, destination=None, destination_path=None,
encoding=None, error_handler='strict'):
self.encoding = encoding
"""Text encoding for the output destination."""
self.error_handler = error_handler or 'strict'
"""Text encoding error handler."""
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):
"""Write `data`. Define in subclasses."""
raise NotImplementedError
def encode(self, data):
"""
Encode and return `data`.
If `data` is a `bytes` instance, it is returned unchanged.
Otherwise it is encoded with `self.encoding`.
Provisional: If `self.encoding` is set to the pseudo encoding name
"unicode", `data` must be a `str` instance and is returned unchanged.
"""
if self.encoding and self.encoding.lower() == 'unicode':
assert isinstance(data, str), ('output encoding is "unicode" '
'but `data` is no `str` instance')
return data
if not isinstance(data, str):
# Non-unicode (e.g. bytes) output.
return data
else:
return data.encode(self.encoding, self.error_handler)
class ErrorOutput:
"""
Wrapper class for file-like error streams with
failsafe de- and encoding of `str`, `bytes`, `unicode` and
`Exception` instances.
"""
def __init__(self, destination=None, encoding=None,
encoding_errors='backslashreplace',
decoding_errors='replace'):
"""
:Parameters:
- `destination`: a file-like object,
a string (path to a file),
`None` (write to `sys.stderr`, default), or
evaluating to `False` (write() requests are ignored).
- `encoding`: `destination` text encoding. Guessed if None.
- `encoding_errors`: how to treat encoding errors.
"""
if destination is None:
destination = sys.stderr
elif not destination:
destination = False
# if `destination` is a file name, open it
elif isinstance(destination, str):
destination = open(destination, 'w')
self.destination = destination
"""Where warning output is sent."""
self.encoding = (encoding or getattr(destination, 'encoding', None)
or _locale_encoding or 'ascii')
"""The output character encoding."""
self.encoding_errors = encoding_errors
"""Encoding error handler."""
self.decoding_errors = decoding_errors
"""Decoding error handler."""
def write(self, data):
"""
Write `data` to self.destination. Ignore, if self.destination is False.
`data` can be a `bytes`, `str`, or `Exception` instance.
"""
if not self.destination:
return
if isinstance(data, Exception):
data = str(data)
try:
self.destination.write(data)
except UnicodeEncodeError:
self.destination.write(data.encode(self.encoding,
self.encoding_errors))
except TypeError:
if isinstance(data, str): # destination may expect bytes
self.destination.write(data.encode(self.encoding,
self.encoding_errors))
elif self.destination in (sys.stderr, sys.stdout):
# write bytes to raw stream
self.destination.buffer.write(data)
else:
self.destination.write(str(data, self.encoding,
self.decoding_errors))
def close(self):
"""
Close the error-output stream.
Ignored if the destination is` sys.stderr` or `sys.stdout` or has no
close() method.
"""
if self.destination in (sys.stdout, sys.stderr):
return
try:
self.destination.close()
except AttributeError:
pass
def isatty(self):
"""Return True, if the destination is connected to a TTY device."""
try:
return self.destination.isatty()
except AttributeError:
return False
class FileInput(Input):
"""
Input for single, simple file-like objects.
"""
def __init__(self, source=None, source_path=None,
encoding=None, error_handler='strict',
autoclose=True, mode='r'):
"""
: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 for reading.
- `encoding`: the expected text encoding of the input file.
- `error_handler`: the encoding error handler to use.
- `autoclose`: close automatically after read (except when
`sys.stdin` is the source).
- `mode`: how the file is to be opened (see standard function
`open`). The default is read only ('r').
"""
Input.__init__(self, source, source_path, encoding, error_handler)
self.autoclose = autoclose
self._stderr = ErrorOutput()
if source is None:
if source_path:
try:
self.source = open(source_path, mode,
encoding=self.encoding,
errors=self.error_handler)
except OSError as error:
raise InputError(error.errno, error.strerror, source_path)
else:
self.source = sys.stdin
elif check_encoding(self.source, self.encoding) is False:
# TODO: re-open, warn or raise error?
raise UnicodeError('Encoding clash: encoding given is "%s" '
'but source is opened with encoding "%s".' %
(self.encoding, self.source.encoding))
if not source_path:
try:
self.source_path = self.source.name
except AttributeError:
pass
def read(self):
"""
Read and decode a single file, return as `str`.
"""
try:
if not self.encoding and hasattr(self.source, 'buffer'):
# read as binary data
data = self.source.buffer.read()
# decode with heuristics
data = self.decode(data)
# normalize newlines
data = '\n'.join(data.splitlines()+[''])
else:
data = self.source.read()
finally:
if self.autoclose:
self.close()
return data
def readlines(self):
"""
Return lines of a single file as list of strings.
"""
return self.read().splitlines(True)
def close(self):
if self.source is not sys.stdin:
self.source.close()
class FileOutput(Output):
"""Output for single, simple file-like objects."""
default_destination_path = '<file>'
mode = 'w'
"""The mode argument for `open()`."""
# 'wb' for binary (e.g. OpenOffice) files (see also `BinaryFileOutput`).
# (Do not use binary mode ('wb') for text files, as this prevents the
# conversion of newlines to the system specific default.)
def __init__(self, destination=None, destination_path=None,
encoding=None, error_handler='strict', autoclose=True,
handle_io_errors=None, mode=None):
"""
: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.
- `encoding`: the text encoding of the output file.
- `error_handler`: the encoding error handler to use.
- `autoclose`: close automatically after write (except when
`sys.stdout` or `sys.stderr` is the destination).
- `handle_io_errors`: ignored, deprecated, will be removed.
- `mode`: how the file is to be opened (see standard function
`open`). The default is 'w', providing universal newline
support for text files.
"""
Output.__init__(self, destination, destination_path,
encoding, error_handler)
self.opened = True
self.autoclose = autoclose
if handle_io_errors is not None:
warnings.warn('io.FileOutput: init argument "handle_io_errors" '
'is ignored and will be removed in '
'Docutils 2.0.', DeprecationWarning, stacklevel=2)
if mode is not None:
self.mode = mode
self._stderr = ErrorOutput()
if destination is None:
if destination_path:
self.opened = False
else:
self.destination = sys.stdout
elif ( # destination is file-type object -> check mode:
mode and hasattr(self.destination, 'mode')
and mode != self.destination.mode):
print('Warning: Destination mode "%s" differs from specified '
'mode "%s"' % (self.destination.mode, mode),
file=self._stderr)
if not destination_path:
try:
self.destination_path = self.destination.name
except AttributeError:
pass
def open(self):
# Specify encoding
if 'b' not in self.mode:
kwargs = {'encoding': self.encoding,
'errors': self.error_handler}
else:
kwargs = {}
try:
self.destination = open(self.destination_path, self.mode, **kwargs)
except OSError as error:
raise OutputError(error.errno, error.strerror,
self.destination_path)
self.opened = True
def write(self, data):
"""Write `data` to a single file, also return it.
`data` can be a `str` or `bytes` instance.
If writing `bytes` fails, an attempt is made to write to
the low-level interface ``self.destination.buffer``.
If `data` is a `str` instance and `self.encoding` and
`self.destination.encoding` are set to different values, `data`
is encoded to a `bytes` instance using `self.encoding`.
Provisional: future versions may raise an error if `self.encoding`
and `self.destination.encoding` are set to different values.
"""
if not self.opened:
self.open()
if (isinstance(data, str)
and check_encoding(self.destination, self.encoding) is False):
if os.linesep != '\n':
data = data.replace('\n', os.linesep) # fix endings
data = self.encode(data)
try:
self.destination.write(data)
except TypeError as err:
if isinstance(data, bytes):
try:
self.destination.buffer.write(data)
except AttributeError:
if check_encoding(self.destination,
self.encoding) is False:
raise ValueError(
f'Encoding of {self.destination_path} '
f'({self.destination.encoding}) differs \n'
f' from specified encoding ({self.encoding})')
else:
raise err
except (UnicodeError, LookupError) as err:
raise UnicodeError(
'Unable to encode output data. output-encoding is: '
f'{self.encoding}.\n({error_string(err)})')
finally:
if self.autoclose:
self.close()
return data
def close(self):
if self.destination not in (sys.stdout, sys.stderr):
self.destination.close()
self.opened = False
class BinaryFileOutput(FileOutput):
"""
A version of docutils.io.FileOutput which writes to a binary file.
"""
# Used by core.publish_cmdline_to_binary() which in turn is used by
# tools/rst2odt.py but not by core.rst2odt().
mode = 'wb'
class StringInput(Input):
"""Input from a `str` or `bytes` instance."""
default_source_path = '<string>'
def read(self):
"""Return the source as `str` instance.
Decode, if required (see `Input.decode`).
"""
return self.decode(self.source)
class StringOutput(Output):
"""Output to a `bytes` or `str` instance.
Provisional.
"""
default_destination_path = '<string>'
def write(self, data):
"""Store `data` in `self.destination`, and return it.
If `self.encoding` is set to the pseudo encoding name "unicode",
`data` must be a `str` instance and is stored/returned unchanged
(cf. `Output.encode`).
Otherwise, `data` can be a `bytes` or `str` instance and is
stored/returned as a `bytes` instance
(`str` data is encoded with `self.encode()`).
Attention: the `output_encoding`_ setting may affect the content
of the output (e.g. an encoding declaration in HTML or XML or the
representation of characters as LaTeX macro vs. literal character).
"""
self.destination = self.encode(data)
return self.destination
class NullInput(Input):
"""Degenerate input: read nothing."""
default_source_path = 'null input'
def read(self):
"""Return an empty string."""
return ''
class NullOutput(Output):
"""Degenerate output: write nothing."""
default_destination_path = 'null output'
def write(self, data):
"""Do nothing, return None."""
pass
class DocTreeInput(Input):
"""
Adapter for document tree input.
The document tree must be passed in the ``source`` parameter.
"""
default_source_path = 'doctree input'
def read(self):
"""Return the document tree."""
return self.source

View file

@ -0,0 +1,83 @@
# $Id: __init__.py 9030 2022-03-05 23:28:32Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
# Internationalization details are documented in
# <https://docutils.sourceforge.io/docs/howto/i18n.html>.
"""
This package contains modules for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
from importlib import import_module
from docutils.utils import normalize_language_tag
class LanguageImporter:
"""Import language modules.
When called with a BCP 47 language tag, instances return a module
with localisations from `docutils.languages` or the PYTHONPATH.
If there is no matching module, warn (if a `reporter` is passed)
and fall back to English.
"""
packages = ('docutils.languages.', '')
warn_msg = ('Language "%s" not supported: '
'Docutils-generated text will be in English.')
fallback = 'en'
# TODO: use a dummy module returning empty strings?, configurable?
def __init__(self):
self.cache = {}
def import_from_packages(self, name, reporter=None):
"""Try loading module `name` from `self.packages`."""
module = None
for package in self.packages:
try:
module = import_module(package+name)
self.check_content(module)
except (ImportError, AttributeError):
if reporter and module:
reporter.info(f'{module} is no complete '
'Docutils language module.')
elif reporter:
reporter.info(f'Module "{package+name}" not found.')
continue
break
return module
def check_content(self, module):
"""Check if we got a Docutils language module."""
if not (isinstance(module.labels, dict)
and isinstance(module.bibliographic_fields, dict)
and isinstance(module.author_separators, list)):
raise ImportError
def __call__(self, language_code, reporter=None):
try:
return self.cache[language_code]
except KeyError:
pass
for tag in normalize_language_tag(language_code):
tag = tag.replace('-', '_') # '-' not valid in module names
module = self.import_from_packages(tag, reporter)
if module is not None:
break
else:
if reporter:
reporter.warning(self.warn_msg % language_code)
if self.fallback:
module = self.import_from_packages(self.fallback)
if reporter and (language_code != 'en'):
reporter.info('Using %s for language "%s".'
% (module, language_code))
self.cache[language_code] = module
return module
get_language = LanguageImporter()

View file

@ -0,0 +1,58 @@
# $Id: af.py 9030 2022-03-05 23:28:32Z milde $
# Author: Jannie Hofmeyr <jhsh@sun.ac.za>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Afrikaans-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Auteur',
'authors': 'Auteurs',
'organization': 'Organisasie',
'address': 'Adres',
'contact': 'Kontak',
'version': 'Weergawe',
'revision': 'Revisie',
'status': 'Status',
'date': 'Datum',
'copyright': 'Kopiereg',
'dedication': 'Opdrag',
'abstract': 'Opsomming',
'attention': 'Aandag!',
'caution': 'Wees versigtig!',
'danger': '!GEVAAR!',
'error': 'Fout',
'hint': 'Wenk',
'important': 'Belangrik',
'note': 'Nota',
'tip': 'Tip', # hint and tip both have the same translation: wenk
'warning': 'Waarskuwing',
'contents': 'Inhoud'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'auteur': 'author',
'auteurs': 'authors',
'organisasie': 'organization',
'adres': 'address',
'kontak': 'contact',
'weergawe': 'version',
'revisie': 'revision',
'status': 'status',
'datum': 'date',
'kopiereg': 'copyright',
'opdrag': 'dedication',
'opsomming': 'abstract'}
"""Afrikaans (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: fa.py 4564 2016-08-10 11:48:42Z
# Author: Shahin <me@5hah.in>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Arabic-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'المؤلف',
'authors': 'المؤلفون',
'organization': 'التنظيم',
'address': 'العنوان',
'contact': 'اتصل',
'version': 'نسخة',
'revision': 'مراجعة',
'status': 'الحالة',
'date': 'تاریخ',
'copyright': 'الحقوق',
'dedication': 'إهداء',
'abstract': 'ملخص',
'attention': 'تنبيه',
'caution': 'احتیاط',
'danger': 'خطر',
'error': 'خطأ',
'hint': 'تلميح',
'important': 'مهم',
'note': 'ملاحظة',
'tip': 'نصيحة',
'warning': 'تحذير',
'contents': 'المحتوى'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'مؤلف': 'author',
'مؤلفون': 'authors',
'التنظيم': 'organization',
'العنوان': 'address',
'اتصل': 'contact',
'نسخة': 'version',
'مراجعة': 'revision',
'الحالة': 'status',
'تاریخ': 'date',
'الحقوق': 'copyright',
'إهداء': 'dedication',
'ملخص': 'abstract'}
"""Arabic (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = ['؛', '،']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,65 @@
# $Id: ca.py 9457 2023-10-02 16:25:50Z milde $
# Authors: Ivan Vilata i Balaguer <ivan@selidor.net>;
# Antoni Bella Pérez <antonibella5@yahoo.com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation,
# please read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
# These translations can be used without changes for
# Valencian variant of Catalan (use language tag "ca-valencia").
# Checked by a native speaker of Valentian.
"""
Catalan-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autor',
'authors': 'Autors',
'organization': 'Organització',
'address': 'Adreça',
'contact': 'Contacte',
'version': 'Versió',
'revision': 'Revisió',
'status': 'Estat',
'date': 'Data',
'copyright': 'Copyright',
'dedication': 'Dedicatòria',
'abstract': 'Resum',
'attention': 'Atenció!',
'caution': 'Compte!',
'danger': 'PERILL!',
'error': 'Error',
'hint': 'Suggeriment',
'important': 'Important',
'note': 'Nota',
'tip': 'Consell',
'warning': 'Avís',
'contents': 'Contingut'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autor': 'author',
'autors': 'authors',
'organització': 'organization',
'adreça': 'address',
'contacte': 'contact',
'versió': 'version',
'revisió': 'revision',
'estat': 'status',
'data': 'date',
'copyright': 'copyright',
'dedicatòria': 'dedication',
'resum': 'abstract'}
"""Catalan (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: cs.py 9452 2023-09-27 00:11:54Z milde $
# Author: Marek Blaha <mb@dat.cz>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Czech-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autor',
'authors': 'Autoři',
'organization': 'Organizace',
'address': 'Adresa',
'contact': 'Kontakt',
'version': 'Verze',
'revision': 'Revize',
'status': 'Stav',
'date': 'Datum',
'copyright': 'Copyright',
'dedication': 'Věnování',
'abstract': 'Abstrakt',
'attention': 'Pozor!',
'caution': 'Opatrně!',
'danger': '!NEBEZPEČÍ!',
'error': 'Chyba',
'hint': 'Rada',
'important': 'Důležité',
'note': 'Poznámka',
'tip': 'Tip',
'warning': 'Varování',
'contents': 'Obsah'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autor': 'author',
'autoři': 'authors',
'organizace': 'organization',
'adresa': 'address',
'kontakt': 'contact',
'verze': 'version',
'revize': 'revision',
'stav': 'status',
'datum': 'date',
'copyright': 'copyright',
'věnování': 'dedication',
'abstrakt': 'abstract'}
"""Czech (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,61 @@
# $Id: da.py 9030 2022-03-05 23:28:32Z milde $
# Author: E D
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Danish-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Forfatter',
'authors': 'Forfattere',
'organization': 'Organisation',
'address': 'Adresse',
'contact': 'Kontakt',
'version': 'Version',
'revision': 'Revision',
'status': 'Status',
'date': 'Dato',
'copyright': 'Copyright',
'dedication': 'Dedikation',
'abstract': 'Resumé',
'attention': 'Giv agt!',
'caution': 'Pas på!',
'danger': '!FARE!',
'error': 'Fejl',
'hint': 'Vink',
'important': 'Vigtigt',
'note': 'Bemærk',
'tip': 'Tips',
'warning': 'Advarsel',
'contents': 'Indhold'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'forfatter': 'author',
'forfattere': 'authors',
'organisation': 'organization',
'adresse': 'address',
'kontakt': 'contact',
'version': 'version',
'revision': 'revision',
'status': 'status',
'dato': 'date',
'copyright': 'copyright',
'dedikation': 'dedication',
'resume': 'abstract',
'resumé': 'abstract'}
"""Danish (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: de.py 9030 2022-03-05 23:28:32Z milde $
# Author: Gunnar Schwant <g.schwant@gmx.de>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
German language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Autor',
'authors': 'Autoren',
'organization': 'Organisation',
'address': 'Adresse',
'contact': 'Kontakt',
'version': 'Version',
'revision': 'Revision',
'status': 'Status',
'date': 'Datum',
'dedication': 'Widmung',
'copyright': 'Copyright',
'abstract': 'Zusammenfassung',
'attention': 'Achtung!',
'caution': 'Vorsicht!',
'danger': '!GEFAHR!',
'error': 'Fehler',
'hint': 'Hinweis',
'important': 'Wichtig',
'note': 'Bemerkung',
'tip': 'Tipp',
'warning': 'Warnung',
'contents': 'Inhalt'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'autor': 'author',
'autoren': 'authors',
'organisation': 'organization',
'adresse': 'address',
'kontakt': 'contact',
'version': 'version',
'revision': 'revision',
'status': 'status',
'datum': 'date',
'copyright': 'copyright',
'widmung': 'dedication',
'zusammenfassung': 'abstract'}
"""German (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: en.py 9030 2022-03-05 23:28:32Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
English-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Author',
'authors': 'Authors',
'organization': 'Organization',
'address': 'Address',
'contact': 'Contact',
'version': 'Version',
'revision': 'Revision',
'status': 'Status',
'date': 'Date',
'copyright': 'Copyright',
'dedication': 'Dedication',
'abstract': 'Abstract',
'attention': 'Attention!',
'caution': 'Caution!',
'danger': '!DANGER!',
'error': 'Error',
'hint': 'Hint',
'important': 'Important',
'note': 'Note',
'tip': 'Tip',
'warning': 'Warning',
'contents': 'Contents'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'author': 'author',
'authors': 'authors',
'organization': 'organization',
'address': 'address',
'contact': 'contact',
'version': 'version',
'revision': 'revision',
'status': 'status',
'date': 'date',
'copyright': 'copyright',
'dedication': 'dedication',
'abstract': 'abstract'}
"""English (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,61 @@
# $Id: eo.py 9452 2023-09-27 00:11:54Z milde $
# Author: Marcelo Huerta San Martin <richieadler@users.sourceforge.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Esperanto-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Aŭtoro',
'authors': 'Aŭtoroj',
'organization': 'Organizo',
'address': 'Adreso',
'contact': 'Kontakto',
'version': 'Versio',
'revision': 'Revido',
'status': 'Stato',
'date': 'Dato',
# 'copyright': 'Kopirajto',
'copyright': 'Aŭtorrajto',
'dedication': 'Dediĉo',
'abstract': 'Resumo',
'attention': 'Atentu!',
'caution': 'Zorgu!',
'danger': 'DANĜERO!',
'error': 'Eraro',
'hint': 'Spuro',
'important': 'Grava',
'note': 'Noto',
'tip': 'Helpeto',
'warning': 'Averto',
'contents': 'Enhavo'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'aŭtoro': 'author',
'aŭtoroj': 'authors',
'organizo': 'organization',
'adreso': 'address',
'kontakto': 'contact',
'versio': 'version',
'revido': 'revision',
'stato': 'status',
'dato': 'date',
'aŭtorrajto': 'copyright',
'dediĉo': 'dedication',
'resumo': 'abstract'}
"""Esperanto (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: es.py 9452 2023-09-27 00:11:54Z milde $
# Author: Marcelo Huerta San Martín <richieadler@users.sourceforge.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Spanish-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Autor',
'authors': 'Autores',
'organization': 'Organización',
'address': 'Dirección',
'contact': 'Contacto',
'version': 'Versión',
'revision': 'Revisión',
'status': 'Estado',
'date': 'Fecha',
'copyright': 'Copyright',
'dedication': 'Dedicatoria',
'abstract': 'Resumen',
'attention': '¡Atención!',
'caution': '¡Precaución!',
'danger': '¡PELIGRO!',
'error': 'Error',
'hint': 'Sugerencia',
'important': 'Importante',
'note': 'Nota',
'tip': 'Consejo',
'warning': 'Advertencia',
'contents': 'Contenido'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'autor': 'author',
'autores': 'authors',
'organización': 'organization',
'dirección': 'address',
'contacto': 'contact',
'versión': 'version',
'revisión': 'revision',
'estado': 'status',
'fecha': 'date',
'copyright': 'copyright',
'dedicatoria': 'dedication',
'resumen': 'abstract'}
"""Spanish (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: fa.py 4564 2016-08-10 11:48:42Z
# Author: Shahin <me@5hah.in>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Persian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'نویسنده',
'authors': 'نویسندگان',
'organization': 'سازمان',
'address': 'آدرس',
'contact': 'تماس',
'version': 'نسخه',
'revision': 'بازبینی',
'status': 'وضعیت',
'date': 'تاریخ',
'copyright': 'کپی‌رایت',
'dedication': 'تخصیص',
'abstract': 'چکیده',
'attention': 'توجه!',
'caution': 'احتیاط!',
'danger': 'خطر!',
'error': 'خطا',
'hint': 'راهنما',
'important': 'مهم',
'note': 'یادداشت',
'tip': 'نکته',
'warning': 'اخطار',
'contents': 'محتوا'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'نویسنده': 'author',
'نویسندگان': 'authors',
'سازمان': 'organization',
'آدرس': 'address',
'تماس': 'contact',
'نسخه': 'version',
'بازبینی': 'revision',
'وضعیت': 'status',
'تاریخ': 'date',
'کپی‌رایت': 'copyright',
'تخصیص': 'dedication',
'چکیده': 'abstract'}
"""Persian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = ['؛', '،']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: fi.py 9452 2023-09-27 00:11:54Z milde $
# Author: Asko Soukka <asko.soukka@iki.fi>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Finnish-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Tekijä',
'authors': 'Tekijät',
'organization': 'Yhteisö',
'address': 'Osoite',
'contact': 'Yhteystiedot',
'version': 'Versio',
'revision': 'Vedos',
'status': 'Tila',
'date': 'Päiväys',
'copyright': 'Tekijänoikeudet',
'dedication': 'Omistuskirjoitus',
'abstract': 'Tiivistelmä',
'attention': 'Huomio!',
'caution': 'Varo!',
'danger': '!VAARA!',
'error': 'Virhe',
'hint': 'Vihje',
'important': 'Tärkeää',
'note': 'Huomautus',
'tip': 'Neuvo',
'warning': 'Varoitus',
'contents': 'Sisällys'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'tekijä': 'author',
'tekijät': 'authors',
'yhteisö': 'organization',
'osoite': 'address',
'yhteystiedot': 'contact',
'versio': 'version',
'vedos': 'revision',
'tila': 'status',
'päiväys': 'date',
'tekijänoikeudet': 'copyright',
'omistuskirjoitus': 'dedication',
'tiivistelmä': 'abstract'}
"""Finnish (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: fr.py 9452 2023-09-27 00:11:54Z milde $
# Author: Stefane Fermigier <sf@fermigier.com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
French-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Auteur',
'authors': 'Auteurs',
'organization': 'Organisation',
'address': 'Adresse',
'contact': 'Contact',
'version': 'Version',
'revision': 'Révision',
'status': 'Statut',
'date': 'Date',
'copyright': 'Copyright',
'dedication': 'Dédicace',
'abstract': 'Résumé',
'attention': 'Attention!',
'caution': 'Avertissement!',
'danger': '!DANGER!',
'error': 'Erreur',
'hint': 'Indication',
'important': 'Important',
'note': 'Note',
'tip': 'Astuce',
'warning': 'Avis',
'contents': 'Sommaire'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'auteur': 'author',
'auteurs': 'authors',
'organisation': 'organization',
'adresse': 'address',
'contact': 'contact',
'version': 'version',
'révision': 'revision',
'statut': 'status',
'date': 'date',
'copyright': 'copyright',
'dédicace': 'dedication',
'résumé': 'abstract'}
"""French (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,62 @@
# Author: David Goodger
# Contact: goodger@users.sourceforge.net
# Revision: $Revision: 2224 $
# Date: $Date: 2004-06-05 21:40:46 +0200 (Sat, 05 Jun 2004) $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Galician-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autor',
'authors': 'Autores',
'organization': 'Organización',
'address': 'Enderezo',
'contact': 'Contacto',
'version': 'Versión',
'revision': 'Revisión',
'status': 'Estado',
'date': 'Data',
'copyright': 'Dereitos de copia',
'dedication': 'Dedicatoria',
'abstract': 'Abstract',
'attention': 'Atención!',
'caution': 'Advertencia!',
'danger': 'PERIGO!',
'error': 'Erro',
'hint': 'Consello',
'important': 'Importante',
'note': 'Nota',
'tip': 'Suxestión',
'warning': 'Aviso',
'contents': 'Contido'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autor': 'author',
'autores': 'authors',
'organización': 'organization',
'enderezo': 'address',
'contacto': 'contact',
'versión': 'version',
'revisión': 'revision',
'estado': 'status',
'data': 'date',
'dereitos de copia': 'copyright',
'dedicatoria': 'dedication',
'abstract': 'abstract'}
"""Galician (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,62 @@
# Author: Meir Kriheli
# Id: $Id: he.py 9452 2023-09-27 00:11:54Z milde $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Hebrew-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'מחבר',
'authors': 'מחברי',
'organization': 'ארגון',
'address': 'כתובת',
'contact': 'איש קשר',
'version': 'גרסה',
'revision': 'מהדורה',
'status': 'סטטוס',
'date': 'תאריך',
'copyright': 'זכויות שמורות',
'dedication': 'הקדשה',
'abstract': 'תקציר',
'attention': 'תשומת לב',
'caution': 'זהירות',
'danger': 'סכנה',
'error': 'שגיאה',
'hint': 'רמז',
'important': 'חשוב',
'note': 'הערה',
'tip': 'טיפ',
'warning': 'אזהרה',
'contents': 'תוכן',
}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'מחבר': 'author',
'מחברי': 'authors',
'ארגון': 'organization',
'כתובת': 'address',
'איש קשר': 'contact',
'גרסה': 'version',
'מהדורה': 'revision',
'סטטוס': 'status',
'תאריך': 'date',
'זכויות שמורות': 'copyright',
'הקדשה': 'dedication',
'תקציר': 'abstract',
}
"""Hebrew to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: it.py 9030 2022-03-05 23:28:32Z milde $
# Author: Nicola Larosa <docutils@tekNico.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Italian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Autore',
'authors': 'Autori',
'organization': 'Organizzazione',
'address': 'Indirizzo',
'contact': 'Contatti',
'version': 'Versione',
'revision': 'Revisione',
'status': 'Status',
'date': 'Data',
'copyright': 'Copyright',
'dedication': 'Dedica',
'abstract': 'Riassunto',
'attention': 'Attenzione!',
'caution': 'Cautela!',
'danger': '!PERICOLO!',
'error': 'Errore',
'hint': 'Suggerimento',
'important': 'Importante',
'note': 'Nota',
'tip': 'Consiglio',
'warning': 'Avvertenza',
'contents': 'Indice'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'autore': 'author',
'autori': 'authors',
'organizzazione': 'organization',
'indirizzo': 'address',
'contatto': 'contact',
'versione': 'version',
'revisione': 'revision',
'status': 'status',
'data': 'date',
'copyright': 'copyright',
'dedica': 'dedication',
'riassunto': 'abstract'}
"""Italian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: ja.py 9030 2022-03-05 23:28:32Z milde $
# Author: Hisashi Morita <hisashim@kt.rim.or.jp>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Japanese-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': '著者',
'authors': '著者',
'organization': '組織',
'address': '住所',
'contact': '連絡先',
'version': 'バージョン',
'revision': 'リビジョン',
'status': 'ステータス',
'date': '日付',
'copyright': '著作権',
'dedication': '献辞',
'abstract': '概要',
'attention': '注目!',
'caution': '注意!',
'danger': '!危険!',
'error': 'エラー',
'hint': 'ヒント',
'important': '重要',
'note': '備考',
'tip': '通報',
'warning': '警告',
'contents': '目次'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'著者': 'author',
' n/a': 'authors',
'組織': 'organization',
'住所': 'address',
'連絡先': 'contact',
'バージョン': 'version',
'リビジョン': 'revision',
'ステータス': 'status',
'日付': 'date',
'著作権': 'copyright',
'献辞': 'dedication',
'概要': 'abstract'}
"""Japanese (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: ka.py 9444 2023-08-23 12:02:41Z grubert $
# Author: Temuri Doghonadze <temuri dot doghonadze at gmail dot com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Georgian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'abstract': 'ანოტაცია',
'address': 'მისამართი',
'attention': 'ყურადღება!',
'author': 'ავტორი',
'authors': 'ავტორები',
'caution': 'ფრთხილად!',
'contact': 'კონტაქტი',
'contents': 'შემცველობა',
'copyright': 'საავტორო უფლებები',
'danger': 'საშიშია!',
'date': 'თარიღი',
'dedication': 'მიძღვნა',
'error': 'შეცდომა',
'hint': 'რჩევა',
'important': 'მნიშვნელოვანია',
'note': 'შენიშვნა',
'organization': 'ორგანიზაცია',
'revision': 'რევიზია',
'status': 'სტატუსი',
'tip': 'მინიშნება',
'version': 'ვერსია',
'warning': 'გაფრთხილება'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'ანოტაცია': 'abstract',
'მისამართი': 'address',
'ავტორი': 'author',
'ავტორები': 'authors',
'კონტაქტი': 'contact',
'საავტორო უფლებები': 'copyright',
'თარიღი': 'date',
'მიძღვნა': 'dedication',
'ორგანიზაცია': 'organization',
'რევიზია': 'revision',
'სტატუსი': 'status',
'ვერსია': 'version'}
"""Georgian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: ko.py 9030 2022-03-05 23:28:32Z milde $
# Author: Thomas SJ Kang <thomas.kangsj@ujuc.kr>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Korean-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': '저자',
'authors': '저자들',
'organization': '조직',
'address': '주소',
'contact': '연락처',
'version': '버전',
'revision': '리비전',
'status': '상태',
'date': '날짜',
'copyright': '저작권',
'dedication': '헌정',
'abstract': '요약',
'attention': '집중!',
'caution': '주의!',
'danger': '!위험!',
'error': '오류',
'hint': '실마리',
'important': '중요한',
'note': '비고',
'tip': '',
'warning': '경고',
'contents': '목차'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'저자': 'author',
'저자들': 'authors',
'조직': 'organization',
'주소': 'address',
'연락처': 'contact',
'버전': 'version',
'리비전': 'revision',
'상태': 'status',
'날짜': 'date',
'저작권': 'copyright',
'헌정': 'dedication',
'요약': 'abstract'}
"""Korean to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: lt.py 9030 2022-03-05 23:28:32Z milde $
# Author: Dalius Dobravolskas <dalius.do...@gmail.com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Lithuanian language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autorius',
'authors': 'Autoriai',
'organization': 'Organizacija',
'address': 'Adresas',
'contact': 'Kontaktas',
'version': 'Versija',
'revision': 'Revizija',
'status': 'Būsena',
'date': 'Data',
'copyright': 'Autoriaus teisės',
'dedication': 'Dedikacija',
'abstract': 'Santrauka',
'attention': 'Dėmesio!',
'caution': 'Atsargiai!',
'danger': '!PAVOJINGA!',
'error': 'Klaida',
'hint': 'Užuomina',
'important': 'Svarbu',
'note': 'Pastaba',
'tip': 'Patarimas',
'warning': 'Įspėjimas',
'contents': 'Turinys'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autorius': 'author',
'autoriai': 'authors',
'organizacija': 'organization',
'adresas': 'address',
'kontaktas': 'contact',
'versija': 'version',
'revizija': 'revision',
'būsena': 'status',
'data': 'date',
'autoriaus teisės': 'copyright',
'dedikacija': 'dedication',
'santrauka': 'abstract'}
"""Lithuanian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,59 @@
# $Id: lv.py 9030 2022-03-05 23:28:32Z milde $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Latvian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autors',
'authors': 'Autori',
'organization': 'Organizācija',
'address': 'Adrese',
'contact': 'Kontakti',
'version': 'Versija',
'revision': 'Revīzija',
'status': 'Statuss',
'date': 'Datums',
'copyright': 'Copyright',
'dedication': 'Veltījums',
'abstract': 'Atreferējums',
'attention': 'Uzmanību!',
'caution': 'Piesardzību!',
'danger': '!BĪSTAMI!',
'error': 'Kļūda',
'hint': 'Ieteikums',
'important': 'Svarīgi',
'note': 'Piezīme',
'tip': 'Padoms',
'warning': 'Brīdinājums',
'contents': 'Saturs'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autors': 'author',
'autori': 'authors',
'organizācija': 'organization',
'adrese': 'address',
'kontakti': 'contact',
'versija': 'version',
'revīzija': 'revision',
'statuss': 'status',
'datums': 'date',
'copyright': 'copyright',
'veltījums': 'dedication',
'atreferējums': 'abstract'}
"""English (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: nl.py 9030 2022-03-05 23:28:32Z milde $
# Author: Martijn Pieters <mjpieters@users.sourceforge.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Dutch-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Auteur',
'authors': 'Auteurs',
'organization': 'Organisatie',
'address': 'Adres',
'contact': 'Contact',
'version': 'Versie',
'revision': 'Revisie',
'status': 'Status',
'date': 'Datum',
'copyright': 'Copyright',
'dedication': 'Toewijding',
'abstract': 'Samenvatting',
'attention': 'Attentie!',
'caution': 'Let op!',
'danger': '!GEVAAR!',
'error': 'Fout',
'hint': 'Hint',
'important': 'Belangrijk',
'note': 'Opmerking',
'tip': 'Tip',
'warning': 'Waarschuwing',
'contents': 'Inhoud'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'auteur': 'author',
'auteurs': 'authors',
'organisatie': 'organization',
'adres': 'address',
'contact': 'contact',
'versie': 'version',
'revisie': 'revision',
'status': 'status',
'datum': 'date',
'copyright': 'copyright',
'toewijding': 'dedication',
'samenvatting': 'abstract'}
"""Dutch (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id$
# Author: Robert Wojciechowicz <rw@smsnet.pl>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Polish-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autor',
'authors': 'Autorzy',
'organization': 'Organizacja',
'address': 'Adres',
'contact': 'Kontakt',
'version': 'Wersja',
'revision': 'Korekta',
'status': 'Status',
'date': 'Data',
'copyright': 'Copyright',
'dedication': 'Dedykacja',
'abstract': 'Streszczenie',
'attention': 'Uwaga!',
'caution': 'Ostrożnie!',
'danger': '!Niebezpieczeństwo!',
'error': 'Błąd',
'hint': 'Wskazówka',
'important': 'Ważne',
'note': 'Przypis',
'tip': 'Rada',
'warning': 'Ostrzeżenie',
'contents': 'Treść'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autor': 'author',
'autorzy': 'authors',
'organizacja': 'organization',
'adres': 'address',
'kontakt': 'contact',
'wersja': 'version',
'korekta': 'revision',
'status': 'status',
'data': 'date',
'copyright': 'copyright',
'dedykacja': 'dedication',
'streszczenie': 'abstract'}
"""Polish (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,60 @@
# $Id: pt_br.py 9452 2023-09-27 00:11:54Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Brazilian Portuguese-language mappings for language-dependent features.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': 'Autor',
'authors': 'Autores',
'organization': 'Organização',
'address': 'Endereço',
'contact': 'Contato',
'version': 'Versão',
'revision': 'Revisão',
'status': 'Estado',
'date': 'Data',
'copyright': 'Copyright',
'dedication': 'Dedicatória',
'abstract': 'Resumo',
'attention': 'Atenção!',
'caution': 'Cuidado!',
'danger': 'PERIGO!',
'error': 'Erro',
'hint': 'Sugestão',
'important': 'Importante',
'note': 'Nota',
'tip': 'Dica',
'warning': 'Aviso',
'contents': 'Sumário'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'autor': 'author',
'autores': 'authors',
'organização': 'organization',
'endereço': 'address',
'contato': 'contact',
'versão': 'version',
'revisão': 'revision',
'estado': 'status',
'data': 'date',
'copyright': 'copyright',
'dedicatória': 'dedication',
'resumo': 'abstract'}
"""Brazilian Portuguese (lowcased) name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: ru.py 9030 2022-03-05 23:28:32Z milde $
# Author: Roman Suzi <rnd@onego.ru>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Russian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'abstract': 'Аннотация',
'address': 'Адрес',
'attention': 'Внимание!',
'author': 'Автор',
'authors': 'Авторы',
'caution': 'Осторожно!',
'contact': 'Контакт',
'contents': 'Содержание',
'copyright': 'Права копирования',
'danger': 'ОПАСНО!',
'date': 'Дата',
'dedication': 'Посвящение',
'error': 'Ошибка',
'hint': 'Совет',
'important': 'Важно',
'note': 'Примечание',
'organization': 'Организация',
'revision': 'Редакция',
'status': 'Статус',
'tip': 'Подсказка',
'version': 'Версия',
'warning': 'Предупреждение'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'аннотация': 'abstract',
'адрес': 'address',
'автор': 'author',
'авторы': 'authors',
'контакт': 'contact',
'права копирования': 'copyright',
'дата': 'date',
'посвящение': 'dedication',
'организация': 'organization',
'редакция': 'revision',
'статус': 'status',
'версия': 'version'}
"""Russian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: sk.py 9452 2023-09-27 00:11:54Z milde $
# Author: Miroslav Vasko <zemiak@zoznam.sk>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Slovak-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Autor',
'authors': 'Autori',
'organization': 'Organizácia',
'address': 'Adresa',
'contact': 'Kontakt',
'version': 'Verzia',
'revision': 'Revízia',
'status': 'Stav',
'date': 'Dátum',
'copyright': 'Copyright',
'dedication': 'Venovanie',
'abstract': 'Abstraktne',
'attention': 'Pozor!',
'caution': 'Opatrne!',
'danger': '!NEBEZPEČENSTVO!',
'error': 'Chyba',
'hint': 'Rada',
'important': 'Dôležité',
'note': 'Poznámka',
'tip': 'Tip',
'warning': 'Varovanie',
'contents': 'Obsah'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'autor': 'author',
'autori': 'authors',
'organizácia': 'organization',
'adresa': 'address',
'kontakt': 'contact',
'verzia': 'version',
'revízia': 'revision',
'stav': 'status',
'dátum': 'date',
'copyright': 'copyright',
'venovanie': 'dedication',
'abstraktne': 'abstract'}
"""Slovak (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,59 @@
# $Id: sv.py 9452 2023-09-27 00:11:54Z milde $
# Author: Adam Chodorowski <chodorowski@users.sourceforge.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Swedish language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'author': 'Författare',
'authors': 'Författare',
'organization': 'Organisation',
'address': 'Adress',
'contact': 'Kontakt',
'version': 'Version',
'revision': 'Revision',
'status': 'Status',
'date': 'Datum',
'copyright': 'Copyright',
'dedication': 'Dedikation',
'abstract': 'Sammanfattning',
'attention': 'Observera!',
'caution': 'Akta!', # 'Varning' already used for 'warning'
'danger': 'FARA!',
'error': 'Fel',
'hint': 'Vink',
'important': 'Viktigt',
'note': 'Notera',
'tip': 'Tips',
'warning': 'Varning',
'contents': 'Innehåll'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# 'Author' and 'Authors' identical in Swedish; assume the plural:
'författare': 'authors',
' n/a': 'author', # removing leads to (spurious) test failure
'organisation': 'organization',
'adress': 'address',
'kontakt': 'contact',
'version': 'version',
'revision': 'revision',
'status': 'status',
'datum': 'date',
'copyright': 'copyright',
'dedikation': 'dedication',
'sammanfattning': 'abstract'}
"""Swedish (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,58 @@
# $Id: uk.py 9114 2022-07-28 17:06:10Z milde $
# Author: Dmytro Kazanzhy <dkazanzhy@gmail.com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <http://docutils.sf.net/docs/howto/i18n.html>. Two files must be
# translated for each language: one in docutils/languages, the other in
# docutils/parsers/rst/languages.
"""
Ukrainian-language mappings for language-dependent features of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
'abstract': 'Анотація',
'address': 'Адреса',
'attention': 'Увага!',
'author': 'Автор',
'authors': 'Автори',
'caution': 'Обережно!',
'contact': 'Контакт',
'contents': 'Зміст',
'copyright': 'Права копіювання',
'danger': 'НЕБЕЗПЕЧНО!',
'date': 'Дата',
'dedication': 'Посвячення',
'error': 'Помилка',
'hint': 'Порада',
'important': 'Важливо',
'note': 'Примітка',
'organization': 'Організація',
'revision': 'Редакція',
'status': 'Статус',
'tip': 'Підказка',
'version': 'Версія',
'warning': 'Попередження'}
"""Mapping of node class name to label text."""
bibliographic_fields = {
'анотація': 'abstract',
'адреса': 'address',
'автор': 'author',
'автори': 'authors',
'контакт': 'contact',
'права копіювання': 'copyright',
'дата': 'date',
'посвячення': 'dedication',
'організація': 'organization',
'редакція': 'revision',
'статус': 'status',
'версія': 'version'}
"""Ukrainian (lowcased) to canonical name mapping for bibliographic fields."""
author_separators = [';', ',']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,62 @@
# $Id: zh_cn.py 9452 2023-09-27 00:11:54Z milde $
# Author: Pan Junyong <panjy@zopechina.com>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Simplified Chinese language mappings for language-dependent features
of Docutils.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': '作者',
'authors': '作者群',
'organization': '组织',
'address': '地址',
'contact': '联系',
'version': '版本',
'revision': '修订',
'status': '状态',
'date': '日期',
'copyright': '版权',
'dedication': '献辞',
'abstract': '摘要',
'attention': '注意',
'caution': '小心',
'danger': '危险',
'error': '错误',
'hint': '提示',
'important': '重要',
'note': '注解',
'tip': '技巧',
'warning': '警告',
'contents': '目录',
}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'作者': 'author',
'作者群': 'authors',
'组织': 'organization',
'地址': 'address',
'联系': 'contact',
'版本': 'version',
'修订': 'revision',
'状态': 'status',
'时间': 'date',
'版权': 'copyright',
'献辞': 'dedication',
'摘要': 'abstract'}
"""Simplified Chinese to canonical name mapping for bibliographic fields."""
author_separators = [';', ',', '', '', '']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

View file

@ -0,0 +1,61 @@
# $Id: zh_tw.py 9452 2023-09-27 00:11:54Z milde $
# Author: Joe YS Jaw <joeysj@users.sourceforge.net>
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
# read <https://docutils.sourceforge.io/docs/howto/i18n.html>.
# Two files must be translated for each language: one in docutils/languages,
# the other in docutils/parsers/rst/languages.
"""
Traditional Chinese language mappings for language-dependent features.
"""
__docformat__ = 'reStructuredText'
labels = {
# fixed: language-dependent
'author': '作者',
'authors': '作者群',
'organization': '組織',
'address': '地址',
'contact': '連絡',
'version': '版本',
'revision': '修訂',
'status': '狀態',
'date': '日期',
'copyright': '版權',
'dedication': '題獻',
'abstract': '摘要',
'attention': '注意!',
'caution': '小心!',
'danger': '!危險!',
'error': '錯誤',
'hint': '提示',
'important': '重要',
'note': '註釋',
'tip': '秘訣',
'warning': '警告',
'contents': '目錄',
}
"""Mapping of node class name to label text."""
bibliographic_fields = {
# language-dependent: fixed
'author (translation required)': 'author',
'authors (translation required)': 'authors',
'organization (translation required)': 'organization',
'address (translation required)': 'address',
'contact (translation required)': 'contact',
'version (translation required)': 'version',
'revision (translation required)': 'revision',
'status (translation required)': 'status',
'date (translation required)': 'date',
'copyright (translation required)': 'copyright',
'dedication (translation required)': 'dedication',
'abstract (translation required)': 'abstract'}
"""Traditional Chinese to canonical name mapping for bibliographic fields."""
author_separators = [';', ',', '', '', '']
"""List of separator strings for the 'Authors' bibliographic field. Tried in
order."""

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
# $Id: __init__.py 9048 2022-03-29 21:50:15Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This package contains Docutils parser modules.
"""
__docformat__ = 'reStructuredText'
from importlib import import_module
from docutils import Component, frontend
class Parser(Component):
settings_spec = (
'Generic Parser Options',
None,
(('Disable directives that insert the contents of an external file; '
'replaced with a "warning" system message.',
['--no-file-insertion'],
{'action': 'store_false', 'default': 1,
'dest': 'file_insertion_enabled',
'validator': frontend.validate_boolean}),
('Enable directives that insert the contents '
'of an external file. (default)',
['--file-insertion-enabled'],
{'action': 'store_true'}),
('Disable the "raw" directive; '
'replaced with a "warning" system message.',
['--no-raw'],
{'action': 'store_false', 'default': 1, 'dest': 'raw_enabled',
'validator': frontend.validate_boolean}),
('Enable the "raw" directive. (default)',
['--raw-enabled'],
{'action': 'store_true'}),
('Maximal number of characters in an input line. Default 10 000.',
['--line-length-limit'],
{'metavar': '<length>', 'type': 'int', 'default': 10000,
'validator': frontend.validate_nonnegative_int}),
)
)
component_type = 'parser'
config_section = 'parsers'
def parse(self, inputstring, document):
"""Override to parse `inputstring` into document tree `document`."""
raise NotImplementedError('subclass must override this method')
def setup_parse(self, inputstring, document):
"""Initial parse setup. Call at start of `self.parse()`."""
self.inputstring = inputstring
# provide fallbacks in case the document has only generic settings
document.settings.setdefault('file_insertion_enabled', False)
document.settings.setdefault('raw_enabled', False)
document.settings.setdefault('line_length_limit', 10000)
self.document = document
document.reporter.attach_observer(document.note_parse_message)
def finish_parse(self):
"""Finalize parse details. Call at end of `self.parse()`."""
self.document.reporter.detach_observer(
self.document.note_parse_message)
_parser_aliases = { # short names for known parsers
'null': 'docutils.parsers.null',
# reStructuredText
'rst': 'docutils.parsers.rst',
'restructuredtext': 'docutils.parsers.rst',
'rest': 'docutils.parsers.rst',
'restx': 'docutils.parsers.rst',
'rtxt': 'docutils.parsers.rst',
# 3rd-party Markdown parsers
'recommonmark': 'docutils.parsers.recommonmark_wrapper',
'myst': 'myst_parser.docutils_',
# 'pycmark': works out of the box
# dispatcher for 3rd-party Markdown parsers
'commonmark': 'docutils.parsers.commonmark_wrapper',
'markdown': 'docutils.parsers.commonmark_wrapper',
}
def get_parser_class(parser_name):
"""Return the Parser class from the `parser_name` module."""
name = parser_name.lower()
try:
module = import_module(_parser_aliases.get(name, name))
except ImportError as err:
raise ImportError(f'Parser "{parser_name}" not found. {err}')
return module.Parser

View file

@ -0,0 +1,56 @@
#! /usr/bin/env python3
# :Copyright: © 2022 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
#
# Revision: $Revision: 9561 $
# Date: $Date: 2024-03-14 17:34:48 +0100 (Do, 14. Mär 2024) $
"""
An interface for parsing CommonMark input.
Select a locally installed parser from the following 3rd-party
parser packages:
:pycmark: https://pypi.org/project/pycmark/
:myst: https://pypi.org/project/myst-docutils/
:recommonmark: https://pypi.org/project/recommonmark/ (deprecated)
The first parser class that can be successfully imported is mapped to
`commonmark_wrapper.Parser`.
This module is provisional:
the API is not settled and may change with any minor Docutils version.
"""
import docutils.parsers
commonmark_parser_names = ('pycmark', 'myst', 'recommonmark')
"""Names of compatible drop-in CommonMark parsers"""
Parser = None
parser_name = ''
for name in commonmark_parser_names:
try:
Parser = docutils.parsers.get_parser_class(name)
except ImportError:
continue
parser_name = name
break
if Parser is None:
raise ImportError(
'Parsing "CommonMark" requires one of the packages\n'
f'{commonmark_parser_names} available at https://pypi.org')
if parser_name == 'myst':
if not Parser.settings_defaults:
Parser.settings_defaults = {}
Parser.settings_defaults['myst_commonmark_only'] = True

View file

@ -0,0 +1,20 @@
# $Id: null.py 4564 2006-05-21 20:44:42Z wiemann $
# Author: Martin Blais <blais@furius.ca>
# Copyright: This module has been placed in the public domain.
"""A do-nothing parser."""
from docutils import parsers
class Parser(parsers.Parser):
"""A do-nothing parser."""
supported = ('null',)
config_section = 'null parser'
config_section_dependencies = ('parsers',)
def parse(self, inputstring, document):
pass

View file

@ -0,0 +1,147 @@
#!/usr/bin/env python3
# :Copyright: © 2020 Günter Milde.
# :License: Released under the terms of the `2-Clause BSD license`_, in short:
#
# Copying and distribution of this file, with or without modification,
# are permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
# This file is offered as-is, without any warranty.
#
# .. _2-Clause BSD license: https://opensource.org/licenses/BSD-2-Clause
#
# Revision: $Revision: 9302 $
# Date: $Date: 2022-12-02 18:14:05 +0100 (Fr, 02. Dez 2022) $
"""
A parser for CommonMark Markdown text using `recommonmark`__.
__ https://pypi.org/project/recommonmark/
.. important:: This module is provisional
* The "recommonmark" package is unmaintained and deprecated.
This wrapper module will be removed in a future Docutils version.
* The API is not settled and may change with any minor Docutils version.
"""
from docutils import Component
from docutils import nodes
try:
# If possible, import Sphinx's 'addnodes'
from sphinx import addnodes
except ImportError:
# stub to prevent errors if Sphinx isn't installed
import sys
import types
class pending_xref(nodes.Inline, nodes.Element): ... # NoQA
sys.modules['sphinx'] = sphinx = types.ModuleType('sphinx')
sphinx.addnodes = addnodes = types.SimpleNamespace()
addnodes.pending_xref = pending_xref
try:
import recommonmark
from recommonmark.parser import CommonMarkParser
except ImportError as err:
raise ImportError(
'Parsing "recommonmark" Markdown flavour requires the\n'
' package https://pypi.org/project/recommonmark.'
) from err
else:
if recommonmark.__version__ < '0.6.0':
raise ImportError('The installed version of "recommonmark" is too old.'
' Update with "pip install -U recommonmark".')
# auxiliary function for `document.findall()`
def is_literal(node):
return isinstance(node, (nodes.literal, nodes.literal_block))
class Parser(CommonMarkParser):
"""MarkDown parser based on recommonmark.
This parser is provisional:
the API is not settled and may change with any minor Docutils version.
"""
supported = ('recommonmark', 'commonmark', 'markdown', 'md')
"""Formats this parser supports."""
config_section = 'recommonmark parser'
config_section_dependencies = ('parsers',)
def get_transforms(self):
return Component.get_transforms(self) # + [AutoStructify]
def parse(self, inputstring, document):
"""Use the upstream parser and clean up afterwards.
"""
# check for exorbitantly long lines
for i, line in enumerate(inputstring.split('\n')):
if len(line) > document.settings.line_length_limit:
error = document.reporter.error(
'Line %d exceeds the line-length-limit.'%(i+1))
document.append(error)
return
# pass to upstream parser
try:
CommonMarkParser.parse(self, inputstring, document)
except Exception as err:
if document.settings.traceback:
raise err
error = document.reporter.error('Parsing with "recommonmark" '
'returned the error:\n%s'%err)
document.append(error)
# Post-Processing
# ---------------
# merge adjoining Text nodes:
for node in document.findall(nodes.TextElement):
children = node.children
i = 0
while i+1 < len(children):
if (isinstance(children[i], nodes.Text)
and isinstance(children[i+1], nodes.Text)):
children[i] = nodes.Text(children[i]+children.pop(i+1))
children[i].parent = node
else:
i += 1
# add "code" class argument to literal elements (inline and block)
for node in document.findall(is_literal):
if 'code' not in node['classes']:
node['classes'].append('code')
# move "language" argument to classes
for node in document.findall(nodes.literal_block):
if 'language' in node.attributes:
node['classes'].append(node['language'])
del node['language']
# replace raw nodes if raw is not allowed
if not document.settings.raw_enabled:
for node in document.findall(nodes.raw):
warning = document.reporter.warning('Raw content disabled.')
node.parent.replace(node, warning)
# drop pending_xref (Sphinx cross reference extension)
for node in document.findall(addnodes.pending_xref):
reference = node.children[0]
if 'name' not in reference:
reference['name'] = nodes.fully_normalize_name(
reference.astext())
node.parent.replace(node, reference)
def visit_document(self, node):
"""Dummy function to prevent spurious warnings.
cf. https://github.com/readthedocs/recommonmark/issues/177
"""
pass
# Overwrite parent method with version that
# doesn't pass deprecated `rawsource` argument to nodes.Text:
def visit_text(self, mdnode):
self.current_node.append(nodes.Text(mdnode.literal))

View file

@ -0,0 +1,413 @@
# $Id: __init__.py 9258 2022-11-21 14:51:43Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This is ``docutils.parsers.rst`` package. It exports a single class, `Parser`,
the reStructuredText parser.
Usage
=====
1. Create a parser::
parser = docutils.parsers.rst.Parser()
Several optional arguments may be passed to modify the parser's behavior.
Please see `Customizing the Parser`_ below for details.
2. Gather input (a multi-line string), by reading a file or the standard
input::
input = sys.stdin.read()
3. Create a new empty `docutils.nodes.document` tree::
document = docutils.utils.new_document(source, settings)
See `docutils.utils.new_document()` for parameter details.
4. Run the parser, populating the document tree::
parser.parse(input, document)
Parser Overview
===============
The reStructuredText parser is implemented as a state machine, examining its
input one line at a time. To understand how the parser works, please first
become familiar with the `docutils.statemachine` module, then see the
`states` module.
Customizing the Parser
----------------------
Anything that isn't already customizable is that way simply because that type
of customizability hasn't been implemented yet. Patches welcome!
When instantiating an object of the `Parser` class, two parameters may be
passed: ``rfc2822`` and ``inliner``. Pass ``rfc2822=True`` to enable an
initial RFC-2822 style header block, parsed as a "field_list" element (with
"class" attribute set to "rfc2822"). Currently this is the only body-level
element which is customizable without subclassing. (Tip: subclass `Parser`
and change its "state_classes" and "initial_state" attributes to refer to new
classes. Contact the author if you need more details.)
The ``inliner`` parameter takes an instance of `states.Inliner` or a subclass.
It handles inline markup recognition. A common extension is the addition of
further implicit hyperlinks, like "RFC 2822". This can be done by subclassing
`states.Inliner`, adding a new method for the implicit markup, and adding a
``(pattern, method)`` pair to the "implicit_dispatch" attribute of the
subclass. See `states.Inliner.implicit_inline()` for details. Explicit
inline markup can be customized in a `states.Inliner` subclass via the
``patterns.initial`` and ``dispatch`` attributes (and new methods as
appropriate).
"""
__docformat__ = 'reStructuredText'
import docutils.parsers
import docutils.statemachine
from docutils.parsers.rst import roles, states
from docutils import frontend, nodes
from docutils.transforms import universal
class Parser(docutils.parsers.Parser):
"""The reStructuredText parser."""
supported = ('rst', 'restructuredtext', 'rest', 'restx', 'rtxt', 'rstx')
"""Aliases this parser supports."""
settings_spec = docutils.parsers.Parser.settings_spec + (
'reStructuredText Parser Options',
None,
(('Recognize and link to standalone PEP references (like "PEP 258").',
['--pep-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for PEP references '
'(default "https://peps.python.org/").',
['--pep-base-url'],
{'metavar': '<URL>', 'default': 'https://peps.python.org/',
'validator': frontend.validate_url_trailing_slash}),
('Template for PEP file part of URL. (default "pep-%04d")',
['--pep-file-url-template'],
{'metavar': '<URL>', 'default': 'pep-%04d'}),
('Recognize and link to standalone RFC references (like "RFC 822").',
['--rfc-references'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Base URL for RFC references '
'(default "https://tools.ietf.org/html/").',
['--rfc-base-url'],
{'metavar': '<URL>', 'default': 'https://tools.ietf.org/html/',
'validator': frontend.validate_url_trailing_slash}),
('Set number of spaces for tab expansion (default 8).',
['--tab-width'],
{'metavar': '<width>', 'type': 'int', 'default': 8,
'validator': frontend.validate_nonnegative_int}),
('Remove spaces before footnote references.',
['--trim-footnote-reference-space'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
('Leave spaces before footnote references.',
['--leave-footnote-reference-space'],
{'action': 'store_false', 'dest': 'trim_footnote_reference_space'}),
('Token name set for parsing code with Pygments: one of '
'"long", "short", or "none" (no parsing). Default is "long".',
['--syntax-highlight'],
{'choices': ['long', 'short', 'none'],
'default': 'long', 'metavar': '<format>'}),
('Change straight quotation marks to typographic form: '
'one of "yes", "no", "alt[ernative]" (default "no").',
['--smart-quotes'],
{'default': False, 'metavar': '<yes/no/alt>',
'validator': frontend.validate_ternary}),
('Characters to use as "smart quotes" for <language>. ',
['--smartquotes-locales'],
{'metavar': '<language:quotes[,language:quotes,...]>',
'action': 'append',
'validator': frontend.validate_smartquotes_locales}),
('Inline markup recognized at word boundaries only '
'(adjacent to punctuation or whitespace). '
'Force character-level inline markup recognition with '
'"\\ " (backslash + space). Default.',
['--word-level-inline-markup'],
{'action': 'store_false', 'dest': 'character_level_inline_markup'}),
('Inline markup recognized anywhere, regardless of surrounding '
'characters. Backslash-escapes must be used to avoid unwanted '
'markup recognition. Useful for East Asian languages. '
'Experimental.',
['--character-level-inline-markup'],
{'action': 'store_true', 'default': False,
'dest': 'character_level_inline_markup'}),
)
)
config_section = 'restructuredtext parser'
config_section_dependencies = ('parsers',)
def __init__(self, rfc2822=False, inliner=None):
if rfc2822:
self.initial_state = 'RFC2822Body'
else:
self.initial_state = 'Body'
self.state_classes = states.state_classes
self.inliner = inliner
def get_transforms(self):
return super().get_transforms() + [universal.SmartQuotes]
def parse(self, inputstring, document):
"""Parse `inputstring` and populate `document`, a document tree."""
self.setup_parse(inputstring, document)
# provide fallbacks in case the document has only generic settings
self.document.settings.setdefault('tab_width', 8)
self.document.settings.setdefault('syntax_highlight', 'long')
self.statemachine = states.RSTStateMachine(
state_classes=self.state_classes,
initial_state=self.initial_state,
debug=document.reporter.debug_flag)
inputlines = docutils.statemachine.string2lines(
inputstring, tab_width=document.settings.tab_width,
convert_whitespace=True)
for i, line in enumerate(inputlines):
if len(line) > self.document.settings.line_length_limit:
error = self.document.reporter.error(
'Line %d exceeds the line-length-limit.'%(i+1))
self.document.append(error)
break
else:
self.statemachine.run(inputlines, document, inliner=self.inliner)
# restore the "default" default role after parsing a document
if '' in roles._roles:
del roles._roles['']
self.finish_parse()
class DirectiveError(Exception):
"""
Store a message and a system message level.
To be thrown from inside directive code.
Do not instantiate directly -- use `Directive.directive_error()`
instead!
"""
def __init__(self, level, message):
"""Set error `message` and `level`"""
Exception.__init__(self)
self.level = level
self.msg = message
class Directive:
"""
Base class for reStructuredText directives.
The following attributes may be set by subclasses. They are
interpreted by the directive parser (which runs the directive
class):
- `required_arguments`: The number of required arguments (default:
0).
- `optional_arguments`: The number of optional arguments (default:
0).
- `final_argument_whitespace`: A boolean, indicating if the final
argument may contain whitespace (default: False).
- `option_spec`: A dictionary, mapping known option names to
conversion functions such as `int` or `float` (default: {}, no
options). Several conversion functions are defined in the
directives/__init__.py module.
Option conversion functions take a single parameter, the option
argument (a string or ``None``), validate it and/or convert it
to the appropriate form. Conversion functions may raise
`ValueError` and `TypeError` exceptions.
- `has_content`: A boolean; True if content is allowed. Client
code must handle the case where content is required but not
supplied (an empty content list will be supplied).
Arguments are normally single whitespace-separated words. The
final argument may contain whitespace and/or newlines if
`final_argument_whitespace` is True.
If the form of the arguments is more complex, specify only one
argument (either required or optional) and set
`final_argument_whitespace` to True; the client code must do any
context-sensitive parsing.
When a directive implementation is being run, the directive class
is instantiated, and the `run()` method is executed. During
instantiation, the following instance variables are set:
- ``name`` is the directive type or name (string).
- ``arguments`` is the list of positional arguments (strings).
- ``options`` is a dictionary mapping option names (strings) to
values (type depends on option conversion functions; see
`option_spec` above).
- ``content`` is a list of strings, the directive content line by line.
- ``lineno`` is the absolute line number of the first line
of the directive.
- ``content_offset`` is the line offset of the first line
of the content from the beginning of the current input.
Used when initiating a nested parse.
- ``block_text`` is a string containing the entire directive.
- ``state`` is the state which called the directive function.
- ``state_machine`` is the state machine which controls the state
which called the directive function.
- ``reporter`` is the state machine's `reporter` instance.
Directive functions return a list of nodes which will be inserted
into the document tree at the point where the directive was
encountered. This can be an empty list if there is nothing to
insert.
For ordinary directives, the list must contain body elements or
structural elements. Some directives are intended specifically
for substitution definitions, and must return a list of `Text`
nodes and/or inline elements (suitable for inline insertion, in
place of the substitution reference). Such directives must verify
substitution definition context, typically using code like this::
if not isinstance(state, states.SubstitutionDef):
error = self.reporter.error(
'Invalid context: the "%s" directive can only be used '
'within a substitution definition.' % (name),
nodes.literal_block(block_text, block_text), line=lineno)
return [error]
"""
# There is a "Creating reStructuredText Directives" how-to at
# <https://docutils.sourceforge.io/docs/howto/rst-directives.html>. If you
# update this docstring, please update the how-to as well.
required_arguments = 0
"""Number of required directive arguments."""
optional_arguments = 0
"""Number of optional arguments after the required arguments."""
final_argument_whitespace = False
"""May the final argument contain whitespace?"""
option_spec = None
"""Mapping of option names to validator functions."""
has_content = False
"""May the directive have content?"""
def __init__(self, name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
self.name = name
self.arguments = arguments
self.options = options
self.content = content
self.lineno = lineno
self.content_offset = content_offset
self.block_text = block_text
self.state = state
self.state_machine = state_machine
self.reporter = state_machine.reporter
def run(self):
raise NotImplementedError('Must override run() in subclass.')
# Directive errors:
def directive_error(self, level, message):
"""
Return a DirectiveError suitable for being thrown as an exception.
Call "raise self.directive_error(level, message)" from within
a directive implementation to return one single system message
at level `level`, which automatically gets the directive block
and the line number added.
Preferably use the `debug`, `info`, `warning`, `error`, or `severe`
wrapper methods, e.g. ``self.error(message)`` to generate an
ERROR-level directive error.
"""
return DirectiveError(level, message)
def debug(self, message):
return self.directive_error(0, message)
def info(self, message):
return self.directive_error(1, message)
def warning(self, message):
return self.directive_error(2, message)
def error(self, message):
return self.directive_error(3, message)
def severe(self, message):
return self.directive_error(4, message)
# Convenience methods:
def assert_has_content(self):
"""
Throw an ERROR-level DirectiveError if the directive doesn't
have contents.
"""
if not self.content:
raise self.error('Content block expected for the "%s" directive; '
'none found.' % self.name)
def add_name(self, node):
"""Append self.options['name'] to node['names'] if it exists.
Also normalize the name string and register it as explicit target.
"""
if 'name' in self.options:
name = nodes.fully_normalize_name(self.options.pop('name'))
if 'name' in node:
del node['name']
node['names'].append(name)
self.state.document.note_explicit_target(node, node)
def convert_directive_function(directive_fn):
"""
Define & return a directive class generated from `directive_fn`.
`directive_fn` uses the old-style, functional interface.
"""
class FunctionalDirective(Directive):
option_spec = getattr(directive_fn, 'options', None)
has_content = getattr(directive_fn, 'content', False)
_argument_spec = getattr(directive_fn, 'arguments', (0, 0, False))
required_arguments, optional_arguments, final_argument_whitespace \
= _argument_spec
def run(self):
return directive_fn(
self.name, self.arguments, self.options, self.content,
self.lineno, self.content_offset, self.block_text,
self.state, self.state_machine)
# Return new-style directive.
return FunctionalDirective

View file

@ -0,0 +1,466 @@
# $Id: __init__.py 9426 2023-07-03 12:38:54Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
This package contains directive implementation modules.
"""
__docformat__ = 'reStructuredText'
import re
import codecs
from importlib import import_module
from docutils import nodes, parsers
from docutils.utils import split_escaped_whitespace, escape2null
from docutils.parsers.rst.languages import en as _fallback_language_module
_directive_registry = {
'attention': ('admonitions', 'Attention'),
'caution': ('admonitions', 'Caution'),
'code': ('body', 'CodeBlock'),
'danger': ('admonitions', 'Danger'),
'error': ('admonitions', 'Error'),
'important': ('admonitions', 'Important'),
'note': ('admonitions', 'Note'),
'tip': ('admonitions', 'Tip'),
'hint': ('admonitions', 'Hint'),
'warning': ('admonitions', 'Warning'),
'admonition': ('admonitions', 'Admonition'),
'sidebar': ('body', 'Sidebar'),
'topic': ('body', 'Topic'),
'line-block': ('body', 'LineBlock'),
'parsed-literal': ('body', 'ParsedLiteral'),
'math': ('body', 'MathBlock'),
'rubric': ('body', 'Rubric'),
'epigraph': ('body', 'Epigraph'),
'highlights': ('body', 'Highlights'),
'pull-quote': ('body', 'PullQuote'),
'compound': ('body', 'Compound'),
'container': ('body', 'Container'),
# 'questions': ('body', 'question_list'),
'table': ('tables', 'RSTTable'),
'csv-table': ('tables', 'CSVTable'),
'list-table': ('tables', 'ListTable'),
'image': ('images', 'Image'),
'figure': ('images', 'Figure'),
'contents': ('parts', 'Contents'),
'sectnum': ('parts', 'Sectnum'),
'header': ('parts', 'Header'),
'footer': ('parts', 'Footer'),
# 'footnotes': ('parts', 'footnotes'),
# 'citations': ('parts', 'citations'),
'target-notes': ('references', 'TargetNotes'),
'meta': ('misc', 'Meta'),
# 'imagemap': ('html', 'imagemap'),
'raw': ('misc', 'Raw'),
'include': ('misc', 'Include'),
'replace': ('misc', 'Replace'),
'unicode': ('misc', 'Unicode'),
'class': ('misc', 'Class'),
'role': ('misc', 'Role'),
'default-role': ('misc', 'DefaultRole'),
'title': ('misc', 'Title'),
'date': ('misc', 'Date'),
'restructuredtext-test-directive': ('misc', 'TestDirective'),
}
"""Mapping of directive name to (module name, class name). The
directive name is canonical & must be lowercase. Language-dependent
names are defined in the ``language`` subpackage."""
_directives = {}
"""Cache of imported directives."""
def directive(directive_name, language_module, document):
"""
Locate and return a directive function from its language-dependent name.
If not found in the current language, check English. Return None if the
named directive cannot be found.
"""
normname = directive_name.lower()
messages = []
msg_text = []
if normname in _directives:
return _directives[normname], messages
canonicalname = None
try:
canonicalname = language_module.directives[normname]
except AttributeError as error:
msg_text.append('Problem retrieving directive entry from language '
'module %r: %s.' % (language_module, error))
except KeyError:
msg_text.append('No directive entry for "%s" in module "%s".'
% (directive_name, language_module.__name__))
if not canonicalname:
try:
canonicalname = _fallback_language_module.directives[normname]
msg_text.append('Using English fallback for directive "%s".'
% directive_name)
except KeyError:
msg_text.append('Trying "%s" as canonical directive name.'
% directive_name)
# The canonical name should be an English name, but just in case:
canonicalname = normname
if msg_text:
message = document.reporter.info(
'\n'.join(msg_text), line=document.current_line)
messages.append(message)
try:
modulename, classname = _directive_registry[canonicalname]
except KeyError:
# Error handling done by caller.
return None, messages
try:
module = import_module('docutils.parsers.rst.directives.'+modulename)
except ImportError as detail:
messages.append(document.reporter.error(
'Error importing directive module "%s" (directive "%s"):\n%s'
% (modulename, directive_name, detail),
line=document.current_line))
return None, messages
try:
directive = getattr(module, classname)
_directives[normname] = directive
except AttributeError:
messages.append(document.reporter.error(
'No directive class "%s" in module "%s" (directive "%s").'
% (classname, modulename, directive_name),
line=document.current_line))
return None, messages
return directive, messages
def register_directive(name, directive):
"""
Register a nonstandard application-defined directive function.
Language lookups are not needed for such functions.
"""
_directives[name] = directive
# conversion functions for `Directive.option_spec`
# ------------------------------------------------
#
# see also `parsers.rst.Directive` in ../__init__.py.
def flag(argument):
"""
Check for a valid flag option (no argument) and return ``None``.
(Directive option conversion function.)
Raise ``ValueError`` if an argument is found.
"""
if argument and argument.strip():
raise ValueError('no argument is allowed; "%s" supplied' % argument)
else:
return None
def unchanged_required(argument):
"""
Return the argument text, unchanged.
(Directive option conversion function.)
Raise ``ValueError`` if no argument is found.
"""
if argument is None:
raise ValueError('argument required but none supplied')
else:
return argument # unchanged!
def unchanged(argument):
"""
Return the argument text, unchanged.
(Directive option conversion function.)
No argument implies empty string ("").
"""
if argument is None:
return ''
else:
return argument # unchanged!
def path(argument):
"""
Return the path argument unwrapped (with newlines removed).
(Directive option conversion function.)
Raise ``ValueError`` if no argument is found.
"""
if argument is None:
raise ValueError('argument required but none supplied')
else:
return ''.join(s.strip() for s in argument.splitlines())
def uri(argument):
"""
Return the URI argument with unescaped whitespace removed.
(Directive option conversion function.)
Raise ``ValueError`` if no argument is found.
"""
if argument is None:
raise ValueError('argument required but none supplied')
else:
parts = split_escaped_whitespace(escape2null(argument))
return ' '.join(''.join(nodes.unescape(part).split())
for part in parts)
def nonnegative_int(argument):
"""
Check for a nonnegative integer argument; raise ``ValueError`` if not.
(Directive option conversion function.)
"""
value = int(argument)
if value < 0:
raise ValueError('negative value; must be positive or zero')
return value
def percentage(argument):
"""
Check for an integer percentage value with optional percent sign.
(Directive option conversion function.)
"""
try:
argument = argument.rstrip(' %')
except AttributeError:
pass
return nonnegative_int(argument)
length_units = ['em', 'ex', 'px', 'in', 'cm', 'mm', 'pt', 'pc']
def get_measure(argument, units):
"""
Check for a positive argument of one of the units and return a
normalized string of the form "<value><unit>" (without space in
between).
(Directive option conversion function.)
To be called from directive option conversion functions.
"""
match = re.match(r'^([0-9.]+) *(%s)$' % '|'.join(units), argument)
try:
float(match.group(1))
except (AttributeError, ValueError):
raise ValueError(
'not a positive measure of one of the following units:\n%s'
% ' '.join('"%s"' % i for i in units))
return match.group(1) + match.group(2)
def length_or_unitless(argument):
return get_measure(argument, length_units + [''])
def length_or_percentage_or_unitless(argument, default=''):
"""
Return normalized string of a length or percentage unit.
(Directive option conversion function.)
Add <default> if there is no unit. Raise ValueError if the argument is not
a positive measure of one of the valid CSS units (or without unit).
>>> length_or_percentage_or_unitless('3 pt')
'3pt'
>>> length_or_percentage_or_unitless('3%', 'em')
'3%'
>>> length_or_percentage_or_unitless('3')
'3'
>>> length_or_percentage_or_unitless('3', 'px')
'3px'
"""
try:
return get_measure(argument, length_units + ['%'])
except ValueError:
try:
return get_measure(argument, ['']) + default
except ValueError:
# raise ValueError with list of valid units:
return get_measure(argument, length_units + ['%'])
def class_option(argument):
"""
Convert the argument into a list of ID-compatible strings and return it.
(Directive option conversion function.)
Raise ``ValueError`` if no argument is found.
"""
if argument is None:
raise ValueError('argument required but none supplied')
names = argument.split()
class_names = []
for name in names:
class_name = nodes.make_id(name)
if not class_name:
raise ValueError('cannot make "%s" into a class name' % name)
class_names.append(class_name)
return class_names
unicode_pattern = re.compile(
r'(?:0x|x|\\x|U\+?|\\u)([0-9a-f]+)$|&#x([0-9a-f]+);$', re.IGNORECASE)
def unicode_code(code):
r"""
Convert a Unicode character code to a Unicode character.
(Directive option conversion function.)
Codes may be decimal numbers, hexadecimal numbers (prefixed by ``0x``,
``x``, ``\x``, ``U+``, ``u``, or ``\u``; e.g. ``U+262E``), or XML-style
numeric character entities (e.g. ``&#x262E;``). Other text remains as-is.
Raise ValueError for illegal Unicode code values.
"""
try:
if code.isdigit(): # decimal number
return chr(int(code))
else:
match = unicode_pattern.match(code)
if match: # hex number
value = match.group(1) or match.group(2)
return chr(int(value, 16))
else: # other text
return code
except OverflowError as detail:
raise ValueError('code too large (%s)' % detail)
def single_char_or_unicode(argument):
"""
A single character is returned as-is. Unicode character codes are
converted as in `unicode_code`. (Directive option conversion function.)
"""
char = unicode_code(argument)
if len(char) > 1:
raise ValueError('%r invalid; must be a single character or '
'a Unicode code' % char)
return char
def single_char_or_whitespace_or_unicode(argument):
"""
As with `single_char_or_unicode`, but "tab" and "space" are also supported.
(Directive option conversion function.)
"""
if argument == 'tab':
char = '\t'
elif argument == 'space':
char = ' '
else:
char = single_char_or_unicode(argument)
return char
def positive_int(argument):
"""
Converts the argument into an integer. Raises ValueError for negative,
zero, or non-integer values. (Directive option conversion function.)
"""
value = int(argument)
if value < 1:
raise ValueError('negative or zero value; must be positive')
return value
def positive_int_list(argument):
"""
Converts a space- or comma-separated list of values into a Python list
of integers.
(Directive option conversion function.)
Raises ValueError for non-positive-integer values.
"""
if ',' in argument:
entries = argument.split(',')
else:
entries = argument.split()
return [positive_int(entry) for entry in entries]
def encoding(argument):
"""
Verifies the encoding argument by lookup.
(Directive option conversion function.)
Raises ValueError for unknown encodings.
"""
try:
codecs.lookup(argument)
except LookupError:
raise ValueError('unknown encoding: "%s"' % argument)
return argument
def choice(argument, values):
"""
Directive option utility function, supplied to enable options whose
argument must be a member of a finite set of possible values (must be
lower case). A custom conversion function must be written to use it. For
example::
from docutils.parsers.rst import directives
def yesno(argument):
return directives.choice(argument, ('yes', 'no'))
Raise ``ValueError`` if no argument is found or if the argument's value is
not valid (not an entry in the supplied list).
"""
try:
value = argument.lower().strip()
except AttributeError:
raise ValueError('must supply an argument; choose from %s'
% format_values(values))
if value in values:
return value
else:
raise ValueError('"%s" unknown; choose from %s'
% (argument, format_values(values)))
def format_values(values):
return '%s, or "%s"' % (', '.join('"%s"' % s for s in values[:-1]),
values[-1])
def value_or(values, other):
"""
Directive option conversion function.
The argument can be any of `values` or `argument_type`.
"""
def auto_or_other(argument):
if argument in values:
return argument
else:
return other(argument)
return auto_or_other
def parser_name(argument):
"""
Return a docutils parser whose name matches the argument.
(Directive option conversion function.)
Return `None`, if the argument evaluates to `False`.
Raise `ValueError` if importing the parser module fails.
"""
if not argument:
return None
try:
return parsers.get_parser_class(argument)
except ImportError as err:
raise ValueError(str(err))

View file

@ -0,0 +1,101 @@
# $Id: admonitions.py 9475 2023-11-13 22:30:00Z milde $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.
"""
Admonition directives.
"""
__docformat__ = 'reStructuredText'
from docutils.parsers.rst import Directive
from docutils.parsers.rst import directives
from docutils.parsers.rst.roles import set_classes
from docutils import nodes
class BaseAdmonition(Directive):
final_argument_whitespace = True
option_spec = {'class': directives.class_option,
'name': directives.unchanged}
has_content = True
node_class = None
"""Subclasses must set this to the appropriate admonition node class."""
def run(self):
set_classes(self.options)
self.assert_has_content()
text = '\n'.join(self.content)
admonition_node = self.node_class(text, **self.options)
self.add_name(admonition_node)
admonition_node.source, admonition_node.line = \
self.state_machine.get_source_and_line(self.lineno)
if self.node_class is nodes.admonition:
title_text = self.arguments[0]
textnodes, messages = self.state.inline_text(title_text,
self.lineno)
title = nodes.title(title_text, '', *textnodes)
title.source, title.line = (
self.state_machine.get_source_and_line(self.lineno))
admonition_node += title
admonition_node += messages
if 'classes' not in self.options:
admonition_node['classes'] += ['admonition-'
+ nodes.make_id(title_text)]
self.state.nested_parse(self.content, self.content_offset,
admonition_node)
return [admonition_node]
class Admonition(BaseAdmonition):
required_arguments = 1
node_class = nodes.admonition
class Attention(BaseAdmonition):
node_class = nodes.attention
class Caution(BaseAdmonition):
node_class = nodes.caution
class Danger(BaseAdmonition):
node_class = nodes.danger
class Error(BaseAdmonition):
node_class = nodes.error
class Hint(BaseAdmonition):
node_class = nodes.hint
class Important(BaseAdmonition):
node_class = nodes.important
class Note(BaseAdmonition):
node_class = nodes.note
class Tip(BaseAdmonition):
node_class = nodes.tip
class Warning(BaseAdmonition):
node_class = nodes.warning

Some files were not shown because too many files have changed in this diff Show more