Guide

Authoring for Halmos

Every convention the renderer honours — and the ones that silently do nothing. Written to be pasted into an assistant as instructions.

docs/authoring.md in the Halmos Editor repository

Writing documents for Halmos

Halmos reads ordinary Markdown. It has no format of its own — citations follow Pandoc, maths follows KaTeX, charts are Vega-Lite and diagrams are Mermaid, so a document written for Halmos stays readable in other tools.

What follows is the part that is not guessable: which conventions Halmos acts on, and the handful of things that silently do nothing.

This file is written to be pasted whole into an AI assistant as instructions for producing a Halmos document.


Frontmatter: exactly four keys

---
bibliography: references.bib
csl: apa
toc: true
toc-depth: 3
---

bibliography, csl, toc and toc-depth are the only keys Halmos reads. All are optional. The bibliography path is resolved relative to the document, so the .bib normally sits beside it; toc and toc-depth are described under A table of contents below.

csl is one of five bundled styles — apa, chicago-author-date, ieee, vancouver, harvard — or the path to a .csl file, relative to the document or absolute. A name Halmos does not know, or a file it cannot load, falls back to APA with a warning. You do not have to type this line: use Format → Citation Style (see Citations).

The whole frontmatter block is removed before rendering. A title: or author: there will not appear anywhere. Put the title in the document:

# Entanglement-verified time distribution

Craig Richards

Citations

Cite by the BibTeX key. Bracketed citations are parenthetical:

Photon pairs decohere over distance [@alqedra2026].
Two sources agree [@alqedra2026; @bennett2019].
As shown elsewhere [see @alqedra2026, p. 31].
Only the year is needed [-@alqedra2026].
  • Separate multiple keys with ;
  • Text before the @ becomes a prefix (see, cf.)
  • A trailing , p. 31, , pp. 31-34, , chapter 3 or , sec. 2 is parsed as a locator; other trailing text becomes a suffix
  • A - immediately before the @ suppresses the author

A bare @key outside brackets is a narrative citation, for naming the author in your own sentence:

@alqedra2026 measured a fidelity of 0.817.

The bibliography is generated automatically at the end of the document under a "References" heading. Do not write one by hand.

Autocomplete

