原始 Markdown
修改后的 Markdown

Markdown Diff:在线比较两个 Markdown 文件

粘贴两份 Markdown 文档,逐行查看变化内容。支持 README 文件、发布说明、MDX 及带 frontmatter 的文档。diff 运行在浏览器中,无需上传。

什么是 Markdown diff 工具?

一款免费的浏览器内工具,用于在源文本层面比较两份 Markdown 文档。将旧版 README.md 粘贴到左侧,更新后的版本粘贴到右侧,每处变化的标题、列表项、链接、代码块和表格单元格都会高亮显示。所有内容都在本机处理,不会离开你的机器。

diff 逐字符运行。Markdown 是纯文本,因此这是最合适的处理方式:你看到的是文档源码中的字面变化,而不是渲染器对其解释的猜测。

如果你已经在使用我们的 文本 diff 工具处理通用文本,Markdown 页面采用相同的引擎,只是针对实际编写文档时常见的场景做了专门说明。若要比较 Jekyll、Hugo 或 MkDocs 文件顶部的 YAML frontmatter 块,YAML 页面对缩进敏感的结构处理得更好。严格的键值结构化数据则适合使用 JSON diff

diff 的实际工作原理

diff 在字符级别运行。原始 diff 完成后,语义清理阶段会将高亮移至完整单词、列表项和链接目标上,而不是将内联 `code span` 从中间截断,或将标题的 ## 前缀分离出来。右侧插入的内容显示为绿色,左侧删除的内容显示为红色。

这是源文本 diff,而非渲染输出 diff。这是处理 Markdown 工作的正确方式,其意义远超表面看起来的那么简单。两份渲染后 HTML 完全相同的文档,其源码可能大相径庭:**bold**__bold__* 列表符与 - 列表符、嵌套列表中的四空格缩进与制表符。渲染器将这些差异都抹平为相同的输出,让你失去关键信号。当你想知道某个贡献者是否真的只是修正了一个拼写错误时,源码 diff 才是真正的答案。

Markdown 也是一个方言家族。John Gruber 的原始规范(见 daringfireball.net)有意保持宽松,此后 CommonMarkGitHub Flavored MarkdownPandoc 和 MultiMarkdown 各自走向了不同方向。表格在 GFM 和 Pandoc 中存在,但不在 CommonMark 中。~~ 删除线和 - [ ] 任务列表是 GFM 扩展。diff 工具不关心你使用哪种方言,它只显示原始文本。方言的选择在你开始关注某个段落在新文档主题下是否仍能正确渲染时才重要,那是渲染器的问题,而不是 diff 的问题。

三步比较 Markdown

两个文本面板,一次 diff。无需注册,无需上传,无需服务器往返。

  1. 1

    粘贴或上传 Markdown 文件

    将旧版本粘贴到左侧,新版本粘贴到右侧。也可以点击任意面板的 上传 按钮,加载 .md.markdown.mdx 文件。点击「示例」按钮会在两侧填入一个小型 README 示例,让你在粘贴自己内容之前先看到 diff 的效果。

  2. 2

    如有需要,统一换行符

    在 Windows 上编辑的文件通常使用 CRLF 换行符,而来自 Linux 服务器的文件使用 LF。字符级 diff 会将两者视为不同,导致每一行都被标记为已更改。如果 diff 结果中红绿颜色异常密集,请先在编辑器中将两个文件统一为相同的换行符。VS Code 在底部状态栏显示当前的换行符类型,一键即可切换。

  3. 3

    阅读 diff 结果

    左侧红色表示删除,右侧绿色表示插入。两个面板同步滚动。Frontmatter 块、代码围栏、表格行和列表项对 diff 引擎来说都是普通文本,因此其中的变化与正文中的变化以相同方式呈现。每个面板头部的变更计数可以快速衡量本次编辑的修改量。

Markdown diff 适用的场景

审查 PR 分支间的 README 变化

