Write
Writing
Every page is a Markdown file in content/, ending .md.
Write a page
---
title: Post 1
date: 2026-10-04
---
The first paragraph.
The lines between the two --- lines are the page’s
front matter. Below them is the writing.
Front matter is optional. Without title:, the title is the opening
# heading.
A file ending .html that opens with front matter is a page written in
HTML. Other files in content/ go with the pages: see
Addresses.
What Markdown can I use?
| Extra | How it is written |
|---|---|
| Tables | A row to a line, cells parted by |, a line of dashes under the first |
| Strikethrough | ~~words~~ |
| Task lists | - [x] done and - [ ] not done |
| Definition lists | A term, then : what it means on the line below |
| Footnotes | [^1] |
| Addresses written bare | www.example.org |
| HTML | As HTML, published as written, apart from the calls and @url in it |
Statac reads CommonMark, with the extras above.
Links
Read the [first post](/posts/post-1/), or [the second][second].
[second]: /posts/post-2/
A link is written [words](address), or [words][label] with the
address on a line of its own anywhere on the page. Every link is
checked.
An address read from where the page is published, such as photo-1.jpg,
../post-2/ or #notes, leads to the same place wherever the writing
is shown: in a list’s excerpt or a feed it is written out from the top
of the domain.
A link names an address, never a file in content/. A page is a folder
at its address, so from content/essays/essay-1.md, published at
/essays/essay-1/, the page beside it is ../essay-2/, not
essay-2.md.
Links inside the site
[About](@url(/about/))
[About][about]
[about]: @url(/about/)
<a href="@url(/about/)">About</a>
A link written from / starts at the top of the domain. @url(...)
leads inside the site, wherever it is published.
| Written | Its / is the top of |
On https://example.org/blog/, it leads to |
|---|---|---|
[About](/about/), or href="/about/" in the page’s HTML |
the domain | /about/, outside the site |
[About](@url(/about/)) |
the site | /blog/about/ |
{{ url("/about/") }} in a template |
the site | /blog/about/ |
, a picture found in content/ or static/ |
the site | /blog/img/logo.svg |
/about/ in permalink, redirect_from or redirect_to |
the site | /blog/about/ |
The top of the site is its url, path and all. On a site
at the top of its domain, the two are one.
@url(...) takes the address a page or file is published at, from the
top of the site. On https://example.org/blog/:
| Written | Gives |
|---|---|
@url(/about/) |
/blog/about/, as a link’s address, or as text where it stands alone |
@url(/about/#team) |
/blog/about/#team: what follows a ? or a # is kept |
@url("/about/") |
/blog/about/: quotes change nothing |
\@url(/about/), or @url in code |
Text, as typed, without the backslash |
Link to a heading
See [how to get there](#getting-there).
## Getting there
Every heading gets an id from its words as typed. Of two headings with
the same words, the second’s id ends -1, a third’s -2, and so on.
To choose the id, end the heading with it in braces, and classes if you like:
## Version 1.0 notes {#version-1.0-notes}
## Getting back {#route .wide}
A chosen id is kept as written, and made ids step aside for it. Other
braces, as in ## Sets {a, b}, are words.
Addresses written bare
Read more at www.example.org/a, or write to name@example.org.
An address with no link around it becomes one: www.example.org/a leads
to http://www.example.org/a, and a mail address to itself after
mailto:.
| The rule | |
|---|---|
| What is linked | An address starting www., http://, https:// or ftp://, and a mail address. After http://, https:// or ftp:// any name will do, as http://localhost:8080. |
| Where it starts | www. at the start of a line, or after a space, *, _, ~ or (. http://, https:// and ftp:// after anything but a letter. A mail address after anything. |
| Where it ends | At the next space or <. Punctuation at its end stays in the sentence. |
| What it leaves out | A closing bracket or quote with no opening one inside the address: (see www.example.org/a). links www.example.org/a. |
| Where nothing is linked | In code, in maths, in a link’s words, in a snippet call, in HTML written as a block of its own, and inside <a>. Between a [ and the next ], only a mail address is linked. |
| To keep an address as text | Write it as code, or put a backslash before one of its full stops: www\.example.org. |
Pictures

The words in the brackets describe the picture for a reader who can’t see it. Keep the file beside the page and name it from there. More: Pictures, and Videos and files.
Callouts
> [!WARNING]
> Back up the site before moving it.
A quotation that opens with one of five markers is a callout. Without a
snippet for callouts, Statac builds each as an <aside> holding the
writing after the marker:
| Marker | Built as | title in English |
|---|---|---|
[!NOTE] |
<aside class="callout note"> |
Note |
[!TIP] |
<aside class="callout tip"> |
Tip |
[!IMPORTANT] |
<aside class="callout important"> |
Important |
[!WARNING] |
<aside class="callout warning"> |
Warning |
[!CAUTION] |
<aside class="callout caution"> |
Caution |
To build callouts your own way, write snippets/markdown/callout.html.
It is handed kind, in small letters; title, the kind’s name in the
page’s language; and body, the writing inside:
<div class="callout {{ kind }}" role="note">
<p class="callout-title">{{ title }}</p>
{{ body }}
</div>
Statac has the names in English alone. Any other language takes them
from the callouts line of the site’s language
file.
Code blocks
```rust An example
fn main() {}
```
The first word after the opening fence names the language the code is coloured as. The rest is the caption, shown above the code.
| After the fence | Coloured as | Caption |
|---|---|---|
rust |
rust |
none |
rust An example |
rust |
An example |
rust "An example" |
rust |
An example |
"An example" |
nothing | An example |
example.rs |
rs |
example.rs |
src/example.rs Part 1 |
rs |
src/example.rs Part 1 |
Cargo.toml |
toml |
Cargo.toml |
Makefile or Dockerfile |
the language it names | none |
notes-1.txt |
nothing | notes-1.txt |
text, txt, plain, plaintext, or no word |
nothing | none |
rust { |
rust |
none |
GNUmakefile, CMakeLists.txt, Gemfile, Rakefile, Cargo.lock, .bashrc or .zshrc |
its language, known by its whole name | the name |
A first word written as a file’s name, in letters, digits, ., _, -
and /, is the caption, and what follows its last dot names the
language.
Language names
Statac colours over two hundred languages, by name or short form, in any capitals. The common ones:
| Language | Names after the fence |
|---|---|
| Rust | rust, rs |
| Python | python, py |
| JavaScript | javascript, js |
| Shell | shell, bash, sh, zsh |
| A terminal session, with its prompts | console |
| C and C++ | c, c++, cpp |
| Go | go, golang |
| Diff | diff, udiff |
| Make | make, makefile |
| Assembly | nasm, asm |
| Common Lisp | cl, common-lisp |
| HTML, CSS, JSON, YAML, TOML and SQL | html, css, json, yaml, toml, sql |
What a block is built as
The language’s word stays as a class on the block’s <code>, such as
language-rust, coloured or not. The colours are classes from the
code stylesheet. Spaces and line breaks
are published as written.
Statac writes the block’s HTML unless the site has a
snippets/markdown/code.html:
pieces of the writing shows both.
For a file beside the writing shown as code, see
Videos and files.
Footnotes
The figures are from 2026.[^1]
[^1]: The yearly report.
A marker, [^1], points to a note, [^1]: on a line of its own anywhere
on the page. Notes are numbered in the order they are first pointed to,
whatever their labels, and shown at the foot of the page with a link
back: ↩, or ↪ on a page written right to left.
The number in the text is in the page language’s digits. The notes are an ordered list, whose digits the stylesheet chooses.
A screen reader says “back to the text” for the link back, in English.
Any other language takes the words from the back_to_the_text line of
the site’s language file.
Maths
The area of a circle is $\pi r^2$.
$$
\int_0^1 x^2 \, dx = \frac{1}{3}
$$
Maths between dollar signs is built into the page as MathML, which browsers show without a script. Two dollar signs either side set the maths on a line of its own.
An opening dollar sign has no space after it, and a closing one has no
space before it and no figure after it, so $30 and $60 stays two
prices. To show a dollar sign that would open maths, write \$.
The notation is LaTeX’s:
| What | Such as |
|---|---|
| Fractions, roots, sub- and superscripts, primes | \frac{1}{3}, \sqrt{2}, x_1^2, f' |
| Greek letters, sums, integrals and limits | \pi, \sum, \int_0^1, \lim |
| Accents, words and other alphabets | \hat{x}, \text{...}, \mathbb, \operatorname, \color |
Matrices and the environments of amsmath |
matrix, cases, aligned |
| Commands of your own | \newcommand, inside one expression |
| Numbered equations | \begin{equation}, counted on through the page; \eqref{...} links to one by its \label{...} |
Maths works the same in headings, tables, footnotes, callouts and
excerpts. A heading’s id and the
table of contents take it without
its dollar signs: ## The $O(n)$ bound is listed as “The O(n) bound”.
Statac adds only the <math> elements. page.maths is true where the
writing holds maths, so a template can load a maths font on those pages
alone: see a stylesheet for maths.
Snippet calls
@figure("photo-1.jpg")
Read @book('Post 1') before the rest.
@aside(kind='tip')
Writing read as *Markdown*, lists and all.
@end
@name(...) places the snippet snippets/name.html there,
on a line of its own or inside a sentence.
| In the call | The snippet is handed |
|---|---|
'Post 1' or "Post 1" |
Text |
2026, true or false, without quotes |
A number, or true or false |
| Any other value without quotes | Text |
kind='tip' |
tip, named kind |
A snippet that shows body wraps writing: called on a line of its own,
it takes the lines below it, up to a line holding only @end, as
Markdown. Snippets has what a snippet takes.
Calls inside HTML
<div class="aside">@book('Post 1')</div>
Calls work inside HTML written in a page, but not inside <style>,
<script>, <pre>, <code> or an HTML comment.
Show a call as text
Type \@book('Post 1') where the book should go.
A backslash before the @ shows the call as text. In code, a call is
text already.
Writing is never read as a template: another tool’s call or mark in
braces, such as {{< figure >}}, is published as words.
Where a post’s excerpt ends
The part a list shows.
<!--more-->
The rest, shown only on the post's own page.
A list can show the start of each post, as post.excerpt in its
template: the writing before
<!--more-->, written on a line of its own between two paragraphs.
<!-- more --> is fine too. Another tool’s marker, such as
<!--break-->, is an ordinary comment.
Without the line, the excerpt is the first paragraph that holds words,
passing over a picture standing alone and the writing a call wraps. On a
page written in HTML, it is the first <p>. Footnote markers are left
out.
Quotes, dashes and ellipses
| You type | The page shows |
|---|---|
"words" |
The language’s outer quotation marks: “words” in English |
'words' |
Its inner marks: ‘words’ in English |
it's |
An apostrophe, ’, in every language |
-- |
An en dash |
--- |
An em dash |
... |
An ellipsis, … |
| Language | Its outer marks |
|---|---|
| English | “ and ” |
| German | „ and “ |
| Japanese | 「 and 」 |
| French | « and ». A language file can ask for a space inside each, and before ;, :, ! or ?. |
| One with no marks of its own | None: quotes stay straight |
Languages says how to write a
language’s marks. A double quote that closes nothing, such as the inch
mark in a 13" screen, stays straight.
Words handed to a snippet call, such as a caption, are set as the writing is. What stays as typed:
| Left as typed | Such as |
|---|---|
| Code and maths | `a--b` |
Anything inside <code>, <pre>, <kbd> or <samp> |
<kbd>--help</kbd> |
| HTML written in a page | <p class="note">"words"</p> |
| Addresses, in a link or written bare | https://example.org/a--b |
A value in a snippet call that names something: one word, an address, a path starting /, or a file’s name |
@figure("photo 1.jpg") |
| A character with a backslash before it, or written as HTML writes it | \", \-, " |
All punctuation, on a site with typography: false in statac.yaml |
Where next?
- Front matter: the title, date, tags and other fields a page can set
- Pictures: where pictures go, describing them, and a photograph’s copies
- Snippets: writing a snippet, and what a call hands it
- Addresses: where each page is published, and a site under a path
Something unclear or wrong? Open an issue on GitHub.