Markdown
aphid uses pulldown-cmark to render Markdown, with a small set of extensions enabled on top of standard CommonMark.
Standard elements
These work out of the box:
| Element | Syntax |
|---|---|
| Paragraph | Plain text separated by blank lines |
| Bold | **text** or __text__ |
| Italic | *text* or _text_ |
Inline code | `code` |
| Link | [text](url) |
| Image |  |
| Blockquote | > text |
| Unordered list | - item or * item |
| Ordered list | 1. item |
| Horizontal rule | --- |
| Hard line break | Two trailing spaces |
Headings
Headings are written with # markers. Because the page title is rendered as <h1> by the template, the markdown pipeline shifts all heading levels up by one — so # becomes <h2>, ## becomes <h3>, and so on. Levels are capped at <h6>.
Every heading automatically receives a slug-based id attribute for anchor links, and is included in the table of contents passed to the template.
When two headings on the same page produce the same slug (e.g. two # Examples sections), the second gets -2, the third -3, and so on, so anchor links remain unique.
Custom heading IDs
Override the auto-generated id by appending {#custom-id} to the heading. Useful when you want stable anchors that won’t change if you rephrase the heading text:
Custom ids are used verbatim — they’re not lowercased or normalised, so {#API_v2.1} produces id="API_v2.1". Custom and auto-generated ids share the same namespace: if a custom id collides with an earlier heading on the page, it gets the same -2, -3, … suffix.
Wiki Links can target either kind: [[page#config-ref]] resolves to a custom id, [[page#configuration-reference]] to the auto-generated slug.
Code blocks
Fenced code blocks are syntax-highlighted using syntect. The highlighter emits CSS classes (prefixed hl-) rather than inline styles, so syntax colors are fully controlled by the theme stylesheet. The default theme uses Catppuccin Mocha colors. Specify a language identifier after the opening fence:
Here is a rendered example:
use HashMap;
/// A page in the site, parameterised by its frontmatter type.
If the language is omitted or unrecognised, the block is rendered without highlighting. The built-in syntax set covers most common languages including Rust, Python, JavaScript, TypeScript, Go, C, C++, Shell, TOML, YAML, JSON, HTML, CSS, Dockerfile, and many more.
Mermaid diagrams
Fenced blocks tagged mermaid are rendered as live diagrams in the browser using Mermaid. The build pipeline emits the source as a <pre class="mermaid"> element and the Mermaid runtime converts it to SVG client-side once the page loads:
Renders as:
sequenceDiagram
Alice->>John: Hello John, how are you?
John-->>Alice: Great!
Alice-)John: See you later!
Mermaid supports flowcharts, sequence diagrams, class diagrams, state diagrams, gantt charts, mindmaps, and more — see the upstream syntax reference for what’s available.
The Mermaid runtime is vendored with aphid (no CDN) and only loaded on pages that contain at least one mermaid block, so unrelated pages don’t pay the bundle cost. If JavaScript is disabled, the original diagram source is shown as preformatted text.
External links
Links whose URL starts with http:// or https:// are rewritten to open in a new tab and carry rel="noopener noreferrer":
renders as:
example
Relative links, fragment links (#section), and other schemes (mailto:, tel:, …) are left untouched. Wiki Links are always treated as internal.
Images and static files
Images use standard markdown syntax: . For local assets, place files under your static_dir (default static/) and reference them with an absolute path:
Here is a rendered example using an image from the wiki’s static directory:

The build step copies static_dir into the output’s static/ directory, so the same path works in both serve and build modes. Theme static files are merged into the same /static/ namespace — see Themes for precedence rules.
Extensions
Tables
Strikethrough
Task lists
- -Footnotes
footnote content.
Wiki-links
Cross-links to any other page by filename stem:
See Wiki Links for full details.
Alerts
GitHub-style alert blocks highlight important information. Five types are supported:
Here are rendered examples:
Note
Highlights information that users should take into account, even when skimming.
Tip
Optional information to help a user be more successful.
Important
Crucial information necessary for users to succeed.
Warning
Critical content demanding immediate user attention due to potential risks.
Caution
Negative potential consequences of an action.
Alerts are rendered as <div class="markdown-alert markdown-alert-{type}"> elements with a title paragraph, so themes can style each type independently. Regular blockquotes (> without a [!TYPE] marker) are unaffected.
Smart punctuation
ASCII punctuation is automatically replaced with typographically correct Unicode characters during rendering:
| Input | Output | Description |
|---|---|---|
"quote" | “quote” | Curly double quotes |
'quote' | ‘quote’ | Curly single quotes |
-- | – | En dash |
--- | — | Em dash |
... | … | Ellipsis |
This happens at parse time and requires no special syntax — just write natural prose and the output will use proper typographic characters.
Not supported
The following are not enabled:
- Math (
$...$/$$...$$) - Custom heading ID syntax (
# Heading {#custom-id}) — IDs are auto-generated from the heading text