Skip to content

Agent #11 — 装帧工人(排版设计师)

角色卡片

维度描述
角色隐喻排版设计师 / 电子书工匠
Agent类型general-purpose
参与阶段Phase 5(发布与装帧)
核心输入output/chapters/final/*.md(所有定稿章节)
核心输出output/publish/*.html(HTML电子书);output/publish/.epub(EPUB电子书)

核心职责

  1. Markdown→HTML转换 — 将定稿的Markdown章节转换为结构化的HTML页面
  2. ASCII图表→SVG转换 — 自动检测文本中的ASCII图表并转换为美观的SVG矢量图
  3. 代码高亮处理 — 根据编程语言自动着色代码块
  4. 排版设计 — 应用护眼配色、CJK排版优化、响应式布局
  5. 导航系统构建 — 生成侧边栏目录、章节导航、滚动进度条
  6. EPUB生成 — 将定稿Markdown章节打包为符合EPUB 3.x标准的电子书文件(.epub

输入文件

文件说明
/output/chapters/final/*.md所有定稿Markdown章节文件
/output/memory/outline.md定稿大纲(用于生成目录结构)

输出规格

output/publish/ 目录结构

output/publish/
├── index.html              # 目录页/首页
├── ch01.html               # 第1章
├── ch02.html               # 第2章
├── ...
├── chNN.html               # 第N章
├── {{epub文件名}}.epub      # EPUB电子书(含封面及全部章节)
└── assets/                 # 静态资源(如需要)
    ├── style.css            # 样式表(或内联)
    └── script.js            # 交互脚本(或内联)

核心能力详解

1. ASCII图表→SVG自动转换 与 Mermaid 渲染

Mermaid 优先:章节中所有 ```mermaid 代码块由装帧工人通过引入 Mermaid.js(CDN 或本地)直接渲染为交互式矢量图,不做额外 SVG 转换。

规范要求:写作 Agent 在绘制流程图、架构图、层次图、目录树时,必须使用 Mermaid,禁止使用 ANSI 盒子字符(┌ ─ ┤ ├ └ │)。

支持检测和转换以下{{SVG检测类型数}}种ASCII兼容图表类型(用于处理存量内容):

类型ID类型名称检测特征转换效果
stacked堆叠块图多个┌──┐框纵向排列彩色卡片纵向堆叠
table表格构成的网格带样式的HTML表格或SVG表格
tree树形图├──└──树状缩进SVG树形结构图
grouped-flow分组流程图带分组标签的箭头流程分组的SVG流程图
mixed-flow混合流程图框+箭头+文字混合SVG流程图
vflow垂直流程图连接的纵向流纵向SVG流程图
numbered-list编号列表图带编号的步骤流程SVG步骤图
flow水平流程图──>连接的横向流横向SVG流程图
generic通用图表其他ASCII图形通用SVG转换

2. 代码高亮

EPUB 模式(需要 mmdc 附带的 Puppeteer):

  • 构建时通过 Puppeteer 启动一个 Chromium 会话,调用 CDN 版 highlight.js(atom-one-dark 主题)批量渲染所有代码块
  • 提取每个 token 的 getComputedStyle 结果,写为内联 style="color:rgb(…)" 属性,不依赖外部 CSS
  • 全书所有代码块共用一个 Chrome 进程(摊薄启动开销)
  • 文字可选中、可复制、可搜索——适合技术书读者
  • 未安装 mmdc / 无网络时优雅降级为纯色 <pre><code>

HTML 模式:通过 Mermaid.js CDN 动态高亮,不需要 Puppeteer。

模式工具输出形式文字可选中
EPUB 默认Puppeteer + highlight.js内联 inline-styled HTML
EPUB(可选)Puppeteer + Chromium 截图PNG 图片(Carbon 风格)
无 Puppeteer<pre><code>(无颜色)

若需启用 PNG 模式,在 build-epub.js 中设置 RENDER_CODE_AS_PNG = true

3. 护眼配色方案

元素颜色说明
页面背景暖白色,减少蓝光刺激
正文文字柔和深色,非纯黑
标题文字略深于正文
代码背景微灰,区分正文
链接柔和蓝色
强调色用于重要标注

4. CJK排版优化

规范设置
标题字体衬线体(如 Noto Serif SC / STSong / 宋体)
正文字体无衬线体(如 Noto Sans SC / PingFang SC / 微软雅黑)
行高1.8 ~ 2.0(中文排版需要更大行高)
段间距1em
中英文间距自动添加thin space
标点挤压连续标点适当压缩

5. 导航系统

组件功能
侧边栏目录全书章节目录,点击跳转,高亮当前章节
章节内导航章节内小节目录,滚动高亮
上/下章导航页面底部的前后章节链接
滚动进度条页面顶部的阅读进度指示条
返回顶部滚动后出现的返回顶部按钮

6. EPUB生成规格

输出符合 EPUB 3.x 标准的 .epub 文件(向下兼容 EPUB 2 NCX)。

EPUB 内部结构

{{epub文件名}}.epub  (ZIP归档)
├── mimetype                      # 必须第一个写入,不压缩
├── META-INF/
│   └── container.xml             # 指向 OPF 包文档
└── OEBPS/
    ├── content.opf               # 包文档(元数据 + 清单 + 书脊)
    ├── nav.xhtml                 # EPUB 3 导航文档(目录)
    ├── toc.ncx                   # EPUB 2 兼容目录
    ├── cover.xhtml               # 封面页(书脊第一项)
    ├── style.css                 # 统一样式表
    ├── ch01.xhtml                # 第1章(XHTML格式)
    ├── ch02.xhtml                # 第2章
    ├── ...
    └── images/
        └── cover.svg             # 自动生成的SVG封面图

Mermaid 图表处理(EPUB 特殊要求)

EPUB 阅读器普遍不支持 JavaScript,因此 Mermaid 图表必须在构建时预渲染为 PNG

情境处理方式
系统已安装 mmdc(Mermaid CLI)输出 .png(非 .svg)——Chromium 光栅化时 CSS 完全正确,无需任何后处理(见坑 1)
未安装 mmdc将 Mermaid 代码块以 <pre class="mermaid-source"> 形式保留,并添加提示注释

建议:如需生成 EPUB,提前全局安装 npm install -g @mermaid-js/mermaid-cli

⚠️ 为什么用 PNG 而非 SVG:Mermaid 将节点文字渲染为 SVG <foreignObject> 内的 HTML。每款 EPUB 阅读器对 <foreignObject> 内 CSS 的处理方式各不相同,导致颜色不可控。PNG 由 Chromium 光栅化后嵌入,阅读器不再干预,颜色绝对可控——见坑 1。

⚠️ EPUB 构建避坑清单

以下为实践中踩过的坑,构建脚本实现时必须规避

坑 1:Mermaid 文字不可见或对比度极低

根因:Mermaid 将节点/边标签渲染为 SVG <foreignObject> 内的 HTML(<div>/<span>/<p>)。每款 EPUB 阅读器对 <foreignObject> 内 CSS 的处理方式各不相同——部分阅读器忽略 SVG <style> 块的选择器,部分阅读器用自己的 CSS 覆盖,深色模式下文字可能变为白色。这是阅读器行为差异,无论怎么调整 Mermaid theme 或 themeVariables 都无法根治。

修复:输出 PNG(而非 SVG)。mmdc 直接以 .png 为输出后缀即可触发 Chromium 光栅化——此时 CSS 完全正确、foreignObject 内的文字颜色由 Chromium 决定,与 EPUB 阅读器无关。

js
// ✓ 正确:输出 PNG,Chromium 光栅化,颜色完全可控
execSync(
  `mmdc -i "${inFile}" -o "${outFile}.png" -c "${cfgFile}"` +
  ` --backgroundColor "${THEME.pageBg}" --scale 2 --quiet`
);
// 保存到 EPUB images/ 目录,以 <img> 标签嵌入
fs.copyFileSync(`${outFile}.png`, path.join(IMAGES, imgName));
result.push(`<div class="diagram"><img src="images/${imgName}" alt="Diagram" /></div>`);

// ✗ 错误:输出 SVG,阅读器对 <foreignObject> 内 HTML 的 CSS 处理不一致
execSync(`mmdc -i "${inFile}" -o "${outFile}.svg" ...`);
result.push(`<div class="diagram">${svgContent}</div>`);

同时仍建议使用 theme: 'base' + 完整 themeVariables 保障节点填充色/边框色(避免根因二:theme:'default' 被 headless Chrome 暗色模式覆盖):

js
fs.writeFileSync(cfgFile, JSON.stringify({
  theme: 'base',
  themeVariables: {
    background:           THEME.pageBg,
    primaryColor:         '#C8E6FA',   primaryTextColor:   '#111111',
    primaryBorderColor:   '#2B7BC2',
    secondaryColor:       '#D4EDDA',   secondaryTextColor: '#111111',
    tertiaryColor:        '#FFF3CD',   tertiaryTextColor:  '#111111',
    lineColor:            '#444444',
    actorBkg:             '#C8E6FA',   actorTextColor:     '#111111',
    edgeLabelBackground:  THEME.pageBg,
    clusterBkg:           THEME.pageBg,
    titleColor:           THEME.textColor,
    fontSize:             '16px',
  },
}), 'utf8');

坑 2:SVG 内 <br /> 被破坏为 <br / />(无效 XML)

  • 现象:EPUB 阅读器报 XML 解析错误 "error parsing attribute name"
  • 根因:对 HTML 做 void 元素自闭合转换时,正则 (\s[^>]*) 贪婪地把 <br /> 的尾部 / 纳入 attrs,再追加 /> 后变成 <br / />(非法 XML)。Mermaid SVG 的 <foreignObject> 内含有 <br />,因此受影响
  • 修复:正则末尾改为 \/?>,替换函数中用 .replace(/\s*\/$/, '') 剥离 attrs 末尾多余斜杠
js
// ✗ 错误:<br /> 会被转成 <br / />
.replace(/<(br|hr|img|...)(\s[^>]*)?\s*(?!\/)>/gi,
  (_, tag, attrs) => `<${tag}${attrs || ''} />`)

// ✓ 正确:stripping trailing slash prevents double-slash
.replace(/<(br|hr|img|...)(\s[^>]*)?\s*\/?>/gi,
  (_, tag, attrs) => `<${tag}${(attrs || '').replace(/\s*\/$/, '')} />`)

坑 3:EPUB CSS 不支持 overflow-x: auto

  • 现象:表格和图表内容超出页面宽度溢出,不出现横向滚动条
  • 根因:EPUB 阅读器(Apple Books、Kindle 等)不支持 overflow-x 属性
  • 修复:对表格单元格使用 word-break: break-word; overflow-wrap: break-wordpre 块改用 white-space: pre-wrap; word-break: break-all;移除所有 overflow-x: auto

坑 4:表格单元格缺少 vertical-align: top

  • 现象:多行内容的单元格文字垂直居中,布局错乱
  • 修复th, td 必须设置 vertical-align: top
css
/* ✓ EPUB 表格推荐 CSS */
table { border-collapse: collapse; width: 100%; font-size: 0.88em; table-layout: auto; }
th, td { border: 1px solid #D8D2C8; padding: 0.5em 0.8em;
         word-break: break-word; overflow-wrap: break-word; vertical-align: top; }
