All formats

Python-Markdown

LanguagePython (3.11+ for the current version)
LicenseBSD-3-Clause
Repositorygithub.com/Python-Markdown/markdown
Documentationpython-markdown.github.io
Depends onnothing
Read / writeparses Markdown (original syntax rules) plus extensions; renders HTML

Python-Markdown implements John Gruber’s original Markdown description, not CommonMark. The differences show up in edge cases: nested list items need 4 spaces of indentation, and emphasis and HTML blocks follow the older rules. On top of that it has a large set of official extensions (tables, fenced_code, footnotes, toc, attr_list, def_list, abbr, admonition, codehilite, meta, md_in_html, sane_lists, smarty, wikilinks) and an API for writing your own. Third-party collections like PyMdown Extensions add task lists, strikethrough, math and more. MkDocs and many static site tools use it.

It passes raw HTML through and has no safe mode (removed in 3.0). Sanitize output (for example with nh3) when the input isn’t trusted.

Installation#

Shell
pip install markdown

Basic usage: convert Markdown to HTML#

Python
import markdown

with open("README.md", encoding="utf-8") as f:
    text = f.read()

html = markdown.markdown(text, extensions=["tables", "fenced_code", "footnotes"])

with open("README.html", "w", encoding="utf-8") as f:
    f.write(html)

How to generate a table of contents#

Python
import markdown

md = markdown.Markdown(extensions=["toc"])
html = md.convert(text)      # headings get id attributes
print(md.toc)                # <div class="toc"><ul>...</ul></div>
for item in md.toc_tokens:   # nested dicts: level, id, name, children
    print(item["level"], item["name"], item["id"])

How to read metadata at the top of a file#

The meta extension reads Key: value lines (MultiMarkdown style) before the first blank line:

Python
md = markdown.Markdown(extensions=["meta"])
html = md.convert("Title: Release notes\nAuthor: Ann\n\n# Notes\n")
print(md.Meta)   # {'title': ['Release notes'], 'author': ['Ann']}

For YAML front matter between --- lines, strip it first with a package like python-frontmatter.

How to convert a file directly#

Python
markdown.markdownFromFile(input="README.md", output="README.html", encoding="utf-8",
                          extensions=["tables"])

From the command line: python -m markdown -x tables README.md > README.html.

How to get closer to CommonMark list behavior#

Python
html = markdown.markdown(text, extensions=["sane_lists"])

sane_lists stops ordered and unordered lists from mixing and respects the first number of an ordered list. For full CommonMark behavior use markdown-it-py.

Tips#