# $Id: __init__.py 9930 2024-09-13 08:13:03Z milde $ # Author: David Goodger # 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 __future__ import annotations from collections import namedtuple from typing import TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Sequence from typing import Any, ClassVar, Literal, Protocol, Union from docutils.nodes import Element from docutils.transforms import Transform _Components = Literal['reader', 'parser', 'writer', 'input', 'output'] _OptionTuple = tuple[str, list[str], dict[str, Any]] _ReleaseLevels = Literal['alpha', 'beta', 'candidate', 'final'] _SettingsSpecTuple = Union[ tuple[str|None, str|None, Sequence[_OptionTuple]], tuple[str|None, str|None, Sequence[_OptionTuple], str|None, str|None, Sequence[_OptionTuple]], tuple[str|None, str|None, Sequence[_OptionTuple], str|None, str|None, Sequence[_OptionTuple], str|None, str|None, Sequence[_OptionTuple]], ] class _UnknownReferenceResolver(Protocol): """See `TransformSpec.unknown_reference_resolvers`.""" priority: int def __call__(self, node: Element, /) -> bool: ... __docformat__ = 'reStructuredText' __version__ = '0.22b.dev' """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')): __slots__ = () major: int minor: int micro: int releaselevel: _ReleaseLevels serial: int release: bool def __new__(cls, major: int = 0, minor: int = 0, micro: int = 0, releaselevel: _ReleaseLevels = 'final', serial: int = 0, release: bool = True, ) -> VersionInfo: 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: E501 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: object) -> bool: if isinstance(other, tuple): other = VersionInfo(*other) return tuple.__lt__(self, other) def __gt__(self, other: object) -> bool: if isinstance(other, tuple): other = VersionInfo(*other) return tuple.__gt__(self, other) def __le__(self, other: object) -> bool: if isinstance(other, tuple): other = VersionInfo(*other) return tuple.__le__(self, other) def __ge__(self, other: object) -> bool: if isinstance(other, tuple): other = VersionInfo(*other) return tuple.__ge__(self, other) __version_info__ = VersionInfo( major=0, minor=22, micro=0, releaselevel='beta', # one of 'alpha', 'beta', 'candidate', 'final' serial=0, # pre-release number (0 for final releases and snapshots) release=False # 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: ClassVar[_SettingsSpecTuple] = () """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: ClassVar[dict[str, Any] | None] = 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: ClassVar[dict[str, Any] | None] = None """A dictionary of auxiliary defaults, to override defaults for settings defined in other components' `setting_specs`. Override in subclasses.""" relative_path_settings: ClassVar[tuple[str, ...]] = () """Settings containing filesystem paths. Override in subclasses. Settings listed here are to be interpreted relative to the current working directory.""" config_section: ClassVar[str | None] = None """The name of the config file section specific to this component (lowercase, no brackets). Override in subclasses.""" config_section_dependencies: ClassVar[tuple[str, ...] | None] = 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) -> list[type[Transform]]: """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: ClassVar[tuple[()]] = () unknown_reference_resolvers: Sequence[_UnknownReferenceResolver] = () """List of hook functions which assist in resolving references. Override in subclasses to implement component-specific resolving of 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: nodes.Element) -> bool: '''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 = True Each function must have a "priority" attribute which will affect the order the unknown_reference_resolvers are run cf. ../docs/api/transforms.html#transform-priority-range-categories :: reference_resolver.priority = 500 Examples: `writers.latex2e.Writer` defines a resolver to mark citation references as resolved by BibTeX if the "use_bibtex" configuration setting is set. The `MoinMoin ReStructured Text Parser`__ provides a resolver for "WikiWiki links" (currently only in the outdated 1.9 version). __ https://github.com/moinwiki/moin-1.9/blob/1.9.11/MoinMoin/parser/ text_rst.py """ class Component(SettingsSpec, TransformSpec): """Base class for Docutils components.""" component_type: ClassVar[_Components | None] = None """Name of the component type ('reader', 'parser', 'writer'). Override in subclasses.""" supported: ClassVar[tuple[str, ...]] = () """Name and aliases for this component. Override in subclasses.""" def supports(self, format: str) -> bool: """ 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