All skills
cat-xierluo avatar

/svg-book-illustrator

@3d04372

书籍/文章 SVG 配图生成工具,专注于架构图、流程图、层次图等专业技术配图。当用户需要为书籍章节或正式文章生成配图、创建架构图/流程图/层次图,或提到"章节配图"、"书籍插图"、"架构图"、"流程图"时使用此技能。

Use this Skill: https://skilld.dev/gh/cat-xierluo/legal-skills/svg-book-illustrator

This session only. Nothing lands on disk.

referencesstyle-guide.md

≈9.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

SVG 书籍配图设计规范

书籍/正式文章 SVG 配图的视觉设计系统。所有生成的 SVG 必须遵循本规范。


一、画布

  • viewBox:宽 720px 固定,高度按内容裁剪(v1.7.1)——viewBox="0 0 720 H",H = 内容底边最大 y + 40px;不再固定 720×400 / 1.8:1(固定 400 会让内容少的图底部留白过大、图注间距不一致;用户 2026-06-30 反馈 SVG 转出 PNG 下边缘离图注间距忽大忽小,根因即此)。
  • 稳定图身份:v1.8.9+ 新生成/新落稿 SVG 的根元素必须有项目内唯一 data-figure-id="fig-chNN-sN-NN"。值限 1–128 位字母、数字、点、下划线或连字符;模板 fig-template-* 只作示例,落稿前替换。下游 review / render inventory 以此绑定跨轮证据,缺失或重复均失败。
  • 背景:透明背景(硬约束)——新生成图不画任何背景矩形、不设 background、不在 <svg> 根设底色。视觉区分由内部模块填充色承担(详见 §5)。
  • 安全边距:左右 40px、顶部 40px;底部 = H − 内容底边(即 40px,由 viewBox 裁剪保证)
  • 有效绘图区:宽 640px(x: 40–680);高度按内容(y 从 40 到 H−40)
  • 渲染:源 SVG 不嵌字体样式;正式预览运行 python3 scripts/render_svg.py in.svg out.png,由 wrapper 读取 assets/render-fonts.css 并固定宽 720(不指定高度,按 viewBox 比例);高 DPI 的 svg2png.js 注入同一 CSS。禁止用裸渲染器输出作验收证据。

关于老图:main 上既有 34 张白底单色 SVG 是历史产物(<rect width="720" height="400" fill="#FFFFFF"/>),保持稳定不回改(作者 2026-06-20 确认)。新规则只管新生成图:透明底 + 内部模块多色柔和区分;data-figure-id 同样不要求在本次升级中回填历史书稿。透明底与白底是两种不同做法——老图不强制改透明。


二、印刷物理尺寸推算

SVG viewBox 是虚拟坐标,实际印刷尺寸由排版决定。本节从物理尺寸反推所有参数。

中国常见书籍开本

开本 成品尺寸 版心宽度 版心高度 通栏配图宽 典型用途
16开 170×240mm ~115mm ~190mm 115mm 技术书、教材(本 skill 主目标)
大32开 140×203mm ~95mm ~160mm 95mm 通俗读物、商业书
32开 130×184mm ~85mm ~150mm 85mm 口袋书
A5 148×210mm ~100mm ~170mm 100mm 国际标准

换算公式

物理尺寸(mm) = SVG单位 × (印刷宽度mm / 720)
物理尺寸(pt) = 物理尺寸(mm) / 0.3528

以主目标 16开(115mm 通栏)为例:1 SVG单位 ≈ 0.160mm

中文印刷可读性标准

等级 字号 物理尺寸 用途
正文 五号 10.5pt 3.70mm 书籍正文
图注 小五号 8pt 2.82mm 图注、标签最低线
辅助 7pt 2.47mm 仅限纯英文/数字,中文不建议
危险 <7pt <2.47mm 中文不可辨认

关键换算表(16开 115mm 通栏)

1 单位 = 0.160mm

SVG字号 物理尺寸 pt值 可读性
24px 3.84mm 10.9pt 舒适,适合图标题
22px 3.52mm 10.0pt 舒适,适合层标签
20px 3.20mm 9.1pt 良好
18px 2.88mm 8.2pt 刚好过 8pt 下限 → 节点标签最低字号
16px 2.56mm 7.3pt 偏小,仅限英文/数字子标签
14px 2.24mm 6.4pt 中文不可读
12px 1.92mm 5.4pt 完全不可读

不同开本的标签最低字号

开本 印刷宽度 达到 8pt(2.82mm) 所需 达到 9pt(3.17mm) 所需
16开 115mm 18px 20px
大32开 95mm 22px 24px
32开 85mm 24px 27px

结论:16开下 18px 是节点标签的硬底线。大32开需要 22px。


三、字体规格(基于 16开 115mm 推算)

用途 SVG字号 物理(16开) pt值 字重 颜色
图标题 22px 3.52mm 10pt 600 #2D3436
层标签(layer 模板) 20px 3.20mm 9.1pt 600 #2D3436
节点标签 18px 2.88mm 8.2pt 400 #2D3436
子标签/第二行 16px 2.56mm 7.3pt 400 #636E72

