claude-skills/markdown-html/commands/cs-md-slides.md
Claude 5c2115dad5
feat(markdown-html): add md-slides v2.10.3 — markdown deck → single-file HTML presentation
Completes the markdown-html/ domain at 5 skills. The Tier-3 use case from
Shihipar's essay ("Slide Decks"): a markdown deck (slides separated by
--- HR boundaries or # H1 headings, with optional <!-- notes: ... -->
presenter notes blocks) becomes a single-file HTML presentation with
keyboard nav, presenter mode, and print-to-PDF.

Three stdlib tools pipeline together:

1. slide_splitter.py — splits markdown on --- HR or # H1 boundaries
   (or --boundary auto: HR wins ≥ 3, else H1 ≥ 5). Extracts the first
   heading per slide as the title. Hard rule: refuses 1-slide decks
   (exit 5 — it's a poster) and no-boundary input (exit 6 — route to
   md-document). Soft-warns slides > 40 source lines (signal-to-noise;
   renders anyway).

2. presenter_notes_parser.py — extracts <!-- notes: ... --> blocks
   (also speaker-notes: and presenter: aliases) per slide, attaches
   as a separate `notes` field, strips from body. Tracks
   notes_coverage_pct for the optional --strict-notes gate (refuses
   < 50% coverage when presenter mode is essential).

