块结构

每一个被处理的行都会对树产生影响,行被分析且根据其内容会对树产生的更改,分为以下几种方式:

  1. 一个或多个打开的块被关闭。
  2. 会在最后一个打开的块中生成新的子块。
  3. 会在最后一个打开的块中增加文本内容。

一旦以这种方式将行合并到树中,就可以将其舍弃,因此可以在流中读取输入。
对于每一行,我们按照以下流程:

  1. 首先,我们遍历打开的块,从文档根节点开始,然后通过最后一个子节点下行到最后一个打开的块。 如果块要保持打开,则每个块需要强加一个条件,如果这个块保持打开,那这个条件必须满足。例如,块引用需要一个>字符,段落需要非空行。 在这个阶段,我们可以匹配所有或仅一些打开的块。但是我们还不能关闭不匹配的块,因为我们可能有延迟行
  2. 接下来,在消耗现有块的连续标记之后,我们寻找新的起始块(例如,给块引用的>)。 如果我们遇到新的起始块,在将新块创建为最后一个匹配块的子节点之前,我们关闭步骤 1 中无法匹配的所有块。
  3. 最后,我们查看该行的其余部分(在块标记之后,如>,列表标记和已经被消耗的缩进)。这是可以合并到最后一个打开块(段落,代码块,标题或原始 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"