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.9.0.tar.gz (720.4 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.9.0-cp39-abi3-win_amd64.whl (4.8 MB view details)

Uploaded CPython 3.9+Windows x86-64

mordant-0.9.0-cp39-abi3-manylinux_2_35_x86_64.whl (32.4 MB view details)

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

mordant-0.9.0-cp39-abi3-macosx_11_0_arm64.whl (4.7 MB view details)

Uploaded CPython 3.9+macOS 11.0+ ARM64

File details

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

File metadata

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

File hashes

Hashes for mordant-0.9.0.tar.gz
Algorithm Hash digest
SHA256 fc0c41378b66b092c0db740aede2cd795775b44db56d9e7b9eede80f53ee7ef5
MD5 0c424e974ed6e6a0d368ea803f75158a
BLAKE2b-256 057460fec852543b36a2584fa99f8016da8684a7083df8001b898827e4d40f2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.9.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.9.0-cp39-abi3-win_amd64.whl.

File metadata

  • Download URL: mordant-0.9.0-cp39-abi3-win_amd64.whl
  • Upload date:
  • Size: 4.8 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.9.0-cp39-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 9f99758058ad779a92e02140bfb21faa9e8111805a79f33b45be24a629382341
MD5 f2a0861083b6f8529d6b086892932b7f
BLAKE2b-256 c445199d90d1b19921354ca36b6f87ec15a36d22a1444ff781a072d5bcc6eb0a

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.9.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.9.0-cp39-abi3-manylinux_2_35_x86_64.whl.

File metadata

File hashes

Hashes for mordant-0.9.0-cp39-abi3-manylinux_2_35_x86_64.whl
Algorithm Hash digest
SHA256 0c3213ba990fba00e972ef3decfc7cd23eb813d8f02c08cb965d60846478652c
MD5 98adad90789780dbfb6d9b8a6bd1a1b2
BLAKE2b-256 3200b1b0fcad5c8337e45ed68f512ed5574eeb5f9950ad9616621f3a4ce98f08

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.9.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.9.0-cp39-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mordant-0.9.0-cp39-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2025d2546e611751d3b918409dabf732718c22f2646b991487f3edca701004ba
MD5 4afff1ab6d39cbe7d02c5e822957ff76
BLAKE2b-256 30fb56a414e686edda2444b6d10ed16f4313ed0383399d5b85ffbb40945fa4a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for mordant-0.9.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

0.10.0

4 files

This release

0.9.0 This release

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