Chapter 01 / 10

Markdown 简介与哲学

理解 Markdown 的诞生背景、设计理念、规范体系与渲染原理

Markdown 的诞生背景

2004 年以前,互联网上写博客意味着要手动敲 HTML 标签。写一篇普通博文,作者需要把 <p><strong><ul><li> 等反复输入,排版工作占用了大量精力,严重干扰写作本身的专注度。

2004 年,John Gruber(Daring Fireball 博主)和 Aaron Swartz(RSS 规范联合作者、Reddit 联合创始人)合作创造了 Markdown。他们的核心目标只有一个:让写作者用最接近自然语言的纯文本写出排版优美的 HTML,同时确保原始文本本身就有良好的可读性

Markdown
一种轻量级标记语言(Lightweight Markup Language),用简单符号描述文档结构,可由解析器转换为 HTML 或其他格式。名称取自"标记语言"(Markup Language)的双关语——Markdown 是 Markup 的"降级"(down),意为更简单的标记。
标记语言(Markup Language)
通过在文本中插入特殊标签来描述文档结构和语义的语言,HTML、XML、LaTeX 都是标记语言。与编程语言不同,标记语言通常不包含逻辑运算,只描述"文档长什么样"。
纯文本(Plain Text)
不包含任何二进制格式信息的文本文件,只有字符和换行符。可以用任何文本编辑器打开和编辑,不依赖特定软件,是长期保存文档的最佳格式之一。

Markdown 的工作原理

Markdown 的工作流程非常简单:你用文本编辑器写 .md 文件,然后 Markdown 解析器(Parser)读取这个文件,将其中的 Markdown 语法转换为 HTML 结构。

你写的 .md 文件 ↓ Markdown 解析器(如 marked.js、markdown-it、goldmark) ↓ HTML 结构(<h1>、<p>、<ul> 等标签) ↓ CSS 样式 ↓ 最终渲染效果(浏览器/GitHub/文档站)

以一个简单示例为例,理解转换过程:

你写的 Markdown 源码
# 你好,世界

这是一段**加粗**文字和
*斜体*文字。

- 第一点
- 第二点
解析器输出的 HTML
<h1>你好,世界</h1>
<p>这是一段<strong>加粗</strong>
文字和<em>斜体</em>文字。</p>
<ul>
  <li>第一点</li>
  <li>第二点</li>
</ul>

最终渲染效果:

你好,世界

这是一段加粗文字和斜体文字。

核心设计哲学

Gruber 在设计 Markdown 时,明确提出了以下设计原则,这些原则至今仍影响着所有基于 Markdown 的工具的设计决策:

1. 可读性优先(Readability Above All Else)

这是 Markdown 最重要的设计原则。原始的 Markdown 文本即使不经过渲染,也应该是清晰可读的。Gruber 的原话是:"A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions."

对比一下 HTML 和 Markdown 对同一内容的书写方式:

HTML(繁琐,不直观)
<h2>安装步骤</h2>
<ol>
  <li>下载安装包</li>
  <li>运行 <code>./install.sh</code></li>
  <li>配置环境变量</li>
</ol>
Markdown(简洁,可直接阅读)
## 安装步骤

1. 下载安装包
2. 运行 `./install.sh`
3. 配置环境变量

2. 借鉴电子邮件惯例(Email-Inspired Conventions)

Markdown 的许多语法来自于程序员多年来在纯文本邮件中形成的自然排版习惯:

惯例来源Markdown 语法含义
邮件引用用 > 前缀> 引用文字引用块
*单词* 表示强调*斜体*斜体
_单词_ 表示下划线强调**加粗**加粗
列表用 - 或数字开头- 项目无序列表
标题用 === 下划线# 标题标题

3. 最小化语法(Minimal Syntax)

Markdown 故意保持语法简单,学习成本控制在 30 分钟以内。它不试图替代 HTML,而是处理"80% 的使用场景"。对于复杂排版需求,Markdown 允许直接内嵌 HTML,这是一个务实的设计决策。

