通用标记规格

版本0.31.2 (2024-01-28)
约翰·麦克法兰
有创造力的
   下议院 BY-SA
CommonMark 规格 约翰·麦克法兰 (John MacFarlane) 获得许可 有创造力的 Commons Attribution-ShareAlike 4.0 国际许可证

1 简介

1.1 什么是 Markdown?

Markdown 是一种用于编写结构化文档的纯文本格式, 基于电子邮件中指示格式的约定 和新闻组帖子。它是由约翰·格鲁伯(John Gruber)开发的(与 在 Aaron Swartz 的帮助下)并于 2004 年以 语法描述 和一个 Perl 脚本( Markdown.pl) 用于将 Markdown 转换为 HTML。在接下来的十年里,数十个实施 以多种语言开发。有的扩展了原来的 具有脚注、表格和约定的 Markdown 语法 其他文档元素。有些允许 Markdown 文档 以 HTML 以外的格式呈现。像 Reddit 这样的网站, StackOverflow 和 GitHub 有数百万人使用 Markdown。 Markdown 开始在网络之外使用,用于撰写书籍, 文章、幻灯片、信件和讲义。

Markdown 与许多其他轻量级标记的区别是什么 语法,往往更容易编写,在于它的可读性。 正如格鲁伯所写:

Markdown 格式化语法的首要设计目标是 使其尽可能可读。这个想法是 Markdown 格式的文档应该可以按原样发布,如下所示 纯文本,看起来没有用标签标记 或格式说明。 ( https://daringfireball.net/projects/markdown/

可以通过比较一个样本来说明这一点 AsciiDoc 与 Markdown 的等效示例。这是一个示例 AsciiDoc 手册中的 AsciiDoc:

1. List item one.
+
List item one continued with a second paragraph followed by an
Indented block.
+
.................
$ ls *.sh
$ mv *.sh ~/tmp
.................
+
List item continued with a third paragraph.

2. List item two continued with an open block.
+
--
This paragraph is part of the preceding list item.

a. This list is nested and does not require explicit item
continuation.
+
This paragraph is part of the preceding list item.

b. List item b.

This paragraph belongs to item two of the outer list.
--

这是 Markdown 中的等效内容:

1.  List item one.

    List item one continued with a second paragraph followed by an
    Indented block.

        $ ls *.sh
        $ mv *.sh ~/tmp

    List item continued with a third paragraph.

2.  List item two continued with an open block.

    This paragraph is part of the preceding list item.

    1. This list is nested and does not require explicit item continuation.

       This paragraph is part of the preceding list item.

    2. List item b.

    This paragraph belongs to item two of the outer list.

AsciiDoc 版本可以说更容易编写。你不需要 担心缩进。但是Markdown版本就简单多了 阅读。列表项的嵌套在 源,而不仅仅是在处理后的文档中。

1.2 为什么需要规范?

John Gruber 对 Markdown 的规范描述 句法 没有明确指定语法。以下是一些示例 它没有回答的问题:

  1. 子列表需要多少缩进?规范说 连续段落需要缩进四个空格,但是 关于子列表不完全明确。人们很自然地认为 它们也必须缩进四个空格,但是 Markdown.pl 做 不需要那样。这并不是一个“极端案例”,并且存在分歧 在这个问题上的实现之间经常会导致意外 真实文档中的用户。 (参见 约翰的评论 格鲁伯 。)

  2. 块引用或标题之前是否需要空行? 大多数实现不需要空行。然而, 这可能会导致硬包装文本出现意外结果,并且 还有解析中的歧义(注意一些实现 将标题放在块引用内,而其他则不然)。 (约翰·格鲁伯也曾表示 赞成要求空白 线 。)

  3. 缩进的代码块之前是否需要空行? ( Markdown.pl 需要它,但是在 文档,某些实现不需要它。)

    paragraph
        code?
    
  4. 确定列表项何时获得的确切规则是什么 包裹在 <p> 标签?列表可以部分“松散”,部分“松散”吗? “紧的”?对于这样的列表我们应该做什么呢?

    1. one
    
    2. two
    3. three
    

    还是这个?

    1.  one
        - a
    
        - b
    2.  two
    

    (约翰·格鲁伯(John Gruber)有一些相关评论 这里 。)

  5. 列表标记可以缩进吗?有序列表标记可以右对齐吗?

     8. item 1
     9. item 2
    10. item 2a
    
  6. 这个列表的第二项有主题中断吗? 或者由主题分隔的两个列表?

    * a
    * * * * *
    * b
    
  7. 当列表标记从数字变为项目符号时,我们是否有 两份清单还是一份? (Markdown 语法描述建议有两种, 但 perl 脚本和许多其他实现都会生成一个。)

    1. fee
    2. fie
    -  foe
    -  fum
    
  8. 内联结构标记的优先规则是什么? 例如,以下链接是否有效,或者代码是否跨越 优先?

    [a backtick (`)](/url) and [another backtick (`)](/url).
    
  9. 强调和强标记的优先规则是什么 强调?例如,下面的内容应该如何解析?

    *foo *bar* baz*
    
  10. 块级和内联级之间的优先级规则是什么 结构?例如,下面的内容应该如何解析?

    - `a long code span can contain a hyphen like this
      - and it can screw things up`
    
  11. 列表项可以包含章节标题吗? ( Markdown.pl 不 允许这样做,但允许块引用包含标题。)

    - # Heading
    
  12. 列表项可以为空吗?

    * a
    *
    * b
    
  13. 可以在块引号或列表项内定义链接引用吗?

    > Blockquote [foo].
    >
    > [foo]: /url
    
  14. 如果同一个引用有多个定义,则需要 优先?

    [foo]: /url1
    [foo]: /url2
    
    [foo][]
    

在缺乏规范的情况下,早期实施者咨询了 Markdown.pl 来解决这些歧义。但 Markdown.pl 非常有问题,并且 在很多情况下都给出了明显不好的结果,所以这不是一个 令人满意的规格替代品。

由于没有明确的规范,因此实现存在分歧 相当。结果,用户常常惊讶地发现 在一个系统上以一种方式呈现的文档(例如 GitHub wiki) 在另一个上呈现不同的效果(例如,使用转换为文档 潘多克)。更糟糕的是,因为 Markdown 中没有任何内容 作为“语法错误”,这种分歧通常不会立即被发现。

1.3 关于本文档

本文档试图明确指定 Markdown 语法。 它包含许多并排 Markdown 和 HTML。这些旨在兼作一致性测试。一个 附带脚本 spec_tests.py 可用于运行测试 针对任何 Markdown 程序:

python test/spec_tests.py --spec spec.txt --program PROGRAM

由于该文档描述了 Markdown 如何被解析为 抽象语法树,使用抽象是有意义的 语法树的表示而不是 HTML。但 HTML 可以 代表我们需要做出的结构区别,以及 选择 HTML 进行测试使得可以针对其运行测试 无需编写抽象语法树渲染器的实现。

请注意,并非 HTML 示例的每个功能都是由 规格。例如,规范规定什么算作链接 目的地,但它不强制要求非 ASCII 字符 URL 采用百分比编码。要使用自动测试, 实现者需要提供一个符合以下要求的渲染器 规范示例的期望(百分比编码 URL 中的非 ASCII 字符)。但符合要求的实施 可以使用不同的渲染器,也可以选择不使用 对 URL 中的非 ASCII 字符进行百分比编码。

该文档是从文本文件生成的, spec.txt,写成 在 Markdown 中,带有用于并排测试的小扩展。 剧本 tools/makespec.py 可以用来转换 spec.txt 进入 HTML 或 CommonMark(然后可以转换为其他格式)。

在示例中, 字符用于表示制表符。

2 预赛

2.1 字符和台词

序列 任何字符 都是有效的 CommonMark 文档。

字符 是一个 Unicode 代码点。虽然有些 代码点(例如,组合重音符号)不对应于 直观意义上的字符,所有代码点都算作字符 就本规范而言。

该规范没有指定编码;它认为线条是组合的 字符 而不是字节 。合格的解析器可能是有限的 到某种编码。

一行 是零个 的序列 或多个字符 除了换行之外( U+000A) 或回车符 ( U+000D), 后跟行 结束符 或文件末尾。

行结束符 换行符 ( U+000A), 回车 ( U+000D) 后面不跟换行符或回车符和 以下换行。

不包含字符的行或仅包含空格的行 ( U+0020) 或制表符 ( U+0009),称为 空行

本规范中将使用以下字符类定义:

Unicode 空白字符 Unicode 中的字符 Zs 一般的 类别或选项卡 ( U+0009), 换行 ( U+000A)、换页( U+000C), 或者 回车( U+000D)。

Unicode 空白 是一个或多个的序列 Unicode 空白字符

一个 选项卡 U+0009

一个 空格 U+0020

ASCII 控制字符 介于 U+0000–1F (两个都 包括)或 U+007F

标点符号 ASCII !, ", #, $, %, &, ', (, ), *, +, ,, -, ., / (U+0021–2F), :, ;, <, =, >, ?, @ (U+003A–0040), [, \, ], ^, _, ` (U+005B–0060), {, |, }, 或者 ~ (U+007B–007E)。

Unicode 标点符号 Unicode 中的字符 P (标点符号)或 S (符号)一般类别。

2.2 选项卡

行中的制表符不会扩展为 空格 。然而, 在空间有助于定义块结构的情况下, 制表符的行为就好像它们被带有制表位的空格替换一样 共 4 个字符。

因此,例如,可以使用制表符代替四个空格 在缩进的代码块中。 (但是请注意,内部 选项卡作为文字选项卡传递,不扩展为 空格。)

示例1 尝试一下
→foo→baz→→bim
<pre><code>foo→baz→→bim
</code></pre>
示例2 尝试一下
  →foo→baz→→bim
<pre><code>foo→baz→→bim
</code></pre>
示例3 尝试一下
    a→a
    ὐ→a
<pre><code>a→a
ὐ→a
</code></pre>

在下面的示例中,列表的延续段落 项目用制表符缩进;这有完全相同的效果 四个空格的缩进将:

示例4 尝试一下
  - foo

→bar
<ul>
<li>
<p>foo</p>
<p>bar</p>
</li>
</ul>
示例5 尝试一下
- foo

→→bar
<ul>
<li>
<p>foo</p>
<pre><code>  bar
</code></pre>
</li>
</ul>

通常情况下 > 可以跟随以块引用开头 可选地通过一个空格,该空格不被视为 内容。在以下情况下 > 后面跟着一个选项卡, 它被视为扩展成三个空间。 由于这些空间之一被认为是 分隔符, foo 被认为是缩进六个空格 在块引用上下文中,所以我们得到一个缩进 以两个空格开头的代码块。

示例6 尝试一下
>→→foo
<blockquote>
<pre><code>  foo
</code></pre>
</blockquote>
示例7 尝试一下
-→→foo
<ul>
<li>
<pre><code>  foo
</code></pre>
</li>
</ul>
示例8 尝试一下
    foo
→bar
<pre><code>foo
bar
</code></pre>
示例 9 尝试一下
 - foo
   - bar
→ - baz
<ul>
<li>foo
<ul>
<li>bar
<ul>
<li>baz</li>
</ul>
</li>
</ul>
</li>
</ul>
示例 10 尝试一下
#→Foo
<h1>Foo</h1>
示例 11 尝试一下
*→*→*→
<hr />

2.3 不安全的角色

出于安全原因,Unicode 字符 U+0000 必须更换 与替换字符( U+FFFD)。

2.4 反斜杠转义

任何 ASCII 标点字符都可以进行反斜杠转义:

示例 12 尝试一下
\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~
<p>!&quot;#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</p>

其他字符之前的反斜杠被视为文字 反斜杠:

示例 13 尝试一下
\→\A\a\ \3\φ\«
<p>\→\A\a\ \3\φ\«</p>

转义字符被视为常规字符并且不会 没有通常的 Markdown 含义:

示例 14 尝试一下
\*not emphasized*
\<br/> not a tag
\[not a link](/foo)
\`not code`
1\. not a list
\* not a list
\# not a heading
\[foo]: /url "not a reference"
\&ouml; not a character entity
<p>*not emphasized*
&lt;br/&gt; not a tag
[not a link](/foo)
`not code`
1. not a list
* not a list
# not a heading
[foo]: /url &quot;not a reference&quot;
&amp;ouml; not a character entity</p>

如果反斜杠本身被转义,则以下字符不会被转义:

示例 15 尝试一下
\\*emphasis*
<p>\<em>emphasis</em></p>

行尾的反斜杠是 硬换行符

示例 16 尝试一下
foo\
bar
<p>foo<br />
bar</p>

反斜杠转义在代码块、代码跨度、自动链接或 原始 HTML:

示例 17 尝试一下
`` \[\` ``
<p><code>\[\`</code></p>
示例 18 尝试一下
    \[\]
<pre><code>\[\]
</code></pre>
示例 19 尝试一下
~~~
\[\]
~~~
<pre><code>\[\]
</code></pre>
示例 20 尝试一下
<https://example.com?find=\*>
<p><a href="https://example.com?find=%5C*">https://example.com?find=\*</a></p>
示例 21 尝试一下
<a href="/bar\/)">
<a href="/bar\/)">

但它们适用于所有其他上下文,包括 URL 和链接标题, 链接引用和 信息字符串 中的 受防护的代码块

示例 22 尝试一下
[foo](/bar\* "ti\*tle")
<p><a href="/bar*" title="ti*tle">foo</a></p>
示例 23 尝试一下
[foo]

[foo]: /bar\* "ti\*tle"
<p><a href="/bar*" title="ti*tle">foo</a></p>
示例 24 尝试一下
``` foo\+bar
foo
```
<pre><code class="language-foo+bar">foo
</code></pre>

2.5 实体和数字字符引用

有效的 HTML 实体引用和数字字符引用 可以用来代替相应的Unicode字符, 但以下情况除外:

符合 CommonMark 解析器不需要存储以下信息 源中是否表示了特定字符 使用 Unicode 字符或实体引用。

实体引用 包括 & + 任何有效的 HTML5 实体名称 + ;。这 文档 https://html.spec.whatwg.org/entities.json 用作有效实体的权威来源 参考文献及其相应的代码点。

示例 25 尝试一下
&nbsp; &amp; &copy; &AElig; &Dcaron;
&frac34; &HilbertSpace; &DifferentialD;
&ClockwiseContourIntegral; &ngE;
<p>  &amp; © Æ Ď
¾  ⅆ
∲ ≧̸</p>

十进制数字字符 参考 包括 &# + 一串 1-7 个阿拉伯数字 + ;。一个 数字字符引用被解析为相应的 统一码字符。无效的 Unicode 代码点将被替换为 替换字符( U+FFFD)。出于安全原因, 代码点 U+0000 也将被取代 U+FFFD

示例 26 尝试一下
&#35; &#1234; &#992; &#0;
<p># Ӓ Ϡ �</p>

十六进制数字字符 参考文献 包括 &# + 任何一个 X 或者 x + 1-6 个十六进制数字的字符串 + ;。 它们也被解析为相应的 Unicode 字符(这 用十六进制数字而不是十进制指定的时间)。

示例 27 尝试一下
&#X22; &#XD06; &#xcab;
<p>&quot;  ಫ</p>

以下是一些非实体的内容:

示例 28 尝试一下
&nbsp &x; &#; &#x;
&#87654321;
&#abcdef0;
&ThisIsNotDefined; &hi?;
<p>&amp;nbsp &amp;x; &amp;#; &amp;#x;
&amp;#87654321;
&amp;#abcdef0;
&amp;ThisIsNotDefined; &amp;hi?;</p>

尽管 HTML5 确实接受一些实体引用 没有尾随分号(例如 &copy),这些不是 在这里得到认可,因为它使语法变得过于模糊:

示例 29 尝试一下
&copy
<p>&amp;copy</p>

不在 HTML5 命名实体列表中的字符串不是 被识别为实体引用:

示例 30 尝试一下
&MadeUpEntity;
<p>&amp;MadeUpEntity;</p>

实体和数字字符引用可以在任何 除了代码跨度或代码块之外的上下文,包括 URL、 链接标题 受保护的代码块 信息字符串

示例 31 尝试一下
<a href="&ouml;&ouml;.html">
<a href="&ouml;&ouml;.html">
示例 32 尝试一下
[foo](/f&ouml;&ouml; "f&ouml;&ouml;")
<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
示例 33 尝试一下
[foo]

[foo]: /f&ouml;&ouml; "f&ouml;&ouml;"
<p><a href="/f%C3%B6%C3%B6" title="föö">foo</a></p>
示例 34 尝试一下
``` f&ouml;&ouml;
foo
```
<pre><code class="language-föö">foo
</code></pre>

实体和数字字符引用被视为文字 代码跨度和代码块中的文本:

示例 35 尝试一下
`f&ouml;&ouml;`
<p><code>f&amp;ouml;&amp;ouml;</code></p>
示例 36 尝试一下
    f&ouml;f&ouml;
<pre><code>f&amp;ouml;f&amp;ouml;
</code></pre>

不能使用实体和数字字符引用 代替 CommonMark 中表示结构的符号 文件。

实施例37 尝试一下
&#42;foo&#42;
*foo*
<p>*foo*
<em>foo</em></p>
示例 38 尝试一下
&#42; foo

* foo
<p>* foo</p>
<ul>
<li>foo</li>
</ul>
实施例39 尝试一下
foo&#10;&#10;bar
<p>foo

bar</p>
示例 40 尝试一下
&#9;foo
<p>→foo</p>
实施例41 尝试一下
[a](url &quot;tit&quot;)
<p>[a](url &quot;tit&quot;)</p>

3 块和内联

我们可以将文档视为一系列 ——结构元素,如段落、块 引用、列表、标题、规则和代码块。一些块(例如 块引用和列表项)包含其他块;其他人(比如 标题和段落)包含 内联 内容 - 文本, 链接、强调文本、图像、代码跨度等。

3.1 优先级

块结构的指标始终优先于指标 的内联结构。因此,例如,以下是一个列表 两项,而不是其中一项包含代码范围的列表:

实施例42 尝试一下
- `one
- two`
<ul>
<li>`one</li>
<li>two`</li>
</ul>

这意味着解析可以分两步进行:首先,块 可以辨别文档的结构;第二,里面的文字行 段落、标题和其他块结构可以被解析为内联 结构。第二步需要有关链接引用的信息 仅在第一个定义的末尾可用的定义 步。请注意,第一步需要按顺序处理行, 但第二个可以并行化,因为内联解析 一个块元素不会影响任何其他块元素的内联解析。

3.2 容器块和叶子块

我们可以将块分为两种类型: 集装箱块 , 它可以包含其他块和 叶块 , 这是不能的。

4 叶子块

本节描述了组成叶子块的不同类型 降价文档。

4.1 专题休息

一行由最多三个缩进空格组成,后跟一个 三个或更多匹配的序列 -, _, 或者 * 字符,每个都跟随 可选地由任意数量的空格或制表符组成 主题休息

实施例43 尝试一下
***
---
___
<hr />
<hr />
<hr />

错误字符:

实施例44 尝试一下
+++
<p>+++</p>
实施例45 尝试一下
===
<p>===</p>

字符数不足:

实施例46 尝试一下
--
**
__
<p>--
**
__</p>

最多允许三个空格的缩进:

实施例47 尝试一下
 ***
  ***
   ***
<hr />
<hr />
<hr />

四个空格的缩进太多了:

实施例48 尝试一下
    ***
<pre><code>***
</code></pre>
实施例49 尝试一下
Foo
    ***
<p>Foo
***</p>

可以使用三个以上的字符:

示例 50 尝试一下
_____________________________________
<hr />

字符之间允许有空格和制表符:

示例 51 尝试一下
 - - -
<hr />
实施例52 尝试一下
 **  * ** * ** * **
<hr />
实施例53 尝试一下
-     -      -      -
<hr />

末尾允许使用空格和制表符:

实施例54 尝试一下
- - - -    
<hr />

但是,该行中不能出现其他字符:

实施例55 尝试一下
_ _ _ _ a

a------

---a---
<p>_ _ _ _ a</p>
<p>a------</p>
<p>---a---</p>

要求除空格或制表符之外的所有字符都相同。 所以,这不是一个主题中断:

实施例56 尝试一下
 *-*
<p><em>-</em></p>

主题休息前后不需要空行:

实施例57 尝试一下
- foo
***
- bar
<ul>
<li>foo</li>
</ul>
<hr />
<ul>
<li>bar</li>
</ul>

主题中断可以打断一个段落:

实施例58 尝试一下
Foo
***
bar
<p>Foo</p>
<hr />
<p>bar</p>

如果一条虚线满足上述条件 的下划线 主题中断也可以解释为固定文本 标题 , 解释为 setext 标题 优先。因此,例如, 这是一个固定文本标题,而不是后面有主题中断的段落:

实施例59 尝试一下
Foo
---
bar
<h2>Foo</h2>
<p>bar</p>

当主题休息和列表项都可以时 对一行的解释,主题中断优先:

示例 60 尝试一下
* Foo
* * *
* Bar
<ul>
<li>Foo</li>
</ul>
<hr />
<ul>
<li>Bar</li>
</ul>

如果您想在列表项中进行主题中断,请使用不同的项目符号:

示例 61 尝试一下
- Foo
- * * *
<ul>
<li>Foo</li>
<li>
<hr />
</li>
</ul>

4.2 ATX 标题

标题 ATX 由一串字符组成,解析为内联内容,位于 1-6 未转义的开头序列 # 字符和可选的 任意数量的未转义的结束序列 # 人物。 开场顺序为 # 字符后必须跟空格或制表符,或者 到行尾。可选的关闭顺序 #s 之前必须是 空格或制表符,并且后面只能跟空格或制表符。开幕 # 字符前面最多可以有三个缩进空格。原始的 标题内容被去除前导和尾随空格或制表符 在被解析为内联内容之前。标题级别等于数字 的 # 开头序列中的字符。

简单标题:

实施例62 尝试一下
# foo
## foo
### foo
#### foo
##### foo
###### foo
<h1>foo</h1>
<h2>foo</h2>
<h3>foo</h3>
<h4>foo</h4>
<h5>foo</h5>
<h6>foo</h6>

六个以上 # 字符不是标题:

实施例63 尝试一下
####### foo
<p>####### foo</p>

之间至少需要一个空格或制表符 # 人物和 标题的内容,除非标题为空。请注意,许多 目前的实现不需要空间。然而, 需要空间 原始ATX实现 , 它有助于防止以下内容被解析为 标题:

示例 64 尝试一下
#5 bolt

#hashtag
<p>#5 bolt</p>
<p>#hashtag</p>

这不是标题,因为第一个 # 被转义:

实施例65 尝试一下
\## foo
<p>## foo</p>

内容被解析为内联:

实施例66 尝试一下
# foo *bar* \*baz\*
<h1>foo <em>bar</em> *baz*</h1>

解析内联内容时会忽略前导和尾随空格或制表符:

实施例67 尝试一下
#                  foo                     
<h1>foo</h1>

最多允许三个空格的缩进:

实施例68 尝试一下
 ### foo
  ## foo
   # foo
<h3>foo</h3>
<h2>foo</h2>
<h1>foo</h1>

四个空格的缩进太多了:

实施例69 尝试一下
    # foo
<pre><code># foo
</code></pre>
实施例70 尝试一下
foo
    # bar
<p>foo
# bar</p>

结束序列 # 字符是可选的:

实施例71 尝试一下
## foo ##
  ###   bar    ###
<h2>foo</h2>
<h3>bar</h3>

它不需要与开头序列的长度相同:

实施例72 尝试一下
# foo ##################################
##### foo ##
<h1>foo</h1>
<h5>foo</h5>

结束序列后允许使用空格或制表符:

实施例73 尝试一下
### foo ###     
<h3>foo</h3>

一系列 # 其后除空格或制表符外的任何字符 不是结束序列,但算作内容的一部分 标题:

实施例74 尝试一下
### foo ### b
<h3>foo ### b</h3>

结束序列之前必须有空格或制表符:

实施例75 尝试一下
# foo#
<h1>foo#</h1>

反斜杠转义 # 字符不算作一部分 关闭顺序:

实施例76 尝试一下
### foo \###
## foo #\##
# foo \#
<h3>foo ###</h3>
<h2>foo ###</h2>
<h1>foo #</h1>

ATX 标题不需要与周围的内容用空格分隔 行,并且它们可以打断段落:

实施例77 尝试一下
****
## foo
****
<hr />
<h2>foo</h2>
<hr />
实施例78 尝试一下
Foo bar
# baz
Bar foo
<p>Foo bar</p>
<h1>baz</h1>
<p>Bar foo</p>

ATX 标题可以为空:

实施例79 尝试一下
## 
#
### ###
<h2></h2>
<h1></h1>
<h3></h3>

4.3 设置文本标题

一个 settext 标题 由一个或多个 不被空行打断的文本行,其中第一行不被空行打断 有超过 3 个缩进空间,后面是 下划线 设置文本标题 。文本行必须是这样的 如果他们后面没有下划线的 setext 标题, 它们将被解释为一个段落:它们不能 可解释为 代码围栏 ATX 标题 块引用 主题休息 列表项 ,或 HTML 块

settext标题 下划线 是一系列 = 字符或序列 - 字符数,最多不超过3个 缩进空格和任意数量的尾随空格或制表符。

如果满足以下条件,则该标题为 1 级标题: = 字符用于 setext标题 下划线 和 2 级标题 if - 使用字符。标题内容即为结果 将前面的文本行解析为 CommonMark 内联 内容。

一般来说,固定文本标题之前或之后不需要 空行。然而,它不能打断一个段落,所以当 setext 标题位于段落之后,段落之间需要一个空行 他们。

简单的例子:

示例 80 尝试一下
Foo *bar*
=========

Foo *bar*
---------
<h1>Foo <em>bar</em></h1>
<h2>Foo <em>bar</em></h2>

标头的内容可能跨越一行以上:

实施例81 尝试一下
Foo *bar
baz*
====
<h1>Foo <em>bar
baz</em></h1>

内容是解析原始标题的结果 内容作为内联。标题的原始内容由以下内容组成 连接各行并删除开头和结尾 空格或制表符。

实施例82 尝试一下
  Foo *bar
baz*→
====
<h1>Foo <em>bar
baz</em></h1>

下划线可以是任意长度:

实施例83 尝试一下
Foo
-------------------------

Foo
=
<h2>Foo</h2>
<h1>Foo</h1>

标题内容前面最多可以有三个缩进空格,并且 不需要与下划线对齐:

实施例84 尝试一下
   Foo
---

  Foo
-----

  Foo
  ===
<h2>Foo</h2>
<h2>Foo</h2>
<h1>Foo</h1>

四个空格的缩进太多了:

实施例85 尝试一下
    Foo
    ---

    Foo
---
<pre><code>Foo
---

Foo
</code></pre>
<hr />

setext 标题下划线前面最多可以有三个空格 缩进,并且可能有尾随空格或制表符:

实施例86 尝试一下
Foo
   ----      
<h2>Foo</h2>

四个空格的缩进太多了:

实施例87 尝试一下
Foo
    ---
<p>Foo
---</p>

setext 标题下划线不能包含内部空格或制表符:

实施例88 尝试一下
Foo
= =

Foo
--- -
<p>Foo
= =</p>
<p>Foo</p>
<hr />

内容行中的尾随空格或制表符不会导致硬换行:

实施例89 尝试一下
Foo  
-----
<h2>Foo</h2>

末尾也没有反斜杠:

示例 90 尝试一下
Foo\
----
<h2>Foo\</h2>

由于块结构的指标优先于 内联结构的指示符,以下是setext标题:

实施例91 尝试一下
`Foo
----
`

<a title="a lot
---
of dashes"/>
<h2>`Foo</h2>
<p>`</p>
<h2>&lt;a title=&quot;a lot</h2>
<p>of dashes&quot;/&gt;</p>

setext 标题下划线不能是 惰性延续 行: 列表项或块引用中的

实施例92 尝试一下
> Foo
---
<blockquote>
<p>Foo</p>
</blockquote>
<hr />
实施例93 尝试一下
> foo
bar
===
<blockquote>
<p>foo
bar
===</p>
</blockquote>
实施例94 尝试一下
- Foo
---
<ul>
<li>Foo</li>
</ul>
<hr />

段落与后续段落之间需要有一个空行 setext 标题,否则该段落将成为一部分 标题内容:

实施例95 尝试一下
Foo
Bar
---
<h2>Foo
Bar</h2>

但一般情况下前后不需要空行 设置文本标题:

实施例96 尝试一下
---
Foo
---
Bar
---
Baz
<hr />
<h2>Foo</h2>
<h2>Bar</h2>
<p>Baz</p>

Setext 标题不能为空:

实施例97 尝试一下

====
<p>====</p>

Setext 标题文本行不得被解释为块 段落以外的结构。所以,虚线 在这些例子中被解释为主题中断:

实施例98 尝试一下
---
---
<hr />
<hr />
实施例99 尝试一下
- foo
-----
<ul>
<li>foo</li>
</ul>
<hr />
示例 100 尝试一下
    foo
---
<pre><code>foo
</code></pre>
<hr />
示例 101 尝试一下
> foo
-----
<blockquote>
<p>foo</p>
</blockquote>
<hr />

如果你想要一个标题 > foo 作为其文字文本,您可以 使用反斜杠转义:

示例 102 尝试一下
\> foo
------
<h2>&gt; foo</h2>

兼容性说明: 大多数现有 Markdown 实现 不允许 setext 标题的文本跨越多行。 但对于如何解读却没有达成共识

Foo
bar
---
baz

人们可以找到四种不同的解释:

  1. 段落“Foo”,标题“bar”,段落“baz”
  2. 段落“Foo bar”,主题休息,段落“baz”
  3. 段落“Foo bar — baz”
  4. 标题“Foo bar”,段落“baz”

我们发现解释 4 最自然,并且解释 4 通过允许增加 CommonMark 的表达能力 多行标题。想要解释1的作者可以 在第一段后添加一个空行:

示例 103 尝试一下
Foo

bar
---
baz
<p>Foo</p>
<h2>bar</h2>
<p>baz</p>

想要解释 2 的作者可以在周围添加空行 主题休息,

示例 104 尝试一下
Foo
bar

---

baz
<p>Foo
bar</p>
<hr />
<p>baz</p>

或使用不能算作 固定文本标题 的主题中断 下划线 ,例如

示例 105 尝试一下
Foo
bar
* * *
baz
<p>Foo
bar</p>
<hr />
<p>baz</p>

想要解释 3 的作者可以使用反斜杠转义:

实施例106 尝试一下
Foo
bar
\---
baz
<p>Foo
bar
---
baz</p>

4.4 缩进代码块

一个 缩进的代码块 由一个或多个组成 缩进块 由空行分隔的 。 是 缩进块 一系列非空行, 每个前面都有四个或更多的缩进空间。代码内容 块是行的文字内容,包括尾随 行结尾 ,减去四个缩进空格。 缩进的代码块没有 信息字符串

缩进的代码块不能打断一个段落,因此必须有 段落和后面的缩进代码块之间的空行。 (但是,代码块和后面的代码块之间不需要空行 段落。)

实施例107 尝试一下
    a simple
      indented code block
<pre><code>a simple
  indented code block
</code></pre>

如果缩进的解释之间存在任何歧义 作为代码块并指示材料属于 列表 item ,列表项解释优先:

示例108 尝试一下
  - foo

    bar
<ul>
<li>
<p>foo</p>
<p>bar</p>
</li>
</ul>
实施例109 尝试一下
1.  foo

    - bar
<ol>
<li>
<p>foo</p>
<ul>
<li>bar</li>
</ul>
</li>
</ol>

代码块的内容是文字文本,不会被解析 作为降价:

示例 110 尝试一下
    <a/>
    *hi*

    - one
<pre><code>&lt;a/&gt;
*hi*

- one
</code></pre>

这里我们有三个由空行分隔的块:

示例 111 尝试一下
    chunk1

    chunk2
  
 
 
    chunk3
<pre><code>chunk1

chunk2



chunk3
</code></pre>

任何超过四个缩进空格的初始空格或制表符都将包含在 内容,即使在内部空白行中:

示例 112 尝试一下
    chunk1
      
      chunk2
<pre><code>chunk1
  
  chunk2
</code></pre>

缩进的代码块不能中断段落。 (这 允许悬挂缩进等。)

示例 113 尝试一下
Foo
    bar
<p>Foo
bar</p>

但是,任何缩进空间少于四个的非空行都会结束 立即执行代码块。所以一个段落可能会立即出现 缩进代码后:

示例 114 尝试一下
    foo
bar
<pre><code>foo
</code></pre>
<p>bar</p>

缩进代码可以紧接在其他类型的之前和之后出现 块:

示例 115 尝试一下
# Heading
    foo
Heading
------
    foo
----
<h1>Heading</h1>
<pre><code>foo
</code></pre>
<h2>Heading</h2>
<pre><code>foo
</code></pre>
<hr />

第一行前面可以有四个以上的缩进空格:

实施例116 尝试一下
        foo
    bar
<pre><code>    foo
bar
</code></pre>

缩进代码块之前或之后的空行 不包括在其中:

实施例117 尝试一下

    
    foo
    
<pre><code>foo
</code></pre>

尾随空格或制表符包含在代码块的内容中:

实施例118 尝试一下
    foo  
<pre><code>foo  
</code></pre>

4.5 围栏代码块

代码 栅栏 是一个序列 至少三个连续的反引号字符( `) 或者 波形符( ~)。 (波形符和反引号不能混合使用。) 块 受围栏保护的代码 以代码围栏开始,前面最多有三个缩进空间。

带有开放代码围栏的行可以选择包含一些文本 遵循代码围栏;这是修剪了前导和尾随的 空格或制表符并称为 信息字符串 。如果 信息字符串 出现 在反引号栅栏之后,它不能包含任何反引号 人物。 (此限制的原因是否则 一些内联代码会被错误地解释为 受保护的代码块的开始。)

代码块的内容由所有后续行组成,直到 关闭 代码栅栏 与代码块类型相同的 以(反引号或波形符)开头,并且至少有同样多的反引号 或波形符作为起始代码栏。如果前导代码围栏是 前面有 N 个缩进空间,然后最多有 N 个缩进空间 从内容的每一行中删除(如果存在)。 (如果内容行不是 缩进,它保持不变。如果缩进N个空格或更少,则全部 压痕已被删除。)

结束代码栅栏之前最多可以有三个缩进空格,并且 后面可能只跟空格或制表符,这些都会被忽略。如果结束时 到达包含块(或文档)并且没有关闭代码围栏 已经找到,代码块包含了之后的所有行 打开代码围栏直到包含块的末尾(或 文档)。 (替代规范需要在 未找到关闭代码围栏的事件。但这使得解析 效率低得多,而且似乎没有真正的缺点 此处描述的行为。)

受隔离的代码块可能会中断一个段落,并且不需要 之前或之后的空行。

代码围栏的内容被视为文字文本,而不是被解析 作为内联。 的第一个单词 信息字符串 通常用于 指定代码示例的语言,并在 class 的属性 code 标签。然而,这个规范并没有强制要求任何 的特殊处理 对信息字符串

这是一个带有反引号的简单示例:

实施例119 尝试一下
```
<
 >
```
<pre><code>&lt;
 &gt;
</code></pre>

带波形符:

示例 120 尝试一下
~~~
<
 >
~~~
<pre><code>&lt;
 &gt;
</code></pre>

少于三个反引号是不够的:

示例 121 尝试一下
``
foo
``
<p><code>foo</code></p>

结束码围栏必须使用与开始码相同的字符 栅栏:

示例 122 尝试一下
```
aaa
~~~
```
<pre><code>aaa
~~~
</code></pre>
示例 123 尝试一下
~~~
aaa
```
~~~
<pre><code>aaa
```
</code></pre>

关闭代码栅栏必须至少与打开栅栏一样长:

示例 124 尝试一下
````
aaa
```
``````
<pre><code>aaa
```
</code></pre>
示例 125 尝试一下
~~~~
aaa
~~~
~~~~
<pre><code>aaa
~~~
</code></pre>

未关闭的代码块在文档末尾关闭 (或封闭的 块引用 列表项 ):

实施例126 尝试一下
```
<pre><code></code></pre>
示例 127 尝试一下
`````

```
aaa
<pre><code>
```
aaa
</code></pre>
示例 128 尝试一下
> ```
> aaa

bbb
<blockquote>
<pre><code>aaa
</code></pre>
</blockquote>
<p>bbb</p>

代码块可以将所有空行作为其内容:

实施例129 尝试一下
```

  
```
<pre><code>
  
</code></pre>

代码块可以为空:

示例 130 尝试一下
```
```
<pre><code></code></pre>

栅栏可以缩进。如果开口围栏是缩进的, 内容行将删除等效的开头缩进, 如果存在:

示例 131 尝试一下
 ```
 aaa
aaa
```
<pre><code>aaa
aaa
</code></pre>
实施例132 尝试一下
  ```
aaa
  aaa
aaa
  ```
<pre><code>aaa
aaa
aaa
</code></pre>
实施例133 尝试一下
   ```
   aaa
    aaa
  aaa
   ```
<pre><code>aaa
 aaa
aaa
</code></pre>

四个空格的缩进太多了:

实施例134 尝试一下
    ```
    aaa
    ```
<pre><code>```
aaa
```
</code></pre>

封闭栅栏之前最多可以有三个缩进空间,并且它们的 缩进不需要与开口栅栏的缩进相匹配:

实施例135 尝试一下
```
aaa
  ```
<pre><code>aaa
</code></pre>
实施例136 尝试一下
   ```
aaa
  ```
<pre><code>aaa
</code></pre>

这不是封闭栅栏,因为它缩进了 4 个空格:

实施例137 尝试一下
```
aaa
    ```
<pre><code>aaa
    ```
</code></pre>

代码围栏(打开和关闭)不能包含内部空格或制表符:

实施例138 尝试一下
``` ```
aaa
<p><code> </code>
aaa</p>
实施例139 尝试一下
~~~~~~
aaa
~~~ ~~
<pre><code>aaa
~~~ ~~
</code></pre>

围栏代码块可以打断段落,并且可以跟随 直接按段落,之间没有空行:

示例 140 尝试一下
foo
```
bar
```
baz
<p>foo</p>
<pre><code>bar
</code></pre>
<p>baz</p>

其他块也可以出现在受防护的代码块之前和之后 没有中间的空行:

示例 141 尝试一下
foo
---
~~~
bar
~~~
# baz
<h2>foo</h2>
<pre><code>bar
</code></pre>
<h1>baz</h1>

信息字符串 可以在开放代码围栏之后提供 尽管这个规范没有强制要求任何特定的处理 信息字符串,第一个单词通常用于指定 代码块的语言。在 HTML 输出中,语言是 通常通过添加一个类来表示 code 元素组成 的 language- 接下来是语言名称。

实施例142 尝试一下
```ruby
def foo(x)
  return 3
end
```
<pre><code class="language-ruby">def foo(x)
  return 3
end
</code></pre>
实施例143 尝试一下
~~~~    ruby startline=3 $%@#$
def foo(x)
  return 3
end
~~~~~~~
<pre><code class="language-ruby">def foo(x)
  return 3
end
</code></pre>
实施例144 尝试一下
````;
````
<pre><code class="language-;"></code></pre>

信息字符串不能包含反引号: 反引号代码块的

实施例145 尝试一下
``` aa ```
foo
<p><code>aa</code>
foo</p>

波形符代码块的信息字符串 可以包含反引号和波形符:

实施例146 尝试一下
~~~ aa ``` ~~~
foo
~~~
<pre><code class="language-aa">foo
</code></pre>

关闭代码围栏不能有 信息字符串

实施例147 尝试一下
```
``` aaa
```
<pre><code>``` aaa
</code></pre>

4.6 HTML 块

HTML 块 一组经过处理的行 作为原始 HTML(并且不会在 HTML 输出中转义)。

有七种 HTML 块 ,可以通过它们来定义 开始和结束条件。该块以满足以下条件的行开始 开始条件 (最多三个可选的缩进空格之后)。 它以满足匹配条件的第一个后续行结束 结束条件 ,或文档的最后一行,或 块 容器 包含当前 HTML 的 块,如果没有遇到满足 结束条件的 行。如果 第一行满足 开始条件 结束 条件 条件 ,该块将只包含该行。

  1. 开始条件: 行以字符串开头 <pre, <script, <style, 或者 <textarea (不区分大小写),后跟一个空格, 制表符、字符串 >,或行尾。
    结束条件: 行包含结束标记 </pre>, </script>, </style>, 或者 </textarea> (不区分大小写;它 不需要匹配开始标签)。

  2. 开始条件: 行以字符串开头 <!--
    结束条件: 行包含字符串 -->

  3. 开始条件: 行以字符串开头 <?
    结束条件: 行包含字符串 ?>

  4. 开始条件: 行以字符串开头 <! 后跟一个 ASCII 字母。
    结束条件: 行包含该字符 >

  5. 开始条件: 行以字符串开头 <![CDATA[
    结束条件: 行包含字符串 ]]>

  6. 开始条件: 行以字符串开头 < 或者 </ 后跟字符串之一(不区分大小写) address, article, aside, base, basefont, blockquote, body, caption, center, col, colgroup, dd, details, dialog, dir, div, dl, dt, fieldset, figcaption, figure, footer, form, frame, frameset, h1, h2, h3, h4, h5, h6, head, header, hr, html, iframe, legend, li, link, main, menu, menuitem, nav, noframes, ol, optgroup, option, p, param, search, section, summary, table, tbody, td, tfoot, th, thead, title, tr, track, ul,随后 由空格、制表符、行尾、字符串组成 >, 或者 字符串 />
    结束条件: 一行后面有一个 空行

  7. 开始条件: 行以完整的 开放标记 开始 ( 使用 pre, script, style, 或者 textarea) 或完整的 结束标签 , 后跟零个或多个空格和制表符,最后是行尾。
    结束条件: 一行后面有一个 空行

HTML 块将继续运行,直到它们被相应的块关闭为止。 结束条件 ,或文档或其他 容器 的最后一行 堵塞 。这意味着 HTML 中的 任何 HTML 块 否则可能被识别为启动条件的 将 被解析器忽略并按原样传递,无需更改 解析器的状态。

例如, <pre> 在由以下内容开始的 HTML 块中 <table> 不会影响 解析器状态;由于 HTML 块是由启动条件 6 启动的,因此 将在任何空行处结束。这可能会令人惊讶:

实施例148 尝试一下
<table><tr><td>
<pre>
**Hello**,

_world_.
</pre>
</td></tr></table>
<table><tr><td>
<pre>
**Hello**,
<p><em>world</em>.
</pre></p>
</td></tr></table>

在本例中,HTML 块以空行终止 — **Hello** 文本保持逐字记录——并且常规解析继续,带有一个段落, 强调 world 以及内联和块 HTML 跟随。

除类型 7 之外的所有类型的 HTML 块 都可能会中断 一个段落。类型 7 的块不能中断段落。 (此限制旨在防止不必要的解释 包装段落内的长标签作为起始 HTML 块。)

下面是一些简单的例子。以下是一些基本的 HTML 块 类型6:

实施例149 尝试一下
<table>
  <tr>
    <td>
           hi
    </td>
  </tr>
</table>

okay.
<table>
  <tr>
    <td>
           hi
    </td>
  </tr>
</table>
<p>okay.</p>
示例 150 尝试一下
 <div>
  *hello*
         <foo><a>
 <div>
  *hello*
         <foo><a>

块也可以以结束标记开头:

示例 151 尝试一下
</div>
*foo*
</div>
*foo*

这里我们有两个 HTML 块,它们之间有一个 Markdown 段落:

实施例152 尝试一下
<DIV CLASS="foo">

*Markdown*

</DIV>
<DIV CLASS="foo">
<p><em>Markdown</em></p>
</DIV>

第一行的标签可以是部分的,只要 因为它在有空格的地方被分割:

示例 153 尝试一下
<div id="foo"
  class="bar">
</div>
<div id="foo"
  class="bar">
</div>
实施例154 尝试一下
<div id="foo" class="bar
  baz">
</div>
<div id="foo" class="bar
  baz">
</div>

开放标签不需要关闭:

示例 155 尝试一下
<div>
*foo*

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

部分标签甚至不需要完成(垃圾 输入,垃圾输出):

实施例156 尝试一下
<div id="foo"
*hi*
<div id="foo"
*hi*
实施例157 尝试一下
<div class
foo
<div class
foo

初始标签甚至不需要是有效的 标签,只要它开头如下:

实施例158 尝试一下
<div *???-&&&-<---
*foo*
<div *???-&&&-<---
*foo*

在类型 6 块中,初始标记不必位于一行 本身:

实施例159 尝试一下
<div><a href="bar">*foo*</a></div>
<div><a href="bar">*foo*</a></div>
示例 160 尝试一下
<table><tr><td>
foo
</td></tr></table>
<table><tr><td>
foo
</td></tr></table>

直到下一个空行或文档末尾的所有内容 包含在 HTML 块中。所以,在下面的 例如,看起来像 Markdown 代码块 实际上是 HTML 块的一部分,一直持续到空白 行或到达文档末尾:

示例 161 尝试一下
<div></div>
``` c
int x = 33;
```
<div></div>
``` c
int x = 33;
```

开始 HTML 块 标签 使用不在 以下位置的 (6) 中的块级标签列表,您必须将标签放在 本身在第一行(并且必须完整):

实施例162 尝试一下
<a href="foo">
*bar*
</a>
<a href="foo">
*bar*
</a>

在类型 7 块中, 标签名称 可以是任何内容:

示例 163 尝试一下
<Warning>
*bar*
</Warning>
<Warning>
*bar*
</Warning>
实施例164 尝试一下
<i class="foo">
*bar*
</i>
<i class="foo">
*bar*
</i>
实施例165 尝试一下
</ins>
*bar*
</ins>
*bar*

这些规则旨在让我们能够使用以下标签: 可以用作块级或内联级标记。 这 <del> 标签就是一个很好的例子。我们可以围绕内容 <del> 以三种不同的方式进行标记。在这种情况下,我们得到一个原始的 HTML 块,因为 <del> 标签本身在一行上:

实施例166 尝试一下
<del>
*foo*
</del>
<del>
*foo*
</del>

在本例中,我们得到一个原始 HTML 块,其中仅包含 这 <del> 标签(因为它以以下空白结尾 线)。因此内容被解释为 CommonMark:

实施例167 尝试一下
<del>

*foo*

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

最后,在这种情况下, <del> 标签被解释 作为 原始 HTML 内的 CommonMark 段落 。 (因为 标签本身不在一行,我们得到内联 HTML 而不是 HTML 块 。)

实施例168 尝试一下
<del>*foo*</del>
<p><del><em>foo</em></del></p>

旨在包含文字内容的 HTML 标签 ( pre, script, style, textarea)、评论、处理说明、 和声明的处理方式有所不同。 这些块不是以第一个空行结束,而是 end 位于包含相应结束标记的第一行。 因此,这些块可以包含空行:

预标记(类型 1):

实施例169 尝试一下
<pre language="haskell"><code>
import Text.HTML.TagSoup

main :: IO ()
main = print $ parseTags tags
</code></pre>
okay
<pre language="haskell"><code>
import Text.HTML.TagSoup

main :: IO ()
main = print $ parseTags tags
</code></pre>
<p>okay</p>

脚本标签(类型 1):

示例 170 尝试一下
<script type="text/javascript">
// JavaScript example

document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
okay
<script type="text/javascript">
// JavaScript example

document.getElementById("demo").innerHTML = "Hello JavaScript!";
</script>
<p>okay</p>

文本区域标签(类型 1):

示例 171 尝试一下
<textarea>

*foo*

_bar_

</textarea>
<textarea>

*foo*

_bar_

</textarea>

样式标签(类型 1):

实施例172 尝试一下
<style
  type="text/css">
h1 {color:red;}

p {color:blue;}
</style>
okay
<style
  type="text/css">
h1 {color:red;}

p {color:blue;}
</style>
<p>okay</p>

如果没有匹配的结束标记,则该块将在 文档末尾(或封闭的 块引用 列表项 ):

实施例173 尝试一下
<style
  type="text/css">

foo
<style
  type="text/css">

foo
实施例174 尝试一下
> <div>
> foo

bar
<blockquote>
<div>
foo
</blockquote>
<p>bar</p>
实施例175 尝试一下
- <div>
- foo
<ul>
<li>
<div>
</li>
<li>foo</li>
</ul>

结束标记可以与开始标记出现在同一行:

实施例176 尝试一下
<style>p{color:red;}</style>
*foo*
<style>p{color:red;}</style>
<p><em>foo</em></p>
实施例177 尝试一下
<!-- foo -->*bar*
*baz*
<!-- foo -->*bar*
<p><em>baz</em></p>

请注意,最后一行上的任何内容 结束标签将包含在 HTML 块 中:

实施例178 尝试一下
<script>
foo
</script>1. *bar*
<script>
foo
</script>1. *bar*

评论(类型 2):

实施例179 尝试一下
<!-- Foo

bar
   baz -->
okay
<!-- Foo

bar
   baz -->
<p>okay</p>

处理指令(类型3):

示例 180 尝试一下
<?php

  echo '>';

?>
okay
<?php

  echo '>';

?>
<p>okay</p>

声明(类型 4):

示例 181 尝试一下
<!DOCTYPE html>
<!DOCTYPE html>

CDATA(类型 5):

实施例182 尝试一下
<![CDATA[
function matchwo(a,b)
{
  if (a < b && a < 0) then {
    return 1;

  } else {

    return 0;
  }
}
]]>
okay
<![CDATA[
function matchwo(a,b)
{
  if (a < b && a < 0) then {
    return 1;

  } else {

    return 0;
  }
}
]]>
<p>okay</p>

开始标记前面最多可以有三个缩进空格,但不能 四:

示例 183 尝试一下
  <!-- foo -->

    <!-- foo -->
  <!-- foo -->
<pre><code>&lt;!-- foo --&gt;
</code></pre>
实施例184 尝试一下
  <div>

    <div>
  <div>
<pre><code>&lt;div&gt;
</code></pre>

类型 1-6 的 HTML 块可以打断一个段落,并且不需要 前面有一个空行。

实施例185 尝试一下
Foo
<div>
bar
</div>
<p>Foo</p>
<div>
bar
</div>

但是,除了结尾处之外,还需要一个以下空行 一个文档,除了 上述 类型 1-5 的块:

实施例186 尝试一下
<div>
bar
</div>
*foo*
<div>
bar
</div>
*foo*

类型 7 的 HTML 块不能中断段落:

实施例187 尝试一下
Foo
<a href="bar">
baz
<p>Foo
<a href="bar">
baz</p>

该规则与 John Gruber 的原始 Markdown 语法不同 规范,其中说:

唯一的限制是块级 HTML 元素 - 例如 <div>, <table>, <pre>, <p>等——必须与 用空行包围内容,以及开始和结束标签 块不应缩进空格或制表符。

在某些方面,格鲁伯的规则比给定的规则更具限制性 这里:

大多数 Markdown 实现(包括 Gruber 自己的一些实现)都没有 尊重所有这些限制。

然而,在一个方面,格鲁伯的规则更加自由 比这里给出的,因为它允许空行出现在里面 HTML 块。这里禁止它们有两个原因。 首先,它消除了解析平衡标签的需要,即 昂贵并且可能需要从文档末尾回溯 如果没有找到匹配的结束标记。其次,它提供了一个非常简单的 以及在 HTML 标签中包含 Markdown 内容的灵活方式: 只需使用空行将 Markdown 与 HTML 分开:

比较:

实施例188 尝试一下
<div>

*Emphasized* text.

</div>
<div>
<p><em>Emphasized</em> text.</p>
</div>
实施例189 尝试一下
<div>
*Emphasized* text.
</div>
<div>
*Emphasized* text.
</div>

一些 Markdown 实现采用了以下约定 如果开放标签有,则将标签内的内容解释为文本 属性 markdown=1。上面给出的规则似乎更简单 实现相同表现力的更优雅的方式,这也是 解析起来要简单得多。

主要的潜在缺点是无法再粘贴 HTML 块以 100% 的可靠性写入 Markdown 文档。然而, 在大多数情况下, 这可以正常工作,因为中的空白行 HTML 后面通常跟着 HTML 块标记。例如:

示例 190 尝试一下
<table>

<tr>

<td>
Hi
</td>

</tr>

</table>
<table>
<tr>
<td>
Hi
</td>
</tr>
</table>

但是,如果内部标签缩进,就会出现问题 用空格分隔,这样它们将被解释为 缩进的代码块:

实施例191 尝试一下
<table>

  <tr>

    <td>
      Hi
    </td>

  </tr>

</table>
<table>
  <tr>
<pre><code>&lt;td&gt;
  Hi
&lt;/td&gt;
</code></pre>
  </tr>
</table>

幸运的是,空行通常不是必需的,可以 已删除。例外是在里面 <pre> 标签,但如上所述 上面 ,原始 HTML 块开头为 <pre> 可以 包含空行。

链接 参考定义 由一个 链接标签 组成,前面可以选择最多三个空格 缩进,后跟 用冒号 ( :)、可选空格或制表符(最多包含一个 行尾 ), 链接目标 , 可选空格或制表符(最多包括一个 行结尾 ) 和可选 链接 title ,如果存在则必须将其分开 通过空格或制表符从 链接目标 开始。 不能再出现任何字符。

链接 参考定义 不对应于文档的结构元素。相反,它 中使用的标签 定义可在参考链接 参考样式 图像 以及文档其他地方的 。关联 参考定义 可以位于使用的链接之前或之后 他们。

实施例192 尝试一下
[foo]: /url "title"

[foo]
<p><a href="/url" title="title">foo</a></p>
实施例193 尝试一下
   [foo]: 
      /url  
           'the title'  

[foo]
<p><a href="/url" title="the title">foo</a></p>
实施例194 尝试一下
[Foo*bar\]]:my_(url) 'title (with parens)'

[Foo*bar\]]
<p><a href="my_(url)" title="title (with parens)">Foo*bar]</a></p>
实施例195 尝试一下
[Foo bar]:
<my url>
'title'

[Foo bar]
<p><a href="my%20url" title="title">Foo bar</a></p>

标题可以跨越多行:

实施例196 尝试一下
[foo]: /url '
title
line1
line2
'

[foo]
<p><a href="/url" title="
title
line1
line2
">foo</a></p>

但是,它可能不包含 空行

实施例197 尝试一下
[foo]: /url 'title

with blank line'

[foo]
<p>[foo]: /url 'title</p>
<p>with blank line'</p>
<p>[foo]</p>

标题可以省略:

实施例198 尝试一下
[foo]:
/url

[foo]
<p><a href="/url">foo</a></p>

链接目标不能省略:

实施例199 尝试一下
[foo]:

[foo]
<p>[foo]:</p>
<p>[foo]</p>

但是,可以使用指定空链接目的地 尖括号:

示例 200 尝试一下
[foo]: <>

[foo]
<p><a href="">foo</a></p>

标题必须与链接目标分隔开 空格或制表符:

示例 201 尝试一下
[foo]: <bar>(baz)

[foo]
<p>[foo]: <bar>(baz)</p>
<p>[foo]</p>

标题和目标都可以包含反斜杠转义符 和文字反斜杠:

实施例202 尝试一下
[foo]: /url\bar\*baz "foo\"bar\baz"

[foo]
<p><a href="/url%5Cbar*baz" title="foo&quot;bar\baz">foo</a></p>

链接可以位于其相应的定义之前:

实施例203 尝试一下
[foo]

[foo]: url
<p><a href="url">foo</a></p>

如果有多个匹配的定义,则第一个为 优先级:

实施例204 尝试一下
[foo]

[foo]: first
[foo]: second
<p><a href="first">foo</a></p>

部分所述 正如链接 ,标签的匹配是 不区分大小写(参见 matches )。

实施例205 尝试一下
[FOO]: /url

[Foo]
<p><a href="/url">Foo</a></p>
实施例206 尝试一下
[ΑΓΩ]: /φου

[αγω]
<p><a href="/%CF%86%CE%BF%CF%85">αγω</a></p>

某物是否是 链接引用定义 是 与它定义的链接引用是否无关 文档中使用。因此,例如,以下 文档仅包含链接引用定义,并且 无可见内容:

实施例207 尝试一下
[foo]: /url

这是另一个:

实施例208 尝试一下
[
foo
]: /url
bar
<p>bar</p>

这不是链接引用定义,因为有 标题后除空格或制表符之外的字符:

实施例209 尝试一下
[foo]: /url "title" ok
<p>[foo]: /url &quot;title&quot; ok</p>

这是一个链接参考定义,但它没有标题:

示例 210 尝试一下
[foo]: /url
"title" ok
<p>&quot;title&quot; ok</p>

这不是链接引用定义,因为它是缩进的 四个空格:

实施例211 尝试一下
    [foo]: /url "title"

[foo]
<pre><code>[foo]: /url &quot;title&quot;
</code></pre>
<p>[foo]</p>

这不是链接引用定义,因为它出现在内部 一个代码块:

实施例212 尝试一下
```
[foo]: /url
```

[foo]
<pre><code>[foo]: /url
</code></pre>
<p>[foo]</p>

链接 引用定义 不能中断段落。

实施例213 尝试一下
Foo
[bar]: /baz

[bar]
<p>Foo
[bar]: /baz</p>
<p>[bar]</p>

但是,它可以直接跟随其他块元素,例如标题 和主题中断,并且后面不需要有空行。

实施例214 尝试一下
# [Foo]
[foo]: /url
> bar
<h1><a href="/url">Foo</a></h1>
<blockquote>
<p>bar</p>
</blockquote>
实施例215 尝试一下
[foo]: /url
bar
===
[foo]
<h1>bar</h1>
<p><a href="/url">foo</a></p>
实施例216 尝试一下
[foo]: /url
===
[foo]
<p>===
<a href="/url">foo</a></p>

几个 链接参考定义 可以一个接一个地出现,中间没有空行。

实施例217 尝试一下
[foo]: /foo-url "foo"
[bar]: /bar-url
  "bar"
[baz]: /baz-url

[foo],
[bar],
[baz]
<p><a href="/foo-url" title="foo">foo</a>,
<a href="/bar-url" title="bar">bar</a>,
<a href="/baz-url">baz</a></p>

链接引用定义 可能发生 在块容器内,例如列表和块引用。他们 影响整个文档,而不仅仅是它们所在的容器 定义为:

实施例218 尝试一下
[foo]

> [foo]: /url
<p><a href="/url">foo</a></p>
<blockquote>
</blockquote>

4.8 段落

不能被解释为其他的非空行序列 各种块组成一个 段落 。 该段落的内容是解析的结果 段落的原始内容作为内联。该段落的原始内容 通过连接行并删除初始和最终形成 空格或制表符。

一个简单的例子,有两段:

实施例219 尝试一下
aaa

bbb
<p>aaa</p>
<p>bbb</p>

段落可以包含多行,但不能包含空行:

示例 220 尝试一下
aaa
bbb

ccc
ddd
<p>aaa
bbb</p>
<p>ccc
ddd</p>

段落之间的多个空行没有效果:

实施例221 尝试一下
aaa


bbb
<p>aaa</p>
<p>bbb</p>

跳过前导空格或制表符:

实施例222 尝试一下
  aaa
 bbb
<p>aaa
bbb</p>

第一行之后的行可以缩进任意数量,因为缩进 代码块不能打断段落。

实施例223 尝试一下
aaa
             bbb
                                       ccc
<p>aaa
bbb
ccc</p>

但是,第一行前面最多可以有三个缩进空间。 四个空格的缩进太多了:

实施例224 尝试一下
   aaa
bbb
<p>aaa
bbb</p>
实施例225 尝试一下
    aaa
bbb
<pre><code>aaa
</code></pre>
<p>bbb</p>

最后的空格或制表符在内联解析之前被删除,因此一个段落 以两个或多个空格结尾的不会以 硬线 结尾 休息

实施例226 尝试一下
aaa     
bbb     
<p>aaa<br />
bbb</p>

4.9 空行

空行将 块级元素之间的 被忽略, 除了它们在确定列表 是否 还是

文档开头和结尾的空白行也将被忽略。

实施例227 尝试一下
  

aaa
  

# aaa

  
<p>aaa</p>
<h1>aaa</h1>

5 个 集装箱块

容器块 具有其他块的块 块作为其内容。有两种基本类型的容器块: 块引用 列表项 列表 的元容器 是列表项

我们递归地定义容器块的语法。将军 定义的形式为:

如果 X 是块序列,则结果 以这样那样的方式转换 X 是类型 Y 的容器 以这些块作为其内容。

因此,我们通过解释来解释什么算作块引用或列表项 如何 生成 从其内容 这些内容。这应该足够了 定义语法,尽管它没有给出 解析 的秘诀 这些构造。 (下面标题为“菜谱”的部分提供了一个食谱 解析策略 。)

5.1 块引用

标记 块引号 , 前面可以选择最多三个缩进空格, 由 (a) 字符组成 > 连同以下空间 缩进,或 (b) 单个字符 > 后面没有空格 缩进。

以下规则定义 块引号

  1. 基本案例。 如果一串行 Ls 构成一个序列 块 Bs 的结果 ,然后是在前面添加块引用 标记 中每行的开头 到Ls 块引用 包含 Bs 的

  2. 懒惰。 如果一串行 Ls 构成一个 块 引用 内容 Bs ,然后删除的结果 初始 块引用标记 来自一个或的 更多行,其中除空格或制表符之外的下一个字符 块引用标记 段落延续 text 块引用 是以Bs 为内容的 。 段落延续文本 是文本 将被解析为段落内容的一部分,但确实 不出现在段落的开头。

  3. 连续性。 一个文档不能包含两个 块 引号 连续 ,除非它们之间有空行

其他任何内容都不能算作 块引用

这是一个简单的例子:

实施例228 尝试一下
> # Foo
> bar
> baz
<blockquote>
<h1>Foo</h1>
<p>bar
baz</p>
</blockquote>

后面的空格或制表符 > 可以省略字符:

实施例229 尝试一下
># Foo
>bar
> baz
<blockquote>
<h1>Foo</h1>
<p>bar
baz</p>
</blockquote>

> 字符前面最多可以有三个缩进空格:

实施例230 尝试一下
   > # Foo
   > bar
 > baz
<blockquote>
<h1>Foo</h1>
<p>bar
baz</p>
</blockquote>

四个空格的缩进太多了:

实施例231 尝试一下
    > # Foo
    > bar
    > baz
<pre><code>&gt; # Foo
&gt; bar
&gt; baz
</code></pre>

惰性条款允许我们省略 >段落延续文字

实施例232 尝试一下
> # Foo
> bar
baz
<blockquote>
<h1>Foo</h1>
<p>bar
baz</p>
</blockquote>

块引用可以包含一些惰性引用和一些非惰性引用 续行:

实施例233 尝试一下
> bar
baz
> foo
<blockquote>
<p>bar
baz
foo</p>
</blockquote>

懒惰仅适用于本来是延续的行 段落前面是否带有 块引号标记 。 例如, > 第二行不能省略

> foo
> ---

不改变含义:

实施例234 尝试一下
> foo
---
<blockquote>
<p>foo</p>
</blockquote>
<hr />

同样,如果我们省略 > 在第二行

> - foo
> - bar

那么块引用在第一行之后结束:

实施例235 尝试一下
> - foo
- bar
<blockquote>
<ul>
<li>foo</li>
</ul>
</blockquote>
<ul>
<li>bar</li>
</ul>

出于同样的原因,我们也不能忽略 > 在...前面 缩进或围栏代码块的后续行:

实施例236 尝试一下
>     foo
    bar
<blockquote>
<pre><code>foo
</code></pre>
</blockquote>
<pre><code>bar
</code></pre>
实施例237 尝试一下
> ```
foo
```
<blockquote>
<pre><code></code></pre>
</blockquote>
<p>foo</p>
<pre><code></code></pre>

请注意,在以下情况下,我们有一个 惰性的 续行

实施例238 尝试一下
> foo
    - bar
<blockquote>
<p>foo
- bar</p>
</blockquote>

要了解原因,请注意

> foo
>     - bar

- bar 缩进太远而无法开始列表,并且不能 是缩进的代码块,因为缩进的代码块不能 中断段落,因此是 段落延续文本

块引用可以为空:

实施例239 尝试一下
>
<blockquote>
</blockquote>
示例 240 尝试一下
>
>  
> 
<blockquote>
</blockquote>

块引用可以有开头或结尾的空行:

实施例241 尝试一下
>
> foo
>  
<blockquote>
<p>foo</p>
</blockquote>

空行始终分隔块引号:

实施例242 尝试一下
> foo

> bar
<blockquote>
<p>foo</p>
</blockquote>
<blockquote>
<p>bar</p>
</blockquote>

(大多数当前的 Markdown 实现,包括 John Gruber 的 原来的 Markdown.pl,将将此示例解析为单块引用 有两个段落。但似乎还是让作者自己决定比较好 是否需要两个块引号或一个。)

连续性意味着如果我们将这些块引用放在一起, 我们得到一个单块引用:

实施例243 尝试一下
> foo
> bar
<blockquote>
<p>foo
bar</p>
</blockquote>

要获得包含两个段落的块引用,请使用:

实施例244 尝试一下
> foo
>
> bar
<blockquote>
<p>foo</p>
<p>bar</p>
</blockquote>

块引号可以打断段落:

实施例245 尝试一下
foo
> bar
<p>foo</p>
<blockquote>
<p>bar</p>
</blockquote>

一般情况下,块前后不需要空行 引号:

实施例246 尝试一下
> aaa
***
> bbb
<blockquote>
<p>aaa</p>
</blockquote>
<hr />
<blockquote>
<p>bbb</p>
</blockquote>

不过因为懒,中间需要空行 块引用和以下段落:

实施例247 尝试一下
> bar
baz
<blockquote>
<p>bar
baz</p>
</blockquote>
实施例248 尝试一下
> bar

baz
<blockquote>
<p>bar</p>
</blockquote>
<p>baz</p>
实施例249 尝试一下
> bar
>
baz
<blockquote>
<p>bar</p>
</blockquote>
<p>baz</p>

这是惰性规则的结果,任何数字 初始的 >a 的连续行上的 s 可以省略 嵌套块引用:

示例 250 尝试一下
> > > foo
bar
<blockquote>
<blockquote>
<blockquote>
<p>foo
bar</p>
</blockquote>
</blockquote>
</blockquote>
实施例251 尝试一下
>>> foo
> bar
>>baz
<blockquote>
<blockquote>
<blockquote>
<p>foo
bar
baz</p>
</blockquote>
</blockquote>
</blockquote>

当在块引用中包含缩进的代码块时, 请记住, 块引用标记 包括 两者都 > 以及后面的缩进空间。所以 五个空格 需要 之后 >:

实施例252 尝试一下
>     code

>    not code
<blockquote>
<pre><code>code
</code></pre>
</blockquote>
<blockquote>
<p>not code</p>
</blockquote>

5.2 列出项目

标记 列表 项目符号列表标记 有序列表标记

标记 项目符号列表 是一个 -, +, 或者 * 特点。

有序 列表标记 是 1-9 个阿拉伯数字的序列 ( 0-9),后跟一个 . 字符或一个 ) 特点。 (长度的原因 限制是 10 位数字后我们开始看到整数溢出 在某些浏览器中。)

以下规则定义 列表项

  1. 基本案例。 如果一系列线 Ls 构成一个序列 阻止 B 以空格或制表符以外的字符开头的 ,并且M 是 的列表标记, 宽度为W 后跟 1 ≤ N ≤ 4 个缩进空间, 添加到第一行的结果 然后将M 和后面的空格 Ls ,并将 的后续行缩进 Ls 个空格 W + N ,是 作为其内容的列表项 以Bs 。列表项的类型 (项目符号或有序)由其列表标记的类型确定。 如果列表项是有序的,那么它也会被分配一个开始 数字,基于有序列表标记。

    例外情况:

    1. 中的第一个列表项 当列表 中断 时 一个段落——也就是说,当它从一行开始时 否则算作 段落延续文本 - 则 (a) 行 Ls 不得以空行开头,并且 (b) 如果 列表项是有序的,起始编号必须为 1。
    2. 如果任何一行是 主题中断 那么 该行不是列表项。

例如,令 Ls 为线

实施例253 尝试一下
A paragraph
with two lines.

    indented code

> A block quote.
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>

并让 M 成为标记 1.,并且 N = 2。然后规则#1 说 以下是一个起始编号为 1 的有序列表项, 的内容相同 和Ls

实施例254 尝试一下
1.  A paragraph
    with two lines.

        indented code

    > A block quote.
<ol>
<li>
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>
</li>
</ol>

最需要注意的是, 列表标记后面的文本决定缩进量 在列表项的后续块中需要。如果列表 标记占用两个缩进空间,并且之间有三个空格 列表标记和除空格或制表符之外的下一个字符,然后阻塞 必须缩进五个空格才能落入列表中 物品。

以下是一些示例,显示内容必须缩进多远 放在列表项下:

实施例255 尝试一下
- one

 two
<ul>
<li>one</li>
</ul>
<p>two</p>
实施例256 尝试一下
- one

  two
<ul>
<li>
<p>one</p>
<p>two</p>
</li>
</ul>
实施例257 尝试一下
 -    one

     two
<ul>
<li>one</li>
</ul>
<pre><code> two
</code></pre>
实施例258 尝试一下
 -    one

      two
<ul>
<li>
<p>one</p>
<p>two</p>
</li>
</ul>

人们很容易从列的角度来思考这一点:延续 块必须至少缩进到除 列表标记后的空格或制表符。然而,这并不完全正确。 列表标记后面的缩进空格决定了相对的程度 需要缩进。该缩进到达哪一列取决于 列表项如何嵌入到其他结构中,如下所示 这个例子:

实施例259 尝试一下
   > > 1.  one
>>
>>     two
<blockquote>
<blockquote>
<ol>
<li>
<p>one</p>
<p>two</p>
</li>
</ol>
</blockquote>
</blockquote>

这里 two 与列表标记出现在同一列中 1., 但实际上包含在列表项中,因为有 最后一个包含块引用标记后有足够的缩进。

反之亦然。在下面的例子中,单词 two 出现在列表项初始文本的右侧很远的地方, one, 但 它不被视为列表项的一部分,因为它没有缩进 距离块引用标记足够远:

示例 260 尝试一下
>>- one
>>
  >  > two
<blockquote>
<blockquote>
<ul>
<li>one</li>
</ul>
<p>two</p>
</blockquote>
</blockquote>

请注意,列表标记和列表标记之间至少需要一个空格或制表符。 任何以下内容,因此这些不是列表项:

实施例261 尝试一下
-one

2.two
<p>-one</p>
<p>2.two</p>

列表项可能包含由多个分隔的块 一个空行。

实施例262 尝试一下
- foo


  bar
<ul>
<li>
<p>foo</p>
<p>bar</p>
</li>
</ul>

列表项可以包含任何类型的块:

实施例263 尝试一下
1.  foo

    ```
    bar
    ```

    baz

    > bam
<ol>
<li>
<p>foo</p>
<pre><code>bar
</code></pre>
<p>baz</p>
<blockquote>
<p>bam</p>
</blockquote>
</li>
</ol>

包含缩进代码块的列表项将保留 代码块中的空行逐字。

实施例264 尝试一下
- Foo

      bar


      baz
<ul>
<li>
<p>Foo</p>
<pre><code>bar


baz
</code></pre>
</li>
</ul>

请注意,有序列表的起始编号必须为九位或更少:

实施例265 尝试一下
123456789. ok
<ol start="123456789">
<li>ok</li>
</ol>
实施例266 尝试一下
1234567890. not ok
<p>1234567890. not ok</p>

起始编号可以以 0 开头:

实施例267 尝试一下
0. ok
<ol start="0">
<li>ok</li>
</ol>
实施例268 尝试一下
003. ok
<ol start="3">
<li>ok</li>
</ol>

起始编号不能为负数:

实施例269 尝试一下
-1. not ok
<p>-1. not ok</p>
  1. 以缩进代码开头的项目。 如果一系列行 Ls 的序列 块B 构成以缩进代码开头的 块, M 的列表标记, 是宽度为W 后跟 一个空格的缩进,然后是前面加上 M 和 第一行后面有空格 Ls ,并缩进后续行 Ls 为其 乘以 W + 1 个 列表项 空格,是一个以 Bs 内容的 。 如果一行是空的,则不需要缩进。的类型 列表项(项目符号或有序)由其列表的类型决定 标记。如果列表项是有序的,那么它也会被分配一个 起始编号,基于有序列表标记。

缩进的代码块前面必须有四个缩进空格 超出列表项中包含文本的区域的边缘。 在以下情况下为 6 个空格:

示例 270 尝试一下
- foo

      bar
<ul>
<li>
<p>foo</p>
<pre><code>bar
</code></pre>
</li>
</ul>

在本例中为 11 个空格:

实施例271 尝试一下
  10.  foo

           bar
<ol start="10">
<li>
<p>foo</p>
<pre><code>bar
</code></pre>
</li>
</ol>

如果 列表项中的第一个 块是缩进代码块, 然后根据规则#2,内容前面必须有 一个 缩进空格 在列表标记之后:

实施例272 尝试一下
    indented code

paragraph

    more code
<pre><code>indented code
</code></pre>
<p>paragraph</p>
<pre><code>more code
</code></pre>
实施例273 尝试一下
1.     indented code

   paragraph

       more code
<ol>
<li>
<pre><code>indented code
</code></pre>
<p>paragraph</p>
<pre><code>more code
</code></pre>
</li>
</ol>

请注意,额外的缩进空间被解释为空格 代码块内:

实施例274 尝试一下
1.      indented code

   paragraph

       more code
<ol>
<li>
<pre><code> indented code
</code></pre>
<p>paragraph</p>
<pre><code>more code
</code></pre>
</li>
</ol>

请注意,规则 #1 和规则 #2 仅适用于两种情况: (a) 情况 其中要包含在列表项中的行以 空格或制表符以外的字符,以及 (b) 的情况 它们以缩进代码开头 堵塞。在如下情况下,第一个块开头为 三个空格的缩进,规则不允许我们通过以下方式形成列表项 缩进整个内容并在前面添加一个列表标记:

实施例275 尝试一下
   foo

bar
<p>foo</p>
<p>bar</p>
实施例276 尝试一下
-    foo

  bar
<ul>
<li>foo</li>
</ul>
<p>bar</p>

这不是一个重要的限制,因为当一个块前面最多有 三个空格的缩进,缩进可以随时删除,无需 解释的改变,允许应用规则#1。所以,在 上述案例:

实施例277 尝试一下
-  foo

   bar
<ul>
<li>
<p>foo</p>
<p>bar</p>
</li>
</ul>
  1. 以空行开头的项目。 如果一系列行 Ls 以一个 空行 开始构成一个(可能是空的) 块序列 Bs M 的列表标记 是宽度W , 结果 然后将M 第一行的 添加到Ls ,以及 的后续行之前 Ls W + 1 个 缩进空间, 作为其内容的列表项 以Bs 。 如果一行是空的,则不需要缩进。的类型 列表项(项目符号或有序)由其列表的类型确定 标记。如果列表项是有序的,那么它也会被分配一个 起始编号,基于有序列表标记。

以下是一些以空行开头但不为空的列表项:

实施例278 尝试一下
-
  foo
-
  ```
  bar
  ```
-
      baz
<ul>
<li>foo</li>
<li>
<pre><code>bar
</code></pre>
</li>
<li>
<pre><code>baz
</code></pre>
</li>
</ul>

当列表项以空行开头时,空格数 遵循列表标记不会更改所需的缩进:

实施例279 尝试一下
-   
  foo
<ul>
<li>foo</li>
</ul>

列表项最多可以以一个空行开始。 在下面的示例中, foo 不属于列表的一部分 物品:

示例 280 尝试一下
-

  foo
<ul>
<li></li>
</ul>
<p>foo</p>

这是一个空的项目符号列表项:

实施例281 尝试一下
- foo
-
- bar
<ul>
<li>foo</li>
<li></li>
<li>bar</li>
</ul>

后面是否有空格或制表符并不重要 列表标记

实施例282 尝试一下
- foo
-   
- bar
<ul>
<li>foo</li>
<li></li>
<li>bar</li>
</ul>

这是一个空的有序列表项:

实施例283 尝试一下
1. foo
2.
3. bar
<ol>
<li>foo</li>
<li></li>
<li>bar</li>
</ol>

列表可以以空列表项开始或结束:

实施例284 尝试一下
*
<ul>
<li></li>
</ul>

但是,空列表项不能中断段落:

实施例285 尝试一下
foo
*

foo
1.
<p>foo
*</p>
<p>foo
1.</p>
  1. 缩进。 如果一系列行 Ls 构成列表项 根据规则 #1、#2 或 #3,然后是前面每一行的结果 Ls 最多三个缩进空间(每行相同 构成具有相同内容和属性的列表项。如果一条线是 为空,则不需要缩进。

缩进一个空格:

实施例286 尝试一下
 1.  A paragraph
     with two lines.

         indented code

     > A block quote.
<ol>
<li>
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>
</li>
</ol>

缩进两个空格:

实施例287 尝试一下
  1.  A paragraph
      with two lines.

          indented code

      > A block quote.
<ol>
<li>
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>
</li>
</ol>

缩进三个空格:

实施例288 尝试一下
   1.  A paragraph
       with two lines.

           indented code

       > A block quote.
<ol>
<li>
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>
</li>
</ol>

四个空格缩进给出一个代码块:

实施例289 尝试一下
    1.  A paragraph
        with two lines.

            indented code

        > A block quote.
<pre><code>1.  A paragraph
    with two lines.

        indented code

    &gt; A block quote.
</code></pre>
  1. 懒惰。 如果一串行 Ls 构成一个 列表 项 内容为 Bs 的 ,则删除的结果 一行或多行的部分或全部缩进,其中 缩进后除空格或制表符之外的下一个字符 段落延续文本 是 具有相同内容和属性的列表项。未缩进的 线被称为 懒惰 延续 线 .

这是一个带有 惰性连续线 的示例:

实施例290 尝试一下
  1.  A paragraph
with two lines.

          indented code

      > A block quote.
<ol>
<li>
<p>A paragraph
with two lines.</p>
<pre><code>indented code
</code></pre>
<blockquote>
<p>A block quote.</p>
</blockquote>
</li>
</ol>

可以部分删除缩进:

实施例291 尝试一下
  1.  A paragraph
    with two lines.
<ol>
<li>A paragraph
with two lines.</li>
</ol>

这些示例展示了惰性如何在嵌套结构中发挥作用:

实施例292 尝试一下
> 1. > Blockquote
continued here.
<blockquote>
<ol>
<li>
<blockquote>
<p>Blockquote
continued here.</p>
</blockquote>
</li>
</ol>
</blockquote>
实施例293 尝试一下
> 1. > Blockquote
> continued here.
<blockquote>
<ol>
<li>
<blockquote>
<p>Blockquote
continued here.</p>
</blockquote>
</li>
</ol>
</blockquote>
  1. 就这样。 不属于规则列表项的内容 #1–5 算作一个 列表项

子列表的规则遵循一般规则 多于 。子列表必须缩进相同的数字 段落需要的缩进空间才能被包含在内 在列表项中。

因此,在这种情况下我们需要两个空格缩进:

实施例294 尝试一下
- foo
  - bar
    - baz
      - boo
<ul>
<li>foo
<ul>
<li>bar
<ul>
<li>baz
<ul>
<li>boo</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>

一个还不够:

实施例295 尝试一下
- foo
 - bar
  - baz
   - boo
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
<li>boo</li>
</ul>

这里我们需要四个,因为列表标记更宽:

实施例296 尝试一下
10) foo
    - bar
<ol start="10">
<li>foo
<ul>
<li>bar</li>
</ul>
</li>
</ol>

三个还不够:

实施例297 尝试一下
10) foo
   - bar
<ol start="10">
<li>foo</li>
</ol>
<ul>
<li>bar</li>
</ul>

列表可以是列表项中的第一个块:

实施例298 尝试一下
- - foo
<ul>
<li>
<ul>
<li>foo</li>
</ul>
</li>
</ul>
实施例299 尝试一下
1. - 2. foo
<ol>
<li>
<ul>
<li>
<ol start="2">
<li>foo</li>
</ol>
</li>
</ul>
</li>
</ol>

列表项可以包含标题:

示例 300 尝试一下
- # Foo
- Bar
  ---
  baz
<ul>
<li>
<h1>Foo</h1>
</li>
<li>
<h2>Bar</h2>
baz</li>
</ul>

5.2.1 动机

John Gruber 的 Markdown 规范对列表项做了以下说明:

  1. “列表标记通常从左边距开始,但可能会缩进 最多三个空格。列表标记后面必须跟一个或多个 空格或制表符。”

  2. “为了让列表看起来更漂亮,你可以用悬挂缩进来包裹项目...... 但如果你不愿意,那就没必要。”

  3. “列表项可能由多个段落组成。随后的每一个 列表项中的段落必须缩进 4 个空格或 1 个空格 标签。”

  4. “如果你缩进后续段落的每一行,看起来会很好, 但在这里,Markdown 会让你变得懒惰。”

  5. “要将块引用放入列表项中,块引用的 > 分隔符需要缩进。”

  6. “要将代码块放入列表项中,需要将该代码块 缩进两次——8 个空格或两个制表符。”

这些规则指定列表项下的段落必须缩进 四个空格(大概是从左边距开始,而不是从开始处开始) 列表标记,但这没有说),以及列表项下的代码 必须缩进八个空格而不是通常的四个空格。他们还说 块引用必须缩进,但不缩进多少;然而, 给出的示例有四个空格缩进。虽然什么也没说 对于其他类型的块级内容,这当然是合理的 推断 所有 列表项下的 块元素,包括其他 列表,必须缩进四个空格。这一原则被称为 四空间规则

四空间规则是明确且有原则的,如果参考 执行 Markdown.pl 跟随它,它可能会 成为标准。然而, Markdown.pl 允许的段落和 子列表仅以两个空格缩进开头,至少在 外层。更糟糕的是,它的行为不一致:一个子列表 外层列表需要两个空格缩进,但它的子列表 子列表需要三个空格。那么,不同的情况也就不足为奇了 Markdown 的实现制定了非常不同的规则 确定列表项下的内容。 (Pandoc 和 python-Markdown, 例如,坚持格鲁伯的语法描述和四空格 规则、折扣、红毯、标记、PHP Markdown 等 已关注 Markdown.pl的行为更接近。)

不幸的是,考虑到实现之间的差异,有 无法给出保证不会的列表项的规格 破坏任何现有文档。然而,这里给出的规格应该 正确处理使用四空格规则或 越宽容 Markdown.pl 行为,只要它们被列出 以人类自然阅读的方式。

这里的策略是让列表标记的宽度和缩进 确定块落入列表所需的缩进 项,而不是具有固定且任意的数量。笔者可以 将列表项的主体视为一个缩进到 足够适合列表标记(以及列表上的任何缩进 标记)。 (惰性规则#5,然后允许连续行 如果需要,可以不缩进。)

我们声称,这条规则优于任何需要固定水平的规则 从页边距缩进。四空格规则很明确,但是 不自然的。这是相当不直观的

- foo

  bar

  - baz

应该被解析为两个列表,中间有一个段落,

<ul>
<li>foo</li>
</ul>
<p>bar</p>
<ul>
<li>baz</li>
</ul>

正如四空间规则所要求的,而不是单个列表,

<ul>
<li>
<p>foo</p>
<p>bar</p>
<ul>
<li>baz</li>
</ul>
</li>
</ul>

四个空间的选择是任意的。可以学习,但这是 不太可能被猜到,而且它经常让初学者绊倒。

采用两格规则会有帮助吗?问题是这样的 一条规则,以及允许最多三个缩进空间的规则 缩进 小于 初始列表标记,允许 要包含在列表项中的原始列表标记。例如, Markdown.pl 解析

   - one

  two

作为单个列表项, two 一个延续段落:

<ul>
<li>
<p>one</p>
<p>two</p>
</li>
</ul>

和类似地

>   - one
>
>  two

作为

<blockquote>
<ul>
<li>
<p>one</p>
<p>two</p>
</li>
</ul>
</blockquote>

这是极其不直观的。

我们可以不要求从边距固定缩进,而是要求 列表标记的固定缩进(例如,两个空格,甚至一个空格)( 本身可以缩进)。该提案将消除最后一个异常 讨论过。与上面提供的规范不同,它会计算以下内容 作为带有子段落的列表项,即使该段落 bar 没有缩进到第一段 foo:

 10. foo

   bar  

可以说这段文字读起来确实像一个列表项 bar 作为一个小段, 这可能有利于该提案。然而,该提案缩进 代码必须在列表标记后缩进六个空格。还有这个 会破坏很多现有的 Markdown,其模式如下:

1.  foo

        indented code

其中代码缩进八个空格。相比之下,上面的规范将 按预期解析此文本,因为测量了代码块的缩进 从一开始 foo

的列表项 需要特殊处理的一种情况是开始 带有缩进代码。在这种情况下需要多少缩进,因为 我们没有“第一段”来衡量?规则#2 简单地规定 在这种情况下,我们需要从列表标记处缩进一个空格 (然后是缩进代码的正常四个空格)。这将匹配 在列表标记加上其初始缩进的情况下的四空格规则 需要四个空格(常见情况),但在其他情况下会有所不同。

5.3 列表

列表 序列 是一个或多个的 列出 相同类型的 项目。清单项目 可以用任意数量的空行分隔。

两个列表项 属于同一类型 开头 列表标记 如果它们以相同类型的 。 两个列表标记是 相同类型,如果 (a) 它们是使用相同字符的项目符号列表标记 ( -, +, 或者 *) 或 (b) 它们是具有相同顺序的列表编号 分隔符(或者 . 或者 ))。

列表是一个 有序列表 如果其组成列表项开头为 有序列表标记 ,以及 项目符号列表 (如果其组成列表) 项目以 项目符号列表标记 开头。

编号 起始 的数量 有序列表 由列表数量决定 它的初始列表项。后续列表项的数量是 被忽视。

该列表是 松散的 如果列表中有任何组成部分,则 列表项由空行分隔,或者如果其任何组成部分 列表项直接包含两个带空行的块级元素 他们之间。否则,名单就很 紧张了 。 (HTML 输出的区别在于松散列表中的段落是 包裹在 <p> 标签,而紧凑列表中的段落则没有。)

更改项目符号或有序列表分隔符会启动一个新列表:

示例 301 尝试一下
- foo
- bar
+ baz
<ul>
<li>foo</li>
<li>bar</li>
</ul>
<ul>
<li>baz</li>
</ul>
示例302 尝试一下
1. foo
2. bar
3) baz
<ol>
<li>foo</li>
<li>bar</li>
</ol>
<ol start="3">
<li>baz</li>
</ol>

在 CommonMark 中,列表可以打断段落。那是, 不需要空行来将段落与后面的段落分开 列表:

示例303 尝试一下
Foo
- bar
- baz
<p>Foo</p>
<ul>
<li>bar</li>
<li>baz</li>
</ul>

Markdown.pl 不允许这样做,因为担心触发列表 通过硬包裹行中的数字:

The number of windows in my house is
14.  The number of doors is 6.

但奇怪的是, Markdown.pl 确实 允许块引用 打断一个段落,即使同样的考虑可能 申请。

在 CommonMark 中,我们确实允许列表打断段落,例如 有两个原因。首先,这对于人们来说是自然的且并不罕见 启动没有空行的列表:

I need to buy
- new shoes
- a coat
- a plane ticket

其次,我们被吸引

统一原则 : 如果一段文本有一定的 意思是,当放入一个 容器块(例如列表项或块引用)。

的规范 (事实上​​,列表项 块引用 预设 这个原则。)这个原则意味着如果

  * I need to buy
    - new shoes
    - a coat
    - a plane ticket

是一个列表项,其中包含一个段落,后跟一个嵌套子列表, 正如所有 Markdown 实现都同意的那样(尽管段落 可以在没有 <p> 标签,因为列表很“紧”), 然后

I need to buy
- new shoes
- a coat
- a plane ticket

其本身应该是一个段落,后面跟着一个嵌套子列表。

由于 Markdown 实践已成熟,允许列表 打断列表项内的段落, 原理 一致性 要求我们允许这个外部列表项为 出色地。 ( 重构文本 采用不同的方法,要求列表前有空行 甚至在其他列表项中。)

为了解决段落中不需要的列表的问题 硬包装数字,我们只允许以以下开头的列表 1 到 打断段落。因此,

实施例304 尝试一下
The number of windows in my house is
14.  The number of doors is 6.
<p>The number of windows in my house is
14.  The number of doors is 6.</p>

在类似的情况下,我们仍然可能会得到意想不到的结果

实施例305 尝试一下
The number of windows in my house is
1.  The number of doors is 6.
<p>The number of windows in my house is</p>
<ol>
<li>The number of doors is 6.</li>
</ol>

但这条规则应该可以防止大多数虚假列表捕获。

项目之间可以有任意数量的空行:

实施例306 尝试一下
- foo

- bar


- baz
<ul>
<li>
<p>foo</p>
</li>
<li>
<p>bar</p>
</li>
<li>
<p>baz</p>
</li>
</ul>
实施例307 尝试一下
- foo
  - bar
    - baz


      bim
<ul>
<li>foo
<ul>
<li>bar
<ul>
<li>
<p>baz</p>
<p>bim</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>

分隔相同类型的连续列表,或分隔 来自缩进代码块的列表,否则将被解析 作为最终列表项的子段落,您可以插入空白 HTML 评论:

实施例308 尝试一下
- foo
- bar

<!-- -->

- baz
- bim
<ul>
<li>foo</li>
<li>bar</li>
</ul>
<!-- -->
<ul>
<li>baz</li>
<li>bim</li>
</ul>
实施例309 尝试一下
-   foo

    notcode

-   foo

<!-- -->

    code
<ul>
<li>
<p>foo</p>
<p>notcode</p>
</li>
<li>
<p>foo</p>
</li>
</ul>
<!-- -->
<pre><code>code
</code></pre>

列表项不需要缩进到同一级别。下列 列表项将被视为同一列表级别的项目, 因为没有一个缩进足以属于前一个列表 物品:

示例 310 尝试一下
- a
 - b
  - c
   - d
  - e
 - f
- g
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
</ul>
示例 311 尝试一下
1. a

  2. b

   3. c
<ol>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
<li>
<p>c</p>
</li>
</ol>

但请注意,列表项前面的字符不得超过 三个空格的缩进。这里 - e 被视为段落延续 行,因为它缩进超过三个空格:

示例312 尝试一下
- a
 - b
  - c
   - d
    - e
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d
- e</li>
</ul>

而在这里, 3. c 被视为缩进代码块, 因为它缩进了四个空格并且前面有一个 空行。

示例313 尝试一下
1. a

  2. b

    3. c
<ol>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
</ol>
<pre><code>3. c
</code></pre>

这是一个松散列表,因为之间有一个空行 其中两个列表项:

示例314 尝试一下
- a
- b

- c
<ul>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
<li>
<p>c</p>
</li>
</ul>

这也是,第二项为空:

实施例315 尝试一下
* a
*

* c
<ul>
<li>
<p>a</p>
</li>
<li></li>
<li>
<p>c</p>
</li>
</ul>

这些是松散的列表,即使项目之间没有空行, 因为其中一项直接包含两个块级元素 它们之间有一个空行:

实施例316 尝试一下
- a
- b

  c
- d
<ul>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
<p>c</p>
</li>
<li>
<p>d</p>
</li>
</ul>
实施例317 尝试一下
- a
- b

  [ref]: /url
- d
<ul>
<li>
<p>a</p>
</li>
<li>
<p>b</p>
</li>
<li>
<p>d</p>
</li>
</ul>

这是一个很紧凑的列表,因为空行位于代码块中:

实施例318 尝试一下
- a
- ```
  b


  ```
- c
<ul>
<li>a</li>
<li>
<pre><code>b


</code></pre>
</li>
<li>c</li>
</ul>

这是一个很紧凑的列表,因为空行位于两个之间 子列表的段落。所以子列表是松散的 外部列表很紧:

实施例319 尝试一下
- a
  - b

    c
- d
<ul>
<li>a
<ul>
<li>
<p>b</p>
<p>c</p>
</li>
</ul>
</li>
<li>d</li>
</ul>

这是一个很紧凑的列表,因为空行位于 块引用:

示例 320 尝试一下
* a
  > b
  >
* c
<ul>
<li>a
<blockquote>
<p>b</p>
</blockquote>
</li>
<li>c</li>
</ul>

这个列表很紧,因为连续的块元素 不以空行分隔:

实施例321 尝试一下
- a
  > b
  ```
  c
  ```
- d
<ul>
<li>a
<blockquote>
<p>b</p>
</blockquote>
<pre><code>c
</code></pre>
</li>
<li>d</li>
</ul>

单段落列表很紧凑:

实施例322 尝试一下
- a
<ul>
<li>a</li>
</ul>
实施例323 尝试一下
- a
  - b
<ul>
<li>a
<ul>
<li>b</li>
</ul>
</li>
</ul>

这个列表很松散,因为之间有空行 列表项中的两个块元素:

实施例324 尝试一下
1. ```
   foo
   ```

   bar
<ol>
<li>
<pre><code>foo
</code></pre>
<p>bar</p>
</li>
</ol>

这里外部列表是松散的,内部列表是紧密的:

实施例325 尝试一下
* foo
  * bar

  baz
<ul>
<li>
<p>foo</p>
<ul>
<li>bar</li>
</ul>
<p>baz</p>
</li>
</ul>
实施例326 尝试一下
- a
  - b
  - c

- d
  - e
  - f
<ul>
<li>
<p>a</p>
<ul>
<li>b</li>
<li>c</li>
</ul>
</li>
<li>
<p>d</p>
<ul>
<li>e</li>
<li>f</li>
</ul>
</li>
</ul>

6 内联

内联从字符的开头按顺序解析 流到末尾(从左到右,在从左到右的语言中)。 因此,例如,在

实施例327 尝试一下
`hi`lo`
<p><code>hi</code>lo`</p>

hi 被解析为代码,将末尾的反引号保留为文字 反引号。

6.1 代码跨度

字符串 反引号 是一串由一个或多个反引号字符组成的字符串 ( `)这两者都不是 前面或后面都有反引号。

