"**HWP/HWPX 통합 편집기 (듀얼 백엔드)**: 한글(Hancom) 문서를 사람처럼 편집한다. Windows에서는 pyhwpx COM 자동화로 한컴오피스를 직접 구동(양식 완전 보존, 수식·표·그림 네이티브 삽입, PDF 검증 루프), 리눅스/샌드박스에서는 기존 hwpx 스킬의 바이트 보존 XML 편집으로 폴백. LaTeX→한글 수식(HwpEqn) 자동 변환 내장. Claude Code·Codex·Cowork 공용.\n - MANDATORY TRIGGERS: HWP, HWPX, .hwp, .hwpx, 한글, 한글파일, 한컴, Hancom, 수식 삽입, 한글 편집, 한글 자동화, pyhwpx"
Resources
7Install
npx skillscat add pantagram1031/hwp-master Install via the SkillsCat registry.
SKILL.md
HWP Master — 듀얼 백엔드 한글 문서 편집
0. 백엔드 선택 (반드시 먼저 판단)
질문 1: 지금 Windows이고 한컴오피스가 설치되어 있는가?
├─ YES → [COM 백엔드] scripts/com_backend.py ← 기본 선택
│ (기존 양식 자동 보존, 수식/그림/표 네이티브, .hwp도 직접 편집 가능)
└─ NO (리눅스/claude.ai 샌드박스/macOS)
├─ 파일이 .hwpx → [XML 백엔드] 기존 hwpx 스킬 (modify_hwpx.py / generate_hwpx.py)
└─ 파일이 .hwp → 편집 불가. 사용자에게 .hwpx로 다시 저장해 달라고 요청하거나,
Windows 환경(Claude Code/Codex 로컬)에서 convert 후 진행.확인 방법: python -c "import sys; print(sys.platform)" → win32이고pip show pyhwpx가 성공하면 COM 가능. pyhwpx 미설치 시:pip install pyhwpx pywin32 (한글 2022 + Python 3.11/3.12 권장).
1. COM 백엔드 워크플로우 (Windows)
철칙: 원본을 직접 덮어쓰지 않는다. 항상 --save-as로 새 파일에 저장.
Step 1 — 구조 파악 (토큰 절약: 전체 본문을 절대 덤프하지 말 것)
python SKILL_DIR/scripts/com_backend.py inspect --file 보고서.hwp→ 본문 미리보기, 필드(누름틀) 목록, 표/수식/그림 개수, 기존 수식 스크립트, 쪽수가
JSON으로 나온다. 이걸 기반으로 편집 계획을 세운다.
Step 2 — ops JSON 작성 후 배치 편집
python SKILL_DIR/scripts/com_backend.py edit \
--file 보고서.hwp --ops ops.json \
--save-as 보고서_v2.hwpx --export-pdf verify.pdfops 예시 (위에서 아래로 순차 실행):
[
{"op": "put_field", "name": "작성자", "value": "이하율"},
{"op": "replace_all", "find": "{{날짜}}", "replace": "2026.06.11."},
{"op": "goto_text", "text": "3. 실험 결과"},
{"op": "move", "to": "line_end"},
{"op": "insert_text", "text": "\r\n측정된 음압 레벨은 다음 식으로 계산하였다.\r\n"},
{"op": "insert_equation", "latex": "L_p = 10 \\log \\frac{p^2}{p_0^2}", "base_pt": 11},
{"op": "insert_table", "data": [["주파수(Hz)","측정값(dB)"],["500","42.1"],["1000","38.7"]]},
{"op": "insert_picture", "path": "C:/work/그래프.png", "width_mm": 100}
]Step 3 — 검증 루프 (필수, 매 편집 후)
edit출력의post_inspect로 표/수식 개수가 의도대로 늘었는지 확인.verify.pdf를 직접 열어 시각 확인 (레이아웃 깨짐, 수식 렌더링, 표 정렬).- 글자색 상속 확인 — 파란/색 안내문 자리에 삽입한 본문은 그 색을 상속한다.
PDF에서 의도치 않은 색 글자가 있으면set_char_color(기본 all=true)로 일괄 검정 처리.set_font(TextColor=...)경유라 크기·굵기 등 다른 속성은 불변. - 레이아웃 QA (수치 게이트 → 시각 이중 게이트) — 빈 문단(엔터) 잔재로 인한
과다 공백을 미적 판단이 아니라 수치로 가린다.- 수치 게이트:
python scripts/layout_qa.py --file verify.pdf→ 페이지별 하단 공백
비율·블록 간 최대 간격(본문 줄높이 배수)을 JSON으로. 기본 임계 하단 ≤25%(마지막
쪽 제외)·간격 ≤3줄. 간격은 '빈 문단 구멍'만 잡도록 그림이 점유한 세로 구간은
제외(그림은 PNG 여백·도형으로 본질적 공간 차지). 임계는 인자로만 바꾼다. - 보정: 연속 빈 문단은
collapse_empty_paragraphs(^n^n^n→^n^n, 1빈줄은 보존).
그림 캡션↔이미지 밀착은delete_blank_after(캡션 앵커), 객체 앞 빈 문단은delete_blank_before(뒤 캡션 앵커). 과압축 금지 — 표·그림 앞뒤 1빈줄과 항목
사이 구분 공백은 정상. - 시각 게이트: 수치 통과 후
fitz로 전 페이지 PNG 렌더해 직접 확인(헤딩 아래 간격,
그림-캡션 밀착, 고아줄/반쪽 빈 페이지). 수치 통과인데 어색하면 근거와 함께 보고.
- 수치 게이트:
- 문제 발견 시: 원본은 그대로이므로 ops를 수정해 재실행 (Ratchet — 통과 전까지 저장본 교체 금지).
인라인 객체 원칙 (큰 객체는 자기 문단)
- 그림·display 수식은 본문 문단에 끼우지 말고 자기 문단(가운데 정렬)에 단독으로 둔다.
고립 텍스트(캡션 줄이 그림 옆에 낌)·수식 줄 걸림·자간 과도 확장은 거의 전부 인라인
객체 위반에서 나온다. - 그림:
insert_picture는own_paragraph(기본 true)면 캡션 끝에서 새 문단을 만들고
그림만 넣은 뒤 가운데 정렬한다. 호출 전 커서를 캡션 문단 끝(goto_text캡션)에 둘 것. - 수식:
insert_equation에display: true면 lead-in 문장 끝(커서)에서 새 문단을 만들고
수식만 넣어 가운데 정렬. 인라인 수식은 짧은 것만. - 정렬:
set_para_align(align: justify/center/left/right). 본문은justify(all),
제목·그림·수식 문단은center, URL/참고문헌 줄은left(양쪽정렬 시 URL 자간이 벌어짐).
순서 주의 —all:justify를 먼저 적용한 뒤 그림/수식을 삽입해야 self-center가 살아남는다. - 참고문헌은 "저자·제목 줄 + URL 단독 줄"로 쪼개고 left 정렬.
표·그림·문구 삭제 / 색
- 표는 항상 순수 2차원 리스트로
insert_table(plain 기본). pandas DataFrame을 넘기면
숫자 헤더 행 + 인덱스 열(0,1,2…)이 셀에 박힌다. 인덱스 열 절대 금지. - 그림은
width_mm만 줘도 원본 종횡비로 높이 자동(PIL→PNG 헤더 폴백). - 콤마가 든 문구 삭제는
find_delete(find 기반, 분리 없음).replace_all은 FindString을
콤마로 분리하므로 콤마 든 문구엔 쓰지 말 것. - 표/그림만 지우고 캡션은 남기려면
delete_ctrls(types: tbl/gso) 후 캡션 앵커로 재삽입.
수식 (한글 수식 편집기 형식)
insert_equation에latex를 주면 내장 변환기(scripts/eqn.py)가 HwpEqn 스크립트로
변환해EquationCreate액션으로 삽입한다. 글꼴은 기본 HancomEQN.- 변환이 의심스러우면 먼저 단독 실행으로 확인:
python SKILL_DIR/scripts/eqn.py "\frac{1}{2}mv^2"→ warnings 비어 있는지 확인. - 복잡한 수식은
hwpeqn키로 스크립트를 직접 줄 것 (문법: references/hwpeqn_cheatsheet.md). - 기존 수식 수정은
edit_equation+index(inspect 출력의 equations 배열 인덱스).
report bundle 조립 (build_report.py)
- report-pipeline의 Stage 4 출력(
bundle/content.md)을 받아 ops JSON을 결정론적으로
만든다. 형식 명세는report-pipeline/references/bundle_spec.md를 엄수(SECTION 앵커,[[EQ]]/[[FIG]]/[[TABLE]]태그, YAML 메타). - 사용:
python scripts/build_report.py --content bundle/content.md --form 양식.hwp > ops.json python scripts/com_backend.py edit --file 양식.hwp --ops ops.json \ --save-as 최종.hwpx --export-pdf verify.pdf--dry-run은 한글 미실행, ops만 출력(단위 테스트).--form은 inspect로 SECTION 앵커를
양식 항목 제목과 대조하고 하나라도 불일치하면 중단(우회 금지 — content.md를 고친다). - 생성 규칙: 수식=
insert_equation(display 기본, latex는 eqn.py+sanity), 그림=insert_picture(own_paragraph+width_mm), 표=insert_table(plain). 인라인 객체 원칙과
동일. 조립 후 검증은 위의 레이아웃 QA + 시각 이중 게이트 그대로 적용. - 회귀 픽스처:
tests/fixtures/regen-brake/(회생제동 보고서를 bundle로 역변환). dry-run
ops 개수(섹션·EQ·FIG·TABLE)와 앵커가 기준과 일치해야 한다.
양식 보존 원칙 (COM)
- 텍스트는 가능하면 필드(누름틀) 채우기(
put_field) >replace_all> 커서 삽입 순으로 선호. - 새 문단 삽입 시 커서를 같은 스타일의 문단 끝에 두고
insert_text— 직전 문단 모양을 상속한다. - 쪽 설정/스타일 정의는 절대 건드리지 않는다 (편집은 본문 내용에 한정).
2. XML 백엔드 워크플로우 (한컴 없는 환경)
기존 hwpx 스킬을 그대로 사용한다 (이 스킬과 공존):
- 새 문서 생성:
hwpx/scripts/generate_hwpx.py(이노베이션아카데미 양식) - 기존 .hwpx 편집:
hwpx/scripts/modify_hwpx.py— 바이트 보존 원칙 유지
(etree.tostring 금지, 원본 바이트에 문자열 수술) - 수식: HwpEqn 스크립트 텍스트가 필요하면 이 스킬의
scripts/eqn.py로 변환한 뒤
XML의 수식 노드에 삽입. 단, 픽셀 퍼펙트가 필요하면 Windows COM으로 마무리할 것. - 검증: 수정 후
read_hwpx.py로 구조 재독 + 가능하면 한컴독스/한글에서 열어 확인 요청.
3. 흔한 실수 (하지 말 것)
- ❌ inspect 없이 바로 편집 — 앵커 문구가 없으면 goto_text가 실패한다.
- ❌ 전체 본문 텍스트를 컨텍스트에 덤프 —
text_preview와 컨트롤 요약만 사용. - ❌ PDF 시각 검증 생략 — 수식 BaseUnit이 본문 글자 크기와 안 맞는 경우가 흔하다
(본문 10pt면base_pt: 10~11). - ❌ .hwp를 XML 백엔드로 편집 시도 — XML 백엔드는 .hwpx 전용.
- ❌ 한글 창을 여러 개 띄운 채 실행 — 기존 한글 프로세스를 모두 닫고 시작.
- ❌ ops 한 번에 20개 이상 — 5~8개 단위로 끊고 매 단위마다 검증.
4. 트러블슈팅
| 증상 | 원인/해결 |
|---|---|
| 보안 승인 팝업에서 멈춤 | pyhwpx가 자동 등록하지만, 구버전 한글이면 한컴 보안모듈(FilePathCheckerModule) 수동 등록 필요 |
insert_picture TypeError |
pyhwpx 버전 차이 — 백엔드가 자동 폴백함. pip install -U pyhwpx 권장 |
insert_picture ValueError (sizeoption=1 width/height) |
폭만 주면 pyhwpx가 둘 다 요구. v0.1.1부터 width_mm만 줘도 종횡비로 높이 자동 계산 |
| 그림이 지정 크기 무시·거대(native)로 삽입 | pyhwpx insert_picture의 width/height 단위는 mm(HwpUnit 아님). v0.1.2에서 mm 직접 전달로 수정. 구버전은 MiliToHwpUnit 변환 탓에 무시됐음 |
| 헤딩 아래·그림 주변 과다 공백 | 빈 문단(엔터) 잔재. layout_qa.py로 수치 측정 → collapse_empty_paragraphs+delete_blank_after/before로 보정. 1빈줄은 보존(과압축 금지) |
| layout_qa가 그림 페이지를 오탐 | 간격 지표는 그림이 점유한 세로 구간을 제외(v0.1.2). 그래도 뜨면 진짜 빈 문단 구멍 |
| 삽입 본문이 파란색(또는 안내문 색) | 색 안내문 위치 상속. set_char_color로 일괄 검정. PDF에서 색 글자 0 확인 |
| 표에 숫자 헤더·인덱스 열 오염 | DataFrame 경유 삽입. 순수 2D 리스트로 insert_table(plain). 기존 표는 delete_ctrls(tbl) 후 재삽입 |
| 콤마 든 문구가 일부만 지워짐(콤마 잔존) | replace_all이 콤마로 분리. find_delete 사용 |
| 수식이 깨져 보임 | HwpEqn 문법 오류. eqn.py 단독 실행으로 warnings 확인 후 hwpeqn 직접 작성 |
| 저장 후 한글에서 "복구" 경고 | XML 백엔드에서 DOM 재직렬화를 했을 가능성 — 바이트 보존 경로만 사용 |
| COM이 응답 없음 | 작업관리자에서 Hwp.exe 잔존 프로세스 종료 후 재시도 |
수식이 \frac·≤ ft처럼 raw로 렌더 |
bundle latex 속성이 이중 백슬래시(\\frac). eqn.py가 v0.2.1부터 정규화하지만 content.md는 단일 백슬래시 권장 |
| 섹션 본문이 마지막 섹션(Ⅵ 참고문헌) 뒤로 밀림 | 옛 insert_table이 MoveDocEnd로 커서를 문서 끝으로 보냄. v0.2.1에서 표 바로 뒤로 복귀하도록 수정 |
| 제목과 본문이 한 줄에 붙음("Ⅵ.참고문헌David…") | build_report가 goto 후 본문을 같은 문단에 삽입. v0.2.1에서 제목 뒤 새 문단 분리 |
| 캡션이 그림과 떨어져 페이지가 갈림 | 객체 op의 leading \r\n이 캡션과 객체 사이 빈 문단을 만듦. v0.2.1에서 문단 맨 앞이면 생략(_para_offset) |
| set_char_color로 검정 적용이 무효 | set_font(TextColor=0)이 falsy 0을 스킵. v0.2.1에서 HParameterSet 경로로 항상 적용. 단 표지 셀 내부는 SelectAll이 못 잡아 문단 표적 처리 필요 |
5. 참고 문서
references/hwpeqn_cheatsheet.md— 한글 수식 스크립트 문법 전체references/com_api_reference.md— pyhwpx/HAction 패턴 모음INSTALL.md— Claude Code / Codex / Cowork / claude.ai 배포 방법