The journal now owns command history and tracking, so retire the md-commander widget. Its dice engine was extracted to src/components/dice in the previous commit. Removes the custom element, tracker/command stores, completions, useCommander, Emmet parser, the doc entry, test fixtures, and the known-element catalog entry (reference docs regenerated). BREAKING CHANGE: :md-commander is no longer a known element; content using it now fails tttk check with TTTK-D001.
8.4 KiB
tttk syntax reference
Generated from src/cli/validate/known.ts by npm run gen:reference.
Do not edit by hand.
Complete catalog of the custom elements, inline directives, and code block
roles that tttk understands. Everything not listed here is standard GFM
markdown. Element names are prefixed md- and must match exactly.
Contents
Directive syntax
:name[content]{key="value" .class #id}
| Part | Meaning | Example |
|---|---|---|
:name |
Registered element name | :md-dice |
[content] |
Directive body | [2d6+d8] |
{attrs} |
Attributes | {key="attack"} |
{.class} |
Shorthand for class |
{.text-red-500} |
{#id} |
Shorthand for id |
{#my-dice} |
Container directives:
::: container
Content here, including nested directives.
:dice[1d20]
:::
Nest with more colons (::::, :::::).
Custom elements
| Directive | Body | Key attributes |
|---|---|---|
:md-dice |
dice formula | key |
:md-table |
CSV path or inline id | roll, remix |
:md-deck |
CSV path | size, grid, layers |
:md-link |
path, optional #section | — |
:md-embed |
path, optional #section | headingBase |
:md-bg |
image path or CSS color | fit |
:md-border |
color or border image | width, slice |
:md-font |
font family | source, weight, color |
:md-pins |
image path | pins, fixed, labelStart |
:md-yarn-spinner |
Yarn Spinner file | start |
:md-dice
Clickable dice roller; key stores the result in the URL.
Clicking the text rolls; clicking the 🎲 resets to the formula. With key, the result is stored in the URL as ?dice-<key>=<value>.
- Body: dice formula
- Attributes:
key
:md-dice[1d20+5]{key="attack"}
:md-dice[2d6+3]
:md-dice[3d6kh1]
:md-table
Tab-separated view of a CSV with optional group tabs.
roll adds a 🎲 random-tab button; remix makes {{prop}} references pull from a random row. A group column in the CSV produces group tabs automatically.
- Body: CSV path or inline id
- Attributes:
roll,remix
:md-table[./npcs.csv]
:md-table[./encounters.csv]{roll=true}
:md-table[./quests.csv]{roll=true remix=true}
:md-deck
Card layout from a CSV (legacy; prefer yaml role=tag).
Prefer the yaml role=tag form — it is the only form that supports template layers, per-layer alignment, and card backs. The directive form is legacy and only supports the compact layers string.
- Body: CSV path
- Attributes:
size,grid,layers
:md-deck[./cards.csv]{size="63x88" grid="5x5" layers="title:1,1-5,1f8 body:1,5-5,8f3"}
:md-link
Clickable link that expands the target article inline.
- Body: path, optional #section
:md-link[./rules.md]
:md-link[./rules.md#combat]
:md-embed
Renders the target article or section inline.
headingBase shifts the heading levels of the embedded content.
- Body: path, optional #section
- Attributes:
headingBase
:md-embed[./rules.md#combat]{headingBase=1}
:md-bg
Sets the surrounding article card background.
fit is one of cover (default), contain, fill, none, scale-down.
- Body: image path or CSS color
- Attributes:
fit - Body may also be a CSS color (e.g.
#2a1a3a,crimson).
:md-bg[./images/dungeon-bg.jpg]{fit="cover"}
:md-bg[#2a1a3a]
:md-border
Applies a border to the article card.
Body is a CSS color or a border-image path. Class flags select sides (t b l r all), style (solid dashed dotted double groove ridge inset outset none), and image repeat (stretch repeat round space).
- Body: color or border image
- Attributes:
width,slice - Body may also be a CSS color (e.g.
#2a1a3a,crimson).
:md-border[crimson]{.b}
:md-border[./frame.png]{width="2mm" slice="10" .all.round}
:md-font
Sets the article font.
source is google, emfont, or local (default).
- Body: font family
- Attributes:
source,weight,color
:md-font[Noto Sans SC]{source="google" weight="700" color="#1a1a2e"}
:md-pins
Numbered markers on an image.
pins is a space-separated list of label:x,y (percent coordinates). fixed makes it read-only; otherwise click to add and click a pin to remove. labelStart sets the first label (letter or number).
- Body: image path
- Attributes:
pins,fixed,labelStart
:md-pins[./images/battle-map.png]{pins="A:25,50 B:75,30 C:50,80" fixed}
:md-pins[./images/dungeon.png]{labelStart="1"}
:md-yarn-spinner
Runs a Yarn Spinner dialogue file.
start names the entry node (default start).
- Body: Yarn Spinner file
- Attributes:
start
:md-yarn-spinner[./story.yarn]{start="start"}
Inline directives
:[name]
Inserts an icon looked up under assets/ (searching upward from the file).
Default extension is .png; .svg, .gif, .jpg, .jpeg, and .webp are also supported. label overlays text, repeat duplicates N times, and join places a tag name between repeats.
- Body: icon name
- Attributes:
label,repeat,join,class
:[attack] :[shield.svg] :[potion]
:[attack]{label=ATK repeat=3 join=br}
:cmd[command]
Renders a clickable span that dispatches a journal command.
- Body: journal command
- Attributes:
label
:cmd[roll 1d20+5]{label=Roll initiative}
:cmd[spark dungeon room-type]{label=Random room}
Code block roles
The role= attribute on the info string determines how a fenced block is
handled.
role=spark-table
CSV (or markdown pipe table) rendered as :md-table.
The first column header must be a dice formula; each row's first cell is the roll value (a number, or a range like 1-3). Extra fence attributes are forwarded to the generated :md-table, e.g. ```csv role=spark-table roll=true.
```csv role=spark-table
d6,结果
1,遭遇强盗
2,平安无事
```
```markdown role=spark-table
| d6 | 结果 |
|----|------|
| 1 | 遭遇强盗 |
| 2 | 平安无事 |
```
role=declare
Reactive variable / tag-modifier definitions.
YAML with two optional maps. vars: maps a $name to its expression. tags: maps a tag name to a map of thresholds to $target modifiers: at that tag count the target gains the value, so sibling thresholds stack. Tag names may be written with or without the leading #. YAML resolves bare numbers to numbers and everything else to strings; both become expression text.
```yaml role=declare
vars:
$hp: $con*5 + $mod_hp
$ac: 10 + $dex
tags:
warrior:
1:
$mod_hp: 20
2:
$mod_str: 1
```
role=file
Stored as inline text content and stripped.
Referenced by the derived inline id, e.g. :md-embed[./text_<hash>].
```text role=file
Stored as inline content.
```
role=tag
YAML rendered as a custom element.
tag: names the element, body: becomes its content, and any other key becomes an attribute. Fence-line attributes override the YAML body. See yaml-tag.md.
```yaml role=tag
tag: md-deck
body: ./cards.csv
size: 63x88
grid: 5x5
```
No role / unknown role
No role → a normal visible code block. Unknown role → warned about and stripped.
Dice notation
Used by :md-dice, spark-table headers, and the journal /roll:
| Notation | Meaning |
|---|---|
2d6 |
two six-sided dice |
1d20+5 |
d20 plus modifier |
3d6kh1 |
keep highest 1 |
3d6dl2-1 |
drop lowest 2, minus 1 |
{d4, d8} |
choose one of the listed dice |
CSV data files
Keep CSV files clean — a header row and data rows. Put deck configuration
and templates in a yaml role=tag block's data-config.
label— unique row id (number or text).body— main content, supports markdown.- Any other columns are custom fields.
{{prop}}inbodyinterpolates another column (or front-matter key) from the same row; with{remix}it pulls from a random row.- Wrap values containing
,,", or newlines in double quotes; escape"as"". Lines beginning with#are comments.