---
title: 为咩你不空行
date: '2017-05-04'
slug: blank-line
---

再来说一个我的强迫症症状：我倾向于写[略拥挤的代码](/cn/2017/01/blank-area/)，但读不了拥挤的文字，所以我看 Markdown 源文件时，很怕没有空行的文件。

瞄了一眼边小编[^1]的[合并请求](https://github.com/cosname/cosx.org/pull/538)（源文件[在此](https://raw.githubusercontent.com/tomatoiscoding/cosx.org/993e00001558e01262f92fac5dd17df9bb58c4c0/content/post/Bandit%E7%AE%97%E6%B3%95%E4%B8%8E%E6%8E%A8%E8%8D%90%E7%B3%BB%E7%BB%9F.md)），本骆驼终于垮了，于是拍拍土爬起来说一下这个空行问题。简单说来就一句话：

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

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

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

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

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

```markdown
---
title: 标题
---

一个段落。

# 第一节

又一个段落。

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

还有一个段落。

# 第二节
```

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

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

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

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

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

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

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

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

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

貌似事情到此也说完了，但其实还没完。关于看不见摸不着的空白字符，还有很多故事。就算是空格，也有好几种空格：普通空格（英文模式下敲空格键）、[硬空格](https://zh.wikipedia.org/wiki/%E4%B8%8D%E6%8D%A2%E8%A1%8C%E7%A9%BA%E6%A0%BC)、[零宽空格](https://zh.wikipedia.org/wiki/%E9%9B%B6%E5%AE%BD%E7%A9%BA%E6%A0%BC)、中文全角空格，等等。前面说的空格都是指普通空格。这些空格各有各的妙用，然而这里纸张太小写不下。

[^1]: 第三届靠谱厮奖的候选人。
