Skip to content

Architecture

Every module in mdx_steroids is an independent Python-Markdown extension. This page explains where each one hooks into Python-Markdown's conversion and in which order they run when you load several.

The Python-Markdown pipeline

Python-Markdown converts text in five stages. Each stage has a registry of processors, and processors with a higher priority run first.

Stage Works on Runs
Preprocessors The source, as a list of lines First
Block processors Blocks of lines, building an element tree Second
Inline patterns Text inside the elements Third
Tree processors The finished element tree Fourth
Postprocessors The serialised HTML string Last

Where each extension runs

Extension Stage Registered name Priority
meta_yaml Preprocessor meta_yaml 29
md_mako Preprocessor md_mako 28
comments Preprocessor comment_munger 25
comments Preprocessor comment_remover 15
interlink Preprocessor interlink 6
wikilink Preprocessor wikilink 4
img_smart Block processor smartImage 75
keys Inline pattern keys 185
figcap Inline pattern image_link (replaces the built-in pattern) 150
figcap Tree processor definition_caption 6
absimgsrc Tree processor absoluteImages 0
replimgsrc Tree processor ReplaceImageSrc 0
comments Postprocessor raw_comment_replacer 5
kill_tags Postprocessor kill_tags 0
translate_no Postprocessor translate_no 0

Processors with the same priority run in the order their extensions were loaded.

What the order means in practice

  • Front matter, then templates. meta_yaml (29) runs before md_mako (28), so the YAML block is gone and md.Meta is filled when Mako renders the page.
  • Templates, then links. md_mako runs before interlink and wikilink, so a template can produce [[Page]] links and they are still converted.
  • Comments after templates. comments removes <!--- … --> after Mako has run. A Mako expression inside a three-dash comment is still evaluated, and an undefined variable there still stops the conversion.
  • Line-based preprocessors see code. comments, interlink, wikilink and md_mako work on raw lines, before Python-Markdown knows what is code. Their syntax is also processed inside indented code blocks and inline code. See each extension's page for details.
  • Images. img_smart (block processor) builds its own <img> for images that stand alone on a line. figcap changes images in running text. Both produce <img> elements that absimgsrc and replimgsrc change later.
  • HTML clean-up last. kill_tags and translate_no work on the final HTML string, so they also see raw HTML from the source and elements created by other extensions, such as the <kbd> elements from keys.

Module layout

File Contents
mdx_steroids/__init__.py __version__ (from __version__.py, generated by hatch-vcs) and __all__
mdx_steroids/<name>.py One extension per module, with a makeExtension() function
mdx_steroids/kbd.py from .keys import *, which makes mdx_steroids.kbd an alias of keys
mdx_steroids/keymap_db.py keymap (key name → displayed text) and aliases (alias → key name)
mdx_steroids/util.py Re-exports pymdownx.util

Python-Markdown loads an extension by its dotted name: it imports the module and calls its makeExtension(**options).

How the options reach the processors

Each extension class defines its options in self.config as {"name": [default, "description"]}. Python-Markdown's Extension class merges the values you pass. Most extensions then hand self.getConfigs(), a plain {"name": value} dict, to their processor. interlink and wikilink hand over self.config itself and read values with config[name][0].