Syntax Guide

The contents of this post have been entirely or partially created using AI. It’s a rare exception on this blog. Read more about how I use or don’t use AI.

This page documents the Markdown syntax and special styles available when writing posts and pages for this blog. It doubles as a live test of the renderer — everything shown below is actually rendered by Magnetizer, not typed out as a picture.

Since a post’s title already occupies the top-level heading, headings inside the body should start at ### — anything more prominent (# or ##) triggers a build warning.

Text formatting

Source:

**bold**, *italic*, `inline code`, and ==highlighted== text.

Renders as:

bold, italic, inline code, and highlighted text.

Headings

Source:

### A level-3 heading
#### A level-4 heading

Renders as:

A level-3 heading

A level-4 heading

Links

Regular links, and bare URLs/email addresses wrapped in <> for automatic linking:

[My values](1.html), or just <https://mxgns.uk> and <[email protected]>.

Renders as:

My values, or just https://mxgns.uk and hello@mxgns.uk.

Lists

An unordered list:

- Optimisation & curation
- Boating
- Reading

Renders as:

  • Optimisation & curation
  • Boating
  • Reading

An ordered list:

1. First
2. Second
3. Third

Renders as:

  1. First
  2. Second
  3. Third

Blockquotes

Source:

> A quoted thought, indented and set apart from the rest of the text.

Renders as:

A quoted thought, indented and set apart from the rest of the text.

Code

Inline code uses single backticks: `like this`.

For a proper code block, indent every line with four spaces (or one tab) rather than fencing it with ```. Triple backticks are not treated as a fenced code block by this renderer — they collapse into an inline <code> span instead, which loses the block formatting and line breaks. Indentation is the only reliable way to get a real block.

Source:

    def greeting(name):
        return f"Hello, {name}!"

Renders as:

def greeting(name):
    return f"Hello, {name}!"

Horizontal rule

Source:

---

Renders as an unstyled <hr> (no custom styling is defined for it in style.css, so it falls back to the browser default):


Smart typography

Straight quotes and apostrophes are automatically converted to their curly (“smart”) equivalents. Dashes (--) and ellipses (...) are left exactly as typed — they are not converted.

Source:

She said "it's fine" -- really...

Renders as:

She said “it’s fine” -- really...

Quotes inside inline code or an indented code block are left untouched, e.g. "like this".

Images

Photos for a post or page aren’t inserted with Markdown’s ![alt](src) syntax. Instead they’re placed alongside the .md file in content/ as {post-id}-image-{NN}.{ext} (e.g. 12-image-01.jpg, 12-image-02.png), and alt text is supplied in the frontmatter, in file order:

---
date: 2026-05-21
title: A day at the coast
images:
  - Beach hut in the rain
  - A bowl of bananas
---

Any image not referenced inline (see below) is automatically shown as a strip of <figure> elements above the post body.

Inline images

To place a specific image inline within the body text, use {{ image N }} on its own line, with blank lines before and after — N matches the two-digit number in the filename:

Some text before the image.

{{ image N }}

Some text after.

This is replaced with a <figure><img></figure> using that image’s resized file and its frontmatter alt text. Referencing an image number the post doesn’t have, or using the token inline with other text, is a build error. (Note: this reference page has no images of its own, so the example above uses a placeholder letter rather than a real number — a real post would give the actual position of the image in its filename, e.g. the third image.)

Read more marker

Placing the marker below on its own line splits a post’s body. On index/category pages only the content above the marker is shown, followed by a “Read more” link (which folds in a photo count if any images are hidden past the marker); on the individual post page the marker has no effect and the full body is shown.

An introductory paragraph, shown everywhere.

<!-- MORE -->

The rest of the story, only shown on the post's own page.

(Shown here in capitals only because this reference page is itself parsed by Magnetizer, and the real, lowercase marker would split this very page. In your own posts, write it exactly as above, but lowercase.)

Frontmatter fields

Beyond date, title and images, a few other fields turn on extra styling:

---
date: 2026-05-21
category: travel
favourite: true
draft: false
ai_assisted: true
---
  • category — must match a slug configured in config.yaml; adds a category link to the post’s footer and includes the post on that category’s page.
  • favourite: true — adds a small star after the post’s entry in the archive listing.
  • draft: true — keeps the post out of index/category/archive/feed listings; it’s still reachable at its own URL.
  • ai_assisted: true — adds a disclosure banner (see below) to the top of the post’s content, everywhere it’s shown.

AI-assisted disclosure

Setting ai_assisted: true in a post’s frontmatter inserts a banner at the very top of the post body — on the individual post page, and in the excerpt or full body shown on index and category pages:

---
date: 2026-07-17
ai_assisted: true
---

The banner’s wording (and any link inside it) comes from ai_disclosure_html in config.yaml, not from anything written in the post itself — Magnetizer has no opinion on the phrasing, only on where the banner appears:

ai_disclosure_html: 'The contents of this post have been entirely or partially created using AI. It’s a rare exception. <a href="48.html">Read more about how I do or don’t use AI on this blog.</a>'

This page itself has ai_assisted: true set, so an example of the banner can be seen at the very top of the page.

The banner uses the container-brown colour variant together with an ai-disclosure class that lays the icon and text out side by side, with tighter padding than a regular container (matching ::: info). The AI icon (resources/ai-icon.svg, black, per the standard AI-content disclosure symbol) is added automatically to the left of the text. If ai_disclosure_html isn’t set in config.yaml, a generic fallback sentence is used instead.

Container blocks

Wrap a section of Markdown in a ::: fence to render it inside a <div class="container">. Content between the fences is itself parsed as Markdown, and an opening ::: without a matching closing ::: is left as plain text. Containers don’t nest.

Source:

::: 
A plain container, useful for setting a block of content apart from the rest of the page.
:::

Renders as:

A plain container, useful for setting a block of content apart from the rest of the page.

Colour variants

Add one of container-pink, container-green, container-yellow, container-blue, container-beige or container-brown after the fence for a tinted version:

::: container-pink
A pink-tinted container.
:::

Renders as:

A pink-tinted container.

The other colours render as:

A green-tinted container.

A yellow-tinted container.

A blue-tinted container.

A beige-tinted container.

A brown-tinted container.

Info box

The info class renders a highlighted callout with an “i” icon, for asides or notes:

::: info
Worth calling out separately from the main text.
:::

Renders as:

Worth calling out separately from the main text.

Circle list

Adding li-circles alongside a plain or colour-variant class turns a bullet list inside the container into a row of circles — handy for a short set of tags or stats. It lays out 1, 2, 4 or 5 items specially (a single item fills the row, 2 or 4 split evenly, 5 splits 3-and-2); any other count wraps as a plain grid of thirds.

::: container-pink li-circles
- Item 1
- Item 2
- Item 3
:::

Renders as:

  • Item 1
  • Item 2
  • Item 3

Download links

There’s no Markdown shorthand for a download link with the little download icon — write the anchor tag directly with a download-link class, since raw HTML passes through untouched:

Get the full-size version <a href="12-image-01-resized.jpg" class="download-link">here</a>.

Renders as:

Get the full-size version here.