@helping-ai-workflow/md2doc 3.14.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,415 +1,215 @@
1
- # @helping-ai-workflow/md2doc
1
+ # md2doc
2
2
 
3
- > Markdown → HTML / PDF renderer with WaveDrom, Mermaid, Graphviz, and draw.io support.
3
+ **把 Markdown 轉成一份單檔 HTML 或 PDF:時序圖、狀態圖、方塊圖、公式直接畫好,離線就能看。**
4
4
 
5
- A single global CLI (`md2doc`) you can call from any directory.
5
+ <p align="center">
6
+ <img src="docs/images/readme/reader.jpg" width="820"
7
+ alt="閱讀頁:左邊是搜尋框和目錄,右邊是訊號表和 Graphviz 方塊圖">
8
+ </p>
9
+ <p align="center"><sub>轉出來的 HTML:左邊目錄跟著閱讀位置走,表格、程式碼、四種圖都排好了。截圖用的是虛構的示範文件。</sub></p>
6
10
 
7
- ## Install
11
+ md2doc 是一個命令列工具(`md2doc`),在哪個資料夾都能用。輸出是**一個檔案**:圖片、字型、圖表引擎全包在裡面,
12
+ 寄出去、丟進共用資料夾、斷網打開都一樣。加上 `--edit`,同一份文件可以直接在瀏覽器裡改,存回原本的 `.md`。
8
13
 
9
- Requires Node.js 18 or higher. The first install pulls puppeteer (≈ 170 MB Chromium download); subsequent installs reuse it.
14
+ 目前版本見 [CHANGELOG.md](CHANGELOG.md)。
10
15
 
11
- Chromium is needed for **PDF export**, for the optional `--bake-svg` flag, and for **`.drawio` diagrams**, which are always rendered to SVG at generation time. Everything else needs nothing extra — Graphviz runs in-process via WebAssembly, and Mermaid / WaveDrom are bundled and inlined.
16
+ ---
12
17
 
13
- Nothing is fetched at render time or at read time: every engine, including the vendored draw.io viewer, runs locally, so documents render and read **offline with no system Graphviz, no draw.io install and no CDN**.
18
+ ## 它幫你解決什麼
14
19
 
15
- ### Recommended: install via nvm
20
+ | 麻煩 | md2doc 怎麼處理 |
21
+ |---|---|
22
+ | 規格書裡的時序圖、狀態圖要另外畫、另外貼 | 在 Markdown 裡寫 `wavedrom`、`mermaid`、`dot` 程式碼區塊,或引用 `.drawio` 檔,轉檔時直接畫進去 |
23
+ | 轉出來的 HTML 一寄出去圖就破 | 本機圖片轉成 base64 內嵌,圖表引擎也內嵌;不連 CDN、不用裝 Graphviz 或 draw.io |
24
+ | 長文件找不到東西 | 側欄目錄跟著閱讀位置展開;全文搜尋會在內文標出每一筆 |
25
+ | 圖太小看不清楚 | 點一下圖就全螢幕開啟,可以縮放、平移,還能直接畫圈、畫箭頭做標註 |
26
+ | 晚上看白底很刺眼 | 右下角 ☀/☾ 切深色,圖表跟著變深;列印和 PDF 一律淺色 |
27
+ | 改一個字就要開編輯器、再轉一次 | `md2doc --edit`:點哪裡就改哪裡,波形圖有自己的編輯器,Ctrl+S 存回 `.md` |
28
+ | 編輯器把整份檔案重新排版、diff 一大片 | 只改你動過的那幾行,其他每個位元組都不變 |
16
29
 
