Skip to main content

Mordant

CI License PyPI - Version PyPI - Python Version crates.io Rust

Version: 0.10.1 (Python and Rust crates in lockstep) Python: 3.9+ · Bindings: PyO3 0.29

A fast CommonMark + GFM Markdown parser and renderer for Python, powered by the mordant Rust library — itself built on the rushdown engine by Yusuke Inuzuka.

Features

  • Blazing fast — one of the fastest Markdown parsers for Python; up to 55x faster than python-markdown on large documents
  • CommonMark 0.31.2 + GFM — tables, task lists, strikethrough; autolink available via GfmOptions.all()
  • Full AST access — parse() returns a Document; traverse parents, children and siblings; kind-specific properties on every node
  • YAML frontmatter — typed metadata extraction (null, bool, int, float, str, list, dict)
  • Emoji shortcodes — :joy: → 😂 with blacklists and custom templates
  • LaTeX math — fenced ```math/```latex blocks, inline $…$ and $$…$$, standalone render_math()
  • Mermaid diagrams — server-side inline SVG by default (~3ms), legacy client-side Mermaid.js mode, hybrid fallback; themeable from code-highlighting themes
  • Footnotes — PHP Markdown Extra style [^1] with backlinks
  • Lint engine — 25 markdownlint-style rules, auto-fix engine, inline suppressions, .markdownlint.json config support
  • Batch linting — lint_many() / fix_many() process many files in parallel via rayon
  • CLI — python -m mordant with --fix, --dry-run, --format human|json|github, glob/directory recursion
  • Document chunking — MarkdownChunker: lazy, low-copy chunk iterator with heading context, built for RAG/embedding pipelines
  • Syntax highlighting — 190+ languages via syntect-assets (bat's syntaxes), VSCode JSON and Sublime .tmTheme themes
  • Multi-threaded — parse, render, lint and fix release the GIL; scales ~4x linearly with thread count

Install

pip install mordant

Or build from source (requires a Rust toolchain):

git clone https://github.com/opticsWolf/mordant
cd mordant/mordant-py
pip install -e .

Rust users can use the same engine directly: cargo add mordant.

Quick Start

import mordant

html = mordant.markdown_to_html("# Hello\n\n**World**")
# '<h1>Hello</h1>\n<p><strong>World</strong></p>\n'

GFM options

opts = mordant.GfmOptions(features=[
    mordant.GfmFeature.Table,
    mordant.GfmFeature.Strikethrough,
    mordant.GfmFeature.TaskList,
])
html = mordant.markdown_to_html("~~strike~~", gfm_opts=opts)

opts = mordant.GfmOptions.all()   # everything incl. the linkify extension
opts = mordant.GfmOptions.none()

Parse to an AST

doc = mordant.parse("# Hello\n\nSome **bold** text.")

doc.kind        # "Document"
doc.children    # [Heading, Paragraph]

for node in doc.walk("depth"):
    print(node.kind, node.text)

heading = doc.children[0]
heading.content          # rendered inner HTML
heading.level            # kind-specific property (1)

# YAML frontmatter (if present at the top of the document)
print(doc.metadata)      # {'title': 'My Document', 'tags': ['a', 'b']}

Frontmatter is controlled through ParseOptions, e.g. ParseOptions(meta_table=True) also injects it as a table.

Emoji

html = mordant.markdown_to_html("I love :heart: and :joy:")
# 'I love ❤️ and 😂'

# Ignore specific shortcodes
html = mordant.markdown_to_html(
    ":joy: stays literal",
    emoji_parse_opts=mordant.EmojiParserOptions(blacklist="joy"),
)

# Custom render template ({emoji}, {shortcode}, {name})
html = mordant.markdown_to_html(
    ":joy:",
    emoji_render_opts=mordant.EmojiHtmlRendererOptions(
        template='<img src="https://cdn.example.com/{shortcode}.png" />'
    ),
)

Math (KaTeX)

```math / ```latex fences and inline $…$ / $$…$$ are rendered automatically. Include mordant.KATEX_CSS in your page for styling.

html = mordant.markdown_to_html("Euler: $e^{i\\pi} + 1 = 0$")

# Standalone rendering, independent of any document
markup = mordant.render_math("E = mc^2", display=True, output="both")

Mermaid diagrams

```mermaid blocks render as inline SVG server-side by default — no CDN or JavaScript needed:

html = mordant.markdown_to_html("""```mermaid
graph LR
    A --> B --> C
```""")
# '<div class="mermaid"><svg>...</svg></div>'

# Legacy client-side rendering, or server→client fallback
opts = mordant.DiagramHtmlRendererOptions(render_mode="client")
opts = mordant.DiagramHtmlRendererOptions(render_mode="hybrid")

# One theme for BOTH code highlighting and diagrams
html = mordant.markdown_to_html(src, theme="Dracula")

Linting & fixing

diagnostics = mordant.lint("# Hello\n\n### Jump\n")
for d in diagnostics:
    print(f"{d.rule}:{d.line} {d.name}: {d.message}")
# MD001:1 heading-increment: Heading incremented by more than 1

result = mordant.fix("trailing   \n\n\ntext")
result.output      # 'trailing\n\ntext\n'
result.fixed       # what was auto-corrected
result.unfixable   # what needs manual attention

# Rule catalogue
for meta in mordant.lint_rules():
    print(meta.id, meta.name, meta.fixable)

Batch process a whole tree (parallel, GIL released):

results = mordant.lint_many(["a.md", "b.md", "notes/*.md"])

Or from the command line:

python -m mordant check docs/*.md --format github
python -m mordant check docs/ --fix

Inline suppressions work too: <!-- markdownlint-disable MD013 -->.

Document chunking

Built for RAG/embedding pipelines — a lazy, low-copy chunk iterator with heading-context tracking:

chunker = mordant.MarkdownChunker(text)          # or .from_file(path)
# or zero-copy: MarkdownChunker.from_file_mmap(path)

for chunk in chunker:                             # bare str chunks
    embed(chunk)

chunks = chunker.get_chunks_with_context()        # ExtractedChunk objects:
chunks[0].text                                    # "# Title\n\nbody…" (context-prefixed)
chunks[0].block_type                              # "Paragraph", "CodeBlock", …
chunks[0].start_offset, chunks[0].end_offset      # byte offsets in source

# Overlap payloads for embedding models
payloads = chunker.compute_overlap_payloads(overlap_words=50)

Syntax highlighting

hl = mordant.Highlighter(theme="Dracula", mode="Attribute")
html = hl.highlight("python", "def hello():\n    print('hi')")

# In documents
html = mordant.markdown_to_html(src,
    highlighting_theme="Dracula",
    highlighting_mode="Attribute")     # or "Class" for CSS classes

# Custom themes: VSCode JSON or Sublime .tmTheme
mordant.add_custom_theme("my-theme", open("theme.json").read())
mordant.list_themes()
mordant.list_syntaxes()                # ~190 languages

Multi-threading

CPU-heavy work (parse, render, lint, fix, batch operations) runs without the GIL, so plain threading scales across cores:

from concurrent.futures import ThreadPoolExecutor
import mordant

with ThreadPoolExecutor(8) as pool:
    htmls = list(pool.map(mordant.markdown_to_html, documents))

Documentation

  • Quick Reference — complete API reference with every option
  • Architecture — internals, design decisions, module map
  • README — project overview, Rust crate feature table

License

MIT

Metadata

Release files for mordant 0.10.1

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

Source distribution (sdist)

Source distribution for mordant 0.10.1
File Size Uploaded Provenance Actions
mordant-0.10.1.tar.gz 766.1 kB With provenance Details for mordant-0.10.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for mordant 0.10.1
File Interpreter ABI Platform Actions
mordant-0.10.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details for mordant-0.10.1-cp39-abi3-win_amd64.whl
mordant-0.10.1-cp39-abi3-manylinux_2_35_x86_64.whl CPython 3.9 abi3 Linux glibc 2.35+ x86-64 Details for mordant-0.10.1-cp39-abi3-manylinux_2_35_x86_64.whl
mordant-0.10.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details for mordant-0.10.1-cp39-abi3-macosx_11_0_arm64.whl

Total release size: 43.2 MB

Release files / mordant-0.10.1.tar.gz

Download URL mordant-0.10.1.tar.gz
Size 766.1 kB
Tags Source
SHA-256 checksum
How to use checksums
1e763777bb0e0ed5ea57acaf6aa75670ed91f797fe376ea626adcd5e58f80464
BLAKE2b-256 checksum
How to use checksums
eefa7812f22889429aa3e583a25fdd65fef4405556ed1f87c46fbe83fa9fe59e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 8, 2026.

Transparency log

Release files / mordant-0.10.1-cp39-abi3-win_amd64.whl

Download URL mordant-0.10.1-cp39-abi3-win_amd64.whl
Size 4.9 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
3d2c338b96a7727dc69448b5a44f82ab337cc85860e8e9861aa8826ca2d7763c
BLAKE2b-256 checksum
How to use checksums
e4f474339f2be97dc7fabecd06c9883f97888c6d9310af26c3b439e1a25eb1bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 8, 2026.

Transparency log

Release files / mordant-0.10.1-cp39-abi3-manylinux_2_35_x86_64.whl

Download URL mordant-0.10.1-cp39-abi3-manylinux_2_35_x86_64.whl
Size 32.7 MB
Tags CPython 3.9 Linux glibc 2.35+ x86-64 abi3
SHA-256 checksum
How to use checksums
d1dc07c0dce8ac015de46b035707a8413dd7b091da91e0297d91adad95643e00
BLAKE2b-256 checksum
How to use checksums
2dcad1e7a7b9b078124abf18134899d8fb54c68390f72f61b49f8887ff21f9e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 8, 2026.

Transparency log

Release files / mordant-0.10.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL mordant-0.10.1-cp39-abi3-macosx_11_0_arm64.whl
Size 4.8 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
44f66d4d35551e7058b0fa260d7d7ede14cc2975172a158dc94f9ff7a6ec0fb2
BLAKE2b-256 checksum
How to use checksums
57ccc03882c39ded24b9823fbe241a174f8a0c083a3e340758f0ca946adecf7c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 8, 2026.

Transparency log

Security for mordant 0.10.1

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.

Full provenance

All 4 files in this release have been uploaded with provenance metadata.

Select from 4 files

Attestation for mordant-0.10.1.tar.gz

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 Nov 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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