sphinx-markdown-parser

August 12, 2026 ยท View on GitHub

Write markdown inside of docutils & Sphinx projects.

This is a docutils-compatibility bridge to Python-Markdown and commonmark.py. It grew out of recommonmark at a time when recommonmark lacked features such as tables, and it keeps that lineage's AutoStructify transform for embedding reStructuredText inside markdown.

Should you use this or MyST?

For most new Sphinx projects you should use MyST (myst-parser). It is the parser the Sphinx ecosystem standardized on after recommonmark was deprecated: CommonMark-based, actively maintained, and it exposes Sphinx roles and directives natively in markdown.

This project fills a narrower niche. Reach for it when:

  • You want the Python-Markdown dialect, not CommonMark โ€” for example your content relies on Python-Markdown extensions such as extra, toc, wikilinks, or nl2br, or on the PyMdown Extensions ecosystem.
  • You are maintaining a recommonmark-era project and want to keep the AutoStructify behaviors (eval_rst blocks, auto toc trees, $...$ inline math) without rewriting your markdown.
  • You want the md2html, md2latex, ... CLI bridges for rendering markdown through plain docutils.

Parsers

ParserUnderlying Library
MarkdownParserhttps://github.com/Python-Markdown/markdown
CommonMarkParserhttps://github.com/readthedocs/commonmark.py

MarkdownParser is the recommended and officially supported parser:

  • It has more features, such as tables and the Python-Markdown extension ecosystem.
  • Its underlying library is actively maintained.

CommonMarkParser is kept for backwards compatibility, but its underlying library (commonmark.py) is unmaintained. If you want CommonMark, use MyST instead.

Getting Started

Install the package:

uv add sphinx-markdown-parser
# or
pip install sphinx-markdown-parser

If using MarkdownParser, you may also want to install some extensions for it:

uv add pymdown-extensions

Then enable the extension in your Sphinx conf.py:

extensions = [
    "sphinx_markdown_parser",
]

markdown_parser_config = {
    "extensions": [
        "extra",
        "nl2br",
        "sane_lists",
        "smarty",
        "toc",
        "wikilinks",
    ],
}

This registers MarkdownParser for .md sources. This allows you to write both .md and .rst files inside of the same project.

Manual setup

If you need the CommonMarkParser, a custom source suffix, or more control, skip the extension and register a parser yourself (do not combine this with the extensions entry above):

# for MarkdownParser
from sphinx_markdown_parser.parser import MarkdownParser


def setup(app):
    app.add_source_suffix(".md", "markdown")
    app.add_source_parser(MarkdownParser)
    app.add_config_value(
        "markdown_parser_config",
        {
            "auto_toc_tree_section": "Content",
            "enable_auto_toc_tree": True,
            "enable_eval_rst": True,
            "extensions": [
                "extra",
                "nl2br",
                "sane_lists",
                "smarty",
                "toc",
                "wikilinks",
                "pymdownx.arithmatex",
            ],
        },
        "env",
    )


# for CommonMarkParser (please see the note above!)
from sphinx_markdown_parser.parser import CommonMarkParser


def setup(app):
    app.add_source_suffix(".md", "markdown")
    app.add_source_parser(CommonMarkParser)
    app.add_config_value(
        "markdown_parser_config",
        {
            "auto_toc_tree_section": "Content",
            "enable_auto_toc_tree": True,
            "enable_eval_rst": True,
            "enable_inline_math": True,
            "enable_math": True,
        },
        "env",
    )

Frontmatter

YAML frontmatter at the top of a markdown file is stripped from the rendered output and exposed as document metadata (env.metadata in Sphinx). Sphinx metadata fields work from markdown, for example:

---
orphan: true
author: Ada Lovelace
---

# My Page

For all links in commonmark that aren't explicit URLs, they are treated as cross references with the :any: role. This allows referencing a lot of things including files, labels, and even objects in the loaded domain. MarkdownParser additionally rewrites relative links to .md files into links to the built .html pages.

AutoStructify

AutoStructify makes it possible to write your documentation in Markdown, and automatically convert this into rST at build time. See the AutoStructify documentation for more information about configuration and usage.

To use the advanced markdown to rst transformations you must add AutoStructify to your Sphinx conf.py:

# At top on conf.py (with other import statements)
from sphinx_markdown_parser.transform import AutoStructify


# At the bottom of conf.py
def setup(app):
    app.add_config_value(
        "markdown_parser_config",
        {
            "auto_toc_tree_section": "Contents",
        },
        "env",
    )
    app.add_transform(AutoStructify)

AutoStructify comes with the following options:

  • enable_auto_toc_tree: enable the Auto Toc Tree feature.
  • auto_toc_tree_section: when set, Auto Toc Tree will only be enabled on sections that match the title.
  • enable_auto_doc_ref: enable the Auto Doc Ref feature. Deprecated
  • enable_math: enable the Math Formula feature.
  • enable_inline_math: enable the Inline Math feature.
  • enable_eval_rst: enable the evaluate embedded reStructuredText feature.
  • url_resolver: a function that maps an existing relative position in the document to an http link

CLI

The package installs docutils front ends for rendering markdown directly: md2html, md2latex, md2man, md2pseudoxml, md2xetex, and md2xml.

md2html README.md > README.html

Development

The project is managed with uv and a conventions-aligned Makefile:

make prepare    # one-time toolchain setup (asdf install + uv sync)
make test       # unit + integration tests with coverage
make test/e2e   # build the sample Sphinx project end to end
make lint       # black --check + basedpyright
make format     # black
make build      # build sdist + wheel into dist/
make docs       # build the documentation

Why a bridge?

Many python tools (mostly for documentation creation) rely on docutils. But docutils only supports a ReStructuredText syntax.

For instance this issue and this StackOverflow question show that there is an interest in allowing docutils to use markdown as an alternative syntax.

Acknowledgement

sphinx-markdown-parser is based on recommonmark.

recommonmark is mainly derived from remarkdown by Steve Genoud and leverages the python CommonMark implementation.

It was originally created by Luca Barbato, and was maintained in the Read the Docs (rtfd) GitHub organization.