> ## Documentation Index
> Fetch the complete documentation index at: https://docs.profy.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Presentations

> profy-pptx — two mutually exclusive pipelines: native .pptx (SVG → DrawingML) and HTML Deck (single-file web presentation)

# Presentations (profy-pptx)

Presentations run through **two mutually exclusive pipelines**. Once chosen you cannot switch mid-way, and you cannot convert between them. Start with this table to decide which path you are on:

|                   | HTML Deck                                       | Native PPTX                                                         |
| ----------------- | ----------------------------------------------- | ------------------------------------------------------------------- |
| Deliverable       | Single-file `.html`, opened in a browser        | `.pptx`, opened in PowerPoint / Keynote                             |
| Visual capability | WebGL backgrounds, CSS motion, horizontal swipe | Vector DrawingML, editable text and shapes                          |
| PDF export        | **Prohibited** (see below)                      | The user exports from PowerPoint themselves                         |
| Suits             | Talks, launch events, magazine or Swiss style   | Work reports, training material, anything needing a real .pptx file |

<Warning>
  **Once a path is chosen, do not attempt cross-path conversion.** Do not turn an HTML Deck into PDF or PPTX, and do not turn a PPTX into an HTML Deck. HTML Decks depend on Tailwind plus WebGL, neither of which WeasyPrint or wkhtmltopdf can render, so the conversion produces severely degraded output. If you need a PDF, take the `builtin/kami` route from the start.
</Warning>

## Activation

`profy-pptx` is `user_selectable: false` — **automatically available, nothing to tick**.

```json theme={null}
{ "id": "profy-pptx", "activation": { "user_selectable": false } }
```

`contracts` declares only `skills: ["skills/"]` and **no tools**. The plugin ships **two** skills: `builtin/pptx` (the native pipeline hub) and `builtin/html-deck` (web presentations).

## The export pipeline lock

<Warning>
  **Never write a custom export or conversion script.** The only supported way to produce a PPTX is executing the skill's own `svg_to_pptx.py`.

  Custom scripts (cairosvg, python-pptx, pptxgenjs, and friends) produce **rasterized image-only slides with broken CJK text** — a known P0 defect.

  This rule applies **unconditionally**, including after sandbox errors, retries, or context compression. If the sandbox recovered, re-run the pipeline script; do not rewrite it.
</Warning>

The reasoning is worth internalising. There are two ways to get SVG into PPTX: render the SVG to a bitmap and paste it into a slide, or translate SVG primitives into PowerPoint's native DrawingML. The first is trivial and any general-purpose library will do it — at the cost of slides that are completely uneditable and text that is no longer text. `svg_to_pptx.py` does the second.

The reason the rule is stated as unconditional is that constraints like this are most often broken **during failure recovery**. After a few errors and retries, writing "a simpler version" looks like reasonable self-rescue, and it happens to route around the only correct implementation. Worse, the wrong path does not error — it produces a file that opens fine and is quietly useless.

## Intent router

| User intent                                                | Path           | Deliverable |
| ---------------------------------------------------------- | -------------- | ----------- |
| Web PPT / magazine style / Swiss style / swipe deck        | HTML Deck      | `.html`     |
| Make a presentation / create slides, with no existing file | Create         | `.pptx`     |
| Uploads .pptx + "edit this"                                | Edit           | `.pptx`     |
| Uploads .pptx + "use this as a template"                   | Template Clone | `.pptx`     |
| Already generated + "change slide N"                       | Iterate        | `.pptx`     |

## Native PPTX: the seven-step pipeline

```
Step 1: Source preparation
Step 2: Project initialization
Step 3: Template selection (optional)
Step 4: Strategist phase (design spec + eight confirmations)
Step 5: Image generation (if needed)
Step 6: Executor phase (SVG generation + speaker notes)
Step 7: Post-processing and export
```

**Phase split**: steps 1–5 are Phase A (planning and assets), steps 6–7 are Phase B (execution and export). For long decks, Phase B can run in a fresh session via the `resume-execute` workflow to reclaim context budget.

### Step 1: source conversion

| Source type          | Converter                                                                 |
| -------------------- | ------------------------------------------------------------------------- |
| PDF                  | `source_to_md/pdf_to_md.py`                                               |
| Word                 | `source_to_md/doc_to_md.py`                                               |
| Excel                | `source_to_md/excel_to_md.py`                                             |
| PowerPoint           | `source_to_md/ppt_to_md.py`                                               |
| Web URL              | `source_to_md/web_to_md.py`                                               |
| Plain text / chat    | Used directly                                                             |
| Topic only, no files | Run the `topic-research` workflow first to gather material via web search |

Everything is normalised to Markdown before the pipeline proper begins, which is what lets one downstream pipeline serve six different input formats.

### Step 2: canvas formats

| Format   | viewBox         | Use case                         |
| -------- | --------------- | -------------------------------- |
| `ppt169` | `0 0 1280 720`  | Business presentations (default) |
| `ppt43`  | `0 0 1024 768`  | Traditional projectors           |
| `xhs`    | `0 0 1242 1660` | Xiaohongshu image-text posts     |
| `wechat` | `0 0 1080 1080` | WeChat Moments / IG square       |
| `story`  | `0 0 1080 1920` | Vertical stories / TikTok        |

The same pipeline produces social media images because the underlying representation is SVG — changing the viewBox changes the canvas, no second pipeline required.

### Step 3: templates (optional)

Templates are applied **only when the user supplies an explicit template directory path**. Bare style words such as "academic style" do not trigger template copying; they feed the Strategist's style descriptor at Step 4 instead.

