This page exists so I never have to guess. Every formatting feature, shortcode and embed the site supports is rendered here, next to the markup that produced it. When I want to know whether a callout suits a paragraph or how a diagram will look in dark mode, I open this page rather than experimenting inside a real post.

It doubles as a test: if something breaks after a theme update, it breaks here first.

Try the theme toggle in the header while reading. The diagrams, callouts and code blocks all follow it.

Text

Ordinary prose gets bold, italic, both at once, struck through and inline code. Links can be inline, referenced, or bare autolinks like https://gohugo.io/ — the last of those is turned into a link automatically.

Beyond the usual set, a few extensions are switched on: highlighted text, inserted text, H2O with a subscript and 106 with a superscript. Emoji work by name too 🚀 🦃.

Footnotes1 sit at the bottom of the page and link both ways.

**bold**, *italic*, ~~struck~~, `code`
==highlight==, ++insert++, H~2~O, 10^6^
[inline](https://gohugo.io/), [referenced][id], :rocket:
A footnote[^1] and its definition.

Headings

Headings from ## to #### are styled; # is reserved for the post title itself. The table of contents at the top is built from ## and ### only, which keeps it useful on a long page.

A third-level heading

A fourth-level heading

Lists

  • An unordered item
  • Another one
    • Nested one level
    • And a sibling
      • Two levels deep
  • Back to the top level
  1. Ordered lists count themselves
  2. So renumbering is free
    1. Nested ordering restarts
    2. As you would expect
  3. Third

Task lists render as checkboxes:

  • Migrate the posts off Ghost
  • Rebuild the theme
  • Write more often

Quotes and callouts

A plain blockquote:

Premature optimisation is the root of all evil.

And a nested one, for a quote inside a quote.

GitHub-style alerts render as callouts:

Note

Useful information the reader should notice even when skimming.

Tip

An optional shortcut that makes the task easier.

Important

Something the reader needs in order to succeed.

Warning

A risk that needs attention right away.

Caution

A consequence of a risky action — data loss, breaking changes.

The hint shortcode produces the same thing, with a couple of extra tones and an optional title:

note — the default. For an aside that does not fit the flow of the paragraph.

info — supplementary detail that helps but is not required.

tip — a recommended approach.

success — a confirmed good outcome, or the recommended path.

Check your indexes first

warning — a caveat. This one carries a title.

danger — irreversible or breaking. Use sparingly, or it stops registering.

> [!WARNING]
> GitHub alert syntax.

{{% hint danger %}}
Shortcode syntax, with **markdown** inside.
{{% /hint %}}

Code

Inline code sits in a paragraph. Fenced blocks take a language:

@Cacheable(value = "products", key = "#id")
public Product getProductById(Long id) {
    log.info("Fetching from DB...");
    return productRepository.findById(id).orElse(null);
}

Line numbers and highlighted lines are per-block options:

1
2
3
4
5
6
7
func main() {
    http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) {
        w.WriteHeader(http.StatusOK)
        io.WriteString(w, "ok")
    })
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Diffs get their own colouring:

- server.tomcat.max-threads=200
+ server.tomcat.threads.max=200

A block with no language is left unhighlighted, which suits output rather than source:

BUILD SUCCESSFUL in 4s
12 actionable tasks: 12 executed
An indented block works too, though a fence is clearer.

Tables

Alignment is set per column in the separator row.

SettingDefaultNotes
pagerSize10Posts per page
summaryLength30Words in the card summary
defaultContentLanguageenRoot language, no URL prefix

Images

A plain markdown image, click to enlarge:

Apollo 11 lifting off from Launch Complex 39A

The image shortcode adds a caption and sets width and height, so the page does not jump while it loads:

A TWA Boeing 307 Stratoliner in flight over mountains
The Boeing 307 Stratoliner, the first airliner with a pressurised cabin — so the first that could fly above the weather.

gallery puts several side by side:

All three are public domain, via Wikimedia Commons.

![alt text](/images/x.png)

{{< image src="/images/x.png" alt="…" caption="…" >}}

{{% gallery cols="3" %}}
![One](/images/a.png)
![Two](/images/b.png)
{{% /gallery %}}

Terminal recordings

asciinema embeds a recording. It is real text, so it can be selected and copied out of the player — unlike a screen capture.