代码范围 反引号字符串开头并以 长度相等的反引号字符串。代码范围的内容是 这两个反引号字符串之间的字符,在 以下方式:

这是一个简单的代码范围:

实施例328 尝试一下
`foo`
<p><code>foo</code></p>

这里使用了两个反引号,因为代码中包含一个反引号。 此示例还说明了单个前导和的剥离 尾随空格:

实施例329 尝试一下
`` foo ` bar ``
<p><code>foo ` bar</code></p>

此示例显示了剥离前导和尾随的动机 空格:

实施例330 尝试一下
` `` `
<p><code>``</code></p>

请注意,仅 一个空格: 删除

实施例331 尝试一下
`  ``  `
<p><code> `` </code></p>

仅当两者上都有空格时才会发生剥离 字符串的两侧:

示例332 尝试一下
` a`
<p><code> a</code></p>

只有 空格 ,而不是 unicode 空白 一般的 以这种方式剥离:

示例333 尝试一下
` b `
<p><code> b </code></p>

如果代码范围仅包含空格,则不会发生剥离:

示例334 尝试一下
` `
`  `
<p><code> </code>
<code>  </code></p>

行结尾 被视为空格:

实施例335 尝试一下
``
foo
bar  
baz
``
<p><code>foo bar   baz</code></p>
实施例336 尝试一下
``
foo 
``
<p><code>foo </code></p>