17
- If you do not yet have Node.js — or your system Node lives under `/usr/local` and `npm install -g` fails with `EACCES` — install Node through [nvm](https://github.com/nvm-sh/nvm) first. nvm puts Node under `~/.nvm`, so global packages never need `sudo`.
30
+ ---
18
31
 
19
- ```bash
20
- sudo apt install -y curl # Debian / Ubuntu only; skip if curl is already installed
21
- curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
22
- source ~/.zshrc # or: source ~/.bashrc
23
- nvm install --lts
24
- nvm use --lts
25
- npm install -g @helping-ai-workflow/md2doc
26
- ```
32
+ ## 三步開始
27
33
 
28
- ### Already have Node.js
34
+ **1. 安裝**(需要 Node.js 18 以上)
29
35
 
30
36
  ```bash
31
37
  npm install -g @helping-ai-workflow/md2doc
32
38
  ```
33
39
 
34
- ### Troubleshooting
35
-
36
- **`EACCES: permission denied, mkdir '/usr/local/lib/node_modules'`**
37
- Your system Node is owned by root. Do **not** run `sudo npm install -g` — puppeteer's postinstall would download Chromium as root and break later runs. Instead, switch to nvm using the steps above.
40
+ 第一次安裝會下載 Chromium(約 170 MB),只有轉 PDF、`--bake-svg` 和 `.drawio` 圖會用到。
41
+ 還沒有 Node.js,或安裝時出現 `EACCES`,見下方[常見問題](#安裝時出現-eacces-permission-denied)。
38
42
 
39
- **`Failed to set up chrome ...! Set "PUPPETEER_SKIP_DOWNLOAD" env variable to skip download.`**
40
- An earlier install left a half-finished Chromium download in `~/.cache/puppeteer`. md2doc ≥ 1.0.3 cleans this automatically; on older versions, clear the cache and retry:
43
+ **2. 轉檔**
41
44
 
42
45
  ```bash
43
- rm -rf ~/.cache/puppeteer
44
- npm install -g @helping-ai-workflow/md2doc
46
+ md2doc spec.md # 轉成 HTML 並直接打開
47
+ md2doc spec.md --out spec.html # 寫到指定的檔案
48
+ md2doc --pdf spec.md # 轉成 PDF
45
49
  ```
46
50
 
47
- ## Usage
51
+ **3. 想改內容就加 `--edit`**
48
52
 
49
53
  ```bash
50
- md2doc foo.md # render HTML to OS temp dir, open viewer
51
- md2doc --pdf foo.md # render PDF instead
52
- md2doc --html --pdf foo.md # render both formats
53
- md2doc *.md # batch: each file → temp + open
54
-
55
- md2doc foo.md --out bar.html # write to a specific file (no auto-open)
56
- md2doc foo.md --out report.pdf # --pdf inferred from the extension
57
- md2doc foo.md --out ./build/ # write to ./build/foo.html (no auto-open)
58
- md2doc *.md --out ./build/ # batch into ./build/
59
- md2doc foo.md --out ./build/ --open # explicit open with --out
54
+ md2doc --edit spec.md
60
55
  ```
61
56
 
62
- By default, `md2doc` writes to your OS temp directory and launches the platform viewer.
63
- Pass `--out <path>` to write somewhere specific; doing so disables auto-open unless you
64
- also pass `--open`.
65
-
66
- ### Flags
57
+ 瀏覽器會開一個只有本機連得到的編輯頁,改完按 Ctrl+S 存檔。
67
58
 
68
- | Flag | Meaning |
69
- |---|---|
70
- | `--html` | Render HTML (default when neither `--html`/`--pdf` nor a `.pdf` file `--out` is given; directory targets always default to HTML). |
71
- | `--pdf` | Render PDF. Combine with `--html` to render both. |
72
- | `--out <path>` | Output path. Ends with `/` or an existing directory → directory mode. Ends with `.html` / `.pdf` → file mode (single input only). Without `--html`/`--pdf`, the extension selects the format. Implies `--no-open` unless `--open` is also passed. |
73
- | `--open` | Launch the platform viewer (`xdg-open` / `open` / `start`) after render. Default when `--out` is absent. |
74
- | `--no-open` | Skip the viewer launch. |
75
- | `--quiet` | Suppress per-file progress messages. |
76
- | `--bake-svg` | Pre-render Mermaid / WaveDrom to inert SVG at generation time (HTML output only; needs Chromium). The output then contains no diagram JavaScript. |
77
- | `--lang <tag>` | Set `<html lang>` (for example `en`, `zh-Hant`). Default: detected — `zh-Hant` when Chinese characters are at least 10% of the prose (code excluded), `ja` / `ko` when kana / Hangul make up at least 20% of the CJK characters, otherwise `en`. |
78
- | `--version`, `-v` | Print version. |
79
- | `--help`, `-h` | Print help. |
80
-
81
- ### Reading view
82
-
83
- - **Dark mode** — a ☀/☾ toggle (bottom-right on desktop, top bar on phone). Light by default; the choice is remembered in the browser. PDF and print stay light.
84
-
85
- ### Images
86
-
87
- Local images referenced from the markdown are resolved against the **markdown file's own
88
- directory** and inlined into the output as base64 `data:` URIs, so the rendered HTML / PDF
89
- stays self-contained wherever it is written (the OS temp dir by default) and however it is
90
- later copied or mailed.
91
-
92
- ```markdown
93
- ![block diagram](assets/block.png) <!-- inlined -->
94
- <img src="assets/block.png" width="400"> <!-- inlined, attributes preserved -->
95
- ![remote](https://example.com/x.png) <!-- left as a remote URL -->
96
- ```
97
-
98
- `srcset` and `<source>` inside `<picture>` are inlined too. Only known image
99
- extensions are inlined, so `![x](../../id_rsa)` is left alone rather than
100
- base64'd into a document you may be about to share.
101
-
102
- A reference with no file on disk keeps its original `src` and prints
103
- `[WARN] image not found, left as-is: ...` on stderr; the render still succeeds.
104
-
105
- Each reference carries its own copy of the payload, so re-using one large diagram
106
- in several places grows the HTML accordingly. PDF output is unaffected.
107
-
108
- ### Viewing diagrams
109
-
110
- Click any image, Mermaid, Graphviz, draw.io or WaveDrom graphic in the rendered HTML to
111
- open it full-screen.
112
-
113
- | Input | Action |
114
- |---|---|
115
- | Wheel / shift+wheel | Scroll vertically / horizontally |
116
- | Ctrl (or ⌘) + wheel | Zoom around the pointer |
117
- | Drag | Pan |
118
- | `+` `-` | Zoom in / out |
119
- | `0` `1` | Fit to window / actual size |
120
- | Double-click | Toggle fit ↔ 100% |
121
- | `Esc`, ✕, backdrop click | Close |
122
-
123
- Vector diagrams open scaled to fill the window; raster images open at actual size. An
124
- image wrapped in a link stays a link. The overlay is hidden in print and never reaches
125
- the PDF output.
59
+ ---
126
60
 
127
- ### Migration from md2html / md2pdf (v1.x → v2.0.0)
61
+ ## 介面一覽
62
+
63
+ <table>
64
+ <tr>
65
+ <td width="50%"><img src="docs/images/readme/search.jpg" alt="搜尋 tx_ready:側欄列出三筆結果,內文與目錄標黃"></td>
66
+ <td width="50%"><img src="docs/images/readme/dark.jpg" alt="深色模式:WaveDrom 時序圖與上色的 Verilog 程式碼"></td>
67
+ </tr>
68
+ <tr>
69
+ <td><sub><b>搜尋。</b>按 Enter 搜尋,結果列出所在章節,內文與目錄標黃,▲▼ 跳上一筆、下一筆。</sub></td>
70
+ <td><sub><b>深色模式。</b>時序圖、狀態圖跟著變深;程式碼有語法上色(Verilog、Python、C、Tcl 等),滑過區塊出現複製鍵。</sub></td>
71
+ </tr>
72
+ <tr>
73
+ <td colspan="2"><img src="docs/images/readme/lightbox.jpg" alt="燈箱:方塊圖放大到 266%,上方是縮放與標註工具列"></td>
74
+ </tr>
75
+ <tr>
76
+ <td colspan="2"><sub><b>點圖放大。</b>Ctrl+滾輪縮放、拖曳平移;<code>f</code> 手繪、<code>e</code> 橢圓、<code>r</code> 方框、<code>a</code> 箭頭,⧉ 連同標註一起複製成圖片。Esc 關閉。</sub></td>
77
+ </tr>
78
+ </table>
79
+
80
+ <p align="center">
81
+ <img src="docs/images/readme/phone.jpg" width="250" alt="手機:文件標題、文件資訊與公式">
82
+ <img src="docs/images/readme/phone-toc.jpg" width="250" alt="手機:☰ 打開的目錄抽屜">
83
+ </p>
84
+ <p align="center"><sub><b>手機。</b>頂列顯示目前章節,☰ 打開目錄;寬的表格左右捲動時,第一欄固定在左邊。</sub></p>
85
+
86
+ ### 編輯模式(`--edit`)
87
+
88
+ <p align="center"><img src="docs/images/readme/editor.jpg" width="820" alt="編輯頁:上方工具列,表格的一格正在編輯,選取的文字上方浮出格式工具列"></p>
89
+ <p align="center"><sub>點一格就能打字;選取文字浮出 B/I/刪除線/底線/程式碼/連結。右上角顯示存檔狀態。</sub></p>
90
+
91
+ - **點哪裡改哪裡**:段落、標題、清單、表格格子直接打字,看到的是排版後的樣子,不是 Markdown 符號。
92
+ - **區塊左邊的 ⠿ 與 +**:⠿ 拖曳排序、刪除、改格式,或開「MD 原始碼」直接改這一塊;+ 在下方插入新區塊。
93
+ - **表格**:Tab 換格、拖格子選範圍、滑過欄列出現握把,可以插入、刪除、拖曳排序。
94
+ - **存檔是手動的**:Ctrl+S 才寫回檔案;檔案在別處被改了,頁面會自動重新載入或提示衝突,不會蓋掉別人的修改。
95
+
96
+ <p align="center"><img src="docs/images/readme/wave-editor.jpg" width="820" alt="波形編輯器:上方電位工具列,下方是 WaveDrom 畫的 5 條訊號與關聯線"></p>
97
+ <p align="center"><sub><b>波形編輯器。</b>滑過時序圖按「編輯」打開。畫布就是輸出的那張圖:點一拍改電位、按住拖曳塗一段、拖圓點拉關聯線,? 看全部快捷鍵。</sub></p>
128
98
 
129
- | Old | New |
130
- |---|---|
131
- | `md2html foo.md` | `md2doc foo.md` |
132
- | `md2pdf foo.md` | `md2doc --pdf foo.md` |
133
- | `md2html foo.md --out f.html` | `md2doc foo.md --out f.html` |
134
- | `md2html foo.md --open` | `md2doc foo.md` (open is default) |
135
- | `md2html *.md` (output next to source) | `md2doc *.md --out ./build/` (or accept temp output) |
99
+ ---
136
100
 
137
- ## Editing (`--edit`)
101
+ ## 圖表與公式怎麼寫
138
102
 
139
- ```bash
140
- md2doc --edit foo.md # serve foo.md in the browser editor, open a tab
141
- md2doc --edit foo.md bar.md # one tab per file
142
- md2doc --edit foo.md --port 4000 # pin the server to a specific port
143
- md2doc --edit foo.md --no-open # start the server without launching a browser tab
103
+ ````markdown
104
+ ```wavedrom
105
+ { "signal": [ { "name": "clk", "wave": "p...." }, { "name": "req", "wave": "01.0." } ] }
144
106
  ```
145
107
 
146
- `--edit` starts a local (`127.0.0.1`-only) server and opens the rendered document in
147
- your browser. Click anywhere inside a paragraph, heading, list item, or table cell
148
- to place your cursor and start typing directly — no separate "select then edit" step.
149
- The block is live-marked as edited; focus leaving the block commits your changes
150
- automatically. Press `Ctrl+S` to save to disk explicitly.
151
-
152
- ### Direct editing: click to type
153
-
154
- Every paragraph, heading, list, and table cell is editable by clicking inside it.
155
- The rendered formatting (bold, italic, code, links) displays as you type; no
156
- Markdown syntax characters are shown. This applies to any block that doesn't
157
- contain unsupported content (see "Degraded blocks" below).
158
-
159
- | Block type | Interaction |
160
- |---|---|
161
- | Paragraph | Click to place caret, type; Enter commits, Esc reverts |
162
- | Heading | Click to place caret, type; Enter commits, Esc reverts |
163
- | List | Click to place caret, type; list-specific keys below |
164
- | Table | Click any cell to edit; Tab/Shift+Tab navigate between cells |
165
-
166
- ### ⠿ Block menu
167
-
168
- Every block has a ⠿ button on its left edge. Click it to open a menu with block-level
169
- operations:
170
-
171
- | Item | Applies to | Action |
172
- |---|---|---|
173
- | **−** (minus) | Heading only | Decrease heading level (# → ... → #####) |
174
- | **+** (plus) | Heading only | Increase heading level |
175
- | **MD 原始碼** | All blocks | Discard in-progress edits, switch to raw Markdown source editing |
176
- | **刪除** | All blocks | Delete the block entirely (absorbs one adjacent blank line; one Ctrl+Z restores it exactly) |
177
- | **✕** | All blocks | Close the menu |
178
-
179
- The **MD 原始碼** button is the escape hatch: it reverts any unsaved typing in the
180
- current block and opens the raw Markdown editor instead, letting you make changes
181
- WYSIWYG cannot express.
182
-
183
- ### + Insert menu
184
-
185
- Every block also has a + button, stacked just above the ⠿ handle in the same left
186
- gutter. Click it to open a menu for inserting a new block directly below:
187
-
188
- | Item | Inserts |
189
- |---|---|
190
- | **段落** | An empty paragraph |
191
- | **標題** | An empty `##` heading |
192
- | **清單** | An empty single-item list |
193
- | **表格** | A minimal 2×2 table skeleton |
194
- | **程式碼** | An empty fenced code block |
195
-
196
- The new block is inserted below the block whose + you clicked, and the cursor lands
197
- directly in it — the first (body) cell for a table, the raw source editor for a code
198
- block, and the always-on WYSIWYG surface (pre-selected, so your first keystroke
199
- replaces the placeholder) for everything else. The whole insert is a single Ctrl+Z
200
- step — one undo removes the block entirely.
201
-
202
- ### Paragraph and heading editing
203
-
204
- Click inside a paragraph or heading to place your cursor. Type and format text
205
- normally; the rendered marks (bold, italic, code, links) show as you type.
206
-
207
- **Selection toolbar**: when you select text inside a paragraph or heading, a
208
- floating toolbar appears with formatting buttons:
209
-
210
- | Button | Action |
211
- |---|---|
212
- | **B** | Toggle bold (`**text**`) |
213
- | **I** | Toggle italic (`*text*`) |
214
- | **`<>`** | Wrap selection in backticks (`` `code` ``) |
215
- | **🔗** | Wrap selection as a link; click to edit the URL |
216
-
217
- **Key shortcuts**:
218
-
219
- | Key | Action |
220
- |---|---|
221
- | Enter | Commit and close the editor |
222
- | Shift + Enter | Insert a line break within the paragraph |
223
- | Esc | Revert all edits and close the editor |
224
- | Ctrl + Z | Step backward through the paragraph's local edit history, then cascade to document-level undos once exhausted |
225
- | Ctrl + Y (or Ctrl + Shift + Z) | Step forward through the paragraph's local edit history, then cascade to document-level redos once exhausted |
226
-
227
- ### List editing
228
-
229
- Click inside a list item to place your cursor and type. Lists support structural editing:
230
-
231
- | Key | Action |
232
- |---|---|
233
- | Enter | Split the current item into two siblings at the caret; empty item + Enter removes it and ends the burst |
234
- | Shift + Enter | Insert a line break (`<br>`) within the item (does not split) |
235
- | Tab | Indent the current item (becomes a child of the previous sibling; no-op if no previous sibling) |
236
- | Shift + Tab | Outdent the current item (moves after its parent; no-op at top level) |
237
- | Esc | Revert all edits and close the list |
238
- | Ctrl + Z / Ctrl + Y | Step through the list's local edit history, then cascade to document-level history |
108
+ ```mermaid
109
+ stateDiagram-v2
110
+ IDLE --> BUSY: start
111
+ ```
239
112
 
240
- An empty list (all items removed) is cleaned up automatically — the block is deleted
241
- entirely and the document structure stays consistent.
113
+ ```dot
114
+ digraph G { cpu -> bus -> uart }
115
+ ```
242
116
 
243
- ### Table editing
117
+ ![系統架構](arch.drawio) <!-- #Flow 選分頁名稱,#2 選第 2 頁 -->
244
118
 
245
- Click any table cell to edit it. The table is treated as a single editing unit —
246
- focus remains inside the table until you press Esc, click outside, or navigate away.
119
+ $$ f_{baud} = \frac{f_{clk}}{16 (div + 1)} $$
120
+ ````
247
121
 
248
- **Cell navigation**:
122
+ Mermaid 與 WaveDrom 預設在瀏覽器裡畫,加 `--bake-svg` 改成轉檔時就畫成 SVG(輸出裡不帶 JavaScript)。
123
+ Graphviz 與 draw.io 一律在轉檔時畫好。本機圖片(`![](assets/x.png)`、`<img>`、`<picture>`)以 `.md` 所在的資料夾為準,轉檔時內嵌。
249
124
 
250
- | Key / Action | Effect |
251
- |---|---|
252
- | Click a cell | Move to that cell and edit |
253
- | Tab | Move to the next cell (left-to-right, row by row; no-op — stays put — on the last cell) |
254
- | Shift + Tab | Move to the previous cell |
255
- | Enter | Insert a line break (`<br>`) within the cell (does NOT commit the table) |
256
- | Esc | Revert the entire table session (all cells) and discard all changes |
257
- | Ctrl + Z / Ctrl + Y | Step through the table's local edit history, then cascade to document-level history |
258
-
259
- **Column grip**: hover any cell in a column — a small horizontal 6-dot grip handle
260
- appears just above it (Notion-style affordance, replacing the old edge-hover-only
261
- target). Click the grip to open the column menu:
262
-
263
- | Option | Action |
264
- |---|---|
265
- | **刪除欄** | Delete the column (last column protected) |
266
- | **對齊** | Cycle alignment: left → center → right → left (no unset state; use Ctrl+Z to revert a cycle) |
267
-
268
- A **+** insert bubble separately appears when you hover the top boundary between
269
- two columns — click it to insert an empty column there.
125
+ ---
270
126
 
271
- **Row grip**: hover any cell in a body row — a small vertical 6-dot grip handle
272
- appears just left of it (the header row never gets one; it isn't deletable or
273
- draggable). Click the grip to open the row menu:
127
+ ## 常用參數
274
128
 
275
- | Option | Action |
129
+ | 參數 | 作用 |
276
130
  |---|---|
277
- | **刪除列** | Delete the row (header row and last body row protected) |
278
- | *Drag* | Press and hold the row grip and drag up/down; drop to reorder (body rows only; header fixed) |
279
-
280
- A **+** insert bubble separately appears when you hover the left boundary between
281
- two rows — click it to insert an empty row there.
282
-
283
- **Edited tables emit minimal form**: tables that you edit are saved with single-space
284
- padding and minimal separators (`|---|`) to keep the Markdown readable and
285
- version-control-friendly.
286
-
287
- ### Degraded blocks: code, diagrams, images, math
131
+ | `--out <path>` | 輸出到指定的檔案或資料夾(`./build/`);副檔名 `.pdf` 就轉 PDF。指定後不自動打開,要打開再加 `--open` |
132
+ | `--pdf`、`--html` | 選輸出格式,兩個都加就兩種都轉 |
133
+ | `--edit [--port <n>]` | 在瀏覽器裡編輯,可以一次開多個檔案 |
134
+ | `--bake-svg` | Mermaid/WaveDrom 在轉檔時就畫成 SVG |
135
+ | `--lang <tag>` | 指定 `<html lang>`;不指定時依內容自動判斷(`zh-Hant`、`ja`、`ko`、`en`) |
136
+ | `--quiet` | 不印進度 |
288
137
 
289
- Blocks containing content WYSIWYG cannot represent (code fences, Mermaid/Graphviz/
290
- WaveDrom/draw.io diagrams, images, LaTeX math, or unstyled HTML) automatically degrade to
291
- raw-edit mode: click the block to open the raw Markdown source in a textarea, make
292
- your changes, then press `Ctrl+Enter` to commit or `Esc` to cancel.
138
+ `md2doc *.md --out ./build/` 一次轉整個資料夾。完整說明:`md2doc --help`。
293
139
 
294
- If a WYSIWYG session encounters unsupported content mid-edit (e.g., via a rich
295
- paste), it automatically falls back to raw-edit with the block's untouched
296
- on-disk source, preserving your unsaved work context.
140
+ ---
297
141
 
298
- ### Burst undo: local history + cascade
142
+ ## 常見問題
299
143
 
300
- Ctrl+Z / Ctrl+Y step through a block's local edit history first (the changes you
301
- made in the current editing session). Once that history is exhausted, the next
302
- Ctrl+Z cascades out to the document-level undo stack, covering all committed edits.
303
- This lets you undo/redo recent changes within a block without affecting work in
304
- other blocks.
144
+ ### 安裝時出現 `EACCES: permission denied`
305
145
 
306
- ### Whole-document controls
146
+ 系統的 Node.js 裝在 root 的目錄底下。**不要**用 `sudo npm install -g`(Chromium 會以 root 下載,之後執行會壞),改用 [nvm](https://github.com/nvm-sh/nvm) 裝 Node.js:
307
147
 
308
- | Key / control | Action |
309
- |---|---|
310
- | `Ctrl`/`⌘` + `S` | Save the document to disk (explicit; changes commit locally when focus leaves) |
311
- | `Ctrl`/`⌘` + `Z` | Undo: first steps through the focused block's local history, then cascades to document level |
312
- | `Ctrl`/`⌘` + `Y` (or `Ctrl`/`⌘` + `Shift` + `Z`) | Redo: mirrors undo's cascade behavior |
313
- | Click outside any block | Commit any open block if changed, dismiss the ⠿/+ menu |
314
- | `Esc` (at document level, not in an open block) | Close the ⠿/+ menu |
148
+ ```bash
149
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
150
+ source ~/.zshrc # 或 ~/.bashrc
151
+ nvm install --lts
152
+ npm install -g @helping-ai-workflow/md2doc
153
+ ```
315
154
 
316
- ### Auto-commit on focus change
155
+ ### 安裝時出現 `Failed to set up chrome`
317
156
 
318
- When focus leaves a block:
319
- - If the block is **unchanged**, it closes silently.
320
- - If the block is **changed**, it commits automatically to the undo stack (but not to disk — you must press Ctrl+S for that).
157
+ 之前的安裝留下下載到一半的 Chromium。刪掉 `~/.cache/puppeteer` 再裝一次:
321
158
 
322
- This means switching between blocks flows naturally — you never get stuck waiting to
323
- confirm or cancel.
159
+ ```bash
160
+ rm -rf ~/.cache/puppeteer && npm install -g @helping-ai-workflow/md2doc
161
+ ```
324
162
 
325
- ### Save and conflict handling
163
+ ### 編輯模式會不會把我的格式改掉?
326
164
 
327
- **Save is explicit, not autosave**. Your changes are committed to the undo stack
328
- immediately when you press Enter or focus leaves a block, but they're not written
329
- to disk until you press `Ctrl+S`.
165
+ 不會。只有你按 Enter、或離開時有改過的區塊會重寫;其他行(包含對齊用的空白、行尾空白、檔尾換行)一個位元組都不動。
166
+ 你改過的表格會存成最精簡的寫法(`| a | b |`、`|---|`)。
330
167
 
331
- **Conflict detection**: each save carries the file's last-known modification time.
332
- If the file on disk has changed since the page loaded (edited elsewhere, or saved
333
- from another tab), the save is rejected with a conflict banner instead of silently
334
- overwriting — reload the page to pick up the newer content, then re-apply your edit.
168
+ ### 在編輯模式裡新增了第一張 Mermaid/WaveDrom 圖或第一個公式,卻沒畫出來?
335
169
 
336
- ### Fidelity guarantee
170
+ 頁面打開時文件裡沒有這種圖,所以沒載入它的引擎。重新整理瀏覽器分頁就好,不用重開 `md2doc --edit`。
337
171
 
338
- Only the lines inside the block(s) you actually commit are rewritten. Every other
339
- line — including whitespace-sensitive formatting like padded table columns, trailing
340
- spaces, and the file's original EOF-newline state — is left byte-for-byte untouched,
341
- whether you save with zero edits or after several. This applies both to unchanged
342
- blocks and to blocks you open and then revert.
172
+ ### 轉檔時 stderr 出現 `data labels are wider than their segments`?
343
173
 
344
- ### Known Phase-3 limitations
174
+ WaveDrom 圖裡有資料標籤比它那一段還寬。訊息會說最寬的是哪一個,以及 `config.hscale` 要設多少才放得下;輸出照常產生,exit code 仍是 0。
345
175
 
346
- **First diagram/math type requires reload**: if a committed edit introduces the
347
- *first* occurrence of a diagram type (Mermaid or WaveDrom) that the document didn't
348
- already contain when the page was loaded, that diagram library was never embedded
349
- into the page, so the new block renders as raw source until you reload the browser
350
- tab (no need to restart `md2doc --edit`). The same applies to math: if a committed
351
- edit introduces the document's *first* `math` fence or `$…$`/`$$…$$` expression,
352
- the KaTeX stylesheet was never injected, so the equation renders unstyled until you
353
- reload the tab.
176
+ ### 從 md2html/md2pdf(v1.x)升級
354
177
 
355
- **Alignment cycle has no unset state**: the **對齊** button cycles through left,
356
- center, and right alignment. To revert an unwanted alignment, use Ctrl+Z.
178
+ `md2html foo.md` 改成 `md2doc foo.md`,`md2pdf foo.md` 改成 `md2doc --pdf foo.md`。
179
+ 以前輸出會寫在原始檔旁邊,現在預設寫到暫存資料夾;要寫在固定的地方就加 `--out ./build/`。
357
180
 
358
181
  ---
359
182
 
360
- `--edit` does not support directory inputs yet (planned for a later phase) and
361
- cannot be combined with `--html` / `--pdf` / `--out` / `--bake-svg`.
362
-
363
- ## Supported diagram types
364
-
365
- Embedded in fenced code blocks inside your Markdown:
366
-
367
- ````markdown
368
- ```mermaid
369
- graph LR
370
- A --> B
371
- ```
372
-
373
- ```wavedrom
374
- { "signal": [...] }
375
- ```
183
+ ## 開發者資訊
376
184
 
377
- ```dot
378
- digraph G { A -> B }
379
- ```
380
- ````
185
+ <details>
186
+ <summary><b>目錄、測試、截圖</b></summary>
381
187
 
382
- A fourth engine, **draw.io**, is referenced with image syntax rather than a code fence, because a `.drawio` file is an external artifact rather than inline source:
188
+ | 路徑 | 內容 |
189
+ |---|---|
190
+ | `bin/md2doc.js` | 命令列入口 |
191
+ | `lib/md2doc.js` | 轉檔主程式(閱讀頁的 HTML、CSS、JavaScript 都在這裡) |
192
+ | `lib/editor/` | `--edit` 的本機伺服器與編輯器 |
193
+ | `lib/theme/` | 深色模式的配色表與切換 |
194
+ | `vendor/drawio/` | 內附的 draw.io viewer(Apache-2.0) |
195
+ | `test/` | 測試 |
383
196
 
384
- ```markdown
385
- ![Architecture overview](arch.drawio)
386
- ![Just the Flow sheet](arch.drawio#Flow)
387
- ![Just the second sheet](arch.drawio#2)
197
+ ```bash
198
+ npm test # 轉檔與編輯器的測試
199
+ npm run test:browser # 在 Chromium 與 WebKit 實際點過閱讀頁和編輯頁
200
+ # (第一次先跑 npx playwright install chromium webkit)
201
+ node docs/readme/shots.js # 重新產生 README 的截圖(用 docs/readme/demo.md)
388
202
  ```
389
203
 
390
- A `.xml` file is treated as a diagram only when its root element really is `<mxfile>` or `<mxGraphModel>`; anything else falls through to the ordinary image path unchanged. `#Name` selects a sheet by name, `#N` by 1-based position (a name wins over a number). The alt text becomes the rendered box's accessible name. Multi-sheet files get a small sheet bar on hover — every sheet is baked into the output, so switching sheets involves no engine.
391
-
392
- All four render directly in the output (HTML or PDF), **offline and with no system dependencies**: Graphviz `dot` runs in-process via WebAssembly (no system `dot` binary required), Mermaid / WaveDrom are bundled and inlined (no CDN), and `.drawio` files are rendered by a vendored draw.io viewer running in a build-time headless Chromium. Each engine's runtime is embedded only when the document actually uses that diagram type — and the draw.io viewer never is, at any size, because `.drawio` diagrams are fully pre-rendered (a multi-sheet document carries only a few lines of sheet-switching script, not an engine).
393
-
394
- By default, Mermaid and WaveDrom render in the browser when the HTML is opened; pass `--bake-svg` to pre-render them to inert SVG at generation time instead (Graphviz and draw.io are always pre-rendered to SVG).
204
+ 貢獻規則與發版流程見 [CLAUDE.md](CLAUDE.md)。
395
205
 
396
- ## Why a global CLI
206
+ </details>
397
207
 
398
- Multiple repos used to ship copies of this script. They drifted. This package centralises the renderer so every repo references the same version. See [`docs/why.md`](https://github.com/helping-ai-workflow/md2doc) for background.
399
-
400
- ## Licence
208
+ ---
401
209
 
402
- md2doc's own source is **MIT** — see [`LICENSE`](LICENSE).
210
+ ## 授權
403
211
 
404
- The published package is not MIT-only, because it ships one vendored
405
- third-party file: `vendor/drawio/viewer-static.min.js`, the draw.io /
406
- diagrams.net viewer (v31.3.2, ~4 MB), under the **Apache License 2.0**.
407
- Its licence text and a per-component NOTICE travel with it, in
408
- [`vendor/drawio/LICENSE`](vendor/drawio/LICENSE) and
409
- [`vendor/drawio/NOTICE`](vendor/drawio/NOTICE).
212
+ md2doc 本身是 **MIT**,見 [`LICENSE`](LICENSE)。
410
213
 
411
- **Running a licence scan? Start at
412
- [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md).** It lists everything
413
- redistributed inside the tarball, including the components bundled inside
414
- the draw.io viewer itself (DOMPurify, pako, spin.js, Rough.js), and says
415
- how each finding was established.
214
+ npm 套件裡另外附了一個第三方檔案:`vendor/drawio/viewer-static.min.js`(draw.io/diagrams.net viewer v31.3.2),授權是 **Apache License 2.0**,
215
+ 授權全文與 NOTICE 在 [`vendor/drawio/`](vendor/drawio/)。要做授權掃描,從 [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md) 開始看。