증상
동일 문서의 .hwpx 와 .hwp 를 파싱하면 ParaShape indent(들여쓰기/내어쓰기) 값이 정확히 2배 어긋난다. 여백(margin_left/margin_right)·문단간격은 완전히 일치하는데 indent 만 불일치한다.
HwpUnitChar switch/case 를 가진 paraPr 에서만 발생하며, 어긋남은 항상 정확히 2배다(예외 0건).
$ rhwp ir-diff "samples/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.hwpx" \
"samples/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.hwp"
[차이] PS[12] indent: -3216vs-1608 ← HWPX -3216 vs HWP5 -1608 (정확히 2배)
[차이] PS[15] indent: -9658vs-4829
[차이] PS[17] indent: -15350vs-7675
... (이 파일에서 14건, 전부 A==2*B)
여러 시험지 샘플에서 동일하게 재현된다(systematic, 문서 독립적):
| 샘플 |
indent 불일치 |
margin 불일치 |
비율 |
3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0 |
14건 |
0건 |
전부 정확히 2× |
3-09월_교육_통합_2023 |
31건 |
0건 |
전부 정확히 2× |
3-10월_교육_통합_2022 |
18건 |
0건 |
전부 정확히 2× |
근본 원인 위치
src/parser/hwpx/header.rs parse_para_shape_switch() — HwpUnitChar case 에서 값에 * 2 를 적용한다(L1143-1155):
if in_hwpunitchar_case {
// HwpUnitChar 값은 실제 HWPUNIT(1× 스케일)이므로
// HWP 바이너리와 동일한 2× 스케일로 변환
let val2x = val * 2;
match tag_name {
b"left" => ps.margin_left = val2x,
b"right" => ps.margin_right = val2x,
b"intent" => ps.indent = val2x, // ← 이 줄(L1150)이 indent 까지 2× 적용
b"prev" => ps.spacing_before = val2x,
b"next" => ps.spacing_after = val2x,
_ => {}
}
}
HWPX <hp:switch> 가 같은 값을 두 표현으로 담는데, intent 만 두 표현 사이의 2배 관계가 margin 과 반대다:
samples/.../3-11월_...구분선위0미주사이0구분선아래0.hwpx 의 paraPr[12]:
| 필드 |
HwpUnitChar case |
default (unit="HWPUNIT") |
현재 코드 결과(case×2) |
HWP5 바이너리 |
left (margin) |
1200 |
2400 |
2400 ✅ HWP5 일치 |
2400 |
intent (indent) |
-1608 |
-3216 |
-3216 ❌ |
-1608 |
즉 margin 은 case×2 == default == HWP5 라서 2× 가 맞지만, indent 는 case == HWP5(= default 의 절반) 이라 2× 를 적용하면 HWP5 와 어긋난다. intent 에만 2× 가 과잉 적용되는 것으로 보인다.
(참고: 같은 파서의 평면 속성 경로 header.rs:1035 b"indent" => ps.indent = parse_i32(&attr) 는 indent 를 1× 그대로 읽어, switch 경로와 스케일이 불일치한다.)
영향
Document IR 에서 renderer 는 margin_left 와 indent 를 같은 단위(HWPUNIT) 로 함께 사용한다. 현재:
- HWPX 파싱:
(margin=2400, indent=-3216)
- HWP5 파싱:
(margin=2400, indent=-1608)
→ 같은 문서인데 두 포맷의 내어쓰기 폭이 2배 차이로 렌더된다(한쪽이 한컴 조판과 불일치). v1.0.0 "한컴 동일 조판" 목표에 직접 영향.
방향 판정 — 한컴 시각 권위 필요
어느 쪽이 옳은지는 추론만으로 확정 불가다(두 일관성 논증이 충돌):
- HWP5(-1608) 가 정답 가설: 렌더러는 주로 HWP5 기준으로 보정되어 왔고, 평면
indent 경로도 1× 로 읽는다 → switch 의 intent 2× 가 버그.
- HWPX(-3216) 가 정답 가설: 같은 paraPr 안에서
margin 이 default 스케일(2400)로 쓰이므로, 동일 단위인 indent 도 default 스케일(-3216)이어야 일관 → HWP5 파서가 indent 를 절반으로 읽는 것이 버그.
정답지(한컴 2022 PDF)가 이 파일에 존재하므로 메인테이너 환경에서 시각 판정 가능:
pdf/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.pdf — 내어쓰기 문단(①②③ 목록)의 첫 줄 시작 x 위치로 -1608/-3216 중 한쪽 확정 가능.
재현
cargo build --bin rhwp
./target/debug/rhwp ir-diff "samples/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.hwpx" \
"samples/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.hwp" \
| grep indent
관련 이슈
제안
방향(어느 값이 한컴 정답인지)만 확정되면 수정은 1줄 수준이다(예: intent 를 val2x 대상에서 제외, 또는 HWP5 파서 측 보정). 방향 지시 주시면 회귀 테스트(파일별 ir-diff indent parity=0)와 함께 PR 올리겠습니다.
증상
동일 문서의
.hwpx와.hwp를 파싱하면 ParaShapeindent(들여쓰기/내어쓰기) 값이 정확히 2배 어긋난다. 여백(margin_left/margin_right)·문단간격은 완전히 일치하는데indent만 불일치한다.HwpUnitCharswitch/case 를 가진 paraPr 에서만 발생하며, 어긋남은 항상 정확히 2배다(예외 0건).여러 시험지 샘플에서 동일하게 재현된다(systematic, 문서 독립적):
3-11월_실전_통합_2024-구분선위0미주사이0구분선아래03-09월_교육_통합_20233-10월_교육_통합_2022근본 원인 위치
src/parser/hwpx/header.rsparse_para_shape_switch()—HwpUnitCharcase 에서 값에* 2를 적용한다(L1143-1155):HWPX
<hp:switch>가 같은 값을 두 표현으로 담는데,intent만 두 표현 사이의 2배 관계가 margin 과 반대다:samples/.../3-11월_...구분선위0미주사이0구분선아래0.hwpx의paraPr[12]:casedefault(unit="HWPUNIT")left(margin)intent(indent)즉 margin 은
case×2 == default == HWP5라서 2× 가 맞지만, indent 는case == HWP5(=default의 절반) 이라 2× 를 적용하면 HWP5 와 어긋난다.intent에만 2× 가 과잉 적용되는 것으로 보인다.(참고: 같은 파서의 평면 속성 경로
header.rs:1035 b"indent" => ps.indent = parse_i32(&attr)는indent를 1× 그대로 읽어, switch 경로와 스케일이 불일치한다.)영향
DocumentIR 에서renderer는margin_left와indent를 같은 단위(HWPUNIT) 로 함께 사용한다. 현재:(margin=2400, indent=-3216)(margin=2400, indent=-1608)→ 같은 문서인데 두 포맷의 내어쓰기 폭이 2배 차이로 렌더된다(한쪽이 한컴 조판과 불일치). v1.0.0 "한컴 동일 조판" 목표에 직접 영향.
방향 판정 — 한컴 시각 권위 필요
어느 쪽이 옳은지는 추론만으로 확정 불가다(두 일관성 논증이 충돌):
indent경로도 1× 로 읽는다 → switch 의intent2× 가 버그.margin이 default 스케일(2400)로 쓰이므로, 동일 단위인indent도 default 스케일(-3216)이어야 일관 → HWP5 파서가 indent 를 절반으로 읽는 것이 버그.정답지(한컴 2022 PDF)가 이 파일에 존재하므로 메인테이너 환경에서 시각 판정 가능:
pdf/3-11월_실전_통합_2024-구분선위0미주사이0구분선아래0.pdf— 내어쓰기 문단(①②③ 목록)의 첫 줄 시작 x 위치로 -1608/-3216 중 한쪽 확정 가능.재현
관련 이슈
HwpUnitChar분기로 문단/줄간격 보정 도입 — 이 2× 로직의 출처)ir-diff도구 — 본 불일치를 표면화한 도구)제안
방향(어느 값이 한컴 정답인지)만 확정되면 수정은 1줄 수준이다(예:
intent를val2x대상에서 제외, 또는 HWP5 파서 측 보정). 방향 지시 주시면 회귀 테스트(파일별 ir-diff indent parity=0)와 함께 PR 올리겠습니다.