agentsclimarketplace

Teaching handbook

Skill unbias38/my-claude-skills/teaching-handbook

將 Word (.docx)、Markdown (.md) 或 PowerPoint (.pptx) 教學講義轉成「側邊欄導航風格」的高畫質 HTML 網頁。使用時機:使用者說「上架教材」「上架講義」「教材轉網頁」「講義轉網頁」「轉成側邊欄導航風格」「轉成側邊欄網頁」「把這份 .docx/.md/.pptx 轉 HTML」,或提供 .docx/.md/.pptx 檔案並要求產出教學網頁時。產出包含固定側邊欄目錄、Scroll Spy、字體縮放、程式碼複製按鈕、自動保留 Word 文字顏色等互動功能。若使用者指名 codelab / Codelabs 風格,改用 codelab-handout skill;本 skill 走忠實機械轉檔路線、不做視覺重設計。From its SKILL.md

Install
npx -y skills add unbias38/my-claude-skills --skill teaching-handbook

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

11.6 KB, ~4.8k tokens by cl100k_base, as published. Nobody here has run it

teaching-handbook

<SKILL_DIR> 代表本 SKILL.md 所在資料夾。

.docx / .md / .pptx 教學講義轉成側邊欄風格的教學網頁。

範圍邊界(重要)

本 skill 只負責機械轉檔(Stage 1):把原檔的文字、圖、結構忠實搬到 HTML,不改寫、不美化、不重組。

內容理解 / 改寫 / 美化(Stage 2)不在本 skill 範圍。原因:每份簡報的領域、讀者、風格差異太大,強行寫死自動規則只會把大部分簡報搞砸。Stage 2 由使用者在跑完轉檔後另起對話、依當份簡報的具體需求請 Claude 處理。

未來的維護者:不要把美化規則寫進這個 skill——本 skill 定位是忠實機械轉檔,美化屬於下游另一層。

若使用者指名 codelab / Codelabs 風格,本 skill 不處理,改用 codelab-handout(強意見視覺設計路線)。

硬規則(不可違反)

  1. 必須使用原始檔.docx / .md / .pptx),不接受先轉過的 .htm / .html(否則圖片會糊)。
  2. 不要改寫 scripts/ 下的 Python 邏輯,直接呼叫即可。
  3. 輸出檔名以輸入檔名為基底(例如 我的講義.docx我的講義.html),不要預設 index.html,避免覆蓋專案主頁。
  4. 若目標輸出檔已存在,先向使用者確認再覆蓋。

依套件

依賴由各腳本的 inline metadata(PEP 723)宣告,uv run 會自動安裝,無需手動裝套件。

執行 SOP

步驟 1:確認輸入檔

  • 使用者提供 .docx → 走 docx_converter.py
  • 使用者提供 .md → 走 md_converter.py
  • 使用者提供 .pptx → 走 pptx_converter.py
  • 其他副檔名 → 停下來問使用者

