WordPress 网站运营了十年的任何人都最终会这样, 我以迁移内容为生, 当我将一批旧帖子从页面构建器中移出并移入基于 Markdown 的文档系统时, 我发现了 "clean HTML" 在野外真正意味着什么: <p> 带有内联样式的标签,空的 <span>S包裹单字, <div>s 三个层次深深地围绕着一段,以及偶尔根本就没有关闭的标签,将其粘贴到 Markdown 字段中,让我看到了一面字面角度括号的墙。复制粘贴 渲染 text 丢失了每一个链接、标题和列表,两个快捷方式都不行,最后我手洗了一下午的文章才懂事。
变得明智意味着将 HTML 到 Markdown 视为它:具有一组清晰规则的结构化转换,而不是复制粘贴。标题元素变成了 # 线。大胆变 **.一个链接变成 [text](url)。一个表变成一个管道表,一旦你有了那些映射和一个足够宽容的解析器,可以生存现实世界的标记,转换是无聊和可靠的- 这正是你想要的。我构建[toolz。dev](/并放置一个基于浏览器的 HTML 到 Markdown 转换器 在那里应用了这些规则,但本指南是关于规则本身的,因此您可以了解输出应该是什么样子以及原因。
TL;博士: HTML 转换为 Markdown,请将块元素映射到其 Markdown 等效项 (
<h2>→##、<ul><li>→-、<blockquote>→>、<pre><code>→ 围栏块),映射内联元素(<strong>→**、<em>→*、<a>→[text](href)、<img>→),转动<table>github 调味的 Markdown 管道表中,将 HTML 实体解码回真实字符,然后掉落<script>/<style>。使用容忍未关闭标签的解析器,并在浏览器中执行此操作,以便您的内容永远不会上传。
为什么要将 HTML 转换为 Markdown?
Markdown是现代开发者网络的便携式格式。README文件,文档网站,静态博客(雨果,杰基尔,Astro,Next。js内容),注意应用程序,如黑曜石和熊,GitHub问题,以及越来越多我们馈送到AI模型的提示和上下文 - 所有这些都说Markdown。it's纯文本,它在Git中干净利落地不同,它从一个系统移动到另一个系统,而不会拖动一堆演示标记随之而来。
HTML,相比之下,就是你 结束与 每当内容通过浏览器或所见即所得编辑器时。从网页复制一个部分,从 CMS 导出,从 API 中拉出文章正文,或从富文本字段中抓取格式化的文本,您就会获得 HTML - 通常杂乱无章的 HTML,充满了包装元素和内联样式您不't想要在干净的文档中。转换是从"被困在演示标记中的内容"到"内容的桥梁我可以在任何地方版本、编辑和重新发布。"
一旦您注意到场景,场景就会不断重复。将博客从 WordPress 或 Medium 上迁移。从旧的 HTML 帮助系统中提取文档。将刮下的文章转换为 Markdown 注释。将电子邮件通讯 's HTML 转换为 Markdown 草案。将网页 's 内容作为干净的上下文提供给 LLM,而不是浪费令牌的原始 HTML <div> soup。inevery case 手动替代品 - 重新打字,或复制粘贴渲染的文本和重建格式的手 - 是缓慢而有损的。基于规则的转换器既不是。
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 作为它的语言。那个's因为 <code> 携带元素 class="language-js"、惯例语法 highlighters 使用,一个好的转换器读取那个类来标记栅栏。它's 一个小东西,它使在您的 docs 网站上突出显示的代码块与不显示的代码块之间的区别't。
是什么让转换器在现实世界的 HTML 中幸存下来?
11选5以上规则是容易的部分,手卷式正则转换器失败的原因- 而I've写了一对,扔掉了一对- 就是真正的HTML不断打破假设,三个问题一再出现。
未关闭的标签。 浏览器是著名的宽容: <p>one<p>two 渲染为两个段落,因为 a <p> 当另一个块元素打开时隐式关闭,并且 <li>a<li>b 是出于同样的原因的两个列表项。只关闭显式上的元素的朴素解析器 </p> will将第二段嵌套在第一个内部,并破坏下游的所有内容一个强大的转换器应用相同的隐含-结束-标签规则HTML spec定义:打开一个块级元素关闭一个打开的段落;打开一个 <li> closes 上一个,我的转换器就是这样做的,这就是为什么粘贴草率的 CMS 输出通常只是起作用的原因。
<script> 並 <style> 块。 这些包含代码和 CSS,而不是内容,并且其内容必须逐字记录(a) < javascript内部不是一个标签),然后完全掉落。忘记特殊情况它们,你就会让javascript源流血进入你的markdown。
HTML 实体。 Web内容中散落着 &、 ©、 —、 以及数字参考 ’。在Markdown- 这是纯文本- 你想要实际的字符: &、 ©、 —,以及一个真正的撇号。解码命名和数字实体不是可选的;跳过它,你的干净的 Markdown 读取就像 view-source 一样。
这就是为什么我不再尝试用查找和替换来转换 HTML,而是构建了一个适当的宽容解析器。它将 HTML 标记为一棵树 - 处理注释,像这样的空元素 <br> 並 <img>、大写标签名称和未引用的属性 - 然后走那棵树发出 Markdown。值得注意的是,它不't依赖于浏览器's DOM,这意味着相同的逻辑也在服务器上运行,但对你的实际回报很简单:它不't抛出真正网站是由混乱的标记。
如何使用转换器?
论 Toolz.dev/tools/html 到 markdown、将您的 HTML 粘贴到左侧窗格中,当您键入时,右侧会出现 Markdown - there's 无上传,无转换按钮可搜索如果您想同时查看每个支持的构造,请加载示例。
几个选项涵盖了常见的偏好。选择你的子弹角色(-、 *、或者 +)用于无序列表以匹配您的项目's风格保持GitHub风味标记为表格和删除线,或者关闭,如果您的目标仅接受CommonMark。当您想要散文而不是URL时切换"保持链接"关闭 - 方便将重链接的文章变成干净的阅读文本 - 和"保持图像"关闭以完全剥离图像。stats行显示单词,标题,链接,图像,代码块和估计的阅读时间,这是一种快速的理智检查,在您将结果粘贴到某个地方之前,结构会遇到。
Site上的所有内容一样,转换是100%客户端的,解析器是普通的JavaScript在你的浏览器中运行,所以粘贴的页面,内部文档和未发布的草稿永远不会发送到任何地方。that's内容工作的正确默认值-你应该't必须将草稿上传到陌生人's服务器只是为了重新格式化它-这意味着该工具一直在离线工作。我更深入地探讨为什么浏览器端处理在 数据隐私工具指南。
HTML 与 Markdown:何时使用哪个
它们之间的转换很容易;知道你想要什么才是真正的决定。
| 方面 | HTML | 降价 |
|---|---|---|
| 主要目的 | 在浏览器中渲染 | 编写和存储文本 |
| 可读性作为来源 | 差(标签重) | 优(读为纯文本) |
| Git 差异 | 吵闹 | 潔 |
| 跨系统的便携性 | 低 | 高 |
| 精确的布局控制 | 满满的 | 受设计限制 |
| 它住在哪里 | 网页、所见即所得输出 | README、文档、注释、静态站点 |
| 学习曲线 | 陡峭 | 分钟 |
Markdown故意交易布局控制以求简单,这就是为什么它会为你编写的内容、版本和移动而获胜,并在你需要像素级演示时失败。将HTML转换为Markdown当你're捕获或迁移 内容;当你're构建一个时保持html 页码。当您需要采取相反的方式时 - 将 Markdown 输入 CMS 字段或电子邮件模板的 HTML - 标记到 HTML 转换器 是这个工具的镜像,并且共享相同的约定,因此对于共同的结构,两个往返是干净的。
这适合内容工作流程
格式转换很少是整个作业;it's一步。我将一篇文章转换为Markdown后I'll通常通过a运行文本 词计数器 要检查目标长度,以及源是否具有需要为其他目的地进行编码的 HTML 实体, HTML实体编码器/解码器 challeres反面处理当i'm在转换前清理手写的html时,一个 HTML 迷你程序 先把噪音剥离出来。这些小工具连在一起形成一个可重复的管道,这就是我对基于浏览器的工具包的思考背后的全部想法 - 我在 中阐述了这种理念 web开发人员工具包指南 而且范围更广 编码工具指南。
将 HTML 转换为 Markdown 的常见错误
复制粘贴渲染的文本而不是转换 HTML。 您丢失链接、标题和列表 - 所有结构。转换实际标记。
忽略代码语言类。 如果您的围栏块在没有语言的情况下出现并且没有't突出显示,转换器会丢弃 class="language-x" 提示。一个好人读了它。
假设 CommonMark 和 GFM 相同。 Tables 和 strikethrough 是 GitHub 调味 Markdown 扩展,而不是核心 CommonMark。如果您的目的地是严格的 CommonMark,则表格获胜't 渲染 - 关闭 GFM 进行转换并以另一种方式处理表格。
信任上传内容的转换器。 大量"免费"在线转换器将您的 HTML 发布到服务器。对于任何未发布或内部的内容,that's 泄漏。使用客户端工具。
常问问题
如何将 HTML 转换为 Markdown?
HTML粘贴到编辑器中,Markdown立即出现-没有文件上传,也没有转换按钮按下。如果您喜欢,调整项目符号样式或链接处理,然后复制Markdown或下载为。md文件。
转换器是否处理表格?
是的。启用 GitHub Flavored Markdown 后,会出现 HTML 成markdown管桌:第一行成为头,插入分隔行,其余行成为主体,单元格内的管字符逃逸,这样就不会打破桌子。
链接和图像会发生什么?
锚成为 [链接文本](href) 形象就变成了 ,在场时保留标题属性,如果关闭"保留链接"锚文本保留但URL掉落,关闭"保留图像"完全删除图像-在你只想要散文的时候有用。
是否保留了代码块和内联代码?
是的。 A block becomes a fenced code block, and if the code element carries a class like "language-js" that language is added to the fence. Inline spans are wrapped in backticks, and the code text itself is never escaped or reformatted, so snippets stay exactly as written.
Will it work on messy HTML copied from a website?
That is what it is built for. The parser is tolerant of unclosed tags, uppercase element names, unquoted attributes and stray comments, and it strips
