Everything you can write in this theme
A reference post that exercises every markdown feature and component the site supports. Keep it, or delete it once you've stopped needing the cheat sheet.
This post exists as a working cheat sheet. Every feature below is enabled in
astro.config.ts and styled in src/styles/global.css. If something here looks
wrong, the styling is wrong — not your post.
Text and inline marks
Standard emphasis works: italic, bold, both, struck through, and
inline code. Smart punctuation is on, so “straight quotes” curl, — becomes an
en dash, --- an em dash, and … an ellipsis.
Superscript and subscript are enabled: 10^6^ and H2O.
Links get a highlighter sweep on hover — like this one.
Keyboard keys aren’t markdown, but the styling exists if you write the HTML: ⌘ + K.
Headings and anchors
Every h2–h4 gets a slugified id automatically, plus a # anchor that
appears on hover — both at build time, via rehype-heading-ids and
rehype-autolink-headings.
Fourth-level headings
These render as small uppercase labels rather than another serif size — useful for breaking up a long section without implying a new topic.
Lists
Unordered lists use a small peach diamond:
- First item
- Second item, with a nested list
- Nested one
- Nested two
- Third item
Ordered lists use monospace numerals:
- Do the first thing
- Then the second
- Then the third
Task lists work (GFM):
- Ship the site
- Write the reference post
- Delete the reference post
Quotes
Blockquotes get a marker-yellow rule and italic text. Good for a pull quote or someone else’s sentence you’re arguing with.
Code
Plain fenced code with a language gets syntax highlighting in both themes:
def reading_time(words: int, wpm: int = 220) -> int:
return max(1, round(words / wpm))
Add title="…" for a filename header, showLineNumbers for a numbered gutter,
and {} to highlight specific lines:
export function slugify(input: string): string {
return input
.toLowerCase()
.trim()
.replace(/[^a-z0-9]+/g, '-')
.replace(/^-|-$/g, '');
}Inline notation comments give you diffs, focus, and error levels:
const config = {
retries: 3,
retries: 5,
timeout: 30_000,
endpoint: undefined,
cache: 'maybe',
};Focus dims everything else until you hover:
setup();
const result = doTheImportantThing();
teardown();
Tables
Wide tables scroll inside their own box rather than widening the page:
| Feature | Enabled by | Where to change it |
|---|---|---|
| GFM tables, footnotes, task lists | unified({ gfm: true }) | astro.config.ts |
| Smart punctuation | unified({ smartypants: true }) | astro.config.ts |
| Maths | remark-math + rehype-katex | astro.config.ts |
| Heading ids and anchors | rehype-heading-ids + rehype-autolink-headings | astro.config.ts |
| Code themes and notation | Shiki + transformers | astro.config.ts |
| Filename tabs, line numbers | transformerCodeTitle | src/lib/shiki-code-title.ts |
| Callouts, figures, asides | MDX components | src/components/mdx/ |
Components
These four are available in any .mdx post with no import needed — they’re
passed in by src/pages/blog/[...slug].astro.
<Aside> puts a margin note in the right gutter on wide screens and folds it
inline on narrow ones.
For images, use <Figure> with an imported asset so Astro optimises it:
import diagram from './diagram.png';
<Figure src={diagram} alt="How the pipeline fans out" caption="Fan-out, then merge." width="wide" />
alt is required by the component’s props, and heroAlt is required by the
content schema whenever a post sets hero — both enforced at build time, so an
unlabelled image fails the build rather than shipping.
For video and embeds, <Embed> keeps a fixed aspect box so nothing jumps:
<Embed src="https://www.youtube-nocookie.com/embed/VIDEO_ID" title="Demo walkthrough" />
Maths
Inline maths with single dollars: the -mean welfare interpolates between social welfare at and egalitarian welfare as .
Display maths with double dollars:
Long expressions scroll inside their own box rather than widening the page:
Rendered by KaTeX at build time, so there’s no maths JavaScript in the page. MathML is emitted alongside the visual output, which means screen readers get real equations rather than a pile of glyphs.
Footnotes
Footnotes collect at the bottom with a return link.1 You can reference the same one twice,1 and they’re numbered automatically.2
Frontmatter reference
Everything the schema accepts, with the required fields first:
---
title: Required, max 120 chars
description: Required, max 300 chars — used in meta tags, lists, RSS, and the OG image
pubDate: 2026-08-14
# Optional from here down:
updatedDate: 2026-08-20
tags: ['one', 'two']
draft: false # true = visible in dev, excluded from the production build
featured: false # true = surfaces on the homepage
series: Building Poiro
toc: true # false = no outline rail
hero: ./cover.jpg # relative to the post file; requires heroAlt
heroAlt: Description of the cover image
---
Validation runs at build time via Zod, so a typo in a field name or a missing
heroAlt fails the build with a pointer to the file.