Skip to content

Commit 354dbb2

Browse files
kinowmr-c
authored andcommitted
Patch MyST to keep the context needed to translate Markdown files
1 parent 8efb720 commit 354dbb2

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

src/conf.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,3 +238,85 @@
238238
gettext_uuid = True
239239
gettext_compact = "user_guide"
240240
locale_dirs = ['../locales/']
241+
242+
243+
# Patched MyST parser
244+
# from __future__ import annotations
245+
246+
from docutils import nodes
247+
from docutils.parsers.rst import Parser as RstParser
248+
from sphinx.parsers import Parser as SphinxParser
249+
from sphinx.util import logging
250+
251+
from myst_parser.config.main import (
252+
MdParserConfig,
253+
TopmatterReadError,
254+
merge_file_level,
255+
read_topmatter,
256+
)
257+
from myst_parser.mdit_to_docutils.sphinx_ import SphinxRenderer, create_warning
258+
from myst_parser.parsers.mdit import create_md_parser
259+
260+
SPHINX_LOGGER = logging.getLogger(__name__)
261+
262+
class MystParser(SphinxParser):
263+
"""Sphinx parser for Markedly Structured Text (MyST)."""
264+
265+
supported: tuple[str, ...] = ("md", "markdown", "myst")
266+
"""Aliases this parser supports."""
267+
268+
settings_spec = RstParser.settings_spec
269+
"""Runtime settings specification.
270+
Defines runtime settings and associated command-line options, as used by
271+
`docutils.frontend.OptionParser`. This is a concatenation of tuples of:
272+
- Option group title (string or `None` which implies no group, just a list
273+
of single options).
274+
- Description (string or `None`).
275+
- A sequence of option tuples
276+
"""
277+
278+
config_section = "myst parser"
279+
config_section_dependencies = ("parsers",)
280+
translate_section_name = None
281+
282+
def parse(self, inputstring: str, document: nodes.document) -> None:
283+
"""Parse source text.
284+
:param inputstring: The source string to parse
285+
:param document: The root docutils node to add AST elements to
286+
"""
287+
# get the global config
288+
config: MdParserConfig = document.settings.env.myst_config
289+
290+
# update the global config with the file-level config
291+
try:
292+
topmatter = read_topmatter(inputstring)
293+
except TopmatterReadError:
294+
pass # this will be reported during the render
295+
else:
296+
if topmatter:
297+
warning = lambda wtype, msg: create_warning( # noqa: E731
298+
document, msg, line=1, append_to=document, subtype=wtype
299+
)
300+
config = merge_file_level(config, topmatter, warning)
301+
302+
parser = create_md_parser(config, SphinxRenderer)
303+
# TODO: In the first pass, the call above will use MarkdownIt over the whole document,
304+
# populating the ``.md_env`` correctly. Over the next passes, from transforms as
305+
# ``sphinx.transforms.i18n.Locale`` it will create a blank new document, as well
306+
# as a new MarkdownIT parser but using just the Docutils document that is being
307+
# translated. As a result of this, the translation has no reference-links, and it
308+
# gives you the translation without resolving the links. Here we just re-use the
309+
# ``md_env`` dictionary that contains the ``.references`` populated in the first
310+
# pass, fixing i18n with MyST Parser.
311+
env = {} if not hasattr(document.settings, 'md_env') else document.settings.md_env
312+
parser.options["document"] = document
313+
parser.render(inputstring, env)
314+
document.settings.md_env = parser.renderer.md_env
315+
316+
317+
def setup(app):
318+
"""Sphinx setup callback."""
319+
320+
# TODO: Here we replace the MySTParser (that replaces the Sphinx default parser...),
321+
# with our patched version above.
322+
app.add_source_parser(MystParser, override=True)

0 commit comments

Comments
 (0)