| name | generating-pptx-from-template |
| description | Generates fully populated PowerPoint presentations that inherit the exact colors, fonts, layouts, and branding from a user-supplied .pptx template. Use when the user uploads or references a .pptx template file and asks to create or generate a presentation on a given topic. Triggers on: use my template, create slides from my pptx, generate a deck using my template, fill in my template, make a presentation from the attached file, build slides using my brand template, or when the user shares a .pptx file and wants a polished output matching their brand. Also use when multiple .pptx files are uploaded and the user wants a presentation combining layouts from all of them. |
| license | MIT |
Generating PPTX from Template
Produces polished PowerPoint presentations using an uploaded .pptx file as the
design source of truth. The output inherits the template's exact visual identity
— no generic AI aesthetics, no hardcoded colors or fonts.
Setup
Install required tools before any other step:
pip install "markitdown[pptx]" Pillow defusedxml --break-system-packages -q
which pdftoppm || apt-get install -y poppler-utils -q
All helper scripts live in two locations:
# Public pptx skill scripts (structural operations)
/mnt/skills/public/pptx/scripts/office/unpack.py
/mnt/skills/public/pptx/scripts/office/pack.py
/mnt/skills/public/pptx/scripts/office/soffice.py
/mnt/skills/public/pptx/scripts/add_slide.py
/mnt/skills/public/pptx/scripts/clean.py
/mnt/skills/public/pptx/scripts/thumbnail.py
# This skill's scripts (QA and analysis)
/mnt/skills/user/generating-pptx-from-template/scripts/audit_overflow.py
/mnt/skills/user/generating-pptx-from-template/scripts/check_placeholders.py
Workflow Overview
Step 1 → Ingest template (markitdown + thumbnails + unpack)
Step 2 → Plan content (layout inventory + slide map)
Step 2.5 → Measure placeholder capacity BEFORE writing any content
Step 3 → Structural edits (add/remove/reorder slides)
Step 3.5 → Populate content (XML editing with overflow prevention)
Step 4 → QA (content check + visual render + overflow check)
Step 5 → Deliver
Step 1 — Ingest the Template
Locate and copy the uploaded template:
ls /mnt/user-data/uploads/*.pptx
cp /mnt/user-data/uploads/YOUR_TEMPLATE.pptx /home/claude/template.pptx
Extract all text and structure to understand existing content:
python -m markitdown /home/claude/template.pptx
Generate visual thumbnails — this is mandatory, not optional. You must see
the actual layout, colors, design motifs, and photo placement before writing
a single character of content:
python /mnt/skills/public/pptx/scripts/thumbnail.py \
/home/claude/template.pptx /home/claude/thumbnails
Unpack to XML for editing:
python /mnt/skills/public/pptx/scripts/office/unpack.py \
/home/claude/template.pptx /home/claude/unpacked/
After unpacking, run a quick structural survey:
ls /home/claude/unpacked/ppt/slides/slide*.xml | grep -v _rels
for f in /home/claude/unpacked/ppt/slides/slide*.xml; do
echo "$f:"; grep -o 'slideLayout[0-9]*' $f/_rels/../_rels/$(basename $f).rels 2>/dev/null || echo " (no layout ref found)"
done
grep -A20 'a:clrScheme' /home/claude/unpacked/ppt/theme/theme1.xml | grep -E 'val=|name='
Read references/template-analysis.md for full inspection guidance: color
extraction, font detection, placeholder mapping, and capacity estimation.
Step 2 — Plan Content
Build a written slide plan before touching any XML. This prevents
structural rework after content has been populated.
For each slide in the plan, record:
- Slide number → source template slide (e.g., "Slide 3 → use slide2.xml layout")
- Topic / section title
- Content type: stat, bullets, quote, two-column, image+text, etc.
- Approximate content length (word/character count estimate)
Rules:
- Use every distinct layout at least once if the content fits
- Never use the same layout for two consecutive content slides
- Match content type to layout (stats → callout, team → multi-column)
- For typical business presentations: 8–12 slides; pitch decks: 10–15
Read references/content-mapping.md for layout-to-content matching tables,
standard slide structures (business, pitch, educational, status report), and
content density rules.
Step 2.5 — Measure Placeholder Capacity (Required Before Writing)
This step must happen before editing any slide XML.
Text overflow is the most common and most preventable visual failure. Catching
it before writing content avoids multiple fix cycles.
Measure box dimensions
python3 -c "
import xml.etree.ElementTree as ET
NS = {'a':'http://schemas.openxmlformats.org/drawingml/2006/main',
'p':'http://schemas.openxmlformats.org/presentationml/2006/main'}
tree = ET.parse('/home/claude/unpacked/ppt/slides/slide2.xml')
for sp in tree.findall('.//p:sp', NS):
name = sp.find('.//p:cNvPr', NS)
ext = sp.find('.//a:ext', NS)
if name is not None and ext is not None:
cx = int(ext.get('cx',0)); cy = int(ext.get('cy',0))
print(f\"{name.get('name','?'):40s} {cx/914400:.2f}\" x {cy/914400:.2f}\")
"
Set a character budget
Use this table to determine how much text fits safely (≤ 80% capacity rule):
| Box height | Box width | Font size | Max lines | Chars/line | Safe budget (80%) |
|---|
| 0.5" | 3" | 14pt | 2 | 31 | ~50 |
| 0.5" | 4" | 12pt | 2 | 48 | ~77 |
| 1" | 3" | 14pt | 5 | 31 | ~124 |
| 1" | 3" | 18pt | 4 | 24 | ~77 |
| 1" | 4" | 14pt | 5 | 41 | ~164 |
| 2" | 3" | 14pt | 10 | 31 | ~248 |
| 2" | 3" | 18pt | 7 | 24 | ~134 |
| 2" | 4" | 16pt | 9 | 34 | ~245 |
| 3" | 4" | 16pt | 13 | 34 | ~354 |
| 4" | 4" | 16pt | 17 | 34 | ~462 |
Formula: capacity = (height_in / (font_pt * 1.2 / 72)) * (width_in / (font_pt * 0.5 / 72))
If your planned text exceeds the 80% budget, shorten it NOW before writing XML.
Run the automated audit
After populating slides (before packing), run the overflow audit:
python /mnt/skills/user/generating-pptx-from-template/scripts/audit_overflow.py \
/home/claude/unpacked/ppt/slides/
This reports every text box as:
- 🔴 OVERFLOW — content already exceeds the box (must fix before delivering)
- 🟡 AT RISK — content at 85–100% capacity (review visually)
- And provides a recommended maximum font size for each flagged box
Fix all 🔴 items. Visually verify all 🟡 items in the QA render.
See references/content-editing.md → Text Overflow — Full Fix Protocol for
the complete decision tree covering all four fix strategies:
autofit XML, font size reduction, box expansion, and content shortening.
Step 3 — Structural Edits
Complete ALL structural operations before editing any content.
Editing content before structure is done causes XML corruption and lost work.
Structural order:
- Remove slides not in your plan (edit
<p:sldIdLst> in ppt/presentation.xml)
- Duplicate slides you need to reuse:
python scripts/add_slide.py unpacked/ slideN.xml
- Reorder slides by rearranging
<p:sldId> entries in presentation.xml
After all structural changes, always clean:
python /mnt/skills/public/pptx/scripts/clean.py /home/claude/unpacked/
Step 3.5 — Populate Content
Editing rules
Preferred method: Use str_replace to make targeted replacements in slide XML.
This is the safest approach for small, clearly unique text blocks.
Acceptable method: Use Python for batch replacements across a slide when
many text values need changing and str_replace would require too many
individual calls. Always write the full file back atomically:
with open(slide_path, 'r', encoding='utf-8') as f:
content = f.read()
content = content.replace('<a:t>OLD TEXT</a:t>', '<a:t>NEW TEXT</a:t>', 1)
with open(slide_path, 'w', encoding='utf-8') as f:
f.write(content)
Never use: sed, awk, or regex substitutions that modify surrounding XML.
These corrupt namespace declarations and run-property attributes unpredictably.
Critical XML rules
- Bold all titles and section headers:
b="1" on a:rPr
- Never use unicode bullet characters — use
<a:buChar char="•"/> or <a:buAutoNum>
- Create separate
<a:p> elements per bullet — never concatenate into one string
- Preserve
a:pPr blocks (line spacing, indentation, alignment) from originals
- Use theme color references (
<a:schemeClr val="accent1"/>) not hardcoded hex values
- Remove
<a:latin typeface="..."/> overrides to inherit theme fonts automatically
- Use XML entities for special characters:
“ ” — ’
- For text with intentional leading/trailing spaces:
<a:t xml:space="preserve"> text</a:t>
After populating each slide
Run the overflow audit immediately:
python /mnt/skills/user/generating-pptx-from-template/scripts/audit_overflow.py \
/home/claude/unpacked/ppt/slides/
Fix all 🔴 OVERFLOW items before moving to the next slide.
Pack the output
python /mnt/skills/public/pptx/scripts/office/pack.py \
/home/claude/unpacked/ \
/home/claude/output.pptx \
--original /home/claude/template.pptx
Step 4 — QA (Required — Do Not Skip)
Content check
python /mnt/skills/user/generating-pptx-from-template/scripts/check_placeholders.py \
/home/claude/output.pptx
python -m markitdown /home/claude/output.pptx | \
grep -iE "lorem|ipsum|click to|placeholder|your title|add text|xxxx|20xx|20yy"
Fix any matches before continuing.
Visual render
cd /home/claude
python /mnt/skills/public/pptx/scripts/office/soffice.py --headless --convert-to pdf output.pptx
pdftoppm -jpeg -r 150 output.pdf slide
Visual QA checklist — inspect every slide image for:
Layout & brand:
Text overflow — check every text box:
Content quality:
Fixing overflow found in the visual render
- Match the overflowing shape in the image to its XML using
off x= / off y= coordinates
- Apply the decision tree from
references/content-editing.md → Text Overflow section:
- Body/description/bullet box → add
<a:normAutofit/> to <a:bodyPr>
- Stat callout or title (design-critical) → shorten the text content
- Spare vertical space available → increase
cy in <a:ext>
- No space to expand → reduce
sz by 100–300 per <a:rPr> + shorten text
- Re-pack and re-render the affected slide
- Confirm fix is resolved before declaring QA passed
Do not declare success without at least one full fix-and-verify cycle.
Step 5 — Deliver
cp /home/claude/output.pptx /mnt/user-data/outputs/presentation.pptx
Present /mnt/user-data/outputs/presentation.pptx to the user with a brief
summary of what each slide covers.
Multiple Templates
If the user uploads more than one .pptx file:
- Analyze all templates with markitdown and thumbnails
- Select the richest template (most layout variety, strongest brand) as primary
- Import unique layouts from secondary templates only when needed
Read references/multi-template.md for the full merge procedure including
media file handling, layout reference resolution, and Content_Types.xml registration.
Common Failure Modes
| Problem | Root Cause | Fix |
|---|
| Output colors changed | Hardcoded hex in slide XML | Use <a:schemeClr> references instead |
| Fonts changed | Hardcoded <a:latin typeface> override | Remove the override — let theme inherit |
| Template logos/images missing | Media files moved or deleted | Never delete ppt/media/; always use --original flag in pack.py |
| Text cut off at box bottom | Content length exceeds box height | Add <a:normAutofit/> to <a:bodyPr>, or reduce sz, or increase cy |
| Text overlaps adjacent shape | Box expanded into another shape's lane | Check off + ext positions; shrink content or reduce cy |
| Stat number clipped | Large sz + long label doesn't fit box width | Shorten label; reduce stat sz by 200–400; never autofit stat boxes |
| Title truncated mid-word | Title text too long for placeholder width | Rewrite title to ≤ 40 chars; reduce sz to minimum 2800 |
| Content unreadably tiny | Over-reduced sz to force fit | Expand cy if space allows; split content across two slides |
| Wrong slide duplicated | add_slide.py called with wrong source | Confirm source slide filename before duplicating |
| Structural edits lost | Content edited before structure complete | Always complete all add/remove/reorder before any text edits |
| XML corruption | Used sed/awk/regex on XML | Only use str_replace or atomic Python file writes |
Reference Files
| File | Contents |
|---|
references/template-analysis.md | Template inspection: color extraction, font detection, placeholder mapping, capacity estimation |
references/content-editing.md | XML patterns for all content types + full text overflow fix protocol |
references/content-mapping.md | Layout-to-content matching, presentation structures, density rules |
references/multi-template.md | Merging multiple uploaded templates |
scripts/audit_overflow.py | Automated overflow detection: scans slide XML, reports at-risk boxes with recommended font sizes |
scripts/check_placeholders.py | QA gate: scans output for leftover placeholder text patterns |