相关问题 |
接受的决定
一个块上的样式不影响块解析模型,即如何匹配一个结构形式。相反,块解析是通过测试各种结构形式(例如,段落、缩进行、结构容器等)的语法规则来进行的,以寻找匹配项。然后样式会影响如何解释匹配语法规则的结果(抽象语法树节点),并将其转换为抽象语义图中的一个节点。
决策摘要
在预设的AsciiDoc中,块样式与块解析规则交织在一起。这种耦合使得为语言定义一种正式语法变得不切实际。我们已经决定重新构架块样式,使其功能符合最初的意图。样式仅仅影响解析块的解释方式以及将其转化为语义节点的过程。
在AsciiDoc中,有各种各样的结构形式,这些是语言在块级别的构建模块。这些结构包括段落、缩进行、列表项、标题、块宏以及限定块。这些结构基于它们匹配的语法规则被解析器识别。
一旦解析器确定了结构是什么,它就会遵循一定的规则来识别构成该结构的行,如何处理任何前导标记或周围的分隔符行,以及是否解析嵌套块。块样式不应该影响解析器识别块结构的方式。换句话说,块解析器应该在不考虑任何块元数据的情况下识别块及其边界。这个规则唯一的例外是标题上的离散样式。离散样式应该导致将标题解析为叶块而不是父块。由于部分和离散标题具有相同的结构形式,而只有部分允许有子节点,因此这个例外是必要的。
一旦块被块解析器解析,样式可以影响接下来会发生的事情。样式可能会:
-
指示解析器在行内运行内联解析器
-
指示解析器不要在这些行上运行内联解析器。
-
指令解析器只对行内处理器的某种模式运行。
-
指导解析器将块从一种类型更改为另一种类型(例如,将段落更改为包含该段落的边栏)。
区块样式在解析中的作用概述:
-
源代码形式(例如,缩进)控制如何确定块的边界及其块内容模型(它是否可以有子块)。
-
样式(可能是隐含的)影响了内联元素的解析方式,并决定了块的名称以及,如果适用的话,其变体。
-
区块名决定了在解析文档被转换时应用哪种转换;转换器不考虑表单,因此表单不影响转换。
让我们来考虑一个例子。我们将观察当`normal`样式被声明在一个缩进行的上方时的情况。(注意`normal`样式是`paragraph`的别名,为了向后兼容而保留)。
[normal] [[idname]]https://example.org[]
This block will be parsed as verbatim since it’s written using the indented form. Then, the normal
style will be applied, transforming the block into a paragraph. The application of that style happens in the action for the rule. The indentation is first stripped away, then the inline parser is run on those lines. This allows the author to leverage the verbatim parsing of an indented form, but still have the text in the paragraph interpreted as though it had been defined as a normal paragraph. The ASG node will still record the form of this paragraph as indented
to track how it was defined.
我们现在来看看在段落结构上声明了`sidebar`样式的情况。
[sidebar] 只是一句旁白。
这个块将被解析为一个段落,因为它没有缩进。然后,将应用 sidebar
样式,将该块转换为侧边栏。样式的应用发生在规则的动作中。规则动作将创建一个合成的侧边栏块,并将段落作为该块的子节点。与该块相关联的任何元数据都将被提升到侧边栏块中,可能有一些例外,如 hardbreaks
选项。然后动作将返回包含源文档中段落的侧边栏块。ASG节点将记录这个侧边栏块的形式为 paragraph
,以跟踪它是如何定义的。
现在让我们考虑在缩进行上面使用`sidebar`样式的情况。
[sidebar] [[idname]]https://example.org[]
这个块将被解析为逐字(verbatim)形式,因为它是用缩进形式写的。接下来发生的事情可能有些出人意料,但为了与早期规范的AsciiDoc兼容这是必要的。该块首先被转换为一个段落,就像指定了`normal`样式一样,如第一个示例所示。然后,将应用`sidebar`样式,将该段落转换为旁白,如前一个示例所示。它的行为就好像块有两种样式,normal`和`sidebar
。然后,动作将返回侧边栏块,其中包括从源文档转换成段落的缩进行。ASG节点将记录这种侧边栏块的形式为`indented`,以追踪它是如何定义的。如果我们是在重新定义语言,我们可能会说解析器会创建一个包含逐字块(literal block)的侧边栏块,但我们已经确定在这种情况下我们必须保持向后兼容。
这种解析策略将成为`subs`属性的解释以及如何运作区块扩展的基础。区块解析始终最先进行,然后元数据可以影响如何处理该结果。在定义了`subs`属性的区块案例中,它告知解析器如何执行内联解析(如果有的话)。`subs`属性不会影响区块的识别方式。区块扩展将在规则动作中运行,当解析结果被解释并转换为ASG节点时。
将这种解析策略应用于`subs`属性,这两个块大致相当:
传递这个消息。 传递这个。
目前还不完全清楚`subs`属性在多大程度上可被遵守,但这种解析策略是理解如何对其建模的第一步。
向后兼容性
在块解析完成后再应用块样式,有可能某些有样式的段落与预先规定的AsciiDoc中的行数匹配多或匹配少。例如,以下的AsciiDoc将不再产生一个文字块,而是一个列表(也许带有文字项目符号的样式?):
[literal] * 这只是一个列表
然而,我们预计这些情况会很少见,并且可以容易地纠正。
这种行为也是不一致的,因为下面的例子会产生一个列表而不是边栏。但是现在它会在边栏里产生一个列表,因为`sidebar`是一种块样式,而不是项目符号样式。
[sidebar] * 这是侧边栏中的一个列表
风格的影响应当是一致的,即作为解析转换的作用,而非作为结构形式。
块扩展的工作方式肯定会受到影响,因为现在将预先进行块解析。然而,关于语法扩展以及它们的处理方式的话题,留待另一份SDR讨论。