强调
John Gruber 的原始文档 Markdown 语法描述中说:
Markdown 将星号(
*
)和下划线(_
)作为强调。 用一个*
或_
包装的文本将用 HTML<em>
标签包装;两个*
或_
将用 HTML<strong>
标签包装。
这对大多数用户来说已经足够了,但是这些规则还有很多不确定性,特别是在嵌套强调方面。 最初的Markdown.pl
测试套件清楚地表明,三重***
和___
分隔符可用于强调,大多数实现也允许以下模式:
***strong emph***
***strong** in emph*
***emph* in strong**
**in strong *emph***
*in emph **strong***
以下模式支持较少,但意图很明确,它们很有用(特别是在参考书目条目的文本中):
*emph *with emph* in it*
**strong **with strong** in it**
许多实现还限制了对*
形式的字内(intraword)强调,以避免在包含内部下划线的单词中出现不必要的强调。(最好将这些放在行内代码中,但用户通常不这样做。)
internal emphasis: foo*bar*baz
no emphasis: foo_bar_baz
下面给出的规则捕获了上述所有的模式,同时允许高效的解析策略不会回溯。
首先,分隔符路程(delimiter run)是一个或多个*
字符的序列,其前面或后面没有非反斜杠转义的*
字符,或者是一个或多个_
字符的序列,前面或后面没有非反斜杠转义 _
字符。
左侧分隔符路程是一个(1)后面没有 Unicode 空格,或(2a)后面没有标点符号,或 (2b) 后面是标点符号且前面是 Unicode 空格 或标点符号的分隔符路程。出于此定义的目的,行的起始和结尾计为 Unicode 空格。
右侧分隔符路程是一个(1)前面没有 Unicode 空格,或(2a)前面没有标点符号,或 (2b) 前面是标点字符且后面是 Unicode 空格或标点符号的分隔符路程。出于此定义的目的,行的起始和结尾计为 Unicode 空格。
以下是一些分隔符路程的示例。
左侧分隔符:
***abc _abc **"abc" _"abc"
右侧分隔符:
abc*** abc_ "abc"** "abc"_
左右侧都分隔:
abc***def "abc"_"def"
左右侧都不分隔:
abc *** def a _ b
(区分左侧和右侧分隔符基于前面和后面的字符的想法来自 Roopesh Chander 的 vfmd。 vfmd 使用术语「强调指示符字符串」而不是「分隔符路程」,它用于区分左侧和右侧路程的规则比这里给出的要复杂一些。)
以下规则定义强调和加强的(strong)强调:
- 单个
*
字符可以可以开启强调,当且仅当它是左侧分隔符路程的一部分。 - 单个
_
字符可以可以开启强调,仅当它是左侧分隔符路程的一部分,并且(a)不是右侧分隔符路程的一部分或(b)在标点符号之前的右侧分隔符路程的一部分。 - 如果单个
*
字符是右侧分隔符路程的一部分,则它可以闭合强调。 - 如果单个
_
字符是右侧分隔符路程的一部分并且 (a)不是左侧分隔符路程的一部分,或者 (b)左侧分隔符路程的一部分后跟标点符号,则单个_
字符可以闭合强调。 - 双
**
可以开启加强的强调,当且仅当它是左侧分隔符路程的一部分。 - 双
__
可以开启加强的强调,当且仅当它是左侧分隔符路程的一部分,并且(a)不是右侧分隔符路程的一部分,或者(b)在标点符号之前的右侧分隔符路程的一部分。 - 如果双
**
是右侧分隔符路程的一部分,则它可以闭合特别强调。 - 如果双
__
是右侧分隔符路程的一部分并且(a)不是左侧分隔符路程的一部分或者(b)左侧分隔符路程的一部分后跟标点符号,则它可以闭合特别强调。 - 强调从分隔符开始,该分隔符可以开启强调并以可以闭合强调的分隔符结束,并且使用与开始分隔符相同的字符(
_
或*
)。 开始和结束分隔符必须属于单独的分隔符路程。 如果其中一个分隔符可以开启和关闭强调,则包含开始和结束分隔符的分隔符路程的长度总和不能是 3 的倍数,除非两个长度都是 3 的倍数。 - 特别强调始于一个分界符,它可以开启特别强调,并以一个可以闭合特别强调的分隔符结束,并使用相同的字符(
_
或*
)作为起始分隔符。 开始和结束分隔符必须属于单独的分隔符路程。 如果其中一个分隔符可以打开和关闭强调,则包含开始和结束分隔符的分隔符路程的长度总和不能是 3 的倍数,除非两个长度都是 3 的倍数。 - 普通
*
字符不能出现在*
或**
分隔符强调的开头和结尾,除非它是反斜杠转义字符。 - 普通
_
字符不能出现在_
或__
分隔符强调的开头和结尾,除非它是反斜杠转义字符。
如果上面的规则 1-12 与多个解析兼容,则以下原则可解决歧义:
- 尽量减少嵌套数量,
<strong>...</strong>
始终优先于<em><em>...</em></em>
。 - 解释
<em><strong>...</strong></em>
始终优先于<strong><em>...</em></strong>
。 - 当两个潜在强调或加强的强调句子重叠时,第二个在第一个结束之前开始并在第一个结束之后结束,第一个优先。 因此,例如,
*foo _bar* baz_
被解析为<em>foo _bar</em> baz_
而不是*foo <em>bar* baz</em>
。 - 当有两个潜在的强调或加强的强调具有相同的结束分隔符时,较短的一个(稍后打开的那个)优先。 因此,例如,
**foo **bar baz**
被解析为**foo <strong>bar baz</strong>
而不是<strong>foo **bar baz</strong>
。 - 内联行内代码,链接,图像和 HTML 标签组比强调更紧要。因此,当包含这些元素之一的解释与不包含其中一个元素的解释之间存在选择时,前者总是获胜。 因此,例如,
*[foo*](bar)
被解析为*<a href="bar">foo*</a>
而不是<em>[foo</em>](bar)
。
可以通过一系列示例来说明这些规则。
规则 1:
示例 360
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的*
后跟空格,因此不是左侧分隔符路程的一部分:
示例 361
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的*
前面有一个字母数字,后跟标点符号,因此不是左侧分隔符路程的一部分:
示例 362
Markdown | HTML | 效果 |
---|---|---|
|
|
Unicode 不间断空格也算作空格:
示例 363
Markdown | HTML | 效果 |
---|---|---|
|
|
允许使用*
强调内部字符:
示例 364
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 365
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 2:
示例 366
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的_
后跟空格:
示例 367
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的_
前面是一个字母数字,后跟标点符号:
示例 368
Markdown | HTML | 效果 |
---|---|---|
|
|
在单词内部不允许用_
强调:
示例 369
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 370
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 371
Markdown | HTML | 效果 |
---|---|---|
|
|
这里_
不会产生强调,因为第一个分隔符路程是右侧,第二个是左侧:
示例 372
Markdown | HTML | 效果 |
---|---|---|
|
|
这是强调,即使开始分隔符是左侧和右侧,因为它之前是标点符号:
示例 373
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 3:
这不是强调,因为结束分隔符与开始分隔符不匹配:
示例 374
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为结束的*
前面有空格:
示例 375
Markdown | HTML | 效果 |
---|---|---|
|
|
换行符也算作空格:
示例 376
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为第二个*
之前是标点符号,后跟一个字母数字(因此它不是右侧分隔符路程的一部分:
示例 377
Markdown | HTML | 效果 |
---|---|---|
|
|
使用此示例更容易理解此限制的要点
示例 378
Markdown | HTML | 效果 |
---|---|---|
|
|
内部字符可以使用*
强调:
示例 379
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 4:
这不是强调,因为结束_
前面有空格:
示例 380
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为第二个_
之前是标点符号,后面跟着一个字母数字:
示例 381
Markdown | HTML | 效果 |
---|---|---|
|
|
嵌套强调:
示例 382
Markdown | HTML | 效果 |
---|---|---|
|
|
内部字符不允许使用_
来进行强调:
示例 383
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 384
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 385
Markdown | HTML | 效果 |
---|---|---|
|
|
这是强调,尽管结束分隔符是左侧和右侧,因为它后面是标点符号:
示例 386
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 5:
示例 387
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为开始分隔符后跟空格:
示例 388
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的**
前面是字母数字,后面是标点符号,因此不是左侧分隔符路程的一部分:
示例 389
Markdown | HTML | 效果 |
---|---|---|
|
|
允许使用**
强调内部字符:
示例 390
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 6:
示例 391
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的分隔符后跟空格:
示例 392
Markdown | HTML | 效果 |
---|---|---|
|
|
换行被认为是空格:
示例 393
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为起始的__
前面有一个字母数字,后面是标点符号:
示例 394
Markdown | HTML | 效果 |
---|---|---|
|
|
禁止用__
强调内部字符内容:
示例 395
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 396
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 397
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 398
Markdown | HTML | 效果 |
---|---|---|
|
|
这是加强的强调,即使起始分隔符既算左侧也算右侧,因为它之前是标点符号:
示例 399
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 7:
这不是强调,因为结束分隔符前面有空格:
示例 400
Markdown | HTML | 效果 |
---|---|---|
|
|
(由于规则11,也不能将其解释为强调*foo bar *
)
这不是强调,因为第二个**
之前是标点符号,后面跟着一个字母数字:
示例 401
Markdown | HTML | 效果 |
---|---|---|
|
|
通过这些示例,更容易理解这一限制的要点:
示例 402
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 403
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 404
Markdown | HTML | 效果 |
---|---|---|
|
|
内部字符强调:
示例 405
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 8:
这不是强调,因为结束分隔符前面有空格:
示例 406
Markdown | HTML | 效果 |
---|---|---|
|
|
这不是强调,因为第二个__
前面是标点符号,后跟一个字母数字:
示例 407
Markdown | HTML | 效果 |
---|---|---|
|
|
使用此示例更容易理解此限制的要点:
示例 408
Markdown | HTML | 效果 |
---|---|---|
|
|
禁止用__
强调内部字符内容:
示例 409
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 410
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 411
Markdown | HTML | 效果 |
---|---|---|
|
|
这是加强的强调,即使结束分隔符既算左侧也算右侧,因为它后面是标点符号:
示例 412
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 9:
任何非空的内联元素序列都可以是强调行的内容。
示例 413
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 414
Markdown | HTML | 效果 |
---|---|---|
|
|
特别地,强调和加强的强调可以嵌套:
示例 415
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 416
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 417
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 418
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 419
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 420
Markdown | HTML | 效果 |
---|---|---|
|
|
注意在前面的情况下,以下解释不会出现
<p><em>foo</em><em>bar<em></em>baz</em></p>
如果包含起始和结束分隔符的分隔符运行的长度之和是 3 的倍数,则可以打开和关闭的分隔符(如foo
之后的*
)不能形成强调的条件,除非两个长度都是倍数 3。
出于同样的原因,我们在这个例子中没有得到两个连续的强调部分:
示例 421
Markdown | HTML | 效果 |
---|---|---|
|
|
相同的条件确保以下情况都将加强的强调被嵌套在强调内,即使内部空格被省略:
示例 422
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 423
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 424
Markdown | HTML | 效果 |
---|---|---|
|
|
当内部闭合和打开的分隔符的长度都是 3 的倍数时,它们可以匹配来创建强调:
示例 425
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 426
Markdown | HTML | 效果 |
---|---|---|
|
|
可以有无穷的嵌套:
示例 427
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 428
Markdown | HTML | 效果 |
---|---|---|
|
|
可以解释为非空强调,或者加强的强调:
示例 429
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 430
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 10:
任何非空的内联元素序列都可以是强调行的内容。
示例 431
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 432
Markdown | HTML | 效果 |
---|---|---|
|
|
特别地,加强的强调可以嵌套强调和加强的强调:
示例 433
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 434
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 435
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 436
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 437
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 438
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 439
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 440
Markdown | HTML | 效果 |
---|---|---|
|
|
可以有无穷的嵌套:
示例 441
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 442
Markdown | HTML | 效果 |
---|---|---|
|
|
这里解释为非空强调,或者加强的强调:
示例 443
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 444
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 11:
示例 445
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 446
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 447
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 448
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 449
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 450
Markdown | HTML | 效果 |
---|---|---|
|
|
请注意,当分隔符不均匀匹配时,规则 11 确定多余的文字*
字符将出现在强调之外,而不是在其中:
示例 451
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 452
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 453
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 454
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 455
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 456
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 12:
示例 457
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 458
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 459
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 460
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 461
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 462
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 463
Markdown | HTML | 效果 |
---|---|---|
|
|
请注意,当分隔符不均匀匹配时,规则 12 确定多余的文字_
字符将出现在强调之外,而不是在其中:
示例 464
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 465
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 466
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 467
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 468
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 13 确定如果你想强调直接嵌入强调内,你必须使用不同的分隔符:
示例 469
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 470
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 471
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 472
Markdown | HTML | 效果 |
---|---|---|
|
|
但是,如果不切换分隔符,会被解释成加强强调中的加强强调:
示例 473
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 474
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 13 可以应用于任意长的分隔符序列:
示例 475
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 14:
示例 476
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 477
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 15:
示例 478
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 479
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 16:
示例 480
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 481
Markdown | HTML | 效果 |
---|---|---|
|
|
规则 17:
示例 482
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 483
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 484
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 485
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 486
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 487
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 488
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 489
Markdown | HTML | 效果 |
---|---|---|
|
|
示例 490
Markdown | HTML | 效果 |
---|---|---|
|
|