From cf7da1843c45a4c2df7a749f7886a2d2ba0ee92a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 19:25:40 +0200 Subject: Adding upstream version 7.2.6. Signed-off-by: Daniel Baumann --- sphinx/parsers.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 sphinx/parsers.py (limited to 'sphinx/parsers.py') diff --git a/sphinx/parsers.py b/sphinx/parsers.py new file mode 100644 index 0000000..1269884 --- /dev/null +++ b/sphinx/parsers.py @@ -0,0 +1,97 @@ +"""A Base class for additional parsers.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any + +import docutils.parsers +import docutils.parsers.rst +from docutils import nodes +from docutils.parsers.rst import states +from docutils.statemachine import StringList +from docutils.transforms.universal import SmartQuotes + +from sphinx.util.rst import append_epilog, prepend_prolog + +if TYPE_CHECKING: + from docutils.transforms import Transform + + from sphinx.application import Sphinx + from sphinx.config import Config + from sphinx.environment import BuildEnvironment + + +class Parser(docutils.parsers.Parser): + """ + A base class of source parsers. The additional parsers should inherit this class instead + of ``docutils.parsers.Parser``. Compared with ``docutils.parsers.Parser``, this class + improves accessibility to Sphinx APIs. + + The subclasses can access sphinx core runtime objects (app, config and env). + """ + + #: The config object + config: Config + + #: The environment object + env: BuildEnvironment + + def set_application(self, app: Sphinx) -> None: + """set_application will be called from Sphinx to set app and other instance variables + + :param sphinx.application.Sphinx app: Sphinx application object + """ + self._app = app + self.config = app.config + self.env = app.env + + +class RSTParser(docutils.parsers.rst.Parser, Parser): + """A reST parser for Sphinx.""" + + def get_transforms(self) -> list[type[Transform]]: + """ + Sphinx's reST parser replaces a transform class for smart-quotes by its own + + refs: sphinx.io.SphinxStandaloneReader + """ + transforms = super().get_transforms() + transforms.remove(SmartQuotes) + return transforms + + def parse(self, inputstring: str | StringList, document: nodes.document) -> None: + """Parse text and generate a document tree.""" + self.setup_parse(inputstring, document) # type: ignore[arg-type] + self.statemachine = states.RSTStateMachine( + state_classes=self.state_classes, + initial_state=self.initial_state, + debug=document.reporter.debug_flag) + + # preprocess inputstring + if isinstance(inputstring, str): + lines = docutils.statemachine.string2lines( + inputstring, tab_width=document.settings.tab_width, + convert_whitespace=True) + + inputlines = StringList(lines, document.current_source) + else: + inputlines = inputstring + + self.decorate(inputlines) + self.statemachine.run(inputlines, document, inliner=self.inliner) + self.finish_parse() + + def decorate(self, content: StringList) -> None: + """Preprocess reST content before parsing.""" + prepend_prolog(content, self.config.rst_prolog) + append_epilog(content, self.config.rst_epilog) + + +def setup(app: Sphinx) -> dict[str, Any]: + app.add_source_parser(RSTParser) + + return { + 'version': 'builtin', + 'parallel_read_safe': True, + 'parallel_write_safe': True, + } -- cgit v1.2.3