Markdown虽然很流行,但是其实是一种非常松散的语言,没有统一的标准。于是就有各种版本的Markdown,比如有kramdown、vfmd还有今天要介绍的commonmark。一般来说,先有一个Markdown的解释器,然后这个解释器开发过程中发现当前的Markdown语法表达能力不够,于是就开始扩展,就有了这种Markdown的方言。
commonmark是一个强定义的Markdown规范,意味着它会对很多细节做出定义,避免歧义性,这样一来,写Markdown解释器和转换器就比较简单了。Learn Markdown in 60 Seconds可以快速帮你一览commonmark的样貌。commonmark dingus可以让你尝试在线书写Markdown并观察其效果。
commonmark spec规范是commonmark定义之所在。目前规范的版本是0.29 (2019-04-06) 。commonmark code则是此规范的标准实现。
平铺类型
Emphasis 和 strong emphasis
6.4Emphasis and strong emphasis
通常在Markdown里面如果用一个*
来包围其他字符,表示以strong的方式(通常是加粗)突出这些字符;如果是以两个*
来包围其他字符,则表示以emphasis(通常是斜体)的方式来强调这些字符。
但是嵌套的情况怎么处理呢?比如字符两边有若干个*
环绕,应该如何处置?
Markdown发明者John Gruber最初是这么说的:
Markdown treats asterisks (*) and underscores (_) as indicators of emphasis. Text wrapped with one * or _ will be wrapped with an HTML
<em>
tag; double *’s or _’s will be wrapped with an HTML<strong>
tag.
本来想在这篇文章中详细说明一些,Emphasis 和 strong emphasis的规则。后来一看,一共有十七条规则,并且举了130个例子来说明这些规则,实在没有办法在此一一列举了。所以下面就以非常不精确的语言来描述以下:
*
和_
都可以用来突出(emphasis),这两者最大的区别是在在单词中的表现,5*6*78
中的6会被突出,而5_6_78
中的6不会被突出,因为_
被视作单词的一部分。*
和_
不能混合使用,不能一个开头以另一个结尾。*
和_
和其所围绕的单词之间不能有空格。*
和_
对字符和标点符号有所区分对待,夹在字符和标点符号之间的多个*
和_
优先作用于字符。- 两个
*
或_
表示强调(strong)。超过两个以上的,表示突出强调。注意,一定是突出在前面,强调在后面,对应html的<em><strong></strong></em>
- 对于间隔出现的多组
*
或_
,采用优先匹配,最短匹配的原则。 *
和_
的效用要比平铺代码串(code)、链接(link)、图片(image)和HTML标签弱
在实际解析中,CommonMark用两个概念:左肋界定群(left-flanking delimiter run)和右肋界定群(right-flanking delimiter run)来协助解析的处理。这两个概念比较复杂,就不翻译了,原文照搬如下:
First, some definitions. A delimiter run is either a sequence of one or more * characters that is not preceded or followed by a non-backslash-escaped * character, or a sequence of one or more _ characters that is not preceded or followed by a non-backslash-escaped _ character.
A left-flanking delimiter run is a delimiter run that is (1) not followed by Unicode whitespace, and either (2a) not followed by a punctuation character, or (2b) followed by a punctuation character and preceded by Unicode whitespace or a punctuation character. For purposes of this definition, the beginning and the end of the line count as Unicode whitespace.
A right-flanking delimiter run is a delimiter run that is (1) not preceded by Unicode whitespace, and either (2a) not preceded by a punctuation character, or (2b) preceded by a punctuation character and followed by Unicode whitespace or a punctuation character. For purposes of this definition, the beginning and the end of the line count as Unicode whitespace.
(完)