Yihui Xie

为咩你不空行

谢益辉 / 2017-05-04


再来说一个我的强迫症症状:我倾向于写略拥挤的代码,但读不了拥挤的文字,所以我看 Markdown 源文件时,很怕没有空行的文件。

瞄了一眼边小编1合并请求(源文件在此),本骆驼终于垮了,于是拍拍土爬起来说一下这个空行问题。简单说来就一句话:

吾真心望尔等写 Markdown 文档时,在不同类型元素之间留一个空行。

拉面。

比如 YAML 元数据与正文之间留一个空行,小节标题与下面的段落之间留一个空行,大图片与段落之间留一个空行,列表项与引用块之间留一个空行,等等。凡是上一个元素和下一个元素类型不同时,都留一个空行。

比如这种写法会让我疯掉:

---
title: 标题
---
一个段落。
# 第一节
又一个段落。
- 列表条目1
- 列表条目2
还有一个段落。
# 第二节

我只能接受这种蓬松的写法:

---
title: 标题
---

一个段落。

# 第一节

又一个段落。

- 列表条目1
- 列表条目2

还有一个段落。

# 第二节

空行的意义不仅仅限于视觉上,它的更重要作用是避免语义模糊,这对 Markdown 编译引擎来说至关重要。如果没有空行,Markdown 引擎很难决定一个元素到底是上一个元素的延续,还是一个新的元素,比如下面的源文件:

我们通常用井号
# 表示代码注释。

它究竟是应该被翻译为一个段落:

<p>我们通常用井号
# 表示代码注释。</p>

还是一个段落和一个一级标题:

<p>我们通常用井号</p>
<h1>表示代码注释。</h1>

如果不加空行,这个 # 的意思对 Markdown 引擎来说就是模糊的。

本文要说的内容到此结束,但既然说到空行,索性再对空白字符作更多的科普好了。在 HTML、LaTeX 以及 Markdown 世界,连续的多个空白字符通常都没有意义。这里说没有意义的意思是多个空白等价于一个空白。根据这条定理,可以得到推论比如:多个连续空行等价于一个空行,多个连续空格等价于一个空格,等等。从此还可以纠正一个很多人可能犯的错误:用一大坨空格居中或者右对齐一个元素。这是没有意义的,空格不能用来对齐元素!尔等大约都被厉害了 Word 哥毒害了,我只能 Excel 而过。

然而,事情总是有例外,这也让人有些头疼。在 Markdown 中,如果一行的末尾有两个连续空格,那么它表示这里要强制换行,注意换行不表示新段落。要理解它只能同类比的方式来说:若你是 Word 用户,强制换行表示 Shift + 回车;HTML 用户可理解为 <br/> 标签;LaTeX 用户可理解为 \\。在 Markdown 中用引用语法 > 引用诗文时,每一句末尾两个空格就完美了,否则只能用代码块语法,尽管表面看起来好像是对的,但一方面字体和样式不太对,另一方面 HTML 语义也不对。

貌似事情到此也说完了,但其实还没完。关于看不见摸不着的空白字符,还有很多故事。就算是空格,也有好几种空格:普通空格(英文模式下敲空格键)、硬空格零宽空格、中文全角空格,等等。前面说的空格都是指普通空格。这些空格各有各的妙用,然而这里纸张太小写不下。


  1. 第三届靠谱厮奖的候选人。