0%

Markdown入门

概述

Markdown 是一种轻量级标记语言,具有纯文本格式语法。

——维基百科

Markdown 是一种创作格式,更多的关注语义。因而,即便是查看其纯文本形式,依然有很高的可读性。

Markdown 可以转换成多种格式的文件,常见的 Markdown 编辑器通常是将其转换为 HTML 文档进行预览或查看。

与常规意义上的纯文本不同,Markdown 具有自己的语法,因此它具有内在一致性

具有内在一致性是计算机的最爱,换句话说,计算机可以很容易地处理 Markdown 文档。因此,Markdown 具有一次编辑即可转换成多种格式的优点。(这听起来有点像是专门为开发人员编写的文件类型,但事实并非如此。)

Markdown vs. HTML

Markdown 并未涵盖所有 HTML 标签特性,但它与 HTML 是兼容的。换句话说,可以在 Markdown 文档中直接使用 HTML。虽然 Markdown 与 HTML 可以混合使用,但是有一些限制:

  • HTML 块级元素需要始于新行,但行级元素可以与 Markdown 文本混合出现于同一行中。
  • Markdown 语法在 HTML 块级元素中不会被处理,但在行级元素中会被解析。
  • HTML 最外层标签前不能有缩进(因为这是 Markdown 代码块的语法)。

另外一点差异在于特殊字符的书写,对于 HTML 而言需要处理诸如 <& 等特殊字符,而 Markdown 通常可以自然书写它们。在 Markdown 中特殊字符的书写与转义有以下一些规则:

  • & 是 HTML 字符实体的一部分,它会保留原状,否则转换成 &amp;
  • < 是 HTML 标签定界符,它会保留原状,否则转换成 &lt;
  • 在代码区块中,&< 一定会转换成字符实体。
  • \ 是转义前缀,可以转义:\ ` * _ {} [] () # + - . !

块级元素

段落

对于 Markdown 而言,段落就是连续行上的文本。不同的段落前后以至少一个空行分隔。

注意,段落前后的空行不必是严格意义上的空行,只包含空格和制表符的行也视为空行。

与段落相关的一个概念是换行,它代表的是“硬换行”,其前后的内容还是属于同一段落。

在 Word 中,段落对应的是回车(Enter),而换行对应的是 Shift + Enter。如果设置“段落符号”可视的话,段落显示的是类似回车键上的符号,而换行显示的是向下的箭头。

在 Markdown 中,键入回车并不能起到换行的效果,它造成的效果仅仅是相当于插入了一个空格。要换行,需在行末插入至少 2 个空格,然后再键入回车。

换行与插入 <br /> 标签是等效的,而想要插入多个换行的唯一方式就是使用 <br />

标题

Markdown 支持 2 种形式的标题:Setext 和 atx。

Setext 样式的标题如下:

1
2
3
4
一级标题
======
二级标题
------

其中 =- 的数量是任意的,但通常至少要有 3 个。

从语法可知,Setext 样式仅支持两级标题,这通常不够用。

另一缺点是,并非所有 Markdown 编辑器都支持它。

atx 样式的标题如下:

1
2
3
# 一级标题
## 二级标题 ####
###### 六级标题 ##

atx 最多支持六级标题。# 闭合是可选,并且闭合字符数量不必与开始的匹配。

分隔线

1
2
3
***
---
___

分隔线有 3 种候选的标记符号:*(星号)、-(连接线)、_(下划线)。

需要 3 个及以上字符,且除空格和制表符外,行内无其他字符。

使用 -(连接线)时,与上一段落间至少应有一空行,否则会将上一行文字解释为二级标题。

大多 Markdown 编辑器中,二级标题预览样式下方也是有分隔线的。

块引用

1
2
3
4
5
6
7
> 段落一
> 还是段落一
>
> 段落二
还是段落二

> 段落三

块引用使用 > 字符,最佳实践是在每一行前面都添加 >。也可以只在每个段落前添加 >

块引用可嵌套使用其他 Markdown 元素,比如,标题、列表、代码块,甚至是块引用。

通常,Markdown 编辑器生成的块引用都是每行前加 >

代码块

顾名思义,代码块用以插入代码段。

其中一种语法是:在每一行前添加 4 个空格或 1 个制表符。

1
2
// 4 个空格或 1 个制表符缩进
var str = "这里是我的代码";

每一行仅移除一级缩进,其他的会被保留。

代码块中所有字符都能自然书写,比如 HTML 标签,甚至是 Markdown 代码。

代码块会一直持续到没有缩进的那一行或文件结束。

另一种代码块语法是使用 ` (反引号):

1
2
3
4
```markdown
* 这里可以自然书写 Markdown 元素
* 在大部分 Markdown 编辑器中预览会根据指定的语言语法高亮显示
```

