Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
run: |
for f in skills/html-slide-deck/scripts/*.mjs skills/html-slide-deck/references/*.mjs skills/html-slide-deck/references/offline-build-template/scripts/*.mjs; do node --check "$f"; done
node --check skills/html-slide-deck/references/offline-build-template/build.js
node --check demo/build.mjs
grep -q 'POLL_CFG={"sim"' docs/index.html && ! grep -q '"key":' docs/index.html # Live Demo 必須是模擬模式、不含 key
for f in skills/html-slide-deck/references/live-poll/*.mjs skills/html-slide-deck/references/live-poll/screen/*.js skills/html-slide-deck/references/live-poll/worker/src/*.js; do node --check "$f"; done
node -e "JSON.parse(require('fs').readFileSync('skills/html-slide-deck/references/live-poll/worker/src/polls.json','utf8'))"
python -m py_compile skills/html-slide-deck/scripts/montage.py examples/pptx-edits-back-to-html.py
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

- **Live Demo**(GitHub Pages):`demo/` 原始檔 → `docs/index.html`,12 頁示範逐步出現、Auto-Animate、3D 翻卡、頁內測驗、手機投票、滑桿對比;build 時量實際檔案大小當猜數字題的答案。
- 手機投票新增**模擬模式**:`poll-slides.mjs --polls <polls.json> --sim [人數]`,不連後端、不含 key,可公開;`live-poll.js` 依 `POLL_CFG.sim` 自動跑出作答過程。
- 新增 `README.en.md`(英文完整說明)、`SECURITY.md`(漏洞回報、ADMIN_KEY 處理與輪替、QA 會執行 JS);README 開頭放 Live Demo 連結與 45 秒流程 GIF(`docs/demo.gif`)。
- 乾淨環境安裝測試(OrbStack Ubuntu 24.04,照 README 從 clone 到離線 QA、講義、PDF、做法 B 全程):發現 **Node 18 跑不了 Playwright**,需求改為 Node 20+(README 徽章、install.sh 檢查、SKILL.md、engines),疑難排解補上;`build-handout.mjs` 找不到 render 目錄時改成明確錯誤訊息。

## 1.3.0 — 2026-10-18

- 新增觀眾手機即時投票 `skills/html-slide-deck/references/live-poll/`:Cloudflare Worker+Durable Object 後端(手機頁、題目 JSON、WebSocket 推播、斷線輪詢)、投影片端 `screen/live-poll.js`/`.css`、`load-test.mjs`(150 支手機壓測);新腳本 `scripts/poll-slides.mjs` 把占位 section 換成加入頁與投票頁並注入講者端程式。源自 2026-10 學會演講的做法(現場 60 人使用)。
Expand Down
162 changes: 162 additions & 0 deletions README.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<div align="center">

# htmlpptskill

**Tell your AI coding agent "make me an HTML slide deck" and get a deck that plays offline, has every QR code verified, lets the audience vote from their phones, and ships with handout PPTX/PDF.**

Two Agent Skills (open `SKILL.md` format) for Claude Code, Codex CLI, Gemini CLI and Grok Build.

**[▶ Live Demo](https://keanu77.github.io/htmlpptskill/)** · [中文 README](README.md) · [Security](SECURITY.md) · [Changelog](CHANGELOG.md)

<img src="docs/demo.gif" width="760" alt="One prompt, then the deck: fragments, Auto-Animate, 3D flip cards, an in-slide quiz, a live audience poll, screenshot QA and three deliverables">

</div>

> The docs and slide templates are in Traditional Chinese, but the scripts are language-neutral: you can write your slides in any language.

## Why not just PowerPoint?

| Problem | What this repo does |
|---|---|
| No Wi-Fi at the venue: fonts, images and plugins break | `QA_OFFLINE=1` fails on any external request; reveal.js, images and QR codes are inlined into **one HTML file** |
| A misprinted QR code sends the audience to a 404 | QA screenshots **every QR code, decodes it** and compares it with `data-url`; a mismatch exits 1 |
| AI-generated slides overflow or miss speaker notes | Every slide is screenshotted into one `montage.png`; overflow, JS errors and missing notes are listed |
| The organizer wants PPTX, you only have HTML | `render-slides` → `build-handout`: one image per slide, speaker notes in the notes pane; PDF in one command |
| You want the whole room to answer, not one volunteer | **Live audience polling**: scan a QR, vote on the phone, results stream to the slide, press `A` to reveal on every phone |
| The speaker edited the PPTX by hand | A full worked example of pulling the edits back into HTML |

## The two skills

| Skill | What it does | Triggers |
|---|---|---|
| **`html-slide-deck`** | Outline → HTML → QA → delivery: layouts, images, QR codes, interactive pages, live polling, handout PPTX/PDF, native editable PPTX | "make an HTML deck", "reveal.js", "add QR codes", "live poll", "export to PPT/PDF", "offline deck" |
| **`html-slide-effects`** | Fragments, Auto-Animate, 3D flip cards, GSAP text, timer bar, lightbox, scroll view, with a STATIC switch for QA and PDF | "add animations", "flip cards", "make it more engaging" |

## Install (30 seconds)

```bash
git clone https://github.com/keanu77/htmlpptskill.git && cd htmlpptskill
./install.sh # installs into every CLI it detects; existing skills are moved to skills-backup/
```

| CLI | Installed to | How to use |
|---|---|---|
| **Claude Code** | `~/.claude/skills/` | Type `/html-slide-deck`, or just ask for an HTML deck. As a plugin: `/plugin marketplace add keanu77/htmlpptskill` → `/plugin install htmlpptskill@keanu77` |
| **Codex CLI** | `~/.codex/skills/` | Describe the task, or `$html-slide-deck` |
| **Gemini CLI** | `~/.gemini/skills/` | `gemini skills list`; or `gemini skills link <repo>/skills/html-slide-deck` |
| **Grok Build** | `~/.grok/skills/` | Describe the task (it also reads `~/.claude/skills/`) |

One CLI only: `./install.sh codex`. Commit with your project: `./install.sh --project` (installs to `.agents/skills/`).

### Requirements

| Needed for | Install |
|---|---|
| All scripts | Node 20+ (Playwright does not support 18; Ubuntu 24.04's `apt install nodejs` is 18, use nvm or nodejs.org). Node 22+ for the poll load test |
| Screenshot QA, rendering, PDF | `npm i -D playwright && npx playwright install chromium` (Linux servers: also `npx playwright install-deps chromium`) |
| Handout PPTX | `npm i pptxgenjs` |
| QR generation, montage | Python 3 + `pip install -r requirements.txt` (segno, pillow, python-pptx; a venv is recommended) |
| CJK text on Linux | A CJK font, e.g. `fonts-noto-cjk` (otherwise screenshots show boxes) |
| Live polling (optional) | A free Cloudflare account |

Scripts look for `node_modules` **from the working directory upwards**, then in the global npm root; or set `SKILL_PKG_ROOT`.

| Platform | Support |
|---|---|
| macOS | Everything (`pptx-to-pdf.sh` needs Microsoft PowerPoint) |
| Linux | Everything except the native PowerPoint export (use `print-pdf.mjs`) |
| Windows | Run the scripts with `node`; use WSL for `install.sh` or copy `skills\*` manually; set `PYTHON=python` |

## First deck in 10 minutes

```bash
mkdir my-deck && cd my-deck && npm init -y
npm i -D playwright && npx playwright install chromium && npm i reveal.js@5 pptxgenjs
SKILL=~/.claude/skills/html-slide-deck # your CLI's skill path

cp $SKILL/references/reveal-template.html draft.html # 9-slide template; 〈…〉 and example.com are placeholders
node $SKILL/scripts/inline-assets.mjs draft.html index.html # inline reveal.js and images → one offline file
QA_OFFLINE=1 node $SKILL/scripts/qa-screenshots.mjs index.html qa/ # screenshots, QR, overflow → look at qa/montage.png
node $SKILL/scripts/render-slides.mjs index.html render/
node $SKILL/scripts/build-handout.mjs render/ handout.pptx "Speaker" # image handout with notes
node $SKILL/scripts/print-pdf.mjs index.html handout.pdf # PDF handout
```

Or just tell your agent:

> Use html-slide-deck to make a 20-slide deck on "XXX" for residents. No Wi-Fi at the venue; put a QR code on every tool slide.

It proposes an outline table first and waits for your OK, then writes the HTML, runs QA and delivers the files.

## Live audience polling

Used by 60 people at once at a medical conference talk in October 2026, and load-tested beforehand with 150 simulated phones (150 votes written and pushed to the slide in about 0.2–1.2 s).

- The audience scans a QR code: no app, no login, anonymous, answers can be changed until the reveal.
- The slide shows live percentages (multiple choice) or a histogram and median (guess-a-number), plus how many phones are connected.
- Press `A` to reveal: the slide marks the answer and every phone shows it. `Shift+R` clears the votes for that question.
- If the venue network drops, the slide shows a warning, falls back to polling, and `A` still reveals.
- Backend: a Cloudflare Worker + Durable Object (free plan). Deploy it once and then edit only `polls.json`.

```html
<section data-poll-join></section> <!-- join slide: big QR + phones online -->
<section data-poll="warmup"></section> <!-- one question per slide, defined in worker/src/polls.json -->
```
```bash
cp -R $SKILL/references/live-poll/worker my-poll && cd my-poll && npm install
npx wrangler login && npx wrangler secret put ADMIN_KEY && npx wrangler deploy # put the same key in .dev.vars
node $SKILL/scripts/poll-slides.mjs index.html index-live.html --worker my-poll --url https://slide-poll.<subdomain>.workers.dev
Comment on lines +106 to +108

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return to the deck directory before generating polling slides

When a reader runs this new English setup block in one shell session, the first command leaves the shell inside my-poll, so the final command looks for the deck as my-poll/index.html and resolves --worker my-poll as a nonexistent nested directory. End the deployment command in a subshell or cd .. before invoking poll-slides.mjs so the documented workflow can generate the presenter deck.

Useful? React with 👍 / 👎.

```

> **The presenter file `index-live.html` contains the ADMIN_KEY.** Keep it on the presenter's computer only: never publish, email or commit it. See [SECURITY.md](SECURITY.md).

For a public demo, use simulation mode (no backend, no key, safe to publish). The Live Demo is built this way:

```bash
node $SKILL/scripts/poll-slides.mjs index.html demo.html --polls polls.json --sim 60
```

Full setup, question format, API and load test: [`live-poll/README.md`](skills/html-slide-deck/references/live-poll/README.md) (Chinese).

## Shortcuts, transitions and effects

While presenting: `→`/`Space` next, `S` speaker view, `O`/`Esc` overview, `F` fullscreen, `B` black screen, `G` go to slide, `A` reveal (poll slides), `?` all shortcuts. Append `?print-pdf` to print, `?view=scroll` to read on a phone.

All effects come with copy-paste code in [`docs/TECHNIQUES.md`](docs/TECHNIQUES.md) (Chinese): fragments, Auto-Animate, 3D flip cards, card-wall fly-in, GSAP letter-by-letter text, Three.js cover particles, spotlight, timer bar, lightbox, in-slide quiz, live polling, interactive map, and a STATIC switch so QA screenshots and PDFs capture the final state.

## Rules learned the hard way

- **Agree on the outline before any HTML.** Regenerating 50 slides costs ten times more than aligning an outline.
- **QA is mandatory, and you must look at the images.** Open `montage.png` first, then the flagged slides; verify again after fixing.
- **Every QR code needs a `data-url`.** Without it QA cannot compare; placeholder URLs (example.com) trigger warnings.
- **Assume the venue has no internet.** Run `QA_OFFLINE=1` before delivery; use system fonts instead of Google Fonts.
- **Ask before deploying or creating a repo.** The skills never push anything to the public web on their own.
- **The QA scripts execute the deck's JavaScript.** Run them only on HTML you generated.

## Troubleshooting

| Symptom | Fix |
|---|---|
| `Playwright requires Node.js 20 or higher` | Upgrade Node (nvm or nodejs.org); Ubuntu 24.04's apt package is 18 |
| `找不到套件 playwright` (package not found) | Run from a directory with `node_modules`, or `npm i -g playwright`, or set `SKILL_PKG_ROOT` |
| `缺 jsqr/pngjs` | Run `npm install` in the skill directory, or set `QA_SKIP_QR=1` explicitly |
| Chromium not downloaded | `npx playwright install chromium`; or point `CHROMIUM_PATH` at an existing Chromium/Chrome |
| Chinese text renders as boxes (Linux) | Install Noto Sans CJK |
| Sites like PubMed return 403 to headless browsers | Ask the user for a screenshot |
| PDF has more pages than slides | `pdfSeparateFragments: false` in `Reveal.initialize` (already set in the templates) |
| Poll votes stay at 0 in your own tests | Voter IDs must be 8–64 characters `[a-z0-9-]` |
| `wrangler dev` will not start | `compatibility_date` is newer than your local workerd; move it back |

## Repository layout

```
skills/html-slide-deck/ main workflow: SKILL.md, scripts/, references/ (templates, live-poll/, pitfalls, design principles)
skills/html-slide-effects/ effects skill
demo/ Live Demo source → docs/index.html (GitHub Pages)
examples/ a 50-slide workshop deck, PPTX-edits-back-to-HTML example, Three.js particles
docs/ TECHNIQUES.md, images, Live Demo build
```

## About

The author is a sports medicine physician who built these skills while preparing workshop and conference talks, then had four models (Codex, Claude, Grok, Gemini) review them. MIT licensed. The template text, URLs and screenshots in `examples/` are samples to replace.
28 changes: 24 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@

# htmlpptskill

**跟 AI 說一句「做一份 HTML 簡報」,拿到能離線播、QR 驗過、還附講義 PPTX/PDF 的成品。**
**跟 AI 說一句「做一份 HTML 簡報」,拿到能離線播、QR 驗過、觀眾能用手機投票、還附講義 PPTX/PDF 的成品。**

### [▶ 打開 Live Demo,直接操作](https://keanu77.github.io/htmlpptskill/)

<sub>這份 12 頁的 Demo 就是用這個 skill 做的:逐步出現、Auto-Animate、3D 翻卡、頁內測驗、手機投票(模擬 60 人)、滑桿對比。279 KB 單檔,電腦按 → 翻頁。</sub>

[English README](README.en.md) · [安全說明](SECURITY.md)

reveal.js 簡報製作流程,包成兩個 Agent Skill。<br>
Claude Code・Codex CLI・Gemini CLI・Grok Build 都能裝。<br>
安裝後的 skill 內建作者的固定規則(`references/fixed-rules.md`)與規劃設計原則(`references/design-principles.md`);X 上分享的簡報技巧整理見 [docs/html-slides-tips-from-x-2026-10-17.md](docs/html-slides-tips-from-x-2026-10-17.md)。

[![CI](https://github.com/keanu77/htmlpptskill/actions/workflows/ci.yml/badge.svg)](https://github.com/keanu77/htmlpptskill/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-teal.svg)](LICENSE)
![Node 18+](https://img.shields.io/badge/Node-18%2B-3FC1B7)
![Node 20+](https://img.shields.io/badge/Node-20%2B-3FC1B7)
![Agent Skills](https://img.shields.io/badge/Agent%20Skills-SKILL.md-F2B84B)

<img src="docs/demo.gif" width="760" alt="一句話 → Demo 操作 → 逐頁 QA → HTML、PDF、PPTX 三種交付">

<sub>45 秒看完流程:一句話、逐步出現、Auto-Animate、翻卡、測驗、手機投票、QA、三種交付。</sub>

<img src="docs/showcase.png" width="900" alt="封面逐字浮現、3D 翻卡、頁內可作答的測驗、雙 QR 工具頁">

<sub>實際講座成品:封面 GSAP 逐字浮現、七張卡片一次翻面、頁內真的能作答的測驗、網站+repo 雙 QR。54 頁、3 MB、拔掉網路照樣播。</sub>
<sub>另一份實際講座成品:封面 GSAP 逐字浮現、七張卡片一次翻面、頁內真的能作答的測驗、網站+repo 雙 QR。54 頁、3 MB、拔掉網路照樣播。</sub>

<p>
<a href="#30-秒安裝">安裝</a> · <a href="#10-分鐘看到第一份成品">10 分鐘上手</a> · <a href="#-現場互動手機投票互動地圖">現場互動</a> · <a href="#-快捷鍵換場與動畫技巧">快捷鍵、換場與動畫技巧</a> · <a href="#疑難排解">疑難排解</a>
Expand Down Expand Up @@ -151,7 +161,13 @@ npx wrangler login && npx wrangler secret put ADMIN_KEY && npx wrangler deploy
node $SKILL/scripts/poll-slides.mjs index.html index-live.html --worker my-poll --url https://slide-poll.<子網域>.workers.dev
```

產出的 `index-live.html` 內含講者控制用的 ADMIN_KEY,**只放講者電腦**;要分享的版本用原本的 `index.html`。
產出的 `index-live.html` 內含講者控制用的 ADMIN_KEY,**只放講者電腦**;要分享的版本用原本的 `index.html`,詳見 [SECURITY.md](SECURITY.md)。

要公開展示(像 Live Demo)就用模擬模式:不連後端、不含 key,進到投票頁自動跑出作答過程,`A` 一樣能揭曉。

```bash
node $SKILL/scripts/poll-slides.mjs index.html demo.html --polls polls.json --sim 60
```

### 互動地圖與製作技巧頁

Expand Down Expand Up @@ -634,6 +650,9 @@ examples/
workshop-2026/content.js 50 頁工作坊完整內容
pptx-edits-back-to-html.py 講者在 PPTX 手改後回灌 HTML+全部效果的實例(見 examples/README.md)
docs/TECHNIQUES.md 快捷鍵、換場、動畫技巧參考(附程式碼)
docs/index.html Live Demo 成品(GitHub Pages;原始檔在 demo/,cd demo && npm i && npm run build)
demo/ Live Demo 原始檔:src/index.html、polls.json、build.mjs
README.en.md、SECURITY.md 英文說明、安全說明(ADMIN_KEY、QA 會執行 JS、漏洞回報)
docs/html-slides-tips-from-x-2026-10-17.md X 使用者分享的 HTML 簡報技巧與工具整理(含來源連結)
docs/*.png 成果圖
.claude-plugin/ Claude Code plugin/marketplace 設定
Expand All @@ -644,6 +663,7 @@ AGENTS.md、CLAUDE.md 給在本 repo 工作的 agent

| 現象 | 處理 |
|---|---|
| `Playwright requires Node.js 20 or higher` | Node 太舊。Ubuntu 24.04 的 `apt install nodejs` 是 18,改用 nvm 或 nodejs.org 的 Node 20+ |
| `找不到套件 playwright` | 在有 `node_modules` 的專案目錄執行,或 `npm i -g playwright`,或設 `SKILL_PKG_ROOT` |
| `缺 jsqr/pngjs` | 到 skill 目錄 `npm install`;或 `QA_SKIP_QR=1` 明確略過 |
| Chromium 沒下載 | `npx playwright install chromium`;已有 Chromium 就設 `CHROMIUM_PATH` |
Expand Down
Loading
Loading