{{< asciinema cast="/casts/demo.cast" speed="1.3" >}}

Any option the player understands can be passed along: autoplay, loop, speed, theme, cols, rows, idleTimeLimit, preload.

Diagrams

A fenced ```mermaid block becomes a diagram. It follows the light and dark themes.

graph LR
    A[Browser] -->|HTTPS| B(Nginx)
    B --> C{Cached?}
    C -->|yes| D[Redis]
    C -->|no| E[Spring Boot]
    E --> F[(PostgreSQL)]
    E -.->|write-through| D

Sequence diagrams:

sequenceDiagram
    participant C as Client
    participant A as API
    participant S as S3
    C->>A: POST /files
    A->>S: presign PUT
    S-->>A: signed URL
    A-->>C: 201 + URL
    C->>S: PUT file
    S-->>C: 200

And the rest of Mermaid’s catalogue — state, class, pie, Gantt, git graphs:

pie showData
    title Where the time goes
    "Writing code" : 45
    "Reading code" : 30
    "Meetings" : 15
    "Fighting YAML" : 10

The library is only fetched on pages that contain a diagram, so an ordinary post loads none of it.

Maths

Set math: true in the front matter and KaTeX renders both inline and block formulas. Inline: the amortised cost is \(O(1)\) per operation, with \(n\) items.

$$ P(\text{cache hit}) = 1 - \left(1 - \frac{1}{n}\right)^{k} $$
Inline: \\(O(1)\\)

$$
E = mc^2
$$

Tabs

Tabs work without JavaScript — each panel is shown by a radio input, so they survive a failed script and print correctly.

brew install hugo
sudo snap install hugo --channel=extended
choco install hugo-extended
{{< tabs >}}
{{% tab "macOS" %}} content {{% /tab %}}
{{% tab "Linux" %}} content {{% /tab %}}
{{< /tabs >}}

Steps

1. ### Create the site `hugo new site myblog` scaffolds the directory layout.
  1. Add a theme

    Add it as a submodule under themes/, then point theme at it.

  2. Write something

    Markdown files go under content/posts/. Set draft: false when it is ready.

  3. Publish

    hugo --minify writes the finished site to public/.

Collapsible sections

What the front matter on this post looks like
title: "Everything This Blog Can Render"
date: 2020-01-01T09:00:00+03:00
tags: ["Reference", "Hugo", "Markdown"]
coverLabel: "Reference"
math: true
showToc: true
TocOpen: true

math: true is what pulls in KaTeX; coverLabel overrides the text on the generated cover tile.

Open by default

Pass open and the section starts expanded.

Columns

Narrow

A 1:2 ratio makes this column half the width of its neighbour.

Wide

Columns take any content — lists, code, images. They stack on narrow screens whatever the ratio says, so nothing is squeezed on a phone.

  • Still a list
  • Still readable

Buttons and badges

GitHub About me

Badges sit inline: this feature is new , that one is beta , and the old API is deprecated .

Other embeds

Hugo ships shortcodes for the common video and social embeds. They need an ID from the service, so they are listed here as syntax rather than rendered:

{{< youtube w7Ft2ymGmfc >}}
{{< vimeo 146022717 >}}
{{< x user="SanDiegoZoo" id="1453110110599868418" >}}
{{< instagram BWNjjyYFxVx >}}

The theme adds a couple more:

{{< figure src="/images/x.png" title="Caption" >}}
{{< video src="/video/demo.mp4" >}}
{{< audio src="/audio/track.mp3" >}}
{{< rawhtml >}}<div>Anything at all</div>{{< /rawhtml >}}

Raw HTML and attributes

Inline HTML passes straight through, which is the escape hatch when markdown has no spelling for something: Ctrl + K, CSS, and super/sub the long way round.

Attributes can be attached to a heading or a block:

A heading with an id

That heading is linkable as #custom-anchor.


A horizontal rule, three dashes, closes a section.

What is not here

Two things I decided against rather than forgot:

  • OpenAPI rendering. Embedding a spec browser means shipping a large viewer for a page or two. A link to the spec does the job.
  • Comments. They need a service, moderation and someone’s data. Email is at the bottom of the about page.

  1. Like this one. Click the arrow to jump back to where you were reading. ↩︎