Full SKILL.md

Deck Generator

Generate a PowerPoint deck from a content brief or markdown file, using your own brand template. Selects the right named layout per slide and fills its placeholders; all fonts, sizes, and colours inherit from the template master and are never set in code, so the output is always on-brand. Trigger when the user wants to build, draft, or assemble a deck / presentation / slides from content, an outline, or a doc against a corporate template.

Builds a deck by selecting the template's named layouts and filling their placeholders. Styling is inherited, never written: the master defines the brand font, the title colour, the body-size ladder, and every background variant. The generator only chooses layouts and drops in text. Pair it with its sibling style-extractor to learn from the edits you make by hand — together they form a generate → edit → learn → fix-at-source loop.

Preconditions

  • template.pptx (or .potx) — your brand template.
  • layout_map.json — built once from that template (see Setup).
  • A content source: a content.md (preferred), or a brief/doc the model first converts into content.md.

If layout_map.json is missing or older than the template, rebuild it first.

Reference map

Load the one reference that matches the task — don't pull both in at once.

Setup (run once per template)

pip install python-pptx lxml --break-system-packages
python scripts/build_layout_map.py template.pptx .

This emits LAYOUT_MAP.md (human reference — read it to choose layouts) and layout_map.json (the field map the generator reads). It also flags any decoy themes and legacy "Section Divider 1–8 / Section Header" layouts, which must not be used (lorem leftovers). A worked sample of both is in references/ and layout_map.json.

Generate

python scripts/generate_deck.py template.pptx content.md out.pptx layout_map.json

The generator clears the template's demo slides, then for each block: selects the layout, fills named placeholders by idx, and lets styling inherit. It prints warnings for fields that don't exist on the chosen layout or that land on picture/object placeholders (which hold images/charts, not text). See examples/sample_content.md for a runnable input and examples/example_output.pptx for an illustrative result.

Adding elements beyond the placeholders

When content needs a chart or callout the layout doesn't provide, add it but derive ALL formatting from the template — never literal hex or font names:

  • Colours: reference theme slots from layout_map.json palette and set them as theme colours, so the link survives a re-theme.
  • Text formatting on an added box: copy an existing placeholder's run formatting rather than setting Pt()/RGBColor in code.

A literal font or hex anywhere is a defect: it reintroduces the drift the template prevents, and the extractor will start logging deltas against the generator's own inventions.

QA (required)

Render and inspect before declaring done:

soffice --headless --convert-to pdf out.pptx
rm -f slide-*.jpg && pdftoppm -jpeg -r 110 out.pdf slide

Inspect with fresh eyes (a subagent). Font caveat: if the QA environment lacks the brand font, LibreOffice substitutes a different-width font, so text-fit checks are approximate — add ~10% slack and trust the real PowerPoint render. Check layout selection, placeholder fill, overflow, and that no demo slides remain.

Known limitations

  • Picture/object placeholders are left empty (they need an image/chart). Fill them in PowerPoint, or extend the generator to insert via insert_picture.
  • Outline level 0 in a body placeholder inherits the template's plain body style, not a distinct "heading" treatment. If a bold/coloured heading is wanted, that's a manual edit — and a candidate the extractor will learn (or a signal to add a heading style to the template).
  • lib/pptx_master.py is duplicated in both skills so each is self-contained. If you change it, copy it to both lib/ folders.