markwright
A Python port of DigitalOcean's do-markdownit JavaScript library.
These are Python-Markdown extensions that bring DigitalOcean's markdown syntax (highlighted text, labeled code fences, and a set of media embeds) to any tool built on Python-Markdown, including MkDocs, Flask, or a plain script.
The port maintains compatibility with the original do-markdownit HTML output, so rendered pages match what DigitalOcean produces.
A bundled command-line tool, mw, runs the same extensions as pre and post filters around any renderer, so the syntax also works in toolchains that are not built on Python-Markdown, like Hugo.
Full documentation and a live demo: https://masonegger.github.io/markwright/
Features
Each extension is standalone and can be loaded on its own or alongside the others.
- 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 (line numbers,
$/#prompts, custom 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
pip install markwright
To work against a local checkout, install it editable:
uv add --editable ../markwright
Usage
With MkDocs
Add the extensions to mkdocs.yml.
Load markwright.fence after pymdownx.superfences and pymdownx.highlight so the code-block HTML is in the shape the fence postprocessor expects.
markdown_extensions:
- pymdownx.superfences
- pymdownx.highlight:
pygments_lang_class: true
- markwright.highlight
- markwright.fence:
allowed_environments:
- local
- second
- third
- markwright.youtube
- markwright.codepen
- markwright.twitter
- markwright.instagram
- markwright.slideshow
- markwright.image_compare
Standalone
The extensions work with Python-Markdown directly, so you can use them in any Python program.
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",
])
html = md.convert("This has a <^>highlighted word<^> in it.")
print(html)
Load only what you need:
import markdown
# Just YouTube embeds
md = markdown.Markdown(extensions=["markwright.youtube"])
html = md.convert("[youtube dQw4w9WgXcQ]")
The fence extension expects pymdownx.superfences and pymdownx.highlight to be loaded too.
Without them the preprocessor still extracts directives, but the code-block HTML may not match what the postprocessor rewrites.
Command-Line Interface (mw)
For a toolchain that is not built on Python-Markdown, the mw command runs the same extensions as a pair of Unix filters around any renderer: a pre stage on the Markdown source, and a post stage on the rendered HTML.
mw pre < in.md | your-renderer | mw post > out.html
mw preexpands the embeds and extracts fence directives into anmw-fencecomment.mw postapplies the fence styling, resolves the highlights, and injects each embed script once.mw renderruns the full pipeline in one shot for callers without their own renderer.mw listprints every extension and the stages it provides.
Your renderer must pass raw HTML and HTML comments through. Hugo is a worked, tested example: see the Hugo guide. The full command and flag reference is in the CLI docs.
Syntax at a Glance
Highlight: <^>important<^>
Fenced code with a label and command prompts:
```command
[label deploy.sh]
ssh root@server
apt update
```
YouTube: [youtube dQw4w9WgXcQ]
[youtube dQw4w9WgXcQ 360 640]
CodePen: [codepen MattCowley vwPzeX]
[codepen MattCowley vwPzeX dark css]
Twitter: [twitter https://twitter.com/github/status/1234567890]
Instagram: [instagram https://www.instagram.com/p/CkQuv3_LRgS]
Slideshow: [slideshow https://picsum.photos/id/10/480/270 https://picsum.photos/id/20/480/270]
Image Compare: [compare before.jpg after.jpg]
See the extension docs for every flag and the exact HTML each one produces.
Development
This project uses uv and just.
just install # uv sync
just test # unit tests, 100% line + branch coverage
just test-integration # end-to-end Hugo pipeline test (needs hugo)
just lint # ruff check + ruff format --check
just typecheck # mypy --strict
just check # test + lint + typecheck
just docs-serve # serve the docs site at localhost:8000
just check must pass before a change is complete.
The tooling bar is strict: mypy --strict, a clean ruff, and full test coverage.
License
markwright is released under the MIT License.
It is a port of do-markdownit by DigitalOcean, which is licensed under the Apache License 2.0.
See the NOTICE file for attribution details.
Metadata
Release files for markwright 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| markwright-0.1.0.tar.gz | 26.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| markwright-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.0 kB
Release files / markwright-0.1.0.tar.gz
| Download URL | markwright-0.1.0.tar.gz |
|---|---|
| Size | 26.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f99ce68cf826d485bd33773e379445259cde69fde0609ed5ee677616667bfae8
|
|
BLAKE2b-256 checksum How to use checksums |
51612512efb81ca06985f869aee02dca803636df921af0b2beab59a387c83403
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / markwright-0.1.0-py3-none-any.whl
| Download URL | markwright-0.1.0-py3-none-any.whl |
|---|---|
| Size | 35.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7144f77788fb879d22d1d79dff5a9a49822addc3a7fbebca87263b13aedb75ae
|
|
BLAKE2b-256 checksum How to use checksums |
3b21367b46296e7e96207d4c088d6f822521f28b5ea00fa6059cc8ba2ed87d48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for markwright 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.