Create and edit PowerPoint decks (pptx) using PptxGenJS.
91
Quality
91%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
When using an existing presentation as a template:
Analyze existing slides:
python scripts/thumbnail.py template.pptx
python -m markitdown template.pptxReview thumbnails.jpg to see layouts, and markitdown output to see placeholder text.
Plan slide mapping: For each content section, choose a template slide.
⚠️ USE VARIED LAYOUTS — monotonous presentations are a common failure mode. Don't default to basic title + bullet slides. Actively seek out:
Avoid: Repeating the same text-heavy layout for every slide.
Match content type to layout style (e.g., key points → bullet slide, team info → multi-column, testimonials → quote slide).
Unpack: python scripts/office/unpack.py template.pptx unpacked/
Build presentation (do this yourself, not with subagents):
<p:sldIdLst>)add_slide.py)<p:sldIdLst>Edit content: Update text in each slide{N}.xml.
Use subagents here if available — slides are separate XML files, so subagents can edit in parallel.
Clean: python scripts/clean.py unpacked/
Pack: python scripts/office/pack.py unpacked/ output.pptx --original template.pptx
| Script | Purpose |
|---|---|
unpack.py | Extract and pretty-print PPTX |
add_slide.py | Duplicate slide or create from layout |
clean.py | Remove orphaned files |
pack.py | Repack with validation |
thumbnail.py | Create visual grid of slides |
python scripts/office/unpack.py input.pptx unpacked/Extracts PPTX, pretty-prints XML, escapes smart quotes.
python scripts/add_slide.py unpacked/ slide2.xml # Duplicate slide
python scripts/add_slide.py unpacked/ slideLayout2.xml # From layoutPrints <p:sldId> to add to <p:sldIdLst> at desired position.
python scripts/clean.py unpacked/Removes slides not in <p:sldIdLst>, unreferenced media, orphaned rels.
python scripts/office/pack.py unpacked/ output.pptx --original input.pptxValidates, repairs, condenses XML, re-encodes smart quotes.
python scripts/thumbnail.py input.pptx [output_prefix] [--cols N]Creates thumbnails.jpg with slide filenames as labels. Default 3 columns, max 12 per grid.
Use for template analysis only (choosing layouts). For visual QA, use soffice + pdftoppm to create full-resolution individual slide images—see SKILL.md.
Slide order is in ppt/presentation.xml → <p:sldIdLst>.
Reorder: Rearrange <p:sldId> elements.
Delete: Remove <p:sldId>, then run clean.py.
Add: Use add_slide.py. Never manually copy slide files—the script handles notes references, Content_Types.xml, and relationship IDs that manual copying misses.
Subagents: If available, use them here (after completing step 4). Each slide is a separate XML file, so subagents can edit in parallel. In your prompt to subagents, include:
For each slide:
Use the Edit tool, not sed or Python scripts. The Edit tool forces specificity about what to replace and where, yielding better reliability.
b="1" on <a:rPr>. This includes:
<a:buChar> or <a:buAutoNum><a:buChar> or <a:buNone>.When source content has fewer items than the template:
When replacing text with different length content:
Template slots ≠ Source items: If template has 4 team members but source has 3 users, delete the 4th member's entire group (image + text boxes), not just the text.
If source has multiple items (numbered lists, multiple sections), create separate <a:p> elements for each — never concatenate into one string.
❌ WRONG — all items in one paragraph:
<a:p>
<a:r><a:rPr .../><a:t>Step 1: Do the first thing. Step 2: Do the second thing.</a:t></a:r>
</a:p>✅ CORRECT — separate paragraphs with bold headers:
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" b="1" .../><a:t>Step 1</a:t></a:r>
</a:p>
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" .../><a:t>Do the first thing.</a:t></a:r>
</a:p>
<a:p>
<a:pPr algn="l"><a:lnSpc><a:spcPts val="3919"/></a:lnSpc></a:pPr>
<a:r><a:rPr lang="en-US" sz="2799" b="1" .../><a:t>Step 2</a:t></a:r>
</a:p>
<!-- continue pattern -->Copy <a:pPr> from the original paragraph to preserve line spacing. Use b="1" on headers.
Handled automatically by unpack/pack. But the Edit tool converts smart quotes to ASCII.
When adding new text with quotes, use XML entities:
<a:t>the “Agreement”</a:t>| Character | Name | Unicode | XML Entity |
|---|---|---|---|
“ | Left double quote | U+201C | “ |
” | Right double quote | U+201D | ” |
‘ | Left single quote | U+2018 | ‘ |
’ | Right single quote | U+2019 | ’ |
xml:space="preserve" on <a:t> with leading/trailing spacesdefusedxml.minidom, not xml.etree.ElementTree (corrupts namespaces)Install with Tessl CLI
npx tessl i gyan/pptx