The Sourcebook dialect
Status: normative. This page is the authoring guide AND the contract the parser is tested against. If the two disagree, this page is right and the parser is wrong.
It is also the engine describing itself — this page lives in a git repository and is pulled in by the engine it documents.
The one rule
A Sourcebook file is a valid Markdown file first. Everything below is either plain CommonMark, or a fenced block whose info string we understand. Open any file in MkDocs Material or Docusaurus and it builds; the reader may lose a player or a live table, never the content.
That rule has a consequence worth stating plainly: we never write raw HTML
with class=. MDX (Docusaurus) requires className, so an HTML block
styled for MkDocs breaks a Docusaurus build. Fenced blocks are the only
extension mechanism, because an engine that does not know ```video shows
its body as a code block and builds fine.
Front matter
---
title: Setting up the i550 inverter # page title; falls back to the first H1
slug: i550-setup # address segment; falls back to the file name
sidebar_position: 3 # order among siblings (Docusaurus spelling)
sidebar_label: i550 # short label for the menu
description: Wiring, parameters, first run.
tags: [inverters, commissioning] # becomes TERMS, see Taxonomy
draft: true # not published; still fetched
---
Every key above is a key MkDocs Material or Docusaurus already uses. We add none of our own. An unknown key is kept and reported, never dropped.
Admonitions — both spellings
Write whichever your team prefers; both render identically here.
!!! warning "Disconnect the mains"
The DC link stays charged for five minutes.
:::warning[Disconnect the mains]
The DC link stays charged for five minutes.
:::
Types: note, tip, info, warning, danger, example, quote.
Video with an outline
The block a machine manual is written around. Everything inside is DATA — it becomes fields on the page, so Views and search can process it.
```video
src: https://www.youtube.com/watch?v=XXXXXXXXXXX
title: Commissioning the i550
outline:
- at: 0:00
text: What you need before starting
- at: 1:24
text: Wiring the mains and the motor
- at: 4:12
text: Setting the ramp time
- at: 7:45
text: First run and what to watch
```
srcmay be a YouTube URL or a path to a video committed to the repository (../assets/i550.mp4).atacceptsM:SS,MM:SSorHH:MM:SS. Write it unquoted; YAML reads1:24as a sexagesimal number and the parser expects that.- Clicking an outline entry seeks the player to that second.
- If the video is on a connected YouTube channel, its transcript is fetched and becomes searchable and seekable. The transcript never overwrites the outline — the outline is what a human wrote, the transcript is what a machine heard, and they are separate layers.
- In MkDocs or Docusaurus the block shows as a readable list of times and descriptions. The content survives; only the player is ours.
Tables
Three kinds, because "a table" means three different things.
Small tables — ordinary GFM. Use these for anything a person typed.
| Parameter | Default | Range |
|-----------|---------|-----------|
| P100 | 5.0 s | 0.1–3600 |
Large data — a table nobody wants in the body:
```table
src: data/parameters.csv
caption: All i550 parameters
searchable: true
```
The CSV lives in the repository next to the page, so it is reviewable in a pull request like anything else.
Live data — what the platform itself holds:
```view
name: error_codes
argument: term # the page's own term; or a literal value
```
This renders a real listing through the existing embed door, with its existing guarantees. If the listing does not exist or refuses to be embedded, the page renders without it and the sync says so.
Layout
Presentation, and therefore the one thing that legitimately stays as markup in the body.
```layout
gap: large
columns:
- |
Left column, ordinary Markdown with **emphasis** and lists.
- |
Right column.
```
Every block keeps its content inside its own fence. An earlier draft let the layout's content follow the fence — it degrades more prettily, and there is no honest way to say where the layout stops. One shape for all five blocks means an unambiguous end and a degradation that still shows the content in order.
```cards
- title: Wiring
href: ./wiring.md
icon: plug
text: Mains, motor and braking resistor.
- title: Parameters
href: ./parameters.md
icon: sliders
text: Every parameter with its default.
```
Taxonomy
tags: in front matter become terms, not text.
- A vocabulary or term that does not exist is created, in your organisation, and the sync tells you it did.
inverters,InvertersandINVERTERSare ONE term. Case, diacritics and surrounding space do not create duplicates.tags: [products/inverters/i550]creates the whole branch in order.- A term whose last use disappears is reported as unused, never deleted — deleting it would silently break every other link to it.
- Every vocabulary a documentation set creates carries that set's GROUP, so an administrator sees which taxonomy belongs to which documentation without opening either.
Links and images
Write them relatively, the way both other engines expect:
See [wiring](./wiring.md) and the [glossary](../reference/glossary.md).

Links to .md files are rewritten to the page's address here and left alone
for the other engines. Images are fetched into the file store, in a folder
tree mirroring the repository, and identical bytes are stored once.
Versions
A version is a tag on main — a photograph of the documentation on the
day it shipped:
git tag docs/3.4 && git push origin docs/3.4
Tags matching docs/* become released versions. main itself is always the
current version. This keeps one rule intact: nothing is ever published
from a branch that was not merged. A version is not somewhere else — it is
this documentation, earlier.
If your repository is already laid out the Docusaurus way, that works too:
docs/ → current
versioned_docs/version-3.4/ → released 3.4
versioned_sidebars/
Both live on main, so both are legitimate.
Until you tag or create a versioned directory, nothing changes: no chooser appears, and you write exactly as you do now. Versioning costs nothing until you use it.
Readers stay inside the version they chose. A page that does not exist in their version says so and offers the current one — it is never shown to them as though it were theirs.
Languages
Write translations either way; both are accepted, because both are what the other engines expect:
docs/i550.md docs/en/i550.md i18n/en/…/i550.md
docs/i550.sk.md docs/sk/i550.md i18n/sk/…/i550.md
A translation is the same page in another language, not a second page. It shares the original's tags, its version, its weight and its place in the tree, and it joins the platform's existing language machinery — so everything that already works in eleven languages works here without a special case.
What a translation may say differently
The title, the body and the video outline. Everything else — the tags, the sidebar order, the version, the address — belongs to the page, and every language of it shares one answer. Letting a translation set its own tags would let two languages of one page drift into different categories, and the drift would be invisible until somebody browsed in the other language.
A language directory is only a language directory if the platform actually
has that language installed. docs/cs/index.md is Czech; docs/api/index.md
is a directory called api. Nothing in the path can tell them apart, so the
installed languages decide — guessing would file an API reference as a
translation.
A page you have not translated yet is shown to that reader in the original language, with a note saying so. Silence would be worse: an untranslated page that does not admit it is indistinguishable from a bad translation.
Version and language are independent. Any version may exist in any language; a missing combination falls back by language first, then by version.
What is fetched, and from where
Only main. Only main is fetched, and only main is published. There
is no staging branch that quietly appears on the site, because a reader
seeing an unmerged branch is the one failure a documentation system cannot
explain away.
A change made in the browser becomes a branch and a pull request. It is
reviewed on GitHub like any other change and appears on the site when it is
merged. The platform cannot write to main, by design.
What you edit there is the Markdown, not the rendered page — each page
keeps its source file byte for byte, so a commit is exactly what you typed,
blocks included. If main moved since the page was imported, the change is
refused and reported rather than forced over somebody else's work.