feat(cli): Complete the check rule catalog
Add D002 (malformed attribute blocks), R004 (skipped declare rows), and V001-V005 (CSV data files). CSV checks run once per referenced file and also cover inline spark-table bodies. Generate docs/reference.md from the known.ts catalog via npm run gen:reference, and add drift guards asserting the catalog matches the customElement call sites and the committed reference.
This commit is contained in:
@@ -0,0 +1,286 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user