这是专题的一部分,详见:Markdown知识贴

虽然目前编辑器对Markdown的支持存在很大差异,方言现象严重,但是对于Markdown的基础语法的支持都是相似的。而且针对Markdown基础语法产生的差异大部分是在区块相接、嵌套、软输入和Lazy输入时产生的,所以养成一个良好的书写习惯可以规避掉大部分兼容性问题。这里会提供一些Markdown书写的建议,遵循这些建议会让Markdown更加易读,更少的语法歧义,也就有更高的兼容性。

范围元素的书写建议

强调、重强调的书写建议

自动链接的书写建议

行首空格的使用建议

行末空格的使用建议

空行的使用建议

标题的书写建议

区块代码的书写建议

分隔线

区块引用的书写建议

列表的书写建议

Markdown书写建议汇总


书写高兼容性的Markdown文档应该时遵循以下两个原则:

  1. 清晰原则。清晰是Markdown文档“易读性”的体现,如果一份Markdown文档人读起来都可能有语法歧义,那么对于机器来说也很容易产生兼容性问题。清晰原则具体表现为区块间有明确的区分、行内元素有明确的范围、避免使用歧义语法、避免使用Lazy输入等方面。
  2. 简单原则。Markdown本身只是轻量级的标记语言,使用过度复杂的功能、画蛇添足式的输入容易产生兼容性问题。简单原则具体表现为避免使用不被公认的偏僻功能、避免不必要的软输入、尽量少用嵌套、范围行内元素避免嵌套交叉等方面。一言以蔽之—— no zuo no Die。

范围元素的书写建议

这里所说的范围元素指采用行内元素中标识包裹的语法元素,包括强调、重强调、删除线、行内代码和下划线HTML标签。

  1. 范围元素不能超出所在的区块,最好不超出所在行,表格内的不能超出单元格。

    虽然目前部分编辑器很智能,允许跨行甚至跨区块使用,但是并不提倡这么使用,容易导致意想不到的结果。既然都是行内元素,那么就最好让它在一行内结束。

    不能跨区块好理解,为什么不提倡跨行呢?一般的跨行使用是没有问题的,但是如果跨行使用行内代码,有的编辑器会变成同一行。另外跨行扩大了范围,再添加范围元素时容易出现范围元素的嵌套或交叉。最重要的原因的是当我们实际书写时,很多时候我们是不能很好的区分应该到底使用多个文本行还是多个段落,当我们需要将文本行间添加空行转化为段落时,跨行的范围元素就会变成跨区块而失效,所以不推荐跨行使用范围元素。

  2. 范围元素尽量避免使用交叉,少用嵌套。

    交叉不应该使用,因为太容易出现错误,而且目前很多编辑器(包括为知与Editor.md插件)支持不好,更重要的原因是交叉违Markdown的易读特性,不符合清晰原则,而且其实完全没有必要,我实在找不到使用交叉的原因。

    尽量少用嵌套也是因为可以让文档更清晰更简单,但是实际书写时,使用嵌套的机会也是很多的。如果使用嵌套,特别多个范围元素作用于同一段文本时,需要注意让元素标识两侧对称。

    如重强调与删除线同时使用。

    推荐的对称写法是:**~~1234567890~~**

    而这种非对称写法**~~1234567890**~~虽然很多编辑器也能识别,但是不推荐使用(实际上Editor.md插件就不能识别后者)。

  3. 除了行内代码之外的范围元素,书写时标识内侧应该紧贴文字,避免紧贴空格或特殊符号。

    部分编辑器和语法是不允许范围元素的标识紧贴空格或文字的,而且紧贴文字之后易读性更高,也更符合Markdown的理念。所以也建议如此使用。

    紧贴文字,内侧避免紧贴符号:123,**456**,789。不推荐这样写:123**,456,**789

    紧贴文字,内侧避免紧贴空格:test *span* elements。不推荐这样写:test* span *elements

    是不是更加清晰,更加易读呢?

强调、重强调的书写建议

强调默认是斜体,重强调默认是粗体。

