pptx-deck-builder
pptx + excal Deck Builder
Build template-bound, validated PowerPoint decks with professional diagrams.
This skill combines two CLI tools (pptx for slide generation, excal for
diagrams) with consulting-grade presentation principles.
When to read the reference files
references/pptx-workflow.md— Read when you need the fullpptxCLI command reference, manifest structure, placeholder details, deck spec format, error codes, or image-handling workarounds.references/excal-diagrams.md— Read when you need to create Excalidraw diagrams, render them to PNG, or understand the scene JSON format.references/mckinsey-style.md— Read when the user asks for consulting-style, executive, strategy, or McKinsey-style presentations. Also read when you need guidance on action titles, storyline structure, slide archetypes, or the Pyramid Principle.
Core workflow
Every deck project follows this sequence. Do not skip steps.
Step 0 — Think before building
Before touching any tool, resolve the presentation's purpose:
- What decision or outcome is this deck driving?
- What is the single governing thought or recommendation?
- What are the 3-5 supporting arguments?
- What evidence proves each argument?
If the user's request is vague, ask clarifying questions. A deck without a clear purpose becomes a collection of slides instead of an argument.
For consulting-style decks, write a ghost deck first — a title-only
outline where each slide title states the takeaway (not the topic). The titles
alone should tell a coherent story. See references/mckinsey-style.md.
Step 1 — Initialize the manifest (one-time setup)
Check if a manifest package already exists. If not, initialize from the template. Do not assume a PowerPoint template exists; ask the user for the actual template path when it is not already present in the workspace:
pptx init <template.pptx> --out ./corp-template --format json
Then run the doctor to verify compatibility:
pptx doctor --manifest ./corp-template --format json
Step 2 — Discover layouts and placeholders
List available layouts, then inspect placeholders for the ones you plan to use:
pptx layouts list --manifest ./corp-template --format json
pptx placeholders list <layout-id> --manifest ./corp-template --format json
Read-only commands can run in parallel for speed. Key information per placeholder:
logical_name— The key to use in your spec (e.g.,title,content_1)placeholder_type—title,body,object, orpicturesupported_content_types— What it accepts (text,markdown-text,image,table,chart)required— Whether it must be filledestimated_text_capacity— Preferred normalized guidance for text-capable placeholders. Readmax_linesfirst, then checkconfidence,source, andfont_size_pt.text_defaults— Raw extracted placeholder hints such as suggested font size or explicitmax_linesfrom the template textleft_emu,top_emu,width_emu,height_emu— The actual geometry. Treatwidth_emuandheight_emuas hard constraints for how much content the placeholder can realistically hold.
For slide drafting, prefer estimated_text_capacity.max_lines over parsing
text_defaults.max_lines directly. Treat it as guidance, not a hard rule:
stay at or below the line estimate when possible, and be more conservative
when confidence is low.
Respect placeholder size in every content decision:
- Text: do not write beyond the likely line budget for the box. If the message does not fit, tighten the wording or choose a layout with a larger text area.
- Images and diagrams: match the placeholder aspect ratio and expected visual density to the available width and height.
- Tables and charts: reduce rows, columns, labels, or series when the placeholder is small. Prefer a larger layout over forcing dense content into a small box.
Also inspect theme colors and assets if you need to match the visual identity:
pptx theme show --manifest ./corp-template --format json
pptx assets list --manifest ./corp-template --format json
Step 3 — Create diagrams with excal (if needed)
When the deck needs diagrams, flowcharts, or visual explanations, create them as Excalidraw scenes and render to PNG.
Critical: match the placeholder aspect ratio. Before designing a diagram, check the target placeholder's dimensions in EMUs (from the placeholders command). Calculate the aspect ratio and design the diagram to match.
For a picture placeholder that is 6642100 x 5514313 EMU (~1.2:1), design a diagram roughly 540px wide x 450px tall. A mismatch causes cropping or letterboxing.
# Create the .excalidraw file, then:
excal validate diagrams/my-diagram.excalidraw
excal render diagrams/my-diagram.excalidraw --outDir ./out/diagrams --png --scale 4 --no-background
Use --no-background for transparent backgrounds that blend with slide
backgrounds. Use --scale 4 for crisp output — scale 2 looks blurry on
large slide placeholders because the pixel density is too low for the
physical size. Scale 4 ensures diagrams stay sharp even on high-DPI
displays and when projected.
Match the template's visual identity. Diagrams should feel like they belong on the slide, not like foreign objects pasted in. Two things matter most:
-
Use
fontFamily: 1(Excalidraw's hand-drawn style) for diagram text. This gives a clean whiteboard aesthetic that contrasts well with formal slide typography and looks intentional rather than mismatched. -
Pull colors from the template theme. Run
pptx theme show --manifest ./corp-template --format jsonand use the accent colors for fills and strokes. Common mapping:- Primary elements → accent1 (e.g.,
#003778) - Secondary elements → accent2 (e.g.,
#4673C3) - Tertiary/subtle → accent3 (e.g.,
#87AAE1) - Success/positive →
#087f5b(green) - Labels/muted →
#868e96(gray)
Avoid arbitrary colors — diagrams that use theme colors integrate seamlessly with the slide's color palette.
- Primary elements → accent1 (e.g.,
Keep elements away from frame edges. Text and shapes positioned within 10px of the frame boundary may be clipped during PNG export. Use at least a 15px margin on all sides of the frame for safe rendering.
See references/excal-diagrams.md for the full Excalidraw scene format and
element types.
Step 4 — Write the deck spec
Create a YAML file mapping layouts to content:
manifest: ./corp-template
metadata:
title: "Presentation Title"
author: "Author Name"
slides:
- layout: layout-id
content:
title: "Action title stating the takeaway"
subtitle: "Optional context"
content_1: |
- Bullet point one
- Bullet point two
source: "Source: Data attribution"
notes: |
# Speaker notes
- Open with the takeaway before reading the slide
- Keep timing to under 90 seconds
- layout: picture-layout-id
content:
title: "Slide title"
picture:
kind: image
path: out/diagrams/my-diagram.png
content_1: |
Supporting text alongside the image
Content value formats:
- Plain string → treated as
text - Multi-line YAML block scalar with markdown-looking content (headings, lists,
ordered items) → auto-detected as
markdown-text @notes.mdvia--set key=@notes.mdor{ kind: "markdown-text", value: "..." }→ markdown parsed with headings, lists, inline emphasis, and light presentation-aware spacing- Slide-level speaker notes →
notes: |in the deck spec, orpptx slide create --notes/--notes-filefor single-slide generation { kind: "image", path: "path/to/file.png" }→ image insertion{ kind: "table", columns: [...], rows: [[...], ...] }→ table{ kind: "chart", chart_type: "column_clustered", categories: [...], series: [{name: "...", values: [...]}] }→ chart
For markdown-heavy placeholders, prefer explicit kind: markdown-text when you
want unambiguous behavior. The current renderer preserves bold, italic, inline
code, bullets, nested bullets, ordered lists, and light block spacing, but it
does not attempt full document-layout fidelity.
Section spacing in markdown content: When a placeholder contains multiple sections (e.g., bold heading + bullets, then another bold heading + bullets), add a blank line between sections to create visual breathing room. Without it, consecutive sections run together with minimal spacing.
Step 5 — Build and validate
pptx deck build --manifest ./corp-template --spec deck.yaml --out ./out/deck.pptx --format json
pptx validate --manifest ./corp-template --deck ./out/deck.pptx --strict --format json
Always validate with --strict. Fix any issues and rebuild. If the output
file is locked (open in PowerPoint), write to a new filename.
Use --dry-run on build to preview without writing files.
Image handling
Image scaling — fit vs crop
Picture placeholders should already advertise image in
supported_content_types. Do not patch manifest.yaml unless inspection
output proves the template contract is actually wrong.
The current build behavior defaults to image_fit: fit, which preserves the
full image inside the placeholder. Use image_fit: cover when you explicitly
want crop-to-fill behavior.
slides:
- layout: picture-layout-id
content:
title: Workflow
picture:
kind: image
path: out/diagrams/workflow.png
image_fit: fit
Slide writing principles
These apply to every deck, not just consulting-style ones.
Action titles, not topic labels
Every slide title should state the takeaway — what the audience should conclude — not just name the topic.
- Bad: "Market Overview"
- Good: "Nordic retail margins will remain under pressure through 2027"
One slide, one message
If a slide has two insights, split it into two slides. The body must prove the headline.
Respect placeholder geometry
Never treat placeholder size as flexible. The template geometry is part of the contract.
- If text exceeds the placeholder's likely capacity, shorten it or split it.
- If a table or chart needs more room, switch to a layout with a larger object placeholder.
- If a diagram becomes unreadable at the placeholder's size, simplify the diagram rather than shrinking text and shapes until they are illegible.
Source attribution
Data-driven slides need source lines. Use the source placeholder when
available.
Storyline coherence
A reader should be able to read only the slide titles, in order, and understand the full argument.
For full consulting-style guidance including the Pyramid Principle, MECE
structuring, ghost decks, slide archetypes, and executive summary
construction, read references/mckinsey-style.md.
Layout selection guide
Match content to the right layout:
| Content type | Suggested layout patterns |
|---|---|
| Opening / title (no image) | front-page-title-and-pattern layouts |
| Opening / title (with image) | front-page-title-and-picture layouts (see Background image warning below) |
| Agenda / TOC | agenda layouts (one item per line — see Agenda formatting below) |
| Section divider | breaker layouts |
| Single topic with bullets | title-and-content |
| Side-by-side comparison | two-contents |
| Topic with description header | title-description-and-content |
| Image with explanation | picture-right-text-and-box (or similar) |
| Minimal / custom | title-only or blank-with-logo |
| Closing | end-slide layouts |
When a template has numbered variants (e.g., 1-title-and-content,
2-title-description-and-content), inspect the placeholders of each to
understand the differences. Numbered variants often differ in placeholder
arrangement, background color, or description fields.
Background image warning — front-page-title-and-picture layouts
On front-page-title-and-picture layouts, the picture placeholder spans
the full slide and the title/subtitle render on top of the image.
This means:
- Use abstract, low-detail images only — blurred photos, gradients, subtle textures, or simple geometric shapes.
- Never use information-dense diagrams (with text labels, data, or fine details) as the background image. The title text will collide with diagram labels, making both unreadable.
- Reserve detailed diagrams for
picture-right-text-and-boxwhere the image sits alongside text, not beneath it. - If you must use a diagram, design it as an ambient background: large shapes only, no text, muted/faded colors at low opacity.
Agenda formatting
Agenda layouts expect one item per line, not a pipe-delimited string. The layout may auto-number items. Do not add numbered prefixes yourself.
# WRONG — renders as a single cramped line
content_1: "Foundations | Modern Patterns | Cloud-Native | Serverless"
# CORRECT — each item on its own line
content_1: |
Foundations
Modern Patterns
Cloud-Native
Serverless
AI-Native
What's Next
Series 2 (white) vs Series 3 (sand) layouts
When a template offers both white-background (series 2) and sand-background (series 3) variants of the same column layout:
| Visual intent | Use |
|---|---|
| Standard content slides | Series 2 (white background) |
| Highlighted or callout content | Series 3 (sand background) |
| Visual rhythm in long decks | Alternate between series 2 and 3 per section |
Do not mix white and sand variants within the same logical section — pick one per section and stay consistent.
Front-page variant differences
Front-page layouts with the same column count may differ in subtitle
placement. For example, variant 1 may place the subtitle above the
title while variant 2 places it below. Always inspect placeholders
(top_emu values) to understand the visual order before authoring content.
End-slide positioning
End-slide layouts typically position the title left-of-center with the right portion of the slide empty. Keep closing titles short (1-3 words like "Thank you" or "Questions?") for visual balance.
Quick reference — common commands
# One-time setup
pptx init <template.pptx> --out ./manifest-dir --format json
pptx doctor --manifest ./manifest-dir --format json
# Inspection (safe to parallelize)
pptx layouts list --manifest ./manifest-dir --format json
pptx placeholders list <layout-id> --manifest ./manifest-dir --format json
pptx theme show --manifest ./manifest-dir --format json
pptx assets list --manifest ./manifest-dir --format json
# Single slide (quick test)
pptx slide create --manifest ./manifest-dir --layout <id> --set title="Hello" --notes-file ./speaker-notes.md --out slide.pptx
# Full deck
pptx deck build --manifest ./manifest-dir --spec deck.yaml --out deck.pptx --format json
pptx validate --manifest ./manifest-dir --deck deck.pptx --strict --format json
# Diagrams
excal validate diagram.excalidraw
excal render diagram.excalidraw --outDir ./out --png --scale 4 --no-background
# Template versioning
pptx manifest diff ./v1-manifest ./v2-manifest --format json
Error handling
All pptx commands return JSON envelopes with ok, errors, and exit codes:
| Exit code | Meaning |
|---|---|
| 0 | Success |
| 10 | Validation error (bad layout, missing placeholder, wrong content type) |
| 20 | Policy error |
| 40 | Conflict (output file exists / locked) |
| 50 | I/O error (file not found) |
| 90 | Internal error |
If output file is locked (exit code 40 or PermissionError), write to a different filename — do not retry.
All excal errors also return JSON envelopes. Key codes: exit 10 for
invalid scene JSON, exit 20 for render failures, exit 50 for I/O errors.