PowerPoint2007 Reader : Read a slide number and a date with their styling - #916
Open
dkulyk wants to merge 3 commits into
Open
PowerPoint2007 Reader : Read a slide number and a date with their styling#916dkulyk wants to merge 3 commits into
dkulyk wants to merge 3 commits into
Conversation
dkulyk
force-pushed
the
fix/reader-field
branch
from
August 22, 2026 10:08
5889eca to
82032ea
Compare
The run is now made before `a:rPr` is looked at, which also moved `setText()` out from under that guard -- so a run without `a:t`, which the schema forbids but files carry anyway, reached `$oSubSubElement->nodeValue` on null. Look for the text rather than assume it. The tests write a deck, take `a:rPr` (or `a:t`) back out of the archive and read it again, so neither needs a binary fixture. Keynote is the export that hits this: one of its slides carries runs with text and no `a:rPr` at all, and every one of them was read as nothing. The seven `is_object()` checks in the rewritten block are now `instanceof DOMElement` -- what the other ninety-four checks in this file use, and what `getElement()` promises.
…n with `a:fld` is a run whose text the application recomputes -- the number of the slide it ended up on, the date the file is opened on. The Writer emits one for every `sldNum` or `dt` placeholder (`AbstractSlide.php:326`), but the Reader walked `(a:r|a:br)` only, so the element was skipped and everything inside it with it. The shape itself survived a round trip: the placeholder is restored from `p:ph` further up, and the Writer re-derives the field from that, so a deck kept its numbering. What it lost was how the number looked -- the paragraph came back with no runs at all, and `a:fld` was written out again with no `a:rPr`, so Georgia 18pt bold red became the default font. `CT_TextField` holds the same `a:rPr` and `a:t` as `CT_RegularTextRun` does, so the element is read by the branch that already reads a run. Both field types are covered at once, the kind being an attribute rather than a separate element. One deliberate consequence: a shape that is not a placeholder but holds a field -- "page 7 of 12" in a plain text box -- now reads the stand-in text as an ordinary run, where it used to be dropped. The text of the file is kept rather than lost, but the field is not expressible in the model yet, so re-saving that shape freezes it. Making a field a text element of its own, next to `Run` and `BreakElement`, is what would close that; it is a larger change and a separate one.
dkulyk
force-pushed
the
fix/reader-field
branch
from
August 23, 2026 12:04
82032ea to
4b64feb
Compare
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.
Description
Depends on #914 — it rewrites the body of the same loop. The first two commits are that PR (and @Wilkolicious's #871 under it); only the last one belongs to this review.
What is wrong
a:fldis a run whose text the application recomputes: the number of the slide it ended up on, the date the file is opened on. The Writer emits one for everysldNumordtplaceholder (AbstractSlide.php:326), but the Reader walked(a:r|a:br)only, so the element was skipped and everything inside it with it.The shape survives the round trip — the placeholder is restored from
p:phfurther up, and the Writer re-derives the field from it — so a deck keeps its numbering. What it loses is how that number looks. Measured on asldNumplaceholder styled Georgia 18pt bold red:sldNumsldNuma:fldon re-savea:rPrat alla:rPrdtbehaves identically.The change
CT_TextFieldholds the samea:rPranda:tasCT_RegularTextRun, so the element is read by the branch that already reads a run — the XPath and the condition, nothing else. Both field types are covered at once, the kind being an attribute rather than a separate element.One deliberate consequence
A shape that is not a placeholder but holds a field —
page <slidenum> of 12in a plain text box — now reads its stand-in text as an ordinary run, where it used to be dropped. The text of the file is kept rather than lost, but a field is not expressible in the model, so re-saving that shape freezes it into dead text.Both outcomes are wrong; I think keeping the text is the better of the two, and it is easy to reverse if you disagree. What actually closes it is a field element of its own next to
RunandBreakElement, which is a larger change and a separate PR. For reference, that is how LibreOffice models it —class TextField final : public TextRun, and both its OOXML and its ODF exporters decide per run rather than per shape.Checklist: