--- name: export-as-pptx-editable description: "Native text & shapes — editable in PowerPoint" user-invocable: true --- # Export as PPTX (editable) Export an HTML slide deck to a `.pptx` with native PowerPoint objects (editable text, shapes, images). One `gen_pptx` tool call does everything: capture, font handling, generation, download. ### What you do 1. **Know the deck.** You probably wrote it. If not, `read_file` the HTML to find: the slide selector, how to navigate (function name? class toggle?), what fonts it uses, whether there's a scaling wrapper. 2. **`show_to_user`** the deck so it's in the user's preview. 3. **Call `gen_pptx`** with the inputs below. 4. **Read the validation flags** in the result and decide if you need to retry. ### gen_pptx inputs ```jsonc { "width": 1920, "height": 1080, // CSS px — match the deck's slide size "slides": [ // one entry per slide, in order { "showJs": "goToSlide(0)", "selector": ".slide.active" }, { "showJs": "goToSlide(1)", "selector": ".slide.active" } // For decks where all slides are in DOM at once and you don't need to navigate: // { "selector": ".slide:nth-child(1)" }, { "selector": ".slide:nth-child(2)" } ], "hideSelectors": [".nav", ".progress", "[data-omelette-chrome]", "[data-noncommentable]"], // If the deck wraps slides in a transform:scale() container, name it here. // gen_pptx clears the transform AND forces width/height onto this element. "resetTransformSelector": ".slide-container", // Font handling — pick ONE strategy based on the directive at the bottom. // Substitution happens BEFORE capture so layout reflows correctly. "googleFontImports": ["Poppins", "Lora"], "fontSwaps": [{ "from": "BrandSans", "to": "Poppins" }], // Or fontSwaps: [{from:"BrandSans", to:"Arial"}] for web-safe. // Or omit both to keep brand fonts as-is. "filename": "my-deck" } ``` If — and only if — the user asked for Google Slides, also pass `"offer_google_slides": true`: the export dialog gains a 'Send to Google Slides' button, and the upload happens only if they click it. `slides[].showJs` runs inside the iframe as a sync expression — don't `await`. If your deck's nav function is async, call it without await; the per-slide `delay` (default 600ms) covers the transition. Bump `delay` for decks with longer CSS transitions. #### If the deck uses the `` starter component - `resetTransformSelector: "deck-stage"` — the exporter sets the `noscale` attribute on it, which the component observes and responds to by dropping its shadow-DOM `transform: scale()`. You cannot reach the scaled canvas any other way. - `slides[N].showJs`: `"document.querySelector('deck-stage').goTo(N)"` — 0-indexed, so slide 1 is `goTo(0)`. - `slides[N].selector`: `"deck-stage > [data-deck-active]"`. - `hideSelectors` is unnecessary — the overlay and tap-zones live in shadow DOM and aren't captured. ### Speaker notes Read automatically from `