Korean official documents — hwp and hwpx
What this chapter covers Reading
.hwp/.hwpxas material, generating official documents from Markdown, and filling blank forms automatically.
The extension the previous chapter didn't have
Turning documents into material covered four formats —
pdf · docx · xlsx · pptx. The extension you meet most often in Korean
practice is not on that list.
Government notices, grant applications, internal drafts, meeting-minute
templates — they arrive as .hwp or .hwpx. And most automation stops right
there, because the received wisdom is that you need a Windows PC with Hancom
Office installed.
You don't.
First — the two extensions are different formats
This is where things go wrong most often.
.hwp | .hwpx | |
|---|---|---|
| What it is | Binary (HWP 5.x) | ZIP + XML |
| Reading | Works | Works |
| Writing / editing | Doesn't | Works |
Both can be read, but only .hwpx can be created or modified. Everything
generated, filled or patched below comes out as .hwpx. If someone needs
.hwp, a person re-saves it from Hangul at the end.
The tool — kordoc
One npm package, invoked without installing it.
- Node.js 18+ is the only requirement. No Hancom Office, no Windows, no COM automation. It runs on a macOS or Linux server as-is.
- Only the first call is slow while the package downloads; after that it's cached.
@^4pins the major version. That is the opposite of the advice for yt-dlp in the previous chapter — here the other side is a document format spec, not a platform, and it doesn't shift weekly.
1. Reading — anything into Markdown
The text copy idea from Turning documents into material holds here too. Put the Markdown next to the original and search starts working.
| What you want | What to add |
|---|---|
| A whole folder | -d ./converted/ |
| Specific pages | -p 1-3 or -p 1,3,5 |
| Structured JSON | --format json |
The same command also reads PDF, DOCX and XLS/XLSX — useful when a bundle from an agency arrives with mixed extensions.
Tables come out as HTML
<table>, not GFM. Merged and nested cells in official documents can't be expressed as pipe tables. That means the merges survived — use them as they are. Equations come out as LaTeX ($...$).
Spotting a scan
For PDFs, a text-layer quality signal is computed alongside the extraction. A
needsOcr signal means it's a scan — pictures of letters, not letters.
kordoc has no built-in OCR, so that's where you stop and find another route. A
PDF whose tables look shredded is usually this case.
2. Generating — from Markdown to an official document
There are seven presets — 기안문 (official draft) · 보고서 (report) ·
계획서 (plan) · 통지 (notice) · 회의록 (minutes) · 개조식 (outline
style, with cover and contents) · 보도자료 (press release).
What this automates is most of the actual tedium of official documents.
| What you write in Markdown | What comes out |
|---|---|
1. / indented - | The 8-level official numbering (1. → 가. → 1) → 가) → …) |
| — | Hamchorom Batang, official margins, standard formatting |
| GFM pipe tables | Tables |
$$...$$ | Native Hangul equations |
A ```chart fence | Native Hangul charts (column, line, pie, doughnut, …) |
Getting the numbering levels and hanging indents right by hand is slow and frequently wrong. Write the content in Markdown and hand off the formatting — that's the point of this command.
Body options: --font gothic · --pt <size> · --line-spacing <percent>, and
--plain to turn official-document mode off for a generic conversion.
3. Filling forms — applications with blanks
This is the most repetitive job of all — the one where you fill in the same application twenty times.
Order matters. Start by asking what can be filled.
You get the list of labels. Build your values from that list as JSON.
- Always pass values via
-j.-f 'k=v,...'works too, but the values end up in your shell history and in the process list. Given what goes into an application form, the reason is obvious. - Original fonts, sizes and alignment are preserved exactly. It doesn't look filled-in by a machine.
- Multi-line values use
\ninside the JSON string.
If the same label appears in several places, the default is to fill all of them. That's deliberate — repeating forms need it — but on some templates it will fill a cell you didn't mean. On a form you're using for the first time, check with
--dry-runhow many times a label occurs.
Seals
Finds an anchor phrase like "(인)" and floats the image in front of the text. Meaning tables and pages never grow — no more discovering that stamping the form pushed it onto an extra page. Use a transparent-background PNG.
4. Editing — while keeping the original formatting
For when only the wording of a received document needs to change.
In ② change content only. Keep structural moves and deletions to a minimum. Fonts, tables, objects and layout stay as they were in the original; only the text is written back in place.
Before you hand it over — validate and preview
Anything you generated or patched gets checked before it goes out.
validate inspects the ZIP structure, required parts and XML well-formedness —
this is where you catch the reasons a Hancom Docs upload would be rejected.
render draws the layout as SVG; files kordoc produced have no layout cache, so
--reflow is required for them.
Comparing two documents to produce a 신구대조표 (old/new comparison table) works as well — you get a diff at the article and paragraph level.
Running it in HyperTeams
A fixed conversion has no judgement in it, so it's terminal — the same
slot as the collection step in
Case study — the content factory.
When something has to decide what goes in the blanks, that part is a task.
Step 4 is a person for the same reason as in Guardrails. Submission can't be undone.
Using it from Connect
kordoc also attaches as an MCP server. That's the route when you want workspace members handling hwp files inside a conversation.
An interactive wizard registers it with your client. For the workspace side, see Connecting MCP servers and Tool settings. It adds eleven tools, so the warnings in When there are too many tools apply directly.
Things to be careful about
These forms carry personal data
Applications and HR forms contain national ID numbers, bank accounts, phone numbers.
The closing warning of Turning documents into material gets stronger here. The working directory is the agent's reach, and if the system is registered with Connect, workspace members reach it too.
Don't overwrite the original
Always write to a new file with -o — filling, patching and sealing alike.
Getting a blank official form again is often more trouble than it sounds.
Password-protected and DRM files won't open
DRM-wrapped documents distributed by an agency, or password-protected files, won't parse. That is not something to work around — it's a signal to find another route.
Check the numbers and the tables
Same as the previous chapter. If money, dates or quantities drive the decision, check the original. "Always verify numbers" from Things to watch applies with particular force to official documents.
Check yourself
1. Can you edit a .hwp file and write it back out in the same format?
Answer
You can read it, but you can't write that format back. Everything generated,
filled or patched comes out as .hwpx. If .hwp is required, a person re-saves
it from Hangul at the end.
2. Why pass form values via -j rather than -f?
Answer
Because the values land in shell history and the process list. What goes into an application form is usually personal data — ID numbers, bank accounts.
3. What do you do with a generated hwpx before handing it to someone?
Answer
Run validate on it. It checks the ZIP structure, required parts and XML
form, catching the reasons a Hancom Docs upload would be rejected. If the layout
is in doubt, look at it with render --reflow too.
That's the end of the Extending it part. If something is stuck → Troubleshooting · Guide contents