Meetup Deck
把「一個月的技術動態」變成一份能上台、能分享、能查證的 HTML 簡報。
輸出是單一自包含 HTML + assets 資料夾:無框架、無 build step、離線可跑、 可直接部署成網址。
什麼時候用
- 每月社群小聚要報告「這個月發生了什麼」
- 把一段時間的產業動態整理成投影片
- 已經有簡報,要改版面 / 補素材 / 加頁 / 部署
不適用:純文字的月報文章、需要正式排版的長文件(那些用文件排版工具,不要用投影片引擎)。
流程
1. 取材
先讀 references/source-recipes.md。裡面是實測過的抓取方式,包含
Reddit / YouTube / Medium / GitHub / 會議官網在「常規做法被擋」之後的可行路徑。
遇到抓不到不要重新試錯,先查那份。
鐵則:
- 版本號一律來自官方機器可讀來源(releases JSON / CHANGELOG),不要信文章
- 每支影片都要查
uploadDate確認屬於本期,RSS 會混進舊片 - 每個數字都要能指回一個 URL
- 抓不到就在投影片上寫明缺口,不要用推測填
同時把素材下載到本機 assets/(yt/ 縮圖、img/ 文章封面與 OG、demo/ 專案示範、
vid/ 影片、spk/ 講者頭像)。素材必須離線可用,會場網路不能賭。
批次下載用 scripts/harvest_media.py,吃一份 JSON manifest:
python3 scripts/harvest_media.py manifest.json --root assets
支援 youtube(maxres 失敗自動退 hqdefault)、github(OG 卡,自動節流避開 429)、
readme(掃 repo README 找 demo gif/webp,會跳過 shields.io badge)、url(直連)。
2. 決定內容與排序
按「聽眾會關心的程度」排,不是按時間。通常是:
開場(總覽 / 三條主線)
官方(版本、部落格、repo 動態)
大事件(會議、發表會)
本月最亮眼的專案(給它兩三頁,不要跟其他擠一頁)
生態與社群(企業案例、熱門討論、開源專案)
收尾(行事曆、數字回顧)
用 data-sect 標章節,data-title 給總覽用的短標。
3. 做投影片
從 assets/deck-template.html 複製,照 references/slide-patterns.md 選版面。
兩條會被退稿的規則:
- 每頁都要有讓人秒懂的視覺。 把說明文字遮住,看得出這頁在講什麼嗎? GitHub OG 卡(只有作者頭像)不算,要找 README 裡的 demo GIF、實際畫面、產品錄影。
- 不要寫自己的想法。 句子裡有「我覺得 / 訊號是 / 值得注意的是 / 分界線 / 敘事」 就先假設要刪。留下來的是「誰、何時、做了什麼、數字多少」—— 但也要給 1–2 句補充事實,不能只剩關鍵字。
細節與反例在 references/slide-patterns.md。
4. 驗證(不可跳過)
python3 scripts/verify_deck.py path/to/slides.html
會起 localhost、走過每一頁、報三種實際會發生的問題:
- overflow — auto-fit 縮到 < 0.85,表示這頁塞太多,該拆頁不是靠縮放
- broken assets — 圖片或影片 404
- orphan lines — 標題斷行留下 1–2 個孤兒字
並產出 contact sheet 供目視檢查。看過那張圖再說「做好了」。
有 exit code:0 乾淨 / 1 有問題。
5. 字體離線化
python3 scripts/refresh_fonts.py path/to/slides.html
掃出簡報實際用到的字元,產生子集 woff2 進 assets/fonts/ 並改寫 @font-face,
移除 CDN 連結。會場沒網路才不會 fallback 成系統字。
⚠️ 改完投影片文字要重跑,否則新增的字會缺字。
6. 部署
讀 references/publish.md。重點:
- 現場放映用
assets/serve.sh走 localhost(複製到簡報資料夾) —— YouTube 拒絕從file://內嵌(error 153), 只有 http(s) 才能頁內播放 - 選 host 要算流量:Firebase 免費方案 360 MB/天,60 MB 的簡報約 6 人就爆; GitHub Pages 是 100 GB/月。發給聽眾選 GitHub Pages
- ⚠️ 絕對不要在個人 vault repo 上開 Pages,那會把整個 vault 公開。另開乾淨 repo
- 部署完要實測:素材各類抽驗 200、字體 loaded、YouTube 頁內播放
檔案
| 路徑 | 用途 |
|---|---|
assets/deck-template.html |
簡報引擎 + 八種版面樣板。auto-fit、lazy media、章節總覽、protocol-aware YouTube |
references/source-recipes.md |
取材食譜。被擋時查這裡 |
references/slide-patterns.md |
選版面、撰稿規則、引擎行為 |
references/publish.md |
部署、host 選擇、現場放映 |
assets/serve.sh |
用 localhost 放映(YouTube 頁內播放的必要條件) |
scripts/verify_deck.py |
驗證閘門:overflow / 破圖 / 孤行 + contact sheet |
scripts/refresh_fonts.py |
字體子集化 |
scripts/harvest_media.py |
依 manifest 批次抓素材到本機 |
引擎行為速查
| 機制 | 說明 |
|---|---|
| auto-fit | 量測 .wrap 高度超出就等比縮放。改引擎時負 margin 不能省,否則 flex 置中會把內容推出畫面 |
| lazy media | 只有當前頁與前後一頁解碼。動態 webp 很吃記憶體 |
| inline video | .vtile video 翻到就播、離開就停。要 muted loop playsinline preload="none" |
| YouTube | http(s) 就地嵌入、file:// 開新分頁。Esc 或關閉鈕收起播放器(焦點進 iframe 後 parent 收不到鍵盤事件,一定要有 parent 端的關閉鈕) |
| 翻頁 | 只有畫面左右邊緣可點,中間留給圈字指東西 |
| 鍵盤 | ← → 翻頁 · O 章節總覽 · F 全螢幕 · Esc 關播放器 |
常見錯誤
| 症狀 | 原因 |
|---|---|
| 內容被切掉但 auto-fit 沒作用 | 首次量測時圖還沒解碼,高度是錯的。要在 img.onload 重量一次 |
| 深色頁溢出 | 深色頁的 padding 在 .wrap 內,avail 不能再扣一次 padding |
| 角標不見 | badge 樣式若綁在 .fig 底下,.thumb 容器就吃不到。要用通用選擇器 |
| 標題出現孤兒字 + 突兀色塊 | <em> 高亮跨行。用明確 <br> 控斷點 |
網址列改 #N 不跳頁 |
引擎只在初次載入讀 hash。要重新整理或按 O 用總覽跳 |
| 部署後中文檔名 404 | GitHub Pages 對中文檔名有問題,改 ASCII 檔名 |