fix(pptx): notitiemaster in presentation.xml, anders laat PowerPoint de notities weg

python-pptx schrijft het onderdeel wel maar noemt het niet in presentation.xml; nu wordt
notesMasterIdLst toegevoegd op de schemaplek, direct na sldMasterIdLst.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido van Dijk
2026-09-22 21:27:26 +02:00
parent 25c6edad88
commit 3e98ca373f
3 changed files with 31 additions and 1 deletions
Binary file not shown.
Binary file not shown.
+31 -1
View File
@@ -18,6 +18,7 @@ Vereist: pdftoppm (Poppler) en python-pptx.
"""
import json
import re
import zipfile
import subprocess
import sys
import tempfile
@@ -112,7 +113,36 @@ for n, sid in enumerate(deck["order"]):
uit = pdf.with_suffix(".pptx")
prs.save(str(uit))
def repareer_notitiemaster(pad: Path) -> bool:
"""python-pptx schrijft de notitiemaster wel als onderdeel, maar noemt hem niet in
presentation.xml. PowerPoint laat de notities dan weg. Deze reparatie zet de ontbrekende
regel erin, op de plek die het schema voorschrijft: direct na de dia-master."""
with zipfile.ZipFile(pad) as bron:
pres = bron.read("ppt/presentation.xml").decode("utf-8")
if "notesMasterIdLst" in pres:
return False
rels = bron.read("ppt/_rels/presentation.xml.rels").decode("utf-8")
m = re.search(r'Id="([^"]+)"[^>]*notesMaster[^>]*/>', rels)
if not m:
return False
pres = pres.replace(
"</p:sldMasterIdLst>",
f'</p:sldMasterIdLst><p:notesMasterIdLst><p:notesMasterId r:id="{m.group(1)}"/>'
f"</p:notesMasterIdLst>", 1)
onderdelen = [(i, bron.read(i.filename)) for i in bron.infolist()]
tijdelijk = pad.with_suffix(".tmp")
with zipfile.ZipFile(tijdelijk, "w", zipfile.ZIP_DEFLATED) as nieuw_zip:
for info, data in onderdelen:
nieuw_zip.writestr(info, pres.encode("utf-8") if info.filename == "ppt/presentation.xml" else data)
tijdelijk.replace(pad)
return True
gerepareerd = repareer_notitiemaster(uit)
# 4. de dia-bestanden terugzetten op de publieke versie
subprocess.run([sys.executable, str(MAP / "maak_dias.py")], check=True, capture_output=True)
soort = "uitgebreide begeleidersnotities (privé, niet delen)" if PRIVE else "de notities uit de dia's"
print(f"{uit.name}: {uit.stat().st_size // 1024} kB, {len(deck['order'])} dia's, met {soort}")
print(f"{uit.name}: {uit.stat().st_size // 1024} kB, {len(deck['order'])} dia's, met {soort}"
+ (", notitiemaster toegevoegd" if gerepareerd else ""))