强调

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)强调:

  1. 单个*字符可以可以开启强调,当且仅当它是左侧分隔符路程的一部分。
  2. 单个_字符可以可以开启强调,仅当它是左侧分隔符路程的一部分,并且(a)不是右侧分隔符路程的一部分或(b)在标点符号之前的右侧分隔符路程的一部分。
  3. 如果单个*字符是右侧分隔符路程的一部分,则它可以闭合强调
  4. 如果单个_字符是右侧分隔符路程的一部分并且 (a)不是左侧分隔符路程的一部分,或者 (b)左侧分隔符路程的一部分后跟标点符号,则单个_字符可以闭合强调
  5. **可以开启加强的强调,当且仅当它是左侧分隔符路程的一部分。
  6. __可以开启加强的强调,当且仅当它是左侧分隔符路程的一部分,并且(a)不是右侧分隔符路程的一部分,或者(b)在标点符号之前的右侧分隔符路程的一部分。
  7. 如果双**右侧分隔符路程的一部分,则它可以闭合特别强调
  8. 如果双__右侧分隔符路程的一部分并且(a)不是左侧分隔符路程的一部分或者(b)左侧分隔符路程的一部分后跟标点符号,则它可以闭合特别强调
  9. 强调从分隔符开始,该分隔符可以开启强调并以可以闭合强调的分隔符结束,并且使用与开始分隔符相同的字符(_*)。 开始和结束分隔符必须属于单独的分隔符路程。 如果其中一个分隔符可以开启和关闭强调,则包含开始和结束分隔符的分隔符路程的长度总和不能是 3 的倍数,除非两个长度都是 3 的倍数。
  10. 特别强调始于一个分界符,它可以开启特别强调,并以一个可以闭合特别强调的分隔符结束,并使用相同的字符(_*)作为起始分隔符。 开始和结束分隔符必须属于单独的分隔符路程。 如果其中一个分隔符可以打开和关闭强调,则包含开始和结束分隔符的分隔符路程的长度总和不能是 3 的倍数,除非两个长度都是 3 的倍数。
  11. 普通*字符不能出现在***分隔符强调的开头和结尾,除非它是反斜杠转义字符。
  12. 普通_字符不能出现在___分隔符强调的开头和结尾,除非它是反斜杠转义字符。

如果上面的规则 1-12 与多个解析兼容,则以下原则可解决歧义:

  1. 尽量减少嵌套数量,<strong>...</strong>始终优先于<em><em>...</em></em>
  2. 解释<em><strong>...</strong></em>始终优先于<strong><em>...</em></strong>
  3. 当两个潜在强调或加强的强调句子重叠时,第二个在第一个结束之前开始并在第一个结束之后结束,第一个优先。 因此,例如,*foo _bar* baz_被解析为 <em>foo _bar</em> baz_ 而不是*foo <em>bar* baz</em>
  4. 当有两个潜在的强调或加强的强调具有相同的结束分隔符时,较短的一个(稍后打开的那个)优先。 因此,例如, **foo **bar baz** 被解析为**foo <strong>bar baz</strong> 而不是<strong>foo **bar baz</strong>
  5. 内联行内代码,链接,图像和 HTML 标签组比强调更紧要。因此,当包含这些元素之一的解释与不包含其中一个元素的解释之间存在选择时,前者总是获胜。 因此,例如,*[foo*](bar) 被解析为*<a href="bar">foo*</a>而不是<em>[foo</em>](bar)

可以通过一系列示例来说明这些规则。
规则 1:

示例 360

Markdown HTML 效果
*foo bar*

<p><em>foo bar</em></p>

这不是强调,因为起始的*后跟空格,因此不是左侧分隔符路程的一部分:

示例 361

Markdown HTML 效果
a * foo bar*

<p>a * foo bar*</p>

这不是强调,因为起始的*前面有一个字母数字,后跟标点符号,因此不是左侧分隔符路程的一部分:

示例 362

Markdown HTML 效果
a*"foo"*

<p>a*&quot;foo&quot;*</p>

Unicode 不间断空格也算作空格:

示例 363

Markdown HTML 效果
* a *

<p>* a *</p>

允许使用*强调内部字符:

示例 364

Markdown HTML 效果
foo*bar*

<p>foo<em>bar</em></p>

示例 365

Markdown HTML 效果
5*6*78

<p>5<em>6</em>78</p>

