Skip to content

feat(docx-core): emit rPrChange for formatted paragraph replacements#215

Open
stevenobiajulu wants to merge 2 commits into
mainfrom
173-rprchange-paragraph-replacements
Open

feat(docx-core): emit rPrChange for formatted paragraph replacements#215
stevenobiajulu wants to merge 2 commits into
mainfrom
173-rprchange-paragraph-replacements

Conversation

@stevenobiajulu
Copy link
Copy Markdown
Member

Summary

Closes #173.

replaceParagraphTextRange now emits w:rPrChange when an explicit replacement formatting request changes the replacement run's effective w:rPr relative to the source/template run. Pure text replacements and explicit formatting requests that leave run properties unchanged preserve the existing insertion/deletion behavior without adding a property-change record.

Implementation

  • Reuses buildRPrChangeElement for the OOXML property-change wrapper.
  • Snapshots the prior source/template run properties inside w:rPrChange.
  • Filters stale nested w:rPrChange records when cloning/snapshotting run properties.
  • Keeps w:rPrChange emission gated on explicit addRunProps / clearHighlight deltas.
  • Re-enables the canonical emission regression expectation for w:rPrChange.
  • Updates SUPPORT.md so the text primitive no longer lists w:rPrChange as pending.

Verification

  • npm -w @usejunior/docx-core run test:run -- src/primitives/text.test.ts src/integration/canonical-emission-regression.test.ts — 60 passed
  • npm -w @usejunior/docx-core run build
  • npm -w @usejunior/docx-core run lint
  • npm run lint:allure-imports — passed with one pre-existing warning in packages/docx-mcp/src/cli/commands/edit.test.ts:133
  • npm run lint:workspaces — fails in unrelated @usejunior/safedocx-mcpb: src/index.ts imports missing runServer from @usejunior/safe-docx and has an implicit any parameter

@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
site Ready Ready Preview, Comment May 22, 2026 6:48am

Request Review

@github-actions github-actions Bot added the feat label May 22, 2026
…ange

Peer review of #215 surfaced two reproducible false positives in
`rPrComparableSignature` that caused `replaceParagraphTextRange` to emit
`w:rPrChange` for no-op formatting requests:

1. **Whitespace-sensitive comparison.** The signature concatenated text
   node `textContent`, so a pretty-printed source `<w:rPr>` with
   inter-element whitespace did not match the whitespace-free `<w:rPr>`
   produced by `cloneRPrWithoutChangeRecords` (which drops non-element
   children). Re-asserting an existing toggle therefore emitted a bogus
   `w:rPrChange`. The OOXML schema only permits element children inside
   `w:rPr`, so any text node there is insignificant pretty-printing —
   the signature now skips text nodes entirely.

2. **ST_OnOff variants compared as strings.** OOXML treats the absence of
   `w:val` on a toggle property as equivalent to `w:val="1"`, and the
   values `1`/`true`/`on` (and their falsy triple) are interchangeable.
   But `ensureBoolProp` always writes the explicit `w:val="1"` form, so
   re-asserting bold against a `<w:b/>` source produced a signature
   mismatch and a bogus `w:rPrChange`. The signature now canonicalizes
   toggle elements: it synthesizes a `w:val="1"` for absent attributes
   and normalizes `1|true|on`/`0|false|off` for the toggle set defined by
   ECMA-376 (`b`, `bCs`, `i`, `iCs`, `caps`, `smallCaps`, `strike`,
   `dstrike`, `outline`, `shadow`, `emboss`, `imprint`, `vanish`,
   `specVanish`, `webHidden`, `noProof`, `snapToGrid`, `rtl`, `cs`).

New regression tests in `text.test.ts` lock both fixes plus two
previously-uncovered shapes: `clearHighlight: true` must trigger
`w:rPrChange` when the source carried a highlight, and a heterogeneous
multi-run deletion pins the documented snapshot contract (the chosen
template run's `rPr` becomes the prior state; per-run formatting of the
removed span is preserved inside `<w:del>`).

Ref: #173

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@stevenobiajulu stevenobiajulu marked this pull request as ready for review May 22, 2026 06:48
@stevenobiajulu stevenobiajulu enabled auto-merge (squash) May 22, 2026 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replaceParagraphTextRange should emit w:rPrChange when run formatting changes

1 participant