你想快速了解 PR 分支与 main 分支的 README.md 有何不同,但不想打开 GitHub、跳过渲染预览、再一层层点进去找「显示源码 diff」。直接将两个原始文件粘贴到这个工具里即可。标题、代码围栏和链接目标都会清晰呈现。当 PR 同时涉及上百个源码文件,文档变更淹没在噪声中时,这尤为有用。

发布前比较 V1 与 V2 发布说明

发布说明在正式发布前会经过多次编辑。草稿会被重新排序,条目会被合并,版本号会移位。将之前发布的 RELEASE_NOTES.md 与新草稿进行 diff,可以发现遗漏的条目和意外的重复,而渲染预览很难发现这些问题,因为眼睛很容易滑过相似的行。diff 还能轻松验证 ## Breaking changes 部分在版本之间是否确实有所增长。

对比 CMS 导出与源码仓库的差异

你的团队在 Git 仓库中用 Markdown 编写文档,但公开网站由 MkDocs、Hugo 或 Docusaurus 等 CMS 或静态网站生成器构建。有时发布页面会与源码产生偏差:有人通过 CMS 界面直接编辑了线上页面却忘记推送回来,或者 CI 步骤重写了文件。将发布页面导出为 Markdown,放入一个面板,再将仓库中的 .md 文件放入另一个面板,几秒内偏差一目了然。

博客草稿与编辑修改稿的对比

你用 Markdown 将一篇博客文章发给了编辑,编辑返回了一份标注修改的版本。与其逐段重新阅读,做一次 diff 来吸收反馈要快得多,尤其是当编辑重新排列了章节或重写了你的开头时。同样适用于代笔内容场景,写手需要确认哪些文风调整在编辑过程中保留了下来。

审计 Markdown 到 MDX 的迁移

将 Docusaurus 或 Astro 网站从 .md 迁移到 .mdx 看似无关紧要,直到你发现某些 import 移动了位置,部分 JSX 组件替换了原来的普通 Markdown 表格,还有一些代码围栏被包裹在自定义组件中。逐文件对比旧的 page.md 和新的 page.mdx,迁移决策变得可审查。如果你决定 MDX 是个错误、想退回到普通 Markdown,同样的流程反向操作即可。

Markdown 快速参考

这是一份简短的语法速查表,涵盖本工具最常暴露的边界情况。方言列说明了哪些方言真正支持某个特性,因为这正是跨渲染器产生意外情况的根源所在。

TopicWhat this tool does
方言差异Markdown 是一个家族。CommonMark 是事实上的基准规范。GFM 增加了表格、任务列表、删除线和自动链接。Pandoc 和 MultiMarkdown 增加了脚注、定义列表等更多功能。相同的源码在不同方言下的渲染结果可能大相径庭。
表格管道分隔的表格存在于 GFM 和 Pandoc 中,不属于 CommonMark 或原始 Markdown 规范。如果渲染器输出的是原始 | 字符而非表格单元格,说明该解析器采用严格 CommonMark 模式,需要切换到兼容 GFM 的渲染器。
删除线~~文字~~ 是 GFM 扩展语法。原始 Markdown 和 CommonMark 均不支持。Pandoc 在启用 strikeout 扩展时支持。如果文字以字面波浪号渲染,说明渲染器不支持 GFM。
任务列表- [ ] 待办- [x] 已完成 是 GFM 扩展。CommonMark 将其渲染为带字面方括号的普通列表项。GitHub、GitLab 和大多数现代文档网站都支持;通用 Markdown 处理器通常不支持。
代码块:围栏式 vs 缩进式围栏式代码块(三个反引号或波浪号,可附带语言标签)是 CommonMark 规范的一部分,各处均支持。原始 Markdown 规范只有四空格缩进代码块,至今仍然有效,但无法携带语言提示。在同一文件中混用两种方式在语法上合法,但会显得混乱。
强制换行有三种方式:行尾加两个空格、行尾加反斜杠 \(CommonMark 和 GFM 支持,原始规范不支持),或插入空行形成段落分隔。行尾空格在大多数编辑器中不可见,这正是强制换行常常在 diff 中出现却无人察觉的原因。
Frontmatter文件最顶部用 --- 包裹的 YAML、用 +++ 包裹的 TOML,或用 { } 包裹的 JSON。不属于 Markdown 规范的任何部分,但在 Jekyll、Hugo、MkDocs、Docusaurus 和 Astro 中无处不在。渲染器在解析正文之前会将其剥离。
内联 HTMLCommonMark 允许在 Markdown 中使用原始 HTML 标签。GFM 同样允许,但在 github.com 上渲染时会应用 HTML 净化器。部分静态网站生成器会净化 HTML,部分会直接透传,少数会转义。包含嵌入式 <div><iframe> 块的页面在迁移审计时常常需要 diff。

Markdown diff 常见问题

这个工具会预览渲染后的输出吗?

不会。工具对比的是 Markdown 源文本,而非渲染器生成的 HTML。这是有意为之的设计。两份文档可能渲染出完全相同的 HTML,但源码却存在有意义的差异,例如用 * 还是 - 书写列表,用 ** 还是 __ 表示加粗。源码级 diff 保留了这些信号。若想查看文档的渲染效果,请将其粘贴到常用预览器中,如 GitHub 网页界面、VS Code 或静态网站生成器。

这与比较渲染后的 HTML 有何不同?

HTML 渲染结果的 diff 告诉你读者会看到什么;源码 diff 告诉你文件中实际修改了什么。两者回答的是不同的问题。对于 Markdown 来说,源码 diff 几乎总是更有用的,因为它忠实地呈现了作者的编辑:标题层级从 ## 变为 ###、代码围栏的语言标签被更换、相对链接变成了绝对链接。如果你需要 HTML 层面的对比,请先将两份文件通过渲染器处理,再对输出结果进行 diff。

CommonMark 与 GitHub Flavored Markdown 的歧义如何处理?

diff 本身不解析 Markdown,因此无论你使用哪种方言都没有影响。表格、任务列表、删除线和自动链接在 diff 看来都只是文本。方言的选择在你需要确认文档是否在目标渲染器下仍能正确显示时才有意义。CommonMark 是最接近基准规范的选择,GitHub Flavored Markdown 是 CommonMark 的超集,增加了表格、任务列表、删除线和自动链接。选择你的目标渲染器支持的方言即可。

如何处理 YAML 或 TOML frontmatter?

Frontmatter 只是文件顶部的文本,YAML 用 --- 包裹,TOML 用 +++ 包裹。Jekyll、Hugo 和 MkDocs 等静态网站生成器用它存储页面元数据。diff 将该块视为普通文本,因此对 title:date:tags: 的修改会像其他行一样显示。如果 frontmatter 内容较多且缩进敏感,建议单独使用我们的 YAML diff 页面处理该块。

支持 MDX 或 Markdown 中嵌入的 JSX 吗?

支持。MDX 是嵌入了 JSX 组件的 Markdown,从 diff 的角度来看,JSX 只是更多的文本。你可以在任意面板中粘贴 .mdx 文件,diff 会以与 .md 相同的方式呈现 import、组件 props 以及周围 Markdown 的变化。工具唯一不做的事情是验证你的 JSX 是否能编译,那是 MDX 编译器的工作。如果需要对 JSX 部分做纯代码审查,请将其粘贴到我们的文本 diff 工具中。

换行符(CRLF 与 LF)如何处理?

换行符也是字符,因此用 Windows 风格 CRLF 保存的文件与用 Unix 风格 LF 保存的文件在每一行都会产生 diff 差异。如果面板中出现大量看似无意义的变化,几乎可以确定就是这个原因。解决方法是在粘贴之前,在编辑器中将两个文件统一为相同的换行符。VS Code 底部状态栏显示当前换行符类型,点击一下即可切换。Git 的 core.autocrlf 设置也可能在不同机器间引入意外的 CRLF 差异。

