What this chapter covers Reading
.hwp/.hwpxas material, generating official documents from Markdown, and filling blank forms automatically.
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.
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.
One npm package, invoked without installing it.
@^4 pins 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.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 ($...$).
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.
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.
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.
-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.\n inside 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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
1. Can you edit a .hwp file and write it back out in the same format?
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?
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?
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
npx -y kordoc@^4 <command> ...npx -y kordoc@^4 business-plan.hwp -o business-plan.mdnpx -y kordoc@^4 draft.md -o report.hwpx --preset 보고서npx -y kordoc@^4 fill application.hwpx --dry-runnpx -y kordoc@^4 fill application.hwpx -j values.json -o filled.hwpxnpx -y kordoc@^4 seal application.hwpx --image seal.png --anchor "(인)" -o sealed.hwpxnpx -y kordoc@^4 original.hwpx -o edit.md # ① to Markdown# ② change the content in edit.mdnpx -y kordoc@^4 patch original.hwpx edit.md -o revised.hwpx # ③ back innpx -y kordoc@^4 validate result.hwpx # structure checknpx -y kordoc@^4 render result.hwpx --reflow -o preview.svg # look at itMondays 08:00 · kind: terminalnpx -y kordoc@^4 ./notices/*.hwp -d ./notices-md/1. terminal — extract labels from the form with --dry-run2. task — find the values in internal material, write values.json3. terminal — fill, then validate4. a person — check it and submitnpx -y kordoc@^4 setup□ Is values.json being committed to the repository?□ Is the filled result sitting in a shared folder?□ Did the values end up verbatim in a chat log?