规则 2:

示例 366

Markdown HTML 效果
_foo bar_

<p><em>foo bar</em></p>

这不是强调,因为起始的_后跟空格:

示例 367

Markdown HTML 效果
_ foo bar_

<p>_ foo bar_</p>

这不是强调,因为起始的_前面是一个字母数字,后跟标点符号:

示例 368

Markdown HTML 效果
a_"foo"_

<p>a_&quot;foo&quot;_</p>

在单词内部不允许用_强调:

示例 369

Markdown HTML 效果
foo_bar_

<p>foo_bar_</p>

示例 370

Markdown HTML 效果
5_6_78

<p>5_6_78</p>

示例 371

Markdown HTML 效果
пристаням_стремятся_

<p>пристаням_стремятся_</p>

这里_不会产生强调,因为第一个分隔符路程是右侧,第二个是左侧:

示例 372

Markdown HTML 效果
aa_"bb"_cc

<p>aa_&quot;bb&quot;_cc</p>

这是强调,即使开始分隔符是左侧和右侧,因为它之前是标点符号:

示例 373

Markdown HTML 效果
foo-_(bar)_

<p>foo-<em>(bar)</em></p>

规则 3:
这不是强调,因为结束分隔符与开始分隔符不匹配:

示例 374

Markdown HTML 效果
_foo*

<p>_foo*</p>

这不是强调,因为结束的*前面有空格:

示例 375

Markdown HTML 效果
*foo bar *

<p>*foo bar *</p>

换行符也算作空格:

示例 376

Markdown HTML 效果
*foo bar
*

<p>*foo bar
*</p>

