mistune
| Language | Python (3.10+ for 3.4) |
|---|---|
| License | BSD-3-Clause |
| Repository | github.com/lepture/mistune |
| Documentation | mistune.lepture.com |
| Depends on | nothing |
| Read / write | parses Markdown (close to CommonMark) plus plugins; renders HTML, reStructuredText, Markdown; AST as Python dicts |
mistune is one of the fastest pure Python Markdown parsers. Version 3 parses into a list of token dicts and renders them with a renderer class: HTML by default, also reStructuredText and Markdown, or your own subclass. Plugins add tables, footnotes, strikethrough, task lists, definition lists, abbreviations, math, URL autolinks, superscript, subscript, mark, insert, spoiler and ruby. It follows CommonMark closely but doesn’t claim full compliance. Jupyter’s nbconvert uses it.
mistune.create_markdown() escapes raw HTML and rejects unsafe URL schemes by default. The mistune.html() shortcut keeps raw HTML (escape off) and enables strikethrough, footnotes and table.
Installation#
Shell
pip install mistune
Basic usage: render Markdown to HTML#
Python
import mistune
markdown = mistune.create_markdown(
plugins=["table", "strikethrough", "footnotes", "task_lists", "url"],
)
with open("README.md", encoding="utf-8") as f:
html = markdown(f.read())
print(html)
How to allow raw HTML (trusted input)#
Python
markdown = mistune.create_markdown(escape=False, plugins=["table"])
markdown("<div class='note'>hi</div>") # '<div class=\'note\'>hi</div>'
# or the shortcut with strikethrough, footnotes and table
html = mistune.html("Some *text* with <b>HTML</b>")
How to get the syntax tree#
Python
import mistune
parse = mistune.create_markdown(renderer="ast", plugins=["table"])
tokens = parse("# Title\n\nSee [docs](https://example.com).\n")
# [{'type': 'heading', 'attrs': {'level': 1}, 'style': 'atx',
# 'children': [{'type': 'text', 'raw': 'Title'}]}, ...]
def walk(nodes):
for n in nodes:
if n["type"] == "heading":
print("h%d" % n["attrs"]["level"])
if n["type"] == "link":
print("link:", n["attrs"]["url"])
walk(n.get("children", []))
walk(tokens)
How to customize HTML output#
Subclass HTMLRenderer and override the method for a token type:
Python
import mistune
class NoFollowRenderer(mistune.HTMLRenderer):
def link(self, text, url, title=None):
return f'<a href="{mistune.escape_url(url)}" rel="nofollow">{text}</a>'
markdown = mistune.create_markdown(renderer=NoFollowRenderer())
print(markdown("[site](https://example.com)"))
How to render Markdown as reStructuredText#
Python
from mistune.renderers.rst import RSTRenderer
to_rst = mistune.create_markdown(renderer=RSTRenderer())
print(to_rst("# Title\n\n*text*"))
Tips#
- Create the Markdown instance once and call it many times.
- Plugin names are strings for built-ins; pass functions for your own plugins.
- mistune 3 changed the renderer and plugin API from 2.x; old custom renderers need updating.