Skip to main content

M2R2

PyPI PyPI version Documentation Tests


M2R2 converts a markdown file including reStructuredText (rst) markups to a valid rst format.

M2R: the original

M2R2 is a fork of m2r which has been archived. Every m2r config should work out of the box.

Why another converter?

Sphinx documents benefit from being written in markdown, since it's widely used and easy to write code blocks and lists. However, converters using pandoc or recommonmark do not support many rst markups and sphinx extensions. For example, rst's reference link like see `ref`_ (very convenient in long documents where the same link appears multiple times) gets converted to a code block in HTML like see <code>ref</code>_, which is not expected.

Features

  • Basic markdown and some extensions (see below)
    • inline/block-level raw html
    • fenced-code block
    • tables
    • footnotes ([^1])
  • Inline- and Block-level rst markups
    • single- and multi-line directives (.. directive::)
    • inline-roles (:code:`print(1)` ...)
    • ref-link (see `ref`_)
    • footnotes ([#fn]_)
    • math extension inspired by recommonmark
  • Sphinx extension
    • add markdown support for sphinx
    • mdinclude directive to include markdown from md or rst files
    • option to parse relative links into ref and doc directives (m2r_parse_relative_links)
    • option to render mermaid blocks as graphs with sphinxcontrib.mermaid (m2r_use_mermaid, default: auto)
      • auto means that m2r2 will check if sphinxcontrib.mermaid has been added to the extensions list
  • Pure python implementation
    • pandoc is not required

Installation

Python 3.9+ is required.

uv add m2r2

Or use uvx to run without installing:

uvx m2r2 your_document.md

For Sphinx integration:

uv add m2r2[sphinx]

Usage

Command Line

m2r2 command converts markdown file to rst format.

m2r2 your_document.md [your_document2.md ...]

Then you will find your_document.rst in the same directory.

Programmatic Use

Import m2r2.convert function and call it with markdown text. Then it will return converted text.

from m2r2 import convert

rst = convert('# Title\n\nSentence.')
print(rst)
# Title
# =====
#
# Sentence.

Or, use parse_from_file function to load a markdown file and obtain converted text.

from m2r2 import parse_from_file

output = parse_from_file('markdown_file.md')

Upgrading to 1.0

The reusable converter class is named M2R2. Existing imports of M2R still work through an alias. The convert and parse_from_file functions remain available.

Generated RST may use different spacing while preserving document content and structure. Standalone images keep block image directives. Images within text, headings, and table cells use substitutions so they can appear inline. RST cannot nest inline markup, so emphasis is applied to surrounding text while nested links and code retain their own formatting.

In Sphinx configuration, use m2r_no_underscore_emphasis instead of no_underscore_emphasis. The old name still works with a deprecation warning.

Sphinx Integration

In your conf.py, add the following lines.

extensions = [
    ...,
    'm2r2',
]

# source_suffix = '.rst'
source_suffix = ['.rst', '.md']

Write index.md and run make html.

When m2r2 extension is enabled on sphinx and .md file is loaded, m2r2 converts to rst and pass to sphinx, not making new .rst file.

mdinclude directive

Like .. include:: file directive, .. mdinclude:: file directive inserts markdown file at the line.

Note: do not use .. include:: file directive to include markdown file even if in the markdown file, please use .. mdinclude:: file instead.

Using mdinclude with another markdown parser

The m2r2 extension parses .md files, so Sphinx refuses to load it next to another extension that does the same, such as myst-parser. To keep the other parser for .md files and still use mdinclude, enable m2r2.mdinclude instead. It adds the mdinclude directive and the m2r_* config values, but no parser.

extensions = [
    "myst_parser",
    "m2r2.mdinclude",
]

Restrictions

  • In the rst's directives, markdown is not available. Please write in rst.
  • Column alignment of tables is not supported. (rst does not support this feature)
  • Heading with overline-and-underline is not supported.
    • Heading with underline is OK
  • Rst heading marks are currently hard-coded and unchangeable.
    • H1: =, H2: -, H3: ^, H4: ~, H5: ", H6: #

If you find any bug or unexpected behaviour, please report it to Issues.

Example

See example document and its source code.

Contributing

See CONTRIBUTING.md for development setup and guidelines.

Acknowledgement

m2r2 is written as an extension of mistune, which is a highly extensible pure-python markdown parser. Without mistune, this project wouldn't exist. Thank you!

Licence

MIT

Release files for m2r2 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for m2r2 1.1.0
File Size Uploaded
m2r2-1.1.0.tar.gz 146.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for m2r2 1.1.0
File Interpreter ABI Platform
m2r2-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size:166.6 kB

Release files / m2r2-1.1.0.tar.gz

Download URL m2r2-1.1.0.tar.gz
Size 146.1 kB
Tags Source
SHA-256 checksum
How to use checksums
998534cc1b6d0542483c976a5387f2d7d2223361fb637ca1d1d733571d5e6db0
BLAKE2b-256 checksum
How to use checksums
535d130372b82e8cbc2b9fcb8882b7dd7edd36262a46ad3934e997f53a726b0f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / m2r2-1.1.0-py3-none-any.whl

Download URL m2r2-1.1.0-py3-none-any.whl
Size 20.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1111dcd7a591795f38cb90ec07ed9cc14671299cd6ca535d3f3d8d3999fe65ba
BLAKE2b-256 checksum
How to use checksums
6ed0e74f47700023fe129446f966d5be532e553120fd2b5ce384f9691682d292
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page