| name | svgbob-cjk-alignment |
| description | 修复 svgbob/bob 绘图中 CJK(中文/日文/韩文)字符导致的竖线对齐问题。Use when: 编写或修复 ```bob 代码块中含中文的 ASCII 图、检查竖线 │ 对齐、计算混合字符串显示宽度、排查 svgbob 渲染错位。 |
| argument-hint | 传入需要检查或修复对齐的 bob 图块内容,或指定包含 bob 图块的 markdown 文件路径 |
svgbob CJK 对齐修复
核心规则
svgbob 以字符网格渲染 ASCII 图形。当图中混入 CJK(中日韩)字符时,每个 CJK 字符的显示宽度 = 2 个英文字符宽度,但仅占源码中 1 个字符位。若不补偿这一差异,│ ┌ ┘ 等结构线将错位。
宽度计算公式
显示宽度(line) = Σ char_width(c) for c in line
char_width(c):
若 east_asian_width(c) ∈ {'W', 'F'} → 2 (CJK 表意字符、全角符号)
否则 → 1 (ASCII、半角、Box Drawing)
常见字符宽度速查:
| 字符类型 | 示例 | 宽度 |
|---|
| ASCII 字母/数字 | A 0 z | 1 |
| ASCII 标点 | . - + | | 1 |
| Box Drawing | │ ─ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ | 1 |
| 箭头符号 | ► ▶ ▼ → | 1 |
| CJK 汉字 | 系 统 层 | 2 |
| 全角标点 | : ( ) 、 【 】 | 2 |
| 全角字母/数字 | A 1 | 2 |
关键:全角冒号 :(U+FF1A, 宽度=2)≠ 半角冒号 :(U+003A, 宽度=1)。混用会导致 1 列偏移。
对齐原理
在一个矩形方框图中,所有行的显示宽度必须相等,│ 字符在每行必须位于相同的显示列:
正确示例(总显示宽度=22):
┌────────────────────┐ ← 显示宽度 = 1(┌) + 20(─) + 1(┐) = 22
│ 应用软件层 │ ← 显示宽度 = 1(│) + 4(空格) + 10(5个CJK×2) + 6(空格) + 1(│) = 22
│ Application Layer │ ← 显示宽度 = 1(│) + 2(空格) + 17(ASCII) + 1(空格) + 1(│) = 22
└────────────────────┘ ← 显示宽度 = 1(└) + 20(─) + 1(┘) = 22
错误示例(未补偿 CJK 宽度,右侧 │ 错位):
┌────────────────────┐ ← 22
│ 应用软件层 │ ← 源码字符数=22,但显示宽度=27!右│溢出
修复方法:每个 CJK 字符多占 1 列,故需减少等量空格。5 个 CJK 字符需比纯 ASCII 少 5 个空格。
操作步骤
步骤 1:定位 bob 代码块
在 markdown 文件中搜索 ```bob 标记,找到所有 svgbob 图块。
步骤 2:逐行计算显示宽度
对每一行,用以下 Python 逻辑计算显示宽度:
import unicodedata
def display_width(s: str) -> int:
"""计算字符串在等宽字体下的显示宽度"""
w = 0
for c in s:
eaw = unicodedata.east_asian_width(c)
w += 2 if eaw in ('W', 'F') else 1
return w
步骤 3:找到目标宽度
方框图的目标宽度由顶/底边框线决定(纯 ASCII 行,显示宽度 = 字符数)。
步骤 4:调整内容行的填充空格
对含 CJK 字符的行:
- 计算 CJK 字符数量 →
n_cjk
- 当前显示宽度比目标多出
n_cjk 列
- 在文本与右侧
│ 之间删除 n_cjk 个空格
步骤 5:验证
运行 对齐检查脚本 验证所有行宽度一致:
python .github/skills/svgbob-cjk-alignment/scripts/align_bob.py docs/chapter1.md
自动修复
运行脚本的 --fix 模式可自动调整空格:
python .github/skills/svgbob-cjk-alignment/scripts/align_bob.py --fix docs/chapter1.md
脚本能力:
- 扫描 markdown 文件中所有
```bob 代码块
- 逐行计算显示宽度并检测不一致
--fix 模式:自动在行尾 │/┤/┘/┐ 前调整空格至目标宽度
- 输出逐行宽度报告与差异标记
特殊情况
多列布局
当 bob 图中有多个并排方框时,每个竖直对齐组的 │ 必须在同一显示列。需要以整行为单位统一计算。
嵌套方框
外框与内框各自的 │ 位于不同显示列,分别对齐即可。
全角标点
全角标点(: ( ) 、 【 】)与 CJK 汉字等宽(宽度=2)。在宽度计算中一视同仁。建议在 bob 图中统一使用半角标点以减少意外偏移。
svgbob 不识别的字符
svgbob 将无法识别的字符原样渲染为文本。CJK 字符属于此类。渲染时每个 CJK 字符占用的 SVG 空间依赖字体度量,通常约为 2 倍 ASCII 宽度,与本规则一致。