块结构
每一个被处理的行都会对树产生影响,行被分析且根据其内容会对树产生的更改,分为以下几种方式:
- 一个或多个打开的块被关闭。
- 会在最后一个打开的块中生成新的子块。
- 会在最后一个打开的块中增加文本内容。
一旦以这种方式将行合并到树中,就可以将其舍弃,因此可以在流中读取输入。
对于每一行,我们按照以下流程:
- 首先,我们遍历打开的块,从文档根节点开始,然后通过最后一个子节点下行到最后一个打开的块。 如果块要保持打开,则每个块需要强加一个条件,如果这个块保持打开,那这个条件必须满足。例如,块引用需要一个
>
字符,段落需要非空行。 在这个阶段,我们可以匹配所有或仅一些打开的块。但是我们还不能关闭不匹配的块,因为我们可能有延迟行。 - 接下来,在消耗现有块的连续标记之后,我们寻找新的起始块(例如,给块引用的
>
)。 如果我们遇到新的起始块,在将新块创建为最后一个匹配块的子节点之前,我们关闭步骤 1 中无法匹配的所有块。 - 最后,我们查看该行的其余部分(在块标记之后,如
>
,列表标记和已经被消耗的缩进)。这是可以合并到最后一个打开块(段落,代码块,标题或原始 HTML)的文本。
当我们看到段落的行是 setext 标题下划线时,会形成 Setext 标题。
关闭段落时检测引用链接定义; 解析累积的文本行以查看它们是否以一个或多个引用链接定义开头。 剩下的内容都成为正常段落。
通过考虑下列四行 Markdown 如何生成上面的树,我们可以看到它是如何工作的:
> Lorem ipsum dolor
sit amet.
> - Qui *quodsi iracundia*
> - aliquando id
一开始我们的文档模型只有
-> document
文本第一行,
> Lorem ipsum dolor
致使block_quote
块被创建为我们打开的document
块的子节点,并且paragraph
块被创建为block_quote
的子节点。 然后将文本添加到最后一个打开的块,即段落
:
-> document
-> block_quote
-> paragraph
"Lorem ipsum dolor"
下一行,
sit amet.
是一个开启的段落
的延迟行
,所以它被添加到段落的文本中:
-> document
-> block_quote
-> paragraph
"Lorem ipsum dolor\nsit amet."
第三行,
> - Qui *quodsi iracundia*
使paragraph
块被关闭,并且一个新的list
块作为block_quote
的子节点打开。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*"
第四行,
> - aliquando id
使list_item
(和它的子节点段落
)被关闭,一个新的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"