Summary
On a PPTX authored by Microsoft Macintosh PowerPoint, changing one paragraph on slide 1 with officecli set re-serializes every slide XML part in the package.
The untouched slides remain visually valid in my test, but they are no longer byte-preserved. This creates noisy package diffs and increases the round-trip risk for unsupported or extension XML on slides that the command did not target.
Environment
- OfficeCLI:
1.0.142
- OS: Linux x86_64
- Source PPTX producer (
docProps/app.xml): Microsoft Macintosh PowerPoint
- Deck: 18 slides
Reproduction
cp input.pptx before.pptx
cp input.pptx after.pptx
officecli set after.pptx \
'/slide[1]/shape[@id=4]/paragraph[1]' \
--prop 'text=OfficeCLI round-trip probe' \
--json
mkdir before after
unzip -qq before.pptx -d before
unzip -qq after.pptx -d after
for f in before/ppt/slides/slide*.xml; do
name=$(basename "$f")
cmp -s "$f" "after/ppt/slides/$name" || echo "$name"
done
Observed output:
slide1.xml
slide2.xml
...
slide18.xml
Only slide 1 was targeted. For example, slide2.xml changed from 19,543 bytes to 19,944 bytes solely through serializer normalization (XML declaration/empty-element/whitespace formatting); its content was not intentionally edited.
The same command on a PPTX generated by OfficeCLI itself did not produce unrelated slide diffs, so this appears to be most visible when OfficeCLI first opens a package serialized by another producer.
Expected behavior
A targeted edit to slide 1 should persist the modified slide and any package-level parts that genuinely require an update, while leaving unrelated slide parts byte-for-byte unchanged.
If whole-deck normalization is intentional, an explicit opt-in mode would be safer than making it the default for a targeted edit.
Possible cause
PowerPointHandler calls InitShapeIdCounter() when an editable document is opened. That method walks GetSlideParts() and calls GetSlide(slidePart) for every slide, loading every slide root into the Open XML SDK DOM. A later package save may then serialize all loaded roots, including clean slides.
Relevant locations:
src/officecli/Handlers/PowerPointHandler.cs (editable constructor)
src/officecli/Handlers/Pptx/PowerPointHandler.Helpers.ShapeId.cs (InitShapeIdCounter)
A regression test could use a fixture with deliberately non-SDK lexical serialization, edit one paragraph on slide 1, then assert that the raw ZIP bytes for ppt/slides/slide2.xml and subsequent untouched slides remain identical.
If a shareable fixture is needed, I can build a synthetic PPTX that preserves the relevant producer/serialization characteristics. The original test deck contains private business material and will not be uploaded.
Summary
On a PPTX authored by Microsoft Macintosh PowerPoint, changing one paragraph on slide 1 with
officecli setre-serializes every slide XML part in the package.The untouched slides remain visually valid in my test, but they are no longer byte-preserved. This creates noisy package diffs and increases the round-trip risk for unsupported or extension XML on slides that the command did not target.
Environment
1.0.142docProps/app.xml):Microsoft Macintosh PowerPointReproduction
Observed output:
Only slide 1 was targeted. For example,
slide2.xmlchanged from 19,543 bytes to 19,944 bytes solely through serializer normalization (XML declaration/empty-element/whitespace formatting); its content was not intentionally edited.The same command on a PPTX generated by OfficeCLI itself did not produce unrelated slide diffs, so this appears to be most visible when OfficeCLI first opens a package serialized by another producer.
Expected behavior
A targeted edit to slide 1 should persist the modified slide and any package-level parts that genuinely require an update, while leaving unrelated slide parts byte-for-byte unchanged.
If whole-deck normalization is intentional, an explicit opt-in mode would be safer than making it the default for a targeted edit.
Possible cause
PowerPointHandlercallsInitShapeIdCounter()when an editable document is opened. That method walksGetSlideParts()and callsGetSlide(slidePart)for every slide, loading every slide root into the Open XML SDK DOM. A later package save may then serialize all loaded roots, including clean slides.Relevant locations:
src/officecli/Handlers/PowerPointHandler.cs(editable constructor)src/officecli/Handlers/Pptx/PowerPointHandler.Helpers.ShapeId.cs(InitShapeIdCounter)A regression test could use a fixture with deliberately non-SDK lexical serialization, edit one paragraph on slide 1, then assert that the raw ZIP bytes for
ppt/slides/slide2.xmland subsequent untouched slides remain identical.If a shareable fixture is needed, I can build a synthetic PPTX that preserves the relevant producer/serialization characteristics. The original test deck contains private business material and will not be uploaded.