diff 会区分 CommonMark、GFM 和 MDX 的差异吗?

这是一个文本 diff,任何字符级的变化都会显示出来,与方言无关。CommonMark 是严格规范;GitHub Flavored Markdown 增加了表格、任务列表、删除线和自动链接;MDX 则在 Markdown 正文中加入了 JSX。如果某个渲染器将 **bold** 规范化为 __bold__(部分 Pandoc 过滤器会这样处理),即使 HTML 输出完全相同,文本 diff 也会产生噪声。若需语义等价性判断,请将两侧内容通过相同的渲染器处理,再用我们的 HTML diff 页面对比输出结果。

如何处理文件顶部的 YAML 或 TOML frontmatter?

Frontmatter 是文件顶部的元数据块,YAML 格式使用 --- 行包裹(适用于 Hugo、Jekyll、Astro),TOML 格式使用 +++(Hugo TOML 模式),某些配置使用 ;;;。文本 diff 将 frontmatter 和正文视为一个连续的文本流,因此日期更新或标签顺序变化会与正文变化一同显示。对于 SEO 重要字段如 titledescriptionslug,这正是我们需要的。对于每次构建都会变化的字段(如 updated_at、构建哈希),建议在 diff 之前先将其剔除。

这个工具免费吗?需要注册吗?

完全免费,无需任何注册。不需要账号、不需要邮箱、没有试用倒计时、也没有锁定的专业版。粘贴两份文档,查看 diff,关闭标签页即可。整个流程以客户端 JavaScript 运行,页面加载后即使断网也能正常使用。上传、格式化和示例功能在第一次访问时与每次访问时的表现完全一致。

这与 GitHub 的 diff 或 StackEdit、Dillinger 等工具有何不同?

GitHub 的 diff 在两个版本都已在仓库中时非常好用,但它偏向渲染视图,需要一些操作才能找到原始源码。StackEdit 和 Dillinger 是带实时预览的 Markdown 编辑器,而非 diff 工具。本页只做一件事:对两份粘贴的文档进行并排源码 diff,不上传任何内容。当两个版本都在剪贴板里、而不是在某个分支中时,它就是你需要的工具。

可以上传两个 .md 文件而不是粘贴吗?

可以。点击任意面板的 上传 按钮,选择 .md.markdown.mdx 文件。浏览器通过 File API 在本地读取文件,直接将文本填入编辑器,文件不会离开你的机器。一侧上传、另一侧粘贴也很常见:从磁盘加载仓库中已提交的 README,再粘贴来自编辑器的草稿。

可以同时比较两个以上的 Markdown 文件吗?

单次视图不支持。工具基于两个面板设计,每次只能比较两份文档。对于三方场景,例如在 main 和两个功能分支之间协调文档,可以运行两次:先用基础版本对比分支 A,再用基础版本对比分支 B。依次阅读两份清晰的 diff,比同时盯着三列 Markdown 要容易得多。

粘贴私人笔记或未发布的草稿安全吗?

安全。diff 完全在浏览器中运行,你的文本不会到达服务器。没有上传操作,不记录面板内容,也不分析你输入的内容。因此粘贴未发布的博客文章、内部运维手册或你不想出现在任何人日志里的个人笔记都是安全的。如果想确认,可以打开浏览器的 DevTools,在粘贴时观察网络面板,你会发现它保持静默。

隐私说明与工作原理

你的 Markdown 不会离开浏览器。编辑器、diff 引擎和格式化工具全部在你的机器上运行。不分析你的输入内容,不记录日志,不与服务器通信。关于 Markdown 格式本身的背景知识,可参阅 维基百科,最新的 CommonMark 规范请访问 spec.commonmark.org/0.31.2,GitHub 方言规范请访问 github.github.com/gfm