--- description: Edit Native PPTX route โ€” import a finished PowerPoint deck into a source-preserving SVG workspace, reference unchanged pages, edit or recompose selected pages, add notes/narration/motion, and export a new PPTX --- # Edit Native PPTX Route > Run when the user brings an existing `.pptx` whose design must survive โ€” a template to fill, a deck to partially rewrite or restructure, or a finished deck that only needs notes, narration, timings, or transitions. Never regenerates from scratch and never runs the Generate SVG pipeline. The source deck becomes a `pptx_to_svg.py --roundtrip` workspace: every slide is a compact editable SVG plus immutable native backing. Untouched pages are **referenced** and restored byte-for-byte; edited pages rebuild only what changed while unchanged objects restore natively; notes, narration, and motion are overlays that never rewrite visible content. | User wants | Route | |---|---| | Fill a raw PPTX template with new content, keep its design; add notes / narration / auto-advance / transitions; rewrite some pages and keep the rest; drop, reorder, or repeat pages without redesign | This route | | Regenerate every page with a new visual design (1:1) | Generate PPTX, [`beautify-pptx`](./profiles/beautify-pptx.md) | | Redesign the pages, or split / merge / re-outline into a newly designed deck | Generate PPTX, PPTX as source material | | Create a reusable brand / style / layout / deck asset | [`create-template`](./create-template.md) | **Hard rule โ€” no Generate pipeline**: never run `pptx_template_import.py`, `project_manager.py init`, or `finalize_svg.py`, and never create `svg_output/`; the round-trip workspace is the project and `svg_to_pptx.py --roundtrip` is the only exporter that restores source slides. --- ## 1. When to Run Raw PPTX called a template + new material or topic; existing deck + selective reuse ("only keep the pages that fit, in this order"), copy replacement, page-level rewrite ("redo page 5 and 7"), page combination ("merge the two market pages"), or a few new pages in the same style; finished deck + delivery add-ons with visible slides stable. Never ask a route-choice question for these shapes; ask one discriminator only when preserving (this route) and redesigning (Generate) are genuinely ambiguous. --- ## 2. Inputs ๐Ÿšง **GATE**: source PPTX (required โ€” the native design authority); new material only when content changes (text, Markdown, documents, or URLs converted with `source_to_md.py`; a bare topic without facts is not enough โ€” ask for material or gather it from user-approved URLs); optional delivery intent (audience, page count, must-keep / must-drop pages, notes, narration, transitions, auto-advance). **Hard rule โ€” facts**: every substantive claim in a page or note comes from the user material; the ยง4.3 content mapping names the source for each page and a page without one is dropped; template placeholder wording never becomes output content. --- ## 3. Import the Round-trip Workspace ```bash python3 skills/ppt-master/scripts/pptx_to_svg.py "" -o "projects/_" --inheritance-mode both --roundtrip ``` | Path | Content | Reading rule | |---|---|---| | `authoring-svg-flat/slide_NN.svg` | One compact editable SVG per source slide, in order | Open only pages you will edit or must judge for reuse | | `authoring-svg-flat/authoring_summary.json` | Roster plus per-page canvas, text, image, vector, placeholder, source-ref, and proxy counts | Read first; plan from it before opening any SVG | | `images/`, `icons/imported/`, `audio/`, `video/`, `sounds/` | Source media and imported vectors | Keep names; changed bytes rebuild every output page whose source graph references that part, and a format mismatch fails export | | `notes/slide_NN.md` | Source speaker notes, when the source has any | Edit, delete, or add per output page (ยง6) | | `native-payloads/`, `analysis/` | Immutable native backing and tool-owned contracts | Tool-written; do not read, edit, or quote them | | `sources/source.pptx` | Exact source package | Read only through `source_to_md/ppt_to_md.py "/sources/source.pptx" -o "/validation/source_readback.md"` when you need page text without opening every SVG | | `validation/`, `exports/` | Diagnostics and published decks | Tool-written | **Hard rule โ€” source proxies are atomic**: an `` stands for an unsupported native object (SmartArt, complex effects, media frames). Leave it to restore the original; a Slide-local proxy may be deleted (an externally linked picture proxy must stay), an inherited Master/Layout proxy stays; editing a proxy or its preview asset fails export. --- ## 4. Plan the Output Deck **Defaults (may override when the user fixes the mapping, asks to preserve order, or asks for new pages)**: treat the roster as a slide library, not an outline โ€” a source page's layout encodes a rhetorical shape (hero statement, lead-then-detail, comparison, progression, metric row, dense explanation), so match each message to a page whose structure expresses the same logic and drop content or the page rather than force a fit; the target story controls order, so source slides may move, drop, or repeat; the source deck is the skeleton โ€” most output pages keep a source structure, sub-content recombines freely, and new pages appear where the story needs them. ### 4.1 Page plan Write `page_plan.json` at the workspace root only when the output differs from the source roster (subset, reorder, repeat, or a copied page); without it export is the identity round trip. ```json { "schema": "ppt-master.roundtrip-page-plan.v1", "pages": [ {"source_slide": 1}, {"source_slide": 4, "svg": "chapter_market.svg"}, {"source_slide": 7}, {"source_slide": 7, "svg": "kpi_second_half.svg"} ] } ``` `pages` is the complete non-empty output order; `source_slide` is the one-based source index whose native slide backs the page; `svg` is the authoring filename inside `authoring-svg-flat/`, omitted to use that page's `slide_NN.svg` โ€” to reuse a source page twice, list a copy of its SVG renamed for its content (the stem also keys its notes and motion row), since every output page needs a distinct file and every extra file must appear in the plan. Only these fields are accepted. **Forbidden โ€” plans the exporter refuses**: a same-deck slide jump whose destination is omitted or repeated; unknown, duplicated, or cross-owned `svg` filenames; `source_slide` out of range. Omitting a slide drops the audio, video, or undecodable payloads only it owns (export prints a note). With a plan, presentation-level sections, custom shows, and a playback selection naming one are dropped and slide ids renumbered; every Master and Layout stays byte-for-byte, and a kept slide's theme override keeps its content under a new part name. **Combining pages**: one output page has exactly one skeleton (`source_slide`). To merge, pick the page whose layout carries the result, then bring objects from other pages only through the adopt command โ€” never pasted raw SVG, because source refs are page-local. The adopted object materializes its effective inherited presentation attributes and ancestor transforms, loses native identity, and makes the page `rebuilt`; a source proxy cannot leave its page, so a merge that needs one keeps that page as the skeleton. The object lands at the end of the target page for normal editing. ```bash python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/_/authoring-svg-flat" --adopt-object slide_05.svg: --into chapter_market.svg ``` **New pages** need a skeleton too: copy the closest source page under a new name, list it with that page's `source_slide`, delete its Slide-local content, and author on the empty canvas (inherited proxies stay); the page is `rebuilt`. ### 4.2 Enhancement modules | Module | Default | Carrier | |---|---|---| | Speaker notes | Source notes travel with every page; add or rewrite only where planned | `notes/.md` | | Narration audio | Off unless requested; implies notes on every output page | [`generate-audio`](./stages/generate-audio.md) โ†’ `audio/.*` | | Auto-advance from narration | On when narration is requested | `svg_to_pptx.py --use-narration-timings` | | Page transitions | Preserve source; replace only on request โ€” a transition the importer reports as `transition-not-reconstructed` still travels natively with its page until replaced, even though the sidecar default reads `none` | `svg_to_pptx.py -t ` or per-slide rows in `animations.json` | | Object animations | Preserve source; author only on explicit request | `animations.json`, [`animations.md`](../references/animations.md) | | Native chart / table data | Source data unless the plan edits it | Inline JSON authority; export needs `--native-charts-and-tables` (ยง7) | ### 4.3 Confirmation โ›” **BLOCKING**: present one plan and wait for explicit confirmation before editing any SVG, writing notes, generating audio, or exporting: the output roster (output page โ†’ source slide โ†’ referenced / edited / new copy, with a one-line reason per edited or dropped page), the content mapping (which material goes where, what is dropped for lack of a fitting layout), each enhancement module on/off with its effect and duration, and any ยง4.1 fail-closed case the plan must avoid. Chat confirmation suffices; write `page_plan.json` afterwards. --- ## 5. Edit Pages Load [`shared-standards-core.md`](../references/shared-standards-core.md) before the first edit; [`svg-effects.md`](../references/svg-effects.md) only when authoring new visual elements; [`native-data-interface.md`](../references/native-data-interface.md) only when changing native chart or table data. **Hard rule โ€” edit only planned pages**: a referenced page is never opened for writing; export proves it by listing it under `passthrough` / `cloned_passthrough` or `patched`, never `rebuilt`. **Hard rule โ€” edit in place, keep identity**: change text, paint, position, or content inside the existing tree and keep every `data-pptx-*` attribute on objects you did not intend to change. An object whose subtree and ancestor transform / opacity are unchanged restores natively; a changed object converts from your SVG but keeps its shape id, so source animations and Morph pairs that target it survive โ€” only removing it or replacing it with a new element orphans them (ยง6). Objects inherited from a Master or Layout (`layout:` / `master:` refs) cannot be edited or deleted. Never paste a page from `svg_output/` conventions or another deck over a round-trip page. | Edit | Rule | |---|---| | Text replacement | Fit the slot's visual capacity from its geometry and font size, not the old placeholder length; resolve overflow by rewriting shorter โ†’ splitting across another selected page โ†’ choosing a larger source layout; shrinking type is last and never deck-wide | | Cover / chapter pages | Replace title, subtitle, author, section label only | | Imported multi-line text | Arrives as `data-pptx-text-model="lines"` (continuation ``) or `"paragraphs"` (one nested `` per paragraph) with `data-paragraph-line-height`; the rows carry no `x` / `dy` and both the exporter and the checker read the model. Edit the text inside it, or replace the whole `` with canonical positioned lines and drop the import-side attributes | | Dense content pages | Compress to the slot count the page has; move overflow to another selected page | | Native tables / charts | Imported objects carry `data-pptx-native-authority="json"`: edit cell text or categories/series values in the inline JSON, keep structure and formatting from the source, and export with `--native-charts-and-tables` โ€” without it the source chart object ships unchanged with its original data. A table the importer marked `unsupported-table-*` is positioned text over a baked grid: editing it exports shapes, not `a:tbl` (the checker warns); leave it unchanged to keep the native table | | Images | Point the existing `` at a new file under `images/`; keep the frame | | New elements | Canonical compact SVG per shared standards; a new chart or text-grid table takes the [`native-data-interface.md`](../references/native-data-interface.md) marker and becomes a PowerPoint object under `--native-charts-and-tables`, editable shapes without it; icons via `icon_sync.py "" `; AI images via `image_gen.py --manifest` when wanted | | Objects from another page | `--adopt-object` only (ยง4.1); proxies cannot move | | Source proxies | Leave or delete; never edit (ยง3) | | Same-deck jumps | Export remaps an inherited `` (marked `data-pptx-source-href`) to the target's output page and fails on links to omitted pages, listing every slide; to retarget, delete that attribute and write the output `#slide-N` | **Mandatory after editing** โ€” refresh the summary, then run the capacity gate: ```bash python3 skills/ppt-master/scripts/svg_authoring_view.py "projects/_/authoring-svg-flat" --refresh-summary python3 skills/ppt-master/scripts/svg_quality_checker.py "projects/_" --roundtrip --json ``` ๐Ÿšง **GATE**: `--roundtrip` estimates edited text against its frame and canvas; errors set `quality_gate=failed` on the export receipt โ€” clear them by rewriting, splitting, or moving the text to a larger layout; warnings are fixed or accepted with a stated reason. With a plan, the checker and `animation_config.py list-groups` cover the planned pages only. Width calibration samples unchanged text on the same page, so a fully rewritten page reports `0%` calibration and uses the default estimator โ€” not an error; an edit reaching no further than the source text of its own slot always passes. The exporter remains the final gate and fails closed on a page it cannot restore or convert. --- ## 6. Notes, Narration, and Motion Skip when no ยง4.2 module beyond preserving source notes is enabled. **Notes** are keyed by output SVG stem: `notes/.md` for a canonical page replaces source notes (delete the file to remove them); for a copied page it applies to that output page only, and without a file the copy inherits the source notes. **Hard rule โ€” spoken prose only**: `svg_to_pptx.py` embeds each note with Markdown markers stripped and `notes_to_audio.py` skips heading lines but reads everything else verbatim, so a `[tag]`, duration line, or stage direction is spoken and shown. Write 2โ€“5 natural sentences per content page, one or two for cover / chapter / ending, transitions as prose, one language per deck, sourced from the page's SVG text or the ยง3 read-back plus user material โ€” a note never adds a claim the page or material does not carry. **Narration audio**: run [`generate-audio`](./stages/generate-audio.md) Steps 1โ€“4 with the workspace path after notes are complete; the source deck's own media in `audio/` is left alone; `notes_to_audio.py` resolves the roster from `page_plan.json` (copies inherit) and refuses an incomplete roster. Stop after audio; ยง7 integrates it. **Motion**: load [`animations.md`](../references/animations.md) when transitions or object animations are requested; `animations.json` rows are keyed by output stem, a copied page inherits its source row unless it has its own, a row that omits `transition` keeps the source transition; drop rows for pages the plan omits. A source page often wraps its whole content in one group: regroup its unchanged children into motion units only on a page whose motion needs it, and let the other pages enter as the source grouped them โ€” ยง5 identity outranks finer motion. **Hard rule โ€” rebuilt animation targets**: removing an object a source animation targets leaves that animation without a target and export stops with `Edited slide removed source animation target(s)` naming the PowerPoint shape id (its imported root group is `shape-`); give the page its own row โ€” `"": {"animation": {"effect": "none"}}` drops the source build, or author the page's motion โ€” then export again. --- ## 7. Export and Validate ```bash python3 skills/ppt-master/scripts/svg_to_pptx.py "projects/_" --roundtrip ``` Add `-t [--transition-duration ]` to replace transition effects deck-wide (source auto-advance stays); `--recorded-narration audio --use-narration-timings` for narration with auto-advance (round-trip export reads the workspace `animations.json` by default); `--animation-config animations.json` for per-slide motion; `-a ` (default `none`) for object animation policy; `--no-notes` to strip notes; `--native-charts-and-tables` when chart/table data was edited; `--primary-language ` to declare the deck language the imported SVG roots lack (otherwise per-run detection, harmless for a monolingual deck). Export writes into `exports/`, prints the exact output path (a `_narrated` or `_native_charts_tables` suffix may apply โ€” use the printed path afterwards), and one receipt: ```text Round-trip export summary: output_pages=N passthrough=P cloned_passthrough=C patched=M rebuilt=R ``` `passthrough` = identity page with original XML (referenced, no plan, no overlay); `cloned_passthrough` = planned referenced page on a cloned part; `patched` = source shape XML kept while order, notes, transitions, animation, or narration timing changed; `rebuilt` = visible authoring or a referenced materialized resource changed โ€” exactly the pages marked edited in ยง4.3 plus pages referencing a changed resource, and a delivery-only job must show `rebuilt=0`. **Revision round**: every count is measured against `sources/source.pptx`, so a second round on a delivered deck โ€” more edits or delivery only โ€” starts by importing that delivered PPTX as a new workspace; a delivery-only round targets `rebuilt=0`, and a new narration pass replaces embedded narration rather than stacking it. **Validation**: `pptx_delivery_check.py "" > ".../validation/.delivery.json"` (no structural errors; review advisories) and `source_to_md/ppt_to_md.py "" -o ".../validation/readback.md"` โ€” slide count equals the plan length (or source count), key titles and replaced text present, notes count matches, receipt buckets match the confirmed roster. ```markdown ## โœ… Edit Native PPTX Complete - [x] Round-trip workspace imported at `projects/_/`; plan confirmed; `page_plan.json` written when the roster differs - [x] Only planned pages edited; `authoring_summary.json` refreshed; `svg_quality_checker.py --roundtrip` reports no errors - [x] Notes / audio / motion prepared as confirmed; `--roundtrip` receipt matches the confirmed roster - [x] Delivery JSON and read-back written under `validation/`; final deck at the printed `exports/` path ``` --- ## 8. Current Boundary Supported: referencing unchanged pages byte-for-byte with select / reorder / repeat / omit; editing text, paint, images, native table cells, and chart data on selected pages (chart/table edits export only with `--native-charts-and-tables`); authoring new elements as canonical compact SVG, native-marked charts and tables included; preserving SmartArt, complex effects, and embedded media as atomic proxies; notes, narration, auto-advance, transitions, and object animations as overlays keyed by output page. Not supported: deleting inherited source notes on a copied page (give the copy its own file); editing a source proxy; changing slide size; adding Master/Layout structure (Create Template โ†’ Generate instead).