Skip to content

Task #353: 쪽번호 처리 — NewNumber 매 페이지 재적용 회귀 수정#366

Closed
planet6897 wants to merge 2 commits into
edwardkim:develfrom
planet6897:task353
Closed

Task #353: 쪽번호 처리 — NewNumber 매 페이지 재적용 회귀 수정#366
planet6897 wants to merge 2 commits into
edwardkim:develfrom
planet6897:task353

Conversation

@planet6897

Copy link
Copy Markdown
Contributor

요약

NewNumber 컨트롤이 모든 후속 페이지에 매번 재적용되어 본문 모든 페이지가
page_number=1 로 고정되던 회귀 버그 수정.

samples/2022년 국립국어원 업무계획.hwp:

  • 페이지 시퀀스: [1, 2, 3, 1, 1, ..., 1][1, 2, 1, 2, 3, ..., 33]
  • 푸터 페이지 10: - 1 -- 8 - (PDF 와 일치)
  • 푸터 페이지 30: - 1 -- 28 - (PDF 와 일치)

closes #353

변경 사항

영역 변경
src/renderer/page_number.rs (신규) PageNumberAssigner — consumed set + 단조 카운터
src/renderer/mod.rs pub mod page_number;
src/renderer/typeset.rs TypesetEngine::finalize_pages 의 NewNumber 블록을 Assigner 호출로 치환
src/renderer/pagination/engine.rs Paginator::finalize_pages 도 동일하게 치환
tests/page_number_propagation.rs (신규) 회귀 테스트 2건

핵심 변경 로직

기존 (버그):

if let Some(fp) = first_para {
    for &(nn_pi, nn_num) in new_page_numbers {
        if nn_pi <= fp {           // 매 페이지마다 참 → 매번 리셋
            page_num = nn_num as u32;
        }
    }
}

수정:

let mut assigner = PageNumberAssigner::new(new_page_numbers, 1);
for page in pages.iter_mut() {
    let page_num = assigner.assign(page);  // 1회만 적용 + 자동 +1
    ...
}

assign() 동작:

  1. consumed 에 없는 NewNumber 중 그 컨트롤의 소유 문단이 페이지에서 처음 등장하면 적용 + consumed 마킹
  2. 카운터 증가

"처음 등장" 판정:

  • FullParagraph / Table / Shape: 항상 인정
  • PartialParagraph: start_line == 0 일 때만
  • PartialTable: is_continuation == false 일 때만

Test plan

  • cargo test --lib renderer::page_number — 단위 테스트 6건 통과
  • cargo test --test page_number_propagation — 회귀 테스트 2건 통과
  • RHWP_USE_PAGINATOR=1 cargo test --test page_number_propagation — PAGINATOR 경로 2건 통과
  • cargo test 전체 — 1006 + 49(통합) 모두 통과, 회귀 0건
  • cargo clippy --all-targets --release — 신규 경고 0건
  • 시각 검증 — PDF 페이지 5/10/15/20/30/35 푸터와 SVG 푸터 정확 일치
  • 다른 샘플 spot check — exam_kor.hwp (24p), exam_math.hwp (20p), 21_언어_기출_편집가능본.hwp (15p) 모두 1..N 단조 증가

명시적 제외 (별도 이슈)

참고 문서

  • 수행 계획서: mydocs/plans/task_m05x_353.md
  • 구현 계획서: mydocs/plans/task_m05x_353_impl.md
  • 단계별 보고서: mydocs/working/task_m05x_353_stage{1..5}.md
  • 최종 보고서: mydocs/report/task_m05x_353_report.md

증상: 모든 페이지가 page_num=1로 고정.

원인: typeset.rs/engine.rs 의 finalize_pages 가 NewNumber 컨트롤을
'nn_pi <= first_para' 조건으로 매 페이지마다 재적용.

수정:
- PageNumberAssigner 신설 (consumed set + 단조 카운터)
- "처음 등장" 판정: PartialParagraph(start_line==0),
  PartialTable(!is_continuation), 그 외 항상 인정
- typeset.rs / pagination/engine.rs 양쪽이 동일 함수 사용