内部空间未塌陷:

实施例337 尝试一下
`foo   bar 
baz`
<p><code>foo   bar  baz</code></p>

请注意,浏览器通常会折叠连续的空格 渲染时 <code> 元素,所以建议 使用以下 CSS:

code{white-space: pre-wrap;}

请注意,反斜杠转义在代码跨度中不起作用。所有反斜杠 按字面意思处理:

实施例338 尝试一下
`foo\`bar`
<p><code>foo\</code>bar`</p>

永远不需要反斜杠转义,因为人们总是可以选择一个 反引号字符作为分隔符的字符串 由n 个 ,其中代码的作用 反引号字符的字符串 不包含任何正好有n 个

实施例339 尝试一下
``foo`bar``
<p><code>foo`bar</code></p>
示例 340 尝试一下
` foo `` bar `
<p><code>foo `` bar</code></p>

代码跨度反引号的优先级高于任何其他内联 除 HTML 标签和自动链接之外的构造。因此,例如,这是 没有被解析为强调文本,因为第二个 * 是代码的一部分 跨度:

实施例341 尝试一下
*foo`*`
<p>*foo<code>*</code></p>

这不会被解析为链接:

实施例342 尝试一下
[not a `link](/foo`)
<p>[not a <code>link](/foo</code>)</p>

代码范围、HTML 标签和自动链接具有相同的优先级。 因此,这是代码:

示例343 尝试一下
`<a href="`">`
<p><code>&lt;a href=&quot;</code>&quot;&gt;`</p>

但这是一个 HTML 标签:

示例344 尝试一下
<a href="`">`
<p><a href="`">`</p>

这是代码:

实施例345 尝试一下
`<https://foo.bar.`baz>`
<p><code>&lt;https://foo.bar.</code>baz&gt;`</p>

但这是一个自动链接:

实施例346 尝试一下
<https://foo.bar.`baz>`
<p><a href="https://foo.bar.%60baz">https://foo.bar.`baz</a>`</p>

当反引号字符串没有被匹配的反引号字符串封闭时, 我们只有字面上的反引号:

示例347 尝试一下
```foo``
<p>```foo``</p>
实施例348 尝试一下
`foo
<p>`foo</p>

下面的案例也说明了开放和开放的必要性 关闭反引号字符串的长度相等:

实施例349 尝试一下
`foo``bar``
<p>`foo<code>bar</code></p>

6.2 强调和强烈强调

John Gruber 最初的 Markdown 语法 描述 说:

Markdown 处理星号( *) 和下划线 ( _)作为指标 强调。用 1 包裹的文本 * 或者 _ 将被 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**

许多实现也将字内强调限制为 这 * 形式,以避免不必要的强调包含 内部下划线。 (最好的做法是将这些放入代码中 跨度,但用户通常不这样做。)

internal emphasis: foo*bar*baz
no emphasis: foo_bar_baz

下面给出的规则捕获了所有这些模式,同时允许 用于不回溯的高效解析策略。

首先,一些定义。 运行 分隔符 是 一个或多个的序列 * 前面没有的字符或 后跟一个非反斜杠转义的 * 字符或序列 一个或多个的 _ 前面或后面没有的字符 非反斜杠转义 _ 特点。

左侧 分隔符运行 是 分隔符 运行 (1) 后面不跟 Unicode 空格的 , 并且 (2a) 后面不跟有 Unicode 标点符号 ,或者 (2b) 后跟 Unicode 标点符号 和 前面有 Unicode 空格 Unicode 标点符号 。 就本定义而言,开头和结尾 行计数为 Unicode 空白。

运行 右侧分隔符 是 的分隔符 运行 (1) 前面没有 Unicode 空格 , 并且 (2a) 前面没有 Unicode 标点符号 ,或者 (2b) 前面有一个 Unicode 标点符号 ,并且 后跟 Unicode 空格 Unicode 标点符号 。 就本定义而言,开头和结尾 行计数为 Unicode 空白。

以下是分隔符运行的一些示例。

(区分左翼和右翼的想法 分隔符根据前面的字符和后面的字符运行 之后来自 Roopesh Chander 的 vfmd 。 vfmd 使用术语“强调指示符字符串”而不是“分隔符” 跑动”以及区分左翼和右翼跑动的规则 比这里给出的要复杂一些。)

以下规则定义了强调和强烈强调:

  1. 单个 * 字符 可以打开强调 当且仅当(当且仅当)它是 左侧分隔符 run 的一部分。

  2. 单个 _ 角色 可以打开强调 iff 的一部分 它是左侧分隔符运行 并且 (a) 不是 右侧分隔符运行 的一部分 的一部分 或 (b)右侧分隔符运行 前面是 Unicode 标点符号

  3. 单个 * 字符 可以关闭强调 当且仅当它是 右侧分隔符运行 的一部分。

  4. 单个 _ 字符 可以关闭强调 iff 的一部分 它是右侧分隔符运行 并且 (a) 不是 左侧分隔符运行 的一部分 的一部分 或 (b)左侧分隔符运行 后跟一个 Unicode 标点符号

  5. 一个双人 ** 可以打开强强调 当且仅当它是 左侧分隔符运行 的一部分。

  6. 一个双人 __ 可以打开强强调 iff 的一部分 它是左侧分隔符运行 并且 (a) 不是 右侧分隔符运行 的一部分 的一部分 或 (b)右侧分隔符运行 前面是 Unicode 标点符号

  7. 一个双人 ** 可以关闭强强调 当且仅当它是 右侧分隔符运行 的一部分。

  8. 一个双人 __ 可以关闭强强调 iff 的一部分 它是右侧分隔符运行 并且 (a) 不是 左侧分隔符运行 的一部分 的一部分 或 (b)左侧分隔符运行 后跟一个 Unicode 标点符号

  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:

示例 350 尝试一下
*foo bar*
<p><em>foo bar</em></p>

这不是强调,因为开头 * 接下来是 空格,因此不是 左侧分隔符运行 的一部分:

示例 351 尝试一下
a * foo bar*
<p>a * foo bar*</p>

这不是强调,因为开头 * 位于之前 由字母数字组成,后跟标点符号,因此 的一部分 不是左侧分隔符运行

实施例352 尝试一下
a*"foo"*
<p>a*&quot;foo&quot;*</p>

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

示例353 尝试一下
* a *
<p>* a *</p>

Unicode 符号也算作标点符号:

示例354 尝试一下
*$*alpha.

*£*bravo.

*€*charlie.
<p>*$*alpha.</p>
<p>*£*bravo.</p>
<p>*€*charlie.</p>

词内强调 * 是允许的:

实施例355 尝试一下
foo*bar*
<p>foo<em>bar</em></p>
实施例356 尝试一下
5*6*78
<p>5<em>6</em>78</p>

规则 2:

示例357 尝试一下
_foo bar_
<p><em>foo bar</em></p>

这不是强调,因为开头 _ 接下来是 空白:

实施例358 尝试一下
_ foo bar_
<p>_ foo bar_</p>

这不是强调,因为开头 _ 位于之前 由字母数字和标点符号组成:

实施例359 尝试一下
a_"foo"_
<p>a_&quot;foo&quot;_</p>

强调与 _ 不允许在以下单词中使用:

示例 360 尝试一下
foo_bar_
<p>foo_bar_</p>
示例361 尝试一下
5_6_78
<p>5_6_78</p>
示例362 尝试一下
пристаням_стремятся_
<p>пристаням_стремятся_</p>

这里 _ 不会产生强调,因为第一个分隔符运行 是右翼,第二个是左翼:

示例363 尝试一下
aa_"bb"_cc
<p>aa_&quot;bb&quot;_cc</p>

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

示例364 尝试一下
foo-_(bar)_
<p>foo-<em>(bar)</em></p>

规则 3:

这不是强调,因为结束定界符 与开始分隔符不匹配:

示例365 尝试一下
_foo*
<p>_foo*</p>

这不是强调,因为结束语 * 前面是 空白:

示例366 尝试一下
*foo bar *
<p>*foo bar *</p>

行结尾也算作空格:

示例367 尝试一下
*foo bar
*
<p>*foo bar
*</p>

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

示例368 尝试一下
*(*foo)
<p>*(*foo)</p>

这种限制的意义更容易理解 以此为例:

示例369 尝试一下
*(*foo*)*
<p><em>(<em>foo</em>)</em></p>

词内强调 * 允许:

示例 370 尝试一下
*foo*bar
<p><em>foo</em>bar</p>

规则 4:

这不是强调,因为结束语 _ 前面是 空白:

示例 371 尝试一下
_foo bar _
<p>_foo bar _</p>

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

示例372 尝试一下
_(_foo)
<p>_(_foo)</p>

这是强调中的强调:

示例373 尝试一下
_(_foo_)_
<p><em>(<em>foo</em>)</em></p>

不允许使用词内强调 _:

示例374 尝试一下
_foo_bar
<p>_foo_bar</p>
示例375 尝试一下
_пристаням_стремятся
<p>_пристаням_стремятся</p>
示例376 尝试一下
_foo_bar_baz_
<p><em>foo_bar_baz</em></p>

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

示例377 尝试一下
_(bar)_.
<p><em>(bar)</em>.</p>

规则 5:

示例378 尝试一下
**foo bar**
<p><strong>foo bar</strong></p>

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

示例379 尝试一下
** foo bar**
<p>** foo bar**</p>

这不是重点强调,因为开头 ** 位于之前 由字母数字组成,后跟标点符号,因此 的一部分 不是左侧分隔符运行

示例 380 尝试一下
a**"foo"**
<p>a**&quot;foo&quot;**</p>

词内强调 ** 是允许的:

示例381 尝试一下
foo**bar**
<p>foo<strong>bar</strong></p>

规则 6:

示例382 尝试一下
__foo bar__
<p><strong>foo bar</strong></p>

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

示例383 尝试一下
__ foo bar__
<p>__ foo bar__</p>

行结尾算作空格:

示例384 尝试一下
__
foo bar__
<p>__
foo bar__</p>

这不是重点强调,因为开头 __ 位于之前 由字母数字和标点符号组成:

示例385 尝试一下
a__"foo"__
<p>a__&quot;foo&quot;__</p>

禁止词内强调 __:

示例386 尝试一下
foo__bar__
<p>foo__bar__</p>
示例387 尝试一下
5__6__78
<p>5__6__78</p>
示例388 尝试一下
пристаням__стремятся__
<p>пристаням__стремятся__</p>
示例389 尝试一下
__foo, __bar__, baz__
<p><strong>foo, <strong>bar</strong>, baz</strong></p>

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

示例390 尝试一下
foo-__(bar)__
<p>foo-<strong>(bar)</strong></p>

规则 7:

这不是重点强调,因为结束分隔符位于前面 通过空格:

实施例391 尝试一下
**foo bar **
<p>**foo bar **</p>

(也不能理解为强调 *foo bar *,因为 规则 11。)

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

实施例392 尝试一下
**(**foo)
<p>**(**foo)</p>

这种限制的意义更容易理解 通过这些例子:

示例393 尝试一下
*(**foo**)*
<p><em>(<strong>foo</strong>)</em></p>
实施例394 尝试一下
**Gomphocarpus (*Gomphocarpus physocarpus*, syn.
*Asclepias physocarpa*)**
<p><strong>Gomphocarpus (<em>Gomphocarpus physocarpus</em>, syn.
<em>Asclepias physocarpa</em>)</strong></p>
实施例395 尝试一下
**foo "*bar*" foo**
<p><strong>foo &quot;<em>bar</em>&quot; foo</strong></p>

词内强调:

示例396 尝试一下
**foo**bar
<p><strong>foo</strong>bar</p>

规则 8:

这不是重点强调,因为结束分隔符是 前面有空格:

示例397 尝试一下
__foo bar __
<p>__foo bar __</p>

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

示例398 尝试一下
__(__foo)
<p>__(__foo)</p>

这种限制的意义更容易理解 以此为例:

示例399 尝试一下
_(__foo__)_
<p><em>(<strong>foo</strong>)</em></p>

禁止词内强调 __:

示例 400 尝试一下
__foo__bar
<p>__foo__bar</p>
示例 401 尝试一下
__пристаням__стремятся
<p>__пристаням__стремятся</p>
示例 402 尝试一下
__foo__bar__baz__
<p><strong>foo__bar__baz</strong></p>

这是强烈强调,即使结束分隔符是 左侧和右侧,因为它后面是 标点:

示例 403 尝试一下
__(bar)__.
<p><strong>(bar)</strong>.</p>

规则 9:

任何非空的内联元素序列都可以是 强调跨度。

示例 404 尝试一下
*foo [bar](/url)*
<p><em>foo <a href="/url">bar</a></em></p>
示例 405 尝试一下
*foo
bar*
<p><em>foo
bar</em></p>

特别是,强调和强调可以嵌套 里面强调:

示例 406 尝试一下
_foo __bar__ baz_
<p><em>foo <strong>bar</strong> baz</em></p>
示例 407 尝试一下
_foo _bar_ baz_
<p><em>foo <em>bar</em> baz</em></p>
示例 408 尝试一下
__foo_ bar_
<p><em><em>foo</em> bar</em></p>
实施例409 尝试一下
*foo *bar**
<p><em>foo <em>bar</em></em></p>
示例 410 尝试一下
*foo **bar** baz*
<p><em>foo <strong>bar</strong> baz</em></p>
示例 411 尝试一下
*foo**bar**baz*
<p><em>foo<strong>bar</strong>baz</em></p>

请注意,在前面的情况下,解释

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

被排除的条件是分隔符 可以打开和关闭(就像 *foo) 如果长度之和不能形成强调 分隔符包含开头和 结束分隔符是 3 的倍数,除非 两个长度都是 3 的倍数。

出于同样的原因,我们不会连续获得两个 本例中的重点部分:

示例 412 尝试一下
*foo**bar*
<p><em>foo**bar</em></p>

相同的条件确保以下 案例都强调嵌套在里面 强调,即使内部空白是 省略:

示例 413 尝试一下
***foo** bar*
<p><em><strong>foo</strong> bar</em></p>
示例 414 尝试一下
*foo **bar***
<p><em>foo <strong>bar</strong></em></p>
实施例415 尝试一下
*foo**bar***
<p><em>foo<strong>bar</strong></em></p>

当内部关闭和打开的长度 不过,分隔符都是 3 的倍数, 它们可以匹配以强调:

示例 416 尝试一下
foo***bar***baz
<p>foo<em><strong>bar</strong></em>baz</p>
示例 417 尝试一下
foo******bar*********baz
<p>foo<strong><strong><strong>bar</strong></strong></strong>***baz</p>

无限级嵌套是可能的:

实施例418 尝试一下
*foo **bar *baz* bim** bop*
<p><em>foo <strong>bar <em>baz</em> bim</strong> bop</em></p>
实施例419 尝试一下
*foo [*bar*](/url)*
<p><em>foo <a href="/url"><em>bar</em></a></em></p>

不能有空强调或强强调:

示例 420 尝试一下
** is not an empty emphasis
<p>** is not an empty emphasis</p>
示例 421 尝试一下
**** is not an empty strong emphasis
<p>**** is not an empty strong emphasis</p>

规则 10:

任何非空的内联元素序列都可以是 强烈强调跨度。

示例 422 尝试一下
**foo [bar](/url)**
<p><strong>foo <a href="/url">bar</a></strong></p>
示例 423 尝试一下
**foo
bar**
<p><strong>foo
bar</strong></p>

特别是,强调和强调可以嵌套 里面强调:

示例 424 尝试一下
__foo _bar_ baz__
<p><strong>foo <em>bar</em> baz</strong></p>
示例 425 尝试一下
__foo __bar__ baz__
<p><strong>foo <strong>bar</strong> baz</strong></p>
示例 426 尝试一下
____foo__ bar__
<p><strong><strong>foo</strong> bar</strong></p>
示例 427 尝试一下
**foo **bar****
<p><strong>foo <strong>bar</strong></strong></p>
示例 428 尝试一下
**foo *bar* baz**
<p><strong>foo <em>bar</em> baz</strong></p>
实施例429 尝试一下
**foo*bar*baz**
<p><strong>foo<em>bar</em>baz</strong></p>
示例 430 尝试一下
***foo* bar**
<p><strong><em>foo</em> bar</strong></p>
示例 431 尝试一下
**foo *bar***
<p><strong>foo <em>bar</em></strong></p>

无限级嵌套是可能的:

例 432 试试
**foo *bar **baz**
bim* bop**
<p><strong>foo <em>bar <strong>baz</strong>
bim</em> bop</strong></p>
示例 433 尝试一下
**foo [*bar*](/url)**
<p><strong>foo <a href="/url"><em>bar</em></a></strong></p>

不能有空强调或强强调:

例 434 尝试一下
__ is not an empty emphasis
<p>__ is not an empty emphasis</p>
示例 435 尝试一下
____ is not an empty strong emphasis
<p>____ is not an empty strong emphasis</p>

规则 11:

示例 436 尝试一下
foo ***
<p>foo ***</p>
例 437 尝试一下
foo *\**
<p>foo <em>*</em></p>
例 438 试试
foo *_*
<p>foo <em>_</em></p>
例 439 试试
foo *****
<p>foo *****</p>
示例 440 尝试一下
foo **\***
<p>foo <strong>*</strong></p>
示例 441 尝试一下
foo **_**
<p>foo <strong>_</strong></p>

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

示例 442 尝试一下
**foo*
<p>*<em>foo</em></p>
示例 443 尝试一下
*foo**
<p><em>foo</em>*</p>
示例 444 尝试一下
***foo**
<p>*<strong>foo</strong></p>
示例 445 尝试一下
****foo*
<p>***<em>foo</em></p>
示例 446 尝试一下
**foo***
<p><strong>foo</strong>*</p>
示例 447 尝试一下
*foo****
<p><em>foo</em>***</p>

规则 12:

例 448 试试
foo ___
<p>foo ___</p>
例 449 试试
foo _\__
<p>foo <em>_</em></p>
示例 450 尝试一下
foo _*_
<p>foo <em>*</em></p>
示例 451 尝试一下
foo _____
<p>foo _____</p>
示例 452 尝试一下
foo __\___
<p>foo <strong>_</strong></p>
示例 453 尝试一下
foo __*__
<p>foo <strong>*</strong></p>
示例 454 尝试一下
__foo_
<p>_<em>foo</em></p>

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

示例 455 尝试一下
_foo__
<p><em>foo</em>_</p>
实施例456 尝试一下
___foo__
<p>_<strong>foo</strong></p>
示例 457 尝试一下
____foo_
<p>___<em>foo</em></p>
例 458 试试
__foo___
<p><strong>foo</strong>_</p>
例 459 试试
_foo____
<p><em>foo</em>___</p>

规则 13 意味着如果你想强调直接嵌套在 强调,您必须使用不同的分隔符:

示例 460 尝试一下
**foo**
<p><strong>foo</strong></p>
示例 461 尝试一下
*_foo_*
<p><em><em>foo</em></em></p>
示例 462 尝试一下
__foo__
<p><strong>foo</strong></p>
示例 463 尝试一下
_*foo*_
<p><em><em>foo</em></em></p>

然而,在不强调的情况下,强调中的强调也是可能的。 切换分隔符:

示例 464 尝试一下
****foo****
<p><strong><strong>foo</strong></strong></p>
示例 465 尝试一下
____foo____
<p><strong><strong>foo</strong></strong></p>

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

示例 466 尝试一下
******foo******
<p><strong><strong><strong>foo</strong></strong></strong></p>

规则 14:

示例 467 尝试一下
***foo***
<p><em><strong>foo</strong></em></p>
示例 468 尝试一下
_____foo_____
<p><em><strong><strong>foo</strong></strong></em></p>

规则 15:

例 469 试试
*foo _bar* baz_
<p><em>foo _bar</em> baz_</p>
示例 470 尝试一下
*foo __bar *baz bim__ bam*
<p><em>foo <strong>bar *baz bim</strong> bam</em></p>

规则 16:

示例 471 尝试一下
**foo **bar baz**
<p>**foo <strong>bar baz</strong></p>
示例 472 尝试一下
*foo *bar baz*
<p>*foo <em>bar baz</em></p>

规则 17:

示例 473 尝试一下
*[bar*](/url)
<p>*<a href="/url">bar*</a></p>
示例 474 尝试一下
_foo [bar_](/url)
<p>_foo <a href="/url">bar_</a></p>
示例 475 尝试一下
*<img src="foo" title="*"/>
<p>*<img src="foo" title="*"/></p>
示例 476 尝试一下
**<a href="**">
<p>**<a href="**"></p>
示例 477 尝试一下
__<a href="__">
<p>__<a href="__"></p>
示例 478 尝试一下
*a `*`*
<p><em>a <code>*</code></em></p>
例 479 试试
_a `_`_
<p><em>a <code>_</code></em></p>
示例 480 尝试一下
**a<https://foo.bar/?q=**>
<p>**a<a href="https://foo.bar/?q=**">https://foo.bar/?q=**</a></p>
示例 481 尝试一下
__a<https://foo.bar/?q=__>
<p>__a<a href="https://foo.bar/?q=__">https://foo.bar/?q=__</a></p>

链接包含 链接文本 (可见文本)、 链接目标 (作为链接目标的 URI),以及可选的 链接标题 。 Markdown 中有两种基本类型的链接。 中 在内联 链接 链接文本后立即给出目的地和标题。在 参考链接的 目的地和标题在其他地方定义 该文件。

链接文本 零个或多个序列组成 用方括号括起来的内联元素 ( [])。这 适用以下规则:

链接目标 以下任一组成:

链接标题 以下任一组成

尽管 链接标题 可能跨越多行,但它们可能不包含 一个 空行

内联链接 组成 链接文本 紧随其后的 通过左括号 (,一个可选的 链接目标 ,一个可选的 链接标题 和右括号 )。 这四个部分可以用空格、制表符和最多一行分隔 结束。 如果 链接目标 链接标题 都存在,则它们 必须 是 以空格、制表符和最多一行结尾分隔。

链接的文本由包含的内联内容组成 在 链接文本 中(不包括方括号)。 链接的 URI 由链接目标组成,不包括封闭的 <...> 如果存在,则反斜杠转义有效,如所述 多于。链接的标题由链接标题组成,不包括其内容 封闭分隔符,反斜杠转义有效,如所述 多于。

这是一个简单的内联链接:

例 482 试试
[link](/uri "title")
<p><a href="/uri" title="title">link</a></p>

标题、链接文本甚至 目的地可以省略:

示例 483 尝试一下
[link](/uri)
<p><a href="/uri">link</a></p>
例 484 试试
[](./target.md)
<p><a href="./target.md"></a></p>
示例 485 尝试一下
[link]()
<p><a href="">link</a></p>
例 486 试试
[link](<>)
<p><a href="">link</a></p>
示例 487 尝试一下
[]()
<p><a href=""></a></p>

目的地只能包含空格 用尖括号括起来:

例 488 试试
[link](/my uri)
<p>[link](/my uri)</p>
例 489 试试
[link](</my uri>)
<p><a href="/my%20uri">link</a></p>

目标不能包含行结尾, 即使用尖括号括起来:

示例 490 尝试一下
[link](foo
bar)
<p>[link](foo
bar)</p>
示例 491 尝试一下
[link](<foo
bar>)
<p>[link](<foo
bar>)</p>

目的地可以包含 ) 如果是封闭的 在尖括号中:

示例 492 尝试一下
[a](<b)c>)
<p><a href="b)c">a</a></p>

包含链接的尖括号必须不转义:

示例 493 尝试一下
[link](<foo\>)
<p>[link](&lt;foo&gt;)</p>

这些不是链接,因为左尖括号 没有正确匹配:

示例 494 尝试一下
[a](<b)c
[a](<b)c>
[a](<b>c)
<p>[a](&lt;b)c
[a](&lt;b)c&gt;
[a](<b>c)</p>

链接目标内的括号可能会被转义:

示例 495 尝试一下
[link](\(foo\))
<p><a href="(foo)">link</a></p>

允许使用任意数量的括号而不转义,只要它们是 均衡:

示例 496 尝试一下
[link](foo(and(bar)))
<p><a href="foo(and(bar))">link</a></p>

但是,如果括号不平衡,则需要转义或使用 <...> 形式:

示例 497 尝试一下
[link](foo(and(bar))
<p>[link](foo(and(bar))</p>
示例 498 尝试一下
[link](foo\(and\(bar\))
<p><a href="foo(and(bar)">link</a></p>
示例 499 尝试一下
[link](<foo(and(bar)>)
<p><a href="foo(and(bar)">link</a></p>

像往常一样,括号和其他符号也可以转义 在降价中:

示例 500 尝试一下
[link](foo\)\:)
<p><a href="foo):">link</a></p>

链接可以包含片段标识符和查询:

示例 501 尝试一下
[link](#fragment)

[link](https://example.com#fragment)

[link](https://example.com?foo=3#frag)
<p><a href="#fragment">link</a></p>
<p><a href="https://example.com#fragment">link</a></p>
<p><a href="https://example.com?foo=3#frag">link</a></p>

请注意,不可转义字符之前的反斜杠是 只是一个反斜杠:

实施例502 尝试一下
[link](foo\bar)
<p><a href="foo%5Cbar">link</a></p>

URL 转义应该单独留在目标中,因为所有 URL 转义字符也是有效的 URL 字符。实体和 将解析目标中的数字字符引用 像往常一样转换成相应的 Unicode 代码点。这些可能 当以 HTML 形式编写时,可以选择进行 URL 转义,但是此规范 不强制执行任何特定的 URL 渲染策略 HTML 或其他格式。渲染器可能会做出不同的决定 关于如何转义或标准化输出中的 URL。

实施例503 尝试一下
[link](foo%20b&auml;)
<p><a href="foo%20b%C3%A4">link</a></p>

请注意,因为标题通常可以被解析为目的地, 如果您尝试省略目的地并保留标题,您将 得到意想不到的结果:

实施例504 尝试一下
[link]("title")
<p><a href="%22title%22">link</a></p>

标题可以用单引号、双引号或括号括起来:

实施例505 尝试一下
[link](/url "title")
[link](/url 'title')
[link](/url (title))
<p><a href="/url" title="title">link</a>
<a href="/url" title="title">link</a>
<a href="/url" title="title">link</a></p>

反斜杠转义以及实体和数字字符引用 可用于标题:

实施例506 尝试一下
[link](/url "title \"&quot;")
<p><a href="/url" title="title &quot;&quot;">link</a></p>

标题与链接之间必须使用空格、制表符和最多一行分隔开 结束。 其他 Unicode 空白 (例如不间断空格)不起作用。

实施例507 尝试一下
[link](/url "title")
<p><a href="/url%C2%A0%22title%22">link</a></p>

不允许嵌套平衡引号而不转义:

实施例508 尝试一下
[link](/url "title "and" title")
<p>[link](/url &quot;title &quot;and&quot; title&quot;)</p>

但通过使用不同的引用类型很容易解决这个问题:

实施例509 尝试一下
[link](/url 'title "and" title')
<p><a href="/url" title="title &quot;and&quot; title">link</a></p>

(笔记: Markdown.pl 确实允许在双引号内使用双引号 标题,其测试套件包括一个证明这一点的测试。 但很难找到一个合理的理由来解释这种额外的复杂性。 带来,因为已经有很多方法——反斜杠转义, 实体和数字字符引用,或使用不同的 封闭标题的引用类型——编写包含以下内容的标题 双引号。 Markdown.pl对标题的处理有很多 其他奇怪的功能。例如,它允许单引号 内联链接中的标题,但参考链接中不包括。并且,在 参考链接但不是内联链接,它允许标题开始 和 " 并结束于 )Markdown.pl 1.0.1甚至允许 标题没有右引号,但 1.0.2b8 没有。 似乎最好采用一种简单、合理且行之有效的规则 在内联链接和链接引用定义中也是如此。)

目标周围允许有空格、制表符和最多一行结尾 标题:

示例 510 尝试一下
[link](   /uri
  "title"  )
<p><a href="/uri" title="title">link</a></p>

但链接文本和链接文本之间不允许存在 下面的括号:

示例511 尝试一下
[link] (/uri)
<p>[link] (/uri)</p>

链接文本可以包含平衡括号,但不能包含不平衡括号, 除非他们逃脱了:

实施例512 尝试一下
[link [foo [bar]]](/uri)
<p><a href="/uri">link [foo [bar]]</a></p>
示例513 尝试一下
[link] bar](/uri)
<p>[link] bar](/uri)</p>
实施例514 尝试一下
[link [bar](/uri)
<p>[link <a href="/uri">bar</a></p>
实施例515 尝试一下
[link \[bar](/uri)
<p><a href="/uri">link [bar</a></p>

链接文本可能包含内联内容:

实施例516 尝试一下
[link *foo **bar** `#`*](/uri)
<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>
实施例517 尝试一下
[![moon](moon.jpg)](/uri)
<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>

但是,链接在任何嵌套级别都不得包含其他链接。

实施例518 尝试一下
[foo [bar](/uri)](/uri)
<p>[foo <a href="/uri">bar</a>](/uri)</p>
实施例519 尝试一下
[foo *[bar [baz](/uri)](/uri)*](/uri)
<p>[foo <em>[bar <a href="/uri">baz</a>](/uri)</em>](/uri)</p>
示例 520 尝试一下
![[[foo](uri1)](uri2)](uri3)
<p><img src="uri3" alt="[foo](uri2)" /></p>

这些案例说明了链接文本分组的优先级 重点分组:

实施例521 尝试一下
*[foo*](/uri)
<p>*<a href="/uri">foo*</a></p>
实施例522 尝试一下
[foo *bar](baz*)
<p><a href="baz*">foo *bar</a></p>

属于链接一部分的括号 请注意,不 不会占用 优先级:

实施例523 尝试一下
*foo [bar* baz]
<p><em>foo [bar</em> baz]</p>

这些案例说明了 HTML 标签、代码跨度的优先级, 以及通过链接分组自动链接:

实施例524 尝试一下
[foo <bar attr="](baz)">
<p>[foo <bar attr="](baz)"></p>
实施例525 尝试一下
[foo`](/uri)`
<p>[foo<code>](/uri)</code></p>
实施例526 尝试一下
[foo<https://example.com/?search=](uri)>
<p>[foo<a href="https://example.com/?search=%5D(uri)">https://example.com/?search=](uri)</a></p>

分为三种 参考链接 饱满 塌陷 、 和 快捷方式

链接 完整的参考 组成 的链接文本 由紧跟 链接标签 相匹配。 链接 引用定义 文档中其他地方的

链接标签 左括号 ( [) 并结束 与第一个右括号 ( ]) 不是反斜杠转义的。 这些括号之间必须至少有一个不是空格的字符, 制表符或行结尾。 内部不允许使用未转义的方括号字符 的左方括号和右方括号 链接标签 。一个链接 标签在方块内最多可以有 999 个字符 括号。

一个标签 匹配 另一个以防万一它们的标准化形式相等。标准化一个 标签,剥去左括号和右括号, 执行 Unicode 大小写折叠 、剥离前导和尾随 空格、制表符和行结尾,以及折叠连续的内部 将空格、制表符和行结尾合并为一个空格。如果有多个 匹配参考链接定义,即第一个链接定义 使用文档。 (在这种情况下最好发出警告。)

链接的 URI 和标题由匹配的 链接 提供 参考定义

这是一个简单的例子:

实施例527 尝试一下
[foo][bar]

[bar]: /url "title"
<p><a href="/url" title="title">foo</a></p>

的规则 链接文本 内联链接 。因此:

链接文本可以包含平衡括号,但不能包含不平衡括号, 除非他们逃脱了:

实施例528 尝试一下
[link [foo [bar]]][ref]

[ref]: /uri
<p><a href="/uri">link [foo [bar]]</a></p>
实施例529 尝试一下
[link \[bar][ref]

[ref]: /uri
<p><a href="/uri">link [bar</a></p>

链接文本可能包含内联内容:

实施例530 尝试一下
[link *foo **bar** `#`*][ref]

[ref]: /uri
<p><a href="/uri">link <em>foo <strong>bar</strong> <code>#</code></em></a></p>
实施例531 尝试一下
[![moon](moon.jpg)][ref]

[ref]: /uri
<p><a href="/uri"><img src="moon.jpg" alt="moon" /></a></p>

但是,链接在任何嵌套级别都不得包含其他链接。

示例532 尝试一下
[foo [bar](/uri)][ref]

[ref]: /uri
<p>[foo <a href="/uri">bar</a>]<a href="/uri">ref</a></p>
实施例533 尝试一下
[foo *bar [baz][ref]*][ref]

[ref]: /uri
<p>[foo <em>bar <a href="/uri">baz</a></em>]<a href="/uri">ref</a></p>

(在上面的示例中,我们有两个 快捷参考链接 而不是一个 完整的参考链接 。)

以下情况说明了链接文本分组的优先级 重点分组:

示例534 尝试一下
*[foo*][ref]

[ref]: /uri
<p>*<a href="/uri">foo*</a></p>
实施例535 尝试一下
[foo *bar][ref]*

[ref]: /uri
<p><a href="/uri">foo *bar</a>*</p>

这些案例说明了 HTML 标签、代码跨度的优先级, 以及通过链接分组自动链接:

实施例536 尝试一下
[foo <bar attr="][ref]">

[ref]: /uri
<p>[foo <bar attr="][ref]"></p>
示例537 尝试一下
[foo`][ref]`

[ref]: /uri
<p>[foo<code>][ref]</code></p>
实施例538 尝试一下
[foo<https://example.com/?search=][ref]>

[ref]: /uri
<p>[foo<a href="https://example.com/?search=%5D%5Bref%5D">https://example.com/?search=][ref]</a></p>

匹配不区分大小写:

例539 试试
[foo][BaR]

[bar]: /url "title"
<p><a href="/url" title="title">foo</a></p>

使用 Unicode 大小写折叠:

实施例540 尝试一下
[ẞ]

[SS]: /url
<p><a href="/url">ẞ</a></p>

连续的内部空格、制表符和行结尾被视为一个空格 确定匹配的目的:

实施例541 尝试一下
[Foo
  bar]: /url

[Baz][Foo bar]
<p><a href="/url">Baz</a></p>

之间不允许有空格、制表符或行结尾 链接文本 和链接文本 链接标签

例542 试试
[foo] [bar]

[bar]: /url "title"
<p>[foo] <a href="/url" title="title">bar</a></p>
实施例543 尝试一下
[foo]
[bar]

[bar]: /url "title"
<p>[foo]
<a href="/url" title="title">bar</a></p>

这与 John Gruber 最初的 Markdown 语法不同 描述,明确允许链接之间有空格 文本和链接标签。它带来的参考链接符合 内联链接 ,(根据原始 Markdown 和 本规范)链接文本后不能有空格。更多的 重要的是,它可以防止无意中捕获连续的 快捷参考链接 。如果之间允许有空格 链接文本和链接标签,那么在下面我们将有 单个参考链接,而不是两个快捷参考链接,如 故意的:

[foo]
[bar]

[foo]: /url1
[bar]: /url2

(请注意, 快捷方式参考链接 是由 Gruber 引入的 他自己在测试版中 Markdown.pl,但从未包括在内 在官方语法描述中。无快捷方式参考 链接,在链接文本和链接文本之间留有空格是无害的 链接标签;但是一旦引入了快捷方式引用, 允许这样做太危险了,因为它经常导致 意想不到的结果。)

当存在多个匹配的 链接引用定义 时, 第一个使用:

例544 试试
[foo]: /url1

[foo]: /url2

[bar][foo]
<p><a href="/url1">bar</a></p>

请注意,匹配是在规范化字符串上执行的,而不是解析的 内联内容。因此以下内容不匹配,即使 标签定义等效的内联内容:

实施例545 尝试一下
[bar][foo\!]

[foo!]: /url
<p>[bar][foo!]</p>

链接标签 不能包含括号,除非它们是 反斜杠转义:

实施例546 尝试一下
[foo][ref[]

[ref[]: /uri
<p>[foo][ref[]</p>
<p>[ref[]: /uri</p>
例547 试试
[foo][ref[bar]]

[ref[bar]]: /uri
<p>[foo][ref[bar]]</p>
<p>[ref[bar]]: /uri</p>
实施例548 尝试一下
[[[foo]]]

[[[foo]]]: /url
<p>[[[foo]]]</p>
<p>[[[foo]]]: /url</p>
例549 试试
[foo][ref\[]

[ref\[]: /uri
<p><a href="/uri">foo</a></p>

请注意,在此示例中 ] 不是反斜杠转义的:

示例 550 尝试一下
[bar\\]: /uri

[bar\\]
<p><a href="/uri">bar\</a></p>

必须 链接标签 至少包含一个不是空格、制表符或制表符的字符 行尾:

示例551 尝试一下
[]

[]: /uri
<p>[]</p>
<p>[]: /uri</p>
实施例552 尝试一下
[
 ]

[
 ]: /uri
<p>[
]</p>
<p>[
]: /uri</p>

链接 折叠的参考 组成 链接 由匹配 标签 链接参考定义 在其他地方 文档,后跟字符串 []。 链接标签的内容被解析为内联, 用作链接的文本。链接的 URI 和标题是 由匹配的参考链接定义提供。因此, [foo][] 相当于 [foo][foo]

示例553 尝试一下
[foo][]

[foo]: /url "title"
<p><a href="/url" title="title">foo</a></p>
实施例554 尝试一下
[*foo* bar][]

[*foo* bar]: /url "title"
<p><a href="/url" title="title"><em>foo</em> bar</a></p>

链接标签不区分大小写:

实施例555 尝试一下
[Foo][]

[foo]: /url "title"
<p><a href="/url" title="title">Foo</a></p>

与完整的参考链接一样,空格、制表符或行结尾不是 两组括号之间允许:

实施例556 尝试一下
[foo] 
[]

[foo]: /url "title"
<p><a href="/url" title="title">foo</a>
[]</p>

链接 快捷参考 组成 链接 由匹配 标签 链接参考定义 在其他地方 文件并且后面没有 [] 或链接标签。 链接标签的内容被解析为内联, 用作链接的文本。链接的 URI 和标题 由匹配的链接参考定义提供。 因此, [foo] 相当于 [foo][]

例 557 试试
[foo]

[foo]: /url "title"
<p><a href="/url" title="title">foo</a></p>
例558 试试
[*foo* bar]

[*foo* bar]: /url "title"
<p><a href="/url" title="title"><em>foo</em> bar</a></p>
例559 试试
[[*foo* bar]]

[*foo* bar]: /url "title"
<p>[<a href="/url" title="title"><em>foo</em> bar</a>]</p>
实施例560 尝试一下
[[bar [foo]

[foo]: /url
<p>[[bar <a href="/url">foo</a></p>

链接标签不区分大小写:

实施例561 尝试一下
[Foo]

[foo]: /url "title"
<p><a href="/url" title="title">Foo</a></p>

应保留链接文本后的空格:

实施例562 尝试一下
[foo] bar

[foo]: /url
<p><a href="/url">foo</a> bar</p>

如果您只想要括号内的文本,则可以反斜杠转义 打开括号以避免链接:

实施例563 尝试一下
\[foo]

[foo]: /url "title"
<p>[foo]</p>

请注意,这是一个链接,因为链接标签以第一个结尾 以下右括号:

实施例564 尝试一下
[foo*]: /url

*[foo*]
<p>*<a href="/url">foo*</a></p>

完整和折叠引用优先于快捷方式 参考:

实施例565 尝试一下
[foo][bar]

[foo]: /url1
[bar]: /url2
<p><a href="/url2">foo</a></p>
实施例566 尝试一下
[foo][]

[foo]: /url1
<p><a href="/url1">foo</a></p>

内联链接也优先:

实施例567 尝试一下
[foo]()

[foo]: /url1
<p><a href="">foo</a></p>
实施例568 尝试一下
[foo](not a link)

[foo]: /url1
<p><a href="/url1">foo</a>(not a link)</p>

在以下情况下 [bar][baz] 被解析为参考, [foo] 作为普通文本:

例569 试试
[foo][bar][baz]

[baz]: /url
<p>[foo]<a href="/url">bar</a></p>

不过在这里, [foo][bar] 被解析为参考,因为 [bar] 定义为:

实施例570 尝试一下
[foo][bar][baz]

[baz]: /url1
[bar]: /url2
<p><a href="/url2">foo</a><a href="/url1">baz</a></p>

这里 [foo] 不会被解析为快捷方式引用,因为它 后面跟着一个链接标签(尽管 [bar] 未定义):

例 571 试试
[foo][bar][baz]

[baz]: /url1
[foo]: /url2
<p>[foo]<a href="/url1">bar</a></p>

6.4 图像

图像的语法类似于链接的语法,其中一个 不同之处。 而是 我们没有链接文本 图像描述 。这样做的规则是 相同 与链接文本 ,除了 (a) 图像描述开头为 ![ 而不是 [, 和 (b) 图像描述可以包含链接。 图像描述具有内联元素 作为其内容。当图像呈现为 HTML 时, 这通常用作图像的 alt 属性。

例 572 试试
![foo](/url "title")
<p><img src="/url" alt="foo" title="title" /></p>
示例573 尝试一下
![foo *bar*]

[foo *bar*]: train.jpg "train & tracks"
<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p>
例 574 试试
![foo ![bar](/url)](/url2)
<p><img src="/url2" alt="foo bar" /></p>
实施例575 尝试一下
![foo [bar](/url)](/url2)
<p><img src="/url2" alt="foo bar" /></p>

尽管此规范涉及解析,而不是渲染,但它是 建议在渲染为 HTML 时,仅使用纯字符串内容 的一部分 图像描述 使用 。请注意,在 上面的例子中,alt属性的值为 foo bar, 不是 foo [bar](/url) 或者 foo <a href="/url">bar</a>。仅纯字符串 内容被渲染,没有格式化。

例 576 试试
![foo *bar*][]

[foo *bar*]: train.jpg "train & tracks"
<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p>
例 577 试试
![foo *bar*][foobar]

[FOOBAR]: train.jpg "train & tracks"
<p><img src="train.jpg" alt="foo bar" title="train &amp; tracks" /></p>
例 578 试试
![foo](train.jpg)
<p><img src="train.jpg" alt="foo" /></p>
例 579 试试
My ![foo bar](/path/to/train.jpg  "title"   )
<p>My <img src="/path/to/train.jpg" alt="foo bar" title="title" /></p>
实施例580 尝试一下
![foo](<url>)
<p><img src="url" alt="foo" /></p>
实施例581 尝试一下
![](/url)
<p><img src="/url" alt="" /></p>

参考风格:

例582 试试
![foo][bar]

[bar]: /url
<p><img src="/url" alt="foo" /></p>
示例583 尝试一下
![foo][bar]

[BAR]: /url
<p><img src="/url" alt="foo" /></p>

折叠:

例584 试试
![foo][]

[foo]: /url "title"
<p><img src="/url" alt="foo" title="title" /></p>
例585 试试
![*foo* bar][]

[*foo* bar]: /url "title"
<p><img src="/url" alt="foo bar" title="title" /></p>

标签不区分大小写:

例586 试试
![Foo][]

[foo]: /url "title"
<p><img src="/url" alt="Foo" title="title" /></p>

与参考链接一样,不允许使用空格、制表符和行结尾 两组括号之间:

例587 试试
![foo] 
[]

[foo]: /url "title"
<p><img src="/url" alt="foo" title="title" />
[]</p>

捷径:

例588 试试
![foo]

[foo]: /url "title"
<p><img src="/url" alt="foo" title="title" /></p>
例589 试试
![*foo* bar]

[*foo* bar]: /url "title"
<p><img src="/url" alt="foo bar" title="title" /></p>

请注意,链接标签不能包含未转义的括号:

实施例590 尝试一下
![[foo]]

[[foo]]: /url "title"
<p>![[foo]]</p>
<p>[[foo]]: /url &quot;title&quot;</p>

链接标签不区分大小写:

实施例591 尝试一下
![Foo]

[foo]: /url "title"
<p><img src="/url" alt="Foo" title="title" /></p>

如果你只想要一个字面意思 ! 后面是括号内的文本,您可以 反斜杠-转义开头 [:

实施例592 尝试一下
!\[foo]

[foo]: /url "title"
<p>![foo]</p>

如果您想在文字后面添加链接 !, 反斜杠转义 !:

实施例593 尝试一下
\![foo]

[foo]: /url "title"
<p>!<a href="/url" title="title">foo</a></p>

Autolink 是里面的绝对 URI 和电子邮件地址 <>。它们被解析为带有 URL 或电子邮件地址的链接 作为链接标签。

URI 自动链接 包括 <,后面跟着一个 绝对 URI 后跟 >。它被解析为 指向 URI 的链接,以 URI 作为链接的标签。

URI 绝对 , 出于这些目的,由一个 方案 组成,后跟一个冒号( :) 后跟零个或多个除 ASCII 控制 之外的字符 字符 空间 <, 和 >。 如果 URI 包含这些字符,则它们必须进行百分比编码 (例如 %20 为一个空间)。

就本规范而言, 方案 是任何序列 由 2–32 个字符组成,以 ASCII 字母开头,后跟 由 ASCII 字母、数字或符号加号的任意组合 (“+”)、句点(“.”)或连字符(“-”)。

以下是一些有效的自动链接:

实施例594 尝试一下
<http://foo.bar.baz>
<p><a href="http://foo.bar.baz">http://foo.bar.baz</a></p>
实施例595 尝试一下
<https://foo.bar.baz/test?q=hello&id=22&boolean>
<p><a href="https://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean">https://foo.bar.baz/test?q=hello&amp;id=22&amp;boolean</a></p>
实施例596 尝试一下
<irc://foo.bar:2233/baz>
<p><a href="irc://foo.bar:2233/baz">irc://foo.bar:2233/baz</a></p>

大写也可以:

示例597 尝试一下
<MAILTO:FOO@BAR.BAZ>
<p><a href="MAILTO:FOO@BAR.BAZ">MAILTO:FOO@BAR.BAZ</a></p>

请注意,许多字符串被视为 URI 绝对 本规范的目的不是有效的 URI,因为它们 计划未注册或由于其他问题 及其语法:

实施例598 尝试一下
<a+b+c:d>
<p><a href="a+b+c:d">a+b+c:d</a></p>
示例599 尝试一下
<made-up-scheme://foo,bar>
<p><a href="made-up-scheme://foo,bar">made-up-scheme://foo,bar</a></p>
示例 600 尝试一下
<https://../>
<p><a href="https://../">https://../</a></p>
示例 601 尝试一下
<localhost:5001/foo>
<p><a href="localhost:5001/foo">localhost:5001/foo</a></p>

自动链接中不允许有空格:

实施例602 尝试一下
<https://foo.bar/baz bim>
<p>&lt;https://foo.bar/baz bim&gt;</p>

反斜杠转义在自动链接内不起作用:

示例 603 尝试一下
<https://example.com/\[\>
<p><a href="https://example.com/%5C%5B%5C">https://example.com/\[\</a></p>

电子邮件 自动链接 包括 <,后跟 电子邮件地址 , 其次是 >。链接的标签是电子邮件地址, 网址是 mailto: 接下来是电子邮件地址。

一个 电子邮件地址 , 出于这些目的,任何匹配的东西 表达式 HTML5 中的非规范正则 规格

/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?
(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/

电子邮件自动链接的示例:

示例 604 尝试一下
<foo@bar.example.com>
<p><a href="mailto:foo@bar.example.com">foo@bar.example.com</a></p>
实施例605 尝试一下
<foo+special@Bar.baz-bar0.com>
<p><a href="mailto:foo+special@Bar.baz-bar0.com">foo+special@Bar.baz-bar0.com</a></p>

反斜杠转义符在电子邮件自动链接内不起作用:

实施例606 尝试一下
<foo\+@bar.example.com>
<p>&lt;foo+@bar.example.com&gt;</p>

这些不是自动链接:

实施例607 尝试一下
<>
<p>&lt;&gt;</p>
实施例608 尝试一下
< https://foo.bar >
<p>&lt; https://foo.bar &gt;</p>
实施例609 尝试一下
<m:abc>
<p>&lt;m:abc&gt;</p>
示例 610 尝试一下
<foo.bar.baz>
<p>&lt;foo.bar.baz&gt;</p>
示例 611 尝试一下
https://example.com
<p>https://example.com</p>
示例612 尝试一下
foo@bar.example.com
<p>foo@bar.example.com</p>

6.6 原始 HTML

之间的文本 <> 看起来 HTML 标签被解析为 原始 HTML 标签并将在不转义的情况下以 HTML 形式呈现。 标签和属性名称不限于当前的 HTML 标签, 因此可以使用自定义标签(甚至 DocBook 标签)。

这是标签的语法:

标签名称 ASCII 字母组成 后跟零个或多个 ASCII 字母、数字或 连字符( -)。

属性 由空格 、制表符和最多一个行结尾组成, 和 属性名称 可选的 属性值规范

名称 属性 由一个 ASCII 字母组成, _, 或者 :,后跟零个或多个 ASCII 字母、数字、 _, ., :, 或者 -。 (注:这是 XML 规范仅限于 ASCII。 HTML5 更宽松。)

属性 值规范 由可选空格、制表符和最多一行结尾组成, 一个 = 字符、可选空格、制表符和最多一行结尾, 和一个 属性值

属性 组成 由不带引号的属性值 , 单 引号属性值 双引号属性值

不带引号的属性 是一个非空字符串,不是 包括空格、制表符、行结束符、 ", ', =, <, >, 或者 `

单引号属性 包括 ', 零个或多个 字符不包括 ',以及最终的 '

双引号属性 包括 ", 零个或多个 字符不包括 ",以及最终的 "

标签 开放 < 字符, 标签名称 , 零个或多个 属性 、可选空格、制表符和最多一行结尾, 一个可选的 / 角色,以及一个 > 特点。

结束标签 字符串组成 </, 一个 标签名称 、可选空格、制表符、最多一行结尾以及字符 >

HTML 注释 以下部分组成 <!-->, <!--->, 或者 <!--,一串 不包括字符串的字符 -->, 和 --> (参见 HTML 规范 )。

一条 处理指令 由字符串组成 <?, 一个字符串 不包括字符串的字符数 ?>,和字符串 ?>

声明 由字符串 组成 <!, 一个 ASCII 字母,零个或多个 不包含该字符的字符 >,以及角色 >

部分 CDATA 包括 字符串 <![CDATA[, 不包含字符串的字符串 ]]>,和字符串 ]]>

HTML 标签 开始 标签 结束标签 、 、 HTML 注释 处理 指令 声明 、 或 CDATA 部分

以下是一些简单的开放标签:

示例 613 尝试一下
<a><bab><c2c>
<p><a><bab><c2c></p>

空元素:

示例 614 尝试一下
<a/><b2/>
<p><a/><b2/></p>

允许使用空格:

实施例615 尝试一下
<a  /><b2
data="foo" >
<p><a  /><b2
data="foo" ></p>

具有属性:

实施例616 尝试一下
<a foo="bar" bam = 'baz <em>"</em>'
_boolean zoop:33=zoop:33 />
<p><a foo="bar" bam = 'baz <em>"</em>'
_boolean zoop:33=zoop:33 /></p>

可以使用自定义标签名称:

示例 617 尝试一下
Foo <responsive-image src="foo.jpg" />
<p>Foo <responsive-image src="foo.jpg" /></p>

非法标签名称,未解析为 HTML:

实施例618 尝试一下
<33> <__>
<p>&lt;33&gt; &lt;__&gt;</p>

非法属性名称:

实施例619 尝试一下
<a h*#ref="hi">
<p>&lt;a h*#ref=&quot;hi&quot;&gt;</p>

非法属性值:

实施例620 尝试一下
<a href="hi'> <a href=hi'>
<p>&lt;a href=&quot;hi'&gt; &lt;a href=hi'&gt;</p>

非法空格:

示例 621 尝试一下
< a><
foo><bar/ >
<foo bar=baz
bim!bop />
<p>&lt; a&gt;&lt;
foo&gt;&lt;bar/ &gt;
&lt;foo bar=baz
bim!bop /&gt;</p>

缺少空格:

实施例622 尝试一下
<a href='bar'title=title>
<p>&lt;a href='bar'title=title&gt;</p>

结束标签:

示例 623 尝试一下
</a></foo >
<p></a></foo ></p>

结束标记中的非法属性:

实施例624 尝试一下
</a href="foo">
<p>&lt;/a href=&quot;foo&quot;&gt;</p>

评论:

实施例625 ​​尝试一下
foo <!-- this is a --
comment - with hyphens -->
<p>foo <!-- this is a --
comment - with hyphens --></p>
实施例626 尝试一下
foo <!--> foo -->

foo <!---> foo -->
<p>foo <!--> foo --&gt;</p>
<p>foo <!---> foo --&gt;</p>

加工说明:

实施例627 尝试一下
foo <?php echo $a; ?>
<p>foo <?php echo $a; ?></p>

声明:

实施例628 尝试一下
foo <!ELEMENT br EMPTY>
<p>foo <!ELEMENT br EMPTY></p>

CDATA 部分:

实施例629 尝试一下
foo <![CDATA[>&<]]>
<p>foo <![CDATA[>&<]]></p>

实体和数字字符引用保留在 HTML 中 属性:

实施例630 尝试一下
foo <a href="&ouml;">
<p>foo <a href="&ouml;"></p>

反斜杠转义在 HTML 属性中不起作用:

示例631 尝试一下
foo <a href="\*">
<p>foo <a href="\*"></p>
示例632 尝试一下
<a href="\"">
<p>&lt;a href=&quot;&quot;&quot;&gt;</p>

6.7 硬换行

前面的行结尾(不在代码范围或 HTML 标记中) 由两个或多个空格组成,并且不会出现在块的末尾 被解析为 硬换行符 (呈现 在 HTML 中作为 <br /> 标签):

示例633 尝试一下
foo  
baz
<p>foo<br />
baz</p>

对于更明显的替代方案,在前面加一个反斜杠 可以使用行结尾 代替两个或多个空格:

示例634 尝试一下
foo\
baz
<p>foo<br />
baz</p>

可以使用两个以上的空格:

示例635 尝试一下
foo       
baz
<p>foo<br />
baz</p>

下一行开头的前导空格将被忽略:

示例636 尝试一下
foo  
     bar
<p>foo<br />
bar</p>
实施例637 尝试一下
foo\
     bar
<p>foo<br />
bar</p>

硬换行可能发生在强调、链接和其他结构中 允许内联内容:

示例638 尝试一下
*foo  
bar*
<p><em>foo<br />
bar</em></p>
实施例639 尝试一下
*foo\
bar*
<p><em>foo<br />
bar</em></p>

代码范围内不会发生硬换行

实施例640 尝试一下
`code  
span`
<p><code>code   span</code></p>
实施例641 尝试一下
`code\
span`
<p><code>code\ span</code></p>

或 HTML 标签:

实施例642 尝试一下
<a href="foo  
bar">
<p><a href="foo  
bar"></p>
示例 643 尝试一下
<a href="foo\
bar">
<p><a href="foo\
bar"></p>

硬换行符用于分隔块内的内联内容。 硬换行符的语法在段落末尾或 其他块元素:

实施例644 尝试一下
foo\
<p>foo\</p>
实施例645 尝试一下
foo  
<p>foo</p>
实施例646 尝试一下
### foo\
<h3>foo\</h3>
示例 647 尝试一下
### foo  
<h3>foo</h3>

6.8 软换行

不存在的常规行结尾(不在代码范围或 HTML 标记中) 前面有两个或多个空格或反斜杠被解析为 软中断 。 (软换行符可以在 HTML 中呈现为 行尾 或作为空格。结果将是相同的 浏览器。在此示例中, 行结尾。) 将使用

实施例648 尝试一下
foo
baz
<p>foo
baz</p>

行尾和下一行开头的空格是 删除:

实施例649 尝试一下
foo 
 baz
<p>foo
baz</p>

符合标准的解析器可以将 HTML 中的软换行符呈现为 行尾或作为空格。

渲染器还可以提供渲染软换行符的选项 当硬线断裂时。

6.9 文本内容

任何未按上述规则解释的字符将 被解析为纯文本内容。

示例 650 尝试一下
hello $.;'there
<p>hello $.;'there</p>
示例 651 尝试一下
Foo χρῆν
<p>Foo χρῆν</p>

内部空间被逐字保留:

示例652 尝试一下
Multiple     spaces
<p>Multiple     spaces</p>

附录:解析策略

在本附录中,我们描述了解析策略的一些特征 在 CommonMark 参考实现中使用。

概述

解析有两个阶段:

  1. 在第一阶段,消耗输入行并且块 文档的结构——段落的划分、引用块、 列表项等等——被构造。文本被分配给这些 块但未解析。解析链接引用定义并生成 链接图已构建。

  2. 第二阶段,段落和标题的原始文本内容 被解析为 Markdown 内联元素序列(字符串、 代码跨度、链接、强调等),使用链接图 第一阶段构建的参考文献。

在处理的每个点,文档都被表示为一棵树 。树的根是一个 document 堵塞。这 document 可以有任意数量的其他块作为 子块 。这些孩子 反过来,可能还有其他子块。块的最后一个孩子 通常被认为是 open ,这意味着后续的输入行 可以改变其内容。 (未打开的块将被 关闭 。) 例如,这里是一个可能的文档树,其中包含开放块 用箭头标记:

-> document
  -> block_quote
       paragraph
         "Lorem ipsum dolor\nsit amet."
    -> list (type=bullet tight=true bullet_char=-)
         list_item
           paragraph
             "Qui *quodsi iracundia*"
      -> list_item
        -> paragraph
             "aliquando id"

第一阶段:区块结构

处理的每一行都会对该树产生影响。该行是 进行分析,并且根据其内容,该文件可能会被更改 通过以下一种或多种方式:

  1. 一个或多个打开的块可以被关闭。
  2. 可以创建一个或多个新块作为该块的子块 最后一个开放块。
  3. 文本可以添加到剩余的最后一个(最深的)开放块中 在树上。

一旦以这种方式将一条线合并到树中, 它可以被丢弃,因此可以在流中读取输入。

对于每一行,我们都遵循以下过程:

  1. 首先,我们迭代开放的块,从 根文档,并从最后一个子文档下降到最后一个 开块。每个块都强加了该行必须满足的条件 如果该块要保持打开状态。例如,块引用需要 > 特点。段落要求非空行。 在此阶段,我们可能会匹配所有或仅部分开放的 块。但我们还不能关闭不匹配的块,因为我们可能有一个 懒惰的续行

  2. 接下来,在消耗现有的延续标记之后 块,我们寻找新的块开始(例如 > 以获得块报价)。 如果我们遇到新的块开始,我们会关闭所有不匹配的块 在步骤 1 中,在创建新块作为最后一个块的子块之前 匹配的容器块。

  3. 最后,我们看看该行的其余部分(在块之后 标记如 >、列表标记和缩进已被消耗)。 这是可以合并到最后打开的文本中 块(段落、代码块、标题或原始 HTML)。

当我们看到段落的一行时,就形成了 Settext 标题 这是一个 setext 标题下划线

当段落关闭时检测参考链接定义; 解析累积的文本行以查看它们是否以 一个或多个参考链接定义。任何余数都变成 正常段落。

我们可以通过考虑上面的树来了解它是如何工作的 由四行 Markdown 生成:

> Lorem ipsum dolor
sit amet.
> - Qui *quodsi iracundia*
> - aliquando id

一开始,我们的文档模型只是

-> document

我们文本的第一行,

> Lorem ipsum dolor

导致 block_quote 块被创建为我们的子块 打开 document 块,和一个 paragraph 块作为子项 这 block_quote。然后将文本添加到最后打开的 块, paragraph:

-> document
  -> block_quote
    -> paragraph
         "Lorem ipsum dolor"

下一行,

sit amet.

是开放的“惰性延续” paragraph,所以它被添加 到该段落的文本:

-> document
  -> block_quote
    -> paragraph
         "Lorem ipsum dolor\nsit amet."

第三行,

> - Qui *quodsi iracundia*

导致 paragraph 要关闭的块,以及一个新的 list 堵塞 作为孩子打开 block_quote。一个 list_item 也是 作为子项添加 list,和一个 paragraph 作为一个孩子 这 list_item。然后将文本添加到新的文本中 paragraph:

-> document
  -> block_quote
       paragraph
         "Lorem ipsum dolor\nsit amet."
    -> list (type=bullet tight=true bullet_char=-)
      -> list_item
        -> paragraph
             "Qui *quodsi iracundia*"

第四行,

> - aliquando id

导致 list_item (及其孩子 paragraph)关闭, 和一个新的 list_item 作为孩子打开 list。一个 paragraph 被添加为新的子项 list_item,包含文本。 这样我们就得到了最终的树:

-> document
  -> block_quote
       paragraph
         "Lorem ipsum dolor\nsit amet."
    -> list (type=bullet tight=true bullet_char=-)
         list_item
           paragraph
             "Qui *quodsi iracundia*"
      -> list_item
        -> paragraph
             "aliquando id"

第二阶段:内联结构

一旦所有输入都被解析,所有打开的块都会被关闭。

然后我们“遍历树”,访问每个节点,并解析原始数据 段落和标题的字符串内容作为内联。在此 点我们已经看到了所有链接引用定义,所以我们可以 随时解析参考链接。

document
  block_quote
    paragraph
      str "Lorem ipsum dolor"
      softbreak
      str "sit amet."
    list (type=bullet tight=true bullet_char=-)
      list_item
        paragraph
          str "Qui "
          emph
            str "quodsi iracundia"
      list_item
        paragraph
          str "aliquando id"

请注意 结尾的行 第一段中 是如何 被解析为 softbreak,以及第一个列表项中的星号 已成为一个 emph

到目前为止,内联解析最棘手的部分是处理强调, 强烈的强调、链接和图像。这是使用以下命令完成的 算法。

当我们解析内联时,我们会点击

我们插入一个文本节点,其中这些符号作为其文字内容,并且我们 将指向该文本节点的指针添加到 分隔符堆栈 中。

定界符栈 一个双向链表。每个 元素包含一个指向文本节点的指针,以及有关

当我们击中一个 ] 字符,我们称之为 查找链接或图像 程序(见下文)。

当我们到达输入的末尾时,我们称该 过程为强调 程序(见下文),与 stack_bottom = 空。

从分隔符堆栈的顶部开始,我们向后看 穿过堆栈寻找一个开口 [ 或者 ![ 分隔符。

过程强调

范围 stack_bottom 为我们能走多远设定一个下限 中下降 在定界符堆栈 。如果它是NULL,我们可以 一直走到底部。否则,我们先停下来 来访 stack_bottom

current_position 指向 分隔符堆栈 上的元素 就在上面 stack_bottom (或者第一个元素,如果 stack_bottom 为空)。

我们跟踪 openers_bottom 对于每个分隔符 类型 ( *, _),索引到结束分隔符运行的长度 (模 3)以及结束分隔符是否也可以是 揭幕战。将此初始化为 stack_bottom

然后我们重复以下操作,直到耗尽潜力 闭门器:

完成后,我们删除上面的所有分隔符 stack_bottom 从 定界符堆栈。