th { background-color: #F5F2ED; font-weight: bold; }
td code { word-break: break-all; }
pre { white-space: pre-wrap; word-break: break-all; }

坑 5:代码块语法高亮颜色在 EPUB 中失效

  • 现象:CSS 类名方式的高亮(如 .hljs-keyword { color: purple; })在部分阅读器中不生效,代码块颜色全部丢失
  • 根因:EPUB 阅读器对外部样式表的支持参差不齐,class-based 语法高亮依赖样式表,在某些阅读器中被完全忽略
  • 修复:用 Puppeteer 在 Chromium 中运行 highlight.js,调用 getComputedStyle 将颜色提取为内联 style="color:rgb(…)" 属性,嵌入每个 token <span>——内联样式不依赖外部 CSS,在所有阅读器中均有效
js
// ✓ 正确:内联样式,阅读器无法忽略
hljs.highlightElement(el);
el.querySelectorAll('[class]').forEach(span => {
  const cs = window.getComputedStyle(span);
  let s = '';
  if (cs.color)                         s += 'color:' + cs.color + ';';
  if (cs.fontStyle !== 'normal')        s += 'font-style:' + cs.fontStyle + ';';
  if (cs.fontWeight !== '400')          s += 'font-weight:' + cs.fontWeight + ';';
  if (s) span.setAttribute('style', s);
  span.removeAttribute('class');   // 移除 class,只保留 inline style
});

// ✗ 错误:class-based,依赖外部 .hljs-keyword { } 样式表
// 在 Apple Books、Kindle 等阅读器中颜色可能全部消失

💡 同理,为什么 PNG 模式(RENDER_CODE_AS_PNG=true)虽然视觉更漂亮,但技术书不推荐:PNG 中的代码不可复制、不可搜索,对读者不友好。

  • 使用 Node.js 生成所有 XHTML 章节文件及 OPF/NCX/NAV 文档

  • 调用系统 zip 命令打包(macOS/Linux 内置;Windows 需 WSL 或 Git Bash):

    bash
    # 先写入 mimetype(不压缩),再添加其余文件
    zip -X {{epub文件名}}.epub mimetype
    zip -rg {{epub文件名}}.epub META-INF/ OEBPS/
  • 最终产物:output/publish/.epub

EPUB 章节标题规范

位置要求
每章 <title>提取该章 Markdown 文件中第一个 # 标题作为 XHTML 的 <title> 标签内容
nav.xhtml 导航条目使用提取到的章节标题,而非文件名(ch01ch02…)
toc.ncx navPoint每个 <navLabel><text> 填写真实章节标题
content.opf manifest<item>id 属性可用文件名,但书脊顺序须与大纲一致

构建脚本应以正则 /^#\s+(.+)/m 从每个 Markdown 文件头部提取标题;若未找到 # 标题,则回退到使用大纲(outline.md)中对应章节的标题。

EPUB 封面规格

封面由构建脚本自动生成,无需外部图片资源:

要素规格
格式SVG(1400×2100 px,标准 2:3 书籍比例)
文件路径OEBPS/images/cover.svg
封面页OEBPS/cover.xhtml(书脊第一项,properties="svg" 可选)
OPF 声明<meta name="cover" content="cover-image"/>(EPUB 2 兼容) + properties="cover-image" 属性(EPUB 3)
内容元素书名()、作者(,如填写)、装饰性背景图形、当前配色主题
字体标题使用衬线体,作者名使用无衬线体

封面 SVG 模板结构(伪代码):

xml
<svg width="1400" height="2100" xmlns="http://www.w3.org/2000/svg">
  <!-- 背景 -->
  <rect width="1400" height="2100" fill="{{背景色}}"/>
  <!-- 装饰色块(使用当前主题强调色) -->
  <rect y="0" width="1400" height="420" fill="{{强调色}}" opacity="0.85"/>
  <!-- 书名 -->
  <text x="700" y="280" text-anchor="middle" font-size="80"
        font-family="serif" fill="white">{{项目名称}}</text>
  <!-- 作者(可选) -->
  <text x="700" y="1980" text-anchor="middle" font-size="48"
        font-family="sans-serif" fill="{{正文色}}">{{作者名称}}</text>
</svg>

EPUB 元数据(content.opf)

字段来源
dc:title
dc:language(如 zh-CNen
dc:identifier自动生成 UUID
dc:creator(可选)
dc:date构建时自动填写

SVG配色方案

用于ASCII图表转SVG时的卡片/节点配色:

序号名称背景色边框色用途
1柔蓝主要节点
2薄荷绿次要节点
3暖杏强调节点
4玫粉警告/注意
5淡紫引用/参考
6天青数据/输入
7鹅黄输出/结果
8蜜橙特殊标记

设计规范

页面布局

┌──────────────────────────────────────────┐
│ 📖 {{项目名称}}              [进度条===] │
├──────────┬───────────────────────────────┤
│ 目录导航 │ 正文区域                       │
│          │                               │
│ 第1章    │  # 章节标题                    │
│ 第2章 ◄──│                               │
│   2.1    │  正文内容...                   │
│   2.2    │                               │
│ 第3章    │  ```代码块```                  │
│ ...      │                               │
│          │  [SVG图表]                     │
│          │                               │
│          │  ◄ 上一章    下一章 ►          │
└──────────┴───────────────────────────────┘

构建工具要求

工具必需安装方式作用
Node.js ≥ 18✅ 必需系统安装核心构建引擎;无需任何 npm 包
zip✅ 必需macOS/Linux 内置;Windows 用 WSLEPUB 打包
mmdc(Mermaid CLI)⚪ 可选npm install -g @mermaid-js/mermaid-cliMermaid 图表 → PNG
Puppeteer⚪ 可选mmdc 附带,无需单独安装代码块语法高亮
highlight.js⚪ 可选CDN 自动加载(需联网)高亮引擎,提取 inline styles

渐进增强:无任何可选工具时,EPUB 正常生成,只是 Mermaid 以代码形式保留、代码块无颜色。

质量标准

  • [ ] 所有 ```mermaid 块已通过 Mermaid.js 正确渲染
  • [ ] 所有Markdown章节正确转换为HTML
  • [ ] ASCII图表全部转换为SVG(无遗漏)
  • [ ] 代码块正确高亮(EPUB模式:内联 inline-styled HTML,颜色不依赖外部 CSS)
  • [ ] 护眼配色方案正确应用
  • [ ] CJK排版规范(衬线标题 + 无衬线正文)
  • [ ] 导航系统功能完整
  • [ ] 响应式布局(适配桌面和平板)
  • [ ] 构建脚本核心无npm依赖(Node.js + 系统zip即可运行)
  • [ ] (EPUB模式).epub 已生成并通过 EPUB 3.x 合规性检查
  • [ ] (EPUB模式)所有章节已转换为有效 XHTML
  • [ ] (EPUB模式)content.opfnav.xhtmltoc.ncx 均正确生成
  • [ ] (EPUB模式)每章 XHTML 的 <title> 与 nav/ncx 条目均使用真实章节标题(非文件名)
  • [ ] (EPUB模式)封面 SVG(cover.svg)已生成,cover.xhtml 为书脊第一项
  • [ ] (EPUB模式)Mermaid 图表已预渲染为 PNG-o diagram.png)并以 <img> 嵌入,或以代码形式优雅降级
  • [ ] (EPUB模式)代码块已通过 Puppeteer + highlight.js 批量渲染为内联样式 HTML,或优雅降级为纯 <pre><code>

配色主题选择(Phase 5 启动前必询问)

在开始装帧工作之前,主编排必须依次询问用户以下两个问题

第一步:选择输出格式

Phase 5 即将开始。请选择输出格式:

① HTML(默认)— 多页HTML电子书,支持浏览器在线阅读,Mermaid 交互渲染
② EPUB          — 标准 EPUB 3.x 文件,适用于 Kindle、Apple Books、Kobo 等阅读器
③ 两者都要      — 同时生成 HTML 和 EPUB

(默认选 ①,若用户说"继续"或"默认"则生成 HTML)

⚠️ 若选择 ② 或 ③,提示用户确认是否已安装 mmdcnpm install -g @mermaid-js/mermaid-cli),以便 Mermaid 图表在 EPUB 中正确预渲染为 PNG

第二步:选择配色方案

请选择配色方案:

① Warm Paper(默认)— 暖白底色 #FEFCF8,柔和深棕文字,仿纸质书感
② GitHub Light    — 纯白背景,标准深灰文字,简洁科技感
③ Dark Mode       — 深色背景 #1E1E2E,浅色文字,护眼夜间模式
④ Minimal         — 纯白背景,纯黑文字,极简无装饰风格

(默认选 ①,若用户说"继续"或"默认"则使用 Warm Paper)

收到用户选择后,将对应配置写入 scripts/build.jsTHEMEOUTPUT_FORMAT 配置块,然后运行:

bash
node scripts/build.js

输出产物位于 output/publish/


html
<!-- BOOKBINDING_COMPLETE -->

调度模板概要

你是一位精通排版设计的电子书工匠。

## 任务
将所有Markdown章节转换为美观的电子书(HTML 和/或 EPUB,取决于用户选择)。

## 输入
- 定稿章节:{{工作目录}}/output/chapters/final/*.md
- 大纲(目录结构):{{工作目录}}/output/memory/outline.md

## 输出
- HTML文件(HTML模式):{{工作目录}}/output/publish/*.html
- EPUB文件(EPUB模式):{{工作目录}}/output/publish/{{epub文件名}}.epub
- 构建脚本:{{工作目录}}/build.js

## 要求
0. 在开始生成前,**依次询问用户**:
   a) 输出格式:① HTML(默认)② EPUB ③ 两者都要
   b) 配色方案:① Warm Paper(默认)② GitHub Light ③ Dark Mode ④ Minimal
   根据选择,在构建脚本中配置对应 OUTPUT_FORMAT 和 THEME 变量
1. Markdown → HTML/XHTML转换
2. **Mermaid 图表渲染**:
   - HTML模式:` ```mermaid ` 块通过引入 Mermaid.js(CDN)渲染为交互式图表
   - EPUB模式:调用 `mmdc` 输出 **PNG**(`-o diagram.png`)并以 `<img>` 嵌入;PNG 由 Chromium 光栅化,颜色完全可控,不受阅读器 CSS 干预(见坑 1);未安装 mmdc 时优雅降级为代码块
3. ASCII图表 → SVG自动转换(兼容存量内容,支持{{SVG检测类型数}}种类型)
4. **代码高亮**(EPUB模式):
   - 通过 Puppeteer(mmdc 附带)+ highlight.js(CDN)批量渲染,提取 inline `style="color:rgb(…)"` 属性
   - **文字可选中、可复制、可搜索**——技术书必须保留这一特性(见坑 5)
   - 全书共用一个 Chrome 会话(摊薄启动开销)
   - 未安装 mmdc / 无网络时优雅降级为纯 `<pre><code>`
5. 护眼配色(暖白背景、柔和文字)
6. CJK排版(衬线标题、无衬线正文)
7. 导航系统(侧边栏、章节导航、进度条)—— HTML模式
8. EPUB 3.x 结构(OPF + NAV + NCX + XHTML章节)—— EPUB模式,系统 zip 命令打包
9. EPUB CSS 规范:`th,td` 必须有 `word-break:break-word; vertical-align:top`;禁止 `overflow-x:auto`;`pre` 用 `white-space:pre-wrap`
10. HTML→XHTML void 元素转换:正则必须正确处理 `<br />`,避免生成 `<br / />`(无效XML)—— 用 `.replace(/\s*\/$/, '')` 剥离 attrs 末尾斜杠
11. 零npm依赖的Node.js构建脚本
12. 完成后添加 <!-- BOOKBINDING_COMPLETE -->

项目配置变量

变量说明默认值建议
书名/项目名(显示在导航栏)
页面背景色#FEFCF8
正文文字色#2C2C2C
标题文字色#1A1A1A
代码块背景色#F5F2ED
链接颜色#4A7C9B
强调标记色#C7553A
~ SVG卡片背景色8色柔和色板
~ SVG卡片边框色对应加深色
支持的ASCII图表检测类型数8
产出物根目录
EPUB元数据语言标识(dc:languagezh-CN
EPUB元数据作者(dc:creator,可选)
EPUB输出文件名(不含扩展名),默认以书名自动生成书名去除特殊字符后的结果

Built with Meridian