这里说个题外话,为什么不直接叫斜体或粗体呢?因为强调与重强调语法本来在HTML中输出就是<em><strong>标签,而不是直接的表示斜体的<i>和粗体<b>标签,只不过<em><strong>标签默认对应斜体和粗体。它们看似没有区别,但是在本质上是有很大区别的,就好比Word中使用样式添加标题,与直接对文字进行加粗放大字号的区别一样。强调与标题一样都有着自身的语义,不是一个具体的添加格式,就好像标题的格式允许修改一样,强调的格式也是可以改变的,不一定非要是斜体。目前大部分编辑器都是直接把强调理解为斜体,这就感觉有点掉价了。这是非常可惜的做法,尤其在中文领域。<em>的强调是一篇文章中读到某处才能发现的程度,<strong>的强调是扫一眼文章能马上认出来程度。在英文领域,这两种强调刚好对应斜体与粗体。但是在中文领域呢,因为斜体汉字太丑,斜体在汉字中使用率极低。如果让我设计,中文强调的格式应该是一种与第一字体相近的字体。不知不觉竟然啰嗦了这么多。希望有一天强调的语法能被有效利用起来,让其回归语义的本质。

强调有两种书写方式:一个星号*或下划线_包裹。 
重强调也有两种书写方式:两个星号**或下划线__包裹。

无论强调还是重强调都只建议使用星号,不建议使用下划线。理由有三:

  1. 在部分语法把__作为添加下划线的语法,而不是强调的语法(有点绕,这里的下划线指添加下划线格式)。

  2. 在计算机领域,经常使用_作为连字符或代替空格。部分Markdown语法规定两个字母间的_不被识别为强调,要用强调语法,需要在两侧的_外加入空格。

  3. 中文状态下,无法直接输入_号,需要切换英文才能输入_号。

自动链接的书写建议

链接的书写有三种方法:行内式、参考式和自动链接。其中自动链接是一种快速添加方式,只要用尖括号包裹即可。为知的Lazy输入还允许不用尖括号包裹,直接输入,如果直接输入请记得在后面加个空格以防万一。建议如果使用自动链接的话还是用尖括号包裹,因为很多编辑器不一定能自动识别链接。

如:<http://wiz.cn>

三种方式建议优先使用行内式,当然熟练掌握的话随意使用。

行首空格的使用建议

行首的空格(包括Tab)主要的功能是用于缩进式区块代码,列表嵌套和软输入。原生Markdown允许在每一行行首任意输入0~3个空格,不会影响最终输出。原生Markdown的原意是让用户可以根据需要使用行首空格对源码进行对齐,增加易读性。可是在Markdown语法百花齐放(面目全非)的今天,使用这种软输入是很危险的,而且现在的编辑器都非常智能,基本不存在易读性问题。

所以建议只在缩进式代码和列表嵌套时使用行首空格。有的教程说可以在段落首行添加2个空格进行缩进,更好看。这种也是属于软输入,除非对Markdown非常熟练,否则不建议随便添加。

行末空格的使用建议

与行首空格不同,一般人都不会想着需要在行末添加空格,除非打字敲错了。原生Markdown也是允许在行末添加空格的,这也输入软输入。一般软输入都是画蛇添足的,但是有一种情况比较特殊,就是文本行需要后接文本行的时候。建议段落中的文本行之间采用行末添加2个空格再回车实现换行。虽然很多编辑器(包括为知)都可以直接回车实现文本行换行,但是目前很多衍生语法仍然沿袭这个规定,所以也建议这么做以保证兼容性。

空行的使用建议

空行的作用主要是用于区块元素的相接,关于区块的相接问题上一章已经讨论过了。这里的建议是除了标题后接区块时可以不加空行外,所有区块都建议使用一个空行区分。因为目前还没有见到一个编辑器会去要求标题后接区块必须添加空行。而且目前大部分编辑器都会把文档种的标题着重突出,也不存在易读性问题,所以标题后面的空行是可以可无的。

