Oven logo

Oven

Published

Python bindings to cmark: CommonMark parsing and rendering (HTML, LaTeX, man, XML)

pip install multimark

Package Downloads

Weekly DownloadsMonthly Downloads

Authors

Project URLs

Requires Python

>=3.9

multimark

PyPI Python versions Downloads MIT License CI

The multimark package has Python bindings to cmark-gfm, the C reference implementation of CommonMark with GitHub Flavored Markdown extensions.

Renders Markdown to HTML, LaTeX, groff man, XML, and normalized CommonMark: all from a single, lightweight package.

Installation

pip install multimark

Wheels are available for Linux, macOS, and Windows (Python 3.9+). No system dependencies required.

Quick Start

from multimark import markdown_to_html, markdown_to_latex

html = markdown_to_html("**Hello**, *world*!")
# '<p><strong>Hello</strong>, <em>world</em>!</p>\n'

latex = markdown_to_latex("**Hello**, *world*!")
# '\\textbf{Hello}, \\emph{world}!\n'

Renderers

FunctionOutput Format
markdown_to_html()HTML
markdown_to_latex()LaTeX
markdown_to_man()groff man page
markdown_to_commonmark()Normalized CommonMark
markdown_to_xml()XML (AST representation)

Options

Use named boolean keyword arguments for common settings:

from multimark import markdown_to_html, markdown_to_latex

# Smart punctuation (curly quotes, em-dashes)
markdown_to_html('"Hello" -- world...', smart=True)
# '<p>\u201cHello\u201d \u2013 world\u2026</p>\n'

# Allow raw HTML passthrough (safe mode is the default)
markdown_to_html('<div>hi</div>', unsafe=True)
# '<div>hi</div>\n'

# Source position attributes
markdown_to_html('**Hello**', sourcepos=True)
# '<p data-sourcepos="1:1-1:9"><strong>Hello</strong></p>\n'

# Line wrapping (LaTeX, man, and commonmark renderers)
markdown_to_latex('**Hello**, *world*!', width=80)
# '\\textbf{Hello}, \\emph{world}!\n'

# Footnotes
markdown_to_html('Text[^1]\n\n[^1]: A footnote\n', footnotes=True)
# '<p>Text<sup class="footnote-ref">...</sup></p>\n<section class="footnotes">...\n'

Or compose flags with the Options bitmask:

from multimark import markdown_to_html, Options

html = markdown_to_html(text, options=Options.SMART | Options.UNSAFE)

GFM Extensions

Enable GitHub Flavored Markdown extensions by name:

from multimark import markdown_to_html

# Tables
markdown_to_html('| A | B |\n|---|---|\n| 1 | 2 |\n', extensions=["table"])
# '<table>\n<thead>\n<tr>\n<th>A</th>\n<th>B</th>\n</tr>...\n'

# Strikethrough
markdown_to_html('~~deleted~~', extensions=["strikethrough"])
# '<p><del>deleted</del></p>\n'

# Multiple extensions
html = markdown_to_html(text, extensions=["table", "strikethrough", "autolink", "tasklist", "tagfilter"])

Available extensions: table, strikethrough, autolink, tagfilter, tasklist.

All Renderer Parameters

Every renderer accepts:

  • text: Markdown string
  • options: raw bitmask (default 0)
  • extensions: list of GFM extension names (default ())
  • smart: smart punctuation
  • hardbreaks: render soft breaks as <br>
  • unsafe: allow raw HTML
  • normalize: consolidate adjacent text nodes
  • footnotes: enable footnote syntax

Additional parameters:

  • sourcepos: Source position attributes (HTML and XML only)
  • width: Line wrap column (LaTeX, man, and commonmark only; 0 = no wrap)

Why multimark?

Several Python packages wrap cmark or provide CommonMark parsing. Here's how they compare:

multimarkcmarkgfmcommonmark.py
Enginecmark-gfm (C, vendored)cmark-gfm (C, vendored)Pure Python
Output formatsHTML, LaTeX, man, XML, CommonMarkHTML onlyHTML only
GFM extensions
Safe by default
Convenience kwargssmart=True, unsafe=True, etc.Raw bitmask onlyN/A
PerformanceFastest (14% faster than cmarkgfm)Fast~31× slower
MaintainedActive (2026)Active (2025)Unmaintained (2019)

multimark uses the same battle-tested C library as cmarkgfm but exposes all five of cmark's output formats (not just HTML). The API is designed around keyword arguments rather than opaque bitmasks, and unsafe content is blocked by default so the safe choice requires no extra configuration.

Thanks to extension pointer caching and reduced Python-side overhead, multimark is the fastest Python Markdown-to-HTML library. Take a look at the benchmarks for more detail on this.

License

MIT and BSD-2-Clause (cmark-gfm).