HWP Authoring Feature Roadmap¶
작성일: 2026-05-11
목적¶
이 문서는 현재 openhwpsdk가 실제 한/글 문서 작성 프로그램의 자주 쓰는 기능과 비교해 어디까지 왔고, 무엇을 다음에 구현해야 하는지 정리한다. 목표는 "대부분의 HWP 문서 작성 기능을 한 번에 구현"이 아니라, 실제 문서 작성에서 자주 쓰는 기능을 작은 개발 단위로 나누고 각 단위마다 검증 가능한 fixture와 합격 기준을 두는 것이다.
근거¶
- 현재 repo 기능 근거:
Program.csCLI 표면,HwpxFormMap,HwpxTableModel,HwpxPackageImageInserter,HwpxLayoutValidator. - 로컬 검증 근거(공개 repo 미포함): 2026-05-11 feature corpus scan에서 HWPX 69개, package/XML parse error 0, 표 3,049개, 셀 70,558개, 병합셀 20,360개, 중첩표 184개, 그림 94개, 필드/양식 492개, header/footer 4개, note 4개, reference 128개, embedded object 5개를 확인했다.
- 한컴 공식 SDK/도움말 기준:
- 한글 SDK: HWP/HWPX 문서 뷰잉, 생성, 열기/저장, HTML/PDF 등 포맷 변환, Text/Image/Table 데이터 삽입/편집, 문서 보안, 문서 비교/병합/이력 관리 기능을 SDK 범주로 제시.
- Hancom SDK 라인업: document editing, automation, comparison, Docs Compare SDK, OCR SDK 등을 별도 SDK 범주로 제시.
- 입력 탭: 표, 차트, 도형, 그림, 스크린샷, 글맵시, 수식, 동영상, 문단 띠, 양식 개체, 누름틀, 각주/미주, 책갈피, 상호 참조, 하이퍼링크, 문자표, 한자 입력.
- 표 메뉴: 표 만들기/그리기, 문자열-표 변환, 표/셀 속성, 테두리/배경, 줄/칸 추가/삭제, 셀 나누기/합치기, 표 계산식.
- 머리말/꼬리말: 쪽마다 반복되는 영역이며, 본문과 별개로 문자, 그림, 표, 그리기 개체와 문단/글자 모양을 가질 수 있음.
- 누름틀: 안내문, 메모, 필드 이름이 있는 입력 필드.
- 차례/색인: 제목/표/그림/수식 차례와 색인 자동 생성.
- 상호 참조: 표, 그림, 수식, 각주/미주, 개요, 책갈피 등을 참조하고 번호/쪽 변화에 대응.
- 수식 명령어: 분수, 근호, 적분, 행렬 등 스크립트 기반 수식 입력 체계.
- HWPX 구조: HWPX는 ZIP 기반 XML 패키지이며
BinData,Contents/content.hpf,Contents/header.xml,Contents/section*.xml등이 핵심.
현재 강한 영역¶
- 기존 제출서식형 HWPX 보존 작성
extract-form-map,probe-form-map,apply-form-map,apply-form-map --package.-
package text/image write, style guard, layout/content validation.
-
표 중심 템플릿 자동 입력
cellAddr/cellSpan기반 grid reconstruction.-
병합셀 guard, 중첩표 텍스트 분리, 기존 셀 currentText 검증.
-
그림 삽입
- COM 기반 그림 삽입.
-
package 기반
BinData/hp:pic/manifest 삽입. -
제출서식 profile
fill-submission-template --profile r-and-d-startup-2026.- Markdown 표 렌더링, 이미지 anchor queue, 보고서/검증 흐름.
완료 요약¶
2026-05-11 이후 현재까지 구현/검증된 authoring 축은 다음과 같다.
- corpus와 inventory 기반
- 로컬 feature corpus 기준으로
scan-hwpx-features가 aggregate counts, authoring coverage, detailed feature groups, missing corpus signals, per-file totals를 출력한다. -
header/footer, field/form, reference, note inventory가 파일/part/type/text 단위로 분리되어 report된다.
-
제출서식 보존 작성
extract-form-map,probe-form-map,apply-form-map,apply-form-map --package가 기존 HWPX 구조를 보존하면서 text/image/field/form 일부 쓰기를 수행한다.- package text write는
currentText검증과 sub-7ptcharPrguard를 적용한다. -
validate-layout,validate-content,scan-hwpx-features, PDF export를 조합한 검증 흐름이 정착됐다. -
rich copy/paste 자동화
list-controls,probe-copy-from-doc,copy-from-doc가 추가됐다.- source selector는
all,paragraph-to-end:<text>,table:<index>,image:<index>,control:<ctrlId>:<index>를 지원한다. - target selector는
doc-end,anchor:<text>,cell:<table,rowMove,colMove>,control:<ctrlId>:<index>를 지원한다. -
image/gso source를 HWPX
control:gso:<index>target에 붙여넣는 경우copy-from-doc가 output package를 post-verify하고, COM process snapshot과 선택적--strict-cleanup진단을 report한다. -
머리말/꼬리말 및 쪽 번호
list-header-footer가 section-aware header/footer inventory를 출력한다.set-header-footer-text가 기존 header/footer body anchor text를 package-level로 치환한다.-
page-number-set은 COM 기반 쪽 번호 삽입 smoke를 통과했다. -
누름틀/필드/양식 일부
list-fields가 package-level field/form item과 선택적 COM field list 결과를 병합한다.extract-form-map은 field/press marker와 checkbox/radio/combo/edit 같은 form object를 별도fieldssection에 출력한다.-
apply-form-map --package는 press field text와 checkbox checked/unchecked 값을 제한적으로 쓴다. -
표 package authoring
table-create-package,table-row-package,table-column-package,table-merge-package,table-split-package가 단순 top-level table 범위에서 검증됐다.table-cell-style-package,table-cell-align-package,table-cell-background-package,table-cell-diagonal-package,table-cell-size-package가 셀 스타일/정렬/배경/대각선/크기 조정 범위에서 검증됐다.-
병합/중첩/sparse/주소 불일치/객체 포함 표는 명시적으로 거부하는 방향으로 안전 범위를 좁혔다.
-
이미지 inventory/교체 일부
list-pictures가 COM 없이 picture index, package gso index,binaryItemIDRef,BinData, SHA256, pixel size, 크기/배치/wrap 속성을 보고한다.- package-level
replace-image-control이 기존hp:pic속성을 유지한 채 단일 picture의 연결 image binary를 교체하고, source/before/after hash, picture/table count, 속성 보존,validate-layout결과를 보고한다. InsertPicture의 HWPXhp:sz단위 오입력은 guard와 docs로 방어한다.- 남은 큰 작업은 COM/editor-backed replacement fallback과 shape/control 속성 재적용이다.
큰 공백¶
현재 구현은 "제출서식형 HWPX의 본문/표/병합셀/중첩표/이미지 작성"에 강하다. 반대로 실제 한/글에서 자주 쓰지만 아직 약하거나 없는 축은 다음이다.
- 기존 HWPX 안의 특정 그림은 package-level로 교체할 수 있지만, COM/editor-backed replacement fallback과 도형까지 포함한 속성 재적용은 아직 남아 있다.
- 그림 control의
BinData해시, pixel size, HWPX 표시 속성 inventory는 들어왔고, 도형 control까지 포함한 범용 diff는 아직 남아 있다. - 머리말/꼬리말의 신규 영역 생성, COM 기반 편집, 그림/표/도형 포함 반복 영역 작성, 구역별 쪽 설정.
- 각주/미주, 메모, 덧말.
- generic field, radio/combo/edit/button form control의 package-level 입력과 검증 contract.
- 책갈피, 캡션, 상호 참조, 차례/색인.
- 일반 도형, 글상자, 글맵시, 문단 띠, 그룹, 회전, z-order, wrapping.
- 수식, 차트, OLE, 동영상/소리.
- 표 작성의 남은 범위: 표 그리기, 계산식, 병합/중첩/객체 포함 표 같은 unsafe case, 더 넓은 표/셀 style coverage.
- 일반 Markdown-to-HWP renderer: 제목, 개요 번호, 목록, 인라인 스타일, 표, 그림, 캡션, 링크를 모두 HWP native 구조로 생성.
- PDF/시각 회귀 검증 자동화.
- SDK parity 관점의 문서 보안: 문서 비밀번호, 배포용 문서 제한, 개인정보 텍스트 암호화.
- SDK parity 관점의 문서 비교/병합/이력 관리: diff report, 병합 결과물 생성, 변경 이력 보존/검증.
- SDK parity 관점의 포맷 변환: PDF 외 HTML/웹페이지/기타 필터 변환과 변환 결과 검증.
- SDK parity 관점의 페이지/레이아웃 설정: 용지, 여백, 방향, 단, 구역 나누기, 구역별 쪽 번호 정책.
로드맵¶
Phase 0. Corpus 확장과 기능 재현성¶
목표: "없다/된다"를 말할 수 있는 최소 fixture를 확보한다.
개발 단위:
- 로컬 feature fixture corpus 구성
header-footer.hwpxfootnote-endnote.hwpxpress-field-form.hwpxcaption-crossref-toc.hwpxequation.hwpxshape-textbox.hwpxchart-ole.hwpxtable-authoring.hwpx-
simple-table.hwpx -
scan-hwpx-features확장 - header/footer 본문 part 감지.
- footnote/endnote body 감지.
- field/form object 종류별 count.
- shape type별 count: line, rect, ellipse, text box, group, container.
- equation/chart/OLE/media count.
- caption/bookmark/cross reference/TOC/index marker count.
합격 기준:
- 각 fixture가 최소 하나 이상의 대상 feature를 가진다.
scan-hwpx-featuresreport가 feature별 count를 사람이 확인 가능한 표로 출력한다.- corpus가 없어서 구현 여부를 판단하지 못하는 항목을 report에서 별도 표시한다.
우선순위: P0
구현 상태(2026-05-11):
- feature fixture corpus와 생성 스크립트는 공개 repo에서 제외하고 로컬 검증 자산으로만 유지한다.
scan-hwpx-featuresreport는 aggregate counts, authoring coverage, detailed feature groups, missing corpus signals, per-file totals를 출력한다.- 상세 inventory report는 header/footer, field/form, reference, note 신호를 파일/part/type/text 단위로 보여준다.
- 이 단계는 corpus inventory이며, 해당 기능의 write/edit 지원을 의미하지 않는다. 실제 작성 기능은 각 phase의 별도 개발 단위에서 검증한다.
복붙 자동화 상태(2026-05-11):
- HWP COM 기반
list-controls,probe-copy-from-doc,copy-from-doc명령을 추가했다. - 현재 rich copy source는
all,paragraph-to-end:<text>,table:<index>,image:<index>,control:<ctrlId>:<index>를 지원한다. - target은
doc-end,anchor:<text>,cell:<table,rowMove,colMove>,control:<ctrlId>:<index>를 지원한다. - 실제 제출서식 smoke에서
table:0을 대상 문서 끝에 붙여넣고, 표 48개 -> 49개, changed core tables 0, layout verdict pass를 확인했다. image:<index>는list-controls의 전역index가 아니라gso행의typeIndex값을 source-only로 복사한다.
Phase 1. 머리말/꼬리말 및 쪽/구역 모델¶
목표: 실무 문서에서 가장 자주 쓰는 쪽 기반 반복 영역을 안전하게 읽고 쓴다.
개발 단위:
- header/footer inventory
- section별 header/footer reference 추출.
- 홀수/짝수/양쪽 위치 구분.
-
텍스트/표/그림/도형 count report.
-
header/footer text write
- 기존 header/footer paragraph anchor에 텍스트 쓰기.
-
package mode와 COM mode 둘 다 지원하되, 우선 package text write.
-
page number support
- COM command로 쪽 번호 삽입 smoke test.
- HWPX package에서는 inventory/보존 검증부터 시작.
합격 기준:
- header/footer가 있는 fixture에서 본문 table count/style drift가 변하지 않는다.
- header/footer 텍스트가 PDF export에서 보인다.
- 여러 header/footer가 있을 때 section/위치가 report에 명확히 나온다.
우선순위: P0/P1
구현 상태(2026-05-11):
list-header-footer명령으로 HWPX 파일/디렉터리의 section-aware header/footer inventory를 별도 출력한다.- report는 section, part, kind, body/reference role,
applyPageType, reference attrs, paragraph/table/picture/shape count, text preview를 포함한다. scan-hwpx-features의 Header/Footer Inventory 표도 동일하게 section/applyPageType 컬럼을 포함하도록 확장했다.set-header-footer-text명령으로 기존 header/footer body 안의 anchor 텍스트를 package-level로 치환한다.header-footer.hwpxfixture에서 header 본문 텍스트 치환 후 content/layout/header-footer inventory smoke를 통과했다.add-header-footer-reference명령으로 이미 존재하는 header/footeridRef를 재사용해 새applyPageTypereference를 하나 추가한다. 같은 section/kind의applyPageType중복은 거부한다.add-header-footer-text명령으로 section 내 신규 header/footeridRef의 단순 1문단 text body와 reference를 함께 추가한다. 중복 header/footeridRef와 중복 section/kind/applyPageType은 거부한다.page-number-set명령으로 COM 기반 쪽 번호를 삽입한다. 실제 제출서식 smoke에서pageNumbers=1,references2 -> 3, 표 48개 유지, layout verdict pass를 확인했다.- rich object 편집, COM 기반 header/footer 쓰기, section page setup은 아직 다음 개발 단위다.
Phase 2. 누름틀/필드/양식 개체¶
목표: 제안서/공문/계약서 템플릿에서 가장 흔한 "빈칸 채우기"를 named field 기반으로 안정화한다.
개발 단위:
- field inventory
- COM
field-list-raw결과와 HWPX package scan 결과를 한 report에 병합. -
field name, 안내문, 현재 값, 위치, 인쇄 여부를 가능한 범위에서 추출.
-
extract-form-mapfield targets 추가 field/presstarget kind 추가.-
기존 cell/anchor target과 분리.
-
package-level press field fill
- named field currentText 검증.
-
placeholder style 유지 또는 정상 본문 style override 옵션.
-
form object inventory
- checkbox, radio, combo, edit box는 우선 보존/검증.
- 값 쓰기는 COM smoke test 이후 별도.
합격 기준:
- 같은 안내문이 여러 번 있어도 field name으로 정확히 채운다.
- 누름틀 안내문 삭제/사용자 입력값 삽입이 HWP에서 열어도 유지된다.
- global replace 없이 target별 report가 남는다.
우선순위: P0/P1
구현 상태(2026-05-11):
list-fields명령으로 package-level field/form item과 선택적 COMGetFieldList결과를 한 report에 병합한다.- package report는 part, kind, attrs(name/value 등), text preview를 출력한다. COM report는 raw list에서 파싱 가능한 field name, 존재 여부, 현재 text를 출력한다.
press-field-form.hwpxfixture에서 field/press/form 6개 package item을 확인했고, 실제 제출서식 smoke에서 checkbox 8개와 COM raw empty 결과를 같은 report에 남겼다.extract-form-map은 이제field/pressmarker와checkBtn, checkbox, radio, combo, edit control 같은 form object를 별도fieldssection에 출력한다.apply-form-map --package는kind=pressfield의writeText enabled="true"값을 package-level로 적용하며,currentTextmismatch는 실패 처리한다.- press-field 개발 단위 smoke에서
press-field-form.hwpx의press-a를Updated press field로 치환했고, content/layout/list-fields 검증을 통과했다. 당시 text 기반 unsupported checkbox write는 skipped_unsafe=1로 막았다. apply-form-map --package는kind=checkBoxfield의writeValue enabled="true"값을CHECKED/UNCHECKED로 적용하며,valuemismatch는 실패 처리한다.- 실제 제출서식 smoke에서
CheckBox1을UNCHECKED->CHECKED로 변경했고, layout/list-fields/package XML 검증을 통과했다. mismatch map은 failed=1, unsupported radio value write는 skipped_unsafe=1로 막았다. - 인쇄 여부, generic field writing, radio/combo/edit value writing은 다음 개발 단위다.
Phase 3. 표 authoring 전 범위¶
목표: 기존 표 채우기에서 "표를 새로 만들고 조작하는 기능"으로 확장한다.
구현 상태(2026-05-11):
table-create-package명령으로 COM 없이 새 단순 표를 만든다.- 기존 HWPX 안의 병합/중첩 없는 top-level 표를 reference style로 복제하고,
--rows,--cols,--text,--text-file,--after-anchor,--reference-table,--border-fill-id,--header-border-fill-id,--report를 지원한다. Anchor 삽입은 top-level 문단으로 제한하고, border fill ID는Contents/header.xml정의에 존재할 때만 허용한다. - 실제 제출서식 smoke에서 top-level 표 44 -> 45, 전체 layout validator 표 48 -> 49, changed core tables 0, leading paragraph style drift 0, content require 통과를 확인했다.
- 병합/중첩 표만 있는
table-authoring.hwpxfixture에서는 안전한 reference table이 없어서 실패하도록 막았고, 양성 경로 검증용simple-table.hwpxfixture를 추가했다. table-row-package명령으로 단순 top-level 텍스트 셀 표의 행 추가/삭제를 지원한다. 병합/중첩/sparse/주소 불일치/객체 포함 표는 거부하고, 행 추가/삭제 후cellAddr,rowCnt,colCnt, 표 크기를 재정규화한다.- 실제 제출서식 smoke에서 top-level table 4에 2행을 추가해 3 -> 5행, 1행을 삭제해 3 -> 2행으로 변경했고,
validate-layout --allow-table-row-change 4에서 expected-change/pass를 확인했다. table-column-package명령으로 같은 안전 범위의 선택한 body section 표에 열 추가/삭제를 지원한다. 열 변경은 표 폭도 함께 바뀌므로validate-layout --allow-table-column-change옵션을 추가해 의도된 열/폭 변경을 expected-change로 분류한다.- 실제 제출서식 smoke에서 top-level table 4에 1열을 추가해 4 -> 5열, 1열을 삭제해 4 -> 3열로 변경했고,
validate-layout --allow-table-column-change 4에서 expected-change/pass를 확인했다. table-merge-package명령으로 단순 unmerged top-level 텍스트 셀 표의 직사각형 셀 병합을 지원한다.--row/--column은 zero-based top-left 셀이고,--row-span/--col-span은 병합 범위다. 병합 후 표의 row/column count는 유지하고 covered cell만 제거하며 top-left cell에cellSpan과 병합 영역 크기를 기록한다.--text가 없으면 병합 범위 안의 기존 셀 텍스트를 row-major 순서로 합친다. 병합 입력은 현재 병합/중첩/sparse/주소 불일치/객체 포함 표를 거부한다.table-split-package명령으로 기존 병합셀을 다시 1x1 셀 grid로 나누는 package writer를 추가했다. 병합된 top-left 셀 주소를 기준으로 covered cell을 다시 만들고, 주변 셀에서 열 너비/행 높이를 샘플링하며,--textmatrix가 없으면 기존 병합 텍스트를 top-left 셀에 보존한다.- 병합 산출물을 다시 split하는 왕복 smoke에서 physical cell 9 -> 12, row/column 3x4 유지, layout/content pass, 직접 XML 기준 네 셀
cellSpan=1x1복원을 확인했다. table-cell-style-package명령으로 기존Contents/header.xml에 정의된 borderFill ID를 셀 또는 직사각형 범위에 적용한다. 선택 범위와 span이 교차하는 셀을 대상으로 하므로 병합셀 내부 covered coordinate를 선택해도 top-left 병합셀 스타일이 바뀐다.- 실제 제출서식 smoke에서 top-level table 4의 row 1/column 1 셀 borderFillIDRef를 16 -> 32로 바꾸고 layout pass와 직접 XML 검증을 확인했다. 존재하지 않는 borderFill ID 9999는 적용 전에 실패한다.
table-cell-align-package명령으로 셀 내부 문단의 가로 정렬과 셀 세로 정렬을 변경한다. 가로 정렬은 공유paraPr를 직접 수정하지 않고Contents/header.xml에서 clone을 만들어 해당 셀 문단만 새paraPrIDRef를 보게 하며, 세로 정렬은hp:subList@vertAlign을 변경한다.- 실제 제출서식 smoke에서 row 1/column 1 셀을
horizontal=RIGHT,vertical=BOTTOM으로 변경했고, 직접 XML에서 새paraPrIDRef=203, header align RIGHT,paraProperties itemCnt=204, subList vertAlign BOTTOM을 확인했다. 병합셀 covered coordinate 선택도 top-left 병합셀 정렬로 적용된다. table-cell-background-package명령으로 셀 배경색을 직접 설정하거나 지운다. 선택 셀의 현재borderFill을 clone하고hc:fillBrush/hc:winBrush@faceColor만 갱신하거나--color none일 때 fillBrush를 제거한 뒤 해당 셀만 새 ID로 retarget한다.- 실제 제출서식 smoke에서 top-level table 4의 row 1/column 1 셀에
#FFF2CC배경색을 적용했고, layout pass와 직접 XML 기준faceColor=#FFF2CC, 기존 leftBorder 유지, cloned borderFill ID 적용을 확인했다. 병합셀 covered coordinate 선택도 top-left 병합셀 배경으로 적용된다. table-cell-diagonal-package명령으로 셀 대각선을 추가/변경/삭제한다. 기존borderFill을 직접 바꾸지 않고 선택 셀의 현재borderFill을 clone한 뒤hh:slash/hh:backSlash와hh:diagonal폭/색상만 갱신하고 해당 셀만 새 ID로 retarget한다.- 실제 제출서식 smoke에서 top-level table 4의 row 1/column 1 셀에
direction=both,width=0.15 mm,color=#000000을 적용했고, layout pass와 직접 XML 기준slash=CENTER,backSlash=CENTER, cloned borderFill ID 적용을 확인했다. 병합셀 covered coordinate 선택은 top-left 병합셀의 대각선으로 적용된다. table-cell-size-package명령으로 단순 unmerged top-level 표의 열 너비와 행 높이를 균등화한다. 전체 표 폭/높이는 유지하고 기존hp:cellSz값을 열/행 단위로 재분배하며, 병합/중첩/sparse/주소 불일치 표는 거부한다.- 실제 제출서식 smoke에서 top-level table 11의 column widths
9788,20451,6361,10513을11778,11778,11778,11779로, row heights2403,1363,1363을1709,1709,1711로 균등화했고, 표 전체 크기47113x5129, row/column count 3x4, layout pass를 확인했다.
개발 단위:
- table create package writer
- 단순 표
rows x cols생성. - template table style clone 옵션.
-
cell border/background 기본값 설정.
-
row/column operations
- 줄/칸 추가/삭제.
- 셀 높이/너비 균등화. (implemented:
table-cell-size-package) -
기존 table model의
cellAddr/cellSpan재계산. -
merge/split operations
- 단순 rectangular merge. (implemented:
table-merge-package) - split back to grid. (implemented:
table-split-package) -
overlap validator 강화.
-
table style operations
- border/background. (partially implemented:
table-cell-style-packageexisting borderFill apply,table-cell-background-packagedirect fill color) - diagonal line. (implemented:
table-cell-diagonal-package) -
paragraph alignment, vertical alignment. (implemented:
table-cell-align-package) -
formulas
- 쉬운 계산식/블록 계산식은 우선 inventory와 COM smoke test.
- package writer는 formula object 구조 파악 후 진행.
합격 기준:
- 새 표가 HWP에서 실제 표로 열린다.
validate-layout가 table grid overlap을 잡는다.- merge/split 후
scan-hwpx-features와 PDF export가 일치한다.
우선순위: P1
Phase 3.5. 이미지/개체 교체 안정화¶
목표: 기존 문서 안의 특정 그림 개체를 "새 그림 삽입"이 아니라 "기존 개체 교체"로 다룬다. 기존 control의 위치, 크기, wrap, anchor, z-order, treatAsChar, margin/crop 계열 속성을 보존하고, 저장 후 실제 BinData와 hp:pic 속성을 검증한다.
배경:
copy-from-doc는 COM select/copy/paste 호출이 모두 성공해도 실제 target 그림 바이너리가 바뀌지 않는 경우가 있었다.InsertPicture는 새 PNG를 넣을 수 있지만 width/height 단위가 HWPX 내부hp:sz와 직접 호환되지 않아 표시 크기와 배치 속성이 깨질 수 있다.validate-layout와validate-content는 표/문단 구조 안정성을 보지만, 특정 그림의 바이너리 교체 성공과 표시 속성 보존까지 증명하지 않는다.
개발 단위:
- picture/control inventory
list-pictures또는inspect-pictures명령을 추가한다.- report에는 section part, picture index, gso typeIndex,
binaryItemIDRef,BinDatapath, SHA256, pixel size, byte size,hp:sz,hp:pos,orgSz,curSz,imgClip,outMargin,textWrap,textFlow,zOrder,treatAsChar, anchor/position 관련vertRelTo/horzRelTo/offset 속성을 출력한다. -
list-controls의 gso typeIndex와 package-levelhp:pic을 연결해 사람이 target을 고를 수 있게 한다. -
package-level
replace-image-control - 우선 COM 없이 HWPX package를 직접 수정한다.
--target control:gso:<index>또는--target image:<binaryItemIDRef>로 기존hp:pic을 찾는다.- 기존
hp:pic/hp:pos/hp:sz/wrap 속성은 보존하고, 연결된BinDataentry와Contents/header.xmlimage entry만 새 이미지에 맞게 갱신한다. -
새 확장자와 mime type, manifest item, package entry 이름 충돌을 안전하게 처리한다.
-
COM/editor-backed replacement fallback
- package-level 교체가 target 문서 구조상 안전하지 않거나 HWP editor reflow가 필요한 경우의 fallback으로 둔다.
- 대상 control 선택, 기존
ShapeObjDialog/shape properties 읽기, 기존 그림 삭제, 새 그림 삽입, 새 그림 재선택, 기존 속성 재적용 순서로 구현한다. -
이 경로는 COM 상태와 HWP 버전에 민감하므로 Phase 3.5 v1의 기본 경로는 package-level이고, COM fallback은 별도 smoke와 cleanup/report 기준을 만족할 때 implemented로 표시한다.
-
교체 결과 검증
- source image path, pixel size, SHA256.
- target control id/typeIndex.
- before/after image id,
BinDatapath, pixel size, SHA256. - picture count/table count before/after.
- preserved object properties diff:
hp:sz,hp:pos,orgSz,curSz,imgClip,outMargin,textWrap,textFlow,zOrder,treatAsChar, anchor/position offset 속성. - input/output path가 모두 있는 replace operation은
validate-layout결과를 report에 연결한다. 실행 환경상 layout validation을 건너뛰면 skipped reason을 report에 남긴다. -
target image hash가 source와 다르면 실패 exit code를 반환한다.
-
copy-from-docpost-verify - image/control target이 들어온 경우 output 저장 후 package-level before/after 검증을 수행한다.
- 호출 성공과 실제 문서 변경 성공을 구분해 report와 exit code에 반영한다.
-
검증 불가 상태는 applied가 아니라 review-needed 또는 failed로 분류한다.
-
InsertPicture단위 명확화와 방어 InsertPicturewidth/height가 HWPX 내부hp:sz단위가 아님을 CLI usage와 docs에 명시한다.- 비정상적으로 큰 width/height가 들어오면 경고 또는 실패 처리한다.
-
HWPX 내부 단위로 기존 object 크기를 재사용하려는 경우
replace-image-control을 사용하도록 안내한다. -
COM cleanup/report 강화
- COM-backed 명령 시작/종료 시
running_hwp_processes요약을 report에 남긴다. --strict-cleanup또는 후속 진단 모드로 "이번 명령 이후 새로 남은 제목 없는 Hwp 프로세스"를 감지한다.- 사용자 소유 HWP 창을 강제 종료하지 않고, 잔류/잠금 가능성을 명확히 보고한다.
합격 기준:
- 기존 그림이 있는 fixture에서
replace-image-control실행 후 picture count와 table count가 유지된다. - target
BinDataSHA256이 source image와 일치한다. - target
hp:pic의hp:sz,hp:pos,orgSz,curSz,imgClip,outMargin,textWrap,textFlow,zOrder,treatAsChar, anchor/position offset 속성 보존 여부가 report에 명시된다. - replace operation report는
validate-layout결과를 포함하거나, 검증을 건너뛴 이유를 명시한다. copy-from-doc는 실제 binary/object 교체 실패를verdict: applied로 보고하지 않는다.InsertPicture문서/usage만 보고는 HWPX 내부 단위를 그대로 넣는 실수를 피할 수 있다.
우선순위: P0/P1
Phase 4. 캡션, 책갈피, 상호 참조, 차례/색인¶
목표: 보고서/논문/제안서에서 그림/표 번호와 차례를 자동화한다.
개발 단위:
- caption inventory
- 표/그림/수식 caption 추출.
-
caption 없는 object report.
-
caption insert
- COM path로 표/그림 caption 삽입.
-
package path는 보존 검증부터.
-
bookmark and cross-reference inventory
- 대상 종류: 표, 그림, 수식, 각주/미주, 개요, 책갈피.
-
reference text와 target id 매핑.
-
TOC/index generation workflow
- COM command smoke test.
- package writer는 직접 생성보다 "기존 차례 새로고침/검증" 중심.
합격 기준:
- 표/그림 번호가 삽입 후 PDF에서 보인다.
- 앞쪽에 새 그림/표를 추가해도 COM refresh 후 reference가 업데이트된다.
- 차례/색인은 직접 생성보다 HWP COM 새로고침을 기본 경로로 둔다.
우선순위: P1/P2
Phase 5. 각주/미주/메모/덧말¶
목표: 학술 문서와 법률/계약서 문서에서 필요한 주석 계층을 지원한다.
개발 단위:
- note inventory
- footnote/endnote part 감지.
-
본문 note marker와 note body 연결 report.
-
note insert via COM
- 각주/미주 삽입 smoke test.
-
note body text 입력.
-
package-level note preservation
-
기존 note가 있는 문서에 package text write를 해도 note marker/body가 유지되는지 검증.
-
memo/comment inventory
- 검토 메모는 우선 보존/검증.
합격 기준:
- 본문 marker와 note body가 양쪽 모두 보존된다.
- PDF export에서 각주/미주 위치가 정상이다.
- package text write가 note 구조를 손상하지 않는다.
우선순위: P1/P2
Phase 6. 도형/글상자/글맵시/문단 띠¶
목표: 실제 문서에서 자주 쓰는 비본문 개체를 최소한 보존하고, 이후 생성/편집으로 확장한다.
개발 단위:
- shape inventory diff
- type, id, zOrder, anchor paragraph, size, position, wrapping.
-
validate-layout에 shape/control inventory diff 추가. -
text box read/write
- 글상자 내부 텍스트 추출.
-
existing text box content replacement.
-
simple shape create
- line/rect/ellipse 기본 생성.
-
explicit HWPX unit size/position.
-
object transform
- rotate, group, z-order, wrap은 inventory/보존 검증 후 단계적으로.
합격 기준:
- shape가 있는 fixture에서 package write 후 shape count/id/type/position이 유지된다.
- 글상자 텍스트 replacement가 HWP에서 보인다.
- 새 line/rect가 PDF에서 보인다.
우선순위: P2
Phase 7. 수식¶
목표: 수식이 있는 문서의 보존부터 시작하고, 스크립트 기반 삽입을 제공한다.
개발 단위:
- equation inventory
-
equation object count, anchor, caption 여부, raw script 가능 여부.
-
equation insert via COM
- 한컴 수식 스크립트 문자열 입력 smoke test.
-
예:
1 over 2,sqrt 2,matrix. -
package preservation validator
-
equation이 있는 문서에 text/image/table write 후 equation object 보존.
-
package-level equation writer
- HWPX 구조 확인 후 별도 진행.
합격 기준:
- 수식 fixture에서 object count가 보존된다.
- COM 삽입 수식이 HWP/PDF에서 보인다.
- caption/cross reference와 연결될 수 있는 식별자를 report한다.
우선순위: P2
Phase 8. 차트/OLE/동영상/소리¶
목표: 작성보다는 손상 방지와 inventory를 먼저 한다.
개발 단위:
- binary object inventory
BinData의 image/OLE/media 구분.-
manifest entry와 object reference 연결.
-
preservation validator
-
package write 후 binary entry, manifest item, object reference가 유지되는지 검사.
-
chart inventory
-
chart object count, source data 가능 여부.
-
COM-based insert smoke tests
- 차트/OLE/동영상/소리는 직접 package writer보다 COM 경로 우선.
합격 기준:
- OLE/chart/media가 있는 문서를 text write해도 열림/보존된다.
- binary object 손상 시 validate가 blocking으로 잡는다.
우선순위: P2/P3
Phase 9. 일반 Markdown-to-HWP renderer¶
목표: 기존 template fill이 아닌 새 문서/일반 문서 생성에서 HWP native 구조를 만든다.
개발 단위:
- Markdown AST 도입
- heading, paragraph, list, table, image, link, code, bold/italic.
-
string manipulation 금지, parser 기반.
-
style profile
- 제목/본문/목록/캡션 style mapping.
-
기본 HWPX template에서 style clone.
-
native object rendering
- heading as paragraph style.
- list as paraHead/numbering.
- table as
tbl/tr/tc. - image as
hp:pic. -
link as hyperlink field/control.
-
round-trip tests
- Markdown -> HWPX -> read-text/scan/PDF.
합격 기준:
- raw Markdown artifact가 문서에 남지 않는다.
- 표/그림/목록이 실제 HWP 구조다.
- PDF 대표 페이지가 비어 있지 않고 layout 검증을 통과한다.
우선순위: P3
Phase 10. 시각 회귀 검증¶
목표: "검증 report는 pass인데 한글에서 보면 깨짐"을 줄인다.
개발 단위:
- export-pdf batch
-
template/candidate 자동 PDF export.
-
PDF render
- 대표 페이지 PNG render.
-
page count와 key page thumbnails.
-
visual metrics
- blank page detection.
- image/object count mismatch.
- text overflow heuristic.
-
table boundary shift heuristic.
-
golden fixture review
- corpus별 expected report.
합격 기준:
- HWP COM/PDF export가 가능한 환경에서 대표 페이지 이미지가 생성된다.
- 레이아웃 깨짐이 있으면 markdown report에 페이지/대상 단위로 표시된다.
우선순위: P1/P2
Phase 11. SDK parity backlog¶
목표: 공식 한글 SDK가 제품 범주로 내세우지만 현재 CLI가 직접 지원하지 않는 기능을 명시적으로 추적하고, 가능한 것은 HWP COM/패키지 래퍼로, 별도 SDK가 필요한 것은 unsupported 상태로 구분한다. 공개 추적 표는 SDK parity matrix에 둔다.
개발 단위:
- official SDK gap ledger
- 문서 보안: 문서 비밀번호, 배포용/읽기전용 문서 제한, 개인정보 텍스트 암호화가 현재 이름 있는 CLI command와 검증 fixture로 지원되지 않음을 추적한다.
- 문서 비교/병합/이력 관리: 표 셀 병합과 구분되는 문서 단위 compare/merge/history 기능이 현재 없으며, 별도 Hancom Docs Compare SDK가 필요한 영역과 HWP COM/패키지 기반 report로 가능한 최소 범위를 분리한다.
- 일반 HWP authoring: 캡션, 책갈피, 상호 참조, 차례/색인, 각주/미주/메모, 도형/글상자/글맵시, 수식, 차트/OLE/동영상/소리는 inventory/보존/COM 삽입/패키지 작성 단계를 각각 별도 상태로 둔다.
- page/section layout: 용지, 여백, 방향, 단, 구역 나누기, 구역별 쪽 번호 정책은 현재 일반 writer가 없으므로 inventory, COM smoke, package writer 가능성을 순서대로 검증한다.
-
form control completeness: press field와 checkbox 일부 write를 기준선으로 삼고, radio/combo/edit/button은 control type별 값 의미와 전후 검증 contract가 생기기 전까지 unsupported 또는 skipped_unsafe로 둔다.
-
SDK parity matrix
- 공식 한글 SDK 범주를
view/create/open/save/convert/extract-edit/security/compare-merge-history로 나눈다. - 각 범주에 현재 CLI command, 구현 방식(COM/package), 검증 command, 남은 gap을 매핑한다.
-
별도 SDK가 필요한 기능은 CLI backlog와 외부 dependency backlog로 분리한다.
-
format conversion expansion
- 현재
export-pdf외 HTML/웹페이지/문서 필터 변환 가능성을 HWP COM action 또는 SDK 경로로 조사한다. -
변환 결과는 파일 존재만 보지 않고 text extraction, page/image presence, 기본 링크/표 보존 여부로 검증한다.
-
document security operations
- document password, distribution/read-only document, private-text encryption의 COM action/API 존재 여부를 먼저 확인한다.
- 구현 전에는 fixture와 reversible smoke test를 만든다.
-
보안 기능은 원본 파일을 직접 덮어쓰지 않고 output-only workflow로 제한한다.
-
document comparison, merge, and history
- Hancom SDK 라인업의 comparison 기능과 HWP product 기능을 분리해서 조사한다.
- 현재 repo에서 가능한 최소 범위는 text/table/style-aware report인지, 실제 merge output인지 구분한다.
-
별도 SDK 없이는 구현할 수 없는 부분은 명확히 unsupported로 표시한다.
-
page setup and section layout
- paper size, margin, orientation, columns, section break, section-specific numbering을 inventory/write 대상으로 분리한다.
-
package writer로 가능한 구조 보존과 HWP COM reflow가 필요한 영역을 구분한다.
-
object placement and form-control completeness
- image/shape/form control의 wrap, z-order, anchor, size, crop, rotate, group, lock 속성을 inventory diff 대상으로 추가한다.
- radio/combo/edit/button form controls는 checkbox와 별도 write contract를 둔다.
합격 기준:
docs/hwp-authoring-feature-roadmap.md또는 별도 parity report에서 공식 SDK 범주별 current support/gap/verification command가 한눈에 보인다.- 위
official SDK gap ledger의 각 항목이unsupported,inventory-only,COM-smoke,package-writer,verified중 하나의 상태를 가진다. - 보안/비교/병합/변환 기능은 실제 HWP/SDK에서 열리는 fixture와 output-only smoke test 없이는 implemented로 표시하지 않는다.
- 별도 Hancom SDK가 필요한 기능은 repo 내부 구현 예정 항목과 외부 라이선스/SDK 의존 항목으로 분리한다.
- 변환/비교/보안 결과물은 원본 파일을 보존하고, 실패 시 partial output을 명시적으로 report한다.
우선순위: P1/P3
추천 개발 순서¶
- 완료: Phase 3.5 일부: picture/control inventory.
- 완료: Phase 3.5 일부: package-level
replace-image-control. - 완료: Phase 3.5 일부:
copy-from-docimage target post-verify. - 완료: Phase 3.5 일부:
InsertPicture단위/usage 방어. - 다음: Phase 3.5 일부: COM/editor-backed replacement fallback과 cleanup diagnostics.
- Phase 0 완료분 유지보수: real-world fixture를 계속 추가하고 expected report를 고정한다.
- Phase 10 일부: PDF visual smoke harness.
- Phase 1: header/footer 신규 영역 생성, COM 기반 편집, rich object support, section page setup.
- Phase 2: field/누름틀 named fill.
- Phase 3: table authoring 미완료 항목과 formulas inventory.
- Phase 4: caption/cross-reference COM insert/refresh workflow.
- Phase 5: footnote/endnote preservation과 COM insert.
- Phase 6: shape inventory diff와 text box write.
- Phase 7: equation inventory와 COM insert.
- Phase 8: chart/OLE/media preservation.
- Phase 9: 일반 Markdown-to-HWP renderer.
- Phase 11 일부: official SDK gap ledger와 SDK parity matrix를 먼저 작성해 문서 보안, 문서 비교/병합/이력, 일반 authoring, page/section layout, form control completeness의 현재 상태를 고정한다.
- Phase 11 일부: PDF 외 변환 가능성 조사, 보안/비교/병합 unsupported 범위 확정, 별도 Hancom SDK 의존 항목 분리.
바로 다음 커밋 후보¶
후보 A: Picture/control inventory¶
상태: 완료. list-pictures 명령으로 구현됐다.
list-pictures또는inspect-pictures명령을 추가한다.- gso typeIndex와 package-level
hp:pic/BinData/hash/size/position/wrap 속성을 한 report에 연결한다. - 실제 HWPX의 특정 그림이 어떤 binary와 속성을 갖는지 COM 없이 확인 가능하게 한다.
이유: 이미지 교체는 target 식별과 before/after 증명이 먼저 안정화되어야 한다.
후보 B: Package-level replace-image-control¶
상태: 완료. package-level replace-image-control 명령으로 구현됐다.
- 기존
hp:pic속성을 보존하면서 연결된BinDataimage만 교체한다. - source/target before/after hash, pixel size, object property diff를 report에 남긴다.
- 실패 시 partial output과 검증 실패 이유를 명확히 남긴다.
이유: copy-from-doc/InsertPicture 조합은 특정 기존 그림 교체 요구에 충분히 안정적이지 않다.
후보 C: copy-from-doc image target post-verify¶
상태: 완료. image/gso source를 HWPX control:gso:<index> target에 붙여넣은 경우 output package를 post-verify한다.
copy-from-docreport를 COM 호출 성공과 실제 package 변경 성공으로 분리한다.- source image hash와 output target image hash, target picture count 보존 여부를 검증한다.
- 검증 실패 시
post_verify=failed를 출력하고 명령을 nonzero로 종료한다.
이유: "붙여넣기 호출 성공"과 "원하는 그림이 바뀜"은 다르다.
후보 D: InsertPicture unit guard and docs¶
상태: 완료. HWP COM InsertPicture width/height guard와 usage/docs 경고가 추가됐다.
- CLI usage와 docs에 width/height 단위 주의사항을 추가한다.
1000을 넘는 width/height 값은 HWPXhp:sz를 잘못 넣은 것으로 보고 거부한다.- 기존 object 크기 보존은
replace-image-control로 유도한다.
이유: HWPX 내부 hp:sz 값을 COM InsertPicture width/height로 착각하면 문서가 크게 깨진다.
후보 E: COM cleanup diagnostics¶
상태: 일부 완료. probe-copy-from-doc와 copy-from-doc report에 COM 작업 전후 HWP process snapshot이 추가됐고, 새 HWP process가 남으면 실패시키는 --strict-cleanup 진단 옵션이 들어갔다.
- COM-backed 명령 report에 시작/종료 HWP process summary를 남긴다.
- 사용자 HWP 창을 강제 종료하지 않는 strict cleanup 진단 옵션을 검토한다.
이유: 제목 없는 HWP 프로세스 잔류는 파일 잠금과 다음 작업 지연의 반복 원인이다.
후보 F: PDF visual smoke harness¶
상태: 구현 2차. visual-smoke-corpus 명령으로 feature corpus scan report와 PDF export 결과를 한 report 묶음으로 남긴다. HWP COM이 건강한 환경에서 PDF가 실제 생성돼야 pass이며, known failure는 fileNameOrPath=exitCode[:reasonFragment] exact xfail contract로만 허용한다. PDF page/content-stream/text/image/drawing metrics와 blank 의심 review-needed 신호를 report에 남긴다. PNG render와 page thumbnails는 아직 다음 개발 단위다.
- 로컬 feature fixture corpus의 대표 fixture를 PDF로 export하는 smoke command 정리.
- scan report와 PDF export 결과를 같은 report 묶음으로 남긴다.
- HWP COM이 불안정하면
diagnose-com과 visible export를 우선 실행한다.
이유: scanner inventory는 구조 신호만 보므로, 실제 한글/PDF 표시 여부를 별도 검증해야 한다.
후보 G: Header/footer rich authoring¶
상태: 구현 3차. set-header-footer-apply-page-type 명령으로 기존 header/footer reference의 applyPageType을 BOTH|EVEN|ODD 중 하나로 package-level 변경한다. add-header-footer-reference 명령은 이미 존재하는 idRef를 재사용해 새 reference만 추가하며, 같은 section/kind의 applyPageType 중복은 거부한다. add-header-footer-text 명령은 section 내 신규 header/footer idRef의 단순 1문단 text body와 reference를 함께 추가한다. rich object 편집은 아직 별도 단위다.
- header/footer 내부 그림/표/도형 포함 rich object 작성과 보존 검증.
- section별 page setup과 COM-backed header/footer editing smoke test.
이유: 기본 inventory/text write/page-number smoke, 기존 body reference 재사용, 단순 text body 생성은 들어왔고, 남은 실무 gap은 rich object 편집과 section setup이다.
후보 H: Field/form write contracts¶
상태: 구현 1차. list-fields report가 package field/form item별 write contract를 표시한다. press-field text는 package-text, checkbox value는 package-value로 지원하고, radio/combo/edit/button/generic field는 inventory-only 및 skipped_unsafe로 남긴다.
- generic field, radio, combo, edit, button control의 write contract를 field type별로 분리한다.
- 값 쓰기 전후 package value/currentText mismatch 정책을 정한다.
- unsupported control은 skipped_unsafe로 남기고 implemented로 표시하지 않는다.
이유: field inventory와 press/checkbox 일부 쓰기는 들어왔고, 남은 위험은 form control별 의미가 다른 값을 한 방식으로 처리하는 것이다.
후보 I: SDK parity matrix¶
상태: 구현 1차. SDK parity matrix에서 공식 Hwp SDK 범주를 현재 CLI command, 검증 command, 남은 gap, unsupported/needs-SDK 상태로 매핑한다.
- 공식 한글 SDK 범주와 현재 CLI command를 표로 매핑한다.
export-pdf,scan-hwpx-features,list-fields,list-controls, table/header/footer commands의 검증 command를 같이 적는다.- 문서 보안, 비교/병합/이력 관리, HTML 변환처럼 현재 래퍼가 없는 기능은 unsupported 또는 needs-SDK로 표시한다.
- 일반 HWP authoring 공백은 캡션/책갈피/상호 참조/차례/색인/각주/미주/메모/도형/글상자/글맵시/수식/차트/OLE/동영상/소리 단위로 나누고, 각 항목의 현재 상태를 inventory-only와 writer 없음으로 분리한다.
- page/section layout은 용지/여백/방향/단/구역 나누기/구역별 쪽 번호 정책으로 쪼개고, form control은 press/checkbox/radio/combo/edit/button별 write contract 상태를 표기한다.
이유: "한글 SDK에는 있는데 우리 프로젝트에는 없는 기능"을 일회성 점검이 아니라 추적 가능한 backlog로 바꿔야 한다.
당장 하지 말아야 할 것¶
- package XML로 차트/OLE/수식/복잡한 도형을 바로 생성하기.
- header/footer/각주/누름틀 fixture 없이 구현 완료라고 주장하기.
- 전체 Markdown 문서를
replace-markdown류로 밀어 넣고 HWP native 구조라고 부르기. - HWP COM으로 한 번 열렸다는 사실만으로 package 구조 보존을 생략하기.
- 별도 Hancom SDK가 필요한 비교/병합/보안 기능을 COM action 추정만으로 supported라고 표시하기.