This release is a pre-release and may not be stable for production use.
mdmint
Export Markdown files to DOCX and/or PDF — pure-Python, cross-platform, minimal dependencies.
A single Markdown → HTML pass feeds both writers. The two features that can't be rendered statically in pure Python (mermaid diagrams and LaTeX math) use an optional renderer if one is available and fall back gracefully otherwise — so the base install stays small and works everywhere.
Install
pip install mdmint
The core install is pure-Python (no native libraries):
markdown-it-py, mdit-py-plugins, htmldocx/python-docx, xhtml2pdf.
Optional extras:
pip install "mdmint[math]" # render LaTeX math (adds matplotlib)
pip install "mdmint[weasyprint]" # higher-fidelity PDF (needs native Pango/Cairo)
pip install "mdmint[all]" # both of the above
For mermaid diagrams, install the mermaid CLI separately (optional):
npm install -g @mermaid-js/mermaid-cli (provides mmdc).
Usage
mdmint notes.md # -> notes.pdf
mdmint notes.md -f docx,pdf -o out/ # both formats into ./out/
mdmint a.md b.md -f docx # -> a.docx and b.docx (one per input)
mdmint a.md b.md --merge -f pdf -o book.pdf # one merged PDF
mdmint report.md --toc -f pdf # insert a table of contents
mdmint report.md -f pdf --pdf-backend weasyprint
| Option | Meaning |
|---|---|
-f, --format |
pdf, docx, or both (comma-separated). Default pdf. |
-o, --output |
Output directory, or a file path. Default: alongside each input. |
--merge |
With multiple inputs, produce one merged file per format. |
--toc |
Insert a table of contents (or honour a [TOC] marker). |
--pdf-backend |
xhtml2pdf (default) or weasyprint. |
-v, --verbose |
Verbose logging. |
| --mkdocs FILE | Build one document from an mkdocs.yml nav (instead of INPUTs). |
| --section-style | With --mkdocs: part (default) or heading — see below. |
| --template FILE | Word template (.docx/.dotx) for DOCX output. |
| --meta KEY=VALUE | Value for a template {{KEY}} placeholder (repeatable). |
| --style ROLE=STYLE | Use a specific template style for a role (repeatable). |
Also runnable as python -m mdmint ....
From an mkdocs site
mdmint --mkdocs mkdocs.yml -f docx,pdf -o out/ # -> out/<site_name>.docx/.pdf
The nav decides which pages go in and in what order (without a nav, the
docs_dir tree is used, like mkdocs does). Sections become headings:
--section-style part(default): a top-level section is a part divider that doesn't use up a heading level, so its pages keep their#as chapters; nested sections become#,##… and demote their pages to match.--section-style heading: every section is a heading one level above its pages.
Pages under a section titled Annex(es), Appendix or Appendices become
appendix chapters. Links between pages (../other/page.md#anchor) become
in-document links; links to pages left out of the nav are kept as plain text.
Headings accept mkdocs attr_list syntax (# Title {#id .part}).
Settings can live in the mkdocs.yml itself (command-line options win):
extra:
mdmint:
template: templates/brand.docx # relative to mkdocs.yml
section_style: part
status: Final # any other key fills {{STATUS}} etc.
confidentiality: Internal
styles: {code: "My Code Style"} # optional role overrides
Branded DOCX with a Word template
mdmint report.md -f docx --template brand.docx --meta status=Draft
With --template, DOCX output is written into a copy of the template: its
cover, contents page, headers/footers, page setup and styles are kept, and the
content is appended at the end (or where a paragraph reading {{CONTENT}} sits).
Text like {{TITLE}}, {{AUTHOR}}, {{DATE}} anywhere in the body, headers or
footers is filled from, in increasing priority: mkdocs.yml (site_name → title,
site_description → subtitle, site_author → author, extra.mdmint), the Markdown
front matter, and --meta. date defaults to the current month; placeholders
left without a value are blanked with a warning.
Each element uses the template's styles, picking the first that exists:
Role (--style key) |
Styles tried |
|---|---|
| headings | Heading 1…Heading N (deeper levels reuse the last) |
part / appendix |
Part Title / Appendix Heading (else Heading 1) |
code / inline_code |
Code Block, Source Code, HTML Preformatted / Inline Code, Verbatim Char, HTML Code |
quote |
Callout, Quote (blockquotes) |
note / warning |
Callout Note / Callout Warning (admonitions, > [!NOTE]) |
table |
the template's own (non-stock) table style, else Table Grid |
table_heading / table_text |
Table Heading / Table Text |
figure / caption |
Figure / Caption ("Figure N." from the image alt text; Table: … before a table gives "Table N.") |
| lists | List Bullet, List Number (real multi-level numbering, restarted per list) |
| footnotes | Footnote Text/Footnote Reference (created if missing) — real Word footnotes |
How to build a template that styles well — required styles, numbering, placeholders, and a specimen file to test it — is in docs/TEMPLATES.md.
Headings are bookmarked so in-document links work, and the template's TOC field
(if any) picks the headings up when Word updates fields on open. Without
--template, DOCX output is unchanged (htmldocx).
Library API
from mdmint import convert
convert(["report.md"], formats=["pdf", "docx"], output="out/")
convert(["a.md", "b.md"], formats=["pdf"], output="book.pdf", merge=True)
Supported Markdown
CommonMark plus: GFM tables, task lists, strikethrough, footnotes, auto table of
contents, fenced code, admonitions
(!!! note / ??? warning callouts), embedded images (relative paths resolved
against the source file; remote URLs downloaded), LaTeX math, and mermaid diagrams.
Notes & limitations
- PDF backend.
xhtml2pdf(default) is pure-Python and runs anywhere, with a pragmatic subset of CSS.weasyprintproduces nicer output but needs native Pango/Cairo libraries, so it is an opt-in extra. - Math uses matplotlib's mathtext engine (a large LaTeX-math subset, no system
LaTeX required) rendered to images. Full LaTeX environments (e.g.
align) are not supported. Without matplotlib, math is shown as literal source with a warning. - Mermaid requires the
mmdcCLI. Without it, diagrams are shown as styled code blocks with a warning. A snap-installedmmdcis supported (mdmint places its scratch files where snap confinement can read them). - Admonitions render as a colour-coded callout box (tinted background + accent
bar + coloured title) in both PDF and DOCX. Type icons are intentionally omitted:
the pure-Python PDF backend can't embed an emoji font, so colour and the title
carry the type instead. The collapsible
???/???+blocks render fully expanded (static documents have nothing to collapse into).
License
Licensed under the Apache License, Version 2.0.
Copyright 2026 Meaningful Data.
Metadata
Release files for mdmint 0.2.0rc1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mdmint-0.2.0rc1.tar.gz | 58.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mdmint-0.2.0rc1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 111.7 kB
Release files / mdmint-0.2.0rc1.tar.gz
| Download URL | mdmint-0.2.0rc1.tar.gz |
|---|---|
| Size | 58.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5c3ef0f1df1d5d25f6d315920e1cba1f26d0901c2b6b1673c5b66c8866414cc2
|
|
BLAKE2b-256 checksum How to use checksums |
86f295d61495edf043cccdeee56f8fffe5c636dcd2a71abeb777b17f43f53a87
|
| 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 Oct 13, 2026.
Transparency logRelease files / mdmint-0.2.0rc1-py3-none-any.whl
| Download URL | mdmint-0.2.0rc1-py3-none-any.whl |
|---|---|
| Size | 53.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fff72e9e9eea910f6c9dd41c8f130b2d7747fe549d63b9263f0bcd4acc652651
|
|
BLAKE2b-256 checksum How to use checksums |
6894bd9a2456b3c30576cd53e4527a2a726abe1246958becf43186e791481313
|
| 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 Oct 13, 2026.
Transparency logSecurity for mdmint 0.2.0rc1
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 2 files in this release have been uploaded with provenance metadata.
Attestation for mdmint-0.2.0rc1.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 Oct 13, 2026.
Transparency logA 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.