feat: parse w:wordWrap on paragraph properties - #3
Merged
Conversation
w:wordWrap is Word's switch between word-level and character-level line breaking for East Asian text: w:val="1" keeps a Hangul eojeol whole, w:val="0" allows a break at any syllable. The reader dropped it, so a consumer could not tell a paragraph asking for character-level breaking from one that says nothing (office2pdf#730). Unlike the neighbouring flags, which record only the true case, this one records both: w:val="0" is the meaningful setting, and collapsing it to None is indistinguishable from the property being absent. read_bool already yields true for a bare <w:wordWrap/>, which is what OOXML means by it. Signed-off-by: Yonghye Kwon <developer.0hye@gmail.com> Signed-off-by: developer0hye <developer.0hye@gmail.com>
Owner
Author
|
CI status, for the record before merging.
Neither red job is caused by this PR, and neither is in scope for it. Merging on that basis. |
pull Bot
pushed a commit
to RadaKichenin/office2pdf
that referenced
this pull request
Aug 5, 2026
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 developer0hye#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: developer0hye#730 Signed-off-by: developer0hye <developer.0hye@gmail.com>
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.
What
Parse
w:pPr/w:wordWrapintoParagraphProperty::word_wrap.Why
w:wordWrapis Word's switch between word-level and character-level line breaking for East Asian text:w:val="1"keeps a Hangul eojeol whole,w:val="0"allows a break at any syllable. The reader dropped the element, so a consumer had no way to distinguish a paragraph that explicitly asks for character-level breaking from one that says nothing and leaves the choice to the style chain.Needed by developer0hye/office2pdf#730, where the value is measured to be the exact discriminator — including overriding the style chain, so it cannot be inferred from
pStyle.Note on the false case
The flags around it (
keepNext,keepLines,pageBreakBefore,widowControl) record only the true case:That is fine where
0and absent mean the same thing. Here they do not —0is the setting that carries the instruction — so this arm records both:read_boolalready returnstruefor a bare<w:wordWrap/>, which matches what OOXML means by the element with now:val.Tests
Two, in the existing
reader::paragraph_propertytest module and following the style of the shading test there:w:val="0"survives asSome(false)<w:wordWrap/>andw:val="1"both giveSome(true), and an absent element givesNone, so the three states stay distinctcargo test -p docx-rs --libpasses 275. The 20 failures intests/reader.rsare present onfix/parse-tolerancebefore this change as well — identical count with and without it — so they are untouched by this PR.Scope follows the shading PR (#2): reader and struct only, no writer.