块元素构成了AsciiDoc文档的主要结构,从文档本身开始。

什么是一个区块?

一个区块元素(又称为块)是AsciiDoc文档中一个离散的、基于行的内容块。一旦被解析,那块内容就成为解析后文档模型中的一个区块元素。某些区块可能包含其他区块,因此我们说区块可以嵌套。转换器依次访问每个区块,按照文档的顺序,将其转换成相应的输出内容块。

块状形式

在AsciiDoc语法中定义块边界的方式各不相同。一些块的边界,如列表、段落和块宏,是隐式的。其他块的边界是使用分界符(即定界块)显式标记的。主要的共同点是块总是以行为导向的。

一个_段落块_被定义为一组连续的(非空的)行。一个_限定块_被定界线所界定。一个_章节块_(又称为节)由一个或多个等号前缀的节标题定义。该节包括所有跟随节标题行的内容,直到下一个同级或上级节标题或文档边界。一个_列表块_由一组同级列表项定义,每个列表项都用一个标记符号表示。一个_描述列表_块由一组同级列表项定义,每个列表项由一个或多个术语表示。一个_块宏_由与块宏语法相匹配的单行定义。而_文档_本身也是一个块。

一个块(包括它的元数据行)应该始终被一个空行或文档边界在其一侧界定。

一个块是否支持嵌套块取决于块的内容模型(以及语法所允许的内容)。

内容模型

块的内容模型决定了块可以拥有何种内容(如果有的话)以及如何处理这些内容。AsciiDoc中块的内容模型如下:

复合物

一个可能只包含其他块的块(例如,一个部分)

简单

一个被视为连续行段落文本的块(并且适用于正常替换)(例如,一个段落块)

逐字

一个用于保持逐字文本的区块(显示为“原样”)(并且受到逐字替换的约束)(例如,一个列表区块)

原始的

一个用来保存未处理内容的块,这些内容直接传递到输出中,没有应用任何替代处理(例如,一个直通块)。

空的

一个没有内容的区块(例如,一个图片区块)

桌子

一种为表格保留的特殊内容模型,用于强制固定结构。

内容模型是为所有内置语法推断的(由上下文确定),但是可以为自定义块进行配置。在不同情况下,块也可能支持不同的内容模型。具体情境由上下文和风格确定,并且在定界块的情况下,还由结构容器确定。

上下文

你可能经常听到一个区块被称为某个名字,比如示例区块、侧边栏区块、警告区块或者章节。那个名字就是区块的上下文。

让我们考虑以下正常部分:

== 章节标题

章节的内容。

这个块的上下文是`section`。我们通常称之为一个章节(或章节块),使用上下文作为形容词来描述块。在这种情况下,由于语法的暗示,作者无需指定上下文。

每个块都有一个上下文。上下文通常由语法暗示,但在某些情况下可以明确声明。上下文是区分一个块与另一个块的特征。你可以将上下文视为块的类型。

上下文可以通过使用块样式进一步修改,以创建一系列具有共同类型的块,就像是在警告块和部分中的情况一样。我们不久将介绍那个修饰符。

对于块,上下文有时被称为块名。特别是在谈论自定义块时,会提到这一点。块名只是另外一层抽象。所有内置的块名都精确映射到一个上下文。但是块扩展可以将任意的块名映射到一个或多个上下文。最终使用哪个上下文取决于扩展的process方法返回的内容。最终,决定块如何转换的是上下文。

上下文通常决定了内容模型。例如,所有章节隐含了复合内容模型,因为一个章节只能包含其他的块元素。所有的字面块隐含了逐字内容模型,因为这个块的目的是呈现逐字的输出。

内置上下文概要

这是AsciiDoc中所有内置块的上下文列表。

Note
在Asciidoctor API中,上下文用符号表示。在Ruby中,符号是一个前缀有冒号的名称(例如,:listing)。这份文档在提到上下文的名称时有时会使用这种标记法。然而,这种标记法并不是普遍适用的。有些处理器,比如Asciidoctor.js, 把上下文存储为字符串。
Table 1. 内置上下文
名称 用途

admonition

五种警告块中的一种。

audio

音频块。

colist

调用列表。

dlist

描述列表。

document

顶级文档或AsciiDoc表格单元格中的文档

example

示例块。

floating_title

独立标题。

image

图片块。

