Markdown 引用与嵌套列表的缩进规则

Markdown 写作约 6 分钟

引用就是行首的 >,再加一个 > 就是嵌套引用。嵌套列表要看父项文字从哪一列开始,子项的标记必须落在这一列或更靠后,- 下面缩进 2 个空格,1. 下面 3 个,10. 下面 4 个。缩进放错地方,四个空格会把一行变成代码块,而 Markdown 本身没有段落首行缩进的语法。妙言 V4.5.0 会把 > [!NOTE] 渲染成和 GitHub 一样的提示框,编辑器里按 Tab 缩进两个空格,上一行是编号项时缩进三个,编号到 10 之前都够用。

引用的写法

> 一句引用。
> 同一个引用的第二行。
>
> 第二段,仍然在引用里面。

> 后面的空格可以省,前面最多可以有三个空格,写成四个空格这一行就成了缩进代码,> 文字 会把 > 原样打出来。不带 > 的空行会结束引用,后面再写 > ... 就是另一个引用,想要一个引用里有两段,空行上留一个单独的 >。

标题、列表、围栏代码和再一层引用都可以放进引用里,前提是每一行都以 > 开头,围栏的上下两行也一样:

> ## 引用里的标题
>
> 1. 第一步
> 2. 第二步
>
> ```bash
> make build
> ```

懒惰延续

CommonMark 允许一个段落的后几行省掉 >,> a 后面跟一行没有 > 的 lazy,仍然是同一个引用里的段落「a lazy」。这条规则只管段落文字,空行会把它截断,> - foo 后面跟一行没有 > 的 - bar,引用在第一行就结束了。

预览里的样子还取决于换行设置,cmark-gfm 会用空格连接懒惰行,妙言默认把每个换行渲染成 <br>,所以同样两行在妙言里分开显示,到 GitHub 的 .md 文件里就连成一行,这个设置在 Markdown 换行 里讲过。要发布的内容每行都写 >,就不用想这件事。

嵌套引用与提示框

> 外层引用。
>
> > 内层引用。
>
> 回到外层。

每多一个 > 就深一层,> > 和 >> 等价,「回到外层」前面那行单独的 > 不能省,否则这句话会接在内层段落后面。

提示框是第一行带标记的引用,妙言 V4.5.0 认五种,大小写都行:

> [!NOTE]
> 补充说明。

> [!WARNING]
> 删除之前先确认这一点。

其余三种是 TIP、IMPORTANT 和 CAUTION,预览里会画出带图标的彩色框,标题行写的是英文的 Note、Tip、Important、Warning 或 Caution。标记必须独占一行,> [!NOTE]: 文字 和 [!DANGER] 这类不认识的词仍然是普通引用,围栏代码块里的标记不会被动,提示框里再嵌一个普通引用也还是引用。GitHub 文档列的是同样五种,并提醒每篇最多用一两个,另外提示框不能嵌在别的元素里面。不支持提示框的应用会显示成一个以 [!NOTE] 开头的普通引用,速查表 把它归在扩展语法里。

嵌套列表的缩进怎么算

一个列表项会收下后面缩进到它内容列的行,内容列就是标记后面文字开始的那一列,子列表的标记从这一列或更靠后开始就算嵌套,所以要缩进多少取决于父项的标记:

父项标记 嵌套所需的最小缩进
- 2 个空格
1. 3 个空格
10. 4 个空格
100. 5 个空格

GitHub 的文档给的也是这个办法,数一数项目文字前面有几个字符,就打几个空格。这些例子在妙言 V4.5.0 自带的 cmark-gfm 0.29.0.gfm.3 里跑过,扩展和选项也一样。1. one 下面跟两个空格的 - sub,得到的是两个并列的列表,没有嵌套,- a 下面只缩进一个空格,子项变成同级,10. one 下面缩进三个空格是一个独立的无序列表,缩进四个才嵌进去。所以无序列表缩进 2 到 5 个空格都行,6 个以上会变成文字或代码,「两个空格还是四个」的争论只在数字列表下面有意义,那里要的是标记的宽度。

标记还决定列表从哪里开始、到哪里结束,-、*、+ 之间换用,或者 . 和 ) 之间换用,都会另起一个列表。起始数字由第一项决定,3. 接 4. 会从 3 开始排,0. 也可以,后面的数字被忽略,所以每行都写 1. 也会正确递增。标记是一到九位数字,只有以 1 开头的列表才能打断段落,段落中间的 2024. was a year 因此仍是文字,放在行首要怎么处理见 转义字符。

想在列表项后面接一个段落或代码,空一行以后缩进到同一列:

- 第一步

  第一步的第二段。

  ```bash
  make build
  ```
- 第二步

围栏如果写在第 0 列,就会把列表截断。

为什么四个空格会变成代码块

缩进代码块就是空行之后、行首有四个或更多空格的内容,顶层的空行后面写 text 就是代码,在列表里面这四个空格从内容列起算,- 下面的代码要六个。普通文字后面紧跟缩进行不会开启代码,只会接在段落后面。所以缩进要对齐内容列,而不是固定写四个,代码尽量用围栏,参见 Markdown 代码块。

段落首行缩进

段落开头的空格会被丢掉,四个空格又会变成代码,办法是让这一行以一个不是空格的字符开头:

&nbsp;&nbsp;&nbsp;&nbsp;An indented paragraph.

  中文段落的首行缩进,用两个全角空格。

&nbsp; 实体会渲染成真正的空格,全角空格(U+3000)对解析器来说是普通字符,不会触发代码块。代价是缩进写在了文字里,每一段都得自己加。

在妙言编辑器里缩进

V4.5.0 里 Tab 会让当前行或所有选中的行缩进两个空格,Shift+Tab 每次去掉最多三个行首空格或一个制表符,「格式」菜单里也有这一对命令,⌘] 增加缩进,⌘[ 减少缩进。如果上一行是编号项,Tab 改缩进三个空格,同时把这一行的编号改成 1,所以 2. two 会变成 1. two,正好是嵌套编号列表的开头。

宽度看的是上一行,不是父项标记的宽度,所以在 10. item 下面只会缩进三个空格,前面的表格说过这是同级的列表,再补一个空格并看预览。列表或引用行末尾按 Return 会带出同样的标记,数字加一,在空标记上再按一次 Return 会清掉它。只有第一个标记会被带出,所以在 > > 引用里第二个 > 要自己打。

出问题时怎么查

看预览,不看编辑器。子项和父项同级,说明缩进对这个标记来说不够;一行变成等宽字体,是空行之后缩进过多;出现原样的 >,是前面有四个以上空格;列表从 1 重新开始,是标记字符换了。

常见问题

引用可以放在列表项里面吗?

可以。把 > 行缩进到该项的内容列,- 下面就是两个空格,每一行都带同样的缩进。

为什么我的引用丢了第二行?

那一行不算段落延续,比如它开启了列表,或者前面有空行。每行行首都写 >。

所有 Markdown 应用都支持提示框吗?

不是。GitHub 和妙言 V4.5.0 会渲染,别的应用会显示成以 [!NOTE] 开头的普通引用。