Boxloom:撰寫投影片
Boxloom 將意義與外觀分離。您只需撰寫內容是什麼(例如:要點列表、選項比較、含日期的計劃)。模板會決定所有顏色、字型大小、邊距和位置。除了唯一一個例外(shapes,最後手段)之外,您永遠不需要指定顏色、大小或座標。
循環永遠是:
boxloom schema— 讀取當前模板接受的內容(請先執行此步驟)。- 撰寫
deck.bx.md。 boxloom check -format json deck.bx.md— 修正每個錯誤,然後修正所有能修正的警告。- 重複步驟 3 直到出現
"ok": true且沒有layout-overflow警告。 boxloom build -o deck.pptx deck.bx.md(旗標放在檔案之前)。
命令需在儲存庫的 boxloom/ 目錄中執行:
go run ./cmd/boxloom <schema|check|build|parse> …(需要 Go 1.24+,無其他依賴)。
1. 先讀取結構描述
boxloom schema [-template light|dark] 會輸出一個 JSON 文件。這是唯一真相來源;如果此文件與結構描述不一致,以結構描述為準。
markdown.rules— 語法規則(簡短清單;請全部遵守)。markdown.frontMatter—---標頭中允許的鍵(title為必填)。templates[].blocks— 此模板認得的圍欄區塊(:::name),包含inside(可出現的位置)、contains(內部可包含的內容)和minChildren(最小子元素數量)。templates[].subsystems— 圖表類型(```name程式碼區塊),包含markdown(其額外規則)和schema(指向irSchema的 JSON 指標,列出所有允許的鍵)。- 未列出的任何內容皆為錯誤。請勿發明區塊名稱、屬性或鍵。
- 模板透過名稱選擇(front matter 中的
template: light,或-template dark)。自訂模板是透過路徑傳遞的值表檔案:-template ./my.json(適用於schema、check、build、fonts;範例:examples/templates/forest.json)。當投影片將使用自訂模板建置時,請使用相同的-template執行schema和check— 角色名稱和文字樣式來自該檔案。 variant(# Title {variant=…})存在於語法中,但當前模板未宣告任何變體(templates[].variants為空),請勿使用。
輸出內容很大。若只想查看所需部分:
go run ./cmd/boxloom schema -template light > /tmp/schema.json
python3 -c "import json;d=json.load(open('/tmp/schema.json'));print(json.dumps({'rules':d['markdown']['rules'],'blocks':d['templates'][0]['blocks'],'subsystems':[(x['name'],x['markdown']) for x in d['templates'][0]['subsystems']]},ensure_ascii=False,indent=1))"
python3 -c "import json;d=json.load(open('/tmp/schema.json'));print(json.dumps(d['irSchema']['\$defs']['gantt'],ensure_ascii=False,indent=1))" # 所有甘特圖鍵
2. 語法一覽
---
title: 將報告服務遷移至新叢集
subtitle: 計劃與選項(虛構範例)
author: 平台團隊
date: 2026-11-11
confidential: 內部文件
disclaimer: 所有名稱和數字均為虛構
template: light
---
# 舊叢集的廠商支援
:::lead
舊叢集將於 2028 年 3 月失去廠商支援,因此其上執行的 14 項服務必須在此之前完成遷移。
:::
- 廠商將於 **2028-03-31** 停止安全性修正
- 仍有 14 項服務在該叢集上執行;其中 9 項無需修改程式碼即可遷移
- 每個服務群組約需 6 週遷移時間
:::source
廠商支援通知 (2026 年 9 月);截至 2026 年 10 月的服務庫存
:::
:::notes
講者筆記置此。僅限純文字段落和項目符號。
:::
-
# Title開始一張投影片。請將標題保持為簡短、可單行顯示的標題(例如「舊叢集的廠商支援」);換行的標題會觸發警告 (title-wrap)。請在標題之後的:::lead中以一句話寫出投影片的結論(1–2 行)。模板會將 lead 放在標題下方、主體之外。 -
---不是投影片分隔符號(使用它會產生錯誤)。##和更深層級的標題都是錯誤(群組標題應使用:::column Title撰寫,而非子標題)。 -
主體:段落、
-/1.項目符號(最多兩層)、**強調**(僅一種強調)、`程式碼`、[文字](網址)、結尾\表示有意義的換行。不支援斜體、刪除線、註腳、HTML。 -
圍欄區塊:以
:::name開頭,並以相同數量的冒號結尾。巢狀時,外層圍欄比內層多一個冒號::::::compare ::::option 保留舊叢集 :::pros - 今年無需進行遷移工作 ::: :::cons - 2028 年 3 月後將不再有安全性修正 ::: :::: ::::option 遷移至新叢集 :::pros - 支援至 2033 年 ::: :::cons - 每個服務群組需六週工作 ::: :::: ::::: -
:::lead(投影片的訊息)、:::notes(講者筆記)和:::source(投影片數字的來源)必須位於投影片的頂層,每張投影片各只能出現一次。:::lead僅用於內容投影片。 -
front matter 中的
date、confidential和disclaimer在整個投影片組中只撰寫一次;模板會將它們放在封面(而confidential會放在頁尾)。切勿在每張投影片的:::note中重複「虛構」/「機密」。 -
圖表是語言為子系統名稱的圍欄程式碼區塊,主體為受限的 YAML:不支援錨點/別名 (
&、*)、標籤、多行值、|/>區塊;布林值僅true/false;日期為字串YYYY-MM或YYYY-MM-DD;範圍2027-01 .. 2027-06。請將任何以*、&、!開頭或包含": "的值加上引號,例如text: ["**最慢步驟**", 平均 5 天]— 若流程項目標頭中未加引號的**…**會被视为 YAML 別名而被拒絕。
3. 為每段內容選擇樣板
在撰寫前先決定內容的類型。依序套用這些規則,並使用第一個符合的規則。(完整規則集及好/壞範例:docs/patterns.md §4。)
目前可用(請檢查 boxloom schema — 可能已新增更多):
| 內容 | 使用方式 | 備註 |
|---|---|---|
| 章節分隔 | # 第二部分:遷移方式 {type=section} | 標題文字是章節標題;其後只能跟 :::notes。不是目錄 — 當投影片組有兩個以上章節時,模板會繪製章節列表,並在每個章節投影片上自動反白當前章節 |
| 投影片只說一句話;證據在其他投影片上 | # 遷移必須提前兩年進行 {type=statement} | 標題文字即為該句話(這是唯一一種標題是完整句子的投影片類型);其後只能跟 :::notes 和 :::source。如果您想加入理由,請使用一般投影片,搭配簡短標題並將結論放在 :::lead |
| 1–4 個需要強烈顯示的數字,且無需比較的序列 | ::::stat → :::value 3 → 12 {unit=模型} + 單行標籤在內部 | 5 個以上數字或時間序列應使用圖表/表格,而非 stat。值保持原樣且必須包含數字。數值和單位絕不從中間斷開,因此請保持簡短 — 4 張卡片會很窄 (stat-value) |
| 數字序列(3 個以上):排名、時間變化、佔比、分佈、兩個數量的關係 | ```chart | compare: item / timeSeries / component / frequency / correlation — 圖表類型會為您選擇(請勿撰寫 bar/line/pie)。categories: [...]、series: [{name, values: [...]}](每個類別一個值,未加引號的數字,最多 3 個數列)、可選 unit、emphasis: [category](一個數列)或 emphasis: true(在一個數列上)、stacked: true(當數列是總體的一部分時)。correlation 使用 xAxis: {title, unit?}、yAxis 和 points: [[x, y], …] 而非類別。component(佔比)有 1 個數列且 ≤ 6 個部分 — 將小部分合併為「其他」 |
| 引用他人言論 | :::quote 來源文字 + 內容在內部 | 來源(標題文字)為必填。絕不引用自己的結論 |
| 一般投影片中要強調的一句話 | :::takeaway + 一句話 | 每張投影片最多一個,通常放在最後 |
| 純文字或數字的列×欄 | GFM 表格:| A | B | + | --- | --- | + 資料列 | 第一列為標題列;每列每個欄位有一個儲存格 (table-shape)。無對齊標記(:--、--: 為錯誤);數字欄位會自動靠右對齊。儲存格僅限行內內容。表格後緊接的一行 : caption 是其標題。如果最後一列是總計,請在該行結尾加上 {total=last} (: 預估 {total=last},或直接 : {total=last});它將被繪製為總計列。總計不會自動計算 — 請自行輸入數值。在標題或標題列中放置單位一次,不要在每個儲存格中重複。儲存格中的評級 → matrix(如下) |
| 每個儲存格都是評級的列×欄(支援 / 有條件 / 不支援 / 風險) | ```matrix | columns: [A, B]、rows: [{label, cells: [{status, text?}]}]、可選 legend: {support: 良好}。每個欄位一個儲存格 (matrix-cells)。建議選項:emphasis: <欄位標題文字>(與 columns 中的寫法完全相同,matrix-emphasis)— 請勿在文字中說「藍色那一欄」。內容為純文字或數字的儲存格應使用表格,而非 matrix |
| 3–7 個無日期的步驟,具有方向性(前一步的輸出是下一步的輸入) | ```process | steps: [{title, detail?, status?, emphasis?}]、可選 caption。數字(1. 2. …)和箭頭會自動為您加入;長流程會換行到第二列。如果使用 status,請在 legend: {conditional: 需要核准} 中說明其意義 (figure-legend) |
| 兩個或多個選項,每個都有優缺點 | :::compare → :::option → :::pros / :::cons | 如果 3 個以上共用標準適用於每個選項,則 matrix 更適合(見上) |
| 具有子項目(和孫項目)的父項目:團隊設定、所有權 | ```orgchart | root: {title, detail?}、units: [{title, detail?, members: [{title, detail?}]}]。最多 3 層。方塊上的 status 需要 legend: {conditional: 還需要兩個人} — 圖表下方的圖例說明其意義;請勿在 :::note 中解釋輪廓顏色。不適用於並列的無關團隊 |
| 階段計數逐漸減少的流程(造訪 → 註冊 → 付費) | ```funnel | stages: [{label, value, note?}]、可選 unit。value 是數字或文字;長條寬度是階梯狀的,而非按比例。階段間轉換率(↓ 45%)會根據數值自動繪製 — 請勿在 note 中撰寫;使用 note 說明階段下降的原因。status 需要 legend。數值增長會觸發警告 (funnel-increase) — 簡單步驟請使用 process |
| 含日期的計劃、期間、截止日期、隨時間變化的狀態 | ```gantt | 狀態為 support、conditional、none、danger(角色,非顏色)。硬體/支援風險期間為群組 risk: A .. B。註解透過 target 指向群組/列 id;子系統會自動放置它們 |
| 2–3 個並列群組供橫向閱讀(今年 / 明年 / 不做) | ::::columns → :::column 群組標題(2 或 3 個) | 每個群組可包含段落、項目符號、一個表格、一張圖片、一個 ```chart 或 :::note。無巢狀 columns、compare、gallery 或其他圖表。圖表與其解說並列:圖表在一個群組中,要點作為項目符號在另一個群組中。寬度不是數字:將主要群組標記為 {role=main}(其他群組支援它),或保持所有群組等寬。4 個以上單行群組 → 使用項目符號。不適用於分為兩半的單一論點 |
| 能說明觀點的圖片(螢幕截圖、照片、圖畫) | 僅包含  的段落 | 替代文字為必填 (image-alt)。路徑相對於投影片檔案;不支援 URL、絕對路徑或 .. (image-path)。僅限 PNG 或 JPEG (image-format)。保持比例,絕不裁剪。圖片 + 文字並列 → ::::columns 並將圖片放在其中一個群組中 |
| 2–6 張用於比較或依序的圖片 | 一個包含 2–6 個  的段落 | 變成圖庫(2–3 張為一行,4–6 張為網格)。7 張以上為錯誤:請分割投影片 |
| 並列要點 | 項目符號 | 最多 2 層 |
| 連續的文字 | 段落 | 2–3 句 |
| 投影片要說的內容:其結論(一兩句) | :::lead 在內容投影片的頂層,一個段落 | **每張內容投影片都有一個。**模板會將其放在標題正下方、主體之外;它會佔用主體的空間(1 行約 32 點,2 行約 57 點)。當需要兩行時,引擎會在句號(。)之後斷行,若無句號則在逗號(,)之後斷行,不會增加行高 — 因此兩句簡短的句子閱讀效果最好。不是條列重點的摘要 — 而是它們要證明的論點 |
| 投影片的數字、表格、圖表或引用的來源(來源、樣本大小、日期) | :::source 在投影片的頂層,一個段落 | **每張顯示數字、表格、圖表或引用的投影片都有一個。**僅限內容和陳述投影片(非章節)。模板會將其放在主體下方、頁尾上方;它會佔用主體的空間 (layout-overflow 會計算它)。每張投影片一個:多個來源請放在一個段落中 |
| 整份投影片組的日期、機密性、免責聲明(「所有數字均為虛構」) | front matter 中的 date、confidential、disclaimer | 僅撰寫一次;顯示在封面(而 confidential 顯示在頁尾) |
| 警告 / 類似註腳的備註 | :::note | 一行簡短文字。不適用於來源(:::source)、不適用於整份投影片組的免責聲明(front matter),也絕不適用於結論或關鍵數字 |
| 位置/連結具有意義且上述任何選項都不合適的圖表 | ```shapes | 最後手段,請見 §3.1 |
在上述四種圖表中,您只撰寫文字、status(support、conditional、none、danger)和 emphasis: true;位置、大小和顏色來自模板。在 chart 中,您只撰寫比較的內容和數字;圖表是真實的 PowerPoint 圖表,其值保持可編輯。請強調標題所說的觀點:
compare: timeSeries
unit: " 註冊數"
categories: [4月, 5月, 6月, 7月, 8月, 9月]
emphasis: [9月]
series:
- name: 註冊數
values: [120, 150, 1
... [因長度截斷]
