Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force Sphinx to interpret Markdown in Python docstrings instead of reStructuredText

I'm using Sphinx to document a python project. I would like to use Markdown in my docstrings to format them. Even if I use the recommonmark extension, it only covers the .md files written manually, not the docstrings.

I use autodoc, napoleon and recommonmark in my extensions.

How can I make sphinx parse markdown in my docstrings?

like image 513
Florentin Hennecker Avatar asked May 09 '19 15:05

Florentin Hennecker


People also ask

Does Sphinx work with markdown?

Markdown and reStructuredText can be used in the same Sphinx project. Markdown doesn't support a lot of the features of Sphinx, like inline markup and directives. However, it works for basic prose content.

Are docstrings interpreted by Python?

They are completely ignored by the Python interpreter. Note: We use triple quotation marks for multi-line strings. As mentioned above, Python docstrings are strings used right after the definition of a function, method, class, or module (like in Example 1). They are used to document our code.

How do you access docstrings in Python?

Accessing Docstrings: The docstrings can be accessed using the __doc__ method of the object or using the help function.

Can docstrings be assigned to variables?

No, it is not possible and it wouldn't be useful if you could. The docstring is always an attribute of an object (module, class or function), not tied to a specific variable.


1 Answers

Sphinx's Autodoc extension emits an event named autodoc-process-docstring every time it processes a doc-string. We can hook into that mechanism to convert the syntax from Markdown to reStructuredText.

Unfortunately, Recommonmark does not expose a Markdown-to-reST converter. It maps the parsed Markdown directly to a Docutils object, i.e., the same representation that Sphinx itself creates internally from reStructuredText.

Instead, I use Commonmark for the conversion in my projects. Because it's fast — much faster than Pandoc, for example. Speed is important as the conversion happens on the fly and handles each doc-string individually. Other than that, any Markdown-to-reST converter would do. M2R2 would be a third example. The downside of any of these is that they do not support Recommonmark's syntax extensions, such as cross-references to other parts of the documentation. Just the basic Markdown.

To plug in the Commonmark doc-string converter, make sure that package is installed (pip install commonmark) and add the following to Sphinx's configuration file conf.py:

import commonmark

def docstring(app, what, name, obj, options, lines):
    md  = '\n'.join(lines)
    ast = commonmark.Parser().parse(md)
    rst = commonmark.ReStructuredTextRenderer().render(ast)
    lines.clear()
    lines += rst.splitlines()

def setup(app):
    app.connect('autodoc-process-docstring', docstring)

Meanwhile, Recommonmark was deprecated in May 2021. The Sphinx extension MyST, a more feature-rich Markdown parser, is the replacement recommended by Sphinx and by Read-the-Docs. MyST does not yet support Markdown in doc-strings either, but the same hook as above can be used to get limited support via Commonmark.

A possible alternative to the approach outlined here is using MkDocs with the MkDocStrings plug-in, which would eliminate Sphinx and reStructuredText entirely from the process.

like image 72
john-hen Avatar answered Oct 17 '22 16:10

john-hen