Markdown 标记语言系统 UML 梳理
Markdown 是 John Gruber(与 Aaron Swartz 合作)于 2004 年发布的一种轻量级标记语言(Lightweight Markup Language),设计目标是"作为纯文本可直接发布、可读性优先"。本文档从行为与结构两个维度,用 UML 图梳理 Markdown 的解析渲染系统、CommonMark 规范结构以及使用者视角。
1. Markdown 概述
Markdown 是一种纯文本格式,用于书写结构化文档,通过少量标点符号约定表达格式(标题、列表、链接、强调等),最终可被转换为 HTML、PDF、Docx 等格式。其哲学是:源码本身就是可读的成品。
核心特性
- 纯文本:任何编辑器都可编写,无锁文件格式
- 可读优先:源码接近成品外观
- 轻量级:语法集精简,学习成本低
- 可移植:一份源码可转 HTML / PDF / Docx / PPT
- 基于约定:用
#、*、[]()等标点表达语义 - 无"语法错误":任何输入都有合法输出(歧义依赖规范裁决)
典型应用场景
- 项目 README 与文档(GitHub 必用)
- 技术博客 / 教程(静态站点生成器)
- 笔记与知识库(Obsidian / Typora / Notion)
- GitHub Issue / PR 评论
- API 文档、学术论文、演示文稿
- AI 工具输出(对话、报告、代码注释)
2. 第一部分:行为图(系统做什么)
从使用者视角出发,逐步细化 Markdown 从写作到渲染的行为过程。
2.1 用例图
展示 Markdown 的不同使用者及其典型操作场景。
2.2 活动图:渲染主流程
一次 Markdown 文档渲染的完整流程:读取 → 块级解析 → 内联解析 → 构建 AST → 渲染 HTML。
专有名词解释:
- 块级解析(Block Parsing):识别标题、段落、列表、引用、代码块等块级(Block)结构,先于内联解析进行。
- 内联解析(Inline Parsing):在段落/标题内部识别强调、行内代码、链接、图片等内联(Inline)元素。
- AST(Abstract Syntax Tree,抽象语法树):解析后得到的文档结构树,渲染器遍历它生成目标格式。
- 消毒(Sanitize):对渲染出的 HTML 做 XSS(跨站脚本攻击,Cross-Site Scripting)过滤的安全步骤。
2.3 活动图:GFM 扩展渲染
GitHub Flavored Markdown 在 CommonMark 之上叠加了表格、任务列表、删除线、自动链接、围栏代码块等扩展。
专有名词解释:
- GFM(GitHub Flavored Markdown):GitHub.com 上用户内容所支持的 Markdown 方言,严格超集(Strict Superset)于 CommonMark。
- 围栏代码块(Fenced Code Block):用三个及以上反引号
```或波浪号~~~包裹的代码块,可标注语言实现语法高亮。 - 自动链接(Autolink):裸 URL(如
http://example.com)自动转换为可点击链接。
2.4 时序图:解析到渲染
以一个典型段落为例,展示源文本如何被块解析器、内联解析器加工为 AST,再由渲染器输出 HTML。
2.5 状态机图:文档生命周期
描述一篇 Markdown 文档从撰写到发布归档的完整状态流转。
3. 第二部分:结构图(系统由什么组成)
从宏观架构到微观细节,拆解 Markdown 的静态结构与工具生态。
3.1 部署图:工具生态
展示 Markdown 从本地写作到在线发布、格式转换的完整部署拓扑。
3.2 组件图:解析器与渲染器
展示一个典型 Markdown 引擎(如 commonmark.js、markdown-it、Pandoc)的内部组件划分与依赖关系。
专有名词解释:
- 块解析器(Block Parser):负责将文本行划分成块级结构,按行顺序处理。
- 内联解析器(Inline Parser):第二阶段解析,处理段落内部的标记,可并行执行。
- 插件 / 扩展(Plugin / Extension):markdown-it 等引擎通过插件机制接入自定义语法。
3.3 包图:块与内联结构
按 CommonMark 规范将文档元素分为容器块、叶子块与内联元素三大类。
专有名词解释:
- 容器块(Container Block):可包含其他块的块结构,如引用
>、列表。 - 叶子块(Leaf Block):不能包含其他块的块,如标题、段落、代码块、分割线。
- 行尾(Line Ending):
\n(LF)、\r\n(CRLF)等行结束符,块解析以行为单位。
3.4 类图:AST 节点
描述解析结果抽象语法树的节点类型及继承关系(以 commonmark.js 的 Node 体系为例)。
4. 实战速查使用手册
4.1 基本语法
标题(Headings)
# 的数量对应标题层级(1–6 级),# 后必须加空格。
# 一级标题
## 二级标题
### 三级标题
标题一级
=======
标题二级
-------
段落与换行(Paragraphs & Line Breaks)
第一段文字。
第二段文字(空行分隔段落)。
第一行结尾加两个空格\n
再回车就是硬换行(或使用 HTML 的 <br>)。
强调(Emphasis)
*斜体* 或 _斜体_
**粗体** 或 __粗体__
***粗斜体*** 或 **_组合_**
~~删除线~~(GFM 扩展)
引用(Blockquotes)
> 一级引用
>
> > 二级嵌套引用
>
> 引用内可含 **加粗** 与列表:
> - 项目 A
> - 项目 B
列表(Lists)
无序列表:
- 苹果
- 香蕉
- 嵌套项(缩进两个空格)
有序列表:
1. 第一步
2. 第二步
1. 嵌套有序项(缩进四个空格)
任务列表(GFM 扩展):
- [x] 已完成
- [ ] 待办
代码(Code)
行内代码:使用 `code` 包裹。
代码块(缩进 4 空格或 1 个 Tab):
<html>
<body>缩进代码块</body>
</html>
围栏代码块(GFM,可标注语言):
```python
def hello():
print("Hello")
```
分割线(Thematic Breaks)
***
---
___
链接(Links)
行内式:[OpenCode](https://opencode.ai "悬停标题")
自动链接:<https://opencode.ai>
邮箱:<contact@example.com>
引用式:
[OpenCode][oc]
[oc]: https://opencode.ai "OpenCode 官网"
图片(Images)

[](https://opencode.ai)
转义字符(Escaping)
在 \ 后输入格式化符号,可显示其字面值:\*、\#、\_、\`、\[、\| 等。
4.2 GFM 扩展语法
表格(Tables)
| 语法 | 描述 | 对齐示例 |
| :--- | :---: | ---: |
| 左对齐 | 居中 | 右对齐 |
| 代码 `code` | 加粗 **bold** | 链接 [x](url) |
表格单元内可用行内代码、加粗、链接;管道符 | 用 | 转义。
任务列表(Task Lists)
- [x] 撰写大纲
- [x] 完成初稿
- [ ] 发布文档
删除线(Strikethrough)
~~删除的旧文案~~ 保留的新文案
围栏代码块与语法高亮
```python
def add(a, b):
return a + b
```
```json
{ "name": "markdown" }
```
脚注(Footnotes,需应用支持)
这里有一条脚注。[^1]
[^1]: 脚注的具体内容,可含多段与代码。
自定义标题 ID(需应用支持)
### 我的章节 {#custom-id}
跳转到该章节:[我的章节](#custom-id)
4.3 编辑器与工具
| 类型 | 代表工具 | 适用场景 |
|---|---|---|
| 所见即所得(WYSIWYG) | Typora、Obsidian、Notion | 笔记、写作、知识库 |
| 代码编辑器 | VS Code(+ Markdown Preview)、Neovim | 开发者写 README / 文档 |
| 静态站点生成器(SSG) | Hugo、Jekyll、Astro、MkDocs、mdBook | 博客、文档站、书籍 |
| 格式转换 | Pandoc、pandoc-crossref | 转 PDF / Docx / EPUB / 学术文档 |
| 在线平台 | GitHub、GitLab、Stack Overflow | 协作、评论、问答 |
4.4 最佳实践
#与标题文字之间保留空格,段前段后留空行,避免跨实现解析差异。- 换行统一用
\n(LF);Windows 的 CRLF 在不同工具间可能引起差异。 - 无序列表全程只用一种符号(
-、*或+),不混用。 - 长 URL 中英文空格用
%20编码,括号用%28/%29编码。 - 列表内嵌套段落 / 代码块时,缩进 4 空格或 1 个 Tab 保持一致。
- 内容含大量格式时优先用围栏代码块(带语言标注),而非 4 空格缩进。
- 正式文档用 CommonMark 校验工具(如
cmark、commonmark.js demo)预先检查。
4.5 速查表
| 元素 | Markdown 写法 | 说明 |
|---|---|---|
| 标题 | # H1 … ###### H6 | 1–6 级 |
| 段落 | 空行分隔 | 多个连续行并成一段 |
| 硬换行 | 行尾两个空格 | 或 <br> |
| 斜体 | *text* / _text_ | 强调(Emphasis) |
| 粗体 | **text** / __text__ | 强强调(Strong) |
| 删除线 | ~~text~~ | GFM 扩展 |
| 引用 | > text | 可嵌套 |
| 无序列表 | - / * / + | 缩进嵌套 |
| 有序列表 | 1. | 数字不必连续 |
| 任务列表 | - [ ] / - [x] | GFM 扩展 |
| 行内代码 | `code` | 反引号包裹 |
| 围栏代码块 | ```lang … ``` | GFM 扩展,可高亮 |
| 缩进代码块 | 行首 4 空格 / Tab | 原始语法 |
| 分割线 | *** / --- / ___ | 三个以上 |
| 链接 | [文本](URL) | 可加 title |
| 引用式链接 | [文本][id] + [id]: URL | URL 集中管理 |
| 自动链接 | <URL> | 裸 URL 也可自动链接(GFM) |
| 图片 |  | 前缀感叹号 |
| 表格 | | a | b | + 分隔行 | GFM 扩展,可对齐 |
| 转义 | \* \# | 反斜杠转义 |
| 脚注 | [^1] + [^1]: 内容 | 需应用支持 |
| 行内 HTML | <br> <mark> | 大部分应用支持 |
5. 标准与生态演进
时间线
| 年份 | 里程碑 | 说明 |
|---|---|---|
| 2004 | Markdown 发布 | John Gruber + Aaron Swartz,Perl 脚本 Markdown.pl |
| 2007–2012 | 方言爆发 | GitHub、Stack Overflow、Reddit 各自扩展,实现严重分裂 |
| 2012 | CommonMark 立项 | John MacFarlane 发起,目标消除歧义、统一规范 |
| 2017 | CommonMark 1.0 | 首个稳定版本,规范 + 官方测试套件 spec_tests.py |
| 2019 | GFM Spec 0.29 | GitHub 正式发布 GFM 规范,基于 CommonMark 超集 |
标准关系
- Markdown(原始):1980s 电子邮件格式约定的数字化,2004 年成型。
- CommonMark:明确无歧义的标准规范,含完整测试套件,是大多数现代引擎的解析基准。
- GFM:CommonMark 严格超集,追加表格、任务列表、删除线、自动链接、围栏代码块、被禁的原始 HTML(Disallowed Raw HTML)等扩展。
- 其他超集:Markdown Extra(表格/脚注/定义列表)、MultiMarkdown、R Markdown(可执行代码)等。