νκ΅μ΄: README.md English: README.en.md
hwpxctlμ HWPX λ¬Έμλ₯Ό ZIP/XML ν¨ν€μ§λ‘ λ€λ£¨λ CLIμ
λλ€. νμ¬ μ€μ¬ λ°©ν₯μ low-level XML surgery λꡬλ₯Ό μ μ§νλ©΄μ, κΈ°μ‘΄ λ³΅ν© μμμ μμ νκ² λΆμνκ³ μ±μ°λ Template-First νΈμ§ νλ¦μ κ°ννλ κ²μ
λλ€.
.hwpxνμΌμ ꡬ쑰λ₯Όinspect,validate,textλ‘ νμΈanalyze-template,find-targets,scaffold-template-contract,fill-template --template --payloadκΈ°λ° Template-First νλ¦ μ§μ- unpack λλ ν°λ¦¬ κΈ°μ€μΌλ‘ λ¬Έλ¨, λ¬Έλ¨ μ λ ¬/λ€μ¬μ°κΈ°/κ°κ²©, λͺ©λ‘, ν, μΉμ , κ°μ£Ό/λ―Έμ£Ό, 머리λ§/꼬리λ§, νμ΄νΌλ§ν¬, μμ, λ©λͺ¨, λν νΈμ§
- Markdown/HTML export μ§μ
- μ€νμΌ, κ°μ²΄, XML νκ·Έ/μμ±/XPath κΈ°λ° κ²μ μ§μ
- opt-in
historyEntryλ³κ²½ μΆμ μ§μ - μ΅μ’
κ²μ¦μ
Hancom Office HWP ViewerPDF μΈμ κ²°κ³Ό κΈ°μ€
v1λ²μμ κ³ μμ€ νΈμ§/κ²μ/export κΈ°λ₯μ λλΆλΆ ꡬνλ¨- λΉ λ¬Έμμμ ν κΈ°λ° μμμ μ¬κ΅¬μ±νλ λ° νμν νμ΄μ§ λ μ΄μμ, ν°νΈ, μ μ€νμΌ, merge/border κΈ°λ₯μ΄ ν¬ν¨λ¨
set-paragraph-text,set-run-text,set-table-cell,find-runs-by-style,replace-runs-by-style,find-objects,find-by-tag,find-by-attr,find-by-xpathλ--sectionλλ--all-sectionsκΈ°λ° λ€μ€ section λ²μλ₯Ό μ§μν¨- λ³κ²½ μΆμ μ νμ¬
history-only1μ°¨ ꡬνμ - low-level XML/history/version μ κ·Όμ λ€μ λ¨κ³λ‘ λ¨μ μμ
νμ¬ λ°©ν₯κ³Ό ꡬ쑰λ docs/architecture.md, λ¨κ³ κ³νμ docs/roadmap.md, μ€μ μ§ν μνλ docs/progress.mdμμ νμΈν μ μμ΅λλ€.
- macOS: CLI νΈμ§ +
Hancom Office HWP ViewerPDF μΈμ κ²μ¦κΉμ§ μ 체 νλ¦ μ§μ - Linux / CI: CLI νΈμ§, validate, export, ν μ€νΈλ κ°λ₯νμ§λ§ Viewer μλ μΈμ κ²μ¦μ μ§μνμ§ μμ
- Windows / PowerShell: CLI λΉλμ κΈ°λ³Έ νΈμ§ νλ¦μ κ°λ₯νμ§λ§ Viewer μλ μΈμ κ²μ¦ μ€ν¬λ¦½νΈλ μ§μνμ§ μμ
ν΅μ¬ μ°¨μ΄λ scripts/print_hwpx_via_viewer.pyκ° macOSμ osascriptμ Hancom Office HWP Viewerμ μμ‘΄νλ€λ μ μ
λλ€.
- νμ¬ λ°°ν¬ λ°©μ κΈ°μ€μΌλ‘ μ€μΉ μ
Go toolchainμ΄ λ¨Όμ μμ΄μΌ ν©λλ€ - Go
1.26+ - Python
- macOSμμ μ΅μ’
λ λ κ²μ¦μ΄ νμνλ©΄
Hancom Office HWP Viewer
νμ¬λ Homebrew, apt, winget, prebuilt release binary λ°°ν¬λ₯Ό μμ§ μ 곡νμ§ μμ΅λλ€.
μ¦ go install λλ go buildλ‘ μ€μΉνλ νλ¦μ΄ κΈ°λ³Έμ
λλ€.
κ³΅κ° μ μ₯μ κΈ°μ€μΌλ‘λ go install λ°©μμ΄ κ°μ₯ μΌλ°μ μ
λλ€.
go install github.com/zarathucorp/project-hwpx-cli/cmd/hwpxctl@latestμ€μΉ ν μ€ν νμΌμ λ³΄ν΅ GOBIN λλ $(go env GOPATH)/bin μλμ λμ
λλ€.
μ νκ²½μμλ λ³΄ν΅ μ¬κΈ°κΉμ§λ‘ λλμ§ μκ³ , κ·Έ λλ ν°λ¦¬λ₯Ό PATHμ μΆκ°ν΄μΌ ν°λ―Έλμμ hwpxctlμ΄ λ°λ‘ μ‘νλλ€.
νμ¬ μ€μΉ μμΉλ μλ λͺ
λ ΉμΌλ‘ νμΈν μ μμ΅λλ€.
go env GOBIN
go env GOPATHνμ¬ μ Έμμλ§ λ°λ‘ μ°λ €λ©΄:
export PATH="$(go env GOPATH)/bin:$PATH"μꡬ λ°μμ μ¬μ©νλ μ Έ μ€μ νμΌμ κ°μ μ€μ μΆκ°νλ©΄ λ©λλ€.
- zsh:
~/.zshrc - bash:
~/.bashrcλλ~/.bash_profile
μλ₯Ό λ€μ΄ macOS κΈ°λ³Έ zsh νκ²½μ΄λ©΄ μλ μμκ° κ°μ₯ μΌλ°μ μ
λλ€.
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
command -v hwpxctl
hwpxctl --helpμνλ©΄ κΈ°λ³Έ μ€μΉ μμΉ λμ λ³λ bin λλ ν°λ¦¬λ₯Ό μ§μ ν μλ μμ΅λλ€.
go env -w GOBIN="$HOME/.local/bin"νμ¬ μ¬μ©μ PATHμ Go λ°μ΄λ리 λλ ν°λ¦¬λ₯Ό μΆκ°νλ μΌλ°μ μΈ λ°©μμ μλμ κ°μ΅λλ€.
$goBin = "$(go env GOPATH)\bin"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";" + $goBin, "User")μ PowerShell μ°½μ μ° λ€ μλμ²λΌ νμΈν©λλ€.
Get-Command hwpxctl.exe
hwpxctl.exe --helpκ°λ° μ€μ΄κ±°λ λ‘컬 μμ λ³Έμ λ°λ‘ μ€ννκ³ μΆμΌλ©΄ μλ λ°©μλ μΈ μ μμ΅λλ€.
go build -o "$(go env GOPATH)/bin/hwpxctl" ./cmd/hwpxctl
hwpxctl --helpgo install github.com/zarathucorp/project-hwpx-cli/cmd/hwpxctl@latest
echo 'export PATH="$HOME/go/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
command -v hwpxctl
hwpxctl inspect ./sample.hwpx
hwpxctl unpack ./sample.hwpx --output ./work/sample
hwpxctl append-text ./work/sample --text "κ²ν λ¬Έλ¨"
hwpxctl pack ./work/sample --output ./output/sample-edited.hwpxgo install github.com/zarathucorp/project-hwpx-cli/cmd/hwpxctl@latest
export PATH="$(go env GOPATH)/bin:$PATH"
command -v hwpxctl
hwpxctl validate ./sample.hwpx --format json
hwpxctl unpack ./sample.hwpx --output ./work/sample
hwpxctl append-text ./work/sample --text "κ²ν λ¬Έλ¨"
hwpxctl pack ./work/sample --output ./output/sample-edited.hwpx
hwpxctl text ./output/sample-edited.hwpx --format jsongo install github.com/zarathucorp/project-hwpx-cli/cmd/hwpxctl@latest
$goBin = "$(go env GOPATH)\bin"
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";" + $goBin, "User")
$env:Path = [Environment]::GetEnvironmentVariable("Path", "User")
Get-Command hwpxctl.exe
hwpxctl.exe inspect .\sample.hwpx
hwpxctl.exe unpack .\sample.hwpx --output .\work\sample
hwpxctl.exe append-text .\work\sample --text "κ²ν λ¬Έλ¨"
hwpxctl.exe pack .\work\sample --output .\output\sample-edited.hwpxhwpxctl inspect ./sample.hwpx
hwpxctl unpack ./sample.hwpx --output ./work/sample
hwpxctl set-text-style ./work/sample --paragraph 0 --font-name "λ§μ κ³ λ" --font-size-pt 12
hwpxctl pack ./work/sample --output ./output/sample-edited.hwpxhwpxctl analyze-template ./sample.hwpx --format json
hwpxctl find-targets ./sample.hwpx --placeholder PROJECT_TITLE --format json
hwpxctl scaffold-template-contract ./sample.hwpx --output ./output/template.yaml --payload-output ./output/payload.yaml
hwpxctl fill-template ./work/sample --template ./output/template.yaml --payload ./output/payload.yaml --roundtrip-check true --format json
hwpxctl safe-pack ./work/sample --output ./output/sample-filled.hwpx --force truehwpxctl create --output ./work/form
hwpxctl set-page-layout ./work/form --orientation PORTRAIT --width-mm 210 --height-mm 297 --left-margin-mm 25 --right-margin-mm 25 --top-margin-mm 15 --bottom-margin-mm 15
hwpxctl add-table ./work/form --rows 4 --cols 3 --width-mm 160
hwpxctl merge-table-cells ./work/form --table 0 --start-row 0 --start-col 0 --end-row 0 --end-col 2
hwpxctl set-table-cell ./work/form --table 0 --row 0 --col 0 --text "μ λͺ©" --font-name "λ§μ κ³ λ" --font-size-pt 14 --bold true
hwpxctl normalize-table-borders ./work/form --table 0
hwpxctl pack ./work/form --output ./output/form.hwpxhwpxctl schema
hwpxctl validate ./sample.hwpx --format json
hwpxctl find-runs-by-style ./work/sample --font-name "λ§μ κ³ λ" --font-size-pt 12 --format jsonpython ./scripts/print_hwpx_via_viewer.py ./output/sample-edited.hwpxμμΈ λͺ λ Ή κ³μ½κ³Ό μ΅μ μ docs/cli-reference.mdμμ νμΈνλ κ²μ κΈ°λ³ΈμΌλ‘ ν©λλ€.
- docs/cli-reference.md: λͺ λ Ήλ³ μ λ ₯, μΆλ ₯, μ΅μ , JSON envelope
- docs/progress.md: νμ¬ μ§ν μνμ μΉΈλ°
- docs/architecture.md: νμ¬ μ½λ κΈ°μ€ μν€ν μ² κ΅¬μ‘°
- docs/agent-guide.md: AI μμ΄μ νΈ νΈμΆ μμμ κΆμ₯ μ¬μ© ν¨ν΄
- docs/example-table-playbook.md: example νλ₯Ό νμ΄μ§ λ¨μλ‘ λ€μ λ§λλ μμ ν κ°μ΄λμ μνμ°©μ€ λ©λͺ¨
- docs/example-parity-harness.md: example μλ³Έκ³Ό μμ±λ³Έμ κ°μ κ²μ¦ 루νλ‘ λΉκ΅νλ parity νλ€μ€ μλ΄
- docs/roadmap.md: ꡬν λ²μμ λ€μ μμ μ°μ μμ
- docs/research-notes.md: HWPX ꡬ쑰 λ©λͺ¨μ μ€κ³ λ°°κ²½
- κ³΅κ° μ μ₯μμλ λ―Όκ°νκ±°λ μ μκΆ μ΄μκ° μμ μ μλ μλ³Έ
example/*.hwpxλ₯Ό ν¬ν¨νμ§ μλ κ²μ κΈ°λ³Έκ°μΌλ‘ ν©λλ€ - sample μλ³Έμ΄ νμνλ©΄ λ‘컬 private κ²½λ‘λ₯Ό μ§μ μ§μ ν΄ μ¬μ©νλ νλ¦μ κΆμ₯ν©λλ€
- λ¬Έμ μ¬μ΄νΈλ GitHub Pagesμ νμν λ μλ λ°°ν¬νλ ꡬμ±μ κΈ°λ³ΈμΌλ‘ λ‘λλ€
- ꡬ쑰 κ²μ¦μ΄λ λ¨μ ν μ€νΈλ§μΌλ‘ μλ£ μ²λ¦¬νμ§ μμ΅λλ€
- νΈμ§ κΈ°λ₯μ κ°λ₯νλ©΄ μ€μ
.hwpxμ°μΆλ¬Όμ λ§λ λ€Hancom Office HWP Viewerλ‘ PDF μΈμ κ²μ¦κΉμ§ μνν©λλ€ - κΈ°λ³Έ κ²μ¦ μ€ν¬λ¦½νΈλ
python ./scripts/print_hwpx_via_viewer.py <file.hwpx>μ λλ€ - κ²μ¦ μ°μΆλ¬Όμ
output/μλμ λ¨κ²¨ before/after λΉκ΅κ° κ°λ₯νλλ‘ μ μ§ν©λλ€
- cmd/hwpxctl/main.go: CLI μ§μ μ
- internal/cli/cobra.go: μλΈμ»€λ§¨λ λΌμ°ν κ³Ό help μ°κ²°
- internal/cli/root.go: κ³΅ν΅ μ΅μ
, μλ¬ envelope,
schema - internal/hwpx/core: ν¨ν€μ§ μ½κΈ°/μ°κΈ°μ export ν΅μ¬ λ‘μ§
- internal/hwpx/shared: κ³΅ν΅ XML νΈμ§ μ νΈλ¦¬ν°
- scripts/print_hwpx_via_viewer.py: νμ»΄ λ·°μ΄ PDF μΈμ κ²μ¦ μ€ν¬λ¦½νΈ
- μΌλΆ νΈμ§/λ μ΄μμ λͺ λ Ήμ μμ§ μ²« section μ€μ¬μΌλ‘ λμν©λλ€
- Viewer PDF μλ μΈμ κ²μ¦μ νμ¬ macOS μ μ©μ λλ€
- λ³κ²½ μΆμ μ visible trackingμ΄ μλλΌ
historyEntryκΈ°λ‘ μμ£Όμ λλ€ .hwpλ μ§μνμ§ μκ³.hwpxλ§ λ€λ£Ήλλ€- low-level XML part μ‘°ν/νΈμ§ APIλ μμ§ μ μ λ ΈμΆνμ§ μμμ΅λλ€