한컴오피스 HWPX 문서를 AI 코딩 에이전트에서 다룰 수 있게 해주는 스킬입니다.
Обзор
한컴오피스 HWPX 문서를 AI 코딩 에이전트에서 다룰 수 있게 해주는 스킬입니다.
README
hwpxskill
한컴오피스 HWPX 문서를 AI 코딩 에이전트에서 다룰 수 있게 해주는 스킬입니다.
서식 보존이 중요한 편집에서는 OWPML XML을 직접 다루는 방식을 택했습니다. 덕분에 기존 문서의 서식이나 구조를 거의 그대로 유지하면서 내용만 갈아끼울 수 있습니다.
뭘 할 수 있나
원본 HWPX 파일을 넣으면 스타일, 표 구조, 셀 병합, 여백까지 분석해서 구조를 보존한 채 내용만 바꿔줍니다. 원본이 없으면 공문, 보고서 같은 내장 템플릿으로 새 문서를 만들 수도 있고요. 다 만들고 나면 page_guard.py가 원본 대비 페이지 수가 달라졌는지 자동으로 잡아냅니다.
OWPML 표준 XML을 직접 다루기 때문에 charPr, paraPr 단위로 서식을 제어할 수 있습니다. Claude Code, Cursor, Codex CLI에서 모두 동작합니다.
주요 업데이트
- 기존 HWPX 양식을 그대로 쓰는
edit_hwpx.py편집 경로를 강화했습니다. 일반 ZIP 재압축 대신 원본 로컬 헤더와 압축 데이터를 보존하고, 변경된Contents/section0.xml만 교체합니다. hwpx_slots.py를 추가해 편집 가능한 문단/표 셀 슬롯을 먼저 추출하고--slot-json으로 채우는 흐름을 지원합니다. 표, 그림, 텍스트상자 컨테이너 문단은 직접 수정하지 않습니다.- 텍스트 수정 문단의
hp:linesegarray줄 배치 캐시는 제거해 한컴의 손상/변조 경고 가능성을 줄입니다. finalize_hwpx.py를 추가해 줄 배치 캐시 제거, 표 셀 밀도, 제목 다음 본문 들여쓰기 같은 레이아웃 위험을 점검합니다. 이 도구도 원본 ZIP 메타데이터를 최대한 보존하며 필요한 XML 엔트리만 교체합니다.fix_namespaces.py를 추가해ns0같은 자동 네임스페이스 프리픽스를hh/hc/hp/hs표준 프리픽스로 정리하고header.xml의itemCnt를 보정합니다.gonmun_lint.py를 추가해 공문서 날짜, 시간, 금액, 붙임, 외국어 병기 표기 오류를 빠르게 검사합니다.- 문단 전체 재작성 시 원본의 볼드/색상 강조가 새 문장에 섞이지 않도록
header.xml의charPr를 분석합니다. 첫 run이나 10pt에 가까운 run을 무조건 고르지 않고, 해당 문단에서 가장 많이 쓰인 본문 글자 높이에 가까운 비강조 run을 선택합니다. content_guard.py를 추가해 구조 검증만으로 잡히지 않는 원문 잔재, placeholder, 필수 키워드 누락, 전면 재작성 시 원본 문장 과다 잔존을 검사합니다.page_guard.py는 문단/셀별 글자 예산과 XML 구조 fingerprint를 함께 비교합니다.hp:t내부 컨트롤은 보존하고,hp:linesegarray제거는 허용합니다.
참고한 프로젝트
이 저장소는 jkf87/hwpx-skill의 최종화/검수 흐름과 문서화 방식을 참고해 보완했습니다. 특히 네임스페이스 보정, 줄 배치 캐시 제거, 레이아웃 위험 경고, 공문서 표기 검수 아이디어를 참고했고, 구현은 이 저장소의 원본 ZIP 메타데이터 보존 원칙에 맞춰 재구성했습니다. 자세한 비교 메모는 references/jkf87-hwpx-skill-comparison.md에 정리했습니다.
설치
Agent Skills 표준을 따르고 있어서, 어떤 도구든 스킬 디렉토리에 넣기만 하면 됩니다.
git clone https://github.com/Canine89/hwpxskill.git
Claude Code
# 이 프로젝트에서만 쓸 때
cp -r hwpxskill .claude/skills/hwpxskill
# 어디서든 쓸 때
cp -r hwpxskill ~/.claude/skills/hwpxskill
넣어두면 HWPX 관련 작업할 때 알아서 불러옵니다.
Cursor
# 이 프로젝트에서만 쓸 때
cp -r hwpxskill .cursor/skills/hwpxskill
# 어디서든 쓸 때
cp -r hwpxskill ~/.cursor/skills/hwpxskill
.hwpx 파일을 열 때 자동으로 활성화되게 하려면 rule 파일을 하나 추가하면 됩니다.
# .cursor/rules/hwpx.mdc
---
description: "HWPX 문서 작업 시 hwpxskill 사용"
globs: ["*.hwpx"]
---
Codex CLI
# 이 프로젝트에서만 쓸 때
cp -r hwpxskill .agents/skills/hwpxskill
# 어디서든 쓸 때
cp -r hwpxskill ~/.agents/skills/hwpxskill
Codex 세션 안에서 $skill-installer로 설치할 수도 있습니다.
빠른 시작
1. 새 문서 만들기
템플릿 골라서 바로 생성. 원본 파일 없을 때 씁니다.
python3 scripts/build_hwpx.py --template gonmun --output result.hwpx
2. 기존 문서 편집
양식을 유지하면서 텍스트나 표 셀만 바꿀 때는 edit_hwpx.py를 씁니다. 원본 ZIP 패키지, header.xml, content.hpf, BinData, 표 크기, 셀 병합, 서식 참조를 그대로 두고 Contents/section0.xml의 텍스트 노드만 최소 수정합니다.
python3 scripts/edit_hwpx.py reference.hwpx \
--output filled.hwpx \
--replace "{{기관명}}=고용노동부" \
--cell "0,2,1=테스트 법인"
python3 scripts/hwpx_slots.py reference.hwpx \
--output reference.slots.json
python3 scripts/edit_hwpx.py reference.hwpx \
--output rewritten.hwpx \
--slot-json values.json
python3 scripts/validate.py filled.hwpx
python3 scripts/fix_namespaces.py filled.hwpx
python3 scripts/finalize_hwpx.py filled.hwpx --strip-linesegarray --layout
python3 scripts/validate.py filled.hwpx --layout
python3 scripts/page_guard.py \
--reference reference.hwpx \
--output filled.hwpx \
--no-strict-paragraph-budget \
--skip-text-drift \
--allow-empty-fill
python3 scripts/content_guard.py filled.hwpx \
--forbid "고용노동부" \
--forbid "044-" \
--require "미국노동부"
python3 scripts/content_guard.py rewritten.hwpx \
--reference reference.hwpx \
--rules content.rules.json \
--max-unchanged-ratio 0.35
좌표는 0부터 시작합니다. --cell "row,col=값"은 첫 번째 표를 대상으로 하고, --cell "table,row,col=값"은 특정 표를 대상으로 합니다.
본문을 실무적으로 고쳐 쓰는 경우에는 먼저 hwpx_slots.py로 편집 가능한 슬롯을 뽑고, --slot-json으로 값을 넣습니다. 이 경로는 표/그림/텍스트상자 컨테이너 문단을 직접 건드리지 않아 새 텍스트가 기존 텍스트와 겹치는 문제를 줄입니다. 문단 전체를 바꿀 때는 header.xml의 charPr를 보고 볼드/색상 강조가 적고, 해당 문단에서 가장 많이 쓰인 본문 글자 높이에 가까운 run을 골라 새 문장을 넣습니다. 본문은 원본 문단 예산 이하로 짧게 다시 써야 하며, 글자 수를 정확히 맞추려고 띄어쓰기를 제거하거나 문장을 중간에서 자르면 안 됩니다.
글자 수까지 더 엄격히 맞추려면 먼저 원본 양식의 예산 프로파일을 만듭니다. 이 파일에는 문단/셀별 기존 글자 수와 셀 폭 기반 입력 가능 글자 수가 저장됩니다.
python3 scripts/page_guard.py \
--reference reference.hwpx \
--write-budget reference.budget.json \
--write-structure reference.structure.json
python3 scripts/page_guard.py \
--reference reference.hwpx \
--output filled.hwpx \
--budget-profile reference.budget.json \
--structure-profile reference.structure.json \
--no-strict-paragraph-budget \
--skip-text-drift \
--allow-empty-fill
이 검사는 표 구조가 같더라도 특정 셀의 글자 수가 원본 셀 예산을 넘으면 실패합니다. 본문 문단은 --no-strict-paragraph-budget --skip-text-drift를 사용해 정확 일치가 아니라 예산 이하와 구조 보존 여부를 봅니다. --write-structure는 패키지 파일 목록/순서, 압축 방식, 날짜, 생성 시스템, 파일 속성, 바이너리 해시, XML 태그/속성/순서를 저장하고 결과 문서와 대조합니다. hp:t의 텍스트 값은 내용 입력 대상으로 제외하지만, hp:t 안의 hp:fwSpace, hp:lineBreak 같은 자식 컨트롤 태그와 순서는 반드시 보존해야 합니다. 반대로 문단 하위 hp:linesegarray는 한컴이 저장한 줄 배치 캐시이므로 텍스트를 바꾼 문단에서는 제거합니다.
구조 검사를 통과해도 원문 기관명, 담당자, 전화번호, ○○ placeholder가 남아 있으면 실무 결과물이 아닙니다. 그런 경우 content_guard.py로 금지어와 필수어를 검사합니다. 예를 들어 보도자료를 미국노동부 문서로 바꿨다면 고용노동부, 기존 담당자명, 044- 연락처를 금지하고 미국노동부를 필수어로 둡니다.
문서 전체 관점 전환이나 전면 재작성이라면 --reference와 --max-unchanged-ratio도 같이 씁니다. 원본의 긴 문장이 많이 남은 결과물은 구조가 정상이더라도 실패로 봅니다.
공문서 표기 자체를 점검해야 하면 gonmun_lint.py를 추가로 실행합니다.
python3 scripts/gonmun_lint.py --hwpx filled.hwpx --format text
edit_hwpx.py는 새 ZIP을 일반 재압축하지 않고 원본 ZIP의 로컬 헤더와 압축 데이터를 복사합니다. 변경 대상인 Contents/section0.xml만 교체하고, 나머지 엔트리는 CRC, compressed size, flag bits, 날짜, 속성까지 원본과 같게 유지합니다. section0.xml도 원본 XML 선언과 줄바꿈 관습을 최대한 유지합니다.
직접 XML을 확인해야 할 때만 HWPX를 풀고 다시 묶습니다. 기본 unpack.py는 XML을 원본 바이트 그대로 추출합니다. hp:t처럼 텍스트와 hp:fwSpace, hp:lineBreak 같은 자식 컨트롤이 섞인 mixed content 안에 들여쓰기 공백이 들어가면 한컴에서 실제 텍스트처럼 렌더링될 수 있기 때문입니다.
python3 scripts/office/unpack.py document.hwpx ./unpacked/
# XML 수정
python3 scripts/office/pack.py ./unpacked/ edited.hwpx
XML을 사람이 읽기 좋게 확인해야 할 때만 --pretty를 사용합니다. 이 결과물은 검사 전용이며 다시 pack.py 입력으로 쓰지 않습니다.
python3 scripts/office/unpack.py document.hwpx ./inspect/ --pretty
3. 텍스트 추출
문서에서 텍스트만 뽑습니다. 표도 포함되고, 마크다운으로도 뽑을 수 있습니다.
python3 scripts/text_extract.py document.hwpx --format markdown
4. 문서 검증
ZIP 구조, XML 유효성, mimetype 위치 같은 걸 점검합니다.
python3 scripts/validate.py result.hwpx
5. 레퍼런스 기반 복원
이게 핵심입니다. 원본 문서를 분석해서 스타일과 구조를 통째로 가져온 뒤, 내용만 갈아끼웁니다. HWPX 파일을 첨부하면 이 흐름이 자동으로 돌아갑니다.
# 분석
python3 scripts/analyze_template.py reference.hwpx \
--extract-header /tmp/ref_header.xml \
--extract-section /tmp/ref_section.xml
# 빌드
python3 scripts/build_hwpx.py \
--header /tmp/ref_header.xml \
--section /tmp/new_section0.xml \
--output result.hwpx
# 검증 + 페이지 가드
python3 scripts/validate.py result.hwpx
python3 scripts/page_guard.py --reference reference.hwpx --output result.hwpx
6. 회귀 테스트
hp:t 내부 컨트롤 삭제처럼 한컴에서 손상으로 이어지는 변경을 막는 테스트입니다.
python3 -m unittest tests/test_hwpx_guards.py
템플릿
| 템플릿 | 용도 | 특징 |
|---|---|---|
| base | 기본 골격 | 최소 스타일, 빈 문서 시작점 |
| gonmun | 공문서 | 기관명, 수신처, 시행일자, 연락처 |
| report | 보고서 | 섹션 헤더, 들여쓰기, 체크박스 |
| minutes | 회의록 | 섹션 라벨, 테두리 구분 |
| proposal | 제안서 | 색상 헤더, 번호 뱃지 |
요구사항
- Python 3.6 이상
- lxml (
pip install lxml) - 가상환경 권장
스크립트
| 스크립트 | 하는 일 |
|---|---|
build_hwpx.py |
템플릿 + XML 조합해서 HWPX 생성 |
edit_hwpx.py |
원본 양식을 보존하며 텍스트/표 셀만 수정 |
analyze_template.py |
레퍼런스 HWPX 분석 |
office/unpack.py |
HWPX를 디렉토리로 풀기, 기본값은 XML 바이트 보존 |
office/pack.py |
디렉토리를 HWPX로 묶기 |
validate.py |
HWPX 구조, manifest, 이미지 참조 검증 |
fix_namespaces.py |
표준 네임스페이스 프리픽스와 header itemCnt 보정 |
finalize_hwpx.py |
줄 배치 캐시 제거, 레이아웃 위험 경고, Windows Hancom 열림 검사 |
page_guard.py |
원본 대비 페이지 드리프트 위험 감지, 문단/셀별 글자 예산 검증 |
content_guard.py |
원문 잔재, placeholder, 필수 키워드 누락 검사 |
gonmun_lint.py |
공문서 날짜/시간/금액/붙임 표기 검수 |
text_extract.py |
XML 직접 파싱 기반 텍스트 추출 |
자세한 사용법
스타일 ID 체계, XML 구조 규칙, 템플릿별 charPr/paraPr 매핑 같은 건 SKILL.md에 다 정리되어 있습니다.
Рекомендуемые инструменты
Попробуйте другой запрос или уберите фильтр.
Установка
npx skillfish add canine89/hwpxskill