Source code for myst_parser.mdit_to_docutils.sphinx_

"""Convert Markdown-it tokens to docutils nodes, including sphinx specific elements."""
from __future__ import annotations

import os
from pathlib import Path
from typing import cast
from urllib.parse import unquote
from uuid import uuid4

from docutils import nodes
from markdown_it.tree import SyntaxTreeNode
from sphinx import addnodes
from sphinx.domains.math import MathDomain
from sphinx.environment import BuildEnvironment
from sphinx.ext.intersphinx import InventoryAdapter
from sphinx.util import logging

from myst_parser import inventory
from myst_parser.mdit_to_docutils.base import DocutilsRenderer

LOGGER = logging.getLogger(__name__)


[docs]class SphinxRenderer(DocutilsRenderer): """A markdown-it-py renderer to populate (in-place) a `docutils.document` AST. This is sub-class of `DocutilsRenderer` that handles sphinx specific aspects, such as cross-referencing. """ @property def sphinx_env(self) -> BuildEnvironment: return self.document.settings.env def get_inventory_matches( self, *, invs: str | None, domains: str | None, otypes: str | None, target: str | None, ) -> list[inventory.InvMatch]: return list( inventory.filter_sphinx_inventories( InventoryAdapter(self.sphinx_env).named_inventory, invs=invs, domains=domains, otypes=otypes, targets=target, ) )
[docs] def render_math_block_label(self, token: SyntaxTreeNode) -> None: """Render math with referencable labels, e.g. ``$a=1$ (label)``.""" label = token.info content = token.content node = nodes.math_block( content, content, nowrap=False, number=None, label=label ) target = self.add_math_target(node) self.add_line_and_source_path(target, token) self.current_node.append(target) self.add_line_and_source_path(node, token) self.current_node.append(node)
def _random_label(self) -> str: return str(uuid4()) def render_amsmath(self, token: SyntaxTreeNode) -> None: """Renderer for the amsmath extension.""" # environment = token.meta["environment"] content = token.content if token.meta["numbered"] != "*": # TODO how to parse and reference labels within environment? # for now we give create a unique hash, so the equation will be numbered # but there will be no reference clashes label = self._random_label() node = nodes.math_block( content, content, nowrap=True, number=None, classes=["amsmath"], label=label, ) target = self.add_math_target(node) self.add_line_and_source_path(target, token) self.current_node.append(target) else: node = nodes.math_block( content, content, nowrap=True, number=None, classes=["amsmath"] ) self.add_line_and_source_path(node, token) self.current_node.append(node) def add_math_target(self, node: nodes.math_block) -> nodes.target: # Code mainly copied from sphinx.directives.patches.MathDirective # register label to domain domain = cast(MathDomain, self.sphinx_env.get_domain("math")) domain.note_equation(self.sphinx_env.docname, node["label"], location=node) node["number"] = domain.get_equation_number_for(node["label"]) node["docname"] = self.sphinx_env.docname # create target node node_id = nodes.make_id("equation-%s" % node["label"]) target = nodes.target("", "", ids=[node_id]) self.document.note_explicit_target(target) return target