Skip to content

入门:Markdown 是什么、两层结构与最小语法

基于 CommonMark 0.31.2 / GFM · 核于 2026-07

速查

  • 定位:轻量级标记语言,纯文本可读 + 可机械转 HTML。John Gruber 2004 年提出,不替代 HTML,而是给写作者读写都轻松、对版本控制友好的格式。
  • 由来与规范:原始语法有歧义、Markdown.pl 有 bug → 各实现渲染不一致。CommonMark0.31.2,2024-01)用「规范 + 参考实现 cmark + 测试套件」消歧;GFM 是它的严格超集,补齐表格/任务列表/删除线等。
  • 两层心智:先解析块级元素(段落/标题/引用/列表/代码块/分隔线/HTML 块)切分文档结构,再在其中解析行内元素(强调/链接/图片/代码跨度/转义)。
  • 标题:ATX 用 #~######(1-6 级,井号后必须有空格);Setext 用底部 =(一级)/-(二级)下划线,只有两级
  • 强调*斜体*_斜体_**加粗**__加粗__***粗斜体***。⚠️ _ 在单词内部不生效(侧翼规则,护住 snake_case),词内强调用 *
  • 列表:无序 -/*/+;有序 1.(起始看首项、后续数字被忽略、自动递增)。嵌套靠缩进。⚠️ 项间有空行 → 松散列表 → 每项被 <p> 包裹、间距变大。
  • 代码:行内用反引号 `code`(内容含反引号则用更多反引号定界);块级优先用围栏码(3+ 个 ``` 或 ~~~,起始行 info string 首词标语言);老写法缩进码(每行 4 空格,不能中断段落)。
  • 引用:行首 >>> 嵌套;引用块内可放标题/列表/代码等其它块级元素。
  • 链接:行内 [文字](url "可选标题");引用式 [文字][标签] + 别处 [标签]: url;自动链接 CommonMark 需尖括号 `<https://…>`,GFM 扩展识别裸 URL。
  • 图片![替代文字](路径 "可选标题")——比链接多一个前导 !,方括号内是 alt。
  • 分隔线:单独一行 3+ 个相同的 -/*/_。⚠️ --- 紧贴上一行文字会被当 Setext 二级标题,前后留空行。
  • 转义\ + 任意 ASCII 标点转字面(如 \*);转义在代码块/代码跨度/自动链接/原始 HTML 内不生效。
  • 换行:段内硬换行=行尾两空格或行尾 \;单个换行是软换行(当空格);空行才分段。
  • GFM 扩展:表格、任务列表 - [ ]/- [x]、删除线 ~~文字~~、扩展自动链接(裸 URL)、禁用原始 HTML(tagfilter)。详见 GFM 扩展页
  • front matter:文件顶部 --- 包裹的 YAML 元数据,非 Markdown 规范,是静态站点生成器约定,渲染前先被剥离。
  • 与 MDX 关系(一句话):标准 Markdown 把 HTML 当静态文本透传;MDX 是 Markdown+JSX,能导入并运行组件——细节见 MDX 叶。
  • 进阶顺序:本页 → 块级元素行内元素与 HTML 安全GFM 扩展方言差异与 front matter参考

一、Markdown 是什么:定位与由来

Markdown 是一种轻量级标记语言:用一套极简的纯文本约定(#*- 等)来标注文档结构,再由解析器转换成 HTML 等结构化格式。它的设计哲学(Gruber 语)是——源码即便不经渲染,也应当保持易读、像纯文本一样自然。所以 Markdown 从不追求表达 HTML 的全部能力,而是聚焦「写作时最常用的那一小撮排版」,剩下的复杂需求可直接内嵌 HTML 兜底。

它诞生于 2004 年,作者 John Gruber,Aaron Swartz 参与了早期设计,并配了一个 Perl 参考实现 Markdown.pl。问题在于:Gruber 的语法说明是散文式的,留下大量未定义的边界情形——子列表要缩进几格?块引用前要不要空行?列表项何时被 <p> 包裹?行内标记的优先级如何?早期实现只能去参考「相当有 bug」的 Markdown.pl,于是同一份文档在 GitHub wiki 上和用 Pandoc 转 DocBook 时,渲染结果可能不同。

CommonMark 就是为解决这种歧义而生(2014 年发起,一度叫「Standard Markdown」)。它提供三件套:一份极其精确的规范、若干参考实现(如 C 语言的 cmark)、一整套**「输入 Markdown → 期望 HTML」的测试样例**。当前锁定版本是 0.31.2(2024-01-28)。GFM(GitHub Flavored Markdown) 则声明自己是「CommonMark 的严格超集」——凡 CommonMark 支持的它都支持,另加表格、任务列表、删除线、扩展自动链接、禁用部分原始 HTML 等扩展。

二、两层心智:块级元素 vs 行内元素

理解 Markdown 解析的关键,是它分两层处理文档:

  1. 块级元素(block-level):先把文档按行切分成一个个「块」——段落、标题、块引用、列表、代码块、分隔线、HTML 块等。CommonMark 进一步把块分成叶子块(不含其它块,如段落/标题/代码块/分隔线)和容器块(可含其它块,只有块引用/列表/列表项三种)。
  2. 行内元素(inline):在每个叶子块的文本内容里,再解析强调、链接、图片、代码跨度、转义、自动链接等行内标记。

这个分层能解释很多行为:为什么代码块(叶子块)里的 * 不会变斜体(块内不再解析行内标记);为什么块引用里能塞列表和标题(它是容器块);为什么标题里可以有 **加粗**(标题是叶子块,内部仍解析行内元素)。

三、最小语法速览

一段示例几乎覆盖了日常八成用法(下面是 Markdown 源码):

md
# 一级标题

这是一个段落,包含 **加粗***斜体*`行内代码`
段内换行要在行尾留两个空格,  否则只是软换行(当空格)。

> 这是块引用,可以嵌套 >> 也可以放列表。

- 无序项 A
- 无序项 B
  - 嵌套项(缩进两格)

1. 有序项
2. 有序项(数字全写 1. 也会自动递增)

```js
// 围栏代码块:起始围栏后的 js 指定高亮语言
const x = 1;
```

[行内链接](https://commonmark.org "可选标题") 和 ![图片](/logo.png)

渲染时:# 变标题、** 变粗体、` 变等宽代码、> 变引用块、-/1. 变列表、三反引号围栏变代码块、[]()/![]() 变链接与图片。注意第 4 行行尾那两个空格——它是把两行合成「同段内换行」的硬换行标记,肉眼不可见却极常被漏写。

四、方言地图与和 MDX 的关系(一句话)

  • 传统 Markdown(Markdown.pl):Gruber 2004 原版,功能最基础、边界有歧义,是一切方言的「基线」。
  • CommonMark:把原版精确化的消歧规范(0.31.2),配参考实现与测试套件,本身不含表格等扩展。
  • GFM:GitHub 的 CommonMark 严格超集,加表格/任务列表/删除线/扩展自动链接/tagfilter。
  • MultiMarkdown / Markdown Extra:更早补齐表格、脚注、定义列表等的方言。
  • Pandoc Markdown:特性最全的超集之一(脚注、多种表格、数学、引文、属性、Div/Span),并支持几十种格式互转。

MDX 的关系一句话:标准 Markdown 里的 HTML 是静态透传的文本,不会执行;MDX 是「Markdown + JSX」,能 import 并渲染真实的 React/Vue 组件、写 JSX 表达式——它把文档编译成组件而非只转 HTML。MDX 的细节见独立的 MDX 叶。


打好定位与两层心智后,下一步进入 块级元素:段落、标题(ATX/Setext)、引用、列表(含松紧陷阱)、代码(缩进/围栏/行内)、分隔线的完整规则。