Repository navigation
fix(line-cache): leave paragraphs with an undefined label or a negative margin to Hancom - #662
Conversation
…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
left a comment
There was a problem hiding this comment.
검토 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")): |
There was a problem hiding this comment.
[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 회귀를 추가하면 이 우회를 막을 수 있습니다.
무엇을 고쳤나
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