Keynote Deck Generator
Turns markdown into a native .key file by pouring content into a branded Keynote template. The model's job is CONTENT ONLY — structure, wording, speaker notes. All visual design lives in the Keynote template's master slides, so never attempt layout, colors, or fonts here.
Pipeline
deck.md ──▶ scripts/generate.sh ──▶ Keynote (AppleScript/md2key) ──▶ deck.key + preview PNGs
Run: ~/.claude/skills/keynote-deck/scripts/generate.sh <markdown-file> [output.key]
The script pins the Homebrew Ruby and md2key paths, launches Keynote by bundle
id (com.apple.Keynote), opens a copy of the user's template, converts, saves,
and exports preview PNGs next to the output.
Workflow
- Locate or author the markdown. If given a file, use it. If given a topic/outline, author the deck markdown first (see Authoring rules) and show it to the user before generating.
- Generate: run
generate.sh deck.md output.key. - Verify — never skip. Read 2–3 of the exported preview PNGs (cover, a code slide, the densest bullet slide). Check for: text overflowing its box, code wider than its panel, tables too tall, orphaned single-word bullet wraps. If found, tighten the markdown (shorter bullets, split slide, trim code) and regenerate. One regeneration pass is normal.
- Report the .key path. The document is left open in Keynote for hand-tweaks.
Authoring rules
Structure:
# Title— first heading becomes the cover slide; the line(s) after it become the cover body (subtitle).- One heading per slide. One idea per slide.
^ note text— presenter note. Every content slide gets one: 2–4 conversational sentences the presenter can speak. For course/video decks this doubles as the narration script.---separators are optional; headings define slides.
Heading level → master slide (the template names its masters cover, h1–h5):
| Markdown | Master | Suggested role |
|---|---|---|
# (first) |
cover |
cover slide |
# (mid-deck) |
h1 |
section divider |
## |
h2 |
content — light |
### |
h3 |
code — dark |
#### |
h4 |
content — dark |
##### |
h5 |
code — light |
The light/dark pairing is the recommended convention (decks can run all-light, all-dark, or alternating) — but the template owner decides what each master looks like; follow whatever their template does.
Density limits (Keynote boxes don't auto-shrink — overflow is the #1 failure):
- ≤ 5 bullets per slide, ≤ 8 words per bullet, ≤ 1 nesting level.
- Code blocks: ≤ 12 lines, ≤ 60 columns. Longer code → split across slides
("part 1 / part 2") or trim to the teaching-relevant lines with
# .... - Tables: ≤ 4 columns, ≤ 5 rows.
- No inline bold/italic/links — md2key pastes plain text; styling comes from masters. Write so emphasis isn't needed.
Supported content per slide (title + ONE of these works best):
- Bullet list (with one nesting level)
- Fenced code block — syntax-highlighted via
highlight(dark panel) - Markdown table
- Image:
 ```mermaidblock — rendered to a diagram (requiresmmdc; if missing, pre-render to PNG and use an image instead)
Deck conventions:
- Open with a cover (
# Deck Title+ subtitle line). - Second slide: agenda or "What you'll learn" — 3–5 bullets.
- Close with a recap/summary slide.
- Prefer many light slides over few dense ones — slides are glanceable signposts, not documents.
Template
Template resolution order (generate.sh handles this):
$KEYNOTE_DECK_TEMPLATEenv var./keynote-template.keyin the current project~/.claude/skills/keynote-deck/templates/default.key- Fallback: stock "White" theme (warn the user output is unbranded)
The template is a normal .key file whose master slides are named cover,
h1–h5 (lowercase, exact). If the user has no template yet, offer to help
them build one — the full method (designing background art with Claude,
rendering it, assembling masters) is in TEMPLATE-GUIDE.md in this skill's
directory. Design changes belong in the template's masters, never compensate
for design issues in markdown.
Requirements & troubleshooting
- Deps: Homebrew Ruby,
md2keygem,highlight(brew). generate.sh checks and prints install commands if missing. - Keynote must be allowed Automation permission for the shell (macOS prompts on first run — user must click Allow).
- md2key drives the front document; tell the user not to click around Keynote mid-generation.
- Code slides: generate.sh auto-patches md2key (idempotently) to use this skill's 1740×800 code panel at position {90, 170}, and snaps pasted code text to {154, 226}. Only text items below y200 are moved — Keynote counts the title placeholder among "text items" and it must never be repositioned.
- Masters used for code slides should have no body placeholder — an unfilled placeholder exports its prompt text onto the slide.
- If AppleScript errors after a macOS/Keynote update, offer the official pptx skill route (.pptx opens in Keynote with minor fidelity loss) as a fallback.