3. deck_html_renderer.py — single-file HTML deck. All slides as
   <section class="slide"> elements, one visible at a time (CSS-
   controlled). Vanilla JS keyboard handlers: → / Space / PgDn advance;
   ← / PgUp previous; Home / End first/last; P toggles presenter mode;
   Esc exits presenter. URL-hash deep linking (#3 jumps to slide 3,
   back/forward walks slides). Progress bar at top (3px); slide counter
   bottom-right. Presenter mode = split view: current slide (60% width)
   + panel (40% width with clock + speaker notes + next-slide preview).
   @media print { section { display: block; page-break-after: always; } }
   → Cmd+P produces PDF with one slide per page. prefers-reduced-motion
   honored throughout. Reuses md-document/scripts/markdown_parser.py
   for slide-body content (consistent paragraphs / lists / code / tables
   / callouts). Prism.js is OPT-IN via --syntax (off by default — most
   decks don't need it; keeps the file tiny).

Plus 3 references each citing 5-7 sources:
  - presentation_ux.md — Atkinson Beyond Bullet Points + Reynolds
    Presentation Zen + Tufte Cognitive Style of PowerPoint + NN/g +
    Weinschenk + Marp/reveal.js/Big convergence + Tom MacWright
  - keyboard_nav_patterns.md — reveal.js/Big/Spectacle keymap + WCAG
    2.1.1 + 2.4.3 + MDN KeyboardEvent + NN/g keyboard accessibility
  - single_file_deck_conventions.md — Big + Marp + Pandoc + reveal.js
    standalone + WCAG 2.3.3 + @media print
1 template asset documenting the canonical single-file deck shape.
/cs:md-slides slash command with 6 pre-flight gates + pipeline +
output digest.

Repo-level updates:
- markdown-html/.claude-plugin/plugin.json: skills array adds
  ./skills/md-slides; version 2.10.2 → 2.10.3; description marks
  domain COMPLETE at 5 skills.
- .claude-plugin/marketplace.json: markdown-html-skills entry version
  and description (domain complete); top-level counters 342 → 343
  skills, 545 → 548 Python tools, 688 → 691 references, 89 → 90 slash
  commands; metadata.version 2.10.2 → 2.10.3.
- Root CLAUDE.md: v2.10.3 release-notes block above v2.10.2.

Validation:
- check_plugin_json.py → OK
- sync-codex-skills.py --dry-run → 1 new symlink, documentation:
  5 skills, total 345
- skill_description_validator.py → PASS (all 5 checks: present,
  826/1024 chars, third-person, trigger "use after", action verb
  "Convert")
- skill_review_checklist_runner.py → 5/6 PASS (under-100-lines warns
  at 102; same advisory as md-document SKILL.md)
- All 3 tools pass --help and --sample
- Hard rules verified end-to-end:
    no-boundary input → exit 6 with md-document routing hint
    1-slide deck → exit 5 with poster recommendation
    --strict-notes with < 50% coverage → exit 7
- Full pipeline on 5-slide sample deck (3 with presenter notes)
  produces 12.2 KB single-file HTML with all 16 expected components
  (slide-1 + slide-5 anchors, notes attribute populated, P-key
  handler, arrow nav, @media print, page-break-after, presenter
  panel + clock + next-preview, palette tokens, progress bar, title
  in header, "1 / 5" counter, history.replaceState URL hash sync,
  prefers-reduced-motion).

Domain status: COMPLETE. All 5 planned skills shipped across 4 PRs
(#780 foundation, #793 md-document, #795 md-review, this PR md-slides).
The markdown-html/ domain operationalizes Shihipar's central claim —
markdown collapses past 100 lines; HTML restores density, clarity,
shareability, and lightweight interaction — across all three layout
families (long-form documents, code reviews, slide decks).

https://claude.ai/code/session_01BK2KoQot1U7J5oSosrCQdc
2026-06-03 05:55:58 +00:00

79 lines
4.1 KiB
Markdown

---
description: Convert a markdown deck (slides separated by --- HR boundaries or by # H1 headings, with optional <!-- notes: ... --> presenter notes blocks) into a single-file HTML presentation with arrow-key navigation, presenter mode (split view with current slide + notes + clock + next-slide preview), URL-hash deep linking, and @media print page-per-slide for PDF export. Refuses 1-slide decks (it's a poster) or inputs without clear boundaries. Single-file output; Google Fonts CSS is the only external (Prism is opt-in via --syntax).
argument-hint: "<path to markdown deck> [--boundary auto|hr|h1] [--title \"My Talk\"] [--syntax] [--strict-notes]"
---
# /cs:md-slides — Markdown deck → single-file HTML presentation
Convert the markdown deck at **$ARGUMENTS** into a single-file interactive HTML presentation.
## Pre-flight gates (refuse, never override)
1. **Input < 100 lines** → refuse (markdown wins below Shihipar's threshold).
2. **Design-system not onboarded** → refuse, surface `/cs:design-system`.
3. **No clear slide boundaries** (auto mode: need ≥ 3 HR or ≥ 5 H1) → refuse, route to md-document.
4. **1-slide deck** → refuse (it's a poster, not a deck).
5. **`--strict-notes` with < 50% notes coverage** → refuse.
6. **Output directory unwritable** → refuse, ask user for `--out`.
## Pipeline
```bash
# 1. Resolve output path (doctype=slides → deck- prefix)
python3 markdown-html/skills/markdown-html-orchestrator/scripts/output_path_resolver.py \
--input "<path>.md" --doctype slides
# 2. Split slides on --- HR or H1 (auto-detect)
python3 markdown-html/skills/md-slides/scripts/slide_splitter.py \
--input "<path>.md" --boundary auto --output /tmp/slides.json
# 3. Extract <!-- notes: ... --> blocks per slide
python3 markdown-html/skills/md-slides/scripts/presenter_notes_parser.py \
--slides /tmp/slides.json --output /tmp/deck.json
# 4. Render single-file HTML deck
python3 markdown-html/skills/md-slides/scripts/deck_html_renderer.py \
--slides /tmp/deck.json --title "<deck title>" \
--output <resolved-out>.html
```
## What ships in the HTML
- **All slides as `<section class="slide">`** with one visible at a time (CSS-controlled, no JS-required content)
- **Keyboard navigation**:
- `→` / `Space` / `PgDn` → next slide
- `←` / `PgUp` → previous slide
- `Home` / `End` → first / last slide
- `P` → toggle presenter mode
- `Esc` → exit presenter mode
- **Presenter mode** — split view: current slide (60% width) + panel (40% width with clock + speaker notes + next-slide preview)
- **URL-hash deep linking** — `#3` jumps to slide 3; back/forward walks slides; share `deck.html#5` to land on slide 5
- **Progress bar** at top (3px); slide counter in bottom-right
- **Print-to-PDF** via browser's native print dialog: `@media print` makes each slide one page (`Cmd+P` / `Ctrl+P`)
- **`prefers-reduced-motion`** honored
- **12 brand CSS tokens** from design-system; design_style affects layout density
## Hard rules
- Output is one `.html` file. No multi-file output.
- External CDN: `fonts.googleapis.com` always; `cdn.jsdelivr.net` (Prism) only when `--syntax` is passed.
- No JS framework runtime. Vanilla JS + keyboard event handlers.
- Re-running on the same input writes `deck-{slug}-2.html` etc.
## Useful flags
- `--boundary {auto,hr,h1}` — slide boundary mode (default: auto)
- `--title "My Talk"` — sets the `<title>` and tab name
- `--syntax` — enable Prism.js CDN for code blocks (off by default; decks rarely need it)
- `--strict-notes` — refuse if < 50% of slides have presenter notes (use when presenter mode is essential)
## Output
Returns: slide count, notes coverage %, output path, design style applied, top features used, one forcing question.
## References
See `markdown-html/skills/md-slides/references/`:
- `presentation_ux.md` — Atkinson + Reynolds + Tufte + NN/g + Weinschenk + Marp/reveal.js/Big convergence
- `keyboard_nav_patterns.md` — reveal.js / Big / Spectacle keymap + WCAG 2.1.1 + 2.4.3 + MDN KeyboardEvent
- `single_file_deck_conventions.md` — Big + Marp + Pandoc + WCAG 2.3.3 + @media print