| Family          | What it provides                                                     |
| --------------- | -------------------------------------------------------------------- |
| Layout template | Brand identity plus an SVG page roster (fixed page structures)       |
| Brand template  | Brand identity only — colours, typography, logo, voice; no page SVGs |

When both are supplied they fuse into a single `design_spec.md`. Precedence on conflict: **colour, typography, logo, and icon style come from Brand; page structure and SVG roster come from Layout.**

## Editing an existing PPTX

The workflow is unpack → edit XML directly → automatic clean → pack. `edit_pptx.py` exposes five subcommands:

| Command                                               | Purpose                       |
| ----------------------------------------------------- | ----------------------------- |
| `read <file.pptx>`                                    | Read content                  |
| `unpack <file.pptx> <output_dir>`                     | Unpack                        |
| `pack <dir> <output.pptx> --original <original.pptx>` | Repack, requires the original |
| `add-slide <unpacked_dir> <source>`                   | Add a slide                   |
| `thumbnail <file.pptx>`                               | Generate a thumbnail          |

`pack` requires `--original` because a pptx package contains many relationship files and resources that were never touched by the edit and must be inherited from the source package.

## HTML Deck: web presentations

A single-file HTML horizontal-swipe deck in one of two visual registers:

### Style A — electronic magazine × e-ink (default)

* WebGL fluid / contour / dispersion backgrounds, visible on the hero slide
* Serif headings (Noto Serif SC + Playfair Display), sans body, monospace metadata
* Suits humanities talks, industry commentary, commercial launches
* Aesthetic anchor: *Monocle* magazine with code stuck to it

### Style B — Swiss International Style

* WebGL ultra-fine grid plus dot-matrix background
* Sans throughout (Inter + Helvetica + Noto Sans SC), extreme type-size contrast
* One high-contrast functional accent: International Klein Blue, lemon yellow, lemon green, or safety orange
* Suits technology products, data reporting, annual reviews
* Aesthetic anchor: Massimo Vignelli, Helvetica Forever

**Shared by both styles**: horizontal navigation (keyboard ← →, scroll wheel, touch, ESC for the index), Lucide icons, Motion One entrance animation with both local and CDN sources.

### When *not* to use HTML Deck

| Situation                          | Use instead                                                      |
| ---------------------------------- | ---------------------------------------------------------------- |
| A `.pptx` file is required         | `builtin/pptx` native pipeline                                   |
| A `.pdf` file is required          | `builtin/kami`                                                   |
| Dense tables, layered charts       | A conventional deck                                              |
| Training material                  | A conventional deck — HTML Deck's information density is too low |
| Multi-person collaborative editing | A conventional deck — HTML Deck is a static file                 |

## Environment constraints

<Warning>
  **All Python dependencies are preinstalled in the sandbox image. Do not run `pip install`, `uv pip install`, or any package manager command.** If an import fails, that is a sandbox image bug, not something to fix at runtime.
</Warning>

Scripts execute inside the sandbox via `skill(action="execute")`. Dependencies deploy automatically on first use and subsequent calls in the same session skip deployment. The sandbox layout:

```
/home/user/workspace/pptx/
├── scripts/      # Python scripts, auto-deployed on first execute
├── templates/    # Icon and chart templates
└── projects/     # Working directory for generated content
```

## Boundaries and failure modes

* **The two pipelines are mutually exclusive** and cannot be converted between (see the warning at the top).
* **A custom export script produces broken CJK text** while appearing to succeed — the failure mode to fear most, because nothing errors.
* **Templates require an explicit path**; style words do not trigger them.
* **Phase B of a long deck should move to a fresh session**, otherwise SVG source fills the context window.
* **HTML Deck is a static file** with no collaborative editing.

### Troubleshooting

| Symptom                                              | Cause                                                 | Fix                                                  |
| ---------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------- |
| Text in the PPTX cannot be selected — it is an image | A custom conversion script was used                   | Re-run `svg_to_pptx.py`                              |
| CJK characters render as boxes or mojibake           | Same cause; classic rasterized-pipeline signature     | Same fix                                             |
| Import errors                                        | Sandbox image is missing a dependency                 | Report it; do **not** install packages at runtime    |
| Said "academic style" but no template applied        | Style words do not trigger templates                  | Provide an explicit template directory path          |
| HTML Deck exported to PDF looks destroyed            | Tailwind and WebGL cannot be handled by PDF renderers | Switch to `builtin/kami` when PDF is the requirement |
| Long deck runs out of context mid-way                | No phase split was performed                          | Continue in a new session via `resume-execute`       |

## Verify your output

1. **Open the PPTX and click on body text** — if it selects and edits, the DrawingML pipeline ran. If it does not, the deck was rasterized.
2. For Chinese decks, confirm there are no box glyphs.
3. For an HTML Deck, page through with ← → and confirm the motion and the ESC index both work.

## Related

<CardGroup cols={2}>
  <Card title="Office documents overview" href="/en/documentation/capabilities/office-documents">
    How the four document capabilities differ and when to use each
  </Card>

  <Card title="PDF documents" href="/en/documentation/capabilities/office-pdf">
    The kami typesetting engine when PDF is the deliverable
  </Card>
</CardGroup>

<Note>
  Verified 2026-08-11. Sources: `services/agent-runtime/src/plugins/builtin/pptx/plugin.json`, `skills/pptx/SKILL.md`, `skills/html-deck/SKILL.md`, `skills/pptx/scripts/`. html-deck originates from guizang-ppt-skill (author: 歸藏).
</Note>