4. 专注内容,而非样式

Markdown 只描述内容的语义结构(这是标题、这是列表、这是引用),而不描述样式(字体颜色、大小、边距)。样式完全由渲染器和 CSS 决定。这与"内容与表现分离"的 Web 设计最佳实践一致。

INFO这种"关注点分离"使同一份 Markdown 文档可以在不同场景呈现不同外观:在 GitHub 上是 GitHub 风格,在 MkDocs 里是文档风格,导出 PDF 时是打印样式——而你的 Markdown 源文件一字不变。

规范的分裂与统一历程

Gruber 最初的 Markdown 规范(2004 年)只有一份简单的 Perl 实现和一篇文档说明,留有大量歧义之处。例如:

不同工具(Redcarpet、Discount、Pandoc、Python-Markdown……)各自解释,导致"同样的 Markdown 在不同平台渲染结果不同"成为普遍问题。

CommonMark(2012 年 — 现在)

2012 年,Jeff Atwood(Stack Overflow 联合创始人)等人发起 CommonMark 项目,联合多位 Markdown 解析器作者,历经 2 年,于 2014 年发布了 CommonMark 0.1 规范。该规范的特点:

GFM(GitHub Flavored Markdown)

GitHub 在 CommonMark 基础上添加了若干实用扩展,形成 GFM(GitHub Flavored Markdown)规范,于 2017 年正式发布 v0.29 规范文档:

表格(Tables)
| 分隔列的表格语法,是 GFM 最常用的扩展之一,CommonMark 不支持。
任务列表(Task Lists)
- [x]/- [ ] 复选框语法,在 GitHub Issues 和 PR 中可以点击切换状态。
删除线(Strikethrough)
~~删除~~ 语法,用于表示内容已废弃或被划掉。
自动链接扩展(Autolinks)
直接识别 https:// 形式的 URL,无需用尖括号包裹,自动变成可点击链接。
告警块(Alerts)
2023 年新增的 > [!NOTE]> [!WARNING] 等语法,渲染为带颜色的提示块。

主要规范对比

规范发布时间特点典型使用场景
原始 Markdown2004Gruber 原版,有歧义早期博客工具(Movable Type 等)
CommonMark2014精确规范,有测试套件现代解析器的基础
GFM2017CommonMark + 表格/任务列表等GitHub/GitLab/Gitee/VS Code
MDX2018Markdown + JSX React 组件Docusaurus、Next.js 文档站
Pandoc Markdown2006+功能最丰富,含脚注/定义列表等学术写作、PDF 导出
MultiMarkdown2009扩展了表格、脚注、引用等macOS 写作应用(Ulysses 等)
INFO本教程主要基于 CommonMark 0.31 规范,并重点讲解 GFM(GitHub Flavored Markdown) 扩展。这两者覆盖了日常 95% 以上的使用场景,也是 GitHub、VS Code、Obsidian 等主流工具的基础。

Markdown 的应用场景

开源项目文档

  • README.md — 项目门面
  • CONTRIBUTING.md — 贡献指南
  • CHANGELOG.md — 更新日志
  • GitHub Issues / PR 描述

技术文档站

  • MkDocs(Python 文档)
  • Docusaurus(React 文档)
  • GitBook(产品文档)
  • VitePress(Vue 文档)

静态博客

  • Hugo(Go 语言,速度最快)
  • Jekyll(GitHub Pages 官方支持)
  • Hexo(Node.js,中文社区大)
  • Astro(现代 Web 框架)

数据科学 / AI

  • Jupyter Notebook 文档格
  • Colab 笔记说明
  • Hugging Face 模型卡片
  • Papers With Code 论文描述

即时通讯与协作

  • Slack(部分支持)
  • Discord(基础格式)
  • Notion(完整支持)
  • 飞书/Lark 文档

个人知识管理

  • Obsidian(本地双向链接)
  • Typora(所见即所得)
  • Logseq(大纲式笔记)
  • Bear(macOS 原生)

