fix: add notesMasterIdLst element when creating notes master - #1128
robbybrodie wants to merge 1 commit into
Conversation
When python-pptx creates a notes master on first access to slide.notes_slide, it correctly creates the NotesMasterPart and adds the relationship in the .rels file, but omits the corresponding <p:notesMasterIdLst> reference from presentation.xml. Without this element, OOXML consumers cannot discover the notes master from the presentation element, even though the relationship and part exist. This causes Apple Keynote (and potentially other consumers) to fail to recognize the notes master, breaking speaker notes import. This fix: - Adds CT_NotesMasterIdList and CT_NotesMasterIdListEntry element classes with proper ZeroOrOne/RequiredAttribute declarations - Registers both element classes in the oxml element class lookup - Adds a ZeroOrOne declaration for notesMasterIdLst on CT_Presentation with correct successor sequence - Updates PresentationPart.notes_master_part to populate the notesMasterIdLst element with the relationship ID after creating the notes master relationship Closes scanny#1051
2e83480 to
c14854d
Compare
Creating a notes master (prs.notes_master on a deck without one, e.g. the default template) related the new notesMaster part but never recorded it in presentation.xml: no p:notesMasterIdLst element, no p:notesMasterId r:id entry. presentation.xml therefore referenced no notes master by id, which can make PowerPoint flag the saved file for repair. Add CT_NotesMasterIdList / CT_NotesMasterIdListEntry oxml classes and a ZeroOrOne notesMasterIdLst on CT_Presentation (inserted per the ECMA-376 CT_Presentation sequence: after sldMasterIdLst, before handoutMasterIdLst / sldIdLst / sldSz / notesSz), and have PresentationPart.notes_master_part write the id entry when it creates and relates the part. Because p:notesMasterId is maxOccurs=1, add_notesMasterId() creates the child when absent and updates it in place otherwise, making registration idempotent. The existing-master path reuses the known rId from relate_to() and registers too, so decks saved by older versions (relationship present, id list absent) are reconciled on access instead of staying repair-flagged. Port of scanny#1128 by robbybrodie.
|
We independently hit this exact issue in production: any deck with speaker notes generated via python-pptx fails to open in Keynote / macOS QuickLook ("can't be imported"), while PowerPoint and python-pptx itself tolerate the file silently. We traced the root cause ourselves before finding this PR — This PR has been open and mergeable for several months with full test coverage — would appreciate a maintainer look. In the meantime we've applied an equivalent workaround downstream (patching |
Summary
When python-pptx creates a notes master on first access to
slide.notes_slide, it correctly creates theNotesMasterPartand adds the relationship in the.relsfile, but omits the corresponding<p:notesMasterIdLst>reference frompresentation.xml. Without this element, OOXML consumers cannot discover the notes master from the presentation element, even though the relationship and part exist in the package.This causes Apple Keynote (and potentially other OOXML consumers) to fail to recognize the notes master, breaking speaker notes when opening python-pptx-generated files.
What this PR does
CT_NotesMasterIdListandCT_NotesMasterIdListEntryelement classes with properZeroOrOne/RequiredAttributedeclarationsZeroOrOnedeclaration fornotesMasterIdLstonCT_Presentationwith the correct successor sequence per the OOXML specPresentationPart.notes_master_partto populate thenotesMasterIdLstelement with the relationship ID after creating the notes master relationshipBefore (missing element)
After (element present)
Test results
Unit tests (pytest): 2700 passed, 0 failed
Acceptance tests (behave): 54 features, 973 scenarios, 2914 steps — all passed
The existing acceptance test in
prs-presentation-props.feature(Presentation.notes_masterwithno notes master) already exercises the code path this fix modifies — creating a notes master when none exists. No new acceptance test was needed.Manual verification:
notesMasterIdLstelement inpresentation.xmlCloses #1051