All formats

mistune

LanguagePython (3.10+ for 3.4)
LicenseBSD-3-Clause
Repositorygithub.com/lepture/mistune
Documentationmistune.lepture.com
Depends onnothing
Read / writeparses 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#