markdownpython-sphinxdocutilsmyst

Sphinx custom directive parsing markdown


So, I know I can invoke parsing of a content nested in a directive via nested_parse, namely:

vl = docutils.statemachine.ViewList(inputLines, source=self.content.source, parent=self.content, parent_offset=0)
self.state.nested_parse(vl, 0, section)

However, this assumes the input I pass to it is in RST. I tried something like

parser = MystParser()
docu = docutils.utils.new_document(".")
parser.parse("**Some Markdown** `goes here`", docu)

...which I found in some documentation samples, but it fails on docu missing some attributes. Moreover, I do not really want to create a new document; just append content to an existing node.

Is there any way to nested parse Markdown explicitly from within a directive? I use the latest sphinx docker image sphinxdoc/sphinx:latest.

EDIT: I also tried

with tempfile.NamedTemporaryFile() as tmp:
    tmp.write(schemaObject["description"].encode("utf-8"))
    content = f"""
.. include:: "{tmp.name}"
   :parser: myst_parser.sphinx_
"""
    vl = docutils.statemachine.ViewList(content.splitlines(), source=self.content.source, parent=self.content, parent_offset=0)
    self.state.nested_parse(vl, 0, section)

but for some reason, I get

expected str, bytes or os.PathLike object, not method

Solution

  • Okay, so I eventually found a working solution. Not proud of it.

    from sphinx.util.docutils import new_document
    from docutils import nodes
    from myst_parser.parsers.sphinx_ import MystParser
    
    
    # within the directive run(self)
    title = nodes.title(text=schemaTitle)
    section = nodes.section(ids=title)
    section += title
    
    parser = MystParser()
    document = new_document(".")
    document.settings.env = self.env
    parser.parse("..my markdown content", document)
    section += document.children