我以遷移內容為生,任何經營 WordPress 網站十年的人最終都會這樣做。當我將一批舊貼文從頁面建立器轉移到基於 Markdown 的文檔系統中時,我發現了什麼 "乾淨的 HTML"在野外的真正意義是: <p> 內聯樣式的標籤,空 <span>s 包裹單字, <div>s 一個段落深處的三個級別,以及偶爾從未關閉的標籤。將其貼到 Markdown 欄位中給了我一堵文字尖括號牆。複製貼上 渲染 文字遺失了所有連結、標題和清單。這兩條捷徑都沒有起作用,我最終用手清理了一個下午的文章,然後才意識到這一點。
變得明智意味著將 HTML 到 Markdown 視為它原本的樣子:具有一組清晰規則的結構化轉換,而不是複製貼上。標題元素變成一個 # 線。粗體變成 **. 連結變成 [text](url). 一張桌子變成了一張管桌。一旦你有了這些映射和一個足夠寬容的解析器來在現實世界的標記中生存下來,轉換就會變得無聊和可靠--這正是你想要的。我建造 工具。dev 並放置一個基於瀏覽器的 HTML 到 Markdown 轉換器 其中應用了這些規則,但本指南是關於規則本身的,因此您可以了解輸出應該是什麼樣子以及原因。
TL;DR: 若要將 HTML 轉換為 Markdown,請將區塊元素對應到其 Markdown 等效項 ((
<h2>→##,<ul><li>→-,<blockquote>→>,<pre><code>→ 圍欄塊,映射內聯元素 (<strong>→**,<em>→*,<a>→[text](href),<img>→),轉身<table>在 GitHub 風味 Markdown 管表中,將 HTML 實體解碼回真實字符,然後丟棄<script>/<style>. 使用能夠容忍未關閉標籤的解析器,並在瀏覽器中執行此操作,以便您的內容永遠不會上傳。
為什麼要將 HTML 轉換為 Markdown?
Markdown 是現代開發人員網路的便攜式格式。自述文件、文件網站、靜態部落格(Hugo、Jekyll、Astro、Next。js 內容)、注意黑曜石和Bear 等應用程式、GitHub 問題,以及我們提供給AI 模型的越來越多的提示和上下文- 所有這些都講Markdown。它'純文本,它在 Git 中清晰地差異,並且在從一個系統移動到另一個系統時倖存下來,而不會拖曳一堆演示標記。
相比之下,HTML 就是你 最終與 每當內容經過瀏覽器或所見即所得編輯器時。從網頁複製一個部分,從 CMS 導出,從 API 中提取文章正文,或從富文本欄位中獲取格式化文本,然後您就會得到 HTML - 通常是雜亂的 HTML,充滿了包裝元素和內聯樣式您不知道'不想出現在乾淨的文檔中。轉換是從" 的橋樑;內容被困在簡報標記和引用中;到&引用;內容我可以在任何地方版本、編輯和重新發布。&引用;
一旦您注意到這些場景,它們就會不斷重複出現。將部落格從 WordPress 或 Medium 上遷移。從舊版 HTML 幫助系統中提取文件。將抓取的文章轉換為 Markdown 註釋。將電子郵件通訊'將 HTML 轉換為 Markdown 草稿。提供網頁'將內容作為乾淨的上下文提供給法學碩士,而不是浪費代幣的原始 HTML <div> 湯。在每種情況下,手動替代方案(重新打字或複製貼上渲染文字並手動重建格式)都是緩慢且有損的。基於規則的轉換器兩者都不是。
HTML 如何對應到 Markdown?
映射自然地分為兩層:區塊級結構和內聯格式化。
塊元素 定義文檔's 骨架,每個骨架都有一個直接的 Markdown 對應項:
<h1>相對<h6>成為#通過######標題行。<p>成為一個以空白行分隔的段落。<ul>/<li>成為-項目符號列表;<ol>/<li>成為1.編號列表和嵌套列表縮排兩個空格。<blockquote>每行的前綴為>.<hr>成為---.<pre><code>成為具有三重反向勾號的圍欄代碼塊。<table>成為 GitHub 風味 Markdown 管桌。
內聯元素 裝飾這些區塊內的文字:
<strong>和<b>成為**bold**.<em>和<i>成為*italic*.<code>成為`inline code`.<a href="...">成為[link text](href),保留title存在時的屬性。<img>成為.<del>和<s>成為~~strikethrough~~(github 風味 Markdown 擴充)。<br>變成硬線突破-換行線前有兩個尾隨空格。
在 HTML 的真實區塊上執行這些規則,並且結構完好無損。給定此輸入:
<article>
<h1>Getting Started</h1>
<p>Convert <strong>HTML</strong> into clean <em>Markdown</em>.</p>
<ul>
<li>Paste from a CMS</li>
<li>Get portable output</li>
</ul>
<pre><code class="language-js">const md = convert(html)</code></pre>
</article>
你得到:
# Getting Started
Convert **HTML** into clean *Markdown*.
- Paste from a CMS
- Get portable output
```js
const md = convert(html)
```
該輸出中的兩個細節值得關注。首先, <article> 包裝器沒有貢獻任何東西--像結構容器一樣 <article>, <section>, 和 <div> 是透明的;轉換器會重複進入它們並將它們的孩子呈現為方塊。其次,代碼柵欄被拾起 js 作為它的語言。那'因為 <code> 攜帶的元素 class="language-js",使用約定語法螢光筆,一個好的轉換器讀取該類別來標記柵欄。它'這是一個小問題,它區分了在文檔網站上突出顯示的程式碼區塊和沒有't 的程式碼區塊。
是什麼讓轉換器在現實世界的 HTML 中倖存下來?
上面的規則是簡單的部分。手動捲起的正規表示式轉換器失敗的原因 - 以及 I'寫了一些並扔掉了幾個 - 是真正的 HTML 不斷打破假設。三個問題一次又一次地出現。
未關閉的標籤。 瀏覽器以寬容而聞名: <p>one<p>two 呈現為兩段,因為 a <p> 當另一個區塊元素開啟時隱式關閉,並且 <li>a<li>b 是兩個清單項目出於相同的原因。一個僅在顯式上關閉元素的樸素解析器 </p> 將第二段嵌套在第一段內並損壞下游的所有內容。強大的轉換器應用 HTML 規範定義的相同隱含結束標記規則:開啟區塊級元素關閉開啟的段落;打開一個 <li> 關閉前一個。我的轉換器會執行此操作,這就是為什麼貼上草率的 CMS 輸出通常只是起作用的原因。
<script> 和 <style> 塊。 它們包含程式碼和 CSS,而不是內容,並且它們的內容必須逐字記錄 (a) < javascript 內部不是標籤,然後完全刪除。忘記特殊情況,您會讓 JavaScript 來源滲入您的 Markdown。
HTML 實體。 網路內容隨處可見 &, ©, —, ,以及數字引用,例如 ’. 在 Markdown(純文字)中,您想要實際字元: &, ©, —,還有一個真正的撇號。解碼命名和數字實體不是可選的;跳過它,乾淨的 Markdown 讀起來就像查看來源一樣。
這就是為什麼我停止嘗試使用查找和替換來轉換 HTML,而是建立了一個適當的容忍解析器。它將 HTML 代幣化為一棵樹 - 處理註解、無效元素等 <br> 和 <img>,大寫標籤名稱和不引用的屬性 - 然後在樹上行走,發出 Markdown。值得注意的是,它不't 依賴瀏覽器's DOM,這意味著相同的邏輯也在伺服器上運行,但給您的實際回報很簡單:它不't 拋出真實網站組成的混亂標記。
如何使用轉換器?
打開 Toolz.dev/tools/html-to-markdown,將 HTML 貼到左側窗格中,鍵入時 Markdown 出現在右側 - there's 無需上傳,也無需尋找轉換按鈕。如果您想立即查看每個支援的構造,請載入範例。
一些選項涵蓋了常見的偏好。選擇您的子彈字元 (-, *,或者 +) 對於與您的項目相符的無序列表'風格。為表格和刪除線保留 GitHub 風味標記,如果您的目標僅接受 CommonMark,則關閉 GitHub 風味標記。切換並引用;保留連結和引用;當您需要散文但不需要 URL 時關閉 - 方便將連結較多的文章轉換為乾淨的閱讀文本 - 和 "保留圖像和引用;完全刪除圖像。統計行顯示單字、標題、連結、圖像、程式碼區塊和估計的閱讀時間,這是在將結果貼到某個地方之前對該結構進行的快速理智檢查。
與網站上的所有內容一樣,轉換是 100% 客戶端。解析器是在瀏覽器中運行的普通 JavaScript,因此貼上的頁面、內部文件和未發布的草稿永遠不會發送到任何地方。 That'這是內容工作的正確預設值 - 您應該'必須將草稿上傳到陌生人'伺服器只是為了重新格式化它 - 這意味著該工具保持離線工作。我更深入地探討了為什麼瀏覽器端處理很重要 資料隱私工具指南.
HTML 與 Markdown:何時使用哪個
在它們之間轉換很容易;知道你想要什麼才是真正的決定。
| 方面 | HTML | 降價 |
|---|---|---|
| 主要目的 | 在瀏覽器中渲染 | 寫入和儲存文字 |
| 可讀性作為來源 | 可憐(標籤重) | 優秀(讀作純文字) |
| Git 差異 | 吵鬧 | 乾淨的 |
| 跨系統的可移植性 | 低 | 高 |
| 精確的佈局控制 | 滿的 | 設計有限 |
| 它居住的地方 | 網頁,所見即所得輸出 | 自述文件、文件、筆記、靜態網站 |
| 學習曲線 | 陡峭 | 分鐘 |
Markdown 故意為了簡單起見而交換佈局控制,這就是為什麼它會在您編寫的內容、版本和移動中獲勝,而在您需要像素級演示時會失敗。當您'正在捕獲或遷移時,將 HTML 轉換為 Markdown 內容;當你'正在建構一個 頁面。 當您需要走另一條路時 - 記入 HTML 以取得 CMS 欄位或電子郵件範本 - 標記為 HTML 轉換器 是該工具的鏡像,具有相同的約定,因此兩次往返對於共同的結構來說是乾淨的。
這適合內容工作流程
格式轉換很少是整個工作;它'一步。將文章轉換為 Markdown I' 後;通常會透過 a 運行文字 字計數器 要檢查針對目標的長度,以及來源是否具有需要編碼回其他目的地的 HTML 實體, HTML 實體編碼器/解碼器 處理相反的情況。當 I'm 在轉換前清理手寫的 HTML 時, HTML 縮小器 首先消除噪音。這些小工具連結在一起形成一個可重複的管道,這就是我如何思考基於瀏覽器的工具包背後的整個想法 - 我在其中闡述了這個理念 web 開發人員工具包指南 而且更廣泛 編碼工具指南.
將 HTML 轉換為 Markdown 的常見錯誤
複製貼上渲染文本而不是轉換 HTML。 您將失去連結、標題和清單 - 所有結構。轉換實際標記。
忽略程式碼語言類別。 如果你的圍欄塊出來時沒有語言並且沒有't突出顯示,轉換器會丟棄 class="language-x" 提示。一個好人讀了它。
假設 CommonMark 和 GFM 相同。 表格和刪除線是 GitHub 風格的 Markdown 擴展,而不是核心 CommonMark。如果您的目的地是嚴格的 CommonMark,則會贏得一個表格並#39;t 渲染 - 轉換並關閉 GFM 並以其他方式處理表格。
信任上傳內容的轉換器。 充足的"免費&引用;線上轉換器將您的 HTML 發佈到伺服器。對於任何未發布或內部的內容,即 ' 洩漏。使用客戶端工具。
問號
如何將 HTML 轉換為 Markdown?
將 HTML 貼到編輯器中,Markdown 會立即出現 - 沒有檔案可上傳,也沒有轉換按鈕可按。如果您願意,請調整項目符號樣式或連結處理,然後複製 Markdown 或將其作為。md 檔案下載。
轉換器可以處理表嗎?
是的。啟用 GitHub 風味 Markdown 後,即可使用 HTML <table> 變成markdown管桌:第一行變成標題,插入分隔行,其餘行變成正文。單元格內的管道字元被轉義,這樣它們就不會破壞表格。
連結和圖像會發生什麼?
錨成為 [link text](href) 影像變得 ,在存在時保留標題屬性。如果您關閉並引用;保留連結和引用;保留錨文本,但刪除 URL,並關閉 "保留圖像和引用;完全刪除圖像 - 當您只想要散文時很有用。
程式碼區塊和內聯代碼是否保留?
是的。 A <pre><code> block 成為一個圍欄代碼塊,如果代碼元素攜帶類似「language-js」的類,則該語言將添加到圍欄中。內聯 <code> 跨度被反引號包裹,程式碼文字本身永遠不會被轉義或重新格式化,因此片段保持與書寫完全相同。
它適用於從網站複製的混亂 HTML 嗎?
這就是它的建構目的。解析器可以容忍未閉合的標籤、大寫元素名稱、未引用的屬性和雜散註釋,並且它會剝離 並且<style>阻止。複製的 CMS 或所見即所得輸出通常會乾淨地轉換,儘管非常不尋常的嵌套結構可能需要小的手動整潔。</p><h3>這是否會將 Markdown 反轉為 HTML 工具?</h3> <p>對於常見的構造,是的。此轉換器是 Markdown 到 HTML 工具的逆轉換器,因此透過該工具運行 Markdown 並透過此工具返回結果通常會重現原始文件。小差異的常見來源。</p><h3>我的內容是否上傳到任何地方?</h3><p>否。轉換完全在您的瀏覽器中使用普通的JavaScript 運行- 您沒有貼上任何內容會免費嗎?</h3><p> 是。沒有註冊、沒有使用限制、沒有浮水印和沒有上傳。瀏覽器本地發生轉換,並且頁面加載後繼續離線工作。</p><hr><pre><代碼類別="語言-json">{"@context": " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " "如何將HTML轉換為Markdown?" & ": {"@type" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " 如果您願意,請調整項目符號樣式或連結處理,然後複製 Markdown 或下載為。md 檔案。"}},{"@type": "Question"," 轉換器處理表格嗎? " "接受答案和引用;:{"@type": " " " 啟用GitHub風味標記後,HTML<table>變成Markdown管表:第一行成為標題,插入分隔行,其餘行成為正文。單元格內的管道字元被轉義,以免破壞表格。&引用;}},{"@type": "連結和圖像會發生什麼?&引用;,&引用;接受答案和引用;:{"@type": " &引用;: "連結和圖像會發生什麼變化?&引用; &引用;接受答案;: {"@type": " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用;: " &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; &引用; & 如果您關閉\"保留連結\"保留錨文本,但 URL 被刪除,並關閉\"保留圖像\"當您只想要散文時,完全刪除有用的圖像。"}},{"@type":"保留程式碼區塊和內聯程式碼嗎?""接受答案和引用;:{"@type":"是,如果程式碼元素帶有諸如\"之類的類別;內聯<代碼>跨度被反引號包裹,並且程式碼文字本身永遠不會逃脫或重新格式化,因此片段完全按照書面形式保留。&引用;}},{"@type":"從網站複製的混亂 HTML 上可以嗎?" @type":"這就是它的建構目的。解析器可以容忍未閉合的標籤、大寫元素名稱、未引用的屬性和雜散註釋,並且它條帶<腳本>和<風格&引用;:"複製的CMS或所見即所得輸出通常需要小手動整潔。&引用;}},{"@type": "將標記反轉至HTML工具嗎?&引用; {"@type": "將標記反轉至HTML工具?&引用;:{"@type": "將標記反轉至HTML工具?&引用; {"@type": "將標記反轉至HTML工具?&引用; {"@type": &引用;將標記反轉至HTML工具?&引用; {"@type": "將標記反轉至HTML工具?&引用; &引用;:&引用;:&引用;對於常見的構造,是的。 這個轉換器是 Markdown 到 HTML 工具的逆過程,因此透過該工具運行 Markdown 以及透過此工具返回的結果通常會複製原始文件。空白和一些純 HTML 功能是小差異的常見來源。"}},{"@type":"我的內容是否上傳到任何地方?","接受答案和引用;:{"@type":"答案和引用;,&引用;不。轉換完全在您的瀏覽器中使用普通的 JavaScript 運行,並且您不粘貼的任何內容都不會發送到伺服器,記錄或存儲。這使得內部頁面、未發布的草稿和任何內容都安全,並且它仍然可以在沒有網路連線的情況下運行。& 引用;}},{"@type":"問答;&引用;:&引用; HTML 到 Markdown 轉換器是否免費?& 引用; & 引用;接受答案和引用;:{"@type": & 引用;; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用;: & 引用; & 引用; & 引用; & 引用;: & 引用; & 引用; & 引用; & 引用; & 引用;: & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; & 引用; &



