The format
The format
Document structure
A 3md document is UTF-8 text with three regions, in order:
- A required frontmatter block.
- An optional preamble of Markdown (any content before the first plane).
- Zero or more planes.
---
3md: 1.0
axis: time
title: My Week
---
Optional preamble Markdown.
@plane z=0 label="Monday"
# Monday
- [ ] Standup
@plane z=1 label="Tuesday"
# Tuesday
A leading UTF-8 byte order mark (BOM) is ignored, and blank lines before the
opening --- are allowed.
Frontmatter
The document MUST begin with a frontmatter block: a line containing exactly
---, one or more key: value lines, and a closing line containing exactly
---.
This is not YAML. It is a small, flat, line-based mini-format. Do not feed it to a YAML parser. The rules:
- Each line is one
key: valuepair, split on the first colon. A line with no colon is invalid frontmatter. - Keys and values are trimmed of surrounding whitespace.
- Blank lines and lines whose first non-whitespace character is
#are ignored (a#line is a comment). - A value may be wrapped in matching single or double quotes, which are then
stripped. Inside a quoted value,
\\becomes a backslash and\"becomes a double quote. Unquoted values are taken verbatim. - Duplicate keys are last-wins.
- There is no nesting, no lists, no typed scalars, and no multi-line values.
Reserved keys
These three keys are matched case-insensitively and have defined meaning:
| Key | Required | Description |
|---|---|---|
3md | Yes | The format version string. Its presence is the magic marker. The value is recorded but never validated, so older markers like 0.1 stay valid. |
axis | No | The meaning of the Z axis. Trimmed and lowercased. Any string is permitted. Defaults to layer. |
title | No | A human-readable title. |
Every other key is preserved verbatim as string metadata and never coerced to a number or boolean.
Conventional metadata keys
These are ordinary string metadata to the parser (they never affect parsing), but renderers MAY honor them:
| Key | Description |
|---|---|
view | A preferred default view a renderer opens in. Canonical values: stack, play, single, present, blend, map. Older names layers, parallax, elevator, and scene are accepted as aliases. See the viewer docs. |
legend | A per-document character map applied only inside fenced blocks, given as whitespace- or comma-separated char=replacement pairs, e.g. legend: g=🟩 w=🟦 .=·. |
billboard | When true (also yes or 1), the viewer makes glyphs face the camera in 3D object views. Used by voxel and animation examples. |
You may add any other keys you like (author, category, and so on); they are
kept as metadata.
The @plane directive
A plane begins with a directive line whose first token is @plane, followed by
space-separated key=value attributes:
@plane z=2 label="The Armory" x=1 y=-1
Rules that keep plane boundaries unambiguous:
- The directive MUST begin at column 0.
- It MUST lie outside a fenced code block. A
@planeline inside a ``` or~~~fence, or indented as code, is body text, not a new plane. - Every attribute token MUST contain an
=(split on the first=); attribute keys are lowercased. - Everything after the directive, up to the next
@planeor end of file, is the plane's Markdown body. Leading and trailing blank lines of a body are trimmed.
Plane attributes
| Attribute | Required | Description |
|---|---|---|
z | Yes | The plane's position on the Z axis. A finite decimal: optional sign, digits with optional fraction and exponent (e.g. 0, -2.5, 1e3). Hex, inf, and nan are rejected. |
x, y | No | Finite decimal in-plane offsets (same grammar as z) for spatial viewers. |
label | No | A human-readable name for the plane. |
Any other attribute is preserved as a string on the plane. Quote a value if it
contains spaces; inside a quoted value, \\ and \" are escape sequences, and
an unterminated quote is an error.
Two planes MUST NOT share the same z. Source order is preserved, though
viewers may reorder by z.
Single-plane shorthand
If a document has frontmatter but no @plane directives, the entire body is one
implicit plane at z = 0.
Fenced-grid bodies
A plane body is plain CommonMark, so a fenced code block renders exactly as
written. This is how grids, ASCII frames, and voxel slices are authored. With a
legend: key, single source characters inside fences are substituted on render:
---
3md: 1.0
axis: frame
legend: x=⬛ S=🟫 C=🌽 .=🟩
---
@plane z=0 label="Spring"
x x x x x x S C C x x . . . x
Without a legend, renderers MUST NOT substitute characters on their own.
Cross-plane links
A plane body may reference another plane by its z position with a
double-bracket link:
See [[z=2]] for the details, or jump [[z=0|back to the start]].
The grammar is [[z= followed by a finite decimal, an optional | and link
text, then ]]. If the captured target is not a finite decimal, the sequence is
not a link and stays literal text.
Links live inside the Markdown body verbatim; implementations expose them through
a separate extraction step that reports the source z, target z, optional
text, and whether a plane with that target exists. This makes link validation
portable: the CLI links and check-links commands use it to find
dangling references.
Errors
A conforming parser rejects:
| Error | Cause |
|---|---|
missingFrontmatter | No frontmatter block. |
invalidFrontmatter | A frontmatter block that is never closed. |
missingVersion | No 3md version key. |
missingPlanePosition | A @plane directive with no z. |
invalidPlaneDirective | A non-finite z/x/y, an attribute token with no =, or an unterminated quote. |
duplicatePlane | Two planes with the same z. |
For the full grammar and conformance rules, see the spec.