diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d9a4ce9..828229cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -125,6 +125,8 @@ - FormFit과 쪽 수 추정이 낱말 바로 뒤의 빈칸 두 개를 줄 끝 너머에 매단다. 첫 빈칸이 줄 끝을 넘고 둘째 빈칸이 줄 끝 너머에서 시작해도 둘째까지 그 줄에 남고, 셋째부터 다음 줄로 간다. 한/글이 그렇게 놓는다. 전에는 둘째 빈칸부터 다음 줄로 보내 빈칸이 여러 개 이어진 자리에서 줄이 한 글자 일찍 나뉘었다. +- FormFit과 쪽 수 추정이 탭 바로 뒤의 닫는 문장 부호(`)`·`.`·`!`·`」` 등)로 줄을 시작할 수 있게 한다. 빈칸 뒤처럼 탭은 앞 줄에 + 남고 부호가 다음 줄을 시작한다. 한/글이 그렇게 놓는다. 전에는 탭까지 다음 줄로 보냈다. - FormFit과 쪽 수 추정이 글꼴 폭 표에 없는 가나(히라가나·가타카나)를 그 글꼴의 한글 음절 폭으로 잡는다(함초롬바탕 972, 한컴 고딕 932). 한/글이 그렇게 놓는다. 전에는 전각(1 em)으로 셌다. - 쪽 수 추정(실험, `estimate_pages`)이 탭 정의를 한 번만 읽는다. 전에는 글자 모양을 볼 때마다 머리 정보의 탭 정의 전체를 diff --git a/src/hwpx/form_fit/measure.py b/src/hwpx/form_fit/measure.py index 5a60a170..16ebdf4d 100644 --- a/src/hwpx/form_fit/measure.py +++ b/src/hwpx/form_fit/measure.py @@ -135,7 +135,7 @@ #: The variation selectors and the zero-width joiner: no advance. _ZERO_WIDTH = frozenset("\ufe0e\ufe0f\u200d") #: Closing punctuation that never starts a line right after a character: it -#: moves down with that character. After a space it may start a line. +#: moves down with that character. After a space or a tab it may start a line. _NO_LINE_START = frozenset("!%),.:;?]}¢°’”‰′″℃〉》」』】〕…·、。") #: Opening punctuation that never ends a line. _NO_LINE_END = frozenset("([{‘“〈《「『【〔") @@ -1698,7 +1698,8 @@ def hancom_line_starts( options = [ index for index in breaks if start < index <= end - and (text[index] not in _NO_LINE_START or text[index - 1] in _HANGING_SPACES) + and (text[index] not in _NO_LINE_START or text[index - 1] in _HANGING_SPACES + or text[index - 1] == " ") and text[index - 1] not in _NO_LINE_END ] start = max(options) if options else end diff --git a/tests/fixtures/hancom_saved/line_cache_tab_punctuation.hwpx b/tests/fixtures/hancom_saved/line_cache_tab_punctuation.hwpx new file mode 100644 index 00000000..050fad5d Binary files /dev/null and b/tests/fixtures/hancom_saved/line_cache_tab_punctuation.hwpx differ diff --git a/tests/test_form_fit_hancom_rules.py b/tests/test_form_fit_hancom_rules.py index 5183fa79..38dd8746 100644 --- a/tests/test_form_fit_hancom_rules.py +++ b/tests/test_form_fit_hancom_rules.py @@ -547,6 +547,15 @@ def test_closing_punctuation_does_not_start_a_line() -> None: assert hancom_line_starts("가나다라마.", [5000], 10, CHARS) == [0, 4] +def test_closing_punctuation_may_start_a_line_after_a_tab() -> None: + # As after a space: the tab stays on its line and the mark starts the next, where after a character the + # mark moves down with it. + keep = replace(TextStyle(), break_non_latin_word="KEEP_WORD") + assert hancom_line_starts("가나다라 )라마바사", [8200], 10, keep) == [0, 5] + assert hancom_line_starts("가나다라 )라마바사", [4200], 10, keep) == [0, 5, 9] + assert hancom_line_starts("가나다라)라마바사", [4200], 10, keep) == [0, 3, 7] + + def test_latin_words_do_not_break_after_inner_punctuation() -> None: assert hancom_line_starts("aa-bbbb cc", [3000], 10, TextStyle()) == [0, 5] diff --git a/tests/test_layout_line_cache.py b/tests/test_layout_line_cache.py index 1186cb1c..f2060c37 100644 --- a/tests/test_layout_line_cache.py +++ b/tests/test_layout_line_cache.py @@ -18,7 +18,7 @@ HANCOM_LAID_OUT = ["line_cache_tabs.hwpx", "line_cache_line_breaks.hwpx", "line_cache_hanging_indents.hwpx", "line_cache_indents.hwpx", "line_cache_labels.hwpx", "line_cache_mixed_sizes.hwpx", "line_cache_taller_past_a_break.hwpx", "line_cache_table_cells.hwpx", - "line_cache_mixed_faces_tabs.hwpx", "line_cache_space_runs.hwpx"] + "line_cache_mixed_faces_tabs.hwpx", "line_cache_space_runs.hwpx", "line_cache_tab_punctuation.hwpx"] def _body(document: HwpxDocument) -> list: