Skip to content

Python markdown extensions for MkDocs

MkDocs use python-markdown and so extensions for python markdown also work in MkDocs.

Some useful existing Extensions

MkDocs comes with some useful python markdown extensions, others can be installed separately. Edit mkdocs.yaml to use them.

venv$ pip install pymdown-extensions
venv$ pip install pygments
markdown_extensions:
  - admonition
  - pymdownx.arithmatex
  - pymdownx.details
  - codehilite
  - pymdownx.superfences

admonition

Gives nicely formatted notes

!!! note "test"
    this is a test

test

this is a test

pymdownx.details

Gives more options than admonition, for example

??? optional-class "Summary (click to reveal)"
    summary the following text looks a bit summary
renders as

Summary (click to reveal)

summary the following text looks a bit summary

pymdown.arithmatex

This one requires some extra javascript in mkdocs.yml. It uses Mathjax to render latex.

markdown_extensions:
  - pymdownx.arithmatex
extra_javascript:
  - 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-MML-AM_CHTML'

So that

$$
\frac{n!}{k!(n-k)!} = \binom{n}{k}
$$
renders as $$ \frac{n!}{k!(n-k)!} = \binom{n}{k} $$

codehilite

markdown_extensions:
  - codehilite

Highlights code in tick blocks (like above examples of code).

Superfences

Allows tabbed fences, nested fences and more.

<div vocab="http://schema.org">
</div>
{
  "@context": "http://schema.org"
}

Writing Python markdown extensions

MkDocs uses Python markdown, and hence uses extensions to Python Markdown. New extensions can be created by plugging into the extensions API.

Start with a simple extension of inline tag processor to replace ---foo--- with <del>foo</del> from the tutorial on writing extensions for python markdown, and get that working in MkDocs.

In the top level project directory (with venv for mkdocs set up and running).

(venv)$ mkdir OCXTest
(venv)$ cd OCXTest
(venv)$ touch setup.py
(venv)$ touch ocxmd.py
(venv)$ touch test.py

Edit the new files:

from setuptools import setup
setup(
    name='ocxtest',
    version='0.1',
    py_modules=['ocxtest'],
    install_requires=['markdown>=2.5'],
)
from markdown.extensions import Extension
from markdown.inlinepatterns import SimpleTagInlineProcessor

DEL_RE = r'(--)(.*?)--'

class OCXTest(Extension):
    def extendMarkdown(self, md):
        # create the del_tag processor to put <del> tags around DEL_RE match(3)
        del_tag = SimpleTagInlineProcessor(DEL_RE, 'del')
        #  register the del_tag procesor with name 'del'
        md.inlinePatterns.register(del_tag, 'del', 176)

def makeExtension(*args, **kwargs):
    # allows calling of extension by string which is not dot-noted
    return OCXTest(*args, **kwargs)
import markdown
from ocxtest import OCXTest
print( markdown.markdown('foo --deleted-- bar', extensions=['ocxmd']) )

Install the extension (the develop keyword installs it as a link to the development directory so that any future edits to it will take effect without re-installing).

(venv)$ python setup.py develop
(venv)$ python test.py
<p>foo <del>deleted</del> bar</p>

To use in mkdocs, edit mkdocs.yml:

markdown_extensions:
  - ocxtest
In markdown:
foo --deleted-- bar
Renders in mkdocs as: foo deleted bar (may require restart of mkdocs to get change to mkdocs.yml noticed)