검증:
- 회귀 테스트 2건 통과 (기본 / RHWP_USE_PAGINATOR=1)
- 단위 테스트 6건 통과
- 전체 cargo test 1006+49 회귀 0
- PDF 페이지 5/10/20/30 푸터와 정확 일치
- exam_kor/exam_math/21_언어 spot check 회귀 0

closes edwardkim#353
CI 환경에 'samples/2022년 국립국어원 업무계획.hwp' 가 없을 때
panic 대신 정상 skip 하도록 수정 (read 실패 시 eprintln 후 return).
edwardkim added a commit that referenced this pull request Apr 27, 2026
PR #366 (@planet6897) 의 코드 변경은 체리픽으로 흡수했으나,
plans/working/report 문서는 Task #361 (이미 v0.7.7 에 적용) 의 문서로
이미 대체되어 중복. M05x 섹션 (orders) 도 Task #361 처리 항목과
중복되므로 정리.

- 코드 흡수: PageNumberAssigner 모듈 + Paginator 경로 정정 + 회귀 테스트 (commit 6cd97f0, fa10ead)
- 문서 제거: task_m05x_353 plans/working/report (Task #361 문서로 대체)
- orders: M05x 섹션 정리 (Task #361#361 항목과 통합)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request Apr 27, 2026
PR #366 의 결함이 이미 v0.7.7 의 Task #361 로 정정되어 있어,
PR 의 다음 가치를 체리픽 방식으로 흡수:
- PageNumberAssigner 모듈 (TypesetEngine + Paginator 통합)
- Paginator 경로의 동일 정정
- 회귀 테스트 (tests/page_number_propagation.rs 2건 + 단위 6건)

검증: 1014 lib passed, 6 svg_snapshot, 2 회귀 + 6 단위 테스트 통과,
샘플 페이지 수 + LAYOUT_OVERFLOW 무변화 (Task #361 효과 유지).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim added a commit that referenced this pull request Apr 27, 2026
PR #366 의 코드 가치 (PageNumberAssigner 모듈 + Paginator 정정 + 회귀 테스트)
체리픽 방식 흡수. 작성자 attribution 보존.

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

Copy link
Copy Markdown
Owner

@planet6897 님 안녕하세요!

쪽번호 처리 결함 #353 에 대한 정성스러운 PR 정말 감사합니다.

본 결함은 동시기에 메인테이너 (Task #361) 에서도 정정되어 v0.7.7 (2026-04-27 배포) 에 이미 포함되었습니다.
다만 본 PR 의 접근이 더 정돈된 부분이 있어서, 메인테이너가 다음 가치를 체리픽 방식으로 흡수하기로 결정했습니다:

  1. PageNumberAssigner 모듈 추출 — TypesetEngine 과 Paginator 두 경로의 같은 시멘틱을 단일 모듈로 통합 (코드 중복 제거 + 재발 방지)
  2. Paginator 경로의 동일 정정 — Task TypesetEngine page_num 갱신 + section 내 vpos reset 결함 (v0.7.3 대비 회귀) #361 은 TypesetEngine 만 정정했는데, 본 PR 이 Paginator 경로의 신뢰성 낮은 부분도 같이 정정한 점이 좋았습니다
  3. 회귀 테스트 (tests/page_number_propagation.rs) — 본 결함 재발 방지의 핵심

작성자 분의 attribution 은 체리픽 commit 으로 보존됩니다 (commit 6cd97f0, fa10ead). 시각/회귀 검증도 통과했습니다 (cargo test --lib 1014 passed).

본 PR 은 close 하지만, 작성자 분의 기여는 v0.7.x 사이클의 코드 정합성에 큰 도움이 됐습니다. 다음 사이클에서도 좋은 PR 부탁드립니다 — 감사합니다! 🙏

상세 보고: `mydocs/pr/pr_366_report.md`

@edwardkim

Copy link
Copy Markdown
Owner

메인테이너 흡수 처리 완료. 상세는 위 댓글 + mydocs/pr/pr_366_report.md 참고.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants