# Editing decks via unpacked XML

Use this when you must **respect an existing template** or fine-tune OOXML directly.

## Template-driven workflow

1. **Preview**  
   - `python scripts/slide_preview_grid.py template.pptx` → JPEG grid of slides.  
   - `python -m markitdown template.pptx` (if installed) for plain text.

2. **Plan layout variety** — avoid repeating one generic title+bullet layout. Prefer different layouts (multi-column, image+text, section breaks, quote slides, stat callouts) matched to content type.

3. **Unpack**  
   `python scripts/ooxml_kit/expand_ooxml_zip.py template.pptx unpacked/`

4. **Structural edits first** (before heavy text edits):  
   - Adjust `ppt/presentation.xml` → `<p:sldIdLst>` for order.  
   - Remove slides from the list, then run `prune_orphan_parts.py`.  
   - Add slides with `insert_slide_copy.py` (duplicates a slide XML or instantiates from a layout). The script auto-updates `[Content_Types].xml`, `presentation.xml.rels`, and `presentation.xml` `<p:sldIdLst>`. Use `--position N` (0-based) to control slide order. **Do not** manually duplicate slide files — relationships and content types must stay consistent.

5. **Content edits** — edit `ppt/slides/slideN.xml` (and related `slideN.xml.rels`). Parallel edits per slide file are safe when coordination is clear.

6. **Prune**  
   `python scripts/prune_orphan_parts.py unpacked/`

7. **Pack**  
   `python scripts/ooxml_kit/build_ooxml_zip.py unpacked/ output.pptx --original template.pptx`

---

## Script quick reference (this skill)

| Script | Purpose |
|--------|---------|
| `ooxml_kit/expand_ooxml_zip.py` | Unzip, pretty-print XML, smart-quote escaping |
| `ooxml_kit/build_ooxml_zip.py` | Zip, optional validation vs `--original` |
| `ooxml_kit/audit_ooxml_package.py` | Validate unpacked or packed package |
| `insert_slide_copy.py` | Add slide from existing slide or layout |
| `prune_orphan_parts.py` | Remove orphans after structural changes |
| `slide_preview_grid.py` | Thumbnail grid for template review |

---

## Slide list mechanics

- Order = `ppt/presentation.xml` → `<p:sldIdLst>` → `<p:sldId r:id="rId…">`.
- **Reorder**: move `<p:sldId>` elements.
- **Delete**: remove `<p:sldId>`, then run `prune_orphan_parts.py`.
- **Add**: use `insert_slide_copy.py`; the script auto-inserts the `<p:sldId>` element. Use `--position N` to place at a specific index.

---

## Editing slide XML

- Replace **all** placeholder content: titles, body, images, chart placeholders, captions.
- Prefer **structured edits** (IDE patch / Edit tool) over blind `sed`.
- **Bold** titles and inline labels via `b="1"` on `<a:rPr>` where the template uses bold.
- **Do not** paste Unicode bullet characters (`•`) into XML — use proper list markup (`<a:buChar>`, `<a:buAutoNum>`, or layout defaults).
- **Multiple list items** → separate `<a:p>` paragraphs; never concatenate steps into one run.

### Smart quotes in XML

When inserting new apostrophes or quotes, use entities so pack stays deterministic:

| Char | Entity |
|------|--------|
| “ | `&#x201C;` |
| ” | `&#x201D;` |
| ‘ | `&#x2018;` |
| ’ | `&#x2019;` |

Leading/trailing spaces in `<a:t>` may need `xml:space="preserve"`.

### Pitfalls

- If the template has **more slots than content**, delete the entire placeholder shape group, not just text.
- Longer text may overflow — verify with a full-render preview (LibreOffice PDF export + `pdftoppm`, or PowerPoint).
- Parsing with `defusedxml.minidom` is safer than naive `ElementTree` round-trips for OOXML namespaces.

---

## High-res visual QA

For pixel-accurate review (not just the thumbnail grid), export to PDF via LibreOffice and rasterize per page — see `SKILL.md` for the general idea.
