§

貼上 Markdown

§

原始

§

預覽

預覽經 DOMPurify 淨化 — script 標籤、事件處理器與 javascript: URI 在渲染前都會被剝離。

在台灣的技術寫作圈,Markdown 是日常工具。iThome 鐵人賽每年數千篇參賽文都以 Markdown 投稿;HackMD 是台灣團隊建立、被全球大量採用的 Markdown 協作平台;矽谷牛的耕田筆記、Huli 的工作日誌等知名工程部落格也都使用 Markdown。Cinnamon AI、Appier、KKBOX、和沛科技、玉山金控的工程團隊在其技術部落格與內部文件都採 Markdown 撰寫。中央研究院、國立臺灣大學、清華大學的學術寫作工作坊已開始介紹 Markdown 與 Pandoc 工作流;國發會、數位發展部主導的 Hugo / Docusaurus 政府開放文件站,也把 Markdown 當作版本控制下的源檔。Markdown 轉 HTML 是台灣技術寫作者與平台工程師每日例行的工作。

什麼是 Markdown 轉 HTML?

Markdown 是一種輕量級純文字格式,使用最少的標點(# 表示標題、* 表示強調、- 表示清單項目)來編碼結構化文章。GitHub Flavored Markdown(GFM)在原始 CommonMark 規格上擴充了表格、刪除線、任務清單與自動連結。HTML 則是瀏覽器最終呈現的形式。將 Markdown 轉為 HTML,讓你既能以輕量語法撰寫,又能輸出到渲染畫面 — 一個 README、靜態站頁面或郵件本文 — 無需手寫標籤。

支援哪些 GitHub Flavored Markdown 功能?

內建的 marked@12.0.2 解析器支援完整 GFM 超集:從 ####### 的 ATX 風格標題、可巢狀的有序與無序清單、粗體 **text** 與斜體 *text*、刪除線 ~~text~~、行內連結 [text](url) 與行內圖片 ![alt](src)、可帶語言標籤的圍欄程式碼區塊(```js)、行內程式碼 `code`、含表頭列的管道表格、GFM 任務清單 - [ ] / - [x]、引用區塊 >、水平分隔線 --- 以及自動連結。每個元素在預覽面板的渲染效果與 GitHub 完全一致。

Markdown 轉 HTML 是如何運作的?

每一次轉換都在你的瀏覽器中使用兩個內建函式庫本機執行 — 無 CDN、無 fetch、無遙測。主要步驟如下:

  1. 解析:marked.parse(source) 讀取你的 Markdown 並產出一段 HTML 字串。解析器在 GFM 模式下運行,因此表格、任務清單、刪除線和自動連結都能被識別。
  2. 淨化:HTML 輸出在指派給 innerHTML 之前會經過 DOMPurify.sanitize(html, { USE_PROFILES: { html: true } })。DOMPurify 是 Mozilla MDN、Atlassian、Microsoft 365 同款的 XSS 淨化器 — 它會解析 HTML、走訪 DOM,移除 <script> 元素、所有 on* 事件處理屬性,以及 javascript: URI 協定。
  3. 渲染:淨化後的 HTML 透過 innerHTML 寫入預覽面板,原始 HTML 則透過唯讀 <textarea> 在第二個面板呈現,方便你複製標記。即時模式會對輸入做 150 ms 去抖動,讓預覽在你輸入時持續更新而不會壓垮解析器。

為什麼用此工具將 Markdown 轉為 HTML?

  • 隱私:每一次解析、淨化與渲染都在你的瀏覽器中完成。Markdown — 包括未發布的部落格文章、內部文件草稿、機密 README 內容 — 永遠不會傳到我們的伺服器。
  • 預設 XSS 安全:渲染預覽面板會把每一段 HTML 字串先經過 DOMPurify,再餵給 innerHTML,因此 Markdown 中混入的 <script> 標籤或 onerror= 處理器只會產出一段不會動作的預覽。原始面板雖呈現未淨化字串,但它被放在唯讀 <textarea>value 中 — 不會被執行。
  • 完整 GFM:表格、刪除線、任務清單與自動連結的渲染效果與 GitHub 完全一致。Markdown 管道表格會生成帶有 <thead><tbody> 的 HTML <table> — 不丟列,不壓平結構。

Markdown 轉 HTML 的常見應用情境有哪些?

在文件撰寫、靜態站建設與電子郵件撰稿中,Markdown 轉 HTML 俯拾即是:

  • GitHub README 撰寫:在本機以 Markdown 起草專案 README,並在推送前預覽渲染後的 HTML。預覽效果在表格、任務清單與圍欄程式碼上與 GitHub 的 GFM 渲染器一致。
  • 靜態站內容:貼上一篇 Markdown 文章並取得 HTML,用於期望標記而非 Markdown 源碼的 CMS 欄位或範本引擎。
  • 電子郵件範本:以 Markdown 撰寫交易郵件本文,再轉為 HTML 餵給電子郵件服務商的範本引擎。輸出是純粹的語意化 HTML — 沒有行內樣式,也沒有郵件客戶端的奇怪覆蓋。

Markdown 轉 HTML 範例長什麼樣?

貼上 # Title\n\n- item 1\n- item 2\n\n[link](https://example.com),預覽面板會包含 <h1>Title</h1>、兩項無序清單以及一個 <a href="https://example.com">link</a>。原始面板顯示精確的 HTML 字串,方便你直接貼入範本。帶有 |---|---| 對齊列的管道表格會產出帶 <thead><tbody> 的完整 <table> — 確認 GFM 表格的渲染效果與 GitHub 一致。

這個 Markdown 轉 HTML 轉換器完全在我的瀏覽器中執行嗎?

是的。每一次解析、淨化與渲染都會以 JavaScript 在你的瀏覽器分頁本機執行。兩個內建函式庫 — marked@12.0.2DOMPurify@3.1.7 — 與頁面同源載入,因此沒有 CDN 依賴、沒有 fetch、沒有 XMLHttpRequest,也不會用 navigator.sendBeacon 回報輸入。頁面一旦載入完畢即可離線使用,因為它就是把第三方函式庫一併打包的靜態 HTML/CSS/JS 套件。未發布的文章、內部文件與機密 README 都留在你的裝置上。

渲染預覽面板是 XSS 安全的嗎?

是的。每一段指派給 innerHTML 的 HTML 字串都會先經過 DOMPurify.sanitize(html, { USE_PROFILES: { html: true } })。DOMPurify 是由 Cure53 維護的開源 XSS 淨化器,也是 Mozilla MDN、Atlassian、Microsoft 365 用來加固使用者提供 HTML 的同款函式庫。預設 html 設定會移除 <script> 元素、所有 on* 事件處理屬性(onerroronclick 等)、href / src 中的 javascript: URI 協定,以及已知有風險的 CSS 表示式。貼上 <img src=x onerror=alert(1)> 會得到一個預覽,其中 document.querySelector('#output-preview img[onerror]') 回傳 null,且不會跳出任何警示。

GFM 表格受支援嗎?

支援。Markdown → HTML 方向透過 marked 的 GFM 模式原生處理管道表格 — 一列表頭加上 |---|---| 對齊列,再加上資料列,會產出帶有 <thead><tbody><table>。刪除線(~~text~~<del>text</del>)與任務清單(- [ ] / - [x]<input type="checkbox">)的渲染效果與 GitHub 完全一致。

我的 Markdown 能無損轉換嗎?

對標準 GFM 功能集 — 從 h1h6 的標題、可巢狀的有序與無序清單、粗體 / 斜體 / 刪除線、行內連結、行內圖片、含語言標籤的圍欄程式碼區塊、行內程式碼、管道表格、任務清單、引用區塊、水平分隔線與自動連結 — HTML 輸出是穩定的,且與 GitHub 的渲染器一致。幾個值得了解的行為:Markdown 中嵌入的原始行內 HTML(例如 <sub>text</sub>)會原樣傳遞到輸出,而 CommonMark 的 setext 風格標題(=== 底線)與 ATX 標題(# Title)都會生成同一個 <h1>。這些是 marked 的既有行為,並非 bug。如果你需要反向轉換,將渲染後的 HTML 拉回 Markdown,請使用 HTML 轉 Markdown 工具。

圍欄程式碼區塊支援語法醒目提示嗎?

v1 中不支援。圍欄程式碼區塊以等寬字型與淡淡背景渲染,但沒有依語言的詞法上色。引入語法醒目提示需要打包 Prism 或 highlight.js,每個都會多增 15–40 KB,再加上每種語言的語法檔,以及需要與 Workshop Terminal 配色對齊的主題矩陣。目前渲染器把重點放在正確性與 XSS 安全上;若使用者對行內醒目提示有需求,做成可選開關是個可行的後續改進。

本 Markdown 轉 HTML 轉換器內建 marked@12.0.2DOMPurify@3.1.7,與頁面同源載入,支援完整 GFM 功能集,並在每段渲染後的 HTML 字串接觸 DOM 前進行淨化。無上傳、無 CDN、無遙測 — 每一個位元都留在你的瀏覽器中。