Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions mydocs/plans/task_m100_842.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 수행계획서 — Task #842 (M100)

## 대상
shortcut.hwp(`samples/basic/shortcut.hwp`) ↔ 한컴 PDF(`pdf/basic/shortcut-2022.pdf`) 시각 정합성 잔여 결함 4건.

GitHub Issue: edwardkim/rhwp#842
브랜치: `local/task842` (← upstream/devel)

## 결함 요약

| # | 증상 | 1차 원인 가설 | 영향 범위 |
|---|------|--------------|----------|
| 1 | 섹션 헤더 바(1×1 TAC 표) 위/아래 줄 간격 ~13~38px 압축 | TAC 1×1 표 앞뒤 단락 간격 보정 누락/부분적용 (구 #770/#773/#776, RFC #774 동일 본질) | 8페이지 전 헤더 |
| 2 | 일부 섹션(파일·편집·보기·입력·서식·기타) 본문에 없어야 할 좌측 여백 | ParaShape `margins.left`(예 4000) 적용 기준 또는 다단 zone 진입 첫 단락 들여쓰기 처리 | 해당 섹션 본문 |
| 3 | 두 단 사이 가운데 구분선이 실선 (점선이어야 함) | ColumnDef 구분선 종류(line type) 미보존 + 렌더러 실선 고정 | 다단 페이지 전체 |
| 4 | 단축키 우측정렬 항목 일부가 단 우측 끝 초과 (예 `Ctrl+(회색)5`, `Alt+P/Ctrl+P`) | cross-run right-tab 정렬이 탭 직후 1개 composed run 폭만 사용 → 스크립트 경계로 쪼개진 나머지 run 오버플로 (`src/renderer/layout/paragraph_layout.rs` 1419~1480행 부근) | 우측정렬 탭 + 혼합 스크립트 콘텐츠 |

## 진행 방침

- 4건은 본질이 다르므로 **독립 단계**로 처리. 한 건 수정이 다른 건 회귀를 일으키지 않도록 매 단계 후 광범위 샘플 + shortcut.hwp 8페이지 SVG 비교.
- 1번(헤더 spacing)은 layout 본질 정정 위험군(메모리: `feedback_essential_fix_regression_risk`) — 다단/단일단/표분할 상호작용 회귀 점검 필수. 가장 위험하므로 마지막 단계 배치.
- 권위 자료: macOS 환경이므로 `pdf/basic/shortcut-2022.pdf` 1차. 한컴 2010 편집기 직접 출력이 가능한 환경이면 그게 최종.
- 코드 수정 전 IR 진단(`dump`, `dump-pages`, `--debug-overlay`) 으로 원인 확정.

## 단계 구성 (예정 — 구현계획서에서 확정)

1. **진단·재현 고정**: 4건 각각의 IR/레이아웃 근거 확정, 회귀 비교용 기준 SVG 캡처(`output/svg/`).
2. **결함 #4 (우측탭 오버플로)**: cross-run right-tab 폭 합산 수정.
3. **결함 #3 (단 구분선 점선)**: ColumnDef 구분선 종류 보존 + 렌더러 dasharray.
4. **결함 #2 (섹션 본문 좌측 여백)**: 원인 확정 후 들여쓰기 기준 수정.
5. **결함 #1 (헤더 표 spacing)**: TAC 1×1 표 앞뒤 단락 간격 보정 — 회귀 광역 검증 포함.
6. **종합 검증·보고서**: 전체 cargo test + clippy + shortcut.hwp 8페이지 + 회귀 샘플 비교, 최종 보고서.

## 검증 기준

- `cargo test` 전건 통과, `cargo clippy` 경고 0(신규).
- shortcut.hwp 8페이지 SVG 가 PDF 와 4건 모두 정합.
- 회귀: 다단/표/목차 류 기존 샘플 SVG diff 무변화(의도된 변경 외).

---
승인 요청: 위 수행 방침으로 진행해도 되는지 확인 부탁드립니다. 승인 시 구현계획서(`task_m100_842_impl.md`)를 작성합니다.
104 changes: 104 additions & 0 deletions mydocs/plans/task_m100_842_impl.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# 구현계획서 — Task #842 (M100)

대상: shortcut.hwp PDF 정합성 잔여 결함 4건 (Issue edwardkim/rhwp#842)
브랜치: `local/task842`

회귀 위험이 가장 큰 #1(헤더 표 spacing, layout 본질 정정)을 마지막에 배치. 작은 위험 → 큰 위험 순.

---

## Stage 1 — 진단 및 회귀 기준 고정

목표: 4건 각각의 IR/레이아웃 근거를 확정하고, 수정 전 기준 산출물을 캡처한다. **소스 수정 없음.**

작업:
- `rhwp export-svg samples/basic/shortcut.hwp -o output/svg/task842_before/` — 8페이지 기준 SVG.
- 결함 #4: `dump -s 0 -p {해당}` 으로 `Ctrl+(회색)5`, `Alt+P/Ctrl+P` 단락의 char-shape run·tab_def 확인. composer가 해당 run 을 스크립트 경계로 쪼개는지 로그/코드로 확정.
- 결함 #3: ColumnDef 파싱 결과(`src/parser/.../column*` 및 IR)에서 단 구분선 종류 필드가 존재/보존되는지 확인. 없으면 파싱 추가 필요 범위 식별.
- 결함 #2: 파일·편집·보기·입력·서식·기타 섹션 본문 첫 단락 `dump -s N -p M` → ParaShape margins, 소속 단/zone, 헤더 표와의 관계 확인. PDF 와 left x 차이를 수치로 기록.
- 결함 #1: `dump-pages -p {각 헤더 페이지}` 로 헤더 표 앞뒤 단락 간격 측정, PDF 대비 부족분 수치화. 구 #770/#773/#776/#774 문서 재확인.
- 회귀 비교 대상 샘플 목록 확정(다단/표분할/목차 류 — `samples/` 내).

산출물: `mydocs/working/task_m100_842_stage1.md` (진단 결과 + 원인 확정 + 수정 범위 + 회귀 대상 목록).

---

## Stage 2 — 결함 #4: cross-run 우측탭 폭 합산 수정

목표: 우측/가운데 탭 뒤 콘텐츠가 여러 composed run 으로 쪼개져도 단 우측 끝에 정확히 정렬되도록 한다.

작업:
- `src/renderer/layout/paragraph_layout.rs` render 패스(1419~1480행 부근, est 패스 992~1069행도 동일 처리):
- 탭 뒤 첫 의미있는 run 부터 **다음 탭 또는 줄끝까지** 의 composed run 들의 폭을 합산하여 정렬 시작 x 산출.
- 빈 공백 run carry-over 로직과 일관되게 유지(공백 run 은 합산 단위 포함 여부 검토 — 한컴 동작 기준).
- leader end_x 보정 로직이 합산 폭 기준으로 동작하도록 조정.
- est 패스(높이 측정)와 render 패스가 동일 규칙을 쓰는지 확인.

검증: shortcut.hwp 8페이지에서 `Ctrl+(회색)5`, `Alt+P/Ctrl+P`, `(회색)+/-`, `Shift+(회색)+/-`, `Ctrl+(회색)+`, `Ctrl+(회색)-` 등 모든 혼합 스크립트 우측탭 항목이 일반 항목과 같은 우측 끝(±1px). 회귀: 목차 류 우측탭(페이지번호) 샘플 SVG diff 무변화. `cargo test`.

산출물: `mydocs/working/task_m100_842_stage2.md`.

---

## Stage 3 — 결함 #3: 단 구분선 점선 반영

목표: 다단 구분선을 ColumnDef 에 지정된 선 종류(점선 등)로 렌더링한다.

작업:
- (Stage 1 결과에 따라) ColumnDef 파싱에 구분선 종류 필드 보존 추가 — HWP5/HWPX 양쪽.
- 레이아웃→렌더 노드로 구분선 종류 전달.
- SVG/렌더러에서 선 종류 → `stroke-dasharray` 매핑(점선/파선/실선 등). SVG export 에 단 구분선이 누락돼 있다면 함께 추가.

검증: shortcut.hwp 다단 페이지에 PDF 와 동일한 점선 세로 구분선. 회귀: 실선 구분선 사용 다단 샘플 무변화.

산출물: `mydocs/working/task_m100_842_stage3.md`.

---

## Stage 4 — 결함 #2: 섹션 본문 좌측 여백 정정

목표: 파일·편집·보기·입력·서식·기타 섹션 본문의 좌측 들여쓰기를 PDF 와 일치시킨다.

작업:
- Stage 1 에서 확정한 원인에 따라 수정:
- (a) ParaShape `margins.left` 적용 기준이 단 안쪽이어야 하는데 본문 영역 기준이면 → 단(column) 기준으로 보정.
- (b) 다단 zone 진입 첫 단락 들여쓰기 처리 차이면 → 해당 경로 수정.
- 룰/휴리스틱 구분(메모리 `feedback_rule_not_heuristic`): HWP 명세상 기준이 명확하면 단일 룰로, 분기 도입 전 자문.

검증: 해당 6개 섹션 본문 left x 가 PDF 와 일치. 회귀: 단일 단 문서 + 다른 다단 문서 본문 들여쓰기 무변화.

산출물: `mydocs/working/task_m100_842_stage4.md`.

---

## Stage 5 — 결함 #1: 헤더 1×1 TAC 표 앞뒤 단락 간격 보정

목표: 섹션 헤더 바 위/아래 간격을 한컴 PDF 와 일치시킨다. **layout 본질 정정 — 회귀 위험 최고, 광역 검증 필수.**

작업:
- Stage 1 진단 + RFC #774 분석 기반으로 TAC 1×1 표 앞뒤 단락 간격(before/after spacing) 보정 규칙 구현.
- 메모리 `feedback_essential_fix_regression_risk`: 다단/단일단/표분할 상호작용 회귀 광범위 검증.

검증: shortcut.hwp 8페이지 전 헤더 위아래 간격이 PDF 와 일치(±수 px). 회귀: TAC 표 포함 샘플 전수 + 표분할 샘플 + 한컴 2010/2020 정답지 대비 비교(가능 범위). `cargo test` 전건.

산출물: `mydocs/working/task_m100_842_stage5.md`.

---

## Stage 6 — 종합 검증 및 최종 보고서

작업:
- `cargo test` 전건 통과, `cargo clippy --all-targets` 신규 경고 0.
- shortcut.hwp 8페이지 SVG ↔ PDF 4건 모두 정합 최종 확인. `output/svg/task842_after/` 캡처 + before/after diff.
- 회귀 대상 샘플 SVG diff 최종 점검.
- 최종 보고서 `mydocs/report/task_m100_842_report.md` 작성.
- merge 전 `git status` 로 미커밋 파일 확인.

---

## 커밋 규약
- 각 Stage 소스 + `working/task_m100_842_stage{N}.md` 함께 커밋, 메시지 `Task #842: ...`.
- 최종 보고서 커밋 후 승인 → `local/task842` → `local/devel` merge (원격 push 금지).

---
승인 요청: 위 6단계 구현계획으로 진행해도 되는지 확인 부탁드립니다. 승인 시 Stage 1 진단부터 착수합니다.
38 changes: 38 additions & 0 deletions mydocs/report/task_m100_842_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# 최종 결과 보고서 — Task #842 (M100)

대상: shortcut.hwp(`samples/basic/shortcut.hwp`) ↔ 한컴 PDF(`pdf/basic/shortcut-2022.pdf`) 시각 정합성 잔여 결함 4건.
GitHub Issue: edwardkim/rhwp#842 · 브랜치: `local/task842` (← upstream/devel)

## 결과 요약

| # | 결함 | 결과 |
|---|------|------|
| 4 | 단축키 우측탭 정렬 일부가 단 우측 끝 초과 | ✅ 수정 (Stage 2 + 2b) |
| 3 | 두 단 가운데 구분선이 실선 (점선이어야 함) | ✅ 수정 (Stage 3) |
| 2 | 페이지 2~8 섹션 헤더 바 +28px 우측 편위 | ✅ 수정 (Stage 4) |
| 1 | 헤더 1×1 TAC 표 앞뒤 수직 spacing 압축 | ⏸ 미수정 — RFC #774 영역, 후속 이슈로 분리 (Stage 5 조사 완료) |

`cargo test` 전건 통과 (svg_snapshot 8/8 포함). 회귀 없음. (`cargo clippy` 는 본 타스크 무관한 pre-existing `error: unwrap() will always panic` — `table_ops.rs:1007`, `object_ops.rs:304` — 으로 컴파일 실패하나 본 변경과 무관.)

## 변경 내역

### 결함 #4 — `src/renderer/layout/paragraph_layout.rs`, `src/renderer/layout/text_measurement.rs`
- `right_tab_block_width()` 헬퍼: cross-run 우측·가운데 탭 정렬 시, 탭 직후 run 부터 `\t` 없는 연속 composed run 들의 폭을 합산해 정렬 시작 x 산출. composer 가 스크립트·char-shape 경계로 run 을 쪼개는 케이스(`"Ctrl+(회색)5"` → `["Ctrl+(", "회색)", "5"]`)에서 나머지 run 이 탭스톱 우측으로 흘러넘치던 ~32px 오버플로 해소.
- `compute_char_positions` 의 in-run RIGHT 인라인 탭 분기 `(2, _) if fill_low != 0` → `(2, _)` 로 확장: RIGHT 인라인 탭은 leader 유무 무관하게 `body_right - our_seg_w` 로 정렬(한컴 `ext[0]` 무시). char-shape 경계가 `\t` 앞에 놓여 run 이 `\t` 로 시작하는 케이스(`"끝"`(id7) + `"\tAlt+X"`(id8))의 ~28px 오버플로 해소.
- 결과: shortcut.hwp 8페이지 우측정렬 단축키 항목 전부 정렬 폭 ±6px 수렴.

### 결함 #3 — `src/renderer/layout.rs::build_column_separators`
- `separator_type → StrokeDash` 매핑에 `6 => Dash`(LongDash 근사), `7 => Dot`(Circle/원형 점선) 추가. `doc_info.rs:294` line_type 의미와 정합. shortcut.hwp 2단 ColumnDef 의 `구분선 type=7` 이 실선 → 점선(`stroke-dasharray="2 2"`)으로 렌더.

### 결함 #2 — `src/renderer/layout.rs::layout_table_item` (`is_tac` 분기)
- 다줄 문단(`composed.lines.len() > 1`)이고 line 0 에 `char::is_alphanumeric()` 글자(한글 음절/라틴/숫자/한자)가 있으면 → 표는 line 0 텍스트 *다음* 이 아니라 자체 줄 좌측에서 시작하므로 `leading = 0` (line 0 폭 미합산).
- line 0 이 HWP TAC 필러(`U+F081C`·`U+F012B` 등 PUA)/공백뿐인 경우(예 복학원서.hwp pi=16 — 한컴이 표 폭만큼 필러를 채워 줄바꿈시킨 케이스)는 종전대로 `compute_tac_leading_width`. `is_alphanumeric()` 판정으로 PUA 필러 자동 제외.
- 결과: shortcut.hwp 헤더 바 페이지 1~8 전부 rect x = body 좌측(94.5), `issue_677_bokhakwonseo_page1` snapshot 유지.

## 미수정 — 결함 #1 (후속 이슈로 분리)
헤더 1×1 TAC 표 앞뒤 수직 여백(과 제목 위 여백)이 PDF 대비 ~15~25px 부족. 본문 행 pitch 자체는 정상. 명시 spacing(`spacing before/after`)에 해당 여백이 없어, 한컴이 zone 전환(1단↔2단)/TAC 표 문단 line-height 기반으로 넣는 암묵 간격으로 추정 — 닫힌 이슈 #770/#773/#776 + RFC #774 의 주제. 본질 정정 위험군이라 RFC 분석 + 광역 회귀 검증과 함께 별도 처리. 정밀 PDF 비교 데이터는 `mydocs/working/task_m100_842_stage5.md`.

부수 발견(별개): (1) 제목 첫 글자 "흔" 누락("흔글 2010" → "글 2010"), (2) 페이지 3→4 column-break 행 밀림(`<편집 화면 분할에서>` "화면 이동" — 닫힌 #768 과 동일). 둘 다 후속 이슈 대상.

## 커밋
`f1665bff`(Stage 1) → `aac23bc7`(Stage 2) → `63a41829`(Stage 2b) → `6f0a0784`(Stage 3) → `2663eb32`/`5f2d85ab`(Stage 4 조사) → `bc2e8e54`(Stage 4 수정) → `3ed8da48`(Stage 5 조사) → 본 보고서.
72 changes: 72 additions & 0 deletions mydocs/working/task_m100_842_stage1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Stage 1 완료 보고서 — Task #842 (M100)

목표: 4건 결함의 IR/레이아웃 근거 확정 + 수정 전 기준 산출물 캡처. **소스 수정 없음.**

## 기준 산출물
- `output/svg/task842_before/shortcut_00{1..8}.svg` — 수정 전 8페이지 SVG (회귀 비교 기준).

---

## 결함 #4 — cross-run 우측탭 오버플로 (원인 확정)

증상: `현재 낱말의 끝 글자로 ⟶ Ctrl+(회색)5` 의 `5` 우측 끝 ≈ x 1013px, 정상 우측탭(`Ctrl+Page Up` 등) ≈ x 973px → ~40px 초과.

원인:
- 단축키 문단은 `tab_def_id=1 auto_right=true` (단 우측 끝 자동 우측탭) + 텍스트 `"…\tCtrl+(회색)5"`.
- `src/renderer/composer.rs::split_runs_by_lang` 가 char-shape run `"Ctrl+(회색)5"` 를 스크립트 경계로 분할 → `["Ctrl+(", "회색)", "5"]` (`회`/`색` 만 Hangul, `(`·`)` 는 중립이라 인접 run 에 흡수, `5` 는 ASCII digit 이라 비중립 → 별도 run).
- `src/renderer/layout/paragraph_layout.rs` cross-run right-tab 처리(render 패스 ~1419~1480, est 패스 ~992~1069): `pending_right_tab_render` 소비 시 **탭 직후 한 개 composed run** 의 폭만 `estimate_text_width(&run.text, …)` 로 빼서 시작 x 산출. 따라서 `"Ctrl+("` 만 우측 정렬되고 뒤따르는 `"회색)"`·`"5"` (~38px) 가 좌→우 정상 진행으로 탭스톱 오른쪽으로 밀려나옴.
- 기존 빈-공백-run carry-over 분기(`run.text.trim().is_empty()`)로는 못 잡음.

수정 방향: 우측/가운데 탭의 정렬 단위 = **해당 탭부터 다음 탭(또는 줄끝)까지의 composed run 전체**. 그 합산 폭 기준으로 블록 시작 x 산출(leader end_x 보정도 합산 폭 기준). est/render 패스 동일 규칙. Task #279 목차(페이지번호) 케이스 회귀 점검.

영향 항목 (혼합 스크립트 우측탭): `Ctrl+(회색)5`, `(회색)+/-`, `Shift+(회색)+/-`, `Ctrl+(회색)+`, `Ctrl+(회색)-` 등. `Alt+P/Ctrl+P` (`"인쇄\t Alt+P/Ctrl+P"` — 탭 뒤 선행 공백) 도 같은 계열(공백 run carry-over → 다음 단독 run 정렬). 합산-폭 방식이면 함께 해소될 가능성 큼 — Stage 2 에서 재확인.

---

## 결함 #3 — 단 구분선 점선 (원인 확정)

증상: 두 단 사이 세로 구분선이 실선. PDF 는 원형 점선(`⋮` 형태).

원인:
- shortcut.hwp 의 2단 ColumnDef: `2단, 유형=배분, 구분선 type=7, width=7, color=0xaeaeae`. (`type=7` = HWP 선 종류 Circle/원형 점선 — `src/parser/doc_info.rs:303` 참조.)
- `src/renderer/layout.rs::build_column_separators` (~1029~1035): `separator_type` → `StrokeDash` 매핑이 `2=>Dash, 3=>Dot, 4=>DashDot, 5=>DashDotDot, _=>Solid` 만 처리. `6`(LongDash), `7`(Circle) 누락 → `7` 이 `_ => Solid` 로 떨어짐.
- 파서/IR(`ColumnDef.separator_type/width/color`)·SVG `<line>` 출력 자체는 정상 동작 (`output/svg/task842_before/shortcut_002.svg` 에 `<line … stroke="#aeaeae" …/>` 존재, dasharray 없음).

수정 방향: `build_column_separators` 의 line-type→dash 매핑을 `doc_info.rs` 의 line_type 의미(1=Solid, 2=Dash, 3=Dot, 5=DashDotDot, 6=LongDash→Dash, 7=Circle→Dot, …)와 일치시킴. 가능하면 `border_line_type_to_dash` 류 공용 변환 재사용. `width=7` → `border_width_to_px` 값(현재 ~1.9px)이 HWP 0.5mm 와 큰 차이면 같이 검토(부차).

---

## 결함 #2 — 섹션 헤더 바 좌측 위치 어긋남 (원인 미확정, Stage 4 에서 확정)

증상(SVG 좌표 재측정으로 정정):
- 페이지 1 `커서 이동` 헤더 바 rect x ≈ 94.5px, 헤더 글자 x0 ≈ 98.3px.
- 페이지 2 `파일` 헤더 바 rect x ≈ 122.5px, 헤더 글자 x0 ≈ 126.3px → 페이지 1 대비 ~28px 우측 이동.
- **본문 텍스트 x0 는 두 페이지 모두 ≈ 121.2px 로 동일** — 즉 어긋난 것은 헤더 바(1×1 TAC 표)뿐. (사용자가 말한 "왼쪽에 여백" = 헤더 바가 오른쪽으로 밀려 본문보다 들어간 상태.)
- 또 페이지 1 body-clip width ≈ 933.5px, 페이지 2+ ≈ 954.0px 로 ~20px 차이.

관찰: 페이지 1 `커서 이동` 헤더 문단(0.1)과 페이지 2 `파일` 헤더 문단(0.36) 의 ParaShape(`margins left=0 right=2000`), TAC 표 outer_margin(1mm), 표 size(69448 HU) 가 **동일**. 차이점: (a) 0.1 은 직전 `구역나누기` + 자체 `다단나누기`, 0.36 은 `쪽나누기`; (b) 직전 ColumnDef 가 0.1 은 `1단 간격=10mm`, 0.36 은 `1단 간격=0mm`. 다단 zone 안에서 쪽나누기로 새 페이지 진입 시 헤더 바 가로 위치/폭 계산이 어긋나는 것으로 추정. 정확한 원인은 Stage 4 에서 `--debug-overlay` + 레이아웃 로깅으로 확정.

---

## 결함 #1 — 헤더 바 1×1 TAC 표 앞뒤 단락 간격 압축 (원인 확정, 회귀 위험 최고)

증상: 각 회색 헤더 바 아래(와 위)에 PDF 가 두는 가시적 여백(~10~13px)이 rhwp 에서 0 에 가까움.

근거 (`dump-pages -p 0`):
- 페이지 1: 단1(헤더 표) `used=31.1px`, 단2/단3(본문) `zone_y_offset=100.2` — 헤더 표 끝(69.1+31.1=100.2)과 본문 시작이 **gap=0**.
- 본문 단2 `used=186.7px` vs `hwp_used≈273.3px` (diff −86.7px), 단3 `used=173.3px` vs `≈253.3px` (diff −80.0px) — dump-pages `used` 가 line-spacing gap 미반영이라 과소 표시이긴 하나(실제 SVG row pitch 는 20px 로 정상), 헤더 표 직후 zone 전환 spacing 누락이 누적 압축의 핵심.
- 헤더 문단 0.1: `spacing before=0 after=0 line=100%`, 본문 문단 0.2: `spacing before=0 after=0` + `[다단나누기]` + `2단 ColumnDef` → 헤더(1단 zone)에서 본문(2단 zone)으로의 **zone 경계**. 명시 spacing 어디에도 없음 → 한컴이 암묵적으로 추가하는 간격(RFC #774 zone-level / TAC 표 후속 spacing).

수정 방향: 구 #770/#773/#776 + RFC #774(`mydocs/...`) 분석 기반으로 TAC 1×1 표 문단 직후(또는 zone 전환 시) 한컴 동일 간격 보정. **layout 본질 정정 — 다단/단일단/표분할 상호작용 회귀 광범위 검증 필수**(메모리 `feedback_essential_fix_regression_risk`). 그래서 Stage 5(마지막)에 배치.

---

## 회귀 비교 대상 (Stage 2~5 공통)
- 목차/페이지번호 우측탭 샘플 (#4 관련)
- 다단 + 단 구분선 사용 샘플 (#3 관련)
- TAC 표 포함 샘플 전수 + 표분할 샘플 + 다단/단일단 혼재 샘플 (#1, #2 관련)
- 한컴 2010/2020 정답지 접근 가능 시 우선 (#1)

---

다음: Stage 2 — 결함 #4 (cross-run 우측탭 폭 합산) 수정.
Loading
Loading