acn-slide-gen — Pipeline
/acn-slide-gen:generate runs a deterministic 6-phase pipeline. Each phase consumes the previous phase’s output. The pipeline drives toward a self-contained Python script that python-pptx executes against the chosen flavor’s template.
flowchart LR
P0["Phase 0<br/>Decrypt"] --> P1["Phase 1<br/>Inspect Template"]
P1 --> P2["Phase 2<br/>Reason About Layout"]
P2 --> P3["Phase 3<br/>Parse Content"]
P3 --> P4["Phase 4<br/>Generate Python Script"]
P4 --> P5["Phase 5<br/>Verify Output"]
Phase 0 — Decrypt
Section titled “Phase 0 — Decrypt”Resolve the source PPTX path and confirm it’s readable.
- New Deck Mode: look up
--flavorin the registry, resolve totemplate.pptx - Modify Mode: use the
<deck.pptx>argument directly - Locate a venv (
.venv-pptx/→.venv/→ any with python-pptx), or fall back to creating/tmp/.venv-pptx - Run
${CLAUDE_PLUGIN_ROOT}/scripts/decrypt_pptx.py "<path>"and handle exit codes 0/1/2/3 (decrypted / not-found / password-fail / DRM-blocked)
Phase 1 — Inspect Template
Section titled “Phase 1 — Inspect Template”Extract shape geometry and theme tokens.
inspect_slide.py "<path>" <slide_number> --json→ shape inventory with EMU coordinates and propertiesinspect_theme.py "<path>" --json→ theme color and font tokens- Read the active flavor’s
brand.mdfor branding rules
Phase 2 — Reason About Layout
Section titled “Phase 2 — Reason About Layout”Classify each shape into a semantic role: brand-label, section-label, title, description, content-card, divider-line, footer-banner, footer-item, background-shape, image, unknown. Tag each as static, parameterized, or repeating. New Deck Mode also catalogs all available layouts and maps content sections (# → cover, ## no body → divider, ## with body → content).
Phase 3 — Parse Content
Section titled “Phase 3 — Parse Content”Map markdown to layout zones.
##heading → slide boundary + title zone- First short line after heading → section-label
- Paragraphs → description
###sub-sections / bullets → content-cards or footer-items- Bold-prefixed bullets (
**Title**: description) split into card title + body - Image input: read via Claude vision, infer headings, bullets, and sections, map to zones
- Overflow: split across multiple slides, append
(1/2),(2/2)suffixes - Underflow: leave card slots unfilled (don’t insert empty shapes)
Phase 4 — Generate Python Script
Section titled “Phase 4 — Generate Python Script”Write a self-contained script to /tmp/slide_gen_<timestamp>.py that:
- Defines EMU constants from Phase 1 coordinates
- One
xml_<role>()f-string function per shape role - Uses
schemeClrreferences — never hardcoded RGB — so shapes inherit theme color - Strict border rule: never use
<a:ln><a:solidFill/></a:ln>(empty solidFill inherits theme line color and produces unintended outlines); explicit color inside<a:solidFill>when a border is intended - Helpers:
_uid(),_esc(),_ext()for IDs, escaping, creation IDs build_slide()assembles shapes ontoslide.shapes._spTreereorder_slides()if--afteris specified
Branding compliance is verified pre-write against the flavor’s brand.md (fonts, colors, sentence-case headlines, left-aligned text, highlight rules, layout selection, color proportions).
Phase 5 — Verify Output
Section titled “Phase 5 — Verify Output”After the script runs, confirm slide count, per-slide shape count, and (if --after was used) slide ordering. Branding spot-check on cover layout, structural markers, and one content slide’s font and color compliance against brand.md.
The generated script is preserved at /tmp/slide_gen_*.py for debugging and reuse.
Pipeline scripts
Section titled “Pipeline scripts”Three Python helpers ship in ${CLAUDE_PLUGIN_ROOT}/scripts/:
decrypt_pptx.py— strip DRM from password-protected files; exit codes signal statusinspect_slide.py— dump layout geometry and shape properties to JSONinspect_theme.py— extract theme color and font tokens
The scripts are flavor-agnostic. Flavor specifics live in assets/flavors/<flavor>/brand.md — see Flavors.