With a bibliography: set, typing [@, ; @, -@ or a bare @ opens a list of entries from the .bib: key, author and year, and title. Keep typing to narrow it; Return inserts the key. The list shows up to 100 entries at a time. There is no list when the document names no bibliography, and none inside code, maths or frontmatter.

Hover and unknown citations

Hover over a citation key in the editor to see the formatted reference in the document's style. If the key is not in the .bib, the hover says Not in <bib name>.

Keys that are not in the .bib get a red wavy underline. The status bar shows "N unknown citations"; click it to see the list with line numbers, and click a line to jump to it. Check this before you submit.

Choosing a style

Format → Citation Style lists APA, Chicago (author-date), Harvard, IEEE and Vancouver. The current one is ticked. Choosing one rewrites the csl: line in the frontmatter.

Other Style File… opens a .csl file from disk. If the file is inside the document's folder, csl: holds a path relative to the document; otherwise it holds the absolute path. A document that has not been saved yet has no folder, so save it first. Halmos does not watch the style file: after editing it, reopen the document or choose the style again.

Footnotes

The result held in every run.[^1] Some runs were repeated.^[Three times each.]

[^1]: Run 4 was discarded after a laser fault [@alqedra2026].
  • [^1] marks the spot; [^1]: text defines the note. The definition can sit anywhere in the document.
  • ^[text] is an inline note with no separate definition.
  • Notes are numbered in the order they are cited and listed after the References.
  • Citations inside a footnote are formatted like any other.

Maths

KaTeX, inline with $…$ and displayed with $$…$$:

The fidelity $F = \langle\Phi^+|\rho|\Phi^+\rangle$ exceeded the classical bound.

$$
C(\rho) = \max(0, \lambda_1 - \lambda_2 - \lambda_3 - \lambda_4)
$$

A malformed expression renders in red rather than breaking the document. $5 and other prices are left alone.

Figures: a caption is what makes a figure

A block with a caption becomes a numbered <figure>. A block without one renders plainly. Charts, images and diagrams share one numbering sequence, in document order.

Captions are never written as a separate paragraph. Each format carries its own, which is what keeps them through a Pandoc conversion:

Block Where the caption comes from
Image the alt text — ![Recovered sources](fig1.png)
Vega-Lite chart the spec's title
Mermaid diagram a title: in the diagram's own frontmatter

An image with empty alt text (![](divider.png)) stays decorative and is not numbered — use that for rules and spacers.

Image paths resolve relative to the document, the same way bibliography: does, so a figure stored beside the file is just its filename. ../shared/ and absolute paths work too. A remote URL works as well.

![Recovered sources](fig1.png)
![Recovered sources](figures/fig1.png)
![Recovered sources](https://example.org/fig1.png)

A document that has never been saved has no folder to resolve against, so save it before referring to a local image.

Do not also write "Figure 1 — …" in prose; Halmos numbers and renders the caption itself, and the number would be wrong as soon as a figure is inserted above it.

Only top-level blocks are numbered. A chart or diagram inside a list item or a blockquote still renders, but takes no figure number.

Tables

GFM pipe tables render as tables. Insert → Table… opens a grid: type into the cells, add or remove rows and columns, set a column's alignment, or paste comma- or tab-separated text under Import. Insert writes a padded table at the cursor; with the cursor inside an existing table the same command opens it for editing and Update replaces it. Cells hold ordinary markdown, so **bold**, links and [@citations] work inside them.

Sample n Mean
Control 12 4.1
Treated 11 6.3

A table of contents

Set toc: true in the frontmatter and the document gets a contents page: every heading is a link that works in the preview and in the exported PDF. By default the contents sit at the top and list headings down to level three; toc-depth: 2 (1–6) changes the cut-off.

To put a title page or an introduction before the contents, write a paragraph containing exactly [[toc]] where the contents belong. Only headings after that point are listed — a title above it stays out of its own contents page — though every heading still gets an anchor, so [see the appendix](#appendix) works anywhere in the document.

Charts

A vega-lite fenced block holding a Vega-Lite JSON spec. Inline the data so the document stays self-contained:

```vega-lite
{
  "title": "Recovered sources by condition",
  "data": {"values": [
    {"dose": 0, "response": 1.5},
    {"dose": 5, "response": 3.25}
  ]},
  "mark": "line",
  "encoding": {
    "x": {"field": "dose", "type": "quantitative"},
    "y": {"field": "response", "type": "quantitative"}
  }
}
```

The title becomes the figure caption and is not drawn inside the chart.

Width and figure alignment are application settings, not document ones — do not set width unless a particular chart genuinely needs to override the document default.

A chart stays editable in the graphical builder only if it uses a single mark with x, y and optional color encodings. layer, transform and facet render fine but cannot be reopened there.

Diagrams

A mermaid fenced block. Any diagram type Mermaid supports works — flowchart, sequence, state, class, ER, gantt, pie.

```mermaid
---
title: Pipeline stages
---
flowchart LR
  A[Ingest] --> B[Parse]
  B --> C[Render]
```

The title: in the diagram's frontmatter becomes the figure caption. Omit it for an unnumbered diagram.

Code

Fenced blocks are syntax highlighted in both panes. The language tag must be one the highlighter recognises, or the block renders plain — python, r, julia, fortran, c++, javascript, go, rust, shell, sql, json, yaml and latex are all safe.

```python
def concurrence(rho):
    return max(0, eigenvalues(rho)[0] - sum(eigenvalues(rho)[1:]))
```

What does not work

  • Raw HTML. It is escaped and appears as literal text. No <br>, no <div align="center">, no <sub>. Use Markdown, or maths for subscripts.
  • A hand-written References section. It is generated.
  • title: or author: in frontmatter. Silently dropped.
  • Figure numbers written by hand. They are generated.

A complete example

---
bibliography: references.bib
csl: apa
---

# Entanglement-verified time distribution

## Introduction

Distributing entangled photon pairs across a metropolitan fibre network
synchronises distant clocks to tens of picoseconds [@alqedra2026].
@bennett2019 first proposed the approach.

The concurrence is bounded below by

$$
C(\rho) = \max(0, \lambda_1 - \lambda_2 - \lambda_3 - \lambda_4)
$$

## Method

```mermaid
---
title: Synchronisation pipeline
---
flowchart LR
  A[Source] --> B[Fibre]
  B --> C[Detector]
```

## Results

```vega-lite
{
  "title": "Fidelity against fibre length",
  "data": {"values": [
    {"km": 0, "fidelity": 0.94},
    {"km": 10, "fidelity": 0.86},
    {"km": 20, "fidelity": 0.82}
  ]},
  "mark": "line",
  "encoding": {
    "x": {"field": "km", "type": "quantitative"},
    "y": {"field": "fidelity", "type": "quantitative"}
  }
}
```

Fidelity fell with distance, remaining above the classical bound throughout.

That document produces two numbered figures — "Figure 1 — Synchronisation pipeline" and "Figure 2 — Fidelity against fibre length" — two resolved citations, a display equation, and a generated reference list.