HWP (한글)
通过 OfficeCLI 创建、读取、编辑 HWP/HWPX 韩文文档
默认启用:是 二进制 HWP:实验性
.hwp 和 .hwpx 文件。如果任务涉及 DOCX、PPTX、XLSX 或 PDF,本技能将不会激活 — 请使用对应的格式专用技能。快速参考
完整的任务到命令查询表。每行显示该操作是否受支持以及使用哪个命令。
| 任务 | 状态 | 命令 |
|---|---|---|
| 按现有 .hwpx 格式化 | 支持 | cp source.hwpx target.hwpx && officecli open target.hwpx |
| 基于模板创建 | 支持 | python3 scripts/build_hwpx.py --template {base|gonmun|minutes|proposal|report} |
| 创建新 .hwpx | 支持 | officecli create file.hwpx |
| 从 Markdown 创建 | 支持 | officecli create file.hwpx --from-markdown input.md |
| 读取/分析 .hwpx | 支持 | view text|annotated|outline|stats|html|markdown|tables|forms|objects |
| 编辑现有 .hwpx | 支持 | set、add、remove、move、swap |
| 基于标签填充 | 支持 | set /table/fill --prop 'fill:label=val' |
| 表单识别 | 支持 | view forms --auto |
| 表格映射 | 支持 | view tables |
| Markdown 导出 | 支持 | view markdown |
| 公式(수식) | 支持 | add --type equation --prop 'script={1 over 2}' |
| 对象查找器 | 支持 | view objects |
| 查询(扩展语法) | 支持 | query 'tc[text~=홍길동]'、:has()、> 组合器 |
| 模板合并 | 支持 | merge template.hwpx out.hwpx --data '{"key":"val"}' |
| 交换元素 | 支持 | swap file.hwpx '/p[1]' '/p[2]' |
| 分栏符 | 支持 | add --type columnbreak --prop cols=2 |
| 图片/浮动对象 | 支持 | add --type picture --prop anchor=page --prop halign=center |
| 文档比较 | 支持 | compare a.hwpx b.hwpx(LCS 差异比较 + 表格比较) |
| 安全验证 | 支持 | ZIP 炸弹、路径穿越、符号链接、XXE 防护 |
| 损坏 ZIP 修复 | 支持 | 通过本地文件头扫描自动修复损坏的 HWPX |
| HTML 预览 | 支持 | view html --browser |
| 实时预览监控 | 支持 | watch file.hwpx |
| 验证 .hwpx | 支持 | validate(9 级检查) |
| 原始 XML | 支持 | raw、raw-set |
| 水印(图片) | 支持 | add --type watermark --prop src=img.png |
| 模式匹配编辑 | Python L4 | scripts/hwpx_cli.py open → 模式编辑 XML → save |
| 视觉 QA | Python L3 | scripts/contact_sheet.py + 子代理审查 |
| 创建新表单字段 | 已阻止 | 源原型已存在;韩软验证尚未完成 |
| 创建新 .hwp(二进制) | 实验性 | officecli create file.hwp --json |
| 读取/导出 .hwp(二进制) | 实验性 | officecli view file.hwp text --json + svg/png/pdf/markdown |
| 编辑 .hwp 文本/字段 | 实验性 | officecli hwp --json 操作方案 |
| 导出 HWPX 为 .hwp | 实验性 | officecli set input.hwpx /save-as-hwp --prop output=out.hwp --json |
| 转换 .hwp 为 .hwpx | 备选方案 | scripts/hwp_convert.py IN.hwp OUT.hwpx |
"~해줌" 使用示例
触发此技能的自然韩语提示。只需描述你需要什么即可。
--template gonmun 的模板组装,然后使用 /table/fill 填充标签值字段,如 문서번호、수신、참조、제목。view tables、view forms --auto 和 view stats,提供文档的结构分析。officecli set form.hwpx / --prop 'fill:성명=홍길동' --prop 'fill:연락처=010-1234-5678'--template minutes 创建,填充日期、地点、参会人员和议程项目等结构化字段。officecli hwp doctor --json 以确认原生 rhwp 支持。如果就绪,使用 officecli view file.hwp text --json。否则回退到 scripts/hwp_reader.py。编辑升级阶梯
当主要工具无法处理任务时,技能会逐级升级,共四个级别。优先使用低级别;仅在必要时才使用高级别。
| 级别 | 适用场景 | 工具 |
|---|---|---|
| L1 OfficeCLI 高级操作 | 常规的 add/set/remove、标签填充、查看模式 | officecli add/set/remove/query/view/merge |
| L2 OfficeCLI raw/raw-set | 直接修改 section0.xml / header.xml | officecli raw FILE /Contents/section0.xml |
| L3 Python 脚本 | 批量查找/替换、模板组装、模式匹配 | python3 scripts/hwpx_cli.py ... 或 scripts/build_hwpx.py |
| L4 解包 → 编辑 XML → 重新打包 | KICE 考试、法规、多文件 XML 编辑 | hwpx_cli.py open → 编辑 work/Contents/*.xml → 去除 lineseg → save |
升级信号
- OfficeCLI 无法添加自定义样式 → L2(raw-set header.xml)+ 阅读
reference/header-xml-guide.md - 自定义模板覆盖 → L3(
scripts/build_hwpx.py)+ 阅读reference/style_id_maps.md - HWP 二进制输入 → 先检查
officecli hwp doctor --json;就绪时使用原生 rhwp,否则 L3 - 多文件模式匹配(考试、法规) → L4
- 样式 ID 查找 → 先阅读
reference/style_id_maps.md
核心工作流
创建与导入
# 空文档
officecli create doc.hwpx
# 从 Markdown 创建(默认 JUSTIFY 对齐)
officecli create doc.hwpx --from-markdown input.md
# 左对齐 Markdown 导入
officecli create doc.hwpx --from-markdown input.md --align left
# 通过 rhwp 桥接创建二进制 HWP
officecli create file.hwp --json
# 使用数据合并模板
officecli merge template.hwpx out.hwpx --data '{"이름":"홍길동"}'
officecli merge template.hwpx out.hwpx --data data.json
# 模板组装(推荐用于结构化文档)
python3 scripts/build_hwpx.py --template gonmun --output gonmun.hwpx
查看模式
officecli view doc.hwpx text # 带行号的文本
officecli view doc.hwpx annotated # 路径 + 样式详情
officecli view doc.hwpx outline # 仅标题
officecli view doc.hwpx stats # 文档统计信息
officecli view doc.hwpx html --browser # A4 HTML 预览
officecli view doc.hwpx markdown # GFM markdown 导出
officecli view doc.hwpx tables # 表格 2D 网格 + 标签映射
officecli view doc.hwpx forms --auto # CLICK_HERE + 标签-值自动检测
officecli view doc.hwpx forms --auto --json # 用于 AI 流水线的 JSON
officecli view doc.hwpx objects # 图片/字段/书签/公式列表
officecli view doc.hwpx objects --object-type field # 按类型过滤
officecli view doc.hwpx styles # charPr/paraPr 样式
officecli view doc.hwpx issues # 9 级验证问题
officecli view file.hwpx 不带模式参数会报错。必须始终指定模式:text、tables、markdown 等。编辑操作
# 添加带文本和字号的段落
officecli add doc.hwpx /section[1] --type paragraph --prop text="content" --prop fontsize=11
# 添加表格
officecli add doc.hwpx /section[1] --type table --prop rows=3 --prop cols=4
# 设置属性(加粗、对齐)
officecli set doc.hwpx '/section[1]/p[1]' --prop bold=true --prop align=CENTER
# 查找并替换文本
officecli set doc.hwpx / --prop find="old" --prop replace="new"
# 删除元素
officecli remove doc.hwpx /section[1]/p[3]
# 交换两个元素
officecli swap doc.hwpx '/p[1]' '/p[2]'
标签填充(表格自动填充)
# 按标签填充(fill: 前缀)
officecli set doc.hwpx / --prop 'fill:대표자=홍길동' --prop 'fill:연락처=010-1234'
# 方向性填充:right(默认)、down、left、up
officecli set doc.hwpx / --prop 'fill:주소>down=서울시'
# 简写(/table/fill 路径下 fill: 前缀可选)
officecli set doc.hwpx /table/fill --prop '이름=김서준'
查询(扩展语法)
officecli query doc.hwpx 'p' # 所有段落
officecli query doc.hwpx 'tc[text~=홍길동]' # 单元格文本搜索
officecli query doc.hwpx 'run[bold=true]' # 加粗的 run
officecli query doc.hwpx 'p:has(tbl)' # 包含表格的段落
officecli query doc.hwpx 'tbl > tr > tc[colSpan!=1]' # 合并的单元格
officecli query doc.hwpx 'run[fontsize>=20]' # 20pt 及以上字号
officecli query doc.hwpx 'p[heading=1]' # 一级标题
运算符:=、!=、~=(包含)、>=、<=
伪选择器::empty、:contains(text)、:has(child)、:first、:last
虚拟属性:text、bold、italic、fontsize、colSpan、rowSpan、heading
常驻模式(实时连接)
officecli open doc.hwpx # 立即返回;守护进程在后台运行
officecli view text # 无需重新打开即可查看
officecli set '/p[1]' --prop bold=true
officecli close # 关闭会话
officecli open 作为后台 shell 任务运行。它会立即返回,守护进程会自动在后台运行。将其作为受监控的后台 shell 运行会产生僵尸进程和文件锁。批处理模式
officecli batch doc.hwpx <<'EOF'
view text
view stats
view forms --auto
EOF
比较
officecli compare a.hwpx b.hwpx # 文本差异(默认)
officecli compare a.hwpx b.hwpx --mode outline # 标题差异
officecli compare a.hwpx b.hwpx --mode table --json # 表格差异 JSON
使用 LCS DP 对齐(超过 1000 万单元格时回退到贪心算法)。表格相似度:维度权重 0.3 + 内容权重 0.7。页面范围过滤:--pages "1-3,5"。
图片与水印
# 内联图片
officecli add doc.hwpx /section[1] --type picture --prop path=/path/to/image.png
# 页面居中浮动图片
officecli add doc.hwpx /section[1] --type picture \
--prop path=/path/to/image.png \
--prop anchor=page --prop halign=center --prop valign=middle
# 水印(建议使用不透明 RGB PNG)
officecli add doc.hwpx /section[1] --type watermark \
--prop src=/path/to/watermark.png --prop bright=0 --prop contrast=0
监控与 HTML 预览
officecli watch doc.hwpx # 文件变更时自动刷新 HTML
officecli unwatch doc.hwpx # 停止监控
officecli view doc.hwpx html --browser # 一次性 A4 预览
模板组装系统
HWP 使用独特的基础 + 覆盖模板系统。大多数 공문/보고서/회의록/제안서 的 HWPX 创建应使用此系统,而非 officecli create 空白文档。
可用模板
| 模板 | 用途 | 关键字段 |
|---|---|---|
base | 空 HWPX 骨架 | mimetype、META-INF、空 header/section |
gonmun | 公文(공문) | 문서번호、수신、참조、제목、본문 |
minutes | 会议纪要(회의록) | 일시、장소、참석자、안건、결정사항 |
proposal | 提案书(제안서) | 제안개요、배경、내용、기대효과 |
report | 报告书(보고서) | 요약、현황、분석、제언 |
方法 1:build_hwpx.py(推荐)
python3 scripts/build_hwpx.py --template report --output Q4Report.hwpx
# 然后使用 officecli 编辑内容
officecli open Q4Report.hwpx
officecli set Q4Report.hwpx /table/fill --prop '제목=2026 Q4 보고'
# ... 继续编辑 ...
officecli close Q4Report.hwpx
方法 2:手动覆盖(用于自定义)
# 1. 复制基础骨架
cp -r templates/base/ work/
# 2. 覆盖领域特定样式
cp -r templates/gonmun/* work/Contents/
# 3. 根据需要编辑 header.xml 和 section0.xml
# 参考:reference/header-xml-guide.md、reference/section0-xml-guide.md
# 样式 ID:reference/style_id_maps.md
# 4. 重新打包为 HWPX(ZIP 格式,含去除和压缩)
python3 scripts/ooxml/pack.py work/ out.hwpx
# 5. 验证
officecli validate out.hwpx
基于参考的编辑
当用户说"按 X.hwpx 的格式"、"공문 양식처럼"、"기존 보고서 스타일"或提供源文件时 — 从源文件开始,不要从零重建。
工作流
- 复制源文件:
cp source.hwpx target.hwpx— 继承 header.xml(样式)、section0.xml(结构)、META-INF - 打开:
officecli open target.hwpx— 守护进程立即返回(请勿作为后台任务运行) - 仅删除正文段落 — 保留
header.xml(charPr/paraPr/borderFill)、META-INF、settings - 添加新内容使用已有的
styleidref值 — 它们会自动应用
header.xml 保存了所有样式定义(charPr、paraPr、borderFill、listItems)。从零重建会破坏 styleidref 交叉引用、丢失一致的视觉规范、导致验证失败,并且耗时增加 10 倍。模板优先级
- 用户提供的源文件 — 最高优先级模板
tests/fixtures/agentic/*.hwpx— 真实样本(公文、报告、含表格的会议纪要)templates/{base,gonmun,minutes,proposal,report}/— 模板组装系统officecli create空白文档 — 仅在没有其他选择时使用
表单识别与填充
四策略识别
| # | 策略 | 描述 |
|---|---|---|
| 1 | 相邻单元格标签-值 | 表格标签 → 值检测(默认) |
| 2 | 表头 + 数据行 | 列标题识别 |
| 3 | 单元格内模式 | ☐ 复选框、keyword( ) 括号留空、(label: ) 标注 |
| 4 | 键值表检测 | 16 个韩语关键词触发自动检测 |
三阶段填充流水线
- 单元格内模式:复选框
☐→☑、括号留空填充、标注填充 - 表格标签-值:精确匹配 + 前缀 60% 匹配,四方向(
right/down/left/up) - 内联段落:正则后向引用匹配表格外的
"label: value"
AI 表单填充工作流
# 步骤 1:识别所有字段
officecli view form.hwpx forms --auto --json > fields.json
# 步骤 2:AI 映射标签 -> 值(你的逻辑在此)
# 步骤 3:填充匹配的字段
officecli set form.hwpx /table/fill --prop '성 명=홍길동'
二进制 HWP 支持(实验性)
原生二进制 .hwp 操作由 rhwp 桥接驱动。所有操作都受能力门控限制 — 在假定支持之前务必检查就绪状态。
发现命令
# 务必先运行这些命令
officecli hwp doctor --json # 运行时就绪检查
officecli capabilities --json # 完整能力矩阵
officecli hwp --json # 当前操作方案和策略
已支持的操作(就绪时)
# 创建
officecli create file.hwp --json
# 查看/导出
officecli view file.hwp text --json
officecli view file.hwp svg --page 1 --json
officecli view file.hwp png --page 1 --out /tmp/hwp-png --json
officecli view file.hwp pdf --page 1 --out out.pdf --json
officecli view file.hwp markdown --json
officecli view file.hwp thumbnail --out thumb.png --json
officecli view file.hwp info --json
officecli view file.hwp tables --section 0 --json
# 编辑字段
officecli set file.hwp /field --prop name=회사명 --prop value=리지 --prop output=out.hwp --json
# 编辑文本
officecli set file.hwp /text --prop find=마케팅 --prop value=브릿지 --prop output=out.hwp --json
# 插入文本
officecli add file.hwp /text --type paragraph --prop value=새본문 --prop output=out.hwp --json
# 编辑表格单元格
officecli set file.hwp /table/cell --prop section=0 --prop parent-para=3 \
--prop control=0 --prop cell=0 --prop value=오피스셀 --prop output=out.hwp --json
# 原生操作(逃生舱口)
officecli view file.hwp native --op get-style-list --json
officecli set file.hwp /native-op --prop op=split-paragraph --prop output=out.hwp --json
# HWPX 导出为 HWP
officecli set input.hwpx /save-as-hwp --prop output=out.hwp --json
.hwp 变更优先使用输出模式:--prop output=out.hwp。仅在 /text 替换时使用原地模式,且仅在明确请求并确认 safeInPlace.ready=true 之后。原地模式必须包含 --in-place --backup --verify。公式处理(수식)
HWPX 公式使用韩软的专有脚本语言。这不是 MathML,不是 LaTeX,也不是 OMML。
| 脚本 | 结果 |
|---|---|
{1 over 2} | 1/2(分数) |
sqrt{x} | x 的平方根 |
x^2、x_i | 上标、下标 |
int _0 ^1 f(x)dx | 定积分 |
sum _{i=1} ^n | 求和 |
lim _{x->0} | 极限 |
matrix{a&b # c&d} | 2x2 矩阵 |
# 创建公式
officecli add doc.hwpx /section --type equation --prop 'script=x^2 + y^2 = r^2'
# 查看所有公式
officecli view doc.hwpx objects --object-type equation
<hp:script> 文本,不能编辑二进制负载。数学考试文档(KICE)的每个表达式都需要 <hp:equation>。绝不要用纯文本表示数学公式。韩文文档设计原则
政府表单美学(한국 공공양식 미감)
- 表格是骨干:韩国表单以表格驱动。每个标签-值对都位于精确合并的单元格网格中。请精确保留网格结构。
- 标题层级:제1조(条) > 제1항(款) > 제1호(项)。使用
styleidref设置大纲级别。 - 固定边距:政府表单使用标准 A4 边距(上下约 15mm,左右约 20mm)。不要修改现有文档的边距。
- 对齐方式:正文默认为 JUSTIFY(양쪽 정렬)。标题可能居中。正式文档的正文绝不要使用 LEFT 对齐。
均匀间距检测(균등분할)
韩国表单通常在单元格中对姓名使用均匀字符间距:"홍 길 동"(每个字符之间有空格)。这是一种显示惯例,不是数据。
- 读取时:去除均匀空格以获得实际值(
"홍길동") - 写入时:如果模板单元格使用均匀间距,则插入空格以匹配(2 字:
"이 준",3 字:"홍 길 동",4 字:"남궁민수") - 检测正则:
^(\S)\s(\S)\s(\S)$等(单字符组之间以 1 个空格分隔)
文档类型分类
| 类型 | 关键信号 | 示例 |
|---|---|---|
exam | 公式 10+ 个、矩形对象 | KICE 수능/모의고사 试卷 |
form | 表格 3+ 个、复选框(☐/■) | 대학 신청서、정부 양식 |
regulation | ○ 项目符号 10+ 个、별첨/조항 引用、表格 10+ 个 | 운영지침、내규、시행세칙 |
report | 长文本、表格较少 | 보고서、논문 |
mixed | 以上皆不符 | 사업계획서 |
强制验证
# 1. 结构验证(必须通过)
officecli validate output.hwpx
# 2. PDF 视觉验证(必须检查)
soffice --headless --convert-to pdf --outdir /tmp output.hwpx
# 验证:表格位置、引导文字已移除、复选框正确、
# 合并单元格文本在正确的行、数字未损坏
# 3. 通过子代理进行视觉 QA(使用 reference/visual_qa_prompt.md)
python3 scripts/contact_sheet.py /tmp/output.pdf sheet.png
# 4. 如果有韩软 Office,也直接打开 .hwpx 检查
交付前检查清单
officecli validate通过(0 个错误)soffice --headless --convert-to pdf→ 视觉检查- 表格单元格位置正确(cellAddr 映射)
- 引导文字(※、예시)已完全移除
- 复选框 ☐/■ 仅在预期单元格中
- 合并单元格文本在正确的行
- 如果有韩软 Office,直接打开 .hwpx 检查
安全
| 检查项 | 限制 |
|---|---|
| ZIP 炸弹 | 1000 个条目、200 MB、100:1 比率 |
| 路径穿越 | 空字节、..、绝对路径、驱动器字母、符号链接 |
| XXE | DtdProcessing.Prohibit |
| 表格大小 | 200 列 x 10,000 行 |
参考资料与脚本
参考文档(reference/)
| 文件 | 何时阅读 | 内容 |
|---|---|---|
reference/hwpx-format.md | 进行任何直接 XML 编辑之前 | OWPML ZIP 结构、命名空间、文件布局、mimetype |
reference/header-xml-guide.md | 添加/修改 charPr/paraPr/borderFill 样式时 | 如何向 header.xml 添加新样式 |
reference/section0-xml-guide.md | 编辑段落/表格/混合格式 XML 时 | section0.xml 正文的 XML 模板 |
reference/style_id_maps.md | 模板覆盖时查找样式 ID | 所有模板的完整样式 ID 索引 |
reference/dependencies.md | 首次设置/环境检查时 | 所需的 Python/系统软件包 |
reference/visual_qa_prompt.md | 通过子代理进行视觉 QA 时 | 用于 PDF 图像检查的即用提示词 |
reference/table_templates/*.xml | 插入预构建表格时 | 2x6、3x3、4x4、5x4 网格 XML 片段 |
Python 脚本(scripts/)
| 脚本 | 用途 | 命令 |
|---|---|---|
hwpx_cli.py | 统一 Python CLI(14+ 个命令) | python3 scripts/hwpx_cli.py {command} ... |
build_hwpx.py | 基于模板创建 | python3 scripts/build_hwpx.py --template {type} |
analyze_template.py | 检查模板结构 | python3 scripts/analyze_template.py work/ |
create_document.py | 创建空白或自定义 HWPX | python3 scripts/create_document.py OUT.hwpx |
table_builder.py | 从 Python 对象构建表格 XML | 内部使用 |
page_guard.py | 检测段落/表格/文本偏移 | python3 scripts/page_guard.py -r ref.hwpx -o out.hwpx |
contact_sheet.py | QA 总览图(页面网格图像) | python3 scripts/contact_sheet.py INPUT.pdf sheet.png |
validate.py | 9 级结构验证 | python3 scripts/validate.py INPUT.hwpx |
hwp_reader.py | 读取 HWP 5.0 二进制(只读) | python3 scripts/hwp_reader.py INPUT.hwp |
hwp_convert.py | HWP → HWPX 转换 | python3 scripts/hwp_convert.py IN.hwp OUT.hwpx |
text_extract.py | 从 HWPX 提取纯文本 | python3 scripts/text_extract.py INPUT.hwpx |
模式匹配编辑(L4 备选方案)
用于超出 officecli set/find-replace 能力的复杂表单编辑 — KICE 考试、多章节法规、碎片化文本节点。
核心流程
# 解包 HWPX
python3 scripts/hwpx_cli.py open input.hwpx
# 编辑 work/Contents/ 中的 XML 文件
#(hwpx_cli.py 会自动去除 lineseg)
# 重新打包
python3 scripts/hwpx_cli.py save output.hwpx
关键模式
| 模式 | 描述 |
|---|---|
| Lineseg 去除 | 在每次直接 XML 写入时移除过期的 <hp:linesegarray> 缓存 |
| 复选框替换 | ☐ → ☑,支持多 <t> 节点处理 |
| 均匀间距规范化 | "홍 길 동" ↔ "홍길동" 转换 |
| p[0] 巨型段落 | secPr + tbl + 问题 1 文本合并在第一个段落中 |
| 公式交错 | <t> ↔ <equation> 交替排列 — 提取文本时跳过公式 |
Lineseg 去除(关键)
直接编辑 HWPX XML 时(非通过 officecli 或 scripts/hwpx_cli.py),必须去除所有 <hp:linesegarray> 元素。过期的布局缓存会导致字符重叠在一行上。
import re
xml = re.sub(r'<(?:hp:)?linesegarray[^>]*>.*?</(?:hp:)?linesegarray>', '', xml, flags=re.DOTALL)
xml = re.sub(r'<(?:hp:)?linesegarray[^/]*/>', '', xml) # self-closing
officecli 和 scripts/hwpx_cli.py 会自动处理 lineseg 去除。此规则仅适用于原始 Python XML 编辑。常见陷阱
| 陷阱 | 正确做法 |
|---|---|
--props text=Hello | --prop text=Hello — 始终使用单数 --prop |
/body/p[1] 路径 | HWPX 使用 /section[1]/p[1] — 基于 section,不是 body |
shell 中未加引号的 [N] | "/section[1]/p[1]" — 路径始终加引号 |
遗漏 fontsize | --prop fontsize=11 始终添加 — 防止 charPr 0 污染 |
officecli view file.hwpx(无模式) | 报错。必须指定:text、markdown、tables 等。 |
| 手动表格映射 | view tables 取代手动检查 |
| 从模板重建 header.xml 样式 | 先 cp source.hwpx target.hwpx。阅读 reference/style_id_maps.md |
将 officecli open 作为后台 shell 运行 | 在前台运行 — 它会立即返回,守护进程自动在后台运行 |
| 直接编辑 XML 未去除 lineseg | 过期缓存导致文本重叠。使用 hwpx_cli.py 或手动去除 |
| 未阅读 reference/ 就进行自定义样式工作 | reference/header-xml-guide.md + reference/style_id_maps.md 为必读 |
反模式(必须避免)
- 数学考试中没有公式 = 输出损坏 — KICE 文档必须包含
<hp:equation>元素 - 不要对 HWP 二进制进行无保护的覆盖 — 优先使用
--prop output=...;仅在safeInPlace.ready=true时使用安全原地模式 - 当 rhwp 有原生原语时不要使用伪造的 HWPX 备选方案 — 如果 OfficeCLI 缺少路由,报告缺口并等待批准
- 不要在未去除 lineseg 的情况下编辑 XML — 过期缓存导致文本重叠
- 不要在固定布局考试中使用可见的 QA 标记 — 改用截图或附件证据
- 不要跨格式加载技能 — 本技能仅限
.hwp/.hwpx - 不要重建模板中已有的样式 — 先
cp然后阅读reference/style_id_maps.md - 不要忽略参考资料 —
header-xml-guide.md、section0-xml-guide.md和style_id_maps.md是自定义 XML 工作的必读文件
依赖项
| 工具 | 用途 | 是否必需? |
|---|---|---|
officecli(全局) | 主要 HWPX CLI + 实验性 rhwp 驱动的 HWP 桥接 | 必需 |
python3 | 备选脚本(scripts/*.py) | L3/L4 必需 |
lxml | scripts/* 的 XML 处理 | L3/L4 必需 |
pyhwp | 旧版 HWP 5.0 二进制读取/转换备选方案 | HWP→HWPX 备选方案必需 |
soffice(LibreOffice) | PDF 转换 + 视觉验证 | 推荐 |
Java(JAVA_HOME) | H2Orestart HWP 转换引擎 | 仅用于 HWP→HWPX |
dotnet | 从源码构建 officecli | 仅用于构建 |
前置条件检查
# OfficeCLI(必需)
which officecli >/dev/null 2>&1 || echo "WARN: OfficeCLI not installed"
# LibreOffice(推荐,需要时自动安装)
which soffice >/dev/null 2>&1 || echo "INFO: LibreOffice not installed"
# Python 软件包(L3/L4 可选)
python3 -c "import lxml; import pyhwp" 2>/dev/null || echo "OPTIONAL: pip install lxml pyhwp"
# Java(仅用于 HWP 转换)
echo "JAVA_HOME=$JAVA_HOME"
工具发现
在猜测之前,始终先通过帮助确认语法。
officecli --help
officecli hwp --json
officecli hwp doctor --json
officecli capabilities --json
officecli view --help
officecli set --help
python3 scripts/hwpx_cli.py --help
python3 scripts/build_hwpx.py --help
考试 XML 结构模式
KICE 风格的考试试卷因固定布局限制需要特殊处理。
| 模式 | 描述 | 检测方式 |
|---|---|---|
| 分页/分栏符 | pageBreak="1" / columnBreak="1" | 页面边界 = 题目组边界 |
| p[0] 巨型段落 | secPr + colPr + 标题 tbl + 问题 1 文本合并 | 所有内容在第一个段落中 |
| 公式交错 | <t> ↔ <equation> 交替排列 | 提取文本时跳过公式 |
| 答案选项 | ① + 5 个 <equation>(5 选 1) | 自动检测答案段落 |
| 文本碎片化 | 1-2 字符 <t> 拆分(HWP 转换产物) | 先拼接所有文本再匹配 |
| 双栏布局 | <hp:colPr type="NEWSPAPER" colCount="2"> | 考试特有布局 |
[CU TEMPLATE EDIT ...] 或 VISUAL QA 等字符串属于严重视觉错误。请改用截图作为前后对照。HWP → HWPX 转换
格式检测
file doc.hwpx # "Zip archive" -> HWPX(ZIP + OWPML XML)
file doc.hwp # "HWP Document" -> HWP 5.0 二进制
结构差异
| 方面 | 原生 HWPX | HWP → HWPX 转换后 |
|---|---|---|
| 文本单元 | 每个 run 一个短 <t> | 整个段落在一个 <t> 中 |
| 标题 p[0] | secPr + tbl + 内容 | 页码碎片 <t>20</t> + <t>1</t> 混入 |
| 编辑方式 | run 级别精确替换 | 需要原始字符串替换或整段落交换 |
转换文件的编辑策略
- 标题:run 感知替换 —
set_run_text(p0, 'old', 'new')(跳过页码 run) - 正文:对序列化 XML 进行原始字符串替换 —
sec0.replace(old, new) - 多
<t>单元格:使用ReplaceTextInCell()— 拼接所有<t>→ 匹配 → 重新分配