Annotate
给同一句话/同一段文字里不同片段加多色标注——让"语法分析、代码 walkthrough、合同条款逐字解读、诗词逐字赏析"在 markdown 里视觉化。
When to use
- ✅ 语法分析:把一句话拆成主谓宾,每部分一个颜色
- ✅ 代码 walkthrough:高亮一行代码里的不同 token + 标签解释
- ✅ 合同条款解读:标出关键条款 / 风险条款 / 义务条款
- ✅ 诗词逐字赏析:典故 / 韵脚 / 意象分别上色
- ✅ 多语言对照:源句 + 标出对应的翻译片段
- ❌ 整段大量内容标注——视觉过载,不如分多个 callout
- ❌ 标注需要"折叠 / 隐藏 / 点击展开"——用 Modal
Basic syntax
annotate 是 fenced code block,分两段——正文 + --- 分隔线 + 标注表:
```annotate
The quick brown fox jumps over the lazy dog
---
4-9|red|形容词
10-15|blue|名词
16-21|green|动词
```
渲染:原句不变,但 quick(4-9 字符位)红色下划线、brown(10-15)蓝色、jumps(16-21)绿色。悬停每个标注片段,浮层显示标签文本。
Syntax 详解
正文
annotate 的正文通常是一行或一小段。多行也支持,但字符位计数要包括换行符。
分隔线
---(三个连字符独占一行)—— 标注表必须紧跟其后。
标注条目
每行一条标注,格式:
<start>-<end>|<color>|<label>
<start>/<end>:字符位置(0-based 或 1-based 见下方"All options")<color>:颜色(6 选 1,同 Layout accent 调色板)<label>:悬停 tooltip 内容(任意文字,但不能含|)
All options
字符位编号方式
| 模式 | 范围含义 | 例子 |
|---|---|---|
| 0-based half-open(推荐 / 默认) | [start, end) |
0-3 标的是 [0,1,2] 三个字符 |
| 1-based inclusive | [start, end] |
1-3 标的是第 1, 2, 3 个字符 |
默认 0-based。强烈建议保持默认,跟 JS / Python 的 string slice 语义一致。
颜色调色板
| 值 | 视觉 | 推荐 |
|---|---|---|
red |
红 | 错误 / 警告 / 关键 |
blue |
蓝 | 一般标注 / 中性强调 |
green |
绿 | 通过 / 推荐 / 正确 |
yellow |
黄 | 注意 / 待审 |
purple |
紫 | 特殊 / 高级 |
gray |
灰 | 低权重 / 弱标注 |
跟 Layout accent 同一组 6 色,方便整页视觉一致。
Examples
Example 1:英文语法分析
```annotate
The quick brown fox jumps over the lazy dog.
---
0-3|gray|定冠词
4-15|blue|形容词组
16-19|green|主语 (名词)
20-25|red|谓语 (动词)
26-30|gray|介词
31-43|purple|宾语 (名词组)
```
渲染:每个句法成分用不同颜色下划线标注,鼠标悬停显示语法角色。整句结构一眼看清:定冠词 → 形容词组 → 主语 → 谓语 → 介词 → 宾语。
Example 2:代码逐 token walkthrough
```annotate
const result = await fetch('/api/users').then(r => r.json());
---
0-5|purple|声明 (const)
6-12|blue|变量名
15-20|red|关键字 (await)
21-26|green|内置函数
28-39|yellow|URL 字符串
42-46|red|Promise 链 (.then)
47-58|gray|箭头函数
```
渲染:JS 单行代码各 token 分类标注。比传统语法高亮多一层"语义角色"信息——读者能看到"这是声明 / 这是异步关键字 / 这是 Promise 链"等概念,不只是"这是关键字 / 这是字符串"的色块。
Example 3:诗句逐字赏析
```annotate
床前明月光,疑是地上霜。
---
0-2|blue|意象:床(家、私密空间)
2-4|gray|方位词
4-6|yellow|意象:明月(思乡符号)
7-8|gray|动词:疑(朦胧 / 错觉)
9-10|gray|介词:是
10-12|blue|意象:地上(人间 / 现实)
12-13|yellow|意象:霜(冷、寒、孤)
```
渲染:一句诗的每个字 / 词被标上意象 / 词性 / 文化符号。读者悬停每个色段看注释,如同现代版的"古文逐字注疏"。
Example 4:合同条款风险标注
```annotate
本协议自双方签字之日起生效,有效期 5 年,到期自动续约。
---
0-2|gray|主语:本协议
3-12|blue|生效条件
13-18|yellow|有效期
19-25|red|⚠️ 自动续约条款 (高风险,建议改 "需双方书面确认续约")
```
渲染:合同关键条款分类标色,"自动续约"红色高危标注 + 详细审查建议。法务用 markdown 做条款评审正合适。
Plain-text fallback behavior
annotate 是 fenced code block。在不支持的 reader 里:
```annotate
The quick brown fox jumps over the lazy dog.
---
0-3|gray|定冠词
4-15|blue|形容词组
...
```
→ 显示为带语法高亮的代码块——读者能看到完整原句 + 标注表清单,能手动对照字符位置和颜色理解标注意图。信息无损,只是不可视化。
具体各 reader:
| Reader | 渲染效果 |
|---|---|
| Rho | 完整可视化(彩色下划线 + tooltip) |
| GitHub web | 代码块(annotate 当作 lang label,无对应高亮,显示纯文本) |
| Obsidian | 同上 |
| VS Code 默认预览 | 同上 |
| cat / less | plain text |
Common pitfalls
1. 字符位置算错
中文 / Emoji / 复合字符容易踩坑:
床前明月光
| 位 | 字符 |
|---|---|
| 0 | 床 |
| 1 | 前 |
| 2 | 明 |
| 3 | 月 |
| 4 | 光 |
1 个汉字 = 1 个字符位(不是 3 字节)。Rho 按 Unicode codepoint 计数。
但 Emoji 和 flag / family 类复合 emoji 可能算多位:
| 字符 | codepoint 数 |
|---|---|
😀 |
1 |
👨👩👧 (家庭) |
5 (含 ZWJ 拼接) |
🇨🇳 (国旗) |
2 |
遇到复合 emoji,先用 JS [...str].length 验证再标注。
2. 范围超出文本长度
正文 5 字符,但写 4-10
→ Rho 会截断到文本末尾(不会报错),但视觉效果不可预期。先数清楚正文长度。
3. 范围重叠
0-5|red|片段 A
3-8|blue|片段 B ← ❌ 与 A 重叠 [3,5)
→ 重叠区域渲染行为未定义(可能后者覆盖前者,或彩色叠加,看 reader 实现)。标注应不重叠。如果确实需要"嵌套语义",把外层和内层拆成两个 annotate 块(同一段重复正文)。
4. label 含 | 字符
0-5|red|risk: A | B | C ← ❌ pipe 是分隔符
→ 解析器会切分成 5 段,全错。label 里不能有 |。
解决:用 /、,、、 替代,或用 unicode 全角 |。
5. 忘了 --- 分隔
```annotate
The quick brown fox
0-3|gray|定冠词 ← ❌ 缺 ---,标注会被当成正文一部分
```
→ 整块变成"无法解析的怪东西"。正文和标注表之间必须有 --- 独占行。
6. 给整段长文用 annotate
如果你想标注 300 字的段落里 20 个片段,不要硬塞一个 annotate 块——视觉过载、tooltip 难找、维护字符位置算不动。 解决:把段落拆成多句,每句一个 annotate 块。或改用"段落 + 脚注"形式(用普通 markdown)。
See also
- Callout — 整段强调(不针对句内片段)
- STL syntax highlighting — 内置 STL 语法着色(不是手工 annotate)
- Modal — 注释需要"点击展开"时用
- Layout grid + cards — accent color 跟 annotate color 同 6 色调色板
- Plain-text fallback principle