# Notation

> How syntax diagrams and validation cases are written on this site.

## Syntax diagrams

Each sequence page opens with the sequence laid out byte by byte. The name of
each piece is on top and the byte it stands for is underneath, in hexadecimal.

- `ESC` is the byte `1B`.
- `CSI` is the Control Sequence Introducer, `ESC [`. ECMA-48 also defines a
  single-byte CSI, `9B`, but terminals that decode their input as UTF-8 do not
  accept it, so it is not shown.
- `OSC` is the Operating System Command introducer, `ESC ]`.
- `ST` is the String Terminator, `ESC \`. Most terminals also accept `BEL`
  (`07`) in its place.
- A dashed box is a parameter. `Pn` is a number, `Ps` is a number that
  selects one of a fixed set of behaviors, and `Pt` is text. A parameter left
  out takes its default, and several parameters are separated by `;`.

## Validation cases

A case is two blocks: the input, and the screen it should produce. A fresh
terminal is made for every case, exactly as wide and as tall as the expected
screen, and the input is written to it.

### Input

One line of input is one *step*: the stepping controls under each case
advance a line at a time. Leading and trailing spaces on a line are ignored,
and anything after a `#` that follows a space is a comment, which is shown
beside the step.

| Escape | Byte |
| --- | --- |
| `\e` | `1B`, ESC |
| `\a` `\b` `\t` `\n` `\v` `\f` `\r` | `07` `08` `09` `0A` `0B` `0C` `0D` |
| `\s` | `20`, a space |
| `\xNN` | the byte `NN` in hexadecimal |
| `\NNN` | the byte `NNN` in octal, so `\033` is ESC |
| `\u{NNNN}` | the code point `U+NNNN`, encoded as UTF-8 |
| `\\` `\#` | a backslash, a `#` |

Everything else is written as UTF-8. Note that `\n` is only a line feed: it
moves the cursor down without returning it to the left margin, because that is
what the byte does.

### Expected screen

Each row of the screen is written between bars, `|like this|`, with `_` for
an empty cell. The number of rows and the width of the first row set the size
of the terminal. After the rows can come any of these:

| Line | Checks |
| --- | --- |
| `cursor R,C` | the cursor is at row `R`, column `C`, counting from 1 |
| `pending-wrap yes` | the cursor is in the last column with a wrap pending (or `no`) |
| `cursor-visible no` | the cursor is hidden (or `yes`, shown) |
| `title "text"` | the window title, as a JSON string |
| `progress text` | the progress reports sent with [OSC 9 ; 4](https://control-codes.page/osc/conemu/index.html.md), in order and separated by commas, such as `set 50, remove`; `progress none` for none |
| `pointer name` | the mouse pointer's shape, set with [OSC 22](https://control-codes.page/osc/pointer/index.html.md), by its CSS name, such as `text` or `wait` |
| `pwd "text"` | the working directory last reported with [OSC 7](https://control-codes.page/osc/cwd/index.html.md), as a JSON string; `""` for none |
| `attr R,C words…` | the style of the cell at row `R`, column `C` |
| `reply text` | everything the terminal sent back to the host, in the input's escape notation, or `reply none` for nothing |
| `bell N` | how many times the bell rang |

The words an `attr` line takes are `bold`, `italic`, `faint`, `blink`,
`inverse`, `invisible`, `strikethrough`, `overline` and `underline` (or
`underline=double`, `curly`, `dotted`, `dashed`), each of which can be negated
with a leading `-`; `fg=N` and `bg=N` for a palette color, `fg=#rrggbb` for a
direct color and `fg=default`; `link` for a cell that is part of an
[OSC 8](https://control-codes.page/osc/hyperlink/index.html.md) hyperlink; `semantic=prompt`, `semantic=input` or
`semantic=output` for what [OSC 133](https://control-codes.page/osc/prompt/index.html.md) marked the cell as; and
`plain` for a cell with no styling at all.

### Replies

Some sequences make the terminal answer the host: a status report, its
cursor position, what kind of terminal it is. The runner collects those
answers, in order, from libghostty-vt's callbacks, and a `reply` line checks
all of them together. On a page, a case that checks a reply or the bell
shows what was sent back as you step through it.

Some answers are the host's to choose rather than libghostty-vt's. For
those the runner gives the answers Ghostty itself gives: Device Attributes
reports a VT220 with ANSI color, `\e[?62;22c` for the primary attributes and
`\e[>1;10;0c` for the secondary, and the answerback message ENQ asks for is
empty, as Ghostty's `enquiry-response` is by default. A size report,
[`CSI 18 t`](https://control-codes.page/csi/xtwinops/index.html.md), gives the case's own size, as a default xterm
would; the size of a cell in pixels is an arbitrary 6 by 13.

Colors are the host's choice too, and for those the runner follows a default
xterm, since the cases do: the terminal starts with xterm's palette and its
black text on white, with the cursor in the foreground color. That is what a
color query such as [`OSC 4`](https://control-codes.page/osc/palette/index.html.md) or [`OSC 11`](https://control-codes.page/osc/dynamic/index.html.md)
answers, and what `fg=N` resolves to. The screens on this site are still
drawn in the page's own colors wherever a cell has the default ones.

### Known differences

A case that libghostty-vt is known not to pass is marked as a *known
difference*. A case's expectation follows what a default xterm does, bugs
included, even where DEC STD 070 or ECMA-48 says otherwise. That includes
ignoring a function a default xterm ignores, so a function libghostty-vt
implements and xterm does not is a known difference too; the
[sources](https://control-codes.page/sources/index.html.md) page says more. A known
difference is still run on every page load, and its badge says whether the
difference is still there; the page's prose explains it.

---

This is the Markdown version of <https://control-codes.page/notation/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.
