Keal
Back to app

Writing docs

Pages in this handbook are markdown files in api/v1/docs/. A page is a file: add one by committing a .md, remove it by deleting the file. Nothing lists them by hand, and no restart is needed — the index notices the change.

The file name is the URL: api/v1/docs/events.md is served at /docs/events.

Front matter

Optional, and only steers the index:

---
title: Events     # nav label; falls back to the first H1, then the file name
order: 20         # position in the index, gaps of 10, lower is higher up
nav: false        # reachable by URL but hidden from the index
---

What you can use

Tables, fenced code blocks, definition lists and footnotes all work. Headings get anchors automatically, and h2/h3 build the contents column on the right — which only appears once a page has enough headings to be worth it.

Callouts use the admonition syntax:

!!! warning "Optional title"
    Indented body. Also: note, tip, danger.

Which renders like this

Useful for the thing a reader will otherwise learn the hard way.

Diagrams

Fenced mermaid blocks are rendered in the browser:

```mermaid
flowchart LR
    A[Request] --> B[Keal]
    B --> C[(MySQL)]
```

The diagram source is handed to the page as JSON rather than left in the HTML, so it never flashes up as raw text before being drawn. If a diagram fails to parse, the page shows its source instead of an empty gap.

Mermaid is loaded from a CDN

cdn.jsdelivr.net, the same way the UI already loads its fonts. On an engine with no outbound access the diagrams will not render — everything else on the page still will.

The search box indexes every h2/h3 section separately, so a result links to the section that matched rather than the top of the page. Nothing needs maintaining; the index is rebuilt whenever a file changes.

A note on tone

These pages are read by someone with a problem in front of them. Say what a thing does and why it is that way — especially where the answer is surprising, or where the obvious approach was tried and abandoned. A sentence explaining a constraint saves more time than a paragraph restating what the code already says.