# 架構

本頁以一張概覽圖說明 NanoMD 的三個元件、它們共用的轉換管線，以及原始碼的分層方式。

## 系統概覽

```mermaid
graph LR
    User[使用者輸入] --> Editor[MDEditor]
    Editor -->|"init() 觸發重新渲染"| Viewer[MDViewer]
    Viewer -->|"讀取編輯器每一列文字"| Editor
    Viewer -->|Markdown| Trans["transToHTML()"]
    Parser[MDParser] -->|Markdown| Trans
    Editor -->|"download('html')"| Trans
    Trans -->|HTML 字串| Viewer
    Trans -->|HTML 字串| Parser
    Trans --> Funcs["set* 轉換函式<br/>src/function/"]
```

三個元件都不自己解析 Markdown，全部呼叫同一個 `transToHTML()`。差別在呼叫時帶入的參數：`MDViewer` 帶 hashtag 路徑與 target、一律使用擴充語法；`MDParser` 帶 `standard` 旗標；`MDEditor` 只在匯出 HTML 時呼叫。

## 分層

| 層 | 位置 | 職責 |
|---|---|---|
| 公開類別 | `src/model/editor.js`、`viewer.js`、`parser.js` | 對外 API；掛到 `window.MDEditor`／`MDViewer`／`MDParser` |
| 編輯器子模組 | `src/model/editorCaret.js`、`editorSelection.js`、`editorHistory.js`、`editorKeydown.js`、`editorTab.js` | 游標、選取範圍、復原堆疊、快捷鍵對應、工具列 |
| 虛擬 DOM | `src/model/vDOM.js` | 新舊節點樹比對；目前預覽器改用 `replaceChildren()` 整段替換，diff 未啟用 |
| 轉換函式 | `src/function/set*.js`、`transToHTML.js` | 每種語法一個函式，依固定順序執行 |
| 共用常數 | `src/data.js` | regex、字串常數、CDN 資源注入、`isDarkMode` |
| 樣式 | `src/sass/` → `dist/NanoMD.css`、`dist/NanoMD-output.css` | 編輯器／預覽器樣式與匯出 HTML 用樣式 |

## 跨切原則

| 原則 | 表現 |
|---|---|
| 零框架 | 只使用原生 DOM API；`createElement()` 是自家的輕量建構函式 |
| 單一轉換入口 | 所有 HTML 都由 `transToHTML()` 產生，語法行為在三個元件間一致（`standard` 旗標除外） |
| 佔位符隔離 | 已轉換的片段換成 `{{tag-uuid}}`，避免後續步驟重複解析，最後一次還原 |
| 全域建置 | `src/**/*.js` 由 terser 串接成一支腳本，函式與常數都在同一個 script scope |

## 延伸閱讀

- [轉換管線](/parsing-pipeline)：`transToHTML()` 的步驟順序
- [渲染與同步](/rendering-and-sync)：預覽器何時、如何重新渲染
- [完整架構文件](https://github.com/pardnchiu/NanoMD/blob/main/doc/architecture.md)：各模組圖、事件序列、vDOM 狀態機