list_item

有序、无序或描述列表中的一项(仅在列表或描述列表块内时相关)。 在描述列表中,此块用于表示术语和描述。

listing

列表块。

literal

字面块。

olist

有序列表。

open

开放块。

page_break

分页符。

paragraph

段落。

pass

透传块。

preamble

文档的前言部分。

quote

引用块(也称为blockquote)。

section

节。 也可能是部分、章节或特殊节。

sidebar

侧边栏块。

table

表格块。

table_cell

表格单元格(仅在表格块内时相关)。

thematic_break

主题分隔(也称为水平线)。

toc

目录块(用于指定自定义目录放置)。

ulist

无序列表。

verse

诗歌块。

video

视频块。

Note
每个内联元素也有一个上下文,但是这些元素还不能从解析后的文档模型中访问。

可以通过使用块、块宏或内联宏扩展点来引入额外的上下文。

转换器使用的上下文环境

上下文是转换器用来分派到转换方法的东西。然后转换器使用风格来对同一家族的块应用特殊行为。

除了两个例外,转换器的上下文和处理方法之间存在一对一的映射关系。这两个例外是 list_itemtable_cell 上下文,它们没有映射到处理方法。在转换器中,这些块必须从其父块访问。

块状样式

上下文并不总是能完全告诉我们一个块的身份。有些块需要特殊化。这就是块风格的用途所在。

在一些区块的上方,你可能会注意到区块属性列表开头的名字(例如,[source][verse])。区块属性列表中的第一个位置(未命名)属性被用来声明区块的样式。

声明的块样式是作者提供的值。然后对该值进行解释和决议。如果已解决的块样式非空,则它会专门化块的上下文。(它可能代替或者除此之外,改变块的上下文)。

考虑以下源代码块的示例:

[source,ruby]
----
puts "Hello, World!"
----

一个源代码块的上下文是 listing(从块限定符推断出来的),并且风格是 source(由作者指定的)。我们说风格将块特化为源代码块。(技术上来说,源语言的存在已经暗示了 source 风格,但内部处理正是这样进行的)。块的上下文仍然相同,但它有额外的元数据来指示需要特殊处理。

我们也看到块样式被用于其他目的。比如,文章标题上方的 appendix 块样式(例如,[appendix])将该部分特化为附录(一种特殊的部分),因而具有特殊的语义和行为。在模型中,该部分的样式同时存储为 sectname。在示例块上方的五种警告样式之一(例如,[TIP])可以将示例块变为带有该名称(即标签)的警告块。在模型中,警告样式以小写形式存储在 name 属性中。在无序或有序列表上方的块样式(例如,[circle][loweralpha]),分别改变列表项前显示的标记。在描述列表上方的块样式(例如,[qanda][horizontal])可以改变其语义或布局。

声明的块样式可以用来改变块的上下文,这称为块伪装。考虑使用文字块定界符的列表块的这种替代语法的情况。

[listing]
....
a > b
....

由于声明的块样式与上下文的名称匹配,块的上下文变成了 listing,并且解析后的块样式保持未设置。这意味着解析后的块样式不同于声明的块样式。要了解更多关于如何使用声明的块样式改变块的上下文,请参见masquerading.html

要全面了解一个块的身份,您必须同时考虑上下文和样式。解析后的样式专门化了上下文,以赋予其特殊的行为或语义。

区块共性

块是使用某种行为导向的语法定义的。节区块以节标题行开始。限定块被一对匹配的分隔线所包围。段落块必须是连续的行。

所有的块都可以容纳零个或多个元数据行,这些元数据行直接堆叠在块的顶部。这些行填充了块的属性,例如ID、标题和选项。这些元数据行如下:

  • 零个或多个区块属性行(用于填充区块的属性)

  • 一个可选的块锚点行

  • 一个可选的块标题行(许多块也支持对应的标题)

  • 一个可选的ID

  • 一个可选的角色集合

  • 一组可选的选项

例如,考虑一个带有标题和ID的侧边栏块:

音乐风格
[#music-styles]
****
偏离原来的话题,来描述一下什么是音乐风格。
****

当涉及到处理内容时,块会分裂成不同的组。这些组主要与块的内容模型有关。

段落块和逐字块有一个隐含的且可修改的替代项集合。替代项不适用于复合块(即,可能包含嵌套块的块)。