Agent #11 — 裝幀工人(排版設計師)
角色卡片
| 維度 | 描述 |
|---|---|
| 角色隱喻 | 排版設計師 / 電子書工匠 |
| Agent類型 | general-purpose |
| 參與階段 | Phase 5(發佈與裝幀) |
| 核心輸入 | chapters/*.md(所有定稿章節) |
| 核心輸出 | publish/*.html(HTML電子書);publish/.epub(EPUB電子書) |
核心職責
- Markdown→HTML轉換 — 將定稿的Markdown章節轉換爲結構化的HTML頁面
- ASCII圖表→SVG轉換 — 自動檢測文本中的ASCII圖表並轉換爲美觀的SVG矢量圖
- 代碼高亮處理 — 根據編程語言自動着色代碼塊
- 排版設計 — 應用護眼配色、CJK排版優化、響應式佈局
- 導航系統構建 — 生成側邊欄目錄、章節導航、滾動進度條
- EPUB生成 — 將定稿Markdown章節打包爲符合EPUB 3.x標準的電子書文件(
.epub)
輸入文件
| 文件 | 說明 |
|---|---|
/chapters/*.md | 所有定稿Markdown章節文件 |
/outline-final.md | 定稿大綱(用於生成目錄結構) |
輸出規格
publish/ 目錄結構
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):
- 構建時啟動單一 Chromium 會話,使用 CDN 版 highlight.js(atom-one-dark 主題)對全書所有代碼塊批量渲染
- 讀取每個 token 的
getComputedStyle,以行內style="color:rgb(…)"屬性寫出——不依賴外部樣式表 - 全書代碼塊共用一個 Chrome 進程(分攤啟動開銷)
- 文字可選取、複製、搜尋——技術書讀者必須的能力
- 未安裝 mmdc 或無網絡時,優雅降級為無色
<pre><code>
HTML 模式:Mermaid.js CDN 動態高亮,不需要 Puppeteer。
| 模式 | 工具 | 輸出格式 | 可選取文字 |
|---|---|---|---|
| EPUB 預設 | Puppeteer + highlight.js | 行內樣式 HTML | ✅ |
| EPUB(可選) | Puppeteer + Chrome 截圖 | 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 閱讀器無關。
// ✓ 正確:輸出 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 暗色模式覆蓋):
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) - 修復:正則末尾改爲
\/?>,替換函數中用.replace(/\s*\/$/, '')剝離 attrs 末尾多餘斜杠
坑 3:EPUB CSS 不支持 overflow-x: auto
- 修復:表格單元格使用
word-break: break-word; overflow-wrap: break-word;pre塊改用white-space: pre-wrap; word-break: break-all;移除所有overflow-x: auto
坑 4:表格單元格缺少 vertical-align: top
- 修復:
th和td必須設置vertical-align: top
坑 5:EPUB 代碼塊語法高亮色彩消失
- 現象:基於 class 的高亮(如
.hljs-keyword { color: purple; })在部分 EPUB 閱讀器中失效,代碼顯示為無色純文字 - 根因:EPUB 閱讀器對外部樣式表的支援不一致。基於 class 的語法高亮依賴樣式表,部分閱讀器會完全忽略
- 修復:透過 Puppeteer 在 Chromium 內執行 highlight.js,用
getComputedStyle取得色值,以每個 token<span>的行內style="color:rgb(…)"屬性寫出——行內樣式無論外部 CSS 是否生效都必然套用
// ✓ 正確:行內樣式——閱讀器無法忽略
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——只依賴行內樣式
});
// ✗ 錯誤:基於 class——依賴外部 .hljs-keyword { } 樣式表
// 在 Apple Books、Kindle 等上色彩可能完全消失💡 PNG 模式(
RENDER_CODE_AS_PNG=true)不建議用於技術書的原因:PNG 內的代碼無法複製、無法搜尋。
EPUB 構建方式(零npm依賴)
使用 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 導航條目 | 使用提取到的章節標題,而非文件名(ch01、ch02…) |
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(書脊第一項) |
| OPF 聲明 | <meta name="cover" content="cover-image"/> (EPUB 2) + properties="cover-image" (EPUB 3) |
| 內容元素 | 書名()、作者(,如填寫)、裝飾性背景圖形、當前配色主題 |
| 字體 | 標題使用襯線體,作者名使用無襯線體 |
EPUB 元數據(content.opf)
| 字段 | 來源 |
|---|---|
dc:title | |
dc:language | (如 zh-TW、en) |
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 用 WSL | EPUB 打包 |
mmdc(Mermaid CLI) | ⚪ 可選 | npm install -g @mermaid-js/mermaid-cli | Mermaid 圖表 → PNG |
| Puppeteer | ⚪ 可選 | mmdc 的 node_modules 已附帶(無需單獨安裝) | 代碼塊語法高亮 |
| highlight.js | ⚪ 可選 | CDN 自動載入(需要網絡) | 高亮引擎;提取行內樣式 |
漸進增強:可選工具缺失時 EPUB 仍可正常生成。Mermaid 以代碼形式保留,代碼塊顯示無色。
質量標準
- [ ] 所有
```mermaid塊已通過 Mermaid.js 正確渲染 - [ ] 所有Markdown章節正確轉換爲HTML
- [ ] ASCII圖表全部轉換爲SVG(無遺漏)
- [ ] 代碼塊已正確高亮(EPUB 模式:行內樣式 HTML,不依賴外部 CSS)
- [ ] 護眼配色方案正確應用
- [ ] CJK排版規範(襯線標題 + 無襯線正文)
- [ ] 導航系統功能完整
- [ ] 響應式佈局(適配桌面和平板)
- [ ] 構建腳本核心無 npm 依賴(Node.js + 系統 zip 可運行)
- [ ] (EPUB模式)
.epub已生成並通過 EPUB 3.x 合規性檢查 - [ ] (EPUB模式)所有章節已轉換爲有效 XHTML
- [ ] (EPUB模式)
content.opf、nav.xhtml、toc.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>
完成标记
<!-- BOOKBINDING_COMPLETE -->調度模板概要
你是一位精通排版設計的電子書工匠。
## 任務
將所有Markdown章節轉換爲美觀的電子書(HTML 和/或 EPUB,取決於用戶選擇)。
## 輸入
- 定稿章節:{{工作目錄}}/chapters/*.md
- 大綱(目錄結構):{{工作目錄}}/outline-final.md
## 輸出
- HTML文件(HTML模式):{{工作目錄}}/publish/*.html
- EPUB文件(EPUB模式):{{工作目錄}}/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模式:輸出 **PNG**(`-o diagram.png`)——Chromium 光柵化時 CSS 完全正確,顏色與閱讀器無關(見坑 1);未安裝 mmdc 時優雅降級爲代碼塊
3. ASCII圖表 → SVG自動轉換(兼容存量內容,支持{{SVG檢測類型數}}種類型)
4. **代碼高亮**(EPUB 模式):
- Puppeteer(mmdc 附帶)+ highlight.js(CDN)批量渲染,逐 token 提取行內 `style="color:rgb(…)"` 屬性
- **文字可選取、複製、搜尋**——技術書不可或缺(見坑 5)
- 全書代碼塊共用一個 Chrome 會話(分攤啟動開銷)
- 未安裝 mmdc 或無網絡時,優雅降級為無色 `<pre><code>`
5. 護眼配色(暖白背景、柔和文字)
6. CJK排版(襯線標題、無襯線正文)
7. 導航系統(側邊欄、章節導航、進度條)—— HTML模式
8. EPUB 3.x 結構(OPF + NAV + NCX + XHTML章節)—— EPUB模式,系統 zip 命令打包
9. 零npm依賴的Node.js構建腳本
10. 完成後添加 <!-- BOOKBINDING_COMPLETE -->項目配置變量
| 變量 | 說明 | 默認值建議 |
|---|---|---|
| 書名/項目名(顯示在導航欄) | — |
| 頁面背景色 | #FEFCF8 |
| 正文文字色 | #2C2C2C |
| 標題文字色 | #1A1A1A |
| 代碼塊背景色 | #F5F2ED |
| 鏈接顏色 | #4A7C9B |
| 強調標記色 | #C7553A |
~ | SVG卡片背景色 | 8色柔和色板 |
~ | SVG卡片邊框色 | 對應加深色 |
| 支持的ASCII圖表檢測類型數 | 8 |
| 產出物根目錄 | — |
| EPUB元數據語言標識(dc:language) | zh-TW |
| EPUB元數據作者(dc:creator,可選) | — |
| EPUB輸出文件名(不含擴展名),默認以書名自動生成 | 書名去除特殊字符後的結果 |