# tttk syntax reference Generated from `src/cli/validate/known.ts` by `npm run gen:reference`. Do not edit by hand. Everything not listed here is standard GFM markdown. Element names are prefixed `md-` and must match exactly. ## Directive syntax ```text :name[content]{key="value" .class #id} ``` - `[content]` is the directive body — a path, dice formula, color, etc. - `{key="value"}` sets attributes; `{.class}` and `{#id}` are shorthands. - Container directives use `::: name` … `:::`; nest with `::::`, `:::::`. ## 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-commander` | command template CSV | `placeholder`, `class`, `height` | | `:md-yarn-spinner` | Yarn Spinner file | `start` | ### `:md-dice` Clickable dice roller; `key` stores the result in the URL. - Body: dice formula - Attributes: `key` ```markdown :md-dice[1d20+5]{key="attack"} ``` ```markdown :md-dice[2d6+3] ``` ```markdown :md-dice[3d6kh1] ``` ### `:md-table` Tab-separated view of a CSV with optional group tabs. - Body: CSV path or inline id - Attributes: `roll`, `remix` ```markdown :md-table[./npcs.csv] ``` ```markdown :md-table[./encounters.csv]{roll=true} ``` ```markdown :md-table[./quests.csv]{roll=true remix=true} ``` ### `:md-deck` Card layout from a CSV (legacy; prefer `yaml role=tag`). - Body: CSV path - Attributes: `size`, `grid`, `layers` ```markdown :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 ```markdown :md-link[./rules.md] ``` ```markdown :md-link[./rules.md#combat] ``` ### `:md-embed` Renders the target article or section inline. - Body: path, optional #section - Attributes: `headingBase` ```markdown :md-embed[./rules.md#combat]{headingBase=1} ``` ### `:md-bg` Sets the surrounding article card background. - Body: image path or CSS color - Attributes: `fit` - Body may also be a CSS color (e.g. `#2a1a3a`, `crimson`). ```markdown :md-bg[./images/dungeon-bg.jpg]{fit="cover"} ``` ```markdown :md-bg[#2a1a3a] ``` ### `:md-border` Applies a border to the article card. - Body: color or border image - Attributes: `width`, `slice` - Body may also be a CSS color (e.g. `#2a1a3a`, `crimson`). ```markdown :md-border[crimson]{.b} ``` ```markdown :md-border[./frame.png]{width="2mm" slice="10" .all.round} ``` ### `:md-font` Sets the article font. - Body: font family - Attributes: `source`, `weight`, `color` ```markdown :md-font[Noto Sans SC]{source="google" weight="700" color="#1a1a2e"} ``` ### `:md-pins` Numbered markers on an image. - Body: image path - Attributes: `pins`, `fixed`, `labelStart` ```markdown :md-pins[./images/battle-map.png]{pins="A:25,50 B:75,30 C:50,80" fixed} ``` ```markdown :md-pins[./images/dungeon.png]{labelStart="1"} ``` ### `:md-commander` Interactive command history / tracker panel. - Body: command template CSV - Attributes: `placeholder`, `class`, `height` ```markdown :md-commander[./commands.csv]{placeholder="输入命令…" height="400px"} ``` ### `:md-yarn-spinner` Runs a Yarn Spinner dialogue file. - Body: Yarn Spinner file - Attributes: `start` ```markdown :md-yarn-spinner[./story.yarn]{start="start"} ``` ## Inline directives ### Icons — `:[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. ```markdown :[attack] :[shield.svg] :[potion] ``` ### Command links — `:cmd[command]{label=...}` Renders a clickable span that dispatches a journal command. ```markdown :cmd[roll 1d20+5]{label=Roll initiative} ``` ## 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`. ````markdown ```csv role=spark-table d6,结果 1,遭遇强盗 2,平安无事 ``` ```` ````markdown ```markdown role=spark-table | d6 | 结果 | |----|------| | 1 | 遭遇强盗 | | 2 | 平安无事 | ``` ```` ### `role=declare` Reactive variable / tag-modifier definitions. ````markdown ```csv role=declare tag,threshold,key,expr ,,$hp,$con*5+$mod_hp #warrior,2,$mod_hp,20 ``` ```` ### `role=file` Stored as inline text content and stripped. ````markdown ```text role=file Stored as inline content. ``` ```` ### `role=tag` YAML rendered as a custom element. ````markdown ```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. ## 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}}` in `body` interpolates 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.