当然标题前面的空行还是建议加上,因为井号在书写中也常用,有的语法会把文本行之后紧接的Atx标题认为是一个新的文本行。而且有的语法允许Setext标题多行,所以不论哪种标题,都建议在标题前预留空行。

至于其他的区块,都用空行区分可以大大增加文档的可读性,而且这样不必记忆到底哪些区块相接需要空行,哪些可以不接空行,再说多敲一空行也不是什么难事。这样做既符合清晰原则又符合简单原则,何乐不为呢?当然,如果愿意,标题后面接空行也是没问题的。

至于用多少空行合适,一般使用一个空行就够了,多了虽然不会影响最后输出,但是会让源码间隔过宽不利于源码的阅读,而且有的编辑器允许多个空行最后输出空行。

与空行使用相关的还有两个小问题,就是文本行与段落的选择问题,还有宽松列表与紧凑列表的选择问题,但是两个问题可以看作一个问题。

当我们书写多段文字时,需要考虑是采用一个段落多个文本行还是采用多个段落来显示。有经验的用户可能会发现文本行与段落在显示上区别其实不大,就是一个紧凑一个宽松而已,但是在概念上其实两个区别挺大的,不是一个层面的东西,而且不区分段落和文本行会逼死强迫症用户的。

如果使用文本行,使用行末两个空格加回车换行,如果使用段落,用空行区分。我的建议是每段文字的文字量都比较少(显示一行以内),使用文本行,这样可以节约空间,也更好看。如果其中一段或多段的文字的文字量比较多(显示上超过一行),使用段落,这样文档更加整齐,也能清晰地区分每个段落。其实就是文字量少本来比较疏的就让它们密一点以防过于空洞,文字量大本来就让它们疏一点以防过于紧凑。只是个人经验,仅供参考。

还有一种混搭的用法,适合用于每段文字都比较短的情况,将相关的文字合作为一段,不相关的分作另一段,比如下面这是我去年写的一份Markdown笔记:

一级标题:#+空格+标题 
二级标题:##+空格+标题 
三级标题:###+空格+标题 
四级标题:####+空格+标题 
五级标题:#####+空格+标题 
六级标题:######+空格+标题

一级无序列表:-+空格+内容 
二级无序列表:空格+-+空格+内容

一级有序列表:数字.+空格+内容(不区分数字顺序) 
二级有序列表:空格+数字.+空格+内容

一级引用:>内容 
二级引用:>>内容

至于宽松列表和紧凑列表,本应该放在上一章介绍的,机会难得就这里一起介绍了。其实它们跟文本行、段落本质上一样的,宽松列表将项目作为段落,项目间采用段间距,所以比较宽松,书写方法也跟段落一样,在项目间添加空行:

1.宽松列表1.宽松列表1.宽松列表

紧凑列表将项目作为文本行,项目间采用行间距,所以比较紧凑,书写时项目间不需要空行,行末也不需要两个空格换行:

1.紧凑列表1.紧凑列表1.紧凑列表

宽松列表和紧凑列表的选择方法大抵与文本行段落相似。列表内容丰富(文字量大、有嵌套),选择宽松列表比较好;列表内容单一(文字量少,单纯罗列),选择紧凑列表比较好。

列表也想混搭?不建议这么做,因为不同编辑器有不同的规定,最后的显示结果各有不同,而且也没有必要松紧混搭。

标题的书写建议

标题有两种书写方式,一种Setext标题,采用等号=或减号-作为底线,一种Atx标题,采用行首井号#

建议使用Atx标题,Atx标题比Setext标题有太多优势:

  1. Atx标题支持6阶标题,而Setext标题只支持2阶标题;
  2. Atx标题只占用一行,而Setext标题占用多行;
  3. 次阶Setext式标题语法与分隔线共用三个减号---作为语法,容易造成语法错误;
  4. 为知要求Setext标题的底线行首不能有空格,灵活性差。

总之,Setext标题不稳定、易出错、功能也单一,所以只推荐使用Atx标题,使用Atx标题唯一需要注意的是,井号#后面记得加空格。

