feat(docx): honour w:wordWrap for Hangul line breaking - #790
Merged
Conversation
w:wordWrap is Word's switch between word-level and character-level Hangul breaking: w:val="1" keeps an eojeol whole, w:val="0" allows a break at any syllable. It was not parsed, so a paragraph explicitly asking for character-level breaking still got the word-level rule #626 applies to every non-justified paragraph. The value now reaches ParagraphStyle and paragraph_eojeol_wrap consults it before anything the paragraph inherits, because Word's own probes show the property overrides the style chain -- a ListParagraph with w:val="0" breaks mid-eojeol although the style alone would not. This needed a dependency field first: docx-rs had no word_wrap anywhere, added upstream in developer0hye/docx-rs#3 and merged into the pinned branch. Adding the field pushed TaggedElement::ListParagraph past clippy's large_enum_variant threshold (232 bytes against Plain's 24), so its Paragraph is boxed. Related: #730 Signed-off-by: developer0hye <developer.0hye@gmail.com>
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
w:wordWrapis Word's switch between word-level and character-level Hangul linebreaking:
w:val="1"keeps an eojeol whole,w:val="0"allows a break at anysyllable. It was not parsed, so a paragraph explicitly asking for
character-level breaking still got the word-level rule #626 applies to every
non-justified paragraph.
The dependency came first
docx-rshad noword_wrapanywhere indocx-core, which is what #730 wasblocked on. Added upstream in developer0hye/docx-rs#3 and merged into the
fix/parse-tolerancebranch this repo pins, so no change is needed here beyondreading the field.
That PR records both values rather than only the true case, unlike the
neighbouring flags —
w:val="0"is the setting that carries the instruction,and collapsing it to
Noneis indistinguishable from the property being absent.Measured
The same Korean sentence in a narrow column, three times, differing only in the
property:
w:val="1"…신뢰를 / 바탕으로……신뢰를 / 바탕으로…w:val="0"…신뢰를 / 바탕으로……신뢰를 바탕 / 으로……신뢰를 / 바탕으로……신뢰를 / 바탕으로…Only the paragraph that asks for character-level breaking changes, and it now
breaks inside
바탕으로instead of before it.The expected behaviour comes from the native Microsoft Word probes recorded in
the issue, not from a local reference render: LibreOffice does not implement
this property. All three paragraphs above break identically in a LibreOffice
24.2.7.2 render of the same file, so it cannot serve as ground truth here and
none is attached.
Change
ParagraphStylegainsword_wrap,merge_paragraph_styleresolves itexplicit-over-style, and
paragraph_eojeol_wrapconsults it before anything theparagraph inherits — Word's probes show a
ListParagraphwithw:val="0"breaks mid-eojeol although the style alone would not, so the property has to win
over the style chain.
ParagraphStyle::merge_fromgained a clause too; without it the property wouldhave been dropped silently on that path.
Adding the field pushed
TaggedElement::ListParagraphpast clippy'slarge_enum_variantthreshold — 232 bytes againstPlain's 24 — so itsParagraphis boxed.Tests
Five:
w:val="0"emits no eojeol frames, so Typst may break insidean eojeol
w:val="1"keeps its frames, so the fix is not "the propertyis present, back off"
docx-rswith0,1and absent all distinctit when the paragraph says nothing
Visual impact
No rendered PDF change
Rendered PDF change or visual evidence added
Reason: no document in the corpus carries
w:wordWrap— 0 of 59 DOCX undertests/fixtures/docxandtests/golden_mocks/*/sources/docxcontain theelement — so the change is inert on everything that exists today: of the 58
that convert, all 58 render byte-identically. It only takes effect on a
document that sets the property, and the sole reference renderer available
here ignores it, so there is no honest GT/Before/After triple to attach. The
probe's extracted lines are quoted in Measured above instead.
Related: #730