diff --git a/CHANGES b/CHANGES index e95c6a132..8bac61c1a 100644 --- a/CHANGES +++ b/CHANGES @@ -54,6 +54,7 @@ Deprecated * The ``language`` argument of ``sphinx.util.i18n:format_date()`` becomes required * ``sphinx.builders.html.html5_ready`` +* ``sphinx.io.read_doc()`` * ``sphinx.util.docutils.__version_info__`` * ``sphinx.util.docutils.is_html5_writer_available()`` * ``sphinx.writers.latex.LaTeXWriter.docclasses`` diff --git a/doc/extdev/deprecated.rst b/doc/extdev/deprecated.rst index 5a03f821a..98bd463a9 100644 --- a/doc/extdev/deprecated.rst +++ b/doc/extdev/deprecated.rst @@ -47,6 +47,11 @@ The following is a list of deprecated interfaces. - 7.0 - N/A + * - ``sphinx.io.read_doc()`` + - 5.0 + - 7.0 + - ``sphinx.builders.Builder.read_doc()`` + * - ``sphinx.util.docutils.__version_info__`` - 5.0 - 7.0 diff --git a/sphinx/io.py b/sphinx/io.py index b4cec7d3e..5ab7b2b63 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -1,5 +1,6 @@ """Input/Output files""" - +import codecs +import warnings from typing import TYPE_CHECKING, Any, List, Type from docutils import nodes @@ -7,19 +8,21 @@ from docutils.core import Publisher from docutils.frontend import Values from docutils.io import FileInput, Input, NullOutput from docutils.parsers import Parser +from docutils.parsers.rst import Parser as RSTParser from docutils.readers import standalone from docutils.transforms import Transform from docutils.transforms.references import DanglingReferences from docutils.writers import UnfilteredWriter from sphinx import addnodes +from sphinx.deprecation import RemovedInSphinx70Warning from sphinx.environment import BuildEnvironment from sphinx.transforms import (AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer) from sphinx.transforms.i18n import (Locale, PreserveTranslatableMessages, RemoveTranslatableInline) from sphinx.transforms.references import SphinxDomains -from sphinx.util import logging +from sphinx.util import UnicodeDecodeErrorHandler, get_filetype, logging from sphinx.util.docutils import LoggingReporter from sphinx.versioning import UIDTransform @@ -152,6 +155,38 @@ class SphinxFileInput(FileInput): super().__init__(*args, **kwargs) +def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.document: + """Parse a document and convert to doctree.""" + warnings.warn('sphinx.io.read_doc() is deprecated.', + RemovedInSphinx70Warning, stacklevel=2) + + # set up error_handler for the target document + error_handler = UnicodeDecodeErrorHandler(env.docname) + codecs.register_error('sphinx', error_handler) # type: ignore + + reader = SphinxStandaloneReader() + reader.setup(app) + filetype = get_filetype(app.config.source_suffix, filename) + parser = app.registry.create_source_parser(app, filetype) + if parser.__class__.__name__ == 'CommonMarkParser' and parser.settings_spec == (): + # a workaround for recommonmark + # If recommonmark.AutoStrictify is enabled, the parser invokes reST parser + # internally. But recommonmark-0.4.0 does not provide settings_spec for reST + # parser. As a workaround, this copies settings_spec for RSTParser to the + # CommonMarkParser. + parser.settings_spec = RSTParser.settings_spec + + pub = Publisher(reader=reader, + parser=parser, + writer=SphinxDummyWriter(), + source_class=SphinxFileInput, + destination=NullOutput()) + pub.process_programmatic_settings(None, env.settings, None) + pub.set_source(source_path=filename) + pub.publish() + return pub.document + + def create_publisher(app: "Sphinx", filetype: str) -> Publisher: reader = SphinxStandaloneReader() reader.setup(app)