Skip to content

Commit d27fb13

Browse files
committed
refactor: split CLI design rules into cli-design/ directory
Replace monolithic cli-textutil-compat.md with structured directory: - unix-conventions.md — Unix CLI general conventions - textutil-compat.md — macOS textutil syntax mapping - convert-entry-point.md — convert unified entry point rules - error-and-output.md — error messages and output conventions
1 parent fb5821e commit d27fb13

6 files changed

Lines changed: 113 additions & 65 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# convert 統一入口規範
2+
3+
## 原則
4+
5+
所有格式轉換必須走 `macdoc convert --to <format> <file>` 統一入口。
6+
舊的 per-format 子命令(`word`, `html`, `srt`)保留為 alias,但 help text 提示改用 `convert`
7+
8+
## 新增轉換路由的步驟
9+
10+
1.`MacDoc+Convert.swift``switch (ext, target)` 加 case
11+
2. 寫對應的 `private func convert<Source>To<Target>(inputURL:)` 方法
12+
3.`validatedInputURL()` 驗證輸入(不要自己寫 guard)
13+
4.`writeStringOutput()``convertToFile/convertToStdout` 輸出
14+
5. 支援 `--full``--css`(如果輸出 HTML)
15+
6. Error messages 用中文(`找不到輸入檔案:`
16+
17+
## 已接線的路由
18+
19+
```
20+
(docx, md) → WordConverter
21+
(html, md) → HTMLConverter
22+
(md, html) → MarkdownConverter
23+
(srt, html) → SRTConverter(支援 --full + --css dark|light)
24+
(bib, html) → BibToAPAHTMLFormatter(支援 --full + --css minimal|web)
25+
(bib, md) → BibToAPAFormatter
26+
(bib, json) → BibToAPAJSONFormatter
27+
```
28+
29+
## 不該做的事
30+
31+
- 不要建新的 top-level subcommand 來做轉換(用 `convert`
32+
- 不要在 `convert` 裡重複實作 CLIHelpers 已有的功能
33+
- 不要用英文 error messages
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Error Messages 與輸出規範
2+
3+
## Error Messages
4+
5+
- 語言:**繁體中文**
6+
-`validatedInputURL()` 統一處理(輸出 `找不到輸入檔案: <path>`
7+
- 不要自己寫 `guard FileManager.default.fileExists`
8+
9+
```swift
10+
// 正確
11+
let inputURL = try validatedInputURL(input)
12+
13+
// 錯誤 — 不要這樣寫
14+
guard FileManager.default.fileExists(atPath: inputURL.path) else {
15+
throw ValidationError("File not found: \(input)") // ← 英文,不一致
16+
}
17+
```
18+
19+
## 輸出
20+
21+
-`writeStringOutput(_:to:)` 統一處理 file/stdout 分流
22+
- 寫入檔案後的狀態訊息寫到 stderr:`已寫入: <path>`
23+
- 不要重複實作 output 邏輯
24+
25+
## CSS / Full Document
26+
27+
- `--full` 輸出完整 HTML 文件(DOCTYPE + head + CSS + body)
28+
- `--css` 選擇 CSS 風格(值因格式而異)
29+
- bib: `minimal`(學術 Times New Roman), `web`(現代系統字體)
30+
- srt: `dark`(深色主題), `light`(淺色/列印)
31+
- 不指定 `--full` 時只輸出 HTML fragment
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# textutil 語法對映
2+
3+
macdoc 的 `convert` 子命令語法與 macOS 內建 `textutil` 對齊。
4+
使用者如果會用 `textutil`,應該能直覺地使用 `macdoc`
5+
6+
## textutil → macdoc 對照
7+
8+
```bash
9+
# textutil # macdoc
10+
textutil -convert html file.docx macdoc convert --to html file.docx
11+
textutil -info file.docx macdoc info file.docx (planned)
12+
textutil -convert txt -output o.txt macdoc convert --to md --output o.md file.docx
13+
textutil -convert html -stdout macdoc convert --to html --stdout file.md
14+
```
15+
16+
## 語法差異
17+
18+
| textutil | macdoc | 理由 |
19+
|----------|--------|------|
20+
| `-convert html` | `--to html` | swift-argument-parser 慣例用 `--` long flags |
21+
| `-output file` | `--output file` | 同上 |
22+
| `-format txt` | (自動偵測) | 從副檔名推斷,更簡潔 |
23+
| `-cat` | (不支援) | 合併多檔不在 scope 內 |
24+
25+
## Format 短名
26+
27+
| --to 值 | 全名 | 對應 package |
28+
|---------|------|-------------|
29+
| `md` | Markdown | `word-to-md`, `html-to-md`, `pdf-to-md` |
30+
| `html` | HTML | `md-to-html`, `srt-to-html`, `bib-apa-to-html` |
31+
| `docx` | Word | `md-to-word`, `html-to-word`, `pdf-to-docx` |
32+
| `json` | JSON | `bib-apa-to-json` |
33+
| `latex` | LaTeX | `pdf-to-latex` |
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Unix CLI 通用慣例
2+
3+
macdoc CLI 遵循標準 Unix 命令列工具的設計慣例。
4+
5+
## 規則
6+
7+
1. **檔案放最後**`macdoc convert --to md file.docx`,不是 `macdoc convert file.docx --to md`
8+
2. **stdout 是預設輸出** — 不指定 `--output` 時寫到 stdout,可 pipe 給其他工具
9+
3. **stderr 寫狀態訊息** — 進度、警告、「已寫入: path」等用 `FileHandle.standardError`
10+
4. **exit code** — 0 = 成功,非零 = 失敗(swift-argument-parser 自動處理)
11+
5. **input format 從副檔名自動偵測** — 不需要使用者指定 `--from`
12+
6. **`--stdout` 強制輸出到 stdout** — 覆蓋 `--output`(stdout 優先)
13+
7. **`--` long flags** — 遵循 GNU 慣例(`--to`, `--output`, `--full`),不用單 dash
14+
8. **靜默原則** — 成功時不輸出多餘訊息到 stderr,除非寫檔時報告路徑

.claude/rules/cli-textutil-compat.md

Lines changed: 0 additions & 63 deletions
This file was deleted.

.claude/rules/native-macos-compat.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ macdoc 必須優先使用 macOS 原生 framework 處理文件,不引入外部
2929

3030
## textutil 能力對照
3131

32-
`textutil` 是 macOS 內建的文件轉換 CLI,macdoc 的轉換指令語法與其相容(見 `cli-textutil-compat.md`)。
32+
`textutil` 是 macOS 內建的文件轉換 CLI,macdoc 的轉換指令語法與其相容(見 `cli-design/textutil-compat.md`)。
3333

3434
| textutil 支援 | macdoc 對應 | 差異 |
3535
|--------------|------------|------|
@@ -45,5 +45,5 @@ macdoc 必須優先使用 macOS 原生 framework 處理文件,不引入外部
4545
- [ ] 基礎提取用原生 framework(PDFKit / Vision / CoreGraphics)
4646
- [ ] 不引入可用原生替代的外部依賴
4747
- [ ] 如果需要外部依賴,記錄在上方「允許的例外」
48-
- [ ] CLI 語法遵循 `cli-textutil-compat.md`
48+
- [ ] CLI 語法遵循 `cli-design/` 規範(unix-conventions + textutil-compat + convert-entry-point)
4949
- [ ]`CONVERSIONS.md` 更新轉換矩陣

0 commit comments

Comments
 (0)