在大多数 Markdown 编辑器中,反引号语法更为常用,甚至一些编辑器会自动转换成反引号语法形式。因为,在代码块开始标记后可以指定代码的语言,这有利于编辑器在预览代码块时应用相应的语法高亮显示。

理论上,代码块中可以自然书写任意代码。但是,如果同上面的示例代码一样,代码块中书写的正好是代码块示例代码呢?这时,为了能正确关闭代码块,代码块标记将由 ` (反引号)改为 ~(波浪号)。不过,并非所有编辑器都支持它,但值得庆幸的是 GitHub 支持。

列表

Markdown 支持有序列表、无序列表和任务列表。

1
2
3
4
5
6
7
8
9
10
11
无序列表:
* item1
+ item2
- item3
有序列表:
8. item1
2. item2
5. item3
任务列表:
- [ ] task todo
- [x] task done

列表标记前最多可有 3 个空格(否则解析为代码块),之后至少接一个空格或制表符。

当列表项包含多个段落时,每个段落必须用 4 个空格或 1 个制表符来缩进。可以缩进每一行,以使列表美观,但这不是必须的。

列表项中嵌套块引用、代码块等时,需要双倍缩进。

与列表格式相同的文本需要使用 \ 转义列表标记,有序列表转义的是英文句点(.)。

在同一文档中,尽量使用同一个无序列表标记,而不应混用。

有序列表前的数字不必是有序的,甚至可以是任意数字,但是为了 Markdown 原始文档的可读性,应使数字与其序号一致。

在一些 Markdown 编辑器中,并不支持任务列表。

支持任务列表的编辑器中,通常预览显示为复选框开头的列表。

表格

表格通常有 2 写法,其中一种简洁写法如下:

1
2
3
4
First Header|Second Header
------------ | -------------
Content from cell 1 | Content fromcell 2
Content inthe first column | Content in the second column

有的 Markdown 编辑器不一定支持这种写法;也有可能会正确识别,但会转换为下一种“标准”写法。

1
2
3
4
5
| Table | Col1 | Col2 |
| ----- |:----:|----: |
| Row1 | 1-1 | 1-2 |
| Row2 | 2-1 | 2-2 |
| Row3 | 3-1 | 3-2 |

注意,: 在哪端表示向哪端对齐,两端都有表示居中。默认为左对齐。

并非所有 Markdown 编辑器都支持文本对齐特性,但通常都能正常解析表格。

行级元素

超链接

自动链接

在 Markdown 中,如果要将一个 URL 或 email 标记为超链接,最简单的是使用“自动链接”,即使用 <> 将其包裹起来:

1
<http://myurl.com>

自动链接在大多数 Markdown 编辑器中的预览效果是,URL 或 email 原样显示的超链接。

部分编辑器中,直接书写的 URL 即便不用 <> 包裹也会以超链接的形式预览显示。

显然,自动链接必然会显示链接本身,而通常情况下,超链接显示的是文本而不是显示指向的 URL。对于这种情况,Markdown 有 2 种形式的链接:内联链接引用链接

内联链接

内联链接语法如下:

1
我的[主页](http://myurl.com "title"),点击访问。

内联链接分为了两部分:

  • [] 中的是显示文本
  • () 中的是 URL 信息,又分为两部分:
    • 前半部分是 URL
    • 后半部分是链接的 title 属性(即鼠标悬停在链接上时显示的帮助信息)。
  • URL 部分可以用 <> 包起来;
  • title 是可选的,并且可以用单引号或双引号。

引用链接

当一个 URL 在同一个 Markdown 文档中多次出现,就应该考虑将其用引用链接表示,一方面形式上更为简洁,另一方面修改 URL 时只需要修改一处。语法如下:

1
2
我的[主页][id]
[id]: http://myurl.com "title"

顾名思义,引用链接就是引用了某个链接定义的链接。因此,引用链接必然包括定义与引用两部分(注意,其顺序不重要)。

其中,引用部分又分为两部分:

  • 前一个 [] 中是显示文本
  • 后一个 [] 中是链接标识,它是在链接定义中指定的

定义部分也分为两部分:

  • [] 中是链接标识,其后紧跟 : 和空格/制表符
  • 后面部分是 URL 信息(这跟内联链接 URL 信息部分类似)
  • 链接标识可包含字母、数字、空格和标点符号等,大小写不敏感;
  • URL 部分可以用 <> 包起来;
  • title 是可选,并可用双引号、单引号或圆括号;
  • 使用引用链接时,可以省略链接标识,比如 [Google][],此时引用链接的链接标识就是前面显示的文本。

在不同 Markdown 编辑器中,引用链接的定义部分的可见性可能是不同的。通常而言,“所见即所得”模式的编辑器中是可见,而“编辑-阅读”模式的编辑器的阅读视图中是不可见的,但输出的网页中均没有定义部分。

脚注

语法如下:

1
2
正文文本[^id]
[^id]: 脚注内容

脚注跟引用链接语法很像,只是脚注标识是带有 ^ 前缀的。

在 Markdown 编辑器预览时:

  • 正文中的脚注标识
    • 通常显示为上标
    • 通常是指向对应脚注定义的超链接
    • 可能会将脚注内容显示为悬停帮助信息
    • 无论标识为何都会按出现顺序转换为有序数字序列
  • 脚注定义
    • 总是会显示在正文末尾,且通常以分隔线与正文分开
    • 脚注内容末尾可能会显示一个链接跳转回脚注对应的正文

图片

与超链接类似,图片也有内联与引用之分:

1
2
3
4
5
内联图片语法
![Alt text](path/to/img.jpg "title")
引用图片语法
![Alt text][id]
[id]: path/to/img.jpg "title"

语法上看,只是比对应的链接形式多了一个 ! 前缀,而 [] 中的是图片的 alt 属性。

值得注意的是,以上两种语法不仅仅支持指定图片链接,还可以内嵌 base64 编码的图片。(具体可参考 这里

使用内嵌图片的好处就是图文一体,不需要依赖图床等;但其缺点也很明显,base64 编码巨长,在编辑器中通常使得可读性较差,还可能引起滚动卡顿。

文本样式

内联代码

上文提到了代码块语法,通常用以显示大段代码。如果只是嵌在行内的一小段代码,则应使用如下语法:

1
后面是一段代码 `code` 使用反引号将代码包裹起来

如果代码片段中也包含 ` ,可以使用多个反引号将其包裹。