这不是强调,因为第二个*之前是标点符号,后跟一个字母数字(因此它不是右侧分隔符路程的一部分:

示例 377

Markdown HTML 效果
*(*foo)

<p>*(*foo)</p>

使用此示例更容易理解此限制的要点

示例 378

Markdown HTML 效果
*(*foo*)*

<p><em>(<em>foo</em>)</em></p>

内部字符可以使用*强调:

示例 379

Markdown HTML 效果
*foo*bar

<p><em>foo</em>bar</p>

规则 4:
这不是强调,因为结束_前面有空格:

示例 380

Markdown HTML 效果
_foo bar _

<p>_foo bar _</p>

这不是强调,因为第二个_之前是标点符号,后面跟着一个字母数字:

示例 381

Markdown HTML 效果
_(_foo)

<p>_(_foo)</p>

嵌套强调:

示例 382

Markdown HTML 效果
_(_foo_)_

<p><em>(<em>foo</em>)</em></p>

内部字符不允许使用_来进行强调:

示例 383

Markdown HTML 效果
_foo_bar

<p>_foo_bar</p>

示例 384

Markdown HTML 效果
_пристаням_стремятся

<p>_пристаням_стремятся</p>

示例 385

Markdown HTML 效果
_foo_bar_baz_

<p><em>foo_bar_baz</em></p>

这是强调,尽管结束分隔符是左侧和右侧,因为它后面是标点符号:

示例 386

Markdown HTML 效果
_(bar)_.

<p><em>(bar)</em>.</p>

规则 5:

示例 387

Markdown HTML 效果
**foo bar**

<p><strong>foo bar</strong></p>

这不是强调,因为开始分隔符后跟空格:

示例 388

Markdown HTML 效果
** foo bar**

<p>** foo bar**</p>

这不是强调,因为起始的**前面是字母数字,后面是标点符号,因此不是左侧分隔符路程的一部分:

示例 389

Markdown HTML 效果
a**"foo"**

<p>a**&quot;foo&quot;**</p>

允许使用**强调内部字符:

示例 390

Markdown HTML 效果
foo**bar**

<p>foo<strong>bar</strong></p>

规则 6:

示例 391

Markdown HTML 效果
__foo bar__

<p><strong>foo bar</strong></p>

这不是强调,因为起始的分隔符后跟空格:

示例 392

Markdown HTML 效果
__ foo bar__

<p>__ foo bar__</p>

换行被认为是空格:

示例 393

Markdown HTML 效果
__
foo bar__

<p>__
foo bar__</p>

这不是强调,因为起始的__前面有一个字母数字,后面是标点符号:

示例 394

Markdown HTML 效果
a__"foo"__

<p>a__&quot;foo&quot;__</p>

禁止用__强调内部字符内容:

示例 395

Markdown HTML 效果
foo__bar__

<p>foo__bar__</p>

示例 396

Markdown HTML 效果
5__6__78

<p>5__6__78</p>

示例 397

Markdown HTML 效果
пристаням__стремятся__

<p>пристаням__стремятся__</p>

示例 398

Markdown HTML 效果
__foo, __bar__, baz__

<p><strong>foo, <strong>bar</strong>, baz</strong></p>

这是加强的强调,即使起始分隔符既算左侧也算右侧,因为它之前是标点符号:

示例 399

Markdown HTML 效果
foo-__(bar)__

<p>foo-<strong>(bar)</strong></p>

规则 7:
这不是强调,因为结束分隔符前面有空格:

示例 400

Markdown HTML 效果
**foo bar **

<p>**foo bar **</p>

(由于规则11,也不能将其解释为强调*foo bar *
这不是强调,因为第二个**之前是标点符号,后面跟着一个字母数字:

示例 401

Markdown HTML 效果
**(**foo)

<p>**(**foo)</p>

通过这些示例,更容易理解这一限制的要点:

示例 402

Markdown HTML 效果
*(**foo**)*

<p><em>(<strong>foo</strong>)</em></p>

示例 403

Markdown HTML 效果
**Gomphocarpus (*Gomphocarpus physocarpus*, syn.
*Asclepias physocarpa*)**

<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.
<em>Asclepias physocarpa</em>)</strong></p>

示例 404

Markdown HTML 效果
**foo "*bar*" foo**

<p><strong>foo &quot;<em>bar</em>&quot; foo</strong></p>

内部字符强调:

示例 405

Markdown HTML 效果
**foo**bar

<p><strong>foo</strong>bar</p>

规则 8:
这不是强调,因为结束分隔符前面有空格:

示例 406

Markdown HTML 效果
__foo bar __

<p>__foo bar __</p>

这不是强调,因为第二个__前面是标点符号,后跟一个字母数字:

示例 407

Markdown HTML 效果
__(__foo)

<p>__(__foo)</p>

使用此示例更容易理解此限制的要点:

示例 408

Markdown HTML 效果
_(__foo__)_

<p><em>(<strong>foo</strong>)</em></p>

禁止用__强调内部字符内容:

示例 409

Markdown HTML 效果
__foo__bar

<p>__foo__bar</p>

示例 410

Markdown HTML 效果
__пристаням__стремятся

<p>__пристаням__стремятся</p>

示例 411

Markdown HTML 效果
__foo__bar__baz__

<p><strong>foo__bar__baz</strong></p>

这是加强的强调,即使结束分隔符既算左侧也算右侧,因为它后面是标点符号:

示例 412

Markdown HTML 效果
__(bar)__.

<p><strong>(bar)</strong>.</p>

规则 9:
任何非空的内联元素序列都可以是强调行的内容。

示例 413

Markdown HTML 效果
*foo [bar](/url)*

<p><em>foo <a href="/url">bar</a></em></p>

示例 414

Markdown HTML 效果
*foo
bar*

<p><em>foo
bar</em></p>

特别地,强调和加强的强调可以嵌套:

示例 415

Markdown HTML 效果
_foo __bar__ baz_

<p><em>foo <strong>bar</strong> baz</em></p>

示例 416

Markdown HTML 效果
_foo _bar_ baz_

<p><em>foo <em>bar</em> baz</em></p>

示例 417

Markdown HTML 效果
__foo_ bar_

<p><em><em>foo</em> bar</em></p>

示例 418

Markdown HTML 效果
*foo *bar**

<p><em>foo <em>bar</em></em></p>

示例 419

Markdown HTML 效果
*foo **bar** baz*

<p><em>foo <strong>bar</strong> baz</em></p>

示例 420

Markdown HTML 效果
*foo**bar**baz*

<p><em>foo<strong>bar</strong>baz</em></p>

注意在前面的情况下,以下解释不会出现

<p><em>foo</em><em>bar<em></em>baz</em></p>

如果包含起始和结束分隔符的分隔符运行的长度之和是 3 的倍数,则可以打开和关闭的分隔符(如foo之后的*)不能形成强调的条件,除非两个长度都是倍数 3。

出于同样的原因,我们在这个例子中没有得到两个连续的强调部分:

示例 421

Markdown HTML 效果
*foo**bar*

<p><em>foo**bar</em></p>

相同的条件确保以下情况都将加强的强调被嵌套在强调内,即使内部空格被省略:

示例 422

Markdown HTML 效果
***foo** bar*

<p><em><strong>foo</strong> bar</em></p>

示例 423

Markdown HTML 效果
*foo **bar***

<p><em>foo <strong>bar</strong></em></p>

示例 424

Markdown HTML 效果
*foo**bar***

<p><em>foo<strong>bar</strong></em></p>

当内部闭合和打开的分隔符的长度都是 3 的倍数时,它们可以匹配来创建强调:

示例 425

Markdown HTML 效果
foo***bar***baz

<p>foo<em><strong>bar</strong></em>baz</p>

示例 426

Markdown HTML 效果
foo******bar*********baz

<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>

可以有无穷的嵌套:

示例 427

Markdown HTML 效果
*foo **bar *baz* bim** bop*

<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>

示例 428

Markdown HTML 效果
*foo [*bar*](/url)*

<p><em>foo <a href="/url"><em>bar</em></a></em></p>

可以解释为非空强调,或者加强的强调:

示例 429

Markdown HTML 效果
** is not an empty emphasis

<p>** is not an empty emphasis</p>

示例 430

Markdown HTML 效果
**** is not an empty strong emphasis

<p>**** is not an empty strong emphasis</p>

规则 10:
任何非空的内联元素序列都可以是强调行的内容。

示例 431

Markdown HTML 效果
**foo [bar](/url)**

<p><strong>foo <a href="/url">bar</a></strong></p>

示例 432

Markdown HTML 效果
**foo
bar**

<p><strong>foo
bar</strong></p>

特别地,加强的强调可以嵌套强调和加强的强调:

示例 433

Markdown HTML 效果
__foo _bar_ baz__

<p><strong>foo <em>bar</em> baz</strong></p>

示例 434

Markdown HTML 效果
__foo __bar__ baz__

<p><strong>foo <strong>bar</strong> baz</strong></p>

示例 435

Markdown HTML 效果
____foo__ bar__

<p><strong><strong>foo</strong> bar</strong></p>

示例 436

Markdown HTML 效果
**foo **bar****

<p><strong>foo <strong>bar</strong></strong></p>

示例 437

Markdown HTML 效果
**foo *bar* baz**

<p><strong>foo <em>bar</em> baz</strong></p>

示例 438

Markdown HTML 效果
**foo*bar*baz**

<p><strong>foo<em>bar</em>baz</strong></p>

示例 439

Markdown HTML 效果
***foo* bar**

<p><strong><em>foo</em> bar</strong></p>

示例 440

Markdown HTML 效果
**foo *bar***

<p><strong>foo <em>bar</em></strong></p>

可以有无穷的嵌套:

示例 441

Markdown HTML 效果
**foo *bar **baz**
bim* bop**

<p><strong>foo <em>bar <strong>baz</strong>
bim</em> bop</strong></p>

示例 442

Markdown HTML 效果
**foo [*bar*](/url)**

<p><strong>foo <a href="/url"><em>bar</em></a></strong></p>

这里解释为非空强调,或者加强的强调:

示例 443

Markdown HTML 效果
__ is not an empty emphasis

<p>__ is not an empty emphasis</p>

示例 444

Markdown HTML 效果
____ is not an empty strong emphasis

<p>____ is not an empty strong emphasis</p>

规则 11:

示例 445

Markdown HTML 效果
foo ***

<p>foo ***</p>

示例 446

Markdown HTML 效果
foo *\**

<p>foo <em>*</em></p>

示例 447

Markdown HTML 效果
foo *_*

<p>foo <em>_</em></p>

示例 448

Markdown HTML 效果
foo *****

<p>foo *****</p>

示例 449

Markdown HTML 效果
foo **\***

<p>foo <strong>*</strong></p>

示例 450

Markdown HTML 效果
foo **_**

<p>foo <strong>_</strong></p>

请注意,当分隔符不均匀匹配时,规则 11 确定多余的文字*字符将出现在强调之外,而不是在其中:

示例 451

Markdown HTML 效果
**foo*

<p>*<em>foo</em></p>

示例 452

Markdown HTML 效果
*foo**

<p><em>foo</em>*</p>

示例 453

Markdown HTML 效果
***foo**

<p>*<strong>foo</strong></p>

示例 454

Markdown HTML 效果
****foo*

<p>***<em>foo</em></p>

示例 455

Markdown HTML 效果
**foo***

<p><strong>foo</strong>*</p>

示例 456

Markdown HTML 效果
*foo****

<p><em>foo</em>***</p>

规则 12:

示例 457

Markdown HTML 效果
foo ___

<p>foo ___</p>

示例 458

Markdown HTML 效果
foo _\__

<p>foo <em>_</em></p>

示例 459

Markdown HTML 效果
foo _*_

<p>foo <em>*</em></p>

示例 460

Markdown HTML 效果
foo _____

<p>foo _____</p>

示例 461

Markdown HTML 效果
foo __\___

<p>foo <strong>_</strong></p>

示例 462

Markdown HTML 效果
foo __*__

<p>foo <strong>*</strong></p>

示例 463

Markdown HTML 效果
__foo_

<p>_<em>foo</em></p>

请注意,当分隔符不均匀匹配时,规则 12 确定多余的文字_字符将出现在强调之外,而不是在其中:

示例 464

Markdown HTML 效果
_foo__

<p><em>foo</em>_</p>

示例 465

Markdown HTML 效果
___foo__

<p>_<strong>foo</strong></p>

示例 466

Markdown HTML 效果
____foo_

<p>___<em>foo</em></p>

示例 467

Markdown HTML 效果
__foo___

<p><strong>foo</strong>_</p>

示例 468

Markdown HTML 效果
_foo____

<p><em>foo</em>___</p>

规则 13 确定如果你想强调直接嵌入强调内,你必须使用不同的分隔符:

示例 469

Markdown HTML 效果
**foo**

<p><strong>foo</strong></p>

示例 470

Markdown HTML 效果
*_foo_*

<p><em><em>foo</em></em></p>

示例 471

Markdown HTML 效果
__foo__

<p><strong>foo</strong></p>

示例 472

Markdown HTML 效果
_*foo*_

<p><em><em>foo</em></em></p>

但是,如果不切换分隔符,会被解释成加强强调中的加强强调:

示例 473

Markdown HTML 效果
****foo****

<p><strong><strong>foo</strong></strong></p>

示例 474

Markdown HTML 效果
____foo____

<p><strong><strong>foo</strong></strong></p>

规则 13 可以应用于任意长的分隔符序列:

示例 475

Markdown HTML 效果
******foo******

<p><strong><strong><strong>foo</strong></strong></strong></p>

规则 14:

示例 476

Markdown HTML 效果
***foo***

<p><em><strong>foo</strong></em></p>

示例 477

Markdown HTML 效果
_____foo_____

<p><em><strong><strong>foo</strong></strong></em></p>

规则 15:

示例 478

Markdown HTML 效果
*foo _bar* baz_

<p><em>foo _bar</em> baz_</p>

示例 479

Markdown HTML 效果
*foo __bar *baz bim__ bam*

<p><em>foo <strong>bar *baz bim</strong> bam</em></p>

规则 16:

示例 480

Markdown HTML 效果
**foo **bar baz**

<p>**foo <strong>bar baz</strong></p>

示例 481

Markdown HTML 效果
*foo *bar baz*

<p>*foo <em>bar baz</em></p>

规则 17:

示例 482

Markdown HTML 效果
*[bar*](/url)

<p>*<a href="/url">bar*</a></p>

示例 483

Markdown HTML 效果
_foo [bar_](/url)

<p>_foo <a href="/url">bar_</a></p>

示例 484

Markdown HTML 效果
*<img src="foo" title="*"/>

<p>*<img src="foo" title="*"/></p>

示例 485

Markdown HTML 效果
**<a href="**">

<p>**<a href="**"></p>

示例 486

Markdown HTML 效果
__<a href="__">

<p>__<a href="__"></p>

示例 487

Markdown HTML 效果
*a `*`*

<p><em>a <code>*</code></em></p>

示例 488

Markdown HTML 效果
_a `_`_

<p><em>a <code>_</code></em></p>

示例 489

Markdown HTML 效果
**a<http://foo.bar/?q=**>

<p>**a<a href="http://foo.bar/?q=**">http://foo.bar/?q=**</a></p>

示例 490

Markdown HTML 效果
__a<http://foo.bar/?q=__>

<p>__a<a href="http://foo.bar/?q=__">http://foo.bar/?q=__</a></p>