字体族单一权威源:assets/render-fonts.css。字体栈只在该文件维护;源 SVG、生成器、模板和渲染脚本均不得复制字体栈。Markdown/Obsidian 预览继承宿主字体,正式导出统一由 scripts/render_svg.py / scripts/svg2png.js 加载该 CSS。

标签长度限制(18px 标签,汉字宽度约为字号的 1.05 倍):

  • 18px 标签:最多 8 个汉字(约 151px)或 10 个英文字符
  • 16px 子标签:最多 10 个汉字(约 168px)
  • 超出时缩写或拆成子标签

中文换行:使用多个 <text> 元素:

<!-- 主标签 + 子标签 -->
<text x="360" y="195" text-anchor="middle" font-size="18" fill="#2D3436">法律评注</text>
<text x="360" y="214" text-anchor="middle" font-size="16" fill="#636E72">知识库最佳载体</text>

行间距:两行文字 y 坐标差 18-20px。


四、节点尺寸(基于 18px 标签推算)

18px 单行中文标签 + 上下内边距:

节点高度 = 18px(文字) + 10px(上内边距) + 12px(下内边距) = 40px 最低
         推荐 44px(留余量给视觉呼吸)
两行标签节点 = 第一行 18px + 间距 18px + 第二行 16px + 上下内边距 = 约 56px
元素类型 宽度 高度 能放多少字
标准节点 140–160px 48px 8 字单行(18px)
宽节点(layer 内) 200–240px 48px 12 字单行
紧凑节点(hub 外围) 120px 44px 6 字
两行节点 140–160px 56px 8字+8字

物理尺寸验证(16开 115mm):

  • 标准节点 160×48px → 物理 25.6×7.7mm → 高度 7.7mm 看起来合适
  • 紧凑节点 120×44px → 物理 19.2×7.0mm → OK
  • 4 个标准节点水平排列:4×140 + 3×26.7 = 640px → 正好占满 640px 有效宽度

节点尺寸下限

任何节点不得小于:

  • 宽 100px(物理 16mm,放 5 个 18px 汉字)
  • 高 40px(物理 6.4mm)

五、颜色系统

5.0 配色总则(v1.7.0 起条件化拆分,按模板语义分类;v1.8.8 起补「蓝色焦点 + 文字二档」通用规则)

适用范围:本节适用于 v1.7.0 及之后新生成的图。main 上既有图(含 v1.5.0-v1.6.x 生成的)保持稳定不回改——只让新生成的 layer/tree/金字塔模板走新规则。

supersede 说明:v1.5.0 DEC-010 的"内部模块多色"规则仍适用于多样性关系类模板(flow/matrix/hub/cycle),但对层级归属类模板(layer/tree/金字塔)不适用——本版为后者引入"同色相灰度梯度"新规则。详见 DEC-012。

项目级规范优先(v1.8.6 起,防漂移):生成配图前先读项目的 figures/FIGURES-OUTLINE.md(或等价配图大纲/风格规范)。若该书在其中锁定了 canonical 配色,从其规定——本 skill 的 P1-P8 / G1-G4 是通用兜底,不得与项目 canonical 冲突。这是防止"不同批次补图风格漂移"的硬约束。

