Skip to content

feat(html): 머리말/꼬리말 렌더링 개선 — haN 페이지번호, footer bottom-align, 빈 줄#107

Merged
ohah merged 1 commit intomainfrom
feat/textbox-paragraph-marker-rendering
Mar 4, 2026
Merged

feat(html): 머리말/꼬리말 렌더링 개선 — haN 페이지번호, footer bottom-align, 빈 줄#107
ohah merged 1 commit intomainfrom
feat/textbox-paragraph-marker-rendering

Conversation

@ohah
Copy link
Copy Markdown
Owner

@ohah ohah commented Mar 4, 2026

Summary

headerfooter.hwp fixture와 snapshot 간의 3가지 구조적 차이를 수정합니다.
(line-height/height의 수치 차이(3.53mm↔2.79mm 등 body_default_hls 관련)는 별도 이슈로 이번 PR 범위에서 제외)


1. Header 내 AUTO_NUMBER 페이지 번호(haN) 렌더링

문제: Header 텍스트에 포함된 AUTO_NUMBER 제어문자(code=18)가 무시되어 페이지 번호 없이 텍스트가 통째로 렌더링됨

Before:

<span class="hrt cs2">Header 이것은 머리말입니다.</span>

After:

<span class="hrt cs2">Header 이것은 머리말입니다</span>
<div class="haN" style="left:0mm;top:0mm;width:1.82mm;height:3.17mm;">
  <span class="hrt cs2">1</span>
</div>
<span class="hrt cs2">.</span>

구현:

  • paragraph.rs: collect_auto_numbers() — 문단의 ParaText 레코드에서 AUTO_NUMBER 위치와 display_text를 수집
  • line_segment.rs: LineSegmentContentauto_numbers 필드 추가. 텍스트 렌더링 시 세그먼트 범위 내 AUTO_NUMBER를 감지하면 텍스트를 분리하고 haN div 삽입
  • page.rs: display_text=None(페이지 번호)인 경우 <!--PN--> 플레이스홀더 사용 → render_page에서 실제 페이지 번호로 치환
  • haN 크기: CharShape base_size 기반. height는 floor 절삭(f64 정밀도 문제로 round_to_2dp(3.175)=3.18이 되는 것을 방지), width는 반각 비율(0.5732) 적용

2. Footer hcI bottom-alignment (top 오프셋)

문제: 꼬리말 ListHeader의 vertical_align: Bottom이 무시되어 콘텐츠가 꼬리말 영역 상단에 붙음

Before:

<div class="hcD" style="left:30mm;top:267mm;">
  <div class="hcI">Footer...</div>
</div>

After:

<div class="hcD" style="left:30mm;top:267mm;">
  <div class="hcI" style="top:11.83mm;">Footer...</div>
</div>

구현:

  • ctrl_header/mod.rs: CtrlHeaderResultfooter_content_height_mm: Option<f64> 필드 추가
  • footer.rs: process_footer()에서 ListHeader vertical_align == Bottom일 때 ParaLineSeg의 마지막 세그먼트 vertical_position + line_height로 콘텐츠 높이 계산 (반올림 없이 raw 값 반환)
  • document.rs: footer_content_height_mm를 수집하여 render_page에 전달
  • page.rs: hcI_top = bottom_margin_mm - content_height_mm 공식으로 top 오프셋 적용. 중간값 반올림 없이 최종 결과만 round_to_2dp 적용하여 정밀도 보장 (15.000111... - 3.175 = 11.825111... → 11.83mm)

3. 머리말/꼬리말 호스트 문단의 빈 줄 렌더링

문제: 본문의 두 번째 문단(머리말/꼬리말 CtrlHeader를 호스팅하는 문단)이 has_header_footer 가드에 의해 본문 콘텐츠까지 통째로 스킵됨

Before: 본문에 "첫 페이지" 1줄만 렌더링
After: "첫 페이지" + 빈 줄(empty hls div) 2줄 렌더링

구현: document.rs에서 if !has_header_footer 가드를 제거하여 머리말/꼬리말 문단도 본문 콘텐츠(빈 줄 등)는 렌더링되도록 변경


변경 파일

파일 변경 내용
ctrl_header/footer.rs vertical_align: Bottom 감지 및 콘텐츠 높이 계산
ctrl_header/mod.rs CtrlHeaderResultfooter_content_height_mm 필드 추가
document.rs footer_content_height_mm 수집, has_header_footer 가드 제거, render_page 호출 시 인자 추가
line_segment.rs LineSegmentContentauto_numbers 필드 추가, AUTO_NUMBER 텍스트 분리 및 haN div 삽입
page.rs render_pagefooter_content_height_mm 파라미터 추가, footer hcI top 오프셋 적용, header 페이지번호 플레이스홀더 치환
page_test.rs render_page 시그니처 변경에 따른 테스트 호출 업데이트
paragraph.rs collect_auto_numbers() 함수 추가, LineSegmentContentauto_numbers 전달
ctrl_header/shape_object.rs, table/cells.rs LineSegmentContent 생성 시 auto_numbers: &[] 필드 추가

Test plan

  • cargo test — 418개 전체 테스트 통과 (0 failed)
  • headerfooter 스냅샷 테스트 통과
  • haN div 크기 fixture 일치 확인: width:1.82mm;height:3.17mm;
  • footer hcI top 오프셋 fixture 일치 확인: top:11.83mm;
  • 빈 줄(empty paragraph) 렌더링 확인
  • 다중 페이지 문서에서 헤더 페이지 번호가 페이지별로 정확히 증가하는지 확인
  • footer vertical_align: Top/Center인 경우 top 오프셋이 적용되지 않는지 확인

🤖 Generated with Claude Code

headerfooter fixture와 snapshot 간의 3가지 구조적 차이를 수정합니다.

1. Header 내 AUTO_NUMBER(페이지 번호) haN div 렌더링
   - 문단 텍스트에서 AUTO_NUMBER 제어문자 위치를 감지하여
     텍스트를 분리하고 인라인 haN div를 삽입
   - display_text=None(페이지 번호)인 경우 <!--PN--> 플레이스홀더를
     사용하여 render_page에서 실제 페이지 번호로 치환
   - CharShape base_size 기반 haN 크기 계산 (floor 기반 height, 반각 비율 width)

2. Footer hcI bottom-alignment top 오프셋
   - ListHeader의 vertical_align이 Bottom인 경우
     꼬리말 콘텐츠 높이를 ParaLineSeg에서 계산
   - hcI top = bottom_margin - content_height 공식으로 오프셋 적용
   - 중간값 반올림 없이 최종 결과만 round_to_2dp 적용하여 정밀도 보장

3. 머리말/꼬리말 호스트 문단의 빈 줄 렌더링
   - has_header_footer 문단도 본문 콘텐츠(빈 hls 등)를 렌더링하도록
     가드 조건 제거

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ohah ohah force-pushed the feat/textbox-paragraph-marker-rendering branch from 089e980 to 3415828 Compare March 4, 2026 04:36
@ohah ohah merged commit bb201dc into main Mar 4, 2026
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.

1 participant