# 往返与保留

读入一个 DOCX 再写回时，哪些内容按语义重建、哪些原样保留、哪些会丢失。

“往返”指 `parseDocx` 读入一个文件，修改或不修改 LitAST，再用 `generateDocx` 写回。`generateDocx` 总是根据 LitAST **重建整个包**，而不是在原 ZIP 上打补丁，所以能写回什么，取决于 LitAST 里保存了什么。

## 三种保留方式

### 按语义重建

被识别的内容（段落、文字格式、表格、图片、页眉页脚、域、内容控件、批注、修订等）会转成对应的节点，写回时从节点重新生成 OOXML。修改这些节点，改动就会体现在输出文件里。

### 原样保留的元素

无法识别的元素会变成 `unknownBlock`（块级）或 `unknownInline`（行内）节点，原始结构存放在 `rawXml` 中，写回时原样输出。`rawXml` 是内部序列化格式，不是 XML 字符串，不要手动修改它。

解析时传入 `preserveRawXml: false` 会直接丢弃这些元素。公式（OMML）始终以原始结构保留在 `math` 节点中，不受这个选项影响。

### 原样保留的部件

以下部件保存在 `ast.meta.rawXmlFiles` 中，写回时原样输出：

- 样式、编号定义、文档设置、字体表、主题
- 核心属性与自定义属性
- 批注及其扩展部件、批注人员列表
- 脚注、尾注

图表的源数据（图表部件与内嵌工作簿）也会原样保留并写回，但不能通过 LitAST 新建或修改图表。

## 拼音指南

`ruby` 会写回原生 `w:ruby`，基文和注音分别保存在 `children` 与 `attrs.rubyText`。
修改任一层文字或已建模属性后，生成器使用当前值；未改的普通 run 格式、未知 rubyPr
属性及显式零值/false 保留在 `_rubyPreservation` 中。不要手工修改该内部来源记录。
`preserveRawXml: false` 不会关闭这份专用保全记录。

包含关系或范围标识的内容不会直接重放旧 XML。整个 ruby 的超链接经公共关系分配器重建；
文字层内部的超链接不符合 OOXML ruby 内容模型，会拒绝导出。复杂嵌套域、批注、修订的
完整生命周期尚未验收，不承诺跨生产者无损。已验证 Word 16.109.2 的重开/编辑保存，
以及 WPS 12.1.28496 的普通横排样本显示；其余生产者和复杂组合仍未验收。

## 会丢失的内容

以下内容目前在往返后**不会**保留：

| 内容 | 说明 |
| --- | --- |
| 文档部件库（glossary） | 读取时记录在 `rawXmlFiles.glossaryXml`，但不会写回 |
| 自定义 XML 部件 | 读取时记录在 `ast.meta.customXmlParts`，但不会写回 |
| 上面清单之外的其他部件 | 不会被复制到输出文件中 |

如果你的场景依赖这些内容，请在写回后自行检查输出文件。

## 保存 LitAST

LitAST 可以直接用 `JSON.stringify` 保存，`JSON.parse` 读回后仍可交给 `generateDocx`，原样保留的内容也会一并写回。
