Get started
Install Markus, convert a page, and use it from Python.
Markus is GitHub Flavored Markdown with a small vocabulary for layout intent. You write Markdown; where Markdown cannot say what you mean, you add a colon-fenced directive.
Install
Markus needs Python 3.10 or newer. The package is anthus-markus, the module is markusmd, and the command is markus.
pip install anthus-markus
Write a page
Save this as page.md. The preview beside it is what Markus renders.
Markus
---
title: Release notes
description: What changed this week.
---
We shipped **three** improvements.
:::callout{kind="tip" title="Upgrade now"}
Every change is backward compatible.
:::
::metric{value="38" unit="%" label="Faster builds" delta="-38%"}
Preview
Release notes
What changed this week.
We shipped three improvements.
- Faster builds
- 38%-38%
Convert it
markus convert page.md -o page.html
convert writes a complete HTML document with Markus's stylesheet inlined. Useful options:
| Option | Effect |
|---|---|
--fragment |
Emit only the <article>, for embedding in your own template |
--no-css |
Leave the stylesheet out and link your own |
--theme NAME |
Apply a named theme |
--minify-css |
Minify the inlined stylesheet |
-o FILE |
Write to a file instead of stdout; use - as the source to read stdin |
Check it
markus validate page.md
markus ast page.md
validate reports the first unknown directive, unknown attribute, or misplaced child with its line number. ast prints the validated document as JSON: front matter and an ordered list of directive and Markdown block nodes.
Edit with a live preview
markus preview page.md
preview opens a local editor with the rendered page beside the source.
Use it from Python
from markusmd import convert, parse, parse_document
html = convert(open("page.md", encoding="utf-8").read())
fragment = convert(source, full_document=False, include_css=False)
document = parse(source) # validated AST: Document, Directive, MarkdownBlock
tree = parse_document(source) # the same structure as plain JSON-ready data
Invalid source raises MarkusSyntaxError or MarkusValidationError, both subclasses of MarkusError, each with a line attribute.
Where to next
- Syntax and metadata covers the rules every directive shares.
- The feature index lists every directive with its page.