| name | pptx-official |
| description | Use this skill whenever a Microsoft PowerPoint (.pptx) file is being produced, opened, transformed, or read. That includes: authoring slide decks, pitch decks, executive readouts, training material, or any presentation deliverable; extracting text or structure from an existing .pptx; filling a .pptx template with values; converting a deck to PDF or images; splitting or merging decks; inspecting slides, layouts, masters, tables, images, charts, speaker notes, or comments. Trigger on words like 'deck', 'slides', 'presentation', 'pitch deck', 'keynote' (when a .pptx is expected as output), or any filename ending in .pptx. Do NOT trigger when the primary deliverable is a Word document, spreadsheet, PDF report, HTML site, or Google Slides API call, even if presentation-shaped content appears along the way. |
| license | Apache-2.0 โ see LICENSE for terms and third-party attributions |
PPTX Skill
An Apache-2.0 toolkit for producing, editing, and reading Microsoft PowerPoint
(.pptx) files. Written from scratch against the public
ECMA-376 / ISO/IEC 29500 (PresentationML)
specification and built on permissively-licensed tooling (python-pptx MIT,
pptxgenjs MIT, lxml BSD-3-Clause, Pillow MIT-CMU, optional external
binaries soffice MPL 2.0 and pdftoppm GPL) so it can be reused in
commercial projects without restriction.
Decision matrix
| Situation | Path | Read first |
|---|
| Build a deck from a prompt or dataset โ no source file to start from | Author with python-pptx (structured / repeatable) or PptxGenJS (design-heavy, JS) | create.md |
You have a .pptx template to fill in โ keep its master, layouts, look | Placeholder replacement via python-pptx | edit.md โ Template fill |
| Deep structural edits โ reorder slides, splice XML, add unusual objects | Explode โ edit XML parts โ assemble | edit.md โ Raw XML workflow |
Only need the text / speaker notes / structure out of a .pptx | Extraction pipeline | read.md |
| Turn a deck into PDF or PNG images (visual QA, publishing) | scripts/render_pdf.py / scripts/render_slides.py via LibreOffice | see QA below |
| Grid of slide thumbnails for previewing a template | scripts/contact_sheet.py (Pillow) | read.md โ Thumbnails |
If the task mixes several of these, do them in this order:
read โ plan slide-by-slide โ edit/create โ validate โ visual QA.
One-time environment setup
Prerequisites
If uv or bun are not yet installed:
curl -LsSf https://astral.sh/uv/install.sh | sh
curl -fsSL https://bun.sh/install | bash
Python (uv)
Python dependencies are managed by uv. Do not use pip directly.
uv init -p 3.12
uv add python-pptx lxml Pillow
uv add defusedxml
Rules:
- Never use
pip โ always uv add for packages.
- Never run
python scripts/... directly โ always uv run scripts/....
- Don't manually manage environments with
python -m venv or source .venv/bin/activate.
TypeScript (bun)
For PptxGenJS creation, use bun (project-local, not global installs):
bun init -y
bun add pptxgenjs
bun add react react-dom sharp
bun add react-icons
bun add mathjax-full
bun add -d @types/react @types/react-dom
Run scripts directly as TypeScript โ no transpilation needed:
bun run create-ppt.ts
System dependencies (PDF/PNG rendering)
brew install --cask libreoffice
brew install poppler
sudo apt-get install -y libreoffice poppler-utils
Every script under scripts/ uses only the standard library plus
python-pptx, lxml, and Pillow. No proprietary dependencies. External
binaries (soffice, pdftoppm) are invoked as subprocesses; nothing is
bundled or statically linked.
Common commands
uv run scripts/dump_text.py input.pptx --notes > input.txt
uv run scripts/render_pdf.py input.pptx
uv run scripts/render_slides.py input.pptx --out slides/
uv run scripts/contact_sheet.py input.pptx --cols 3
uv run scripts/explode.py input.pptx unpacked/
uv run scripts/assemble.py unpacked/ output.pptx
uv run scripts/prune.py unpacked/
uv run scripts/insert_slide.py unpacked/ --clone slide3.xml
uv run scripts/insert_slide.py unpacked/ --blank-from slideLayout5.xml
uv run scripts/diagnose.py output.pptx
Every script is a small, self-contained Python file. Read the top of the file
for its full CLI options.
Authoring principles
Slides are a visual surface. Users read the deck at 40 feet from the back
of a room, or in a browser tab three inches wide on a phone. Both have to
work. Keep these in mind:
- One idea per slide. If you can't summarize the slide in a five-word
title, split it in two. Long-form reasoning belongs in the doc that
accompanies the deck, not on the slide itself.
- Title, not label. The title is the thesis of the slide. "Revenue" is a
label. "Revenue grew 34% on 22% headcount" is a title. Titles carry the
argument; bodies carry the evidence.
- Every slide earns its visuals. A slide without a chart, image, icon,
or shape is usually a bullet dump. Turn it into a comparison, a stat
callout, a diagram, or delete it.
- Layouts, not per-slide geometry. For anything reused (section
dividers, content pages, quote slides), define a
slide_layout once and
apply it. This makes swapping the theme a one-line change instead of a
fifty-slide sweep.
- Aspect ratio matches the target. 16:9 (default) for laptops and
projectors; 4:3 only when explicitly asked (still common in academia and
some corporate templates); 16:10 for older widescreen.
- Speaker notes carry the words. Put the full narration into
slide.notes_slide.notes_text_frame so the presenter can rehearse from
the deck itself. On the slide, keep it to the phrase they can hold in
their head.
- Bullets are not the default. Bullet lists are the failure mode of
most decks โ comparisons, tables, icons-with-labels, and stat callouts
almost always land better.
Typography defaults (safe starting point)
| Element | Font | Size | Weight | Notes |
|---|
| Slide title | Calibri / Segoe UI | 32-40pt | Bold | One line โ wrap = rework the title |
| Section header | Calibri | 24-28pt | Bold | On dedicated divider slides |
| Body / bullets | Calibri | 18-22pt | Regular | Never below 18pt for a room; 14pt for on-screen decks |
| Stat callout | Calibri Light | 60-96pt | Bold | The number, then the label below at 14-18pt |
| Caption / footer | Calibri | 10-12pt | Regular | Muted gray #7A7A7A |
| Code / mono | Consolas / Cascadia Code | 16-20pt | Regular | Left aligned, no word wrap |
Change the palette for the topic (financial โ navy #1F3A5F; environment โ
forest #2C5F2D; product launches โ your brand's accent). Avoid pure black
on pure white for backgrounds โ #F7F5F0 cream on #1F1F1F ink reads
softer under a projector.
Slide sizes
| Aspect | Width ร Height (inches) | Pixels @ 96 DPI | When to use |
|---|
| 16:9 widescreen (default) | 13.333 ร 7.5 | 1280 ร 720 | Almost every new deck |
| 16:10 | 13.333 ร 8.333 | 1280 ร 800 | Older projectors; some corporate templates |
| 4:3 standard | 10.0 ร 7.5 | 960 ร 720 | Academia, legacy templates, printed handouts |
| A4 landscape | 11.69 ร 8.27 | 1123 ร 794 | Print-first decks (EU) |
| Letter landscape | 11.0 ร 8.5 | 1056 ร 816 | Print-first decks (US) |
QA checklist โ always run before declaring done
Assume something is wrong. PowerPoint opens broken files quietly: a
misaligned text box, a chart pointing at deleted data, a stray placeholder
that survived template fill. Verify explicitly.
-
Opens cleanly. No repair dialog, no missing-part warning.
uv run scripts/diagnose.py output.pptx
-
Text integrity. No placeholder residue and no unfilled {{token}}s:
uv run scripts/dump_text.py output.pptx --notes \
| grep -Ei "\{\{|TODO|TBD|lorem|ipsum|xxxx|click to add"
Grep must return nothing.
-
Visual sanity. Render the whole deck to PNG, spot-check the first,
last, and any slide you touched. Look for:
- Text overflowing the placeholder or getting auto-shrunk past readability.
- Two shapes overlapping (title over image, footer over content).
- Legend / axis labels cut off on charts.
- Icons at the wrong scale (tiny hairline icons, or huge stretched ones).
- Off-brand colors that snuck in from a copied slide.
uv run scripts/render_slides.py output.pptx --out qa/
-
Layout hygiene. Every non-master slide should reference a real layout,
not slideLayout1 by default for a section divider:
uv run python -c "
from pptx import Presentation
prs = Presentation('output.pptx')
for i, s in enumerate(prs.slides, 1):
print(f'slide {i}: layout={s.slide_layout.name!r}')"
If any of these fail, fix and re-run โ don't paper over.
Common visual pitfalls
- Titles wrap onto two lines โ either shorten the title or widen the
placeholder. Wrapped titles push body content down and break layout
alignment across slides.
- Body text auto-shrinks below 14pt โ python-pptx respects the
placeholder's autofit setting; if the resulting size is unreadable, split
the slide instead of accepting the shrink.
- Charts inherit Office defaults โ the pale blue / gray palette shipped
with PowerPoint looks generic. Explicitly set
chart.chart_style or use
python-pptx's low-level access to set fill colors on series.
- Speaker notes forgotten โ a deck without notes cannot be rehearsed.
Fill
notes_slide.notes_text_frame.text on every slide, even if just a
single sentence.
- Images at wrong DPI โ a 4000ร3000 photo on a 1280ร720 slide bloats
the file with no visual benefit. Resample down to ~150 DPI at the target
display size (see
create.md โ Images).
- Fonts not embedded โ
python-pptx does not embed fonts. If the deck
is opened on a machine without the chosen font, PowerPoint substitutes,
and layout drifts. Either use system-safe fonts (Calibri, Arial, Segoe UI,
Times New Roman, Consolas) or ship the .pptx alongside a font install
step.
What is out of scope
.ppt (PowerPoint 97-2003 binary). Convert first:
soffice --headless --convert-to pptx old.ppt.
- VBA / macros /
.pptm. This skill does not emit or execute macros.
- Password-protected or encrypted decks.
python-pptx cannot read
encrypted files; strip protection with PowerPoint or LibreOffice first.
- Live PowerPoint automation. For COM (Windows) or AppleScript (macOS)
integration, use a dedicated automation library โ this toolkit is
file-in / file-out.
- Keynote
.key files. Not a PresentationML format; use Apple's
Keynote or LibreOffice for round-trip.
Where each detail lives
- Creating from scratch:
create.md โ python-pptx recipes,
PptxGenJS recipes, layouts, text, tables, images, charts, icons,
backgrounds, speaker notes, palette and typography guidance.
- Editing / templating:
edit.md โ placeholder fill, slide
duplication / reorder / delete, explode/assemble for XML surgery, comments,
cleanup of orphaned parts, common pitfalls.
- Reading / extracting:
read.md โ plain-text export
(including speaker notes), structural walk, metadata, thumbnails, image
extraction, conversion to PDF / PNG for QA.
- Scripts:
scripts/ โ self-contained CLI utilities.