技能:add-rust-svgbob
此技能中的檔案參考(@path)皆相對於此目錄。
我的職責
我負責將 ASCII 藝術圖表 加入 Rust 的 /// 文件註解中,使用 svgbobdoc crate 的 transform!() 巨集。```svgbob 程式碼區塊內的 ASCII 藝術圖表會在編譯時被轉換為 內嵌 SVG,並以 data:image/svg+xml 資料 URI 的形式嵌入——不需要額外檔案,無論在本機 cargo doc 或 docs.rs 上皆可運作。
圖表直接存在於原始碼中——任何閱讀 Rust 檔案的人都能直接看到 ASCII 藝術圖。
何時使用我
在以下情況使用此技能:
- 您的 Rust 函式庫有 結構/架構概念,用圖表說明最為清楚
- 您需要 快速流程圖、流程圖或資料流圖形,但不希望使用外部圖片檔案
- 圖表簡單到可以用 ASCII 方框繪製字元來表示
- 您希望圖表在 原始碼中可見(而非隱藏在外部 PNG 中)
- 您維護的 crate 可以接受
svgbobdoc的依賴權重
不適合用於:
- 真實資料視覺化(散佈圖、折線圖)——請使用
embed-doc-image - 帶有曲線路徑或細節的複雜圖表——ASCII 藝術有其限制
- 使用非常舊的 Rust 編譯器(< 1.54)的專案
必要條件
| 需求 | 用途 |
|---|---|
| Rust ≥ 1.54 或 nightly | 支援內部屬性 + 程序巨集 |
在依賴中加入 svgbobdoc | 程序巨集 crate |
啟用 svgbobdoc 的 enable 特徵 | 啟動 svgbob SVG 渲染器 |
doc-images 特徵旗標(或自訂) | 特徵門控以確保相容性 |
| 已設定 docs.rs 中繼資料 | 確保 SVG 在 docs.rs 上正確渲染 |
我的運作方式
步驟 1:檢查當前狀態
讀取 Cargo.toml 以檢查 svgbobdoc 是否已設定:
svgbobdoc是否在[dependencies]中且帶有features = ["enable"]?- 是否為 選用(建議)?
- 是否有
doc-images或類似的特徵來啟用它? [package.metadata.docs.rs]是否包含features = ["doc-images"]?
檢查原始檔中是否已存在 ```svgbob 使用或 svgbobdoc::transform!() 呼叫。
步驟 2:設定基礎設施(若缺少)
若 svgbobdoc 尚未設定,則加入它:
Cargo.toml 新增內容:
[dependencies]
svgbobdoc = { version = "0.3", optional = true, features = ["enable"] }
[features]
doc-images = ["dep:svgbobdoc"]
[package.metadata.docs.rs]
features = ["doc-images"]
如果也使用了 embed-doc-image,則將其合併到同一個特徵下:
[features]
doc-images = ["dep:embed-doc-image", "dep:svgbobdoc"]
步驟 3:掃描專案
遞迴地查看 <project>/src/ 目錄下的 *.rs 檔案。找出適合加入圖表的 圖表候選項目——也就是那些可以用 ASCII 圖表來說明概念的型別和函式。
步驟 4:辨識圖表候選項目
函式/型別/模組在以下情況可作為「圖表候選項目」:
| 訊號 | 範例 |
|---|---|
| 資料流 | 輸入 → 處理 → 輸出 |
| 處理步驟 | 具有明確階段的演算法 |
| 座標映射 | (x, y) → 轉換後的座標 |
| 幾何轉換 | 旋轉、投影、縮放 |
| 樹/圖結構 | 二元樹、網路清單、相依性圖 |
| 架構 | 模組層級、管線階段 |
| 狀態機 | 狀態與轉換 |
| 比較 | 之前 vs 之後、兩種替代方案 |
| 佈局 | 平面圖、記憶體佈局、封裝 |
步驟 5:設計 ASCII 圖表
svgbob 渲染能力:
| ASCII 元素 | svgbob 渲染 |
|---|---|
.─. / '─' | 圓角矩形邊框 |
│ / ─ | 線條 |
/ / \ | 對角線 |
► / ▼ / ▲ / ◄ | 箭頭頭部(Unicode) |
-> / <- | 箭頭連接器 |
=== / ~~~ | 雙線/波浪線 |
( ) / [ ] | 曲線/方括號 |
○ / ● | 圓形標記 |
... | 虛線連接器 |
清晰圖表的設計提示:
- 保持簡潔——每個圖表最多 15-25 行
- 使用方框邊框——頂部用
.───.,底部用'───' - 標記箭頭——在
──►連接器旁加入文字 - 使用 Unicode 方框繪製字元對齊——
─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ - 測試圖表——使用 svgbob 編輯器 預覽
範例——簡單的資料流:
.───────────. .───────────. .───────────.
│ 輸入 │────►│ 處理 │────►│ 輸出 │
'───────────' '───────────' '───────────'
步驟 6:加入圖表
用於結構層級的文件:
/// 現有描述。
///
/// 轉換流程:
#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
/// ```svgbob
/// .───────────. .───────────.
/// │ 步驟 1 │────►│ 步驟 2 │
/// '───────────' '───────────'
/// ```
))]
pub struct MyType { ... }
用於函式層級的文件:
/// 描述。
#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
/// ```svgbob
/// .───────────. .───────────.
/// │ 輸入 x │────►│ 輸出 f(x) │
/// '───────────' '───────────'
/// ```
))]
pub fn my_function(x: f64) -> f64 { ... }
重要:transform!() 內部的 /// 行必須完全保留。巨集會將 /// 解析為文件註解行,並處理其中的 ```svgbob 區塊。
步驟 7:建置並驗證
# 使用圖表建置
cargo doc --features doc-images --no-deps --open
驗證檢查清單:
-
cargo build(不帶特徵)通過——沒有 svgbobdoc 依賴洩漏 -
cargo build --features doc-images通過——transform!()巨集執行 -
cargo doc --features doc-images --no-deps完成且 零警告 - 產生的 HTML 包含
data:image/svg+xml;base64,...URI - SVG 在瀏覽器中正確渲染(適當的箭頭、方框、文字)
# 驗證每個結構頁面上的 SVG 資料 URI
grep -c "data:image/svg" target/doc/my_crate/struct.MyType.html
步驟 8:檢查兩種特徵狀態
cargo build # 必須通過(未連結 svgbobdoc)
cargo build --features doc-images # 必須通過(transform! 執行)
cargo test --all-features # 所有測試必須通過
設定參考
基本 Cargo.toml(僅 svgbobdoc)
僅使用 svgbobdoc 的專案的最小設定:
[package]
name = "my-crate"
version = "0.1.0"
edition = "2024"
[dependencies]
svgbobdoc = { version = "0.3", optional = true, features = ["enable"] }
[features]
doc-images = ["dep:svgbobdoc"]
[package.metadata.docs.rs]
features = ["doc-images"]
與 embed-doc-image 共用
當同時使用 svgbobdoc(ASCII 圖表)和 embed-doc-image(PNG/SVG 圖形)時:
[dependencies]
embed-doc-image = { version = "0.1", optional = true }
svgbobdoc = { version = "0.3", optional = true, features = ["enable"] }
[features]
doc-images = ["dep:embed-doc-image", "dep:svgbobdoc"]
[package.metadata.docs.rs]
features = ["doc-images"]
兩者共用同一個 doc-images 特徵——一個 cargo doc --features doc-images 即可同時啟用兩者。
自訂特徵名稱
如果您的專案已有用於其他用途的 doc-images 特徵,請使用不同的名稱:
[features]
default = []
svg-docs = ["dep:svgbobdoc"] # 自訂名稱
doc-images = ["dep:embed-doc-image"] # 現有名稱
然後在原始碼中:
#[cfg_attr(feature = "svg-docs", doc = svgbobdoc::transform!(
/// ```svgbob
/// diagram
/// ```
))]
pub struct MyType;
使用 dep: 語法解析特徵
特徵定義中的 dep: 前綴在 Rust 1.60 中穩定。它明確引用一個選用依賴:
# 現代語法(Rust ≥ 1.60)——推薦:
doc-images = ["dep:svgbobdoc"]
# 舊語法——可行但不明確:
doc-images = ["svgbobdoc"]
dep: 形式是首選——它可以防止依賴名稱和特徵名稱之間的歧義。
docs.rs 中繼資料選項
| 設定 | 用途 |
|---|---|
features = ["doc-images"] | 在文件建置期間啟用 svgbobdoc |
rustdoc-args = ["--html-in-header", "src/doc-header.html"] | 注入 KaTeX/JS 標頭 |
all-features = true | 使用 ALL 特徵建置文件(謹慎使用) |
[package.metadata.docs.rs]
features = ["doc-images"]
rustdoc-args = ["--html-in-header", "src/doc-header.html"]
使用 cfg_attr 進行條件編譯
核心模式:
#[cfg_attr(
feature = "doc-images", // 條件
doc = svgbobdoc::transform!( // 要發出的屬性
/// ```svgbob
/// diagram
/// ```
)
)]
在每次建置時如何運作:
| 建置命令 | cfg_attr 評估為 | 結果 |
|---|---|---|
cargo build | feature = "doc-images" 為 false | 屬性被抑制——無巨集,無 svgbob 依賴 |
cargo build --features doc-images | feature = "doc-images" 為 true | #[doc = svgbobdoc::transform!(...)] 被發出——SVG 產生 |
cargo doc --features doc-images | 同上 | SVG 資料 URI 嵌入 HTML |
| docs.rs(中繼資料設定特徵) | 同上 | SVG 在 docs.rs 上渲染 |
檢查特徵解析
驗證特徵是否正確連接:
# 檢查 svgbobdoc 在預設建置中是否未連結
cargo build --verbose 2>&1 | grep svgbobdoc
#(應無輸出)
# 檢查 svgbobdoc 在啟用特徵時是否已連結
cargo build --features doc-images --verbose 2>&1 | grep svgbobdoc
# 輸出:"Compiling svgbobdoc v0.3.0"
svgbob ASCII 藝術語法指南
方框繪製字元
svgbob 渲染器辨識這些 Unicode 方框繪製字元,並將其轉換為 SVG 路徑:
| 字元 | 碼點 | 渲染為 |
|---|---|---|
─ | U+2500 | 水平線 |
│ | U+2502 | 垂直線 |
┌ | U+250C | 左上角 |
┐ | U+2510 | 右上角 |
└ | U+2514 | 左下角 |
┘ | U+2518 | 右下角 |
├ | U+251C | 左 T 形接點 |
┤ | U+2524 | 右 T 形接點 |
┬ | U+252C | 上 T 形接點 |
┴ | U+2534 | 下 T 形接點 |
┼ | U+253C | 十字接點 |
╱ | U+2571 | 右上對角線 |
╲ | U+2572 | 左上對角線 |
◄ | U+25C4 | 左箭頭頭部 |
► | U+25BA | 右箭頭頭部 |
▲ | U+25B2 | 上箭頭頭部 |
▼ | U+25BC | 下箭頭頭部 |
● | U+25CF | 實心圓 |
○ | U+25CB | 空心圓 |
═ | U+2550 | 雙水平線 |
║ | U+2551 | 雙垂直線 |
≈ | U+2248 | 波浪線 |
→ | U+2192 | 向右箭頭 |
建立方框
圓角矩形(圖表節點最常用):
.───────────.
│ 內容 │
'───────────'
- 左上角使用
.,右上角使用' - 左下角使用
',右下角使用. - 用
─填充頂部和底部邊框 - 用
│填充側邊邊框
尖角矩形:
┌───────────┐
│ 內容 │
└───────────┘
用箭頭連接方框
水平箭頭:
.───. .───.
│ A │────────►│ B │
'───' '───'
垂直箭頭:
.───.
│ A │
'───'
│
▼
.───.
│ B │
'───'
從特定側邊的箭頭:
.───.
│ B │
'───'
▲
│
.───. │
│ A │──────┘
'───'
為箭頭加入標籤
將文字放在箭頭線條旁。svgbob 會自動定位:
.───. 條件 .───.
│ A │══════════════════►│ B │
'───' '───'
.───. false .───.
│ A │──────────────►│ B │
'───' '───'
方框中的多行文字
svgbob 會根據方框寬度自然地換行文字:
.──────────────────.
│ 這段文字會 │
│ 在方框邊界內 │
│ 自動換行 │
'──────────────────'
對角線
.───. .───.
│ A │╲ │ C │
'───' ╲ '───'
╲
╲ .───.
╲│ B │
╲'───'
樹與層級結構
二元樹:
.───.
│ R │
'───'
╱ ╲
.───. .───.
│ L │ │ R │
'───' '───'
╱ ╲ ╲
.───. .───. .───.
│LL │ │LR │ │RR │
'───' '───' '───'
縮排層級結構(無線條):
.───────────────.
│ 根節點 │
│ ├── 子節點 A │
│ ├── 子節點 B │
│ └── 子節點 C │
'───────────────'
網格與矩陣
.──────┬──────┬──────.
│ a │ b │ c │
├──────┼──────┼──────┤
│ d │ e │ f │
├──────┼──────┼──────┤
│ g │ h │ i │
'──────┴──────┴──────'
比較佈局
並排:
.─────────────. .─────────────.
│ 之前 │ │ 之後 │
│ .───────. │ │ .───────. │
│ │ 舊版 │ │ │ │ 新版 │ │
│ '───────' │ │ '───────' │
'─────────────' '─────────────'
之前 → 之後(順序性):
.───────────────. .───────────────.
│ 慢路徑 │────►│ 快路徑 │
│ O(n²) │ │ O(n log n) │
'───────────────' '───────────────'
資料庫/資料表結構
.──────────────────────.
│ 資料表:users │
├──────────────────────┤
│ id INTEGER │──► PK
│ name TEXT │
│ email TEXT │──► UNIQUE
│ created_at DATETIME │
'──────────────────────'
帶有決策的流程圖
.───────────.
│ 開始 │
'─────┬─────'
│
▼
.───────────.
│ 處理 │
'─────┬─────'
│
▼
.───────────. 是 .───────────.
│ 檢查? │─────────►│ 選項 A │
'─────┬─────' '───────────'
│
│ 否
▼
.───────────.
│ 選項 B │
'───────────'
分層架構
.───────────────────────────.
│ 應用層 │
├───────────────────────────┤
│ 商業邏輯層 │
├───────────────────────────┤
│ 資料存取層 │
├───────────────────────────┤
│ 資料庫 │
'───────────────────────────'
時序/序列圖(簡化)
客戶端───┬──────────────────┐
│ 請求 │
│─────────────────►│
│ │
│◄─────────────────│
│ 回應 │
客戶端───┴──────────────────┘
進階技巧
使用區塊註解做內聯圖表
對於簡短的圖表,您可以使用 /*! 區塊註解將圖表內聯到程式碼中:
/*!
轉換流程:
```svgbob
.───. .───.
│ A │────────►│ B │
'───' '───'
*/ pub fn convert() { ... }
### 多個圖表在同一個文件註解中
可以使用多個 `transform!()` 巨集:
```rust
/// 步驟 1:
#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
/// ```svgbob
/// .───.
/// │ A │
/// '───'
/// ```
))]
/// 步驟 2:
#[cfg_attr(feature = "doc-images", doc = svgbobdoc::transform!(
/// ```svgbob
/// .───.
/// │ B │
/// '───'
/// ```
))]
pub fn two_steps() { ... }
巢狀方框與分組
.───────────────────────────────.
│ 系統 │
│ .───────────. .───────────. │
│ │ 模組 A │ │ 模組 B │ │
│ '───────────' '───────────' │
│ │ │ │
│ └─────┬─────┘ │
│ │ │
│ .─────┴─────. │
│ │ 匯流排 │ │
│ '───────────' │
'───────────────────────────────'
使用帶有標籤的邊框
.───. 輸入 .───.
│ A │════════►│ B │
'───' '───'
常見問題
變更圖表而不改動原始碼
svgbobdoc 在編譯時處理圖表,因此無法在不修改原始碼或重新建置 crate 的情況下變更圖表。如果圖表需要頻繁更新,請考慮使用外部文件(例如 README.md)搭配 embed-doc-image。
效能影響
transform!() 巨集在編譯時執行,其開銷與 ASCII 圖表的大小和複雜度成正比。對於大多數圖表(< 50 行),開銷可以忽略不計。大型或大量的圖表可能會增加編譯時間。
與其他文件工具的相容性
- rustdoc:完全支援——巨集直接輸出有效的
#[doc = ...]屬性 - docs.rs:只要
[package.metadata.docs.rs]正確設定即可運作 - 本地
cargo doc:如果正確啟用特徵,則可直接運作 - IDE 整合:圖表在原始碼中顯示為 ASCII 藝術;SVG 在 rustdoc 預覽中可見
與 egui / 其他 GUI 的相容性
svgbobdoc 僅在文件建置期間執行,執行期間環境中不運作。它不會影響執行時期行為或二進位檔案大小。
對 no_std 的支援
是的。svgbobdoc 僅是一個程序巨集 crate,不需要 std。它可以在 #![no_std] crate 中安全使用。
對 WASM 的支援
是的。transform!() 在編譯期間執行,輸出的資料 URI 可以無問題地在 WASM 目標上使用。
故障排除
transform!() 巨集錯誤
問題: error: cannot find macro 'transform' in this scope
解決方案: 確保 svgbobdoc 已正確加入 Cargo.toml:
[dependencies]
svgbobdoc = { version = "0.3", features = ["enable"] } # 需要 "enable" 特徵
並且在原始碼中正確導入:
use svgbobdoc::transform; // 或使用完整路徑 svgbobdoc::transform!()
SVG 未在 docs.rs 上渲染
問題: 圖表在本機 cargo doc 中運作,但在 docs.rs 上未顯示。
解決方案: 驗證 [package.metadata.docs.rs] 已正確設定:
[package.metadata.docs.rs]
features = ["doc-images"]
重新發布 crate 以便 docs.rs 重建文件。
圖表在瀏覽器中看起來不對
問題: SVG 渲染具有斷裂的線條、遺失的字元或對齊不正確。
解決方案:
- 使用svgbob 編輯器測試 ASCII 圖表
- 確保使用正確的 Unicode 方框繪製字元(
─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼) - 在圖表中使用等寬字型(例如
Consolas、DejaVu Sans Mono) - 檢查圖表中是否有不能正常顯示的寬字元(例如全形字元)
建置速度變慢
問題: 新增 svgbobdoc 後編譯時間顯著增加。
解決方案:
- 保持圖表簡潔(< 30 行)
- 使用
sccache或mold來加速增量建置 - 如果圖表很多(> 50 個),考慮使用
embed-doc-image將圖表拆分為外部檔案