如果代码片段中仅包含 ` ,则需要在开始标记后及结束标记前插入一个空格。

强调

1
2
3
4
*斜体text*
_斜体text_
**加粗text**
__加粗text__
  • 使用 1 个或 2 个 *_ 符号包裹
  • 1 个符号包裹转换成 <em>,2 个符号包裹转换成 <strong>
  • 开闭标记必须匹配,不能混用
  • 开闭标记内部不能紧临空格,否则会被当成普通符号
  • 如果要输出强调语法类似的字面量,需要使用 \ 转义标记

删除线

1
~~delete~~

高亮

1
==高亮==

注意,高亮与内联代码不是同一概念。从外观上看,可能在某些环境下是相似的。但它们的语义不同,转换为的标签也不同。高亮语义上是强调,会转换为 <mark> 标签;而内联代码语义上代表代码段,会转换为 <code> 标签。

大多数 Markdown 编辑器不支持该语法(目前已知仅 Typora 支持),GitHub 也不支持。为了跨环境兼容,可以使用 <mark> 代替。

上下标

1
2
普通文本^上标^
普通文本~下标~

有的 Markdown 编辑器中,上标的语法有所不同,仅需要开始标记而不需要关闭标记,普通文本^上标

各 Markdown 编辑器对上标/下标的支持也不心如人意,如果想保证跨环境兼容,应该使用 <sup><sub> 标签。

杂项

目录

与 Word 类似,Markdown 支持依据各级标题生成目录,最简单的语法如下:

1
[TOC]

如果使用 jekyll 这样的工具生成静态网站,那么生成目录需要用以下语法:

1
2
* content
{:toc}

后一种语法 Markdown 编辑器不一定支持。

YAML Front Matter

YAML Front Matter 主要用于提供文档信息,在 jekyll 中会使用到:

1
2
3
---
title: 标题
---

转义

由于 Markdown 语法使用了一些常用符号作为标记,当要使用这些符号的字面量时,需要用 \ 进行转义,可转义的字符有:

1
2
3
4
5
6
7
8
9
10
11
12
\   backslash
` backtick
* asterisk
_ underscore
{} curly braces
[] square brackets
() parentheses
# hash mark
+ plus sign
- minus sign (hyphen)
. dot
! exclamation mark

小结

本文讲述了大部分常用的 Markdown 语法,但并非全部。至少 Markdown 还支持公式以及流程图,不过这些内容比较多且繁杂,会采用专题的方式对其进行讲解。

参考

文章

《GitHub 风格的 Markdown 正式规范》发布:GFM 规范发布说明

Markdown:语法(中文翻译版)

一份 Markdown 简介(译文)

规范文档

GFM 规范

CommonMark 规范

站点

CommonMark 官网:目前 GFM 基于此构建

CommonMark 论坛讨论区: 可以提出关于该规范的的问题和更改建议

GitHub 仓库

Sundown:一个 Markdown 解析器,老版本的 GitHub Markdown 解析器基于此构建

cmark:CommonMark 的 C 语言实现

cmark-gfm:GFM 的 C 语言实现,cmark 的衍生版本

commonmark-spec:CommonMark 各种语言实现的列表