第六章 Markdown 语法差异
学过核心语法和几种常见扩展后,很容易碰到一个问题:为什么有些写法在 GitHub 能显示,换个软件却不行?
先看任务列表:
- [x] 已完成任务
- [ ] 未完成任务有的工具会显示复选框,有的只把它当作普通文本。
公式也一样:
$$
E = mc^2
$$支持数学渲染的编辑器会排出公式;不支持的环境里,你看到的可能还是原样的标记:
$$
E = mc^2
$$这不是文件坏了。Markdown 的实现一直不止一种,工具也会按自己的需要增加扩展。先把它看成“共同基础 + 按需扩展”会比较好理解:
Markdown
│
├── 原始 Markdown:奠定基础写法
├── CommonMark:明确核心解析规则
│ └── GFM:在 CommonMark 基础上加入 GitHub 常用扩展
└── 工具扩展:按各自需要加入,不一定以 GFM 为基础下面先分清这些规则从哪来,再拿同一份文件对照两个平台的显示结果。
6.1 差异来源
原始 Markdown
Markdown 起初想做的事很直接:让人用容易读的纯文本写内容,再转换成 HTML。
例如:
# Python
Python 是一种编程语言。
- 简单
- 易学
- 生态丰富这种文本不用转换成 HTML 也能直接读懂,这是 Markdown 一开始就很看重的设计目标。不过早期 Markdown 更像“一套语法说明加一个参考实现”,不像正式标准那样把每种边界情况都定义得很细。
例如:
列表缩进几个空格?
空行如何处理?
HTML 和 Markdown 混合时怎么解析?
嵌套列表如何判断?不同开发者写解析器时,可能会做出不同选择:
解析器 A
↓
一种行为
解析器 B
↓
另一种行为方言差异就这样慢慢出现了。
基础语法
先看最早的 Markdown 解决了哪些基础需求,这也能帮助理解后面的 CommonMark 和 GFM:
标题
段落
强调
列表
链接
图片
引用
代码
分隔线例如:
# 标题
这是一段正文。
**重要内容**
- Python
- Java
[官网](https://example.com)
> 引用内容这些语法构成了 Markdown 的基本形态,直到今天仍是最常用的一部分。
解析歧义
原始 Markdown 的麻烦不只是功能少,更在于有些细节没有定义清楚。普通写作者未必会留意,但解析器开发者必须决定这些情况该怎么处理:
假设有一段复杂文本:
列表
缩进
代码块
空行
HTML规则不够精确,不同实现就可能把同一段内容转换成不同的 HTML:
同一个 .md 文件
↓
解析器 A
↓
结果 A
同一个 .md 文件
↓
解析器 B
↓
结果 B这就是 Markdown 兼容性出现问题的原因之一。
方言成因
Markdown 的“方言”可以类比不同地区的表达习惯:大家都懂基础写法,平台却会加上自己的说法和功能。比如:
# 标题- 列表[链接](https://example.com)不同平台还可能增加:
表格
任务列表
删除线
数学公式
双向链接
流程图
提示块这些分支合在一起,就形成了不同的 Markdown 方言:
共同基础
↓
Markdown 核心语法
↓
不同平台继续扩展
↓
不同 Markdown 方言差异大致来自几方面。
早期规则
规范没说清的边界情况,不同开发者就可能各自判断。比如:
这种写法到底算列表还是普通文本?解析器给出的结果也就可能不同。
平台需求
平台做什么,往往决定了它想给 Markdown 加什么。GitHub 常用于代码和项目协作:
代码
项目文档
Issue
Pull Request任务列表
表格
代码
自动链接知识管理软件更看重:
双向链接
页面嵌入
属性
标签数学笔记工具则可能需要:
LaTeX
公式编号
数学环境需求不同,扩展方向自然也不同。
扩展机制
Markdown 还很容易接入其他工具。代码块可以标注语言:
```python
print("Hello")
```沿着这个做法,有些工具会把特定标记交给其他解析器处理,例如 Mermaid:
```mermaid
flowchart LR
A --> B
```也就是说:
普通代码块
↓
增加特定语言标记
↓
由扩展工具继续处理代码块本身还是 Markdown 的结构,标记后的内容则由扩展接手。
6.2 CommonMark
规则统一
CommonMark 试着把 Markdown 的核心解析规则说得更清楚,让不同工具遇到同一段文本时,尽量按同一套方式处理。它没有重新发明 Markdown,而是明确了这些内容的行为:
- 标题;
- 列表;
- 代码块;
- 引用;
- 链接;
- HTML;
- 转义。
解析价值
简单说,原始 Markdown 给出大致写法,CommonMark 则进一步规定遇到各种情况时该怎么解析:
原始 Markdown
↓
告诉你“大概应该怎么写”
CommonMark
↓
进一步明确“各种情况下到底应该怎么解析”普通写作者在简单内容里未必看得出区别,比如:
# Python
- Flask
- FastAPI这类写法通常到处都能正常显示。普通作者未必能明显感觉到 CommonMark 的存在,但它给解析器、编辑器和文档工具提供了更统一的参照。
规范边界
可以把 Markdown 生态理解成:
Markdown 生态
├── CommonMark:核心解析规则
│ └── GFM:在其基础上扩展
└── 各工具:按需选用规则和扩展CommonMark 关注的是 Markdown 基础部分如何稳定工作,并不打算包下所有工具功能。数学公式、Mermaid 和 Obsidian 双向链接都属于其他扩展:
数学公式
Mermaid
Obsidian 双向链接6.3 GFM
语法扩展
GFM 是 GitHub Flavored Markdown 的缩写,也就是 GitHub 风格的 Markdown。它以 CommonMark 为基础,增加表格、删除线、任务列表和自动链接等协作中常用的写法:
- 表格;
- 删除线;
- 任务列表;
- 自动链接。
开发协作需求
GitHub 不只是发布文章的地方,还承载代码托管、Issue、Pull Request 和项目协作:
代码托管
Issue
Pull Request
项目管理
开发者协作所以项目 README 常要写功能对比、安装步骤和任务进度,Issue 里也会列待办:
功能对比表
安装步骤
任务进度
代码块
链接Issue 中经常需要:
- [ ] 修复登录问题
- [ ] 增加测试
- [x] 更新文档表格
例如:
| 框架 | 语言 |
| --- | --- |
| FastAPI | Python |
| Vue | JavaScript |表格现在很常见,但它是后来加入并普及的扩展,不属于最早的核心语法。
任务列表
例如:
- [x] 创建项目
- [x] 编写 README
- [ ] 编写测试任务列表在这些地方尤其顺手:
Issue
项目计划
检查清单删除线
例如:
~~旧方案~~可以标记已经废弃或不再采用的内容:
我们原本计划使用 ~~Flask~~,后来改成 FastAPI。自动链接
在很多 GFM 环境里,直接输入网址就会被识别为链接:
https://github.com/邮箱地址等文本也可能自动变成链接,写 Issue、README 和评论时会省几步。
规范关系
关系可以这样看:
CommonMark
↓
提供基础 Markdown 规则
↓
GFM
↓
增加 GitHub 常用扩展经常写下面这些内容的话,了解 GFM 会很有帮助:
README
开源文档
技术文章常见支持范围
其他工具不一定完整实现 GFM,不过表格、删除线、任务列表和代码块已经相当常见:
表格
删除线
任务列表
代码块掌握核心语法,再熟悉其中常见的几项,日常写作通常就够用了。
GFM 的定位
GFM 不是 Markdown 的“下一版”,也不是从 Markdown 1.0 升级到 GFM 2.0;它是建立在 CommonMark 上的一种常用方言:
Markdown 1.0
↓
GFM 2.0上面这种版本升级关系并不准确,实际关系更接近:
Markdown
├── CommonMark
│ └── GFM
└── 软件按需增加的扩展6.4 工具扩展
除了 CommonMark 和 GFM,具体软件也会按自己的场景增加语法。
比如,知识管理软件可能支持:
双向链接
页面嵌入
属性
标签文档网站工具则可能提供:
自定义容器
组件
Frontmatter
代码组数学工具还可能加入:
LaTeX
数学环境这些都超出了 Markdown 的通用核心。
平台语法
Obsidian
Obsidian 用 Markdown 文件保存笔记,同时加上了不少知识管理功能。比如 [[Python]] 可以指向笔记:
[[Python]]同样,[[FastAPI]] 会链接到名为 FastAPI 的笔记。这种双向链接在个人知识库里很方便,但它不是通用 Markdown;放到不支持它的工具里,可能只会看到原始字符:
[[FastAPI]]嵌入语法
Obsidian 还可以用下面的写法嵌入其他笔记:
![[python.md]]也能用来嵌入其他内容,例如:
图片
音频
PDF
其他内容这对个人知识库很实用,也意味着文件会更依赖 Obsidian。要跨平台迁移时,记得检查这些写法。
VitePress
VitePress 用 Markdown 构建文档网站,因此还提供了不少面向技术文档的功能:
Frontmatter
代码高亮
自定义容器
Vue 组件
Markdown 插件页面里甚至能直接写 Vue 组件,例如:
<MyDemo />这已经超出传统 Markdown 核心,属于 VitePress 的 Markdown + Vue 文档体系。
Frontmatter
静态网站生成器常在 Markdown 顶部放一段 Frontmatter:
---
title: Markdown 入门
date: 2026-10-04
---它用来保存页面元数据,例如:
标题
日期
作者
分类
标签
布局Frontmatter 很常见,却不属于 Markdown 核心语法,通常由这些工具生态定义:
静态网站生成器
内容管理工具
文档框架嵌入能力
数学公式
例如:
$$
E = mc^2
$$标记写在 Markdown 文件里,但公式内容由数学系统处理:
E = mc^2Markdown
负责文档结构
LaTeX
负责数学表达
MathJax / KaTeX
负责公式渲染换句话说,这是几种工具配合完成的效果,不是 Markdown 自己突然多出了完整的数学排版能力。
LaTeX 的定位
容易混淆的是把 Markdown、GFM 和 LaTeX 当成同一层的版本:
Markdown
GFM
LaTeX它们其实不是并列关系:
Markdown
│
├── CommonMark:核心解析规则
│ └── GFM:增加 GitHub 常用语法
└── 工具扩展:由具体工具决定
├── 数学公式支持(嵌入部分 LaTeX 数学语法)
├── Mermaid 图表支持
├── Obsidian 语法
└── VitePress 扩展LaTeX 是独立的排版系统;Markdown 工具只是可能支持在文档里嵌入其中一部分数学语法。
Mermaid
例如:
```mermaid
flowchart LR
A --> B
```Markdown 先把它识别成代码块,mermaid 标记再告诉支持它的工具把内容交给 Mermaid 解析器:
mermaid处理过程大致是:
Markdown
↓
识别 mermaid 代码块
↓
Mermaid 解析器
↓
生成图表所以 Mermaid 不是 Markdown 的另一个版本,而是借助代码块接入的图表扩展。
扩展边界
统一语法很难包下所有功能,因为工具的用途并不一样。GitHub 需要:
Issue
任务列表
代码Obsidian 更需要:
知识链接
嵌入
笔记关系VitePress 则关注:
文档网站
组件
导航学术工具可能更看重:
公式
引用
论文如果全部塞进 Markdown:
Markdown
+
任务管理
+
知识图谱
+
数学排版
+
网页组件
+
数据库属性
+
图表这样一来,Markdown 反而会失去简单这个特点。现实中的做法更像是:
一个稳定的基础
+
按需要增加扩展6.5 兼容性核验
对照任务
假设你在 Obsidian 里写笔记,现在准备把同一份文件发布到 GitHub。把下面内容保存为 compat_check.md,再在同目录新建一个只含 # Python 的 Python.md。发布时把两个文件一起放进仓库:
# FastAPI
## 安装
```bash
pip install fastapi
```
## 学习任务
- [x] 安装
- [ ] 路由
- [ ] 数据验证
## 公式
$$
E = mc^2
$$
## 相关笔记
[[Python]]先不要改源码。分别在 Obsidian 的预览和 GitHub 的目标页面查看 compat_check.md,对照下面四项:
| 源码 | Obsidian 预览 | GitHub 页面 | 核对点 |
|---|---|---|---|
# FastAPI 与代码块 | 记录标题和代码是否成形 | 记录标题和代码是否成形 | 基础结构是否保留 |
- [x] 与 - [ ] | 记录是否出现任务框 | 记录是否出现任务框 | 扩展是否被识别 |
$$...$$ | 记录公式或原始字符 | 记录公式或原始字符 | 数学渲染是否启用 |
[[Python]] | 记录链接或原始字符 | 记录链接或原始字符 | 目标平台是否识别内部链接 |
GitHub 上的显示还要看实际发布位置。以目标页面的预览为准;文件能打开,不代表里面的扩展都能正常显示。
再给每项写法标明来源:
# 标题
→ 核心 Markdown
代码块
→ 核心 Markdown
任务列表
→ 常见扩展 / GFM
数学公式
→ LaTeX 数学扩展
[[Python]]
→ Obsidian 扩展如果 [[Python]] 在目标页面原样显示,而 Python 笔记也会随文档一起发布,可以把它改成普通链接:
[Python](./Python.md)链接里的文件名和大小写要与目标仓库中的 Python.md 一致。
如果公式还是原样字符,先检查目标平台是否启用了数学渲染;不支持时,再按发布需要换成图片或普通文字。任务框没显示,也可以保留清单内容,或改成普通列表。每次调整一处,再回到两个页面核对。
这样就能看出哪些内容可以直接迁移,哪些扩展需要替换或降级。
差异判断
排查显示差异时,先分清源码和渲染器。article.md 这样的 Markdown 文件只是文本;GitHub、Typora、Obsidian 和 VitePress 则负责解释它:
GitHub
Typora
Obsidian
VitePress不同渲染器支持的扩展不同,所以:
同一个 Markdown 文件
+
不同 Markdown 渲染器
=
不同显示结果平台专属语法
一个常见误会,是把某个软件的扩展当成通用语法。比如你习惯在 Obsidian 里写:
[[FastAPI]]放到其他网站后,页面可能原样显示:
[[FastAPI]]这不是文件坏了,而是目标工具不认识 Obsidian 的语法。再看自定义容器:
::: tip
注意事项
:::某些文档工具能识别它,换到别的平台却未必。碰到看起来很特别的写法,先问一句:
这是通用 Markdown,还是当前工具自己的扩展?
语法识别
下面这些通常是最基础、最通用的写法:
#
##
**
*
-
1.
>
[]
![]
`而看到这些标记时,就该留意它们可能依赖扩展:
[[]]
:::
$$
```mermaid
---
key: value再确认目标工具是否支持。
显示差异
Markdown 保证的重点是内容结构,不是像 PDF 那样在所有软件里像素级一致。例如:
# PythonGitHub、Typora 和 VitePress 可能各用一套字体和样式,但都会把它认作一级标题。这种差异是正常的。
6.6 迁移策略
通用写法
文档要同时放在 GitHub、Typora、Obsidian、VitePress 等地方时,优先用通用语法。
例如:
# FastAPI
## 安装
执行:
```bash
pip install fastapi
```
更多信息请查看 [FastAPI 官网](https://fastapi.tiangolo.com/)。这种内容通常比较好迁移。至于双向链接、LaTeX、Mermaid、自定义容器等扩展,先确认目标平台是否支持:
双向链接
LaTeX
Mermaid
自定义容器场景取舍
大致来说,越靠近核心 Markdown,兼容性越高,但功能也越少;平台专属扩展能提供更多功能,跨平台时却更容易遇到差异:
越接近核心 Markdown
↓
兼容性越高
功能越少而:
使用越多平台专属扩展
↓
功能越丰富
兼容性可能越低例如:
标准链接
[FastAPI](fastapi.md)兼容性通常很好。
而:
[[FastAPI]]在 Obsidian 中更加方便,但跨平台能力会下降。
没有哪种写法总是最好,先想清楚文档最后要在哪儿用。
个人笔记
如果笔记只在 Obsidian 里用,放心写:
[[双向链接]]双向链接等功能在个人库里很省事。如果文档确定只发布到 VitePress,也可以用它的自定义容器、组件和 Frontmatter:
自定义容器
组件
Frontmatter真正容易出问题的是:现在依赖很多专属语法,之后又希望无成本地迁到别的平台。
公开内容
教程、开源文档、README、长期资料或多平台文章,通常更适合采用:
核心 Markdown
+
少量常见扩展以后换工具时,迁移成本也会低一些:
GitHub
↓
VitePress
↓
其他平台学习顺序
刚开始不用同时记住所有方言,按这个顺序学就够了:先掌握核心语法,包括:
- 标题;
- 段落;
- 强调;
- 列表;
- 链接;
- 图片;
- 引用;
- 代码。
然后补上常见 GFM 能力:
- 表格;
- 删除线;
- 任务列表;
- 常见自动链接行为。
最后按使用的工具补扩展:Obsidian 的双向链接、嵌入和属性,VitePress 的 Frontmatter、代码组、自定义容器和 Vue 组件。写数学内容时再学 LaTeX,需要图表时再看 Mermaid。
6.7 本章小结
Markdown
│
├── 核心思想
│ ├── 纯文本
│ ├── 标题
│ ├── 列表
│ ├── 链接
│ └── 代码
│
├── CommonMark:更严格地规范核心行为
│ └── GFM:在 CommonMark 基础上增加扩展
│ ├── 表格
│ ├── 删除线
│ ├── 任务列表
│ └── 自动链接等
│
└── 工具扩展
├── Obsidian
│ └── 双向链接 / 嵌入
├── VitePress
│ └── Frontmatter / 组件 / 文档扩展
├── 数学渲染
│ └── 嵌入部分 LaTeX 数学语法
└── Mermaid
└── 图表原始 Markdown:奠定基础写法
↓
CommonMark:明确核心解析规则
├── GFM:在其基础上增加 GitHub 常用语法
└── 其他工具可按需增加扩展,不必经过 GFM跨平台分享时优先用通用语法;文档只服务于一个工具时,也可以用它的专属功能。下一章会看看常用编辑器和平台各自支持什么,包括 VS Code、JetBrains、Typora、Obsidian、GitHub、VitePress 和 AI 工具。