ttrpg-tools/docs/markdown.md

568 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Markdown 编写说明
本文档介绍 TTRPG Tools 支持的 Markdown 扩展语法和组件用法。
## 基础语法
使用标准 Markdown 语法,支持以下扩展:
- [GFM](https://github.github.com/gfm/) - GitHub Flavored Markdown
- [marked-alert](https://github.com/Insidify/marked-alert) - 警告/提示块
- [marked-gfm-heading-id](https://github.com/markedjs/marked-gfm-heading-id) - 标题 ID
- [marked-directive](https://github.com/fengzilong/marked-directive) - 指令语法
## 指令语法
通过 `marked-directive` 支持自定义组件插入:
```markdown
:component-name[content]{key="value" another="test"}
```
### 语法说明
| 部分 | 说明 | 示例 |
|------|------|------|
| `:name` | 组件名称 | `:dice` |
| `[content]` | 内容参数 | `[2d6+d8]` |
| `{attrs}` | 属性对象 | `{key="attack"}` |
支持多个嵌套指令:
```markdown
::: container
这里是容器内容
:dice[1d20]
:::
```
## 分栏布局
使用简单的分隔符语法创建多栏布局:
```markdown
|---
左侧栏内容
-|-
右侧栏内容
---
```
**语法说明:**
| 分隔符 | 说明 |
|--------|------|
| `\|---` | 开始分栏容器 |
| `-|-` | 分隔各栏 |
| `---` | 结束分栏容器 |
**多栏示例:**
```markdown
|---
第一栏
-|-
第二栏
-|--
第三栏(更宽)
---
```
`-|--` 中的额外 `-` 会添加 `-N` 后缀到 CSS 类名(如 `col-2`),可用于自定义宽度。
## 图标语法
使用简单的 `:[icon-name]` 语法插入图标:
```markdown
:[attack] :[defense] :[potion] :[sword]
```
图标会渲染为 `<icon class="icon-attack"></icon>` 形式。
### 支持多种图片格式
默认情况下,`:[icon-name]` 会查找 `.png` 文件。你也可以显式指定其他支持的格式:
```markdown
:[attack] <!-- 查找 attack.png -->
:[attack.svg] <!-- 查找 attack.svg -->
:[shield.gif] <!-- 查找 shield.gif -->
:[photo.jpg] <!-- 查找 photo.jpg -->
:[icon.webp] <!-- 查找 icon.webp -->
```
**支持的扩展名:** `.svg`、`.png`、`.gif`、`.jpg`、`.jpeg`、`.webp`
**注意:** CSS class 名称始终使用不带扩展名的图标名称(如 `icon-attack`),方便统一样式控制。
### 配置图标前缀
可通过 `iconPath` 属性指定图标目录:
```markdown
<Article src="/content/page.md" iconPath="./assets/icons" />
```
或使用空字符串禁用图标前缀:
```markdown
<Article src="/content/page.md" iconPath="" />
```
## 组件库
### 🎲 骰子组件 (md-dice)
```markdown
:md-dice[2d6+d8]
:md-dice[1d20+5]{key="attack"}
```
**功能:**
- 点击文本执行掷骰
- 点击骰子图标重置为公式
- `key` 属性将结果记录到 URL 参数中 (`?dice-attack=15`)
**属性:**
| 属性 | 类型 | 说明 |
|------|------|------|
| `key` | string | 用于 URL 参数记录的标识 |
**示例:**
```markdown
攻击检定 :md-dice[1d20+5]{key="attack"}
伤害掷骰 :md-dice[2d6+3]{key="damage"}
```
### 🔗 链接组件 (md-link)
```markdown
:md-link[./other-page.md]
:md-link[./rules.md#combat-section]
```
**功能:**
- 点击链接在当前页面内展开显示目标文章内容
- 支持 `#section` 语法显示特定章节
- 支持相对路径引用
**属性:**
| 属性 | 类型 | 说明 |
|------|------|------|
| (无) | - | 内容即为链接目标路径 |
**示例:**
```markdown
查看完整规则 :md-link[./rules.md]
查看战斗章节 :md-link[./rules.md#combat]
```
### 🖼️ 背景组件 (md-bg)
```markdown
:md-bg[./images/background.jpg]
:md-bg[./images/pattern.png]{fit="contain"}
```
**功能:**
- 将图片设置为当前文章卡片的背景
- 自动覆盖整个卡片区域
**属性:**
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `fit` | `cover` \| `contain` \| `fill` \| `none` \| `scale-down` | `cover` | 背景适配方式 |
**示例:**
```markdown
:md-bg[./images/dungeon-bg.jpg]{fit="cover"}
# 地牢探险
这里是地牢的描述内容...
```
### 📍 标记组件 (md-pins)
```markdown
:md-pins[./images/map.png]{pins="A:30,40 B:10,30" fixed}
:md-pins[./images/city-map.png]
:md-pins[./images/dungeon.png]{labelStart="1"}
:md-pins[./images/quest.png]{labelStart="C"}
```
**功能:**
- 在图片上显示标记点A-Z, AA-ZZ, AAA-ZZZ... 或数字)
- `fixed` 模式:仅显示标记,不可编辑
- 非 fixed 模式:点击图片添加标记,点击标记删除
- 提供复制按钮生成标记代码
- 支持自定义标签起始值(字母或数字)
**属性:**
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `pins` | string | `""` | 标记列表,格式 `"A:30,40 B:10,30"` (标签x,y) |
| `fixed` | boolean | `false` | 是否为固定模式(只读) |
| `labelStart` | string | `"A"` | 标签起始值,支持字母(如 `"A"`, `"C"`)或数字(如 `"1"`, `"7"` |
**标签生成规则:**
| 起始值类型 | 说明 | 示例 |
|------|------|------|
| 字母(默认) | 从起始字母开始,按 A-Z, AA-ZZ, AAA-ZZZ 顺序 | `A` → A, B, C...; `C` → C, D, E... |
| 数字 | 从起始数字开始递增 | `1` → 1, 2, 3...; `7` → 7, 8, 9... |
**字母标签序列(从 A 开始):**
- 0-25: A-Z
- 26-51: AA-ZZ
- 52-77: AAA-ZZZ
**示例:**
```markdown
<!-- 固定标记模式 - 字母标签(默认从 A 开始) -->
:md-pins[./images/battle-map.png]{pins="A:25,50 B:75,30 C:50,80" fixed}
<!-- 可编辑模式 - 点击添加标记 - 从 A 开始 -->
:md-pins[./images/blank-map.png]
<!-- 数字标签 - 从 1 开始 -->
:md-pins[./images/dungeon.png]{labelStart="1"}
<!-- 数字标签 - 从 7 开始 -->
:md-pins[./images/cave.png]{labelStart="7"}
<!-- 字母标签 - 从 C 开始 -->
:md-pins[./images/quest-map.png]{labelStart="C"}
<!-- 自定义标签 + 预设标记 -->
:md-pins[./images/map.png]{pins="5:30,40 6:75,30" labelStart="5" fixed}
<!-- 复制生成的格式 -->
:md-pins[./images/map.png]{pins="A:30,40 B:10,30" fixed}
```
### 📊 表格组件 (md-table)
```markdown
:md-table[./data.csv]
:md-table[./data.csv]{roll=true}
:md-table[./data.csv]{roll=true remix=true}
```
**CSV 格式要求:**
```csv
label,body,group
第一页,这是**第一页**的内容group1
第二页,这是*第二页*的内容group1
第三页这是第三页的内容group2
```
- 使用英文逗号分隔
- 支持 `#` 开头的注释行
- 包含逗号或 `#` 的字段用双引号包裹
**特殊列:**
| 列名 | 说明 |
|------|------|
| `label` | 标签页名称 |
| `body` | 标签页内容(支持 Markdown |
| `group` | 分组标识(可选) |
**属性:**
| 属性 | 类型 | 说明 |
|------|------|------|
| `roll` | boolean | 添加随机切换按钮 |
| `remix` | boolean | `{{prop}}` 引用随机行内容 |
**变量引用语法:**
`body` 列中可使用 `{{prop}}` 引用同行其他列:
```csv
label,name,description,body
战士,约翰,勇敢的战士,{{name}}是一位{{description}}。
```
**Front Matter 支持:**
CSV 可包含 YAML front matter所有行会继承这些属性
```csv
---
source: 玩家手册
version: 1.0
---
label,name,description
1战士近战专家
2法师奥术施法者
```
**示例:**
```markdown
<!-- 基础表格 -->
:md-table[./npcs.csv]
<!-- 带随机切换 -->
:md-table[./encounters.csv]{roll=true}
<!-- 随机引用变量 -->
:md-table[./quests.csv]{roll=true remix=true}
```
**自动表格转换:**
标准 Markdown 表格会自动转换为 `md-table` 组件,当表头包含 `label``md-table-label` 列时:
```markdown
| label | name | description |
|-------|------|-------------|
| 1 | 战士 | 近战专家 |
| 2 | 法师 | 奥术施法者 |
```
自动转换为 `:md-table` 组件。
**特殊表头标识:**
| 表头 | 效果 |
|------|------|
| `label``md-table-label` | 转换为 md-table |
| `md-roll-label` 或骰子格式(如 `1d6` | 添加 `roll=true` |
| `md-remix-label` | 添加 `roll=true remix=true` |
### 🃏 卡牌组件 (md-deck)
```markdown
:md-deck[./cards.csv]{grid="5x8" layers="title:1,1-5,1f8 body:1,5-5,8f3"}
```
**CSV 格式:**
```csv
label,title,body
1,卡牌名称,这张卡牌的**效果**描述
2,另一张牌,更多效果
```
**属性:**
| 属性 | 类型 | 说明 |
|------|------|------|
| `grid` | string | 卡牌布局(行 x 列) |
| `layers` | string | 图层定义 |
**图层语法:**
```
layers="字段:起始行,起始列 - 结束列,字体大小"
```
示例:`title:1,1-5,1f8` 表示 title 字段从第 1 行开始,占据 1-5 列8mm字体。
### 🧶 叙事线组件 (md-yarn-spinner)
用于展示分支叙事结构,支持 Yarn Spinner 格式文件。
```markdown
:md-yarn-spinner[./story.yarn]
```
### 🪙 代币组件 (md-token)
用于展示游戏代币/棋子。
```markdown
:md-token[./token.png]
```
### 🎨 代币预览组件 (md-token-viewer)
用于 3D 预览 3MF 格式的代币模型。
```markdown
:md-token-viewer[./token.3mf]
```
**功能:**
- 使用 Three.js 渲染 3D 模型
- 支持鼠标拖拽旋转
- 自动旋转展示
### 📋 命令追踪器 (md-commander)
支持命令历史和状态追踪。
```markdown
:md-commander
```
**追踪器命令:**
```
track npc#john.dwarf.warrior[hp=4/4 ac=15 name="John"]
```
**Emmet 简写语法:**
- `#id` - 设置 ID
- `.class` - 添加类别
- `[attr=value]` - 设置属性
**属性类型:**
| 类型 | 格式 | 显示 |
|------|------|------|
| progress | `x/y` | 进度条 |
| count | 整数 | 数字计数器 |
| string | 文本 | 文本字段 |
## YAML 标签
使用 ```yaml/tag 代码块创建自定义标签:
````markdown
```yaml/tag
tag: tag-name
class: custom-class
id: my-id
body: 标签内容
```
````
渲染为:
```html
<tag-name id="my-id" class="custom-class">标签内容</tag-name>
```
## Mermaid 图表
支持 mermaid 流程图:
````markdown
```mermaid
graph TD
A[开始] --> B{选择}
B -->|选项 1| C[结果 1]
B -->|选项 2| D[结果 2]
```
````
支持的图表类型:
- flowchart - 流程图
- sequenceDiagram - 时序图
- classDiagram - 类图
- stateDiagram - 状态图
- erDiagram - ER 图
- pie - 饼图
## 警告/提示块
```markdown
> [!NOTE]
> 这是一条备注
> [!TIP]
> 这是一条提示
> [!IMPORTANT]
> 这是重要信息
> [!WARNING]
> 这是警告信息
> [!CAUTION]
> 这是危险警告
```
## 文件引用
### 相对路径
```markdown
<!-- 引用同目录文件 -->
:md-table[./data.csv]
<!-- 引用子目录文件 -->
:md-deck[./cards/deck.csv]
<!-- 引用上级目录文件 -->
:md-table[../shared/npcs.csv]
<!-- 引用图片 -->
![地图](./images/map.png)
```
### 路径解析规则
- 所有路径相对于当前 Markdown 文件
- 支持 `.``..` 导航
- 自动处理 URL 编码
## 样式定制
### 使用 Tailwind 类
组件支持 Tailwind CSS 类:
```markdown
:md-dice[1d20]{class="text-red-500"}
```
### 自定义 CSS
```css
/* 在 styles.css 中添加 */
.md-dice {
@apply text-blue-600 hover:text-blue-800;
}
```
## 最佳实践
### 内容组织
```markdown
# 章节标题
这里是章节内容。
## 子章节
### 规则说明
:md-dice[2d6] 掷骰决定结果。
:md-table[./options.csv]{roll=true}
> [!TIP]
> 这是一个有用的提示。
```
### 性能优化
- 大型 CSV 文件使用 `group` 列分组
- 图片使用适当分辨率
- 避免过多嵌套组件
### 可访问性
- 为图片添加 `alt` 文本
- 使用语义化标题层级
- 确保颜色对比度