Skip to content

fix(line-cache): leave paragraphs with an undefined label or a negative margin to Hancom - #662

Merged
airmang merged 2 commits into
mainfrom
fix/line-cache-undefined-bullet
Nov 5, 2026
Merged

airmang merged 2 commits into
mainfrom
fix/line-cache-undefined-bullet

Conversation

@airmang

@airmang airmang commented Nov 4, 2026 •

Copy link
Copy Markdown
Owner

무엇을 고쳤나

write_line_caches가 다음 두 가지 문단에는 줄 캐시를 쓰지 않습니다. 둘 다 엔진이 나눈 줄과 한/글이 나누는 줄이 달랐던 경우입니다. 한/글은 캐시에 적힌 줄 나눔을 그대로 믿기 때문에, 이런 문단에 캐시를 쓰면 한/글이 줄을 눌러 담을 수 있었습니다.

  • 정의되지 않은 글머리표나 번호를 가리키는 문단 모양. 예를 들어 글머리표 idRef="0"인데 문서 머리 부분에 그 hh:bullet 정의가 없는 경우입니다. 한/글은 정의가 없어도 글머리 자리를 잡아서 첫 줄에 1~2자를 덜 넣습니다. 엔진은 글머리가 없는 것으로 보고 줄을 나눴습니다.
  • 왼쪽이나 오른쪽 여백이 음수인 문단. 줄이 단이나 칸의 가장자리 밖으로 나가는 문단입니다. 이런 줄을 한/글이 어떤 폭으로 나누는지는 확정하지 못했습니다. 실제로 엔진과 한 글자 이상 다르게 나눈 문단이 있었습니다.

시험

  • test_a_paragraph_headed_by_a_label_the_header_does_not_define_is_left_for_hancom: 글머리표와 번호 두 경우를 봅니다.
  • test_a_paragraph_with_a_negative_margin_is_left_for_hancom: 왼쪽 여백과 오른쪽 여백 두 경우를 봅니다.
  • 네 경우 모두 고치기 전에는 실패합니다.

🤖 Generated with Claude Code

airmang and others added 2 commits November 5, 2026 00:49
…mber to Hancom

A paragraph shape whose heading names a bullet or a number the header
does not define (a bullet idRef of 0, say) still gets a label from
Hancom, which then fits fewer characters on the first line. The line
cache broke such a paragraph as if it had no label, and Hancom, trusting
those breaks, could press the line together. Such paragraphs now get no
cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A paragraph whose left or right margin is negative runs its lines past
the column's or the cell's edge, at a width Hancom was not seen to share
with FormFit (one 500 out on the right, one 339 out on the left in a cell,
broke a character or more otherwise). Such paragraphs now get no cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@airmang airmang changed the title fix(line-cache): leave paragraphs headed by an undefined bullet or number to Hancom fix(line-cache): leave paragraphs with an undefined label or a negative margin to Hancom Nov 4, 2026

@airmang airmang left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

검토 head bd0618f / base 3a9f37a. 소스 diff와 write_line_caches의 본문/그림/표/셀 경로를 확인했고 로컬 tests/test_layout_line_cache.py 150개가 통과했습니다. 같은 head에서 완료된 Python 3.12 CI는 7,647 passed/18 skipped/1 xfailed 및 Ruff/mypy/Pyright 통과이며, 일부 매트릭스 job은 아직 실행 중입니다. 독립 공개 API 검증에서 표만 담은 문단의 _table_line fallback이 새 차단 조건을 우회하는 P2를 확인했습니다. 검증되지 않은 문단에는 캐시를 쓰지 않는다는 변경의 보장이 이 경로에도 적용되도록 수정하고 회귀 검증해 주세요. 자기 PR이므로 COMMENT로 기록하고 병합을 보류합니다.

vertical = _vertical_align(measure, paragraph.get("paraPrIDRef"))
if shape.font_line or vertical not in _BASELINES or not _shapes_sure(measure, paragraph, runs):
return None
if _unknown_label(measure, paragraph.get("paraPrIDRef")):

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 표 문단의 fallback에도 동일한 차단 조건을 적용해 주세요. write_line_caches는 _lines(...) or _table_line(...) or _picture_lines(...)로 작성 경로를 고르므로, 여기서 None을 반환해도 _table_line은 _unknown_label/음수 여백 검사를 하지 않아 캐시를 만듭니다. 공개 API 재현: 새 문서에 1×1 표(칸 텍스트 '가나다')를 만들고, 표의 holder p에만 기존 hh:paraPr을 복사한 별도 id=999를 참조시킵니다(칸 문단의 모양은 그대로). 그 모양을 hh:heading type=BULLET/NUMBER,idRef=999(정의 없음) 또는 왼쪽/오른쪽 margin=-500으로 바꾸고 write_line_caches를 호출하면 네 경우 모두 written=2, skipped=0이고 holder에도 linesegarray가 생깁니다. 왼쪽 음수 사례에는 horzpos=-500,horzsize=43020이 기록됩니다. 같은 모양의 텍스트 문단은 올바르게 건너뜁니다. PR이 한/글과의 폭을 확정하지 못해 차단하는 조건이므로 표 holder도 캐시 작성 대상에서 제외하거나 이 경로를 별도로 검증해 주세요. _table_line 공통 사전검사와 holder별 공개 API 회귀를 추가하면 이 우회를 막을 수 있습니다.

@airmang
airmang merged commit d1c7d0a into main Nov 5, 2026
13 checks passed
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