区块代码的书写建议

区块代码有两种书写方式:缩进式和围栏式。建议围栏式区块代码

围栏式代码比缩进式代码有太多优势:

  1. 围栏式代码有明确的开始和结束标识,而缩进式采用的Tab不是明确的开始标识;
  2. 围栏式代码可以定义代码种类并高亮语法,而缩进式不能;
  3. 缩进式代码与嵌套列表的共用一个Tab作为语法,容易出现错误;
  4. 为知的缩进式代码已经出现错误了;
  5. 缩进一时爽,修改难上天。

看到第四条大家就明白了,为知已经用行动告诉大家不要使用缩进式代码。使用缩进式代码的各位施主们,回头是岸。

分隔线

分割线的写法有三种:三个以上的_*-

建议使用三个星号书写分割线,因为这样最安全、也最方便。具体的说,原因有以下2个:

  1. 下划线需要切换英文才能输入,不够星号来得方便直接;
  2. 减号与次阶Setext标题共用同一个语法,不够安全;

如果想使用减号写分割线,我提供两个建议可以让它也变得安全:

  1. 减号分割线前预留空行;
  2. 分割线允许带空格,而Setext标题不允许中间有空格,所以可以这样写- - -,这样就与Setext标题语法区分开了。

区块引用的书写建议

区块引用的书写其他很简单,因为最多就是嵌套一下段落之类的,出错概率很低。只是建议不使用用Lazy输入,老老实实在每一行敲>号。>号后面可接可不接空格,建议还是接一个空格,因为这样更好看,而且这样与列表、Atx标题等语法齐平,减少记忆负担。

列表的书写建议

与区块引用一样,请避免使用Lazy输入,因为列表太容易出问题。然后注意择好宽松列表还是紧凑列表,还有就是项目标识后需要接空格。另外尽量少用列表嵌套,如果列表需要包含很多内容,可以多使用标题。如果使用嵌套,为知中首选Tab方式吧。为知对对齐方式支持不好,而插件对Tab方式支持不好(好纠结有没有~),毕竟最后文档要在为知中显示,所以还是从了为知首选Tab方式吧。

对于有序列表,建议从数字1开始写,因为有的语法允许用户自定义开始的数字,而这个一般用不到。

对于无序列表,为知支持三种符号作为项目标识,分别是:星号*、加号+和减号-。无序列表应像有序列表一样避免使用Lazy输入。三个项目符号中,首选使用减号-,因为减号不用shift就可以直接输入,非常方便。

另外还有一项建议希望大家采用:同一个列表内同一级的项目使用同一个项目标识。不同级的列表用不同标识显示效果更好。像下面这样书写:

-一级列表+二级列表*三级列表-一级列表+二级列表*三级列表-一级列表+二级列表*三级列表

不要使用不同符号写同一级列表,因为有的语法规定,用不同的项目符号会生成全新的列表。

-一级列表-一级列表+一级列表+一级列表

像这样写,有点编辑器会当作两个列表,而且这样写易读性差,也不符合清晰原则。

Markdown书写建议汇总

  1. 范围元素不超出行,表格内的不超出单元格;
  2. 范围元素不交叉,少嵌套。如果嵌套,请两侧标识对称;
  3. 除行内代码之外的范围元素应紧贴文字;
  4. 不使用Lazy输入;
  5. 除了标题后不接空行外,所有区块使用空行区分;
  6. 只在缩进式代码与列表嵌套时使用行首缩进;
  7. 段落内的文本行之间最好使用行末两个空格换行;
  8. 同一级的无序列表使用同一个项目符号;
  9. 少用区块嵌套,如果列表需要嵌套很多内容,建议使用标题;
  10. 标题首选Atx式;
  11. 区块代码首选围栏式;
  12. 分割线首选使用星号;
  13. 无序列表的项目符号首选减号;
  14. 有序列表建议从1开始写;
  15. 图片与链接首选行内式;
  16. 以上建议仅供参考,请根据需要甄别筛选。