recommonmark

A docutils-compatibility bridge that lets Sphinx and docutils projects write documentation in CommonMark Markdown alongside reStructuredText.

Library
PyPI
v0.7.1
341stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity0
Maintenance0
Community64
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
57/100Fair
Architecture62
Code Quality55
Innovation45
Learning Curve65

recommonmark is a docutils parser that translates CommonMark Markdown into the docutils document tree, so Sphinx projects can mix .md files with .rst files in the same documentation build. It registers as a Sphinx extension (extensions = ['recommonmark']) or a source_parsers entry for older Sphinx versions, and ships an AutoStructify transform that upgrades plain Markdown into Sphinx-flavored reStructuredText constructs — table of contents trees, eval-rst blocks, math, and cross-references — at build time.

The project is explicitly deprecated by its maintainers (the Read the Docs organization), who now recommend MyST-Parser for new projects. It is still widely installed (over 180,000 weekly PyPI downloads) because a large body of existing Sphinx documentation depends on it, but it receives no active development.

What You Get

  • A CommonMarkParser class registered with docutils/Sphinx that converts Markdown AST nodes into the docutils document tree Sphinx already knows how to render
  • AutoStructify, a docutils transform that promotes plain Markdown into Sphinx-aware reStructuredText behavior: auto-generated toctrees, eval_rst fenced blocks, math rendering, and cross-reference resolution
  • Six cm2* console scripts (cm2html, cm2latex, cm2man, cm2pseudoxml, cm2xetex, cm2xml) for converting a CommonMark file directly through docutils writers without a full Sphinx build
  • Any-role cross-reference behavior for non-URL Markdown links, so [text](path/to/file) resolves against Sphinx’s object/file/label domain the same way RST cross-references do

Common Use Cases

  • Legacy Sphinx documentation sites that were written in Markdown before MyST-Parser existed and have not been migrated
  • Mixed-format documentation repos that keep some pages in .rst (for directive-heavy content) and others in .md (for simpler prose)
  • One-off CommonMark-to-HTML/LaTeX/man-page conversion via the cm2* CLI scripts, independent of a full Sphinx project
  • Projects on Read the Docs that adopted .md docs early via the readthedocs/rtfd package family and haven’t revisited their doc toolchain

Under The Hood

Architecture recommonmark is a thin adapter layer, not a Markdown implementation of its own: parser.py defines CommonMarkParser, a docutils Parser subclass whose parse() method hands the raw source to the external commonmark package, walks the resulting AST with a visitor dispatch (visit_<nodetype>/depart_<nodetype> methods resolved via getattr), and builds a docutils document tree node-by-node; transform.py’s AutoStructify is a separate docutils Transform registered at high priority that walks the already-built tree a second time, rewriting specific node patterns (fenced blocks matching eval-rst, math spans, plain links) into Sphinx-native directives, with states.py supplying a DummyStateMachine shim so the RST parser can be invoked as a sub-parser mid-transform. Because the parser only emits generic docutils nodes, Sphinx’s existing HTML/LaTeX/man writers require no changes — the entire integration surface is the docutils Parser/Transform interfaces plus a recommonmark_config dict read off document.settings.env.config.

Tech Stack Pure Python (single-language repo), built on three tightly-coupled dependencies pinned in setup.py: commonmark>=0.8.1 for the actual CommonMark parsing (recommonmark itself parses nothing), docutils>=0.11 for the document tree and writer machinery, and sphinx>=1.3.1 for the addnodes extension node types AutoStructify emits. Packaging is classic setuptools (setup.py + setup.cfg, universal wheel), tested via tox across a Python 2.7/3.5/3.6 x Sphinx 1.6/1.7/1.8 matrix on Travis CI, with prospector wired in as a separate lint tox environment.

Code Quality Tests live in tests/test_basic.py and tests/test_sphinx.py, using stdlib unittest with a hand-rolled assertParses helper that renders parsed output to pretty-printed XML and diffs it against expected strings — a whitebox, snapshot-style approach rather than behavioral assertions, plus fixture directories (sphinx_generic, sphinx_xref, etc.) for full-build integration tests. There is no type annotation anywhere in the four core modules, and error handling is minimal (a handful of bare try/except AttributeError guards around optional Sphinx config access); the .travis.yml/tox.ini CI matrix and prospector lint step are the main quality gates, but the project’s own README badge states “No Maintenance Intended” and the maintainers have not merged fixes since 2021.

What Makes It Unique The project’s one genuinely distinctive design choice is symmetry with docutils’ own extension model: rather than building a new Markdown-to-HTML pipeline, it makes CommonMark participate as a peer input format inside an existing, mature toolchain (docutils/Sphinx) by implementing only the two extension points that toolchain already exposes (Parser, Transform). That is also its ceiling — it does not attempt Markdown extensions, MDX-style embedding, or any capability past what AutoStructify’s node-rewriting can express, which is why the same authors’ community has since moved to MyST-Parser for anything requiring deeper Sphinx-directive fidelity.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search