rhwp
Al(R),大家的韩文 — 从 Al 开始
所有 HWP,向所有人开放
简体中文 | English
**随时随地**打开 HWP/HWPX 文件。免费,无需安装。
rhwp 是一个基于 Rust + WebAssembly 的开源 HWP/HWPX 查看器/编辑器。它打破了封闭格式的壁垒,让所有人、所有 AI、所有平台都能自由读写韩文文档。
## 路线图
独自搭建骨架,共同血肉丰满,最终成就为大家的成果。
```
0.5 ──── 1.0 ──── 2.0 ──── 3.0
뼈대 조판 협업 완성
```
| 阶段 | 方向 | 策略 |
|------|------|------|
| **0.5 → 1.0** | 在读写基础上建立排版引擎体系 | 独自稳固核心架构 |
| **1.0 → 2.0** | 在 AI 排版 pipeline 上开放社区参与 | 降低贡献门槛的结构 |
| **2.0 → 3.0** | 在社区贡献功能的基础上实现公共资产化 | 达到与 Hancom 同等水平 |
## 里程碑
### v0.5.0 ~ v0.7.x — 骨架 (当前阶段)
- HWP 5.0 / HWPX 解析器,段落、表格、公式、图像、图表渲染
- 分页(多栏分割、表格行分割),页眉/页脚/母版页/脚注
- SVG 导出 (CLI) + Canvas 渲染 (WASM/Web)
- Web 编辑器 + hwpctl 兼容 API (30 个 Actions, Field API)
- 1100+ 测试
#### v0.7.15 周期 (2026-06-06)
**浏览器扩展安全**
- 验证 Chrome/Firefox service worker 的文档 fetch sender,拦截内网/localhost/private URL,强化重定向最终 URL 的二次验证
- 对 extension 端的 fetch 应用 `credentials: "omit"`,防止 thumbnail 数据的 page DOM 直接暴露
- Chrome/Edge/Firefox 扩展 v0.2.4:无新增权限,无新增外部网络 endpoint
**公式与尾注流**
- 强化仅包含 TAC 的公式行的自动换行与段落缩进应用
- 修复强制换行后 TAC 公式光标移动、尾注区域光标移动、段落间移动的回归问题
**HWPX 存储契约**
- 修正 HWPX 图形序列化时的 flip/rotation 及 `isEmbeded` 输出
- 保留 HWPX 对角线单元格边框的 `hh:slash` / `hh:backSlash` type
- 保留零长度 HWPX field 的 ordering
#### v0.7.13 周期 (2026-05-18 ~ 2026-05-26)
**HWPX → HWP 存储兼容性**
- 改进表格/单元格 axis contract、cell LIST_HEADER materialization、渐变 `BORDER_FILL`、单元格内边距、单元格背景图像填充类型存储的一致性
- 强化 memo 控件序列化、memo 样式保留、目录字段标记/页码输出、隐藏页码/起始新页码控件存储
- 解决大量 `hwpx-h-01/02/03`、`mel-001`、`aift`、`exam_kor`、`exam_social` 系列的 Hancom 文件损坏/中断案例
**HWPX 渲染一致性**
- 强化母版页(偶数/奇数/末尾)、页眉/页脚、段落编号、段落边框、试卷题干框渲染
- 改进文本框位置、渐变、矩形圆角处理
- 改进与 `exam_kor.hwpx`、`exam_social.hwpx`、`hwp3-sample16-hwp5.hwpx` 等 Hancom 转换文件的 SVG/Web Canvas 视觉一致性
**分页与排版修正**
- 修复 HWPX `treat_as_char` 表格 LINE_SEG 高度过大计算、嵌套表格分页、图形 pushdown/vpos 重复计算、多栏尾注 vpos 处理
- 改进 TAC 形状光标移动及连续空格移动体验
**发布与扩展**
- 发布 `@rhwp/core` / `@rhwp/editor` v0.7.13 到 npm
- GitHub Release `v0.7.13` 附带 Linux/macOS/Windows CLI 二进制文件及 SHA-256 校验和
- rhwp-chrome / Edge / Firefox 扩展 v0.2.3:提供本地 `file://` 访问权限指南,抑制 Chrome/Edge 本地文件重复下载,集成 rhwp core 0.7.13 WASM bundle
#### v0.7.12 周期 (2026-05-12 ~ 2026-05-18)
**核心回归修复**
- 将原 Issue #952 拆分为 5 个独立缺陷并解决:页面边框基准、空 caption phantom advance、column 基准图形 advance、line break 前的 inline TAC line 映射、文本框内部的 inline equation 重复 emit
- 修正 WMF `SetTextAlign` vertical bits 解释,修复 HWP3 空段落 + 分页符 overflow 页面数量 inflate 问题
- 通过对 release 构建应用 LTO / `codegen-units=1` / strip,减小 CLI 及 WASM 产物体积
**rhwp-studio / API**
- 强化 F5 正文块选择、F3 区域扩展、菜单 hotkey 基础设施、从新页码开始 UI/API
- 引入 `searchAllText` API、`rhwpDev.goto()` 开发工具、文档比较与历史记录初步功能
- 强化未保存更改保护、外部剪贴板粘贴优先级、嵌套表格 hit-test 等编辑稳定性
**HWP3/WMF/EMF/排版**
- EMF/WMF 图像内容渲染,HWP3 tab spec 一致性,强化 HWP3/HWPX 外部引用图像一致性
- 大量回归修正,如页眉/页脚图像旋转/镜像、母版页表格 margin、公式 Canvas/WASM 渲染、多栏最后一栏流向等
#### v0.7.11 周期 (2026-05-10 ~ 2026-05-11)
**渲染与排版**
- Skia 原生栅格化 Issue #536 取得阶段性进展:Layer IR 契约加固,文本 replay 一致性,Text IR v2 兼容性契约
- 强化 HWP3 原生渲染一致性:基于 `hwp3-sample10.hwp` Oracle 763 页面的多阶段修正
- 整理 Git LFS `pdf-large/` 隔离及大型 fixture 运维方式
**rhwp-studio 编辑 UX**
- scrollbar 拖拽,韩文 IME chord 按键判定,为避开 Chrome 预留快捷键将 `Ctrl+N → Ctrl+M` 进行调整
- Alt/Option+Arrow 单词移动,拖拽表格单元格时保留单元格上下文,修正行尾/文档末尾光标移动
- 强化表格编辑 Undo/Redo,表格大小调整 SnapshotCommand,多栏/新编号对话框,Ctrl/Cmd+Arrow / Ctrl+E 快捷键
#### v0.7.10 周期 (2026-05-06)
**新功能与基础设施**
- 引入将 Linux/macOS/Windows CLI 二进制文件及 SHA-256 校验和附带至 GitHub Release 资产的 pipeline
- 添加基于原生 Skia 的 `PageLayerTree → PNG` export、`native-skia` feature gate 以及 `DocumentCore::render_page_png_native(page)` API
- 强化 `export-png` CLI,`--vlm-target claude`、`--scale`、`--max-dimension`、`--font-path` 选项及中/英手册
**排版与渲染修正**
- 补全 HWP3 Square wrap,HWP3 转换文件识别启发式算法,修正 HWP 5.0 规范 0x18/0x1E swap
- 修正单元格 inline TAC Shape margin + indent,TAC 表格 `outer_margin_bottom`,inline 表格+公式段落偏移,预览单元格分数段落 routing,单元格内部 TopAndBottom 图像 1 行 offset
- 修复 PUA SVG 输出,exam_eng 箭头丢失,Square wrap 表格 `horz_rel_to=Column`,inline 公式未渲染问题
#### v0.7.9 周期 (2026-05-01 ~ 2026-05-02)
**回归修复 (维护者)**
- 修复 mel-001.hwp 第 2 页表格单元格高度回归 ([#501](https://github.com/edwardkim/rhwp/issues/501)) — 添加模仿 Hancom 自身防御逻辑的 guard,应对异常巨大的 cell.padding (1700 HU 对比 cell.height 1280 HU)。编写排障指南与 wiki ([HWP 单元格 Padding 防御逻辑](https://github.com/edwardkim/rhwp/wiki/HWP-%EC%85%80-Padding-%EB%B0%A9%EC%96%B4-%EB%A1%9C%EC%A7%81))
- 修复 PUA (Private Use Area) 项目符号字形回归 ([#509](https://github.com/edwardkim/rhwp/issues/509)) — Option F (保留 PR #251 draw_text 区域 + 精确匹配表 Hancom PDF 标准答案)。添加修正映射 2 项 + 新增映射 10 项 + `gen-pua` 验证工具
**外部 PR cherry-pick (5 项)**
- 实现组内图形序列化 (外部贡献由 [@oksure](https://github.com/oksure) 提供 — PR [#428](https://github.com/edwardkim/rhwp/pull/428))
- 外部暴露 `Paragraph::utf16_pos_to_char_idx` ([#484](https://github.com/edwardkim/rhwp/issues/484)) — 外部贡献由 [@DanMeon](https://github.com/DanMeon) 提供,PR [#494](https://github.com/edwardkim/rhwp/pull/494)
- Layout 一致性 + 公式修正集合 (7 Task / 10 commits — #488/#490/#483/#489/#495/#480/#476) — 外部贡献由 [@planet6897](https://github.com/planet6897) 提供,PR [#478](https://github.com/edwardkim/rhwp/pull/478)
- HWP 3.0 解析器 + Square wrap 环绕渲染 (Task #417 + Task #460, 51 commits) — 外部贡献由 [@jangster77](https://github.com/jangster77) 提供,PR [#506](https://github.com/edwardkim/rhwp/pull/506)
- 为 PageLayerTree image paint op 添加 brightness/contrast JSON 字段 ([#508](https://github.com/edwardkim/rhwp/issues/508)) — 强化 alhangeul-macos 下流的 backend replay 契约。外部贡献由 [@postmelee](https://github.com/postmelee) 提供,PR [#510](https://github.com/edwardkim/rhwp/pull/510)
**回归验证基础设施 (外部贡献)**
- Canvas 视觉差异 pipeline (自动验证 legacy Canvas ↔ PageLayerTree replay 像素差异,relates [#364](https://github.com/edwardkim/rhwp/issues/364)) — 外部贡献由 [@seo-rii](https://github.com/seo-rii) 提供,PR [#498](https://github.com/edwardkim/rhwp/pull/498)
#### v0.7.8 周期 (2026-04-29)
- 修复多栏 section 累计公式回归 ([#391](https://github.com/edwardkim/rhwp/issues/391)) — 外部贡献由 [@planet6897](https://github.com/planet6897)
- 改进公式渲染 ([#174](https://github.com/edwardkim/rhwp/issues/174), [#175](https://github.com/edwardkim/rhwp/issues/175)) + 图像亮度/对比度效果 ([#150](https://github.com/edwardkim/rhwp/issues/150)) — 外部贡献由 [@oksure](https://github.com/oksure)
- 公式 ATOP 解析 + HWPX 公式序列化保留 ([#286](https://github.com/edwardkim/rhwp/issues/286)) — 外部贡献由 [@cskwork](https://github.com/cskwork) (本仓库首位外部 contributor)
- Canvas → PageLayerTree replay 切换 P2 — 外部贡献由 [@seo-rii](https://github.com/seo-rii) (PR [#456](https://github.com/edwardkim/rhwp/pull/456))
- WASM API 扩展 (insertParagraph / deleteParagraph, [#269](https://github.com/edwardkim/rhwp/issues/269), [#271](https://github.com/edwardkim/rhwp/issues/271)) + set_field round-trip 修正 — 外部贡献由 [@oksure](https://github.com/oksure)
#### v0.7.7 周期 (2026-04-27)
#### v0.7.6 周期 (2026-04-26)
**多位外部 contributor + 排版精准化**
- 目录前导点 + 页码右制表符对齐 ([#279](https://github.com/edwardkim/rhwp/issues/279)) — 外部贡献由 [@seanshin](https://github.com/seanshin) 提供,PR [#282](https://github.com/edwardkim/rhwp/pull/282)
- form-002 内部表格分页缺陷 ([#324](https://github.com/edwardkim/rhwp/issues/324)) — 外部贡献由 [@planet689](https://github.com/planet6897) 提供,PR [#327](https://github.com/edwardkim/rhwp/pull/327)
- typeset 路径 PageHide / Shape / 重复 emit 缺陷 ([#340](https://github.com/edwardkim/rhwp/issues/340)) — 外部贡献由 [@planet6897](https://github.com/planet6897) 提供,PR [#341](https://github.com/edwardkim/rhwp/pull/341)
- Task #321~#332 累积整理 + vpos / cell padding 回归解决 ([#342](https://github.com/edwardkim/rhwp/issues/342)) — 外部贡献由 [@planet6897](https://github.com/planet6897) 提供,PR [#343](https://github.com/edwardkim/rhwp/pull/343)
**API · 输出 (外部贡献由 [@oksure](https://github.com/oksure) 提供)**
- 添加 `replaceOne(query, newText, caseSensitive)` WASM API ([#268](https://github.com/edwardkim/rhwp/issues/268), PR [#334](https://github.com/edwardkim/rhwp/pull/334))
- SVG/HTML `draw_image` base64 内嵌 (PR [#335](https://github.com/edwardkim/rhwp/pull/335))
**Firefox AMO (外部贡献由 [@postmelee](https://github.com/postmelee) 提供 — PR [#339](https://github.com/edwardkim/rhwp/pull/339))**
- 解决 AMO 验证警告 + viewer bundle 安全 sanitize → rhwp-firefox 0.2.2
#### 最近更改 (v0.7.3 / 扩展 v0.2.1, 2026-04-19)
**rhwp-studio (库 0.7.3)**
- 禁用 HWPX 来源文档的保存 + 用户指引 ([#196](https://github.com/edwardkim/rhwp/issues/196)) — 防止数据损坏 (直到 HWPX→HWP 完全转换器 [#197](https://github.com/edwardkim/rhwp/issues/197) 完成为止)
- 保留 HWPX→HWP IR 映射适配器资产 ([#178](https://github.com/edwardkim/rhwp/issues/178)) — rhwp 自兼容性 100% 恢复,Hancom 兼容性将在 #197 之后跟进
- 改进旋转形状调整大小光标 + Flip 处理 (外部贡献由 [@bapdodi](https://github.com/bapdodi) 提供 — PR [#192](https://github.com/edwardkim/rhwp/pull/192))
- 在 SVG 中反映 HWP 图形效果(灰度/黑白) (外部贡献由 [@marsimon](https://github.com/marsimon) 提供 — PR [#149](https://github.com/edwardkim/rhwp/pull/149))
- 修复 Windows 环境下 CFB 路径分隔符错误 (外部贡献由 [@dreamworker0](https://github.com/dreamworker0) 提供 — PR [#152](https://github.com/edwardkim/rhwp/pull/152))
- 实现 HWPX Serializer — Document IR → HWPX 存储 (外部贡献由 [@seunghan91](https://github.com/seunghan91) 提供 — PR [#170](https://github.com/edwardkim/rhwp/pull/170))
- HWPX ZIP entry 压缩限制 + strikeout shape 白名单 (外部贡献由 [@seunghan91](https://github.com/seunghan91) 提供 — PR [#153](https://github.com/edwardkim/rhwp/pull/153), PR [#154](https://github.com/edwardkim/rhwp/pull/154))
- 形状调整大小时的宽度/高度限制 (外部贡献由 [@seunghan91](https://github.com/seunghan91) 提供 — PR [#163](https://github.com/edwardkim/rhwp/pull/163))
- 修复移动端下拉菜单图标/标签重叠 (外部贡献由 [@seunghan91](https://github.com/seunghan91) 提供 — PR [#161](https://github.com/edwardkim/rhwp/pull/161))
**rhwp-chrome / Edge 扩展 (v0.2.1)**
- 恢复激活 Chrome 扩展时记住常规文件下载最后位置的行为 ([#198](https://github.com/edwardkim/rhwp/issues/198))
- 兼容 options 页面 CSP 的修正 ([#166](https://github.com/edwardkim/rhwp/issues/166))
- 使用 `Ctrl+S` 保存 HWP 文件时直接覆盖原文件 (外部贡献由 [@ahnbu](https://github.com/ahnbu) 提供 — PR [#189](https://github.com/edwardkim/rhwp/pull/189))
- 整理缩略图加载 spinner + options CSP 兼容 (外部贡献由 [@postmelee](https://github.com/postmelee) 提供 — PR [#168](https://github.com/edwardkim/rhwp/pull/168))
- 拦截 DEXT5 类 handler 下载时产生的空白查看器标签页
### v2.0.0 — 协作
- 插件/扩展架构,实时协作编辑
- 多种输出格式(PDF, DOCX 等)
### v3.0.0 — 完成
- 全面的 HWP 功能覆盖率,无障碍 (a11y),移动端适配
- 达到可在公共机构实际业务中投入使用的水平
详情请参阅 [路线图文档](mydocs/report/rhwp-milestone.md)。
## 功能
### Parsing (解析)
- HWP 5.0 二进制格式 (OLE2 Compound File)
- HWPX (基于 Open XML 的格式)
- Sections, paragraphs, tables, textboxes, images, equations, charts
- Header/footer, master pages, footnotes/endnotes
### Rendering (渲染)
- **段落排版**:行距、缩进、对齐、制表位
- **表格**:单元格合并、边框样式(实线/双线/三线/点线)、单元格公式计算
- **多栏排版**(2 栏、3 栏等)
- **段落编号/项目符号**
- **垂直文本**(英文横排/竖排)
- **页眉/页脚**(奇偶页分离)
- **Master pages**(Both/Odd/Even, is_extension/overlap)
- **对象放置**:TopAndBottom, treat-as-char (TAC), in-front-of/behind text
### Equation (公式)
- Fractions (OVER), square roots (SQRT/ROOT), subscript/superscript
- Matrices: MATRIX, PMATRIX, BMATRIX, DMATRIX
- Cases, alignment (EQALIGN), stacking (PILE/LPILE/RPILE)
- Large operators: INT, DINT, TINT, OINT, SUM, PROD
- Relations (REL/BUILDREL), limits (lim), long division (LONGDIV)
- 15 text decorations, full Greek alphabet, 100+ math symbols
### Pagination (分页)
- 多栏文档的栏/页分割
- 表格行级别的分页 (PartialTable)
- shape_reserved 处理 TopAndBottom 对象
- 基于 vpos 的段落位置修正
### Output (输出)
- SVG 导出 (CLI, legacy + layer replay)
- Canvas 渲染 (WASM/Web)
- HWP 编辑保存及 HWPX → HWP 转换保存路径
- Debug overlay(段落/表格边界 + 索引 + y 坐标)
### Multi-Renderer Backends (多渲染器后端)
- `PageRenderTree` 在后端 replay 之前可以降级为 `PageLayerTree` 绘制 IR。
- P1 公共接口是 Rust 原生的 `DocumentCore::build_page_layer_tree(page)` 和 WASM 的 `getPageLayerTree(page)`。
- Layer JSON 起始于 `schemaVersion: 1`,使用附加的 `schemaMinorVersion` / `resourceTableMinorVersion`,`unit: "px"` 以及 `coordinateSystem: "page-top-left-y-down"`,以匹配现有的页面渲染坐标。
- 兼容的 schema 变更应该是附加式的;不兼容的 JSON 结构变更需要提升 schema 版本号。
- **Legacy SVG** 仍作为默认的兼容性输出。
- **Layered SVG** 可通过 `RHWP_RENDER_PATH=layer-svg` 启用。
- Layered SVG 路径是一个过渡适配器,它将 `PageLayerTree` 扩展回现有的 SVG 渲染器。
- 浏览器/原生 Canvas 路径默认通过 `PageLayerTree` replay 进行渲染。
- Legacy Canvas 仍可通过 `renderPageCanvasLegacy` / `renderPageToCanvasLegacy` 进行一致性检查。
- P3 视觉回归覆盖在 `rhwp-studio` 中运行 `npm run e2e:render-diff:ci`,在 Chromium 中比较 legacy Canvas 和 layer Canvas;CI 会上传 render-diff 产物并编写摘要。
- 默认的 render-diff fixture 覆盖基本的文本/表格输出、商业文档排版以及 treat-as-char 对象放置;可以通过 `RHWP_RENDER_DIFF_FILES`、`RHWP_RENDER_DIFF_MAX_PAGES` 或 `RHWP_RENDER_DIFF_ALL=1` 覆盖。
- P4 在 `--features native-skia` 背后添加了仅限原生的 `DocumentCore::render_page_png_native(page)`;它通过 `SkiaLayerRenderer` 将 `PageLayerTree` 渲染为编码后的 PNG。
- P5 添加了来自 `EquationNode.layout_box` 的原生 Skia 公式 replay,因此公式不再是 PNG 路径中的占位框。
- P5 直接 replay 现有的公式 layout tree;它不添加 CanvasKit 公式 replay 或原生表单 replay。
- P6 通过 `resvg` 添加了原生 Skia `RawSvg` 片段栅格化,禁用了外部文件 href 加载。
- P11 添加了 Text IR v2 兼容性契约:`textSources`、每个 `TextRun` 的 source spans、paint 样式元数据、run placement/clusters、feature 数组以及显式的特殊文本视觉操作。`TextRun` 仍然是 fallback replay 路径。
- P12 添加了受保护的 `GlyphRun` sidecar 变体、字体 blob/face 标识元数据以及 shape-lowering API。Canvas2D/layered SVG 仍然使用 `TextRun` fallback;原生 Skia 在确切的 blob 支持的 typeface replay 接入之前也会保留 fallback。正常的降级不会 emit glyph id,除非 shaping pass 明确插入它们。
- P14 添加了受保护的 `GlyphOutline` sidecar 变体和后端文本变体选择诊断。现有的渲染器仍然保留 `TextRun` fallback 路径。
- P15-P17 添加了仅用于诊断的 CanvasKit replay 策略规划以及浏览器 CanvasKit 直接渲染器。`default` 和 `compat` 都禁止隐藏的 Canvas2D overlays;`compat` 是一种保守的直接 replay 策略,而不是 overlay fallback。
- P18 扩展了 CanvasKit 图像 replay,以处理 crop、fill mode、original size、transform 和 payload-fingerprint 缓存键,同时将图像效果留作确定性诊断。
- P19 为颜色层、位图字形和经过 sanitize 的静态 SVG 字形添加了受保护的、更丰富的 `GlyphOutline` payload 词汇表。它还开启了第一个明确的 CanvasKit replay 子集,用于 COLRv1 solid/linear/radial/sweep 颜色字形路径,同时将不支持的图形节点和其他 payload 系列保留在 `TextRun` fallback 上。
- P20 添加了字形 payload 资源标识键和原生 Skia 字体构建验证诊断。位图、SVG 和颜色字形 sidecar 不再仅仅因为它们的数字引用重叠而共享 replay/cache 标识,并且原生 Skia 会在启用 glyph-id replay 之前报告缺少的 blob bytes、face-index 和 variation 阻碍因素。
- 后续的渲染器扫描应评估规范化的 `PageLayerTree` replay 迭代器,以便 SVG、CanvasKit、原生 Skia、PDF 和 export API 共享相同的 background/behindText/flow/inFrontText 平面排序和 clip/group 上下文契约。
- CI 通过 `cargo test --features native-skia skia --lib` 覆盖原生 Skia 路径;该 feature 在 `wasm32` target 上不可用。
- 初始的原生 Skia 路径是一个 PNG 栅格化后端,具备核心图像/公式/raw-svg replay;完整的 CanvasKit 字形 replay、精确的原生字形 replay、真实的字体 blob 提取、复杂的文本 shaping、高级图像对齐以及原生表单 replay 留待后续工作。
- C ABI export 故意留待以后的 PR。
- `ResourceArena` 现在为字形 replay 保留了字体 blob 存储和字体资源标识;文档图像/SVG interning 留待后续工作。
- 此阶段确立了用于后续 CanvasKit 和更完整原生 Skia 后端的前端/后端边界。
### Web Editor (Web 编辑器)
- 文本编辑(插入、删除、撤销/重做)
- 字符/段落格式对话框
- 表格创建、行/列插入/删除、单元格公式
- hwpctl 兼容 API 层(兼容 Hancom Web 编辑器)
### hwpctl Compatibility (Hancom 兼容层)
- 30 个 Actions:TableCreate, InsertText, CharShape, ParagraphShape 等。
- ParameterSet/ParameterArray API
- Field API:GetFieldList, PutFieldText, GetFieldText
- 模板数据绑定支持
## npm 包 — 直接在 Web 上使用
当前发布版本为 `@rhwp/core` / `@rhwp/editor` v0.7.15。
### 嵌入编辑器(3 行代码)
将 HWP 编辑器整体嵌入到网页中。菜单、工具栏、样式、表格编辑 —— 所有功能均可直接使用。
```
npm install @rhwp/editor
```
```
```
### HWP 查看器/解析器(直接 API 调用)
直接使用基于 WASM 的解析器/渲染器将 HWP 文件渲染为 SVG
```
npm install @rhwp/core
```
```
import init, { HwpDocument } from '@rhwp/core';
globalThis.measureTextWidth = (font, text) => {
const ctx = document.createElement('canvas').getContext('2d');
ctx.font = font;
return ctx.measureText(text).width;
};
await init({ module_or_path: '/rhwp_bg.wasm' });
const resp = await fetch('document.hwp');
const doc = new HwpDocument(new Uint8Array(await resp.arrayBuffer()));
document.getElementById('viewer').innerHTML = doc.renderPageSvg(0);
```
| 包 | 用途 | 安装 |
|--------|------|------|
| [@rhwp/editor](https://www.npmjs.com/package/@rhwp/editor) | 完整的编辑器 UI (iframe) | `npm i @rhwp/editor` |
| [@rhwp/core](https://www.npmjs.com/package/@rhwp/core) | WASM 解析器/渲染器 (API) | `npm i @rhwp/core` |
## Quick Start (源码构建)
首次参与项目的开发者请先阅读 [新手指南](mydocs/manual/onboarding_guide.md)。可以快速了解项目架构、调试工具和开发工作流。
### 需求
- Rust 1.93.1(基于 `rust-toolchain.toml`)
- Docker(用于 WASM 构建)
- Node.js 18+(用于 Web 编辑器)
### Native Build
```
cargo build # Development build
cargo build --release # Release build
cargo test # Run tests (1,100+ tests)
```
### WASM Build
WASM 构建使用 Docker。这是为了保证跨平台拥有一致的 `wasm-pack` + Rust 工具链环境。
```
cp .env.docker.example .env.docker # 최초 1회: 환경변수 템플릿 복사
docker compose --env-file .env.docker run --rm wasm
```
构建结果将生成在 `pkg/` 目录中。
### Web 编辑器
```
cd rhwp-studio
npm install
npx vite --host 0.0.0.0 --port 7700
```
在浏览器中打开 `http://localhost:7700`。
## CLI 用法
### SVG 导出
```
rhwp export-svg sample.hwp # Export to output/
rhwp export-svg sample.hwp -o my_dir/ # Export to custom directory
rhwp export-svg sample.hwp -p 0 # Export specific page (0-indexed)
rhwp export-svg sample.hwp --debug-overlay # Debug overlay (paragraph/table boundaries)
```
### 文档检查
```
rhwp dump sample.hwp # Full IR dump
rhwp dump sample.hwp -s 2 -p 45 # Section 2, paragraph 45 only
rhwp dump-pages sample.hwp -p 15 # Page 16 layout items
rhwp info sample.hwp # File info (size, version, sections, fonts)
```
### 调试工作流
1. `export-svg --debug-overlay` → 通过 `s{section}:pi={index} y={coord}` 识别段落/表格
2. `dump-pages -p N` → 检查段落布局列表和高度
3. `dump -s N -p M` → 查看 ParaShape、LINE_SEG、表格属性
整个调试过程无需修改代码。
## 项目结构
```
src/
├── main.rs # CLI entry point
├── parser/ # HWP/HWPX file parser
├── model/ # HWP document model
├── document_core/ # Document core (CQRS: commands + queries)
│ ├── commands/ # Edit commands (text, formatting, tables)
│ ├── queries/ # Queries (rendering data, pagination)
│ └── table_calc/ # Table formula engine (SUM, AVG, PRODUCT, etc.)
├── renderer/ # Rendering engine
│ ├── layout/ # Layout (paragraph, table, shapes, cells)
│ ├── pagination/ # Pagination engine
│ ├── equation/ # Equation parser/layout/renderer
│ ├── svg.rs # SVG output
│ └── web_canvas.rs # Canvas output
├── serializer/ # HWP file serializer (save)
└── wasm_api.rs # WASM bindings
rhwp-studio/ # Web editor (TypeScript + Vite)
├── src/
│ ├── core/ # Core (WASM bridge, types)
│ ├── engine/ # Input handlers
│ ├── hwpctl/ # hwpctl compatibility layer
│ ├── ui/ # UI (menus, toolbars, dialogs)
│ └── view/ # Views (ruler, status bar, canvas)
├── e2e/ # E2E tests (Puppeteer + Chrome CDP)
│ └── helpers.mjs # Test helpers (headless/host modes)
mydocs/ # Project documentation (Korean)
├── orders/ # Daily task tracking
├── plans/ # Task plans and implementation specs
├── feedback/ # Code review feedback
├── tech/ # Technical documents
└── manual/ # Manuals and guides
scripts/ # Build & quality tools
├── metrics.sh # Code quality metrics collection
└── dashboard.html # Quality dashboard with trend tracking
```
## 使用 AI 结对编程进行开发
Vibe coding —— 不阅读 AI 输出就盲目接受、将架构决策交给 AI、部署自己无法理解的代码 —— 是一个陷阱。表面上看起来能运行,但因为不理解,出现问题时无法进行诊断,从而产生代码。
本项目采取截然相反的方法。人类**指挥官**完全掌控方向、质量和架构决策的所有权,而 AI 则以单靠人类无法企及的速度和规模执行实现。核心区别:**人类绝不停止思考。**
### Vibe Coding vs. AI 主导开发
| | Vibe Coding | 本项目 |
|--|-----------|-----------|
| **人类角色** | 接受 AI 输出 | 指示、审查、决策 |
| **计划** | 无 —— “直接做” | 编写计划书 → 批准 → 执行 |
| **质量关卡** | 祈祷能运行 | 1100+ 测试 + Clippy + CI + 代码审查 |
| **调试** | 让 AI 修复 AI 的 bug | 人类诊断,AI 实现 |
| **架构** | 偶然形成 | 有意设计 (CQRS, 依赖方向) |
| **文档** | 无 | 2200+ 文件的过程记录 |
| **产出** | 脆弱,难以维护 | 生产级,10 万行+ 代码 |
AI 是倍增器。但倍增器会放大现有的过程。无过程 × AI = 快速的混乱。良好的过程 × AI = 非凡的产出。
### 开发过程
本项目使用 **[Claude Code](https://claude.ai/code)** (Anthropic AI 编码 agent) 作为结对编程伙伴进行开发。整个开发过程都有透明文档记录。
```
작업지시자 (사람) AI 페어 프로그래머 (Claude Code)
──────────────── ─────────────────────────────
방향 설정, 우선순위 결정 → 분석, 계획, 구현
계획 검토, 승인 ← 구현 계획서 작성
도메인 피드백 제공 → 디버깅, 테스트, 반복
아키텍처 결정 → 정밀하게 실행
품질 및 정확성 판단 ← 코드, 문서, 테스트 생성
```
`mydocs/` 目录中包含完整的开发记录(2200+ 文件,英文翻译:`mydocs/eng/`):每日工作日志、实现计划书、代码审查反馈、技术研究文档、排障记录。
**[Hyper-Waterfall 方法论](mydocs/manual/hyper_waterfall.md)** — 宏观 Waterfall + 微观 Agile,AI 让这两者得以同时实现。
### Git 工作流
```
local/task{N} ──커밋──커밋──┐
├─→ devel merge (관련 타스크 묶어서)
├─→ main merge + 태그 (릴리즈 시점)
```
| 分支 | 用途 |
|--------|------|
| `main` | 发布(标签:v0.5.0 等) |
| `devel` | 开发集成 |
| `local/task{N}` | 基于 GitHub Issue 编号的任务分支 |
### 任务管理
- 使用 **GitHub Issues** 自动分配任务编号 —— 防止重复
- 使用 **GitHub Milestones** 对任务进行分组
- Milestone 标记:`M{version}`(例如:M100=v1.0.0, M05x=v0.5.x)
- 今日待办:`mydocs/orders/yyyymmdd.md` — 以 `M100 #1` 格式引用
- Commit 信息:`Task #1: 内容` — 使用 `closes #1` 自动关闭 Issue
### 任务执行流程
1. `gh issue create` → 创建 GitHub Issue(指定 milestone)
2. 创建 `local/task{issue编号}` 分支
3. 编写执行计划书 → 批准 → 实现 → 测试
4. 合并到 devel → `closes #{编号}`
### 调试协议
1. `export-svg --debug-overlay` → 识别段落/表格
2. `dump-pages -p N` → 布局列表和高度
3. `dump -s N -p M` → ParaShape, LINE_SEG 详情
### 文档生成规则
所有文档均以**韩语**编写。
```
mydocs/
├── orders/ # 오늘 할일 (yyyymmdd.md)
├── plans/ # 수행 계획서, 구현 계획서
│ └── archives/ # 완료된 계획서 보관
├── working/ # 단계별 완료 보고서
├── report/ # 기본 보고서
├── feedback/ # 코드 리뷰 피드백
├── tech/ # 기술 사항 정리 문서
├── manual/ # 매뉴얼, 가이드 문서
└── troubleshootings/ # 트러블슈팅 관련 문서
```
| 文档类型 | 位置 | 文件名规则 |
|----------|------|------------|
| 今日待办 | `orders/` | `yyyymmdd.md` — Milestone(M100)+Issue(#1) 格式 |
| 执行计划书 | `plans/` | 引用 Issue 编号 |
| 完成报告 | `working/` | 引用 Issue 编号 |
| 技术文档 | `tech/` | 按主题自由命名 |
## 架构
```
graph TB
HWP[HWP/HWPX File] --> Parser
Parser --> Model[Document Model]
Model --> DocumentCore
DocumentCore --> |Commands| Edit[Edit Operations]
DocumentCore --> |Queries| Render[Rendering Pipeline]
Render --> Pagination
Pagination --> Layout
Layout --> SVG[SVG Output]
Layout --> Canvas[Canvas Output]
DocumentCore --> WASM[WASM API]
WASM --> Studio[rhwp-studio Web Editor]
Studio --> hwpctl[hwpctl Compatibility Layer]
```
## HWPUNIT
- 1 inch = 7,200 HWPUNIT
- 1 inch = 25.4 mm
- 1 HWPUNIT ≈ 0.00353 mm
## 贡献
欢迎贡献。请首先确认以下核心事项:
- **PR 的基础分支是 `devel`**(而不是 `main`)。GitHub 的默认分支是 `main`,但所有的贡献 PR 都会合并到 `devel`。
- **首先确认 Issue**:请先查看 [开放的 Issue](https://github.com/edwardkim/rhwp/issues) 和 [开放的 PR](https://github.com/edwardkim/rhwp/pulls),确认是否有相同领域正在进行的工作。以防止重复工作。
- **Issue 的关闭由维护者操作**:工作完成后只需提交 PR。Issue 会在 PR 合并时由维护者关闭。
- **Hancom PDF 并非标准答案**:Hancom 工具(编辑器 / Viewer / Hancom Docs)、版本(2010 / 2020 / 2022)、输出路径(Hancom 本身 / OS 打印)的不同都会导致 PDF 结果不同。详情及各环境对比资料请参阅 [Hancom PDF 环境依赖性 Wiki](https://github.com/edwardkim/rhwp/wiki/한컴-PDF-환경-의존성)。
详细的贡献流程(Fork → 分支 → 提交 → PR)请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。
### Wiki 资料
我们正在 [Wiki](https://github.com/edwardkim/rhwp/wiki) 中整理有助于贡献者和 fork 用户的权威资料:
- [Hancom PDF 环境依赖性](https://github.com/edwardkim/rhwp/wiki/한컴-PDF-환경-의존성) — Hancom 工具 / 版本 / 操作系统导致的 PDF 差异详情及 PR 验证时的注意事项
- [HWP 5.0 Spec Errata](https://github.com/edwardkim/rhwp/wiki/HWP-5.0-Spec-Errata) — HWP 5.0 规范勘误表
- [HWP LINE_SEG vpos 理解](https://github.com/edwardkim/rhwp/wiki/HWP-LINE_SEG-vpos-이해) — 理解行分割 vpos
- [HWP Tab Leader Rendering](https://github.com/edwardkim/rhwp/wiki/HWP-Tab-Leader-Rendering) — Tab leader 渲染
- [Export API 使用指南](https://github.com/edwardkim/rhwp/wiki/Export-API-사용-가이드) — exportHwp / exportHwpx API
- [HWPX2HWP Probe 追踪新手指南](https://github.com/edwardkim/rhwp/wiki/HWPX2HWP-Probe-%EC%B6%94%EC%A0%81-%EC%98%A8%EB%B3%B4%EB%94%A9) — HWPX→IR→HWP 存储损坏/Hancom 兼容性 probe 追踪方法
- [使用 Cloudflared 实现 rhwp-studio 外部 HTTPS 访问](https://github.com/edwardkim/rhwp/wiki/Cloudflared-로-rhwp-studio-외부-HTTPS-접근)
- [Hyper-Waterfall 文档体系指南](https://github.com/edwardkim/rhwp/wiki/Hyper‐Waterfall-문서-체계-가이드)
- [Investigation PR 指南](https://github.com/edwardkim/rhwp/wiki/Investigation-PR-가이드)
- [Legal FAQ](https://github.com/edwardkim/rhwp/wiki/Legal-FAQ)
## 声明
本产品参考了 Hancom 公司的韩文文档文件(.hwp)公开文档进行开发。
## 商标
“Hangul”、“Hancom”、“HWP”、“HWPX”是 Hancom Inc. 的注册商标。
本项目是一个独立的开源项目,与 Hancom Inc. 不存在合作、赞助或认可关系。
"Hangul", "Hancom", "HWP", and "HWPX" are registered trademarks of Hancom Inc.
This project is an independent open-source project with no affiliation, sponsorship, or endorsement by Hancom Inc.
## 许可证
[MIT License](LICENSE) — Copyright (c) 2025-2026 Edward Kim