这是本节的多页打印视图。 .
设计提案与 PRD
- 1: 反向链接与知识图谱
- 2: 媒体收敛
- 3: Agent 批量索引
- 4: Book 出版链路
提案描述的行为可能尚不存在。当前行为由契约、已接受决策、实现与归属检查器定义。不能把提案 当作配置参考。
本栏目是 OINK 产品需求文档、RFC 风格设计与未决维护者提案的唯一正本位置。不要在主题仓库或
文档仓库中另建本地 plan/、plans/、proposal/ 或其它并行设计树。
当前提案
| 提案 | 当前边界 |
|---|---|
| 反向链接与知识图谱 | G1(静态反向链接)已接受,已在主题 main 分支实现,随 OINK 0.8.0 发布;局部与全站图谱(G2/G3)保持草案 |
| 媒体收敛 | 部分已实现;media-result 契约与 Landing 资源元数据已交付,M3 决议为原生图片处理,退役(M4)保持开放 |
| Agent 批量索引 | 已接受(2026-08-27);两类输出都已在主题 main 分支实现,随 OINK 0.8.0 发布,之后本提案退役 |
| Book 出版链路 | manifest 与 EPUB/PDF 工具已随版本发布,见架构;本页只剩消费站迁移未决 |
生成式配置 Schema 提案已按生命周期退役:行为的规范位置是配置总览, 长期理由进入生成式配置 Schema 决策,草案原文由 Git 历史保存。
新 PRD 放在哪里
创建一份英文主页面及其简体中文对页:
两份文件都使用显式、稳定的英文标题 ID。中文页面中的代码、键、路径、版本与 API 名称保持原样。 提案开头要有可见的草案状态,并包含:
- 状态、负责人、日期和受影响契约面;
- 背景与证据;
- 目标与明确非目标;
- 提议行为,以及输出、无障碍、安全边界;
- 兼容与迁移影响;
- 实现与归属检查器计划;
- 验收标准与待决问题;
- 记录提案自身变化的决策日志。
大型实验可以在 ../research/ 下增加带日期的页面;临时日志与生成
产物不进入 Hugo 内容,也不进入 Git。
生命周期
提案被接受后不会自动成为第二份契约。稳定行为进入归属契约,稳定理由进入 Decisions,用户步骤进入 相关指南,然后把提案退出活动导航。本地构建、提交、tag、公开模块、消费站 pin 与部署仍是相互独立 的完成状态。
评审门禁
实施前,评审者确认提案没有重复已有外壳、resolver、组件族或数据权威。实施期间,如果设计改变, 先更新这份双语提案,不能让代码悄悄漂移。验收至少覆盖主题的最窄归属检查、真实文档站、渲染后的 中英文、相关输出、无障碍与响应式检查。
1 - 反向链接与知识图谱
2026-08-27 决议 G1 的全部待决问题并接受 G1(静态反向链接)。它已在主题 main 分支实现,随 OINK 0.8.0 发布。局部与全站图谱(G2/G3)保持草案状态,等待 G1 的 真实使用证据;它们的名称和配置在被接受之前不是公开 API。
前提
反向导航与页面连接视图是链接图的属性,不是 [[wikilink]] 拼写的属性。Hugo 已经接受普通
Markdown 链接和 ref / relref。OINK 可以从作者已经在写的内容中派生图谱,无需增加解析器、
Goldmark 扩展或并行创作语法。
首要价值是反向链接,而不是可视化。静态入链列表不需要 JavaScript,在 Print 与 Markdown 中也能 降级。交互图谱应当只是完整列表之上的可选增强。
目标与非目标
目标:
- 每次构建为每种语言派生一份链接索引;
- 在页面上显示确定性的入链;
- 可选显示有界的局部邻接图;
- 可选发布全站视图与机器可读图数据;
- 编辑链接暂时陈旧或不完整时,普通预览仍然可用。
非目标:
- 引入
[[wikilink]]语法; - 索引外链、
mailto:、同页锚点或自链接; - 用 JavaScript 发现正文中已经存在的链接;
- 把可视化变成唯一导航方式;
- 承诺从任意 shortcode 参数或原始 HTML 中完整提取语义图。
交付阶段
| 阶段 | 交付物 | 运行时 | 独立价值 |
|---|---|---|---|
| G1 | 语言内链接索引与反向链接列表 | 无 | HTML、Print、Markdown 中的反向导航 |
| G2 | 当前页面周围的局部图谱 | 既有 ECharts 加一个小型本地运行时 | 以 G1 为无障碍兜底的空间视图 |
| G3 | 全站图谱页与图数据输出 | 同一运行时 | 全站探索与机器可读边 |
每个阶段单独验收。G1 不等待 G2,G2 也不会强迫每一页加载图谱代码。
提取契约
提议的索引按语言扫描源码一次,每对来源与目标只记录一条边。它先剥离代码围栏和行内代码,再提取
普通 Markdown 链接与 ref / relref;随后只解析站内页面,去掉 fragment 以确定页面身份,
排除自链接,并合并重复引用。
实现至少要测试:
- 同一目标的重复链接合并为一条边;
- 围栏与行内代码不产生边;
- 外链、protocol-relative URL、邮件、同页锚点与自链接被排除;
ref与relref被纳入;- 每种语言生成相互独立的图;
- 无法解析的派生边由警告或专项检查报告,但不会让普通
hugo server不可用。
扫描原始源码存在已知遗漏。自定义 shortcode 参数或原始 <a href> 中的 URL 可能不会进入图谱。
必须明确记录这种遗漏,不能声称得到完整语义图。
反向链接输出
G1 在右栏输出一个 aside 组,与目录、分类标签云并列:目录讲这一页写了什么,反向链接
讲哪些页面指向这一页。该组默认展开,先显示前八条,其余折进原生 disclosure,避免被
大量引用的页面把右栏撑满。开关是站点键 params.ui.backlinks(裸布尔,默认关闭),页面用同名去前缀的
front matter 键 backlinks 覆盖,section 可以 cascade。排序必须确定:按稳定页面路径
排序——它与语言无关、与导航自然同组,且不需要第二个排序权威。该组使用普通链接;没有
入链时不渲染。
无法解析的派生边被静默丢弃并作为已知遗漏记录在案:G1 是本地导航增强,不是链接检查器, 让它替站点报告断链只会制造重复告警。
Print 与 Markdown 保留可读列表。除非后续 feed 研究证明反向链接能改善文章订阅而不是制造站点导航 噪音,否则 RSS 省略它。
交互图谱边界
G2 复用本地内置的 ECharts graph series。当前页面是中心,直接入链与出链邻居组成默认深度。硬性 节点上限防止视图不可读或成本失控。键盘焦点、文字替代、reduced motion、forced colors、窄屏和 Print 都是验收要求,不是后续润色。
JavaScript 或 ECharts 不可用时,G1 仍然完整可见。运行时只在真正渲染图谱的页面加载,并进入既有 feature bundle key,避免不同特性页面在资产缓存中撞车。
全站输出
G3 可以新增专用图谱页与 opt-in JSON 输出。JSON schema 包含版本、语言、节点和带稳定 URL 的有向边, 不暴露本机文件路径或未发布页面。它必须和 G1、G2 使用同一索引,避免三种表示各自漂移。
兼容与迁移
普通 Markdown 写法不变,因此无需内容迁移。配置名称继续待定,直到原型证明最小公开面。所有交互 与全站输出默认关闭;静态反向链接列表可以单独讨论,因为它只是本地导航,不涉及网络与浏览器状态。
验收标准
验收需要专项 graph 检查器、提取夹具、HTML/Print/Markdown golden、严格构建负向用例、浏览器无障碍 与响应式测试,以及真实双语站构建。性能在有代表性的大站上测量,但带日期的原型耗时不能自动成为 永久预算。
待决问题
G1 的问题已全部决议(见决策日志)。仍然开放、属于 G2/G3 的问题:
- 局部图只暴露一层,还是允许严格限额的第二层?
- 哪些页面元数据值得进入 graph JSON?
- 在 G1、G2 获得生产证据前,G3 是否值得新增输出格式?
决策日志
- 2026-08-19:起草三阶段设计。
- 2026-08-27:决议 G1 并接受,排入 OINK 0.8.0。G1 是 opt-in:站点键
params.ui.backlinks裸布尔默认关闭,页面覆盖键backlinks,不按 shell type 区分——策略归站点与页面,不归外壳。排序简化为稳定页面路径单键排序,删去 「section → weight → 标题」的三级链:单一确定性权威已经满足反向导航,多级排序 等于第二个导航权威。无法解析的边静默丢弃并记录为已知遗漏,不产生告警。 G2/G3 与图数据输出继续等待生产证据。 - 2026-08-27:设计评审把这一块从页尾移到右栏。反向链接是页面元数据,与目录成对; 页尾是读者的收尾区——分享、反馈、出处、翻页、评论。右栏这一组同时引入八条上限, 其余收进原生 disclosure。
2 - 媒体收敛
M1(共享 media-result 契约)与 M2(Landing 资源元数据)已在主题 main 分支实现;
M3 已决议为方案 2:图片处理只属于原生 Markdown 图片形态,完整 fig 源形态保持
容器语义,其参数表刻意不含 command/options。M4(兼容退役)在完成消费方盘点
之前保持开放。以下各节为原始设计记录。
当前基线
正文图片钩子、编号 fig、卡片与 gallery 统一通过 content/image-resolve.html 解析页面资源、
section 资源、全局资产、static 文件与显式远程 URL。栅格资源可以提供固有尺寸与处理后派生图。
HTML Zoom 资格使用 data-td-image-zoom 标记;构建期检测只查找主题自己输出的标记。
独占 Markdown 图片已经可以把题注或 Book 编号与图片处理、链接组合起来。编号图片 figure 共用
td-figure 与 td-book-figure 语义。Landing 媒体经过共享 URL 信任策略;代表图片则刻意使用
排序 resolver,因为它的职责是选择代表图片,而不是渲染一个显式来源。
剩余问题
共享安全边界已经比共享媒体模型更成熟。Landing 媒体仍然拿不到与正文图片相同的页面资源元数据和
处理结果;代表图片选择与显式图片解析返回不同结果形状;部分兼容 class 仍保留在标记中;Book 的
全量 fig 形态也不能表达原生图片钩子的所有处理选项。
因此问题已经不再是“替换七种图片入口”,而是:能否在不抹掉各自语义差异的前提下,让剩余表面共享 一份小型结果契约。
目标与非目标
目标:
- 为 URL、原始 URL、尺寸、替代文字、署名、可处理状态与外部状态定义一个规范化媒体结果形状;
- 在来源语义重合处,让显式正文图片、Landing 媒体与代表图片复用这个形状;
- 继续让 figure 标记与 Zoom 资格分别只有一个归属实现;
- 决定全量
fig是否需要处理能力,还是要求处理过的编号图使用原生图片形态; - 只有在完成消费站证据与 release note 后才退役兼容标记。
非目标:
- 增加第三方 lightbox 或远程图片服务;
- 意外把 image Zoom 从 opt-in 改成站点政策;
- 给 gallery 新增题注、序列或轮播模型;
- 把表格、公式、示例等非图片 Book 目标合并进只适用于图片的基类;
- 强迫代表图片排序与显式图片解析完全相同。
提议阶段
M1 — 结果契约
记录正文 resolver 与代表图片 resolver 的返回字段,再把交集提取成一份内部媒体结果契约。代表图片 继续负责来源排序,正文 resolver 继续负责显式来源解析。这是要求字节输出不变的内部重构。
M2 — Landing 资源元数据
允许 Landing 条目中的合格本地资源通过媒体契约解析,获得固有尺寸与相同 URL/安全结论。Landing 数据中显式给出的宽高继续优先。远程与 static 来源仍然合法,但不能伪装成拥有可处理资源元数据。
M3 — 全量 figure 能力决策
从两个答案中明确选择一个:
- 为全量
fig的来源形态增加处理参数,并通过同一处理 helper 规范化;或者 - 处理能力只属于原生 Markdown 图片,把全量
fig明确定义为任意编号块内容的容器。
实现不能让两个答案各完成一半。两种形态的 Markdown/LLMS 输出必须一致地链接到文档规定的原图 或派生图。
M4 — 兼容标记退役
移除旧图片元素 class 或属性之前,先盘点下游 CSS 与 JavaScript。兼容名称仍被使用时,要么保留一个 明确的版本窗口,要么在同一 release train 中迁移归属站点。
安全、输出与无障碍
- 图片 URL 继续遵守共享 scheme 与远程主机策略。
- 缺少必需替代文字时发出警告,且只在现行契约允许处渲染装饰性回退。
- 宽高不能声称 SVG、static 文件或远程来源没有提供的元数据。
- 带链接的图片不是 Zoom 目标;运行时保留 dialog 焦点、键盘关闭、reduced motion 与窄屏约束。
- Print、Markdown、RSS 与 LLMS 去掉交互标记,同时保留目标图片、题注、署名、编号与链接。
验收标准
每个阶段分别拥有 HTML 与 Markdown 字节级证据、正文与 Landing resolver 测试、URL/安全检查、图片处理 测试、Book 目标、gallery/Zoom 浏览器测试,以及真实站中英文窄屏审查。只有 M3 的能力选择明确后, 提案才能被接受。
待决问题
- 一份共享结果结构是否足够,还是共享更底层的 URL/资源记录会让 resolver 归属更清晰?
- Landing 应消费资源署名,还是只消费尺寸与 URL?
- 原生图片已经能组合编号、题注、链接和处理后,全量
fig处理能力是否仍有真实消费需求? - 哪些输出兼容名称仍被真实消费站使用?
3 - Agent 批量索引
2026-08-27 决议全部待决问题后接受本提案。两类输出——按顶层 section 分包的
LLMSFULL 与语言根下的 NAVJSON 导航树——都已在主题 main 分支实现,随 OINK
0.8.0 发布,之后本提案退役;发布后的行为由架构契约
承担。OINK 已经支持每页 Markdown、语言内 llms.txt、HTML discovery link 与
Copy Markdown;本页只覆盖新增的两类。
当前基线
站点可以为 page 与 section 启用 Hugo 的 Markdown 输出,并为 home 启用生成 llms.txt 的 LLMS
输出。OINK 把 shortcode 渲染成语义化 Markdown,保留源码 URL 和语言内 LLMS 索引发现信息,Copy
Markdown 也读取同一个 alternative output URL。主题声明输出格式,但不强迫站点选择哪些 outputs。
导航已经存在权威链:有显式 data/docs_nav.json 树时使用它,否则使用内容树与 weight。侧栏、
pager 与已声明 section index 共用这一权威。机器导航输出必须从同一棵树派生,不能再造排序。
目标与非目标
目标:
- 为显式启用的顶层 section 可选装配语言内全文包;
- 可选发布带版本的导航 JSON,供 Agent 与外部工具使用;
- 复用人工站点的同一 Markdown 页面渲染器、页面纳入规则与导航权威;
- 所有输出仍通过 Hugo output 配置 opt-in;
- 验证链接、语言隔离、media type 与确定性顺序。
非目标:
- 替换每页 Markdown 或
llms.txt; - 新建
params.oink.*配置树; - 在 Hugo 构建期间抓取生成好的
public/文件; - 嵌入私有源码路径、草稿页面或跨语言回退;
- 承诺一个巨型全文包适合所有模型上下文。
全文包
llms-full.txt 输出拼接每页输出所用的同一份语义化 Markdown。页面之间使用稳定、可见的
分隔符与来源 URL。第 1 版只实现按顶层 section 分包:每个在自身 _index front matter 的
outputs 中显式启用该格式的顶层 section,在语言内得到一个文件。整站单文件形态被推迟,
待真实站点证据表明按 section 分包不够用时再议——巨型单文件既容易超出模型上下文,又会
把所有 section 的更新耦合到一个产物上。
由 Hugo output 配置决定哪些 section 获得该格式,而不是由主题参数决定。主题提供检查器, 报告意图与实际输出不一致,但不能修改站点输出集合。
全文包在 Hugo 内部通过共享页面渲染 partial 组装,不读取 public/ 中的兄弟产物,也不依赖输出
构建顺序。文件大小作为证据报告;任意阈值不能通过警告让 --panicOnWarning 拒绝原本合法的发布。
导航 JSON
导航 JSON 是 home output,与 llms.txt 同级:每种语言在语言根下一个文件。内容包含
schema 版本、语言、根节点与递归有序节点。页面节点包含稳定 ID(语言内 permalink 路径)、
标题、HTML URL、启用时的 Markdown URL、kind 与 children;有 description 时一并携带。
显式外部导航节点只包含标签、URL 与 external kind。
节点不序列化 weight:数组顺序就是契约,weight 是派生顺序的私有机制,公开它会诱导
消费者重新排序。输出遵循渲染侧栏相同的可见性与排序规则,排除 draft、headless resource、
隐藏导航项与当前语言不可用页面,永不序列化本机文件名。
该格式拥有自己的 JSON Schema(schema/nav.v1.schema.json,手工编写的版本化契约产物,
不属于生成式配置 Schema 的漂移门禁)与 golden 夹具,并标记为 notAlternative,避免 Hugo
把它广告为页面级 alternate。
发现信息与输出边界
llms.txt 默认列出已经启用的全文包与导航 JSON——发现信息属于索引文件,这正是它存在的
理由。HTML head 继续发现每页 Markdown 和语言内 LLMS 索引,不把每个批量产物塞进每一页。
shortcode、Landing section、Book 目标与交互组件继续使用当前 Markdown 降级。新输出无权增加组件 HTML、脚本、评论、反馈控件或导航 chrome。
兼容与迁移影响
两种输出都默认关闭,未启用的站点字节不变。启用是站点侧的 Hugo outputs 配置,没有新的
params 键,没有重命名,没有迁移步骤。关闭输出即完全退出,不留残余。
实现与归属检查器计划
- 输出格式:
LLMSFULL(text/plain、baseName: llms-full、notAlternative、 section 级)与NAVJSON(application/json、notAlternative、home 级), 与既有MARKDOWN/LLMS定义并列声明。 - 模板:section 的
llms-full布局复用每页 Markdown 输出的共享渲染 partial 按导航 顺序拼接;home 的导航 JSON 布局走既有导航权威 partial,不引入第二套树遍历。 - 归属检查器:新增
bin/check-agent-indexes.py,在tests/site夹具上验证语言隔离、 链接可解析、顺序与侧栏一致、schema 合规、字节稳定重建,并报告每个包的字节数与页数 (只报告,不设上限门禁)。 - Golden:
check-goldens.py矩阵增加 llms-full 与导航 JSON 夹具。 - 文档:站点新增双语 Agent 索引指南;
llms.txt发现行为并入既有 LLMS 文档; 本提案按生命周期退役。
验收标准
- EN 与 ZH 输出只包含各自语言的页面和 URL。
- 每个列出的 Markdown URL 都存在;每个导航 URL 都可解析,或明确标记为外部节点。
- 同一根下的顺序与渲染侧栏、pager 一致。
- 导航 JSON 通过
schema/nav.v1.schema.json校验。 - 固定 Hugo 版本与输入时,相同源码重建得到字节稳定输出。
- 新格式关闭时,HTML、Markdown、Print、RSS 与 LLMS golden 均无回归。
- 大站夹具能证明按顶层 section 分包,而不是为每个嵌套 section 都生成文件。
决策日志
- 2026-08-20:起草;全文包给出全站与按 section 两种形态,导航 JSON 位置未定。
- 2026-08-27:决议五个待决问题并接受提案。全文包第 1 版只做按顶层 section 分包,
整站单文件推迟到有真实证据;导航 JSON 定为 home output;schema v1 节点元数据取
最小集(稳定 ID、标题、HTML URL、Markdown URL、kind、children、可选 description),
不序列化
weight;llms.txt默认列出已启用的两类产物;检查器只报告体积证据, 不执行任何模型上下文上限。
4 - Book 出版链路
选择启用的 BookManifest、通用 EPUB/PDF runner 与产物校验都已随版本发布,
其规范性描述在架构。没有任何一次构建会自己产出这两种文件。
本提案仍然未决、且只在本提案未决的,是消费站迁移。
背景与证据
OINK 已经负责 Book 导航顺序、编号图表公式示例、交叉引用、整书 Print HTML、标题与 脚注命名空间,以及逐页 Markdown 降级。缺失的是一份机器可读的整书交接产物,供 通用打包器消费。
DDIA 当前保留了一份规模不小的 EPUB 预处理器,持续追踪 OINK 的编号原语、跨页链接、 脚注、图片路径与 Book 顺序。TPME 则留有一份更早的导出脚本,它依赖的历史根目录文件 已经不再匹配当前 Hugo 内容树。前者证明出版需求真实存在,后者证明消费站自有配方会 悄悄过期。
EPUB 不是一份模板渲染结果。它是一个 ZIP 容器,包含出版元数据、资源 manifest、 spine、导航、内容文档、样式与媒体。Hugo 可以渲染中间输出,但最终文件必须由打包工具 生成并校验。
目标
- 让每一种 Book 原语在出版场景中只有一份主题拥有的语义结果。
- 发布选择启用的整书中间产物,确定性记录页面顺序、稳定目标与交叉引用;只在显式打包时 从语义 Print 文档解析本地资源。
- 提供通用、带版本的 EPUB 打包器,以及版本固定的 Print-to-PDF runner;消费站只传入 自己的出版事实。
- 用两个结构不同的公开 Book 消费站证明边界成立。
非目标
- 不为每个站点或分区默认启用昂贵的聚合输出。
- 不把 Markdown、JSON 或 HTML 中间产物称为 EPUB。
- 不猜测书名、作者、封面、ISBN、版本、权利或发布策略。
- 普通 Hugo 构建不抓取远程图片或服务。
- 不增加第二套 Book 外壳、第二个导航权威或通用出版配置命名空间。
- 不承诺不同浏览器引擎产生逐像素相同的 PDF 分页。
所有权边界
| OINK 负责 | 消费站负责 |
|---|---|
| 从现有导航权威导出的 Book 顺序 | 要发布的语言、版本与 Book 根 |
fig、tbl、eq、eg、xref、标题与脚注的语义降级 |
书名、作者、标识符、封面、权利与出版者信息 |
| 稳定中间 schema 与通用打包器行为 | 可选章节排除,以及出版专用的前后置内容 |
| EPUB 结构/链接校验与 Print-to-PDF runner | 发布自动化、签名、分发与法律批准 |
| 主题夹具与兼容检查 | 内容正确性与最终产物批准 |
消费站传递事实,不补丁 OINK 标记;OINK 提供语义,不决定一本书是否可以分发。
提议行为
第一步实现是一份选择启用的 Book manifest,不是最终电子书。它引用已经发布的逐页 Markdown,只记录主题能够诚实推导的事实:
- schema 版本与语言;
- Book 根与拍平后的页面顺序;
- 页面标题、可选 Book 编号、HTML URL 与 Markdown URL;
- 稳定标题目标与编号对象目标;
- 跨页引用。
只有明确启用该输出的 Book 根才生成 manifest。普通 HTML、Print、Markdown、RSS、 搜索与导航构建不受这项 opt-in 影响,保持彼此独立。
OINK EPUB 打包器消费 manifest 与既有整书 Print HTML;后者已经包含命名空间化标题与脚注、 编号目标、作者原始锚点、MathML 与静态交互降级。打包器只改写出版 URL,调用固定版本的 Pandoc 3.10 profile,再用 EPUBCheck 与 OINK 自有内部目标检查器验证。消费站提供一份小型 metadata 文件与封面。逐页 Markdown 仍作为可审计的源码形态输出记录在 manifest 中, 但不成为第二条语义转换路径。
本地资源必须存在于生成的 public/ 树下,默认打包完全不访问网络。如果消费站明确保留了
远程图片,必须显式传入 --allow-remote-resources;它只允许被动 HTTP(S) 媒体,绝不放行
远程脚本或本地文件协议。除非明确传入 --force,工具也不会覆盖已有 EPUB。
PDF 来自同一份整书 Print HTML。Runner 在带 script-src 'none' 的临时回环服务中提供构建产物,
默认阻止外部资源,调用显式指定的 Chrome/Chromium 二进制,并拒绝隐式覆盖。Print CSS 负责 A4 纸张、纸面代码
换行、占满版心的编号公式与页码。Checker 通过 Poppler 校验 PDF 结构、A4 几何、可提取的
Book 标题与抽样页码;最终批准仍包含渲染页面复核。
参考工作流保持四个显式步骤,不增加 Hugo 模式:
输出、无障碍与安全
- HTML 与现有输出不加载 exporter,也不增加浏览器运行时。
- 中间产物保留文档语言、标题层级、替代文本、表头、链接文本与源码顺序。
- 交互控件沿用既有静态 Markdown/Print 降级。
- 资源路径必须解析到构建产物内部,或明确作为外部链接;打包过程绝不跟随作者内容中的 任意本地路径。
- 任何消费站值在未经现有输出同等级的校验与规范化之前,都不能成为原始 HTML、CSS、 命令参数或文件系统路径。
兼容与迁移
这是一项增量、选择启用的能力。现有 Book 站保留当前输出与脚本。只有当主题中间产物能 解释 DDIA 当前校验的每一章、编号对象、脚注、图片与内部链接后,DDIA pilot 才删除消费站 侧的转换。TPME 是第二消费站门禁;任何 DDIA 专用路由、标签或章节清单都不能进入通用 schema。
原型证据
第一版 manifest 在两个消费站隔离快照中选择启用,未修改任一消费站工作树,结果如下:
| 消费站 | 有序页面 | 标题 | Markdown 原始锚点 | 编号目标 | Xref | 未解析 |
|---|---|---|---|---|---|---|
| DDIA | 23 | 597 | 33 | 131(106 图、3 表、22 示例) | 292 | 0 |
| TPME | 18 | 295 | 946 | 41(31 图、10 表) | 1,062 | 0 |
两份 manifest 都没有重复编号目标 ID。本机样本中,严格构建额外耗时约为 DDIA 0.28 秒、 TPME 0.22 秒。TPME 大量保留原始锚点这一事实很关键:打包器必须消费仍保留这些显式锚点的 渲染输出。整书 Print HTML 已经同时携带命名空间化标题、脚注、编号目标与 MathML,因此 manifest 不应再复制整棵文档树。
随后,两份隔离快照通过同一个通用命令完成打包:
| 消费站 | EPUB 章节 | 带类型目标 | 包大小 | OINK 包/链接检查 | EPUBCheck 5.3.0 |
|---|---|---|---|---|---|
| DDIA | 23 | 131 | 22.9 MB | 0 错误 | 0 错误、0 警告 |
| TPME | 18 | 41 | 2.2 MB | 0 错误 | 0 错误、0 警告 |
DDIA 唯一的远程海报图使用了显式网络资源开关;TPME 完全由本地产物打包。通用 checker
按 BookManifest 校验每个页面锚点,以及每个目标的 kind 与 num,不再依赖 DDIA
旧预处理器的包装类。主题夹具同样通过了 Hugo minify 后的打包检查。出版 CI 把 Pandoc
3.10 与 EPUBCheck 5.3.0 的版本及归档摘要固定下来,并与 Hugo 兼容矩阵分为独立 job。
Print-to-PDF 试点使用 Chrome for Testing headless shell 151.0.7922.34,并在同一出版 CI job 按归档摘要固定:
| 消费站 | Book 页面 | PDF 页数 | 包大小 | 结构/文本/页码检查 | 渲染复核 |
|---|---|---|---|---|---|
| 主题夹具 | 5 | 23 | 1.1 MB | 0 错误 | 封面、表格、代码、公式、脚注 |
| DDIA | 23 | 527 | 60.3 MB | 0 错误 | CJK、表格、图片、代码、参考文献、后置内容 |
| TPME | 18 | 197 | 8.4 MB | 0 错误 | CJK、宽表、代码、callout、后置内容 |
三份 PDF 均为 Tagged、未加密的 A4 文档。真实消费站 checker 找到了全部 manifest 页面标题,
以及首页、中页和末页的 CSS 页码。视觉复核还暴露并修复了三项既有 Print 缺陷:子页面数学
能力未把 KaTeX 样式传播给整书聚合;过宽的 Bootstrap 列重置误命中 KaTeX col-align-*
内部类;pre > code 覆盖了纸面换行。它们都是范围明确的 Print 修复,不是 exporter 专用
DOM 改写。
实施计划
- 已完成:把 Print 页面序列提取成一份共享 Book partial,不改变 Print 产物。
- 已完成:增加默认关闭的 manifest 与夹具 checker。
- 已完成:用同一条通用 EPUB 链路打包 DDIA 与 TPME 隔离快照,再校验带类型目标、 内部链接与 EPUB 3.3 合规性。
- 已完成:用同一份固定 Chrome runner 渲染主题夹具与 DDIA/TPME 隔离快照,校验并 目视复核代表页面。
- 下一项消费站迁移:只有在 DDIA 仓库独立接受新出版门禁后,才用 metadata 加一次 调用替代它的语义预处理器。
验收标准
- 默认站点不发布新聚合文件,也没有显著构建成本。
- 固定的 Hugo Extended 0.165.0 工具链能在 warning 即失败模式下构建 opt-in 夹具。
- 现有 HTML、Print、Markdown、RSS、导航、搜索与浏览器测试全部通过。
- DDIA pilot 保留 23 章以及全部 106 图、3 表、22 示例与内部链接;这些都作为带类型的 语义目标存在,未解析目标为零。
- TPME 通过同一份 schema 与打包器生成产物。
- 消费站脚本不再包含 OINK 原语专用正则表达式。
- EPUBCheck 与 OINK 包/链接检查器通过;PDF 结构/文本/页码 checker 与代表页面渲染复核 全部通过。
待决问题
- 消费站迁移应发生在下一个 OINK release tag 之前还是之后?
决策记录
- 2026-08-24:起草主题/消费站所有权边界;先选择 opt-in 语义中间产物,不提前承诺最终 EPUB API 或实现。
- 2026-08-24:DDIA/TPME 隔离试点解决了第一项格式决策:保留一份引用既有逐页 Markdown 的 JSON manifest,并消费既有整书 Print HTML;不增加生成式整书 Markdown 或另一条 语义降级路径。
- 2026-08-24:打包器消费整书 Print HTML,因此 manifest 同样使用既有
no_print排除。 这样出版顺序只有一份,也不需要第二个输出专用排除键。 - 2026-08-24:实现通用 EPUB 链路,并在出版 CI 固定 Pandoc 3.10 与 EPUBCheck 5.3.0。 DDIA 与 TPME 隔离包同时通过带类型目标/内部链接检查与官方 EPUB 3.3 校验。
- 2026-08-24:远程出版资源继续默认拒绝。DDIA 的历史远程海报图通过显式 opt-in 验证, 没有因此放松默认值,也没有加入 DDIA 专用改写。
- 2026-08-24:增加回环 Print-to-PDF runner,并按归档摘要固定 Chrome for Testing headless shell 151.0.7922.34。主题、DDIA 与 TPME PDF 均通过结构、文本、A4、页码检查 与渲染复核。
- 2026-08-24:PDF 复核只修复 owning Print 契约:聚合数学能力传播、Bootstrap 列选择器 范围、代码换行、编号公式单列布局与 CSS 页边距。