Skip to content

Slide master and layout editing, Header & Footer (round 3, G5) - #13

Merged
uvrt merged 2 commits into
mainfrom
r3-master-layout-editing
Oct 11, 2026
Merged

uvrt merged 2 commits into
mainfrom
r3-master-layout-editing

Conversation

@uvrt

@uvrt uvrt commented Oct 11, 2026

Copy link
Copy Markdown
Owner

Production feedback round 3, item G5: master and layout text (footer year and entity, legal text per language, prompt text) could not be found, replaced or edited. Full editing, as approved.

Library

  • deck.masters / deck.master() -> Master (id M0, name, part_path, layouts, slides, shapes); Layout gains id (L2), master, type, slides, placeholder("body"), rename, duplicate, delete.
  • Layout.shapes / Master.shapes return the same Shape a slide has (text, run/paragraph formatting, fill, move/resize, delete, replace_image), plus add_shape, add_textbox, add_picture (SVG too), add_connector, add_table. Addresses L<n>.<id> / M<n>.<id>: n is the sldLayoutId / sldMasterId less 2147483648. Measured: PowerPoint keeps these ids on save (it renumbers the parts), so they are as stable as a slide's sldId; the local part is the slide scheme (stamp, creationId, cNvPr id).
  • shape.set_prompt() / shape.prompt: first level written, hasCustomPrompt="1", levels kept -- measured: typing in a layout placeholder in Slide Master view sets it (whole text or first line).
  • deck.find_text(..., scope="slides"|"layouts"|"masters"|"all"), outline_blocks(scope=).
  • deck.set_footer(text, slide_number=, date="auto"|text|None, slides=, skip_title=) as Insert > Header & Footer writes it (measured, notes below); add_slide after Apply to All copies the layout's footers, as New Slide does (measured).
  • add_layout, duplicate_layout, rename_layout, delete_layout(reassign_to=) as Slide Master view does them; a layout in use is refused (PowerPoint disables Delete for it).
  • Safety: shape.inherited_by(); deleting a layout/master placeholder something inherits from is refused with the list. Slides' own placeholder overrides are untouched. deck.affected_slides().

Measured in PowerPoint for Mac 16 (nl UI)

  • Header & Footer, Apply to All: master and every layout's ftr get the text, dt a datetime1 field (or a run for fixed text); master <p:hf hdr="0"/> (off items ="0", e.g. all off sldNum="0" hdr="0" ftr="0" dt="0"), after sldLayoutIdLst; showSpecialPlsOnTitleSld="0" when not on the title slide; each slide gets dt, ftr, sldNum appended (ph type/sz/idx copied, empty spPr, sldNum with the layout's field id); turning off removes them from slides. Apply (one slide) leaves master and layouts alone.
  • Duplicate Layout: right after the original, 1_<name>, id max+1, master rel + content type. Insert Layout: preserve="1" userDrawn="1", no type, title + master's dt/ftr/sldNum. Rename: cSld@name only. Delete of an unused layout: part, rel, id entry.

Tools

  • ppt_set_text, ppt_format_text, ppt_set_shape, ppt_arrange take L2.5 / M0.7; ppt_add_shape/ppt_add_picture/ppt_add_connector/ppt_add_table take slide: L2 / M0. Every result has checks.affects ({"M0": ["s:256", ...]}) and its fit/collision/empty-placeholder checks run on those slides.
  • find_text / replace_text: decks' stories = body (slides, default), layouts, masters, all (Undo by scope: shared parts; decks' stories on find/replace (round 3, G5) ooxml-edit#23). A replace that finds nothing on slides warns when the text is on a layout/master.
  • describe: masters (id, name, non-placeholder text, footer), layouts with id, placeholder ids and custom prompts, non-placeholder text.
  • New deferred ppt_edit_master (group ppt_slides): set_prompt, set_footer, add_layout, duplicate_layout, rename_layout, delete_layout.
  • Undo: plain undo covers layout/master parts (snapshots); undo by slide includes the slide's layout and master in its scope and refuses such a change as entangled (undo_shared, ooxml-edit 0.16.0). Tested.

Budgets (offline proxy): core 3,398 -> 3,440 estimated (~5,029 -> ~5,091 counted, <= 5,500); every definition 11,309 -> 11,779 (guard 11,800). Strict set unchanged: replace_text, set_properties, ppt_add_table, ppt_add_slide, ppt_draft_slides, ppt_manage_slides; 29 free strings, 24 optional (only replace_text's stories enum/description grew). Online strict check not run.

Golden p17: Example Corp's template made ready for 2027 in Dutch (master legal line, Dutch legal notice on a renamed layout, Dutch prompt, Header & Footer with slide numbers, not on the title slide); 8 calls, 18/18.

Office verification: p17 output and a wider verify deck (duplicated/added/deleted/reassigned layouts, SVG logo on the master) open unprompted, export to PDF with the edits on every page, survive a PowerPoint save with ids, prompts, p:hf and showSpecialPlsOnTitleSld kept; Normal view shows "Typ hier uw bevinding" in an empty placeholder; Slide Master view shows the Dutch notice, footer and legal line.

Docs: SUPPORTED.md (master/layout editing supported), GUIDANCE.md (when to edit masters vs slides, affects), USAGE.md, tools README, CHANGELOG.

CI installs ooxml-edit from r3-master-layout-scope (# TEMPORARY (r3)); merge uvrt/ooxml-edit#23 first, then switch the pin back to @main.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WCxhY1fvWQPiWCwz7SYUVh

uvrt and others added 2 commits October 11, 2026 11:40
Layout.shapes and Master.shapes are the editable Shape a slide has, addressed
L<n>.<id> / M<n>.<id> (sldLayoutId / sldMasterId less 2147483648, which
PowerPoint keeps on save). deck.masters; set_prompt (hasCustomPrompt);
find_text(scope=); set_footer as Insert > Header & Footer writes it, and new
slides get the footers after Apply to All; add, duplicate, rename and delete
layouts as Slide Master view does (a layout in use is refused); deleting a
placeholder something inherits from is refused. All measured in PowerPoint 16.

Tools: L/M addresses in the text and shape tools, the add tools on L2 / M0,
checks.affects with checks on the affected slides, decks' stories on
find_text/replace_text, describe lists masters, layout ids, prompts and their
text, and the deferred ppt_edit_master. Undo by slide refuses a layout or
master change (ooxml-edit 0.16.0's undo_shared). Golden p17.

CI installs ooxml-edit from r3-master-layout-scope until uvrt/ooxml-edit#23
is merged (TEMPORARY (r3)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WCxhY1fvWQPiWCwz7SYUVh
@uvrt
uvrt merged commit bf1f391 into main Oct 11, 2026
19 checks passed
@uvrt
uvrt deleted the r3-master-layout-editing branch October 11, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant