markdown-it-py
| Language | Python (3.10+) |
|---|---|
| License | MIT |
| Repository | github.com/executablebooks/markdown-it-py |
| Documentation | markdown-it-py.readthedocs.io |
| Depends on | mdurl; optional linkify-it-py (for autolinks); plugins in mdit-py-plugins |
| Read / write | parses CommonMark plus plugins; renders HTML; token stream and syntax tree |
markdown-it-py is a Python port of markdown-it, one of the most used JavaScript Markdown parsers. It follows the CommonMark spec, is configurable through presets and rules, and produces a flat list of tokens (heading_open, inline, link_open, …) that renderers turn into HTML. SyntaxTreeNode gives a nested view of the same tokens. It’s the parser behind MyST Markdown, Jupyter Book and the Sphinx MyST parser.
Presets: commonmark (strict spec), gfm-like (adds tables, strikethrough and linkify; needs linkify-it-py), js-default (markdown-it’s defaults) and zero. In commonmark mode raw HTML is allowed; set {"html": False} to escape it. Extra syntax comes from the mdit-py-plugins package.
Installation#
pip install markdown-it-py
pip install "markdown-it-py[linkify]" mdit-py-plugins # for gfm-like and plugins
Basic usage: render Markdown to HTML#
from markdown_it import MarkdownIt
md = MarkdownIt("commonmark").enable("table").enable("strikethrough")
with open("README.md", encoding="utf-8") as f:
html = md.render(f.read())
with open("README.html", "w", encoding="utf-8") as f:
f.write(html)
How to render untrusted input#
md = MarkdownIt("commonmark", {"html": False}) # raw HTML is escaped
html = md.render("<script>alert(1)</script> *hi*")
# <p><script>alert(1)</script> <em>hi</em></p>
markdown-it also refuses javascript:, vbscript: and most data: URLs in links by default (validateLink).
How to list headings and links#
from markdown_it import MarkdownIt
md = MarkdownIt("commonmark")
tokens = md.parse(text)
for i, tok in enumerate(tokens):
if tok.type == "heading_open":
print(tok.tag, tokens[i + 1].content) # h2 Installation
if tok.type == "inline" and tok.children:
for child in tok.children:
if child.type == "link_open":
print("link:", child.attrGet("href"))
How to add footnotes, front matter and task lists#
from markdown_it import MarkdownIt
from mdit_py_plugins.footnote import footnote_plugin
from mdit_py_plugins.front_matter import front_matter_plugin
from mdit_py_plugins.tasklists import tasklists_plugin
md = (
MarkdownIt("commonmark")
.enable("table")
.use(front_matter_plugin)
.use(footnote_plugin)
.use(tasklists_plugin)
)
tokens = md.parse(text)
front = next((t.content for t in tokens if t.type == "front_matter"), None) # raw YAML
html = md.renderer.render(tokens, md.options, {})
How to work with a syntax tree#
from markdown_it.tree import SyntaxTreeNode
tree = SyntaxTreeNode(md.parse(text))
for node in tree.walk():
if node.type == "heading":
print(node.tag, node.children[0].content)
How to use the command line tool#
markdown-it README.md > README.html
Tips#
- Create one
MarkdownItinstance and reuse it; configuration happens once. md.parse(text, env)collects reference definitions and plugin data inenv.- For Markdown output (formatting or normalizing), use the
mdformatpackage, which is built on markdown-it-py.