Skip to main content

Mordant

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

Version: 0.9.0 (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 accessparse() 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 lintinglint_many() / fix_many() process many files in parallel via rayon
  • CLIpython -m mordant with --fix, --dry-run, --format human|json|github, glob/directory recursion
  • Document chunkingMarkdownChunker: 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mordant-0.10.0.tar.gz (729.3 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

mordant-0.10.0-cp39-abi3-win_amd64.whl (4.9 MB view details)

Uploaded CPython 3.9+Windows x86-64

mordant-0.10.0-cp39-abi3-manylinux_2_35_x86_64.whl (32.8 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.35+ x86-64

mordant-0.10.0-cp39-abi3-macosx_11_0_arm64.whl (4.8 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

Details for the file mordant-0.10.0.tar.gz.

File metadata

  • Download URL: mordant-0.10.0.tar.gz
  • Upload date:
  • Size: 729.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mordant-0.10.0.tar.gz
Algorithm Hash digest
SHA256 63b480b935e814d4ae551ead6f5c61038fcffcbc48dba638814582d61f917044
MD5 db8a8cc2c3412b2a0075fa06a7b711de
BLAKE2b-256 8752def1adcd7e713801eb2e03c3376d76bd9016e501e7742e9dd062f76f334a

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.10.0.tar.gz:

Publisher: release.yml on opticsWolf/mordant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mordant-0.10.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: mordant-0.10.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 4.9 MB
  • Tags: CPython 3.9+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for mordant-0.10.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 66041052e1b0d67eac1e08cced320bd17bce672f355ddbb997f29cda434c58e7
MD5 31fea9a81e99850f83f9b71cd4e472f9
BLAKE2b-256 81153b382078a0db77fd37d36a51c0e096573d85691618628064b09fdd447e08

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.10.0-cp39-abi3-win_amd64.whl:

Publisher: release.yml on opticsWolf/mordant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mordant-0.10.0-cp39-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for mordant-0.10.0-cp39-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 2351317571e023128deefb77638362a4d04296a4615021e9cec9c79410d0cd5d
MD5 d7bf59ba967dec0e6b2a85a107d11707
BLAKE2b-256 09edff3531a2086dc9c3b2209b6248a83f517b4aca52a247c22a806bb7a3ff47

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.10.0-cp39-abi3-manylinux_2_35_x86_64.whl:

Publisher: release.yml on opticsWolf/mordant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mordant-0.10.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mordant-0.10.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 734199f95c2f21e1783a45d8ad4f8f068b38425e7903cb27da603300c9545d64
MD5 14be1ae08822bc57849979c1c78df336
BLAKE2b-256 55e1f77d764f5f9d1efc8cbe9e340986a982193e62bfef5f47b0dbf481b0d1cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.10.0-cp39-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on opticsWolf/mordant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.10.0 This release

4 files

0.9.0

4 files

0.8.11

4 files

0.8.10

4 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