「蓝色焦点 + 文字二档」通用规则(v1.8.8 起,DEC-020):即便项目未锁定 canonical,本 skill 默认推荐以下三条作为通用配色纪律(跨项目,非项目指针):

  1. 文字色统一深灰二档:图内所有文字仅允许主标签 #2D3436、子标签 #636E72(见 §5.1);深色填充(L* ≤ 50)模块上文字用 #FFFFFF/#EDF2F7(见 §5.5.1)。不再使用 #1A202C/#4A5568 等四档深灰——收敛到二档,消除同图深浅灰混用的不一致。
  2. 蓝色(#2C5282/#1A365D)只用于焦点节点的填充 / 描边,不得作文字 fill:当项目 canonical 锁定某主色(如 #2C5282 蓝)为视觉标识时,该色只出现在焦点节点(起点 / 终点 / 核心 / 输出)的填充或描边上以色块承载强调,禁止把它当文字 fill 染字(蓝字与深灰字混用会导致层次不清)。文字强调改用字重(600/700)或字号,不用色相。
  3. 每张结构 / 流程图至少 1 个焦点节点:layer / tree / flow / hub / cycle / matrix 等结构性模板应至少有 1 个焦点节点(用 canonical 主色或更深一档填充 / 描边)承载层次,反对纯灰平铺(无焦点 → 平、无重点)。纯并列清单(如五要素列表)无自然焦点时,用灰阶递进 + 边框粗细区分层次,逐图评估是否补焦点色。

这三条是对 §5.1(文字色)、§5.5.1(深底浅字)的规则化提级——把它们从"默认假设"升级为"生成期硬约束 + review checklist 勾选项",防"语法合法但配色不一致 / 无焦点"的漂移。

两条总原则:

  1. 透明背景,绝不加底色:SVG 根标签和内容里不画任何背景矩形、不设 background、不写画布底色。视觉空间由排版(纸/页面)提供,配图叠上去就是透明底。
  2. 按模板语义分类配色——按"内部模块之间的语义关系"选择调色板类别:
模板类型 语义关系 调色板类别 规则
layer / tree / 金字塔 层级归属(同族,递进) §5.2b 灰度梯度 G1-G4 同色相 + 不同明度,顶层最浅、底层最深
flow / matrix / hub / cycle 多样性区分(不同对象) §5.2 模块色 P1-P8 多色相 + 柔和去饱和,相邻模块不同色
  1. 颜色不是唯一区分手段:仍用形状、位置、线型、边框粗细、填充深浅协同区分元素——黑白打印或 CMYK 偏色下仍可辨(继承自旧规范)。

5.1 基础中性色(文字 / 边框 / 连线 · v1.8.8 收敛二档)

用途 色值 说明
深灰文字 / 边框 / 连线 #2D3436 主文字色(统一收敛),对任何柔和模块填充色对比 ≥ 7:1
中灰子标签 #636E72 辅助文字(统一收敛)
浅灰辅助线 #B2BEC3 分隔线、弱连接

文字色硬规则(v1.8.8 起,DEC-020):

  • 图内所有文字仅允许深灰二档:主标签 #2D3436、子标签 #636E72;深色填充(L* ≤ 50)模块上文字用 #FFFFFF/#EDF2F7(见 §5.5.1)。
  • 不再使用 #1A202C / #4A5568(收敛到二档,消除同图四档深灰混用的不一致——这两档在过去版本偶现于标题/强调位,现统一到 #2D3436)。
  • 禁止以项目 canonical 主色(如 #2C5282/#1A365D 蓝)作为文字 fill——主色只出现在焦点节点的填充 / 描边上(§5.0 第 2 条)。文字强调改用字重(600/700)或字号,不用色相。

文字色统一用深色(#2D3436 / #636E72)保证在任意柔和模块填充色上都清晰可读。不要把文字写成柔和色(浅蓝/浅绿等)或项目主色——文字可读性优先。

5.2 预定义柔和模块色调色板(8 组,新生成图选用)

每组 = 一组柔和的「模块色」(5-6 个去饱和、低饱和、纸面友好的色),用于区分 SVG 内部不同模块 / 分支 / 方向 / 层级。一组内所有色都是柔和(去饱和)的同明度档(避免某个模块过亮/过暗抢视觉重心),色相彼此拉开但都压住饱和度。

关键概念转变:上一版"调色板"是「画布浅底 + 强调色」二元结构(已被废弃)。本版调色板是「内部模块多色」结构——一组给 5-6 个模块色,不再有"画布底"这一列。

编号 色组名 模块色(用于区分内部模块,去饱和柔和) 适用主题
P1 雾蓝系 #D6E4F0 #C5D9E8 #B8CFE0 #DCE8F2 #C9DCEC #E0EBF4 科技、AI、数据、系统架构
P2 浅青系 #C0E8E0 #B5DDD4 #A8D2C9 #CFEDE5 #BCDFD6 #D3EFE9 工具、流水线、协作
P3 嫩绿系 #C8EBC8 #BDDFBD #B0D2B0 #D4EED4 #C3E3C3 #D8F0D8 成长、流程闭环、正向结果
P4 暖米系 #E8D8C0 #DCCAB0 #D0BEA0 #EDDFC8 #E0D0B5 #F0E2CC 法律、正式、风控、合规
P5 浅紫系 #DCC8E8 #CFBDDC #C2B2D0 #E2D0EC #D5C3DF #E7D6F0 思考、概念、抽象、方法论
P6 浅粉系 #F5D8E0 #E8CBD2 #DCBEC6 #F8DFE5 #EFD2D8 #FAE4EA 情感、用户视角、体验
P7 暖灰系 #E8DFD0 #DCD3C4 #D0C7B8 #EDE5D7 #E0D8C9 #F0E9DC 叙事、随笔、文化
P8 混合柔和系 #D6E4F0(蓝) #C8EBC8(绿) #E8D8C0(米) #DCC8E8(紫) #F5D8E0(粉) 多方向/多分支对比(一图内天然多色,无需另选)

使用约定:

  • 每张图选 1 组(P1-P7)或用 P8 混合系;同图内部模块按"模块 1 取色 1、模块 2 取色 2…"依次分配,让相邻模块不同色。
  • 模块色用于内部矩形 / 卡片 / 区块的 fill:<rect fill="{模块色}" stroke="#2D3436" stroke-width="2"/>。
  • 文字色始终 #2D3436 / #636E72,不写浅色。
  • 绝对不画背景矩形:不要 <rect width="720" height="400" fill="..."/>。SVG 直接画模块(透明底由页面/纸面提供)。
  • 模块色应覆盖内部所有矩形/区块;连线/箭头/marker 用深灰 #2D3436(或取该模块对应的更深一档色做箭头),不抢戏。

5.2b 预定义单色灰度梯度调色板(v1.7.0 新增,专用于层级类模板)

用途:layer / tree / 金字塔模板——表达"层级归属(上层包下层 / 父节点辖子节点)"语义时,颜色用同色相的不同明度档营造层次感,而不是不同色相混搭。

关键概念:与 §5.2 的 P1-P8 多色区分不同——这里一组给的是5 档明度(同色相),按"层级 1 取档 1、层级 2 取档 2、…"分配,色相统一、仅明度变化。一图内部同一色相,靠明度差建立层次。

编号 色组名 档位 1(最浅) 档位 2 档位 3(中) 档位 4 档位 5(最深) 适用主题
G1 蓝灰梯度 #F0F4F8 #D6E4F0 #B8CFE0 #9AB8D0 #7CA0BC 科技、AI、数据、系统架构(冷调中性)
G2 法律米梯度 #F4ECDC #E8D8C0 #D8C4A4 #C4AE88 #B8A282 法律、合规、正式文书(暖调,本 skill 主推荐)
G3 暖灰梯度 #F0EDE8 #E8DFD0 #DCD3C4 #D0C7B8 #C4BBAC 叙事、随笔、文化、通用文档
G4 蓝梯度 #E8F0F8 #C5D9E8 #A0BED4 #7CA0BC #5A82A4 系统、架构、技术(冷调明度跨度大)

使用约定:

  • layer / tree / 金字塔模板强制使用 G1-G4 中任一组——禁止误用 P1-P8 多色区分(把同色系层画成不同色相)。
  • 同图层级数 ≤ 5 时:层级 1(最顶层)取档位 1(最浅),层级 5(最底层)取档位 5(最深),中间按"层级 N → 档位 N"对应。
  • 同图层级数 > 5 时:拆成两张图,或取档位 1-5 的子集(按层级数等距取)。
  • 树/金字塔同理:根节点用档位 1、子节点用档位 2、叶子用档位 3(金字塔 3 层变体)或更深档。
  • 模块色用于内部矩形 / 卡片 / 区块的 fill:<rect fill="{档位 N 色}" stroke="#2D3436" stroke-width="2"/>。文字色统一 #2D3436。
  • 明度跨度的硬约束:档位 1(最浅)模块色明度 L* ≥ 90,保证深色文字 vs 模块填充色对比 ≥ 4.5:1(WCAG AA 正常文本);档位 5(最深)模块色明度 L* ≥ 55(最深档 G2-5 = #B8A282,L* ≈ 56,对比度 ≥ 4.5:1,刚好过线)。若发现最浅档不够浅 / 最深档过深,按 G2/G4 切换组或微调档位。
  • 绝对不画背景矩形:同 §5.2。
  • 连线/箭头/marker 用深灰 #2D3436,不抢戏。

5.3 打印友好约束(CMYK / 纸面可读硬约束)

透明背景下的对比度口径:对比度是 文字色 vs 所在模块的填充色(不是 vs 画布底——没有画布底)。因此模块填充色必须足够浅(去饱和),让深色文字落在上面仍 ≥ 4.5:1。

约束 阈值/规则 验证方法
文字对比度 文字色(#2D3436)与所在模块填充色亮度对比 ≥ 4.5:1(WCAG AA 正常文本);标题/节点标签(≥18px)≥ 3:1(AA 大文本) WebAIM Contrast Checker(输入文字色 vs 模块填充色)
相邻模块区分度 相邻模块(同行/同列/直接连接的两个矩形)填充色之间亮度差 ≥ 10% 且色相差可辨;非相邻可同色 肉眼:相邻模块一眼能分开
模块填充明度上限 所有模块色明度 L* ≥ 80(约 #E0E0E0 以上偏浅),保证深色文字对比 调色板内 8 组已统一标定到柔和档
禁高饱和荧光 禁 #FF0000/#00FF00/#FFFF00/#FF00FF 等纯三原色高饱和;调色板内已统一去饱和 不使用调色板外的色
红绿不并置做区分 红绿对比在色盲+黑白下都失效;若必须红绿,靠填充深浅+边框粗细补区分 避免纯红与纯绿相邻做唯一区分手段
CMYK 转换不偏色 所有色值在 sRGB 空间,转 CMYK 时不出现明显色相漂移(蓝→紫、黄→棕) 出片前用 Photoshop/Ghostscript 转 CMYK 预览
黑白降级可辨 去色(grayscale)后,相邻模块灰度差 ≥ 10%;文字与模块填充灰度差 ≥ 15% convert in.svg -colorspace Gray out.png 预览

打印友好自检脚本(生成后必跑一次,灰度预览 + 目检):

python3 scripts/render_svg.py in.svg out.png
# 灰度预览(模拟黑白印刷)
convert out.png -colorspace Gray gray.png
# 肉眼看 gray.png:模块彼此可分、文字清晰 = 通过

5.4 颜色语法约束(与既有语法门禁兼容,必读)

硬约束:颜色只能通过 fill/stroke 属性内联到具体元素上。源 SVG 禁止 <style> 与任何元素的 style=;字体只由外部 assets/render-fonts.css 管理。严禁以下写法:

<!-- ❌ 禁止 1:用 <style> 块定义颜色类 -->
<style>
  .node-blue { fill: #D6E4F0; stroke: #2C5282; }
</style>

<!-- ❌ 禁止 2:在 <svg> 开标签上写 font-family -->
<svg viewBox="0 0 720 400" font-family="...">

<!-- ❌ 禁止 3:在任一元素写 style= 或复制字体栈 -->
<text style="fill:#2D3436" font-family="...">节点</text>

<!-- ❌ 禁止 4:用 CSS 变量 / currentColor / class 引用色 -->
<rect class="node-blue"/>

<!-- ❌ 禁止 5:画背景矩形当画布底(透明背景硬约束) -->
<rect width="720" height="400" fill="#F0F4F8"/>

正确写法:每个元素的 fill/stroke 直接写色值;不画任何背景。

<!-- ✅ 正确:透明背景 + 属性内联模块色 -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 400" width="720" height="400" data-figure-id="fig-ch03-s2-01">
  <!-- 注意:没有背景矩形!直接画模块 -->
  <rect x="40" y="176" width="140" height="48" rx="6" fill="#D6E4F0" stroke="#2D3436" stroke-width="2"/>
  <text x="110" y="205" text-anchor="middle" font-size="18" fill="#2D3436">识别场景</text>
  <!-- 相邻模块用同组不同色 -->
  <rect x="207" y="176" width="140" height="48" rx="6" fill="#C5D9E8" stroke="#2D3436" stroke-width="2"/>
  <text x="277" y="205" text-anchor="middle" font-size="18" fill="#2D3436">梳理流程</text>
</svg>

为何如此:

  • 透明背景:作者 2026-06-20 明确要求——配图叠在排版纸面上,底色由书页提供,不应自带底色。
  • 属性内联(不用 <style> / style= / 内嵌 font-family):Obsidian/Markdown 内嵌渲染时存在已知不兼容(嵌套引号、样式作用域——见 memory feedback_svg_embed_syntax)。颜色保持 fill/stroke 属性,字体在导出时从受控外部 CSS 注入,保证源文件兼容与正式导出稳定不冲突。

5.5 可视友好化配色与渲染禁忌(v1.8.7 新增,硬约束)

为什么加这节:§5.1-§5.4 的"文字色统一深灰 #2D3436/#636E72、模块色柔和浅"是默认假设「模块填充是浅色、文字是深色」的搭配。但生成图时若模块用深色填充(项目 canonical 锁定的 #2C5282 深蓝做强调、#1A202C 近黑、tree 根节点加深档 #5A82A4、表头 #2C5282 等),深灰文字落上去会与深底融为一片不可读。此外图 7-13 / 8-3 / 6-7 等若干图出现"框画了但 <text> 没写 / 文字 fill 与背景同色 / 文字被裁出框外"的视觉缺失。本节把这些"看似显然、却反复发生"的渲染事故固化为硬约束。

来源:作者 review T134 决策清单嵌图时实测发现(图 7-6 箭头落点错位、图 11-8 字色不可辨、图 11-9 深蓝背景配深色字、图 7-13/8-3/6-7 框内文字缺失),均属"语法 xmllint 通过、但视觉渲染失败"的典型。

5.5.1 深底浅字(硬约束)

凡 <rect> / <circle> / <path> 等模块填充色为深色(明度 L* ≤ 50,典型如 #2C5282/#1A365D/#1A202C/#2D3748/#4A5568,以及 G1-G4 梯度的最深档 #5A82A4/#7CA0BC 与项目 canonical 强调色),其内部所有 <text> 的 fill 必须用浅色:

<!-- ✅ 深蓝表头 + 白字 -->
<rect x="40" y="40" width="640" height="40" rx="6" fill="#2C5282"/>
<text x="360" y="66" text-anchor="middle" font-size="18" fill="#FFFFFF">表头标题</text>

<!-- ❌ 禁止:深底深字(融合不可读) -->
<rect ... fill="#2C5282"/>
<text ... fill="#2D3436">表头标题</text>

允许的浅色文字 fill(深底专用):

  • #FFFFFF(纯白,深底首选)
  • #EDF2F7 / #F7FAFC(极浅灰白,柔和档)
  • #E2E8F0(浅灰白)

绝对禁止:深色填充(L* ≤ 50)的模块上写 #2D3436/#636E72/#4A5568 等深灰字——视觉对比度 < 2:1,不可辨。

判定快捷法:模块 fill 转灰度后 < #7F7F7F(中灰)即判深底,文字必走浅色。

5.5.2 字色对比度(与所在模块填充色,WCAG 视觉判断)

通用规则(覆盖浅底与深底):<text> 的 fill 与其所在区域(最贴近的、含该 <text> 几何中心的 <rect>/<circle>/<path> 的 fill,或 SVG 根透明背景外的页面底)的亮度对比度 ≥ 4.5:1(WCAG AA 正常文本);≥18px 大文本 / 图标题 ≥ 3:1。

  • 浅底(柔和模块色 P1-P8、灰度梯度 G1-G4 档 1-4,L* ≥ 55):文字用深灰 #2D3436/#636E72(默认 §5.1 规则)。
  • 深底(L* ≤ 50):文字必走 §5.5.1 的浅色 #FFFFFF/#EDF2F7。
  • 临界区(L* ≈ 50-55,如 G2-5 #B8A282、G4-4 #7CA0BC):两种方向都需测对比度,无脑深灰可能 < 4.5:1——用 WebAIM Contrast Checker 验证,不够则换白字或换更浅的模块色档。

验证手段:把文字 fill 与模块 fill 输入 WebAIM Contrast Checker,看对比度数值;或在 review-checklist §④ 视觉目检里用多模态渲染 PNG 直接看(深底深字在渲染图上一眼可辨)。

5.5.3 箭头 marker 与落点(与 §六「箭头」协同,硬约束)

此节为 §六「箭头」落点对齐规则的渲染友好化补强,专防图 7-6 类「marker 落点穿框 / 悬空 / 方向错」问题。

  • marker 必带 markerUnits="userSpaceOnUse" + orient="auto",单 id="arrow":禁止 arrV/arrF/arrG/arrT/arrR/arrL 等多方向自造 marker(详见 §六 / DEC-011)。一个 id="arrow" + orient="auto" 通吃水平 / 垂直 / 斜向。
  • 落点公式(硬算,不靠目测):
    • 线起点 x1/y1 = 源框边缘 + 4px 间隙
    • 线终点 x2/y2 = 目标框边缘 − 4px 间隙(让 marker 箭头尖端落在目标框边外 4px,不穿框、不悬空)
    • 例:源框右 x=180、目标框左 x=207 → x1=184、x2=203;可见线长 = 203−184−10(markerWidth) = 9px 纯线 + 10px 箭头
  • 斜向 / 垂直箭头同理:tree 的父→子斜线、hub 的中心→外围放射线、cycle 的弧形连线,终点都落在目标框边外 4px——禁止 marker 落在框内(穿框)、禁止离框 > 8px(悬空)。
  • 方向自洽:<line x1 y1 x2 y2> 的 (x2,y2) 是箭头尖端方向;写反了箭头会指错(图 7-6 即此问题)。生成后核对每条 line 的 (x2,y2) 是否落在目标节点,不在则改 x1/y1 ↔ x2/y2 对调。
5.5.4 文字完整性(生成后核实每个框的 <text> 齐全)

此节防图 7-13 / 8-3 / 6-7 类「框画了但文字没写 / 文字 fill 与背景同色 / 文字坐标出框外」的视觉缺失——这些图 SVG 语法合法、xmllint 通过,但渲染出来框里是空的或文字"看不见"。

生成 SVG 后逐框核实(建议自动化 grep + 多模态目检双保险):

  • 每个 <rect>/<circle>/<path> 节点都有对应 <text>:grep <rect 计数与 <text 计数对照(一个框允许 0 个 text——纯装饰/连线点,但有标题语义的节点框不可缺 text)。重点查:表头栏、layer 各层标签、tree 叶节点、hub 外围节点、matrix 单元格。
  • 文字 fill 与所在模块 fill 不同色:若文字 fill="#2C5282" 落在 fill="#2C5282" 的模块上(或同色系深浅相差 < 10%),渲染时融为一片"看似缺失"——必须改文字 fill(按 §5.5.1/5.5.2 走浅或深)。
  • 文字坐标在框内:<text x y> 的几何中心应在所属 <rect x y width height> 范围内(x 在 [rect.x+8, rect.x+rect.w−8]、y 在 [rect.y+12, rect.y+rect.h−8])。文字 x/y 算错(如复用了上一节点坐标)会"飘出框外",渲染看似缺字。
  • 文字不空:<text>...</text> 之间不能是空串 / 纯空白 / 占位符(如 ??? / TODO / XXX)——生成器漏填字段时常见。
  • 多模态渲染目检兜底:渲染为 PNG 后用多模态模型看,逐框核对"框里是否有可读文字"(与 SVG 源码的 text 列表对照,源码有但渲染看不见 = 配色或坐标问题;源码就没有 = 生成器漏写)。

六、形状规范

圆角矩形

模块填充色从 §5.2 调色板取值(以下示例用 P1 雾蓝系的两个相邻模块色;边框统一深灰):

<!-- 模块 1 -->
<rect x="40" y="40" width="150" height="48" rx="6" fill="#D6E4F0" stroke="#2D3436" stroke-width="2"/>
<!-- 相邻模块 2,同组不同色 -->
<rect x="207" y="40" width="150" height="48" rx="6" fill="#C5D9E8" stroke="#2D3436" stroke-width="2"/>
  • 圆角 rx="6"
  • 边框 2px(普通)、3px(强调根节点/终止节点)
  • 线宽 2px 在 16开下物理 0.32mm,印刷可见
  • 相邻模块同色组取不同色,避免色块连成一片

容器包含语义(v1.8.10+,与 writing-reviewer v0.16+ 对齐)

shape 完全包含另一 shape 既可能是“面板承载信息卡”的正常构图,也可能是坐标写错造成的遮挡。不要靠几何猜意图:默认先把包含/重叠当作布局缺陷修坐标;只有外层 shape 确实承担容器语义时,才使用唯一的 candidate-bound 窄声明。

<!-- 合法:外层卡片真实承载内层信息卡,意图与身份均可审计 -->
<rect id="outer-card" x="40" y="40" width="220" height="160" rx="6"
  fill="#EDF2F7" stroke="#2D3436" stroke-width="2"
  data-overlap-role="container"
  data-overlap-note="外层卡片承载内层信息卡"/>
<rect x="60" y="70" width="180" height="90" rx="6"
  fill="#D6E4F0" stroke="#2D3436" stroke-width="2"/>
  • data-overlap-role 只允许精确值 container;禁止 decoration、background 或任意自造 role,禁止用 data-allow-overlap 给候选 SVG 自发放行。
  • 声明只能放在 writing-reviewer 可测量的外层 area shape:rect / circle / ellipse / polygon / path;不要标在 g、text、连线或根 svg 上。
  • 外层必须同时有:①单张 SVG 内唯一、无 namespace 的稳定安全 id(1–128 位字母、数字、点、下划线或连字符,首位为字母或数字);②无 namespace、至少六字且含“承载/包含/容纳”等关系词的具体 data-overlap-note,说明“外层承载什么”,不能只写“这里允许重叠/覆盖”;③可静态证明非透明的 hex/rgb/hsl fill。none/transparent、零 alpha、命名色、inherit/currentColor/var()/url() 等继承或无法在 producer 侧证明的值均不合格,opacity/fill-opacity 必须大于 0。
  • data-overlap-note 不能脱离 container role 单独存在;x:id、x:data-overlap-note 等 namespaced 假属性不会被浏览器 getAttribute("id") 识别,producer contract 直接拒绝。
  • 这组属性只表达候选源中的设计意图,不构成几何通过证据。producer contract 负责静态拒绝缺 id / 缺 note / 非法 role;writing-reviewer v0.16+ render gate 用真实浏览器几何判断是否实际包含,并把命中的 outer / inner / reason 写入 evidence。
  • 装饰底纹若压住信息 shape,仍应改尺寸、层级或坐标;不得把装饰标成容器来消除 finding。容器声明长期未命中也不等于合规,应删除无效声明。

箭头

单个 marker 通吃所有方向(水平/垂直/斜向都用同一个 id="arrow",靠 orient="auto" 自动旋转,不要为每个方向另造 marker 如 arrV/arrF/arrG):

<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5"
  markerWidth="10" markerHeight="10" orient="auto" markerUnits="userSpaceOnUse">
  <path d="M 0 0 L 10 5 L 0 10 z" fill="#2D3436"/>
</marker>

为什么必须有 markerUnits="userSpaceOnUse":SVG 规范中 markerUnits 的默认值是 strokeWidth(不是像素),意味着 markerWidth="10" 在 stroke-width="2" 时实际渲染为 10 × 2 = 20px,在 stroke-width="1.5" 时为 15px——同一个规范下箭头大小随线宽飘忽。设 userSpaceOnUse 后 marker 尺寸固定为像素,与 stroke-width 解耦。详见 DEC-011。

为什么必须用 orient="auto" 单 marker:模型若为垂直 / 斜向箭头另造 id="arrV" 等并硬编码 refX/refY,方向一多就乱(实测产物里出现 arrV/arrF/arrG/arrT/arrR/arrL 等 10+ 自创 marker,refX/refY 各种组合)。orient="auto" 让 marker 沿 <line> 方向自动旋转,一个 id 通吃水平 / 垂直 / 斜向。

箭头落点对齐规则(箭头线 <line> 端点坐标怎么定):

位置 公式 例(flow 节点 1→2,源框右=180、目标框左=207)
线起点 x1 源框边缘 + 4px 间隙 184(180+4)
线终点 x2 目标框边缘 − 4px 间隙 203(207-4)
实际可见线长 x2 − x1 − markerWidth 203 − 184 − 10 = 9px 纯线 + 10px 箭头
  • 线起点 / 终点都留 4px 间隙:避免 marker 压源框、悬空目标框。
  • 斜向箭头(tree、hub)按相同规则:线终点落在目标框边外 4px,避免扎进框内。

连线

  • 实线:关键关系
  • 虚线 stroke-dasharray="6,4":辅助/可选关系
  • 线宽:主流程 2px、辅助 / 树形 / 中心辐射 1.5px(线宽变化不再影响箭头大小,因 markerUnits="userSpaceOnUse")
  • 语义优先:承载流程、反馈、复核、状态或条件含义的线不得为了“清爽”而删除;若线与文字或节点冲突,优先重路由、调整节点,再用简短的读者标签说明虚线 / 点线含义。只有无读者信息承载的调试线、辅助框或创作提示可删。
  • 分叉连续:同一关系的主干与支线应视觉相接;除非刻意表达“未连接 / 条件未满足”,否则线段交界不留几何缝隙。分叉 / 汇合处应令读者一眼看出是一个关系还是多个关系。
  • 层级连接紧凑:相邻层级箭头的可见线身优先为 16–32px;超过 48px 时,先压缩层间留白或重排节点,而不是用长箭头撑开画面。确有中间步骤、注释或跨组语义时可例外,但要让中间语义可见。

标签卡、编号与图例

  • 标签卡:深色标题 + 浅色正文是同一张卡时,画一个外轮廓;标题栏仅保留上圆角,下边应为直角。避免用两个圆角矩形叠出下圆角、细缝或双层边框;需要时以单个 path 画标题栏。
  • 步骤编号:①②③或 1/2/3/4 置于卡内独立上方带,标题与说明在其下排列;编号不得压住文字。空间不足时先增加卡高 / 内边距,不缩小文字或强行叠放。
  • 读者图例:实线、虚线、点线、问号、状态色等说明必须直接告诉读者“分别表示什么”;不把只用于作者、AI 或制图过程的协作提示放进最终图。

七、间距

规则 数值 物理(16开) 理由
元素最小间距 24px 3.8mm 印刷下不糊在一起
层间垂直间距 40px 6.4mm 层次清晰
同层水平间距 28px 4.5mm 节点不挨
节点内边距 16px 水平, 12px 垂直 2.6mm / 1.9mm 文字不贴边

八、印刷黑白兼容

  1. 颜色不是唯一区分手段:用形状、位置、线型区分
  2. 避免红绿对比(色盲+黑白都不行)
  3. 关键连线实线,辅助虚线
  4. 节点区分靠填充深浅 + 边框粗细,不仅靠颜色

九、元素密度上限

基于 680px 有效宽度和 48px 节点高度:

模板 最大节点 计算 最大字数/节点
flow(水平) 4 个 4×140+3×26.7=640 7-8 字
flow(垂直) 5 个 高度足够 12 字
layer 4 层 4×56+3×24=296 12 字
matrix 2列×3行 行高 60px×3+间距 8 字/格
hub 1+5 外围 半径 130px 6 字
tree 1→3→5 叶子 5×120+4×20=680 6 字
cycle 4 个 矩形排列 8 字

超过上限时:拆成两张图,不要硬塞。


十、大32开适配说明

如果目标是大32开(95mm 通栏),1 单位 ≈ 0.132mm,所有尺寸需放大:

参数 16开值 大32开调整
节点标签 18px 22px
子标签 16px 18px
图标题 22px 26px
节点高度 48px 56px
最大 flow 节点 4 个 3 个
最大 hub 外围 5 个 4 个

建议大32开书籍直接缩小 viewBox(如 520×290),这样 18px 标签在 95mm 下达到 3.34mm = 9.5pt,舒适可读。


十一、图注格式

**图 N-X:图标题**

十二、SVG 代码模板

注意:模板与生成器产物不得包含 <style>、style= 或任何内嵌字体栈——这是 Obsidian/Markdown 兼容的源文件硬约束(见 §5.4)。预览继承宿主字体;正式导出统一由 assets/render-fonts.css 外部注入。不得把字体栈复制到 <svg> 或单个 <text>。下面的 fig-template-* 只是模板身份,复制进书稿时必须改成项目内唯一 fig-chNN-sN-NN。

模板 A:透明背景 + 内部多色(新生成图默认,示例用 P1 雾蓝系)

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 400" width="720" height="400" data-figure-id="fig-template-style-a">
  <defs>
    <!-- 箭头 marker:markerUnits=userSpaceOnUse 固定像素;orient=auto 单 marker 通吃所有方向 -->
    <marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5"
      markerWidth="10" markerHeight="10" orient="auto" markerUnits="userSpaceOnUse">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#2D3436"/>
    </marker>
  </defs>
  <!-- 注意:无背景矩形!透明底由书页提供 -->
  <!-- 模块 1 -->
  <rect x="40" y="176" width="140" height="48" rx="6" fill="#D6E4F0" stroke="#2D3436" stroke-width="2"/>
  <text x="110" y="205" text-anchor="middle" font-size="18" fill="#2D3436">识别场景</text>
  <!-- 模块 2,同色组相邻模块用不同色 -->
  <rect x="207" y="176" width="140" height="48" rx="6" fill="#C5D9E8" stroke="#2D3436" stroke-width="2"/>
  <text x="277" y="205" text-anchor="middle" font-size="18" fill="#2D3436">梳理流程</text>
  <!-- 模块 3 -->
  <rect x="373" y="176" width="140" height="48" rx="6" fill="#B8CFE0" stroke="#2D3436" stroke-width="2"/>
  <text x="443" y="205" text-anchor="middle" font-size="18" fill="#2D3436">编写</text>
  <!-- 箭头:线两端各留 4px 间隙 -->
  <line x1="184" y1="200" x2="203" y2="200" stroke="#2D3436" stroke-width="2" marker-end="url(#arrow)"/>
  <line x1="351" y1="200" x2="369" y2="200" stroke="#2D3436" stroke-width="2" marker-end="url(#arrow)"/>
</svg>

模板 B:旧极简白底单色(仅 main 上 34 张历史图兼容,新图不再用)

历史产物保留:既有 34 张图带 <rect width="720" height="400" fill="#FFFFFF"/> 白底,保持稳定不回改。新生成图一律走模板 A(透明底 + 内部多色)。

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 400" width="720" height="400" data-figure-id="fig-template-legacy-example">
  <defs>
    <marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5"
      markerWidth="8" markerHeight="8" orient="auto">
      <path d="M 0 0 L 10 5 L 0 10 z" fill="#2D3436"/>
    </marker>
  </defs>
  <rect width="720" height="400" fill="#FFFFFF"/>
  <!-- 内容 -->
</svg>

Source: SKILL.md on GitHub

No alerts15d3 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    The skill is a technical tool designed to create, extract, and render SVG diagrams for books and articles. It includes Python scripts for diagram generation and Node.js scripts for PNG conversion. The analysis found that the skill uses standard system utilities to perform its tasks, creating an expected command execution surface. Additionally, like most tools that process user-provided documents, it has a potential surface for indirect prompt injection. No evidence of malicious behavior, data exfiltration, or obfuscation was detected.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: LOW · No issues

Signed by skilld at 3d04372. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 20 hours ago.

Activeupdated last month
homepage
https://github.com/cat-xierluo/legal-skills
author
杨卫薪律师(微信ywxlaw)
version
1.9.2

README badge

README badge for cat-xierluo/legal-skills/svg-book-illustrator