Skip to content

Quillmark Format

Quillmark is the document format TongueToQuill uses. It is CommonMark plus a structured metadata system — readable as plain text, parseable as structured data, and trivially editable by humans, LLMs, and tooling.

This page is the reference for the format itself. For producing actual documents, start at Anatomy of a Memorandum or Document Types.

Document structure

A document is a sequence of blocks. Each block has:

  • A card-yaml header — structured frontmatter.
  • A prose body — the markdown content beneath the header, up to the next card-yaml header or end of file.

Minimal document:

~~~card-yaml
$quill: usaf_memo
memo_for:
  - 20 FW/CC
subject: Example
signature_block:
  - JOHN A. SMITH, Lt Col, USAF
~~~

The body goes here. The renderer auto-numbers top-level paragraphs.

card-yaml blocks

A card-yaml block opens with ~~~card-yaml and closes with ~~~, both at column zero. The opener is exactly three tildes plus card-yaml~~~yaml and ```card-yaml do not open a card-yaml block. The content between the fences is YAML.

~~~card-yaml
key: value
list:
  - one
  - two
~~~

Blank line above the opener

A blank line is required immediately above every ~~~card-yaml opener, unless the opener is line 1. Without the blank line, the parser treats the fence as an ordinary code block — the document looks superficially valid but silently loses its structure. This is the most common authoring mistake.

Reserved $ keys

The engine accepts a closed set of $-prefixed keys. Anything else with a leading $ is a parse error.

Key Where it appears Purpose
$quill Root block only (required) Binds the document to a Quill and version.
$kind Any block Identifies the block type. The root block's kind is main (implicit by position; explicit $kind: main is also accepted, but non-root cards must not use main). Indorsement cards use $kind: indorsement.

$id and $ext are also accepted but exist for tooling round-trips, not for authors. Don't write them in documents you author by hand — leave them to the editor and the engine.

All other keys are user data. Their interpretation depends on the Quill's schema.

Version selectors

The $quill value is <name>@<version>:

Form Meaning
usaf_memo@0.2.0 Exact version
usaf_memo@0.2 Latest 0.2.x
usaf_memo@0 Latest 0.x.x
usaf_memo Latest overall

Pin to a minor or exact version when you need bit-stable output (e.g., for archival). Use the unversioned form for "always use the current format."

Cards

A document can contain multiple cards. Each card is a separate ~~~card-yaml block plus its prose body. The root card defines $quill; later cards inherit it.

Cards are the mechanism for indorsements, attachments-as-sections, and any multi-part document structure the Quill supports.

~~~card-yaml
$quill: usaf_memo
subject: Pass Request
~~~

Main body.

~~~card-yaml
$kind: indorsement
format: informal
signature_block:
  - ~~~

Indorsement body.

The card sequence is significant — the renderer stacks cards in the order they appear in the source.

Supported markdown

CommonMark 0.31.2 plus three additions:

  • GFM strikethrough (~~text~~)
  • GFM pipe tables, including alignment (:---, :---:, ---:)
  • <u>text</u> for underline (the only allowed HTML tag besides comments)
Feature Syntax
Bold **text**
Italic *text*
Underline <u>text</u>
Strikethrough ~~text~~
Headings # Heading (ATX-style only)
Ordered list 1. item
Unordered list - item
Pipe tables with alignment \| col \|, \| :--- \|, \| :---: \|, \| ---: \|
Links [text](url)
Inline code `code`
Code blocks ```
HTML comments <!-- comment -->

Not rendered: images, footnotes, math ($...$, $$...$$), task lists, definition lists, raw HTML other than <u>. These parse without error but produce no output, so don't rely on them.

How memo body content is numbered

The usaf_memo Quill auto-numbers top-level paragraphs as 1., 2., 3. per AFH 33-337. Do not write the numbers yourself. Nested - item bullets are auto-lettered as a., b., c.; deeper nesting continues to (1), (a), then underlined number. Each Quill controls its own numbering scheme — check the Quill blueprint (via get_specs) for non-memo formats.

Validation

The Quillmark engine validates frontmatter against the Quill's schema before composing the output:

  • Missing required fields → render error with a path into the frontmatter.
  • Wrong type (string where a list is expected, etc.) → render error with the path.
  • Unknown keys → typically a warning, not an error. Unknown keys are ignored.

The render either succeeds (you get a valid PDF) or fails with a diagnostic. There is no path where invalid input silently produces a malformed document.

For the deeper format spec and engine internals, see quillmark.readthedocs.io.