步驟 2:確認參數(都有預設值,可略)

  • --title:瀏覽器分頁標題(預設 教學手冊,md 預設 Document
  • --sidebar-title:側邊欄標題(docx 預設 教學手冊導航;pptx 預設 投影片目錄
  • --no-notes(僅 pptx):不納入講者備註。預設納入
  • 輸出檔名:省略則自動用輸入檔名 + .html

使用者若沒主動提,直接用預設值,不要反覆追問。

步驟 3:執行轉換

DOCX:

uv run <SKILL_DIR>/scripts/docx_converter.py "<input.docx>" --title "<標題>" --sidebar-title "<側邊欄標題>"

Markdown:

uv run <SKILL_DIR>/scripts/md_converter.py "<input.md>" --title "<標題>"

PPTX:

uv run <SKILL_DIR>/scripts/pptx_converter.py "<input.pptx>" --title "<標題>" --sidebar-title "<側邊欄標題>"

步驟 4:回報結果

告訴使用者輸出檔路徑,讓他可以打開檢查。不用自行開啟瀏覽器。

產出的網頁功能

  • 左側 280px 固定側邊欄,自動從 h1/h2/h3 生成目錄(Scroll Spy 高亮目前章節)
  • << 收折按鈕:側邊欄縮成 60px,主區域擴展到 1400px
  • A- / 100% / A+ 字體縮放(預設 1.15x)
  • 程式碼區塊(單格表格或 <pre>)自動加「複製」按鈕
  • 圖片響應式(max-width: 100%),保留 Word 原始高畫質

檔案結構

<SKILL_DIR>/
├── SKILL.md                      ← 本文件
└── scripts/
    ├── docx_converter.py         ← .docx 入口
    ├── md_converter.py           ← .md 入口
    ├── pptx_converter.py         ← .pptx 入口
    ├── style_injector.py         ← 核心樣式 + 導航 + 複製按鈕引擎(上游、不動)
    └── _polish.py                ← 共用 helper:sidebar 搜尋框 + 圖片 lazy load

style_injector.py 自成一體,三個 converter 皆透過 import style_injector 呼叫它。 _polish.py 是 converter-side 的共用增強,與 style_injector.py 無關(後者保持原樣)。

三個 converter 共享的功能(透過 _polish.py

下列功能無論 docx / md / pptx 都會生效:

  • 圖片 loading="lazy":所有 <img> 自動帶 lazy 屬性,大檔載入快
  • Sidebar 重建:清空 style_injector.py 生成的 nav,用文件中所有 H1/H2/H3 重建(按文件順序)。修復「1. 章節」「純中文標題」等不符合上游 regex 的 heading 被 sidebar 漏掉的問題
  • Sidebar 即時搜尋:在重建後的 #sidebar-nav 上方注入 <input id="th-search">,輸入即時過濾目錄項

執行時機:converter 在 body 末端塞 <script>,於 window.load 後執行(此時 style_injector.py 已跑完,nav 已被它的 regex 邏輯填好)。

為什麼放在 _polish.py 而非 style_injector.py:硬規則 #2 不動上游 style_injector.py。converter-side 增強統一抽到 _polish.py

為什麼是「清空重建」而非「補登」

上游 style_injector.py sidebar JS 用 regex ^(\d+(\.\d+)?)(\s|$) || ^[A-Z](\s|$) 過濾 H2/H3。對下列常見情境全部會誤殺

  • markdown 標題「1. 章節」(digit + dot + space,regex 在 dot 後 require digit,失敗)
  • 純中文 H2 / H3(既無數字也無大寫字母前綴)
  • docx heading 用中文起頭

如果只「補登被漏的」,當 H1(永遠通過)和 H2(中文,被漏)交錯時,順序會錯(既有 H1 在前,後補的 H2 全部塞最後)。所以必須清空 nav 整個重建,按 querySelectorAll('h1, h2, h3') 的 document order 全列。

ID 兼容性style_injector.py 給通過 regex 的 heading assign id="section-N",scroll-spy IntersectionObserver 用這些 ID 對應 nav-link。重建邏輯重用既有 id(若 heading 已有 id 則保留),新加的 heading assign th-section-N。Observer 端比對 href === '#' + id,新舊 ID 都對得上 → scroll-spy 正常。

順序保證:document order 由 querySelectorAll 保證,重建後 sidebar 順序 = 文件順序,與單純 append 在 H1/H2/H3 交錯文件的順序錯亂問題隔絕。

驗證(2026-04-25):

  • LSpe2.md(1 H1 + 15 H2 + 7 H3 共 23 個 heading):之前 sidebar 1 條,現在 23 條 ✅
  • 防災宣導_SROI.docx(10 H1):10 條 → 10 條,無 regression ✅
  • 金融大數據_v0.pptx(10 H2 「01 - 標題」):10 條 → 10 條,無 regression ✅

不要這樣修style_injector.py 的 regex 一勞永逸 — 違反硬規則 #2。_polish.py 的清空重建是正確的繞道方式。

pptx 轉換原則

  • 每張投影片 = 一個 <h2> 章節(側邊欄自動列出)
  • 章節分隔投影片 → <h1>(無內容、無 bullets、≤1 圖、或 layout 名稱含 section headertitle slidechapter
  • 投影片標題空白 → 用 Slide N 標示
  • 投影片內文 → <ul>(短)或 <p>(長)
  • 投影片內嵌圖片 → 以 base64 data URI 內嵌、loading="lazy"、80×80 縮圖橫排
  • 講者備註 → 預設納入(教學型 pptx 常把真正內容放在備註);用 --no-notes 可關閉
  • Sidebar 自動加搜尋框(輸入即時過濾目錄項)
  • 不做投影片轉圖、不還原版面 —— 這是重排器,不是螢幕截圖器
  • 動畫、轉場、嵌入影片會丟失(pptx → HTML 的必然代價)

pptx 採坑紀錄(2026-04-25 實測 12 頁簡報)

下面是「為什麼 pptx_converter.py 看起來怪怪的」的解答。未來除錯前先讀完,避免把對的東西改壞。

1. 標題會被強制加 01 - 前綴 — 這是故意的

現象pptx_converter.py_render_slide_html 會把 投影片標題 改成 01 - 投影片標題 才送進 HTML。

原因:上游 style_injector.py 第 430 行 sidebar nav 生成 JS 用 regex 過濾 h2/h3 標題:

const match = text.match(/^(\d+(\.\d+)?)(\s|$)/) || text.match(/^[A-Z](\s|$)/);
if (match || header.tagName === 'H1') { /* add to sidebar */ }

只接受「數字 + 空白開頭」(如 1 章 1.1 節)或「單一大寫字母 + 空白開頭」(如 A 概論)。純中文標題全部被略過 → sidebar 變空白

對策:converter 端強制前綴 f"{i:02d} - {title}"(不動上游腳本,符合硬規則 #2)。

不要這樣修style_injector.py 把 regex 放寬 — 違反硬規則 #2,且會影響 docx/md 流程。

2. 圖片預設縮成 80×80 縮圖橫排 — 這也是故意的

現象:投影片裡的圖片不是大圖內嵌,是 <div class="pptx-thumbs"> 裡的 80×80 小方塊橫排。

原因:PowerPoint 教學簡報通常每張投影片埋 5–10 張 256×256 的裝飾圖示(流程箭頭、燈泡、章節標誌等)—— 不是「正文圖」。如果當大圖內嵌,每張佔約 300px 垂直空間,累積就一片空白海。實測 12 頁簡報共 32 張圖、所有都是 256×256,幾乎全是裝飾。

對策:用 flex + 80×80 縮圖排在標題下方,視覺上是一行 icons。

不要這樣修改回每張一行的大圖呈現 — 會讓所有教學型 pptx 變成空白海。如果未來真遇到「圖才是主角」的 pptx(例如設計作品集),應該另開新 skill(如 pptx-gallery),別改這個。

3. 過濾純數字/單字母的短 bullet

現象_collect_body_paragraphs 會跳過長度 ≤ 2 且為純數字或純字母的文字。

原因:PowerPoint 投影片底部常有頁碼("2"、"3")或裝飾編號,會被 python-pptx 當成一般文字框讀進來,污染 bullet 清單。

不要這樣修移掉這個過濾 — 除非使用者明確表示需要保留頁碼。

4. 上游 style_injector 的兩處來源專案特定 hack — 保留原樣

上游 style_injector.py 含兩處來源專案特定 hack(emoji 狀態色替換、「執行步驟」表格的 copy-btn 排除),對一般文件無害、幾乎不觸發;依硬規則 #2 保留原樣,不要清理。


教訓(給未來的我)

「LLM 按按鈕」型 skill 並非「加個檔就完事」。下游 style_injector.py隱性假設(標題要數字開頭、image 要適合大圖呈現),新加的 converter 必須學會這些假設才能對接。設計上的拗口都是有原因的,不要看到就想「優化」掉。

pptx 大檔擴張(2026-04-25 加,因應 200+ 頁簡報)

為了讓大檔(50+ 頁)也好用,pptx_converter.py 內建章節偵測:

章節偵測 → <h1>

_is_chapter_slide() 判斷規則:

  • 投影片 layout 名稱含 section header / section divider / title slide / chapter → 是章節
  • 或 投影片無 bullets、無 long paragraphs、且 ≤1 張圖 → 是章節

章節投影片用 <h1>(不加 01 - 前綴,因 H1 不需 regex 匹配)。style_injector.py 自動把 H1 列為 sidebar 頂層(level-1,含上方分隔線)—— 這是上游已經支援的功能,我們只是讓 pptx 能觸發它

不要這樣修:~~改用 H3 區分章節~~ — H3 受 regex 限制,且 sidebar 顯示太小看不出階層。

lazy load 與 sidebar 搜尋已移至三 converter 共享的 _polish.py,見上節「三個 converter 共享的功能」。

What ships with it: 5 files

40.0 KB alongside SKILL.md, 5 of them executable

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.