Markdown 解析器的工作方式

了解解析器的工作原理有助于理解一些看似奇怪的渲染行为。Markdown 解析器通常分两个阶段工作:

阶段一:块级解析(Block-level Parsing)

解析器首先将文档分割为块级元素(Block Elements):段落、标题、代码块、列表、引用块、水平分隔线等。块级元素各自占据独立的行,不能内嵌在其他内联元素中。

阶段二:内联解析(Inline Parsing)

在每个块级元素内部,解析器再处理内联元素(Inline Elements):粗体、斜体、内联代码、链接、图片等。内联元素可以出现在段落、标题、列表项等文本内容中。

TIP理解"块级 vs 内联"的区分很重要。例如,你不能在内联代码(`code`)里面使用加粗(**bold**),因为内联代码会把其中的所有字符当作字面量显示;但你可以在列表项(块级)里面使用加粗(内联)。

选择合适的编辑器

VS Code(最推荐)

微软出品的免费开源编辑器,内置 Markdown 支持,是大多数开发者的首选:

Typora

所见即所得(WYSIWYG)Markdown 编辑器,输入语法后立即渲染:

Obsidian

基于 Markdown 的本地知识管理工具:

在线工具

工具特点适合场景
GitHub 网页编辑直接在浏览器编辑 .md 文件,实时预览快速修改 README
StackEdit在线 Markdown 编辑器,支持 Google Drive 同步临时写作
HackMD多人实时协作 Markdown团队文档协作
Dillinger简洁的在线 Markdown 编辑器快速体验

Markdown 文件的基本结构

一个良好的 Markdown 文件通常遵循以下约定:

# 主标题  <!-- 整个文档只有一个 H1,通常是文档标题 -->

简短的介绍段落,说明本文档的目的和范围。

## 一级章节  <!-- H2 用于主要章节 -->

章节内容...

### 子章节  <!-- H3 用于子章节,尽量避免使用 H4+ -->

子章节内容...

## 另一个一级章节

- 列表项1
- 列表项2

## 参考资料

- [资源名称](URL)
- [另一个资源](URL)
WARNING常见误区:很多人在一个文档中使用多个 H1(#)。从 SEO 和可访问性角度,每个页面应该只有一个 H1 作为主标题。章节应从 H2 开始,向下依次使用 H3、H4。GitHub 对此没有强制限制,但这是最佳实践。

YAML Front Matter:文档元数据

很多 Markdown 工具(Jekyll、Hugo、Docusaurus、Obsidian)支持在文件顶部用 YAML 格式描述文档元数据,称为 Front Matter:

---
title: 我的文章标题
date: 2026-03-26
author: 张三
tags:
  - Markdown
  - 写作
draft: false
---

# 正文从这里开始

...

Front Matter 用三条短横线 --- 包裹,必须位于文件最顶部。解析器会读取这些元数据并在构建时使用(如生成文章日期、作者信息等),而 Front Matter 本身不会显示在最终页面中。

INFOYAML Front Matter 不是 CommonMark 规范的一部分,但几乎所有静态站点生成器都支持它,Obsidian 也用它存储笔记属性(如创建时间、标签等)。

Markdown 与其他轻量标记语言的对比

语言创建时间优势劣势主要场景
Markdown2004学习曲线最低,生态最大规范分裂,功能有限文档/博客/README
reStructuredText (reST)2001语义更丰富,Sphinx 支持好语法复杂,学习成本高Python 官方文档
AsciiDoc2002功能最强,支持书本级文档语法繁琐技术书籍(O'Reilly)
Org Mode2003功能极其强大(日程/任务/代码)依赖 Emacs,学习门槛高Emacs 用户
Wiki Markup2001MediaWiki 生态与 Markdown 语法冲突,正在被淘汰Wikipedia

Markdown 在这些语言中并不功能最强,但其简洁性和庞大生态使其成为事实标准,在开发者社区中占据绝对主导地位。

小结

本章要点