markwright¶
markwright is a set of Python-Markdown extensions plus a companion CLI, mw, for author-friendly markdown: highlighted text, labeled code fences, and media embeds.
Use the extensions in any tool built on Python-Markdown (including MkDocs), or the mw pipeline in toolchains that are not, like Hugo.
The author-facing syntax and HTML output are derived from DigitalOcean's do-markdownit (licensed under the Apache License 2.0); markwright ports those to Python-Markdown and adds the mw CLI on top.
See NOTICE for attribution.
Features¶
- Highlight wraps
<^>text<^>in<mark>, and works inside inline code and fenced code blocks where==text==cannot reach. - Fence adds labels, secondary labels, environment classes, and command-line prefixes to code blocks.
- YouTube turns
[youtube ID]into a responsive iframe embed. - CodePen embeds a pen with theme, default-tab, and layout options.
- Twitter embeds a tweet with theme and alignment options.
- Instagram embeds a post with caption and alignment options.
- Slideshow builds an image slideshow with navigation arrows.
- Image Compare renders two images with a draggable before/after slider.
Installation¶
uv add markwright
Or install from a local path:
uv add --editable ../markwright
MkDocs 2.0 Compatibility
MkDocs 2.0 removes the plugin system and rewrites the theming architecture, breaking all existing plugins and themes including Material for MkDocs. There is no migration path. This project pins MkDocs 1.x (mkdocs>=1.6,<2).
Usage¶
These extensions work with Python-Markdown directly, so you can use them in any Python program (a Flask app, a CLI tool, a static site generator, or a simple script).
import markdown
md = markdown.Markdown(
extensions=[
"pymdownx.superfences",
"pymdownx.highlight",
"markwright.highlight",
"markwright.fence",
"markwright.youtube",
"markwright.codepen",
"markwright.twitter",
"markwright.instagram",
"markwright.slideshow",
"markwright.image_compare",
]
)
source = """
```command
[label deploy.sh]
ssh root@server
apt update
```
"""
html = md.convert(source)
print(html)
You can also load only the extensions you need by listing just those in the extensions list.
Using MkDocs? See Using with MkDocs for the mkdocs.yml configuration.
Note
The fence extension should be used alongside pymdownx.superfences and pymdownx.highlight for proper code block rendering. Without them, the fence preprocessor will still extract directives, but the code block HTML structure may differ from what the postprocessor expects.
Using It Outside Python¶
If your toolchain is not built on Python-Markdown, the mw command-line tool runs the same extensions as pre and post filters around any renderer:
mw pre < in.md | your-renderer | mw post > out.html
See the CLI Reference for the commands and flags, and the Hugo integration guide for a worked setup.
Architecture¶
Each extension is a standalone Python-Markdown extension loaded by name (e.g., markwright.highlight). The extensions use three processor patterns:
-
Fence uses a Preprocessor (priority 40) that runs before
pymdownx.superfencesto extract directives. A Postprocessor (priority 25) injects labels, classes, and prefix markup into rendered HTML. -
Embeds use Preprocessors (priority 20) that run after superfences, matching standalone
[name ...]lines. Social embeds add a Postprocessor (priority 15) for one-time script injection. -
Highlight uses an InlineProcessor (priority 175) for regular text, plus a Postprocessor (priority 25) for
<^>markers inside code blocks where the delimiters are HTML-escaped.
License¶
This project is a port of do-markdownit by DigitalOcean, which is licensed under the Apache License 2.0. See the NOTICE file for attribution details.