Skip to content

HWPX 직렬화 무손실 개선: ColumnDef(#1584)+Ruby(#1587)+shapeComment(#1588)+빈문단(#1592)#1586

Closed
planet6897 wants to merge 46 commits into
edwardkim:develfrom
planet6897:devel
Closed

HWPX 직렬화 무손실 개선: ColumnDef(#1584)+Ruby(#1587)+shapeComment(#1588)+빈문단(#1592)#1586
planet6897 wants to merge 46 commits into
edwardkim:develfrom
planet6897:devel

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

요약

HWPX 저장 시 본문 첫 문단의 인라인 ColumnDef(cold/2번째 <hp:colPr>)가 드롭되던
결함을 수정합니다. 컨트롤 인덱스가 밀려 후속 표/필드 참조가 어긋나고, 표 셀 char_shape 가
연쇄 변위(숨은 바코드 가시화 등)하던 하위 증상도 동시 해소됩니다. closes #1584

수정 전 문단0: [secPr, ctrl,colPr, ctrl,        fieldBegin, tbl]   colPr 1  ← 드롭
수정 후 문단0: [secPr, ctrl,colPr, ctrl,colPr, ctrl,fieldBegin, tbl]   colPr 2  (원본 일치)

근본원인 (src/serializer/hwpx/section.rs)

  • 섹션 템플릿 앵커가 본문 첫 문단의 첫 ColumnDef 1개만 colPr 로 흡수.
  • 본문(depth 0) 인라인 슬롯 필터가 ColumnDef 를 전부 제외 → 2번째+ 가 어느 경로로도
    방출되지 않아 드롭
    (controls 6→5, cc −8).

해결 (Option A surgical)

  • context.rs: body_coldef_template_pending consume-once 플래그.
  • write_section: 첫 문단 렌더 전후로 플래그 set/reset.
  • render_runs: all-controls 분기는 첫 ColumnDef 슬롯 유지(char-offset 회계 보존),
    filter 분기는 첫 ColumnDef 슬롯 제외(위치 미점유분)·2번째+ 포함.
  • render_control_slot: 본문 첫 ColumnDef 의 XML 만 consume-once 억제(템플릿 중복 방지).

두 슬롯 분기가 ColumnDef 의 char-offset 슬롯 점유 여부에서 본질적으로 달라 분기별 처리.
단순 일괄 제거는 −8 char_shape 시프트·position→mismatch 전환 회귀를 유발 — 통제 비교로 검출·교정.

검증

검사 결과
단위 task1584_..._roundtrip (RED→GREEN) PASS (ColumnDef 1→2 보존)
cargo test --lib 1960 passed / 0 failed
hwpx_roundtrip_baseline 4/4 (#1407/#1388 컬럼 보존)
opengov snapshot (36382399 가드 편입) PASS
fidelity 전수 통제 비교(hwpdocs 9350) 개선 49 / 회귀 0 / 순효과 +49 (IR_DIFF 59→10)
Hangul 페이지 오라클 (8 표본) OK 8 / COLLAPSE 0

회귀 가드

  • 단위 테스트 + 대표 실문서 36382399samples/hwpx/opengov/ 고정 말뭉치에 편입.

🤖 Generated with Claude Code

planet6897 and others added 4 commits June 27, 2026 12:05
본문 첫 문단의 2번째 인라인 ColumnDef 가 HWPX 저장 시 드롭되는 버그를
serialize_hwpx -> parse_hwpx roundtrip 으로 재현. 현재 reparse 후 1개(기대 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
본문 첫 문단의 2번째+ ColumnDef 가 HWPX 저장 시 드롭되던 버그 수정.
- all-controls 분기: 첫 ColumnDef 슬롯 유지(회계 보존) + XML consume-once 억제
- filter 분기: 첫 ColumnDef 슬롯 제외(위치 미점유분) + 2번째+ 포함

RED 테스트 GREEN, baseline 4/4, lib 1960/0, 실문서 36382399 PASS diff=0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fidelity 전수 통제 비교: 개선 49 / 회귀 0 / 순효과 +49 (IR_DIFF 59->10).
Hangul 오라클 8표본 COLLAPSE 0. 대표 실문서 36382399 를 opengov 고정 말뭉치
회귀 가드로 편입(snapshot PASS). 최종 보고서 작성.

closes edwardkim#1584

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
planet6897 and others added 5 commits June 27, 2026 13:16
Ruby(덧말) 컨트롤이 render_control_slot arm 부재로 저장 시 드롭되는 버그를
serialize_hwpx -> parse_hwpx roundtrip 으로 재현. 현재 reparse 후 Ruby 소실(0, 기대 1).
잔존 IR_DIFF 10건 분석 문서 동봉.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ruby 모델에 main_text/pos_type/align/sz_ratio/option/style_id_ref 추가(alignment 제거).
parse_dutmal 이 mainText 보존 + posType/align 분리 + szRatio/option/styleIDRef 파싱.
alignment 제거 외부 파급 0(parse_dutmal 한정). 빌드 성공, RED 유지.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
render_dutmal(<hp:dutmal> 역매핑) + render_control_slot 에 Control::Ruby arm 추가.
RED 테스트 GREEN(전 필드 무손실), lib 1961/0, baseline 4/4, clippy 무경고.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fidelity 통제 비교: 개선 3(ruby 3건) / 회귀 0 / 순효과 +3 (IR_DIFF 10->7).
Hangul 오라클 2건 시각 정상. 대표 36389301 을 opengov 가드 편입(snapshot PASS).
부수 발견: 36384160 페이지 붕괴(IR diff=0, ruby 무관 선존)는 edwardkim#1589 분리 등록.

closes edwardkim#1587

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897 planet6897 changed the title Task #1584: HWPX 본문 인라인 ColumnDef 드롭 수정 HWPX 직렬화 무손실 개선: 인라인 ColumnDef(#1584) + Ruby 덧말(#1587) 드롭 수정 Jun 27, 2026
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1587 — Ruby(덧말) 드롭 수정

본 PR 에 #1587 이 합류했습니다(devel 누적).

  • 근본원인: render_control_slot 에 Control::Ruby arm 부재(ColumnDef HWPX 저장 시 본문 문단의 인라인 ColumnDef(cold) 드롭 → 컨트롤 인덱스 시프트 #1584 동형) + Ruby 모델 손실 구조(mainText 미보존, posType/align 병합).
  • 수정: 모델+파서+직렬화기 3계층 — main_text/pos_type/align/sz_ratio/option/style_id_ref 보존, render_dutmal 추가.
  • 검증: fidelity 통제 비교 개선 3/회귀 0(IR_DIFF 10→7), lib 1961/0, baseline 4/4, Hangul 오라클 시각 정상 2건.
  • 회귀 가드: 단위 + opengov 36389301 편입.

부수 발견

36384160 은 ruby 수정으로 IR PASS 가 됐으나 한글에서 29→3쪽 붕괴(IR diff=0, ruby 무관 선존) → #1589 분리 등록. closes #1587

planet6897 and others added 4 commits June 27, 2026 13:56
write_line 이 write_shape_comment 미호출로 선 도형 설명("선입니다.")을 드롭하는 버그를
단위 테스트로 재현. 현재 shapeComment 미방출.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
write_line 의 caption 직후 write_shape_comment 1줄 추가(write_rect 동형).
RED 테스트 2건 GREEN, lib 1963/0, baseline 4/4, clippy 무경고.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fidelity 통제 비교: 개선 3(선 도형 shapeComment 3건)/회귀 0/순효과 +3 (IR_DIFF 7->4).
36392900 opengov 가드 편입(snapshot PASS). Ruby/shapeComment 클래스 완전 해소.

closes edwardkim#1588

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897 planet6897 changed the title HWPX 직렬화 무손실 개선: 인라인 ColumnDef(#1584) + Ruby 덧말(#1587) 드롭 수정 HWPX 직렬화 무손실 개선: ColumnDef(#1584) + Ruby(#1587) + 선도형 shapeComment(#1588) Jun 27, 2026
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1588 — 선 도형 shapeComment 드롭 수정

본 PR 에 #1588 합류(devel 누적).

  • 근본원인: write_line 만 write_shape_comment 미호출(rect/container 는 호출) → 선 도형 설명 드롭. 순수 직렬화기 1줄 누락.
  • 수정: write_line caption 직후 write_shape_comment 1줄 추가.
  • 검증: fidelity 통제 비교 개선 3/회귀 0(IR_DIFF 7→4), lib 1963/0, baseline 4/4. opengov 36392900 가드.

누적 효과(3 타스크): HWPX 실문서 IR_DIFF 59→4. closes #1588

planet6897 and others added 7 commits June 27, 2026 14:40
근본원인 확정: section.rs:416-426 이 북마크를 문단 시작으로 hoisting → 컨트롤 재배치 →
후속 슬롯 +8 → char_shape 시프트(edwardkim#1584 ColumnDef 동형). edwardkim#1584 무관(이전 바이너리 동일).
Class C 분해: C1 북마크 2건(36384689/36385445), C2 필드 1건(36388711, 별개).
RED 테스트 박제.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
북마크를 문단 시작 hoisting 대신 char-offset 슬롯 위치에 방출(is_hwpx_inline_slot 편입
+ render_control_slot arm). diff 비교는 종전대로 북마크 제외(보수적 결합 분리).
RED GREEN, lib 1964/0, baseline 4/4, clippy 무경고.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stage 2 북마크 슬롯 편입은 컨트롤 순서는 교정했으나 char_shape +8 미해소(순효과 0).
진짜 근본은 first-para mismatch-path 위치추정(slot_count vs slots 불일치, F3급, 별건).
section.rs/roundtrip.rs Stage2 직전 복원, RED 테스트 #[ignore](repro 보존).
불채택 결론 + 최종 보고서.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
render_runs 가 완전 빈 문단(char_shapes=[] 등)에 빈 run 을 추가해 재파싱 시 (0,0) 이
생기던 버그 수정. char_shapes=[] = 원본에 run 없음 → run 미방출. RED GREEN,
task1378 빈문단 테스트 갱신(run 미방출이 정답). lib 1964/0, baseline 4/4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fidelity 통제 비교(전체 경로 키): 개선 1/회귀 0/순효과 +1 (IR_DIFF 4->3).
빈 문단 광역 변경에도 공통 10581건 회귀 0. 36386761 opengov 가드 편입(snapshot PASS).

closes edwardkim#1592

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897 planet6897 changed the title HWPX 직렬화 무손실 개선: ColumnDef(#1584) + Ruby(#1587) + 선도형 shapeComment(#1588) HWPX 직렬화 무손실 개선: ColumnDef(#1584)+Ruby(#1587)+shapeComment(#1588)+빈문단(#1592) Jun 27, 2026
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1592 — 빈 문단 spurious (0,0) 수정

본 PR 에 #1592 합류(devel 누적).

  • 근본원인: render_runs 가 run 없던 빈 문단(char_shapes=[])에 빈 <hp:run charPrIDRef=0> 추가 → 재파싱 시 (0,0) 발생. (RunSplitter 규칙3+close_run 규칙5)
  • 수정: 완전 빈 문단(text·char_shapes·슬롯·field 전부 없음)은 run 미방출. task1378 빈문단 테스트 갱신.
  • 검증: 통제 비교 개선 1/회귀 0/순효과 +1 (IR_DIFF 4→3), 빈 문단 광역 변경에도 공통 10581건 회귀 0. lib 1964/0.

누적 효과 (4 채택 타스크)

HWPX 실문서 IR_DIFF 59→3. 잔여 3 = Class C1(first-para mismatch-path, #1591 재범위) 2건 + C2(Field) 1건. closes #1592

planet6897 and others added 5 commits June 27, 2026 17:47
단락 이진탐색+정규화 diff 로 단일 속성까지 규명: 직렬화기가 holdAnchorAndSO 를 "0"
하드코딩(IR prevent_page_break 무시). orig 1→0 치환으로 붕괴 재현 확정. 붕괴파일 84%
가 hold=1 패턴. IR 비교 미검사로 게이트 미검출. 수정 가능한 실버그.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
직렬화 4지점(table/picture/shape/equation)이 holdAnchorAndSO 를 "0" 하드코딩 대신
common.prevent_page_break 값으로 방출. 페이지 하단 앵커 개체의 1→0 드롭(페이지 붕괴 edwardkim#1589
주원인) 해소. RED 테스트 GREEN, lib 1969/0, baseline 4/4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ObjectHoldAnchor IrDifference + diff_hold_anchor 헬퍼. Table/Picture/Equation 비교에
prevent_page_break 검사 추가 → IR-invisible 였던 holdAnchorAndSO 드롭을 게이트가 검출
(미래 회귀 봉인). 직렬화 수정 후이므로 samples 회귀 0(baseline 4/4).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IR 통제 비교 회귀 0(IR_DIFF 4, holdAnchor 게이트 0 mismatch). 한글: 36383351 붕괴 해소,
이전 OK 30/30 유지(악화 0). 36383351 opengov 가드(게이트 IR-visible化로 회귀 봉인).
한계: edwardkim#1589 군집 이질적 — holdAnchorAndSO 는 부분집합만 해소, 대다수 다른 원인(후속).

closes edwardkim#1594

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1594 — holdAnchorAndSO 드롭 수정

본 PR 에 #1594 합류(devel 누적).

closes #1594

@edwardkim edwardkim self-requested a review June 27, 2026 09:33
@edwardkim edwardkim added hwpx HWPX 포맷 처리: 파싱, 직렬화, roundtrip, XML/ZIP 패키지 보존, 호환성 개선 enhancement New feature or request labels Jun 27, 2026
@edwardkim edwardkim added this to the v1.0.0 milestone Jun 27, 2026
planet6897 and others added 3 commits June 27, 2026 18:48
field.rs:180 ClickHere => "CLICKHERE"(틀림) → "CLICK_HERE". 한글이 미인식하던 placeholder
타입을 정정 → 페이지 붕괴(edwardkim#1589) 지배원인 해소. RED 테스트 GREEN, lib 1969/0, baseline 4/4.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
한글 오라클: 이전 붕괴 파일 37/40(92.5%) 해소, 이전 OK 30/30 유지(악화 0). IR 통제 비교
회귀 0(IR_DIFF 4). edwardkim#1589 페이지 붕괴 군집 지배원인 단일 수정으로 대다수 해소.

closes edwardkim#1595

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1595 — ClickHere 필드 타입 CLICK_HERE 수정 (페이지 붕괴 지배원인)

본 PR 에 #1595 합류(devel 누적).

  • 근본원인: field.rs:180 이 ClickHere 타입을 "CLICKHERE"(언더스코어 누락)로 방출. 정답 "CLICK_HERE"(파서·템플릿). 한글이 미인식 → placeholder 높이 변동 → 페이지 붕괴(HWPX 재저장 시 한글에서 페이지 붕괴(29→3, IR diff=0) — 시각 무손실 갭 #1589). 파서 양형 수용 → IR diff=0.
  • 수정: field.rs:180 "CLICK_HERE" + 테스트 갱신(1줄).
  • 검증: lib 1969/0, baseline 4/4, IR 회귀 0. 한글 오라클: 이전 붕괴 37/40(92.5%) 해소, 이전 OK 30/30 유지(악화 0).

#1589 페이지 붕괴 군집(~16%)의 지배원인. 단일 수정으로 대다수 해소(시각 갭 16%→1.3% 추정). closes #1595

planet6897 and others added 3 commits June 27, 2026 19:05
CLICK_HERE(edwardkim#1595) 후 잔여 붕괴 3건 이진탐색: 전부 polygon/ellipse 보유, render_common_shape_xml
이 도형 지오메트리(lineShape/points/fillBrush) 드롭이 deciding(태그속성 복원 미해소 확인).
도형 직렬화 완성이 별 타스크 필요(우선순위 낮음, long tail).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@planet6897

Copy link
Copy Markdown
Contributor Author

#1597 로 대체합니다 — devel 통합 브랜치의 누적 작업을 stream/devel 기준 단일 squash 커밋으로 정리. 본 PR은 close.

@planet6897 planet6897 closed this Jun 27, 2026
@planet6897

Copy link
Copy Markdown
Contributor Author

추가: Task #1596 — generic-shape 지오메트리 직렬화 완성

본 PR 에 #1596 합류(devel 누적).

  • 근본원인: render_common_shape_xml(section.rs:1327)이 polygon/ellipse/arc/curve 의 지오메트리(lineShape/shadow/hc:pt 꼭짓점) 드롭 → 도형 형상 소실 → 페이지 붕괴(HWPX 재저장 시 한글에서 페이지 붕괴(29→3, IR diff=0) — 시각 무손실 갭 #1589 잔여). IR 보유, serializer-only.
  • 수정: drawing+points 수신, shape_block 직후 지오메트리 방출(write_rect 동형) + 태그/pos 속성 보강.
  • 검증: lib 1970/0, baseline 4/4, IR 회귀 0. 한글 36396457 polygon 11→4 붕괴 → 11→11 해소, 이전 OK 40/40 유지(악화 0).

#1589 잔여 shape 붕괴 해소. 누적(#1594+#1595+#1596) 페이지 붕괴 ~95%+ 해소. closes #1596

planet6897 added a commit to planet6897/rhwp that referenced this pull request Jun 27, 2026
…ash)

활성 devel 통합 브랜치의 누적 작업을 upstream/devel 기준 단일 squash 커밋으로 정리.

포함 작업 (직렬화/렌더 무손실):
- edwardkim#1584 본문 인라인 ColumnDef 드롭 수정
- edwardkim#1587 Ruby(덧말) 직렬화 (모델/파서/serializer)
- edwardkim#1588 선 도형 shapeComment 방출
- edwardkim#1592 HWPX 빈 문단 spurious (0,0) 수정
- edwardkim#1594 holdAnchorAndSO 드롭 수정 + diff_documents 게이트 (페이지 붕괴)
- edwardkim#1595 ClickHere 필드 타입 CLICK_HERE 수정 (페이지 붕괴 지배원인)
- edwardkim#1596 generic-shape(polygon/curve) 지오메트리 직렬화 완성 (페이지 붕괴)
- edwardkim#1598 ellipse/arc 전용 지오메트리 파서+직렬화 완성 (페이지 붕괴 잔여)

회귀 게이트/말뭉치:
- edwardkim#1564 opengov 고정 실문서 회귀 말뭉치 + 스냅샷 게이트
- serializer/hwpx roundtrip·table rustfmt 정리

조사/도구:
- edwardkim#1589 페이지 붕괴 군집/오라클 조사 (tools/verify_hangul_pages.py, 문서)
- edwardkim#1591 para0 북마크 hoist 조사 (순효과 0, 롤백)

edwardkim#1589 누적 4종(holdAnchorAndSO/ClickHere/generic-shape/ellipse-arc) IR-invisible
직렬화 결함 해소 — 붕괴율 ~16% → 잔여 표본 미관측.

검증(로컬): cargo test --lib 1970 passed 0 failed, clippy·fmt clean.
단일 squash라 task 단위 히스토리는 원본 devel 브랜치에 보존됨.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
planet6897 added a commit to planet6897/rhwp that referenced this pull request Jun 27, 2026
…ash)

활성 devel 통합 브랜치의 누적 작업을 upstream/devel 기준 단일 squash 커밋으로 정리.

포함 (직렬화/렌더 무손실):
- edwardkim#1584 본문 인라인 ColumnDef 드롭 / edwardkim#1587 Ruby(덧말) / edwardkim#1588 선 도형 shapeComment
- edwardkim#1592 빈 문단 spurious (0,0) / edwardkim#1594 holdAnchorAndSO + diff_documents 게이트
- edwardkim#1595 ClickHere CLICK_HERE (붕괴 지배원인) / edwardkim#1596 generic-shape 지오메트리
- edwardkim#1598 ellipse/arc 전용 지오메트리 파서+직렬화

회귀 게이트: edwardkim#1564 opengov 말뭉치/스냅샷, serializer/hwpx rustfmt 정리
조사: edwardkim#1589 페이지 붕괴 군집/오라클, edwardkim#1591 북마크 hoist(롤백)

edwardkim#1589 누적 4종(holdAnchorAndSO/ClickHere/generic-shape/ellipse-arc) IR-invisible
직렬화 결함 해소. 검증: cargo test --lib 1970 passed 0 failed, fmt --all clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request Jun 27, 2026
HWPX 직렬화 무손실 개선 + opengov 회귀 말뭉치 + 페이지붕괴 군집 해소 (#1586 통합 squash)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request hwpx HWPX 포맷 처리: 파싱, 직렬화, roundtrip, XML/ZIP 패키지 보존, 호환성 개선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants