Repository navigation
fix(docx-io): keep every nested inline formatting tag on DOCX export - #5150
Open
vincent69001 wants to merge 1 commit into
Open
vincent69001 wants to merge 1 commit into
vincent69001 wants to merge 1 commit into
Conversation
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
🦋 Changeset detectedLatest commit: 2c9dfda The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
vincent69001
added a commit
to vincent69001/plate
that referenced
this pull request
Oct 8, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
vincent69001
force-pushed
the
fix/docx-io-nested-marks
branch
from
October 8, 2026 07:57
ca827c7 to
2c9dfda
Compare
vincent69001
marked this pull request as ready for review
October 8, 2026 08:10
This branch has not been deployed
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.
🐛 Fixes ➖ N/A
🧭 Task plan: docs/plans/2026-10-07-fix-docx-io-nested-inline-formatting.md
🟢 95% confidence in the verified package behavior
main, 5 of the newhtmlToDocxBlobrows and the new round-trip case fail:<em><b>bold italic</b></em>exports<w:b/>onlypnpm check✅ Outcome
htmlToDocxBlob, and thereforeexportToDocxandDocxExportPlugin, apply every enclosing inline formatting tag to a text run. A leaf that carries several marks keeps all of them in the DOCX, and a mark no longer leaks onto the sibling text that follows a nested tag.Plate's static renderer emits one tag per mark plugin, nested, for a multi-mark leaf. With
BoldPluginandItalicPlugin,{ text: 'bold italic', bold: true, italic: true }becomes:<w:rPr>onmain<w:rPr>with this PR<p><em><b>bold italic</b></em></p><w:b/><w:b/><w:i/><p><b><em>bold italic</em></b></p><w:i/><w:b/><w:i/><p><u><em><b>all three</b></em></u></p><w:b/><w:b/><w:i/><w:u/><p><span><u><em><b>x</b></em></u></span></p><w:b/><w:b/><w:i/><w:u/><p><b><em>p <s>q</s></em><u>r</u></b></p>r:<w:b/><w:i/><w:u/>r:<w:b/><w:u/><p><mark>a <code>x</code> c</mark></p>x: two<w:highlight>x:<w:highlight w:val="lightGray"/><p><b>a <em>b</em></b></p>a:<w:b/>;b:<w:b/><w:i/><p><b><em>x</em> tail</b></p>x:<w:b/><w:i/>;tail:<w:b/><p><em>a <b>x</b> c</em></p>a:<w:i/>;x:<w:i/><w:b/>;c:<w:i/><p><em>a</em><b>b</b></p>a:<w:i/>;b:<w:b/><p><em><span><b>bold italic</b></span></em></p><w:i/><w:b/>Cause: in
buildRun(packages/docx-io/src/lib/internal/helpers/xml-builder.ts), the formatting-tag loop flattened the subtree into one queue and resettempAttributes = {}at every formatting tag. The flag was only folded into the durableattributeswhen the tag had more than one child, so a single-child chain kept the innermost flag only, and a multi-child chain leaked its flags to the siblings that followed (rabove).Child order inside
<w:rPr>still follows attribute insertion order, as before. Inside a formatting tag,<br>is still dropped and<a>still loses its hyperlink; both are pre-existing and out of scope. When highlight tags (mark,code,kbd) or vertical-alignment tags (sub,sup) nest, the innermost one wins, which keeps one<w:highlight>/<w:vertAlign>per run. Hosted CI fails onpnpm test:slowestforpackages/markdown/src/lib/table.spec.tsandapps/www/src/registry/ui/media-file-node.spec.tsx, neither touched here; the same gate failed on #5145 and #5148 before they merged.🏗️ Design
Each queued node now carries the run attributes inherited from its formatting ancestors, the way the
spanbranch already passes{ ...attributes, ...tempAttributes }down. Thechildren.length > 1heuristic and the reset go away. The loop is kept rather than recursing throughbuildRunOrRuns, becausebuildRundoes not descend into tags such as<a>or<abbr>and the loop keeps their text today.buildFormattingand therunPropertiesFragmentimport stay, because they still feed the run emitted for an empty tag. The change is confined to this branch ofbuildRun; no public API or export changes.🧪 Verified
mainwith the new tests: 5 of the first 10 matrix rows and the app round-trip case fail.bun test ./packages/docx-io/src/lib/internal/html-to-docx.slow.ts: 49 pass.bun test ./apps/www/src/__tests__/package-integration/docx-io.roundtrip.slow.tsx: a bold italic leaf round trips throughserializeHtml→htmlToDocxBlob→ mammoth import (fails onmainwithitalicmissing).pnpm turbo build --filter=./packages/docx-io,pnpm turbo typecheck --filter=./packages/docx-io,pnpm turbo brl --filter=./packages/docx-io(no barrel drift),pnpm lint:fix,pnpm check: pass.pnpm checkwas rerun after rebasing onmainat 53.3.11.AI-assisted (Claude Code), fully tested. Codex is not installed on the contributor's machine, so
codex review --base origin/mainwas not run; the repoautoreviewhelper could not authenticate its nested Claude CLI, so an independent Claude review pass was run on the diff instead and its findings (nested highlight duplication, matrix coverage, changeset wording) are addressed.