规格目标
AsciiDoc 语言规范的目标是描述一个确定的、全面的、可解析的 AsciiDoc 语法文档。目前的重点是能够识别 AsciiDoc 文档的结构,并将其内容解析成节点模型。语法将在技术部分使用最适合该语言的语法表达式(例如,PEG)进行文档化。规范将明确指出语法中哪些部分由预处理器处理,哪些部分由核心结构解析器处理,以及需要从文档中捕获并记录在抽象语义图(ASG)中的信息。此外,规范必须明确给出转换器的期望,这些期望是根据节点模型中提供的信息确定的。
从纯技术角度来看,规范可能不会定义一个可以与解析器生成器一起使用的单一语法(因为可能甚至做不到这一点)。然而,实际上,规范将定义语法,当这些语法协同工作时,将描述如何解析AsciiDoc文档。语法的定义方式将在开发规范的第一版本时得到解决。
AsciiDoc的语言规范旨在提高可读性、便于作者编写、保持一致性和提高效率。通过AsciiDoc,我们希望在最小的标记和最大的语义之间取得平衡。由于AsciiDoc语言处理器将用于处理大量内容,因此必须以一种可以高效解析的方式明确语言规范。在可能的情况下,该语言设计为能够优雅地降级。如果无法匹配某个语法规则,并且这样做是安全的,处理器应当回退到将该行或文本串视为未解释的文本。能够从AsciiDoc文档中提取信息也是至关重要的,因此应该能够对文档的整个结构进行建模。当语法解释出现冲突时,应选择最直观的行为。
AsciiDoc语言简介及其用途
AsciiDoc是一种轻量级标记语言,专门用于写作。具体来说,AsciiDoc是一种主要以行为导向并以起始边缘对齐(即在从左到右阅读的文本中为左对齐)的轻量级标记语言。这意味着AsciiDoc是一种符合Unicode标准的文本(非二进制)语言,它有用于处理的约定和专用/保留的标记。所有保留的标记字符都是从ASCII字符集中选取的(因此得名)。
语言的目的是注重以清晰简洁的方式编码解释性或文学信息,从而保持内容与呈现分离(形式和选项中的合理呈现提示除外)。约定和标记赋予文档一个固有的结构。处理器的责任是识别和从文档中提取该结构。在轻量级标记语言中,除非字符序列明确地创建不平衡的边界/无效组合或引用,否则所有字符序列都是有效的。有些字符序列具有特殊含义。识别这些含义取决于处理器。
Part I: 基础知识
词汇表、概念和常见模式
-
标记字符/字符序列
-
文件
-
块级元素与内联元素(垂直排版与水平排版)
-
区块总是从上到下(垂直方向)定义的,而内联标记可以被认为是水平的(将包裹的行视为同一逻辑行的一部分)。我们在这里只是绘制一幅图画,但要小心不要过度泛化这个概念。
-
-
元素
-
文字
-
属性 / 元数据
-
处理器(解析器 / 转换器)
-
输入
-
输出 / 输出格式
-
上下文(某物被使用的地方/环境)
-
标记器
-
标题
-
属性列表 / 带框属性列表
-
预处理器指令
-
宏观
-
分隔线
-
标记文本(通常在一对相同的标记内包裹的文本)
-
假定文档编码为Unicode;允许使用所有Unicode字符。
-
保留标记是从ASCII字符集中选取的
-
语法以与起始边距对齐(从左到右文本中向左对齐)的行为中心。
-
块语法不回溯;如果一个限定的块已经被打开,它必须被关闭。
-
语法中的块边界是显式和隐式的混合。
-
如果定界符不明确,块可以嵌套在块中;你不能在相同类型中嵌套,但可以将一个类型作为另一个相同类型的子块进行嵌套。
-
对于块语法,不完全匹配已识别模式的行将被视为与段落文本相同。
-
内联语法被认为是(未解释的)文本和(被解释的)标记语言交错在一起。
-
对于内联语法,标记模式的左手边被假定为有效直到它不是;如果它不是,它就会回退到下一个选择或未解释的文本。
-
空格字符,特别是空白行,通常是有意义的,但并不总是如此。
角色
-
AsciiDoc文档是一个连续的、未经压缩的字符序列(文本),也被称为字符数据。
-
一个字符是文本的单个码点。
-
任何文本或代码编辑器都可以阅读和显示AsciiDoc文件。
-
有些字符有可见的字形,其他的则没有。
-
任何字符序列都是有效的;某些字符的使用具有特殊含义;当发现其中一个被指定的使用/序列时,它可能激活额外的规则,比如一个匹配的块定界符行。
Unicode 支持
-
AsciiDoc中的字符可以是Unicode定义的任何字符。
-
控制字符和其他不占用空间的字符应该避免。
-
-
AsciiDoc会将Unicode转义序列(如`\u2318`)识别为字符引用的替代方案吗?
-
一个AsciiDoc文档被假定为使用UTF-8编码。
-
处理器可能支持其他编码,但在解析之前必须将输入重新编码为UTF-8。
-
保留字符
-
保留字符是从ASCII字符集中选择的用于AsciiDoc语法标记的字符。
-
保留字符几乎总是一个标点符号或符号(宏名是一个例外)。
空格字符
-
一个AsciiDoc文档可以使用制表符或空格作为空字符,尽管内联语法主要只考虑空格。
-
空格字符是空格、制表符或行结束符(例如,换行符)。
-
FI 精确地,哪些空白字符是被允许的(例如,空格、制表符、换行符)或者被限制的?(比如,在JavaScript中`\s`包括不换行空格(
\u00a0
),但在Ruby中不包括。)
-
-
文档中允许使用其他空格字符,但不会被解释为此类字符。
-
换行符创建了独立的行,在AsciiDoc中这通常会被特殊处理。
-
在分析AsciiDoc文档的块结构时,空行通常被视为具有重要意义。
-
连续两个换行符会创建一个空行;在非逐字内容中,连续的空行在语义上等同于单个空行。
-
除了在逐字的或原始的内容或区块元数据中,一个空行被解释为一个区块的边界。
-
开头的空格字符会创建一个缩进行。
-
尾随空格字符是无关紧要的,可以被处理器丢弃。
-
源代码中的尾随空格字符将如何处理?
-
-
唯一的例外是包含尾随空格字符的行的非AsciiDoc包含文件;这些字符必须被保留。
冗长的字符
-
AsciiDoc经常使用单词和单词边界来确定哪些标记是有效的。
-
然而,在这个上下文中“单词”的含义并没有明确定义。
-
此外,“
word
”一词传统上包含下划线字符,这在AsciiDoc标记中是保留字符。-
下划线字符不应再被视为单词字符;应仅被视为语法标记。
-
-
因此,AsciiDoc将术语“
wordy
”定义为类似单词的(但不严格意义上的单词)字符。 -
一个wordy是一个字母字符(根据Unicode定义)或者一个阿拉伯数字。详情见https://www.unicode.org/reports/tr44/#Alphabetic.
-
一个在AsciiDoc语法中具有意义的冗长字符的例子是,受限标记不能被任何一个冗长字符所界限。
字符引用
-
一个字符引用是一种特殊的转义序列,它通过字符的名称、十进制表示或十六进制表示来识别一个字符。
-
一个命名字符引用有时被称为实体。
-
尽管AsciiDoc并不局限于HTML或XML,但它采用了来自XML的字符引用语法。
-
这些字符引用将被解析器识别,处理程序在转换为输出格式时有机会替换它们。
线条
-
AsciiDoc是一种面向行的语言。
-
因此,在AsciiDoc语言中,线条可以具有重要意义。
-
AsciiDoc文档可以使用通用/Unix(
\n
)或Windows(\r\n
)的行结束符,尽管首选行进符(\n
)。 -
在段落中相邻行之间的换行符不重要。
-
转换器可以选择用空格字符来替换这些行结束符;然而,在解析树中必须保留它们。
-
在解析树中保留行结束符使得在TCK中表达场景变得更容易。
-
FI 我们应该声明行规范化吗?尾随空格不重要,但不强制删除它?(TCK可能会产生歧义)
-
-
区块边界和区块元数据总是定义在它们自己的行上,且占据整行。
-
当行之间不连续(由一个空行分隔)时,这可能表示从一个区块过渡到另一个区块。
-
在解析过程中必须保留行尾符;在转换时可能不总是需要保留。
缩进
-
AsciiDoc是一种起始边距对齐(即在从左到右的语言中为左对齐)的语言。
-
在语法中使用起始边距作为锚点,使得内容的移动变得更容易,避免了过度/复合缩进的问题,鼓励作者对嵌套进行更明确的说明,并使得语言更容易被解析。
-
这意味着,在某些例外情况下,一行开头处的空格字符(缩进的行)是有意义的。
-
关键的例外是列表标记,即使它们被缩进也不具有特定的意义。
-
在块边界处具有前导空格字符的一行会形成一个文字段落。
-
建议使用空格进行缩进,但也可以使用制表符。
空行和中断行
-
空行可能具有重要意义。
-
在逐字内容中,空行会被保留。
-
通常,空行被用来分隔不同的块。
-
段落之间缺少空行会导致各行合并为一个段落。
-
除了在保留空行的情况下(例如在逐字内容中),多个连续空行等同于单个空行。
-
在代码块的开始和结束处的空行将被删除。⇐ 需要阐明这一行为。
-
块元数据行之间和之后的空行是无关紧要的。
-
在两个简单列表项之间的空行会被忽略。⇐ 我们可以说两个空行打断了列表
-
在其他所有地方,空行用作两个块之间的边界。
-
对于没有明确边界的块元素(例如,一个定界块),当遇到中断行时,该块将结束。
-
一个空行通常是一个中断行,但不是唯一的。
-
一个块属性行(包含一个框住的属性列表的行)也是一个中断线。
-
闭合块定界符(如果使用在一个能与开放块定界符匹配的地方)是中断线。
-
列表续行结束了一个附加的块(但不结束列表;相反,它将接下来的块附加到列表项上)
-
在列表中,列表项是一个中断线;根据标记的不同,它要么开始一个新的列表项,要么开始一个嵌套列表。
-
一个块属性行在列表上方并不会中断列表,如果它直接邻接前一个列表项的内容(没有空行充当隐式的列表续接)。
-
-
当语言使得区分块元素变得不含糊(例如当遇到中断线时),可以省略空行,尽管强烈建议使用空行来保持块元素之间的分隔。
-
文档的第一行和最后一行在外边缘隐含有一个空行界定。
块和文档元数据、块分隔符和跳过的行
-
并非所有非空行都会对文档的内容有所贡献。
-
一行文本可以为随后的元素提供元数据(一个块属性行)或为文档提供属性条目。
-
一条线可能划定了一个块的边界(尽管并非所有块都有明确的界定符)。
-
如果一行是注释行或位于注释块中,则会跳过这一行。
-
一行代码可能包含预处理指令,用于向源代码中添加或删除行。
-
一些非内容行是中断线,但并非全部都是。
宏观
-
宏在AsciiDoc中类似于函数调用;通常用来创建一个块级或行内元素。
-
有块级宏和行内宏。
-
大多数宏是通过 命名宏形式 输入的:
<name>::?<target>?[<attrlist>?]
。-
在命名的宏形式中,宏名后面跟着一个宏名称分隔符,然后是一个目标,后面是一个带框的属性列表(或带框的内容)。
-
在命名宏形式中,总是需要一个宏名称。
-
宏名称的分隔符是`::`用于块宏,`:`用于行内宏。
-
块宏只能在块上下文中使用;内联宏只能在内联上下文中使用。
-
对于某些宏,目标是可选的或禁止的(例如,
toc::[]
)。 -
对于某些宏,属性列表是可选的或禁止的。
-
对于某些宏来说,attrlist 只是单一的属性值,通常写作
<text>
。 -
宏的框可以是内容(content)、属性列表(attrlist)或者是内容后面跟可选的属性列表(但是键盘(kbd)怎么样呢?)
-
-
一些宏除了具有命名形式外,还有简写形式/符号(例如,
<<target>>
和xref:target[attrlist]
)。 -
一些宏命令使用它们自有的独特形式输入(例如,主题分割宏、自动链接等)。
-
一些语法,例如内联直通和包含或条件指令,可能采用宏的形式,但实际上并不是宏。
转义机制
-
为了防止标记被解释,它可能会被一个反斜线所前置(即,语法规则的开始)。
-
反斜杠会取消紧随其后的标记序列的作用。
-
使用反斜杠可能会导致匹配不同的标记序列;然后必须单独转义该序列。
-
过度转义并无害处;无论文本是否会被解释,前面有反斜杠的保留标记字符都将被移除。
-
要在输出中写入反斜线字符(可能仅在其前面是保留的标记字符时),它必须被写为两个反斜线字符。
-
标记也可以通过将其包含在传递块、内联传递跨度或内联传递宏中来转义。
-
"passthrough"也是一种方法,用于将原始文本原样传递到转换后的输出。
-
#25 应该将哪些标记字符定义为保留字符?我们应该说ASCII字符集中的所有符号/标点都可以被转义,还是仅限于AsciiDoc语法目前使用的ASCII字符?作为参考,CommonMark允许转义所有ASCII标点。这是到目前为止确定的保留标记字符:
反引号 ` 下划线 _ 星号 * 井号 # 波浪号 ~ 尖号 ^ 冒号 : 左方括号 [ 小于号 < 左小括号 (
请注意,通常情况下不需要转义标记元素的关闭括号,这也是为什么这些字符没有在此列为保留字符。
-
#25 对于块级构造,我们是因为它出现在行的开头而解释反斜杠,还是因为它用于转义字符?我认为我们应该考虑因为它用在行的开头。 (我认为这将转化为去除段落开头的反斜杠)。这减少了我们必须指定为保留的标记量。应该考虑以下块级构造:
-
预处理指令(
\include::target[]
) -
块宏(
\image::target[]
) -
列表项(
\*
是一个星号) -
dlist term (
App\:: is a Ruby namespace
) (or should it be\App:: is a Ruby namespace
?) -
标题(
\=
是等号)
-
文档结构
-
AsciiDoc文档是它包含的所有元素的组合。
-
它本质上是一种树形结构(有向无环图),其中每个节点是代表文档一个部分的元素。
-
这个文档模型将解析后的文档表示为一个逻辑树。
-
这棵树中的每个节点都有一个名称,它标识了节点的主要功能(例如,
admonition
)。 -
节点可以按类型分组(例如,
block
或inline
)。 -
节点可能有一个变体来区分其名称的不同变体(例如,
strong
用于span
)。 -
节点可能有一种形式来指示它们在源中的结构/表达方式(例如,
宏
、`无约束`等)。 -
五种概念节点类型
-
块级父元素
-
阻塞终端(元素)
-
内联父元素(元素)
-
内联终端(元素)
-
内联字面量/字符串(自然是一个非元素终端)
-
元素
-
一个*元素*是文档中可以识别、定址和组合的内容块。
-
在一个文档中,元素主要形成了一个从起始边距对齐的、嵌套的元素层次结构。
-
主要有两大类元素组:块级元素和内联元素。
块级元素
-
块级元素构成了文档的主要结构。
-
区块元素会垂直地堆叠,一行一行地位于其他区块元素的上方或下方。
-
在块元素中主要有两种类型的节点:简单/末端块和复合/父块。
-
这些节点类型通过其内容模型进一步描述(例如,simple 可以是逐字的、原始的、常规的/散文的/段落的,或者为空的;compound 可以是章节的或非章节的)。内容模型相当于块内容的语法规则。
-
-
一个*简单的区块*只能包含内联节点(元素和非解释文本)。
-
一个*复合块*只能包含其他块;那些在复合块中的块可以包含内联元素,除非它们自己也是复合块。
-
除了区块标题外,简单区块通过一个空行分隔符与其他区块元素区分开来,但它们可以有中断器(边界)。
-
许多复合块通过界定线与其他块元素区分开来。
-
文档、章节和列表没有界定;所有其他复合块都有明确的界定。
-
-
区块元素可能是隐式的块,例如章节、段落和块宏,也可能是限定的块,例如示例、诗歌和侧边栏。
内联元素
-
一个*内联元素*,是*内联*的一个子集,是简单块中的内容跨度。
-
内联元素包括标记文本(强调、加强等)、内联宏和内联简写。
-
填充在这些元素之间的内容是未经解释的文本和字符引用(非元素)。
-
未解释的文本
-
未解释文本(即纯文本)是指所有内联语法规则都无法匹配的文本(字符数据)。
-
因此,未解释的文本实际上是内联元素(在任何嵌套级别)之间的所有文本。
-
文本可能未被解释,因为它没有使用保留的标记字符,因为它只部分匹配语法规则(只有开启标记而无闭合标记),或者因为它已经被转义或以其他方式被包含在一个透传区域/跨度中。
Part II: 文件、文档元数据和文档属性
文件
-
一个*文档*是根复合块元素。
-
一个文档可以有一个可选的头部和零个或多个块元素。
-
一个空白文档没有块元素也没有头部。
-
所有元素都有一个指向文档对象的引用/属于它。
-
一个文档具有固有的大纲结构,由章节层次构成。
文件类型
-
文档类型(简称doctype)决定了允许和/或要求使用哪些块级元素,以及它们允许出现的顺序。
-
有三种内置文档类型:文章(article)、书籍(book)、手册页(manpage)。
-
默认的文档类型是文章。
-
书籍文档类型涵盖有部件和无部件的书籍;有部件的书籍称为多部分书籍。
文档头部
-
一个*文档头*可能包含文档标题、作者和修订线,元数据(来自块属性行)、文档属性条目和注释行,所有这些都是可选的。
文档头部结构
-
文档头部只接受一些 AsciiDoc 语法,比如隐式元数据行、属性条目和注释行。
-
文档标题不得包含中断线。
-
文档头部可以包含空行吗?如果可以,什么定义了文档头部的结束?
-
-
文档标题行是可选的,但使用隐含的作者和修订行(即,作者信息和修订信息行)时是必需的。
文档标题(亦称为 doctitle)
-
一级标题。
-
由于文档头必须位于文档的开始,我们可以推断出文档标题是文档的第一个0级标题。
-
可能位于任意数量的属性条目和注释行的上方、下方或中间位置。
-
必须直接位于隐式元数据行之前。
隐式元数据行
-
作者行
-
考虑到国际化,制定作者名称的州指南。
-
有些名称形式可能无法通过作者行识别,在这种情况下,需要显式设置属性。
-
-
修订行;必须在作者行之后(因此需要有作者行)。
-
这些元数据可以使用属性条目显式定义;隐式行只是一种简写形式。
文档属性
-
文档属性是实体(在XML词汇中),全局选项,和文档元数据。
-
它们在文档的头部或正文中通过属性条目被设置,并且可以选择性地赋予一个值或者取消设置。
-
它们也可以通过其API使用名为`attributes`的选项传递给处理器。
-
如果文档上设置了一个属性,那么它的值是非空(非未定义)的。
-
如果一个属性未设置,那么它是不存在的。
-
一个属性不能被设置为null/undefined值。
-
当在文档头部设置时,该属性被称为文档头部属性。
属性条目
-
一个属性条目的格式为
:<key-name>: <value>?
或者:!<key-name>:
。 -
每个属性条目必须单独输入在自己的一行上。
-
我们应该取消属性名称的规范化(即允许属性名称具有混合字母大小写)吗?(这意味着名称将不再被翻译/在属性定义中自动转换从"短语"到名称。)
-
在属性条目中,我们应该禁止属性名中出现空格吗?(并且移除自动翻译吗?)
-
通常,我们需要定义什么是有效的属性名称;如果名称有效,属性条目才被识别吗?
-
-
我们应该允许在限定的块内设置文档属性吗?
-
我们应该停止使用`{set:...}`吗?
-
FI 我们应该选择
\
还是+
作为继续属性值的字符?-
我们应该在属性条目的值中保留换行符吗?我们能否说``折叠/消费了换行符,而`+`则保留它;这样,
+ +
会是快速进行强制换行的方法吗?
-
-
在解析文档中,当访问其前面的节点时,必须能够获取在body中设置的文档属性值。
-
属性条目不能与块元数据行交错。
属性覆盖和优先级
-
硬与软(取消)设置。
-
只能在传递给处理器的属性上定义;不能在文档内的属性条目中定义。
-
-
属性条目可以用来重新定义文档属性。
-
如果文档属性已被锁定,则无法重新定义。
-
-
通过API设置或取消设置一个文档属性(或者通过相关的CLI)来锁定它。
-
通过在属性名称(或值,尽管推荐使用名称)后附加`@`来进行设置或取消设置,可以在不锁定属性的情况下(软性设置/取消设置)通过API对其进行操作。
-
通过API设置的属性可以有值`false`或`null`(或等效于编程语言的值,例如`nil`或`undefined`)。
-
值`false`表示要在文档上软解除属性的设置。
-
值
null
表示要在文档上硬性取消设置该属性。
-
内置属性
-
内置文档属性用于添加、配置和控制文档中的常见功能(例如,目录
toc
)。 -
提供一种填充文档元数据的方法(例如,
author
)。 -
许多内置属性只有在文档头部定义时才会生效(可以通过属性条目定义或通过API传入)。
-
一些内置的文档属性是布尔值。这些属性的作用就像一个开关,它们唯一的功能是打开或关闭一个功能。
-
如果一个布尔属性被定义了,但是没有赋予一个值(即,被设置了),它处于“开”状态。当被设置时,一个布尔属性通常是空值。
-
如果布尔属性没有定义(即,没有设置),它处于“关闭”状态。
-
我们应该将布尔文档属性类型值
true
标准化为设定值(作为空字符串的替代)吗?
-
-
我们应该将`experimental`属性作为内置属性去除,还是保留它作为实验特性的标志?(请注意,将UI宏提升为完全支持是一个单独的决定)。
命名规范
-
保留属性名称;不得用于用户定义的上下文(可重用文本或条件语句)。
-
定义内置属性的命名约定。
-
识别保留和推荐的前缀。
全局块属性和选项
用户定义的属性
-
用户定义的文档属性是指用户或扩展程序设置的任何属性,只要这些属性不是由AsciiDoc语言或扩展程序预留的。
-
这些属性允许用户定义命名的、可重用的内容,或者作为预处理器条件或扩展的开关。
命名规范
-
用户定义的属性名必须至少有一个字符长,必须以字母、数字或下划线开头,其后可以包含任意数量的字母、数字、下划线或连字符。
-
属性名称应该只包含小写字母,尽管也允许使用大写字符。
属性使用
-
文档属性可以通过属性引用在文档内容中使用。
-
属性引用是内联预处理器识别的标记。
-
请参阅属性引用了解详情。
Part III: 积木
文档正文
-
文档主体包含了除文档头部以外的所有内容。
-
文档主体被分割成多个块。
块结构和变体
-
一个*块级元素*,称为一个*块*,是文档结构中按行划分的独立元素。
-
一个块总是以整行开始和结束(从一行的开始或有效开始处开始,并在同一行或不同行的结尾处结束)。
-
一个块可能有两到三个源特征:元数据、主体和封闭结构。
-
一个块的父元素总是另一个块(如果嵌套了,那就是父块;如果没有嵌套,那就是父节或者文档,假如不在节中的话)。
-
块的主体可能有一个由分隔线形成的封闭结构。
-
一个区块的内容模型(例如:
simple
、compound
、verbatim
)决定了该区块可以包含哪些内容(如果有的话)以及如何解析这些内容。 -
一个区块的名称和可选的样式修饰符决定了它的转换方式。
-
区块元素的解析优先于行内元素解析。例如,行内直通无法包含将结束该区块的行,比如区块分隔符或列表延续。先确定区块边界,然后在这些边界内进行行内解析。(问题:这是否意味着在行内直通中不能使用反斜杠转义?)
-
语法应该按照它在文档中出现的顺序进行解析(这可能需要更具体地定义,或者列出例外情况)。
模块名称
-
每个块都有一个名字(例如,图片、侧边栏等)。
-
名称标识了元素的主要专业化。
-
每个名称都与一个单一的内容模型相链接。
-
每个块名都提供了其他块名未涵盖的语义。
-
区块名称可能是隐式的或显式的。
-
如果没有指定块名称,它将通过其源形式推断出来(例如,块分隔符、标记、隐含边界)。
区块元数据
-
'''块元数据是包含块属性的块的属性的超集;元数据包括ID、标题和样式等特殊属性;还包括名称等。'''
-
所有块都容纳零个或多个明确的元数据行,这些行直接堆叠在块内容的顶部,如果适用,也包括开头的定界符行。
-
可选的元数据行包括:零个或多个块属性行(用于填充块的属性)、块 attrlist(在块属性行内部)、块属性,以及可选的块标题行(许多块还支持相应的标题)。
-
SDR 确认我们用来指代原始形式与解析形式的属性列表的术语及其定义。(attrlist, boxed attrlist, attributes)
-
-
共享的(但可选的)块属性包括:id、style、角色集、选项集、标题、参考文本以及data-属性。
区块属性
-
用于存储块元数据。
-
可以是位置参数或者命名参数。
-
位置属性使用基于1的索引;索引赋值会跳过任何具名属性(即,具名属性不影响位置)。
-
仅可直接在块上使用。
-
不要影响文档属性。
-
区块属性与文档属性之间唯一的关系是,有时会使用文档属性作为缺失区块属性的备选项(这需要进一步明确/规范)。
-
区块选项是以
-option
结尾的区块属性;因此,-option
是一个保留后缀。 -
FI 提议/确认所有以
data-
开头的区块属性应该被传递到输出格式;在HTML输出中,这些属性与相应标签上的HTML数据属性一一对应。 -
提出一个语法建议,用于取消设置块属性,包括块选项(例如,
[!id]
、[%!header]
或[%noheader]
)。 -
建议使用
+[[id,reftext]style.role]+`作为统一块属性行和块锚点行的方式,其中
+[id,reftext]+`必须放在前面(或后面?)。 -
FI 建议不应将无效的块锚点视为段落文本(仍作为块锚点消费,只是不设置ID)?
区块标题
-
区块标题是一个区块的卫星。
-
它与块有一些共同点,比如它可以单独定义在自己的行上,并且可以有内嵌内容;然而,它是块的一个从属部分。
-
如果没有指定reftext,块标题是块的隐含引用文本。
-
区块标题可能会根据区块名称/出版惯例显示在主要内容的上方或下方。
-
在某些情况下,当块标题充当标题时,它会以相应标题属性(例如,
example-caption
)的值和一个自动生成的编号为前缀。-
SDR 标题在AsciiDoc中定义不清。通过分解标题的所有部分并在适当的上下文中使用它们来修正术语。
-
<block>-caption`并不直接对应一个典型的标题,因此它阻碍了自定义标题各个部分的努力,例如标题的标识符、参考编号/字母和分隔符。
-
标题 = 引用标志 + 引用数字/字母 + ": " + 标题, 其中引用标志 + 引用数字 + ": " 是前缀。
-
我们避免使用术语label,因为在其他出版系统中label是用来指元素的ID的。
-
-
FI 提议将
-caption
属性重命名和重新映射为-caption-signifier
?(例如,example-caption-signifier
)。 -
提议能够自定义参考文献编号/字母与标题之间的分隔符吗?
-
FI 提议能按章节对资源进行编号吗?
-
隐式块
-
隐式块 是指没有明确边界的块,不同于有边界的块。一个隐式块在遇到中断线时结束,例如另一个隐式块的开始、有边界块的开头或结尾行,或空行。
-
隐性区块包括部分(sections)、独立标题(discrete headings)、段落(paragraphs)、文字段落(literal paragraphs)、简单告诫(simple admonitions)、简单引用(simple blockquotes)、区块宏(block macros)、列表/列表项(lists / list items)以及文档本身。
-
块元数据行也有隐式边界(单行),但它们本身不是块。
分隔块 / 结构容器
-
一个*界定块*是一个复合块,由称为分界线的明确边界所界定。
-
一个定界块只有在与开始该块的定界线相同的层级再次找到时才会结束(与创建嵌套块相反)。
-
限定块必须是平衡的;如果有一个开始定界符行,就必须有一个相应的结束定界符行;否则,处理器必须发出警告。
-
分隔块创建了新的解析上下文(当前块必须在结束祖先块之前结束)。
-
如果子块是一个定界块,它将开始一个新的定界块解析上下文;当子定界块结束时,先前的定界块解析上下文将被恢复。
-
说明限定块的嵌套规则和限制。
-
-
被定界的块不得包含节。定界块包括:示例、列表、文字、源码、STEM、引用、诗歌和表格块。
-
提议在一个限定的区块中的任何标题隐式转换为独立标题。
打断线路
-
对于没有明确边界的块级元素(例如,一个限定的块),当遇到中断线时块将会结束。
-
哪些行会中断一个代码块取决于上下文。
-
一个空行(在所有预处理器指令计算之后仍然保留的)总是结束一个隐式块(例如,段落、列表等)。
-
一个块属性行总是结束一个隐式块(除非是连续的相邻块属性行之后)。
-
一个结束块定界符可以打断任何非定界的块。
-
开放块界定符行正在中断。
-
我们是否应该说,只有一个结束块的定界符行是中断的,换句话说,必须位于该块内部?
-
-
列表续行会结束一个隐式块,但不会结束列表;相反,它会将接下来的块附加到列表项中。
-
列表中的文字段落由一个隐式的列表继续行开始。
-
-
在一个列表中,列表项是一个中断线;根据标记的不同,要么开始一个新的列表项,要么开始一个嵌套列表。
区块宏
-
一个块宏在源码中单独占一行输入,并在输出中单独显示一行。
-
它不包含内容(即内联元素),只有元数据。
-
它总是被解析。
-
大多数块宏遵循命名块宏的形式,
name::<target>?[<attrlist>?]
,除了分页和主题分隔符之外。 -
大多数块宏可以有块元数据行。
-
区块宏包括:图片,视频,音频,目录,分页符,以及主题分隔线。
-
块宏的目标不能以空格开头,以便将其与定义列表项的开始区分开来。
章节
-
一个*section block*(章节块),被称为*section*(章节),是一个由atx风格的标题标记(
=+
)表示的复合块元素,并且没有独立的样式。 -
该部分包括从节标题行之后所有的内容,直到下一个同级或父级节标题或文档边界。
-
一节的标题行之前必须有一个空行,其后可以选择性地跟随块元数据。
-
章节标题标记用于指定章节的层次级别(级别0(
=
)- 级别n)。-
无法跳过章节层级,因为在某些输出格式中,层级是由层次结构决定的。
-
FI 我们是否应该允许节的层级数目是无限的?这将取决于转换器对于它无法管理的层级进行规范化处理。
-
使用aria元数据可能会解决我们的HTML问题:https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/heading_role。
-
也可以考虑使用嵌套的`<section>`标签和`<title>`,一旦它超过h6。
-
-
在节标题标记后面允许有多于一个空格吗?
-
-
相邻段落行中的节标记未被识别(标题不是中断线)。
-
章节标题是一个块标题(一个包含内联元素的单行)。
-
如果文档中的第一个块是级别为0的部分,那么它被指定为文档的标题/头部。
-
只有 book 文档类型允许在文档主体中使用 level-0 节。
-
我们应该使用基于1的级别进行分节吗?
-
节不允许存在于非节区块中。
-
提议一种创建匿名节(即一个没有可见标题的节)的语法。也许可以使用`== <<<` 或
== !
,甚至是>>>
(尽管这并不设定层级)。 -
我们应该标准化使用
%notitle
选项来隐藏一个章节标题吗?
章节编号
-
部分标题和独立标题的ID是自动生成的。
-
ID是由解析标题中所有内联节点的文本值连接生成的。
-
内联宏应该如何处理;例如,是否会考虑图片的替代文本?
-
随后会移除无效字符。
-
空格会被替换为`idseparator`属性的值,默认为`_`。
-
ID前缀是由`idprefix`属性的值决定的,默认为`_`。
-
如果生成的ID已经在文档中被使用,那么会追加一个计数,该计数由`idseparator`属性的值偏移,直到找到一个唯一的ID。
-
-
通过取消设置内置的`sectids`属性,可以关闭对节标题和独立标题的ID生成。
-
处理器应该允许将ID生成例程替换为用户代码。
-
是否允许使用内联锚点来设置章节的ID?如果可以,它可以位于开头、结尾,还是两者都可以?使用内联锚点给章节分配多个/替代的ID是否可行?
Note
|
我们养成修改idprefix和idseparator习惯的原因之一是因为GitHub为标题使用了自己的ID。然而,通过让处理器重写xrefs目标以匹配输出中将会生成的ID,可以避免这个问题。另一个需要考虑的是是否应该更改默认的`idprefix`和`idseparator`,尽管这将构成一个重大的不兼容变更。 |
章节编号
-
标志符属性(例如,
part-signifier
)控制特定部分类型前面的数字的标志符。-
参见 signifier FI。
-
-
ASG很可能需要一个属性来表示章节号,以便验证它是否正确。
特别章节
-
内置的用于专门前言和后记部分的样式被称为*特殊部分*。
-
文件类型决定了哪些节样式可供使用。
-
请注意,"部分"和"章节"是由文档中部分的位置暗示的,因此不是特殊的章节。
-
FI 提议在文档类型为书籍时,为每个书籍部分添加作者属性;可能每章都添加?
-
对于每个特殊章节 + 文档类型
如果部分存在,都有一些复杂的章节级别要求(例如,为什么术语表在文档类型为文章或没有任何书籍部分时必须是一级章节,它为什么不能是二级章节?)
-
摘要(成为一章)
-
后记
-
奉献
-
致谢
-
前言
-
partintro(必须是part的第一个子元素)
-
附录
-
词汇表
-
当一个部分被标记为术语表时,
glossary
块样式必须设置在定义列表上吗?(这并不意味着我们想要弃用glossary
块样式,我们只是想让事情更加简洁)。
-
-
参考文献
-
指数
-
摘要
-
建议将文章中的摘要标题定义为一个特殊部分,就像前言一样?
-
-
附录
-
词汇表
-
参考文献
-
指数
内在目录表
-
目录(TOC)是AsciiDoc文档中章节标题的索引。
-
目录是文档大纲的子集;包括所有部分(部件、章节、常规节以及特别节)。
-
当启用
toc
文档属性时,AsciiDoc 处理器会根据文档的结构自动生成目录(TOC)并将其插入到输出文档中。 -
目录的位置、显示的层级、标题和CSS类名可以通过文档属性进行控制。
Note
|
目录(TOC)必须在抽象语法树(ASG)中表示出来,以便我们能正确验证处理器是否已准确识别条目、它们的标题,并按指定的层数填充它们。 |
序言
-
文档头部结束到文档主体中第一个节标题之间的内容是前言。
-
FI 澄清前言的边界规则以及其解析方式。
-
Q(可能属于FI):澄清序言是否实际上是一个无标题的部分或是一种块状样式?它是否只在文档类型为文章时出现,还是在文档类型为书籍但没有部分时出现?如果有部分,它会出现吗?(只在书的标题之后,每个部分在部分标题和下一个章节标题之间的内容如果这些内容没有明确指定为`partintro`,它会出现吗?)
段落
-
一个*段落*是一个简单的,隐式的块,由一组连续的(非空)行组成,这些行可以包含内联元素和未解释的文本。
-
段落是AsciiDoc中的基础结构。
-
除了节和块标题外,所有非逐字的叶子块元素都是段落。
-
如果一行文字没有被识别为特定元素,它就被当作一个段落。
-
未识别的语法或不允许在段落内使用的语法将被当作普通文本处理(不会被删除)。
-
为了解析段落中的内联标记,首先必须识别出段落中的所有行(因为内联标记可以跨越多行)。
样式化的段落
-
一个段落可能拥有一个块级样式(例如,示例、引用等)。
-
段落上的样式不会影响块解析模型,即如何匹配结构化形式。相反,块解析是通过测试各种结构化形式(例如,段落、缩进线、结构容器等)的语法规则来寻找匹配的。
-
那么样式会影响匹配语法规则的结果(AST节点)如何被解释和转换为ASG中的一个节点。
-
与该块关联的任何元数据都将被提升到合成封闭块中,可能有一些例外,例如`hardbreaks`选项。
-
某些选项,例如`hardbreaks`,是否是此规则的例外,或者段落会取走它们或复制它们的角色?
-
-
-
编写规格说明时的详细信息,请参见 #31,以及由此产生的SDR-3: Reframe Block Style as Parsing Transformation]。
文字段落
-
一个直白的段落是一个以至少一个空格字符(空格,制表符)开始,后跟至少一个非空格字符的块。
-
文字段落中的所有行都必须至少缩进一个空格字符;第一行不缩进(它是左对齐的或空的)则结束文字段落。
-
文字段落会创建一个字面块元素。
-
列表项中的文字段落从一个隐含的列表续行开始(尽管它仍然可以使用一个续行符号来连接)。
离散标题
-
通常,块解析器在不考虑任何块元数据的情况下识别块及其边界。这个规则的唯一例外是标题上的离散样式。
-
离散样式导致标题被解析为叶块,而不是父块。
-
这个例外是必要的,因为章节和离散标题具有相同的结构形式,但只有章节被允许有子内容。
-
-
提议在一个限定的区块中的任何标题隐式转换为独立标题。
-
我们应该允许使用`[heading]
来代替非小节标题的
[discrete]`吗? -
术语"float"或"floating"不应用于标记或描述离散的标题语法,因为这些术语在AsciiDoc语法中已有保留的含义(它们指的是某些输出格式中元素的布局/定位)。
列表
-
一个*列表*是一个复合隐式块,包含一个或多个列表项。
-
列表的开始是由第一个列表项定义的。
-
列表可以嵌套到任意深度,并且可以是混合的列表类型。
-
支持的列表类型包括:无序列表、清单(无序列表的变体)、有序列表和标注。
-
一个*列表项*是一个由列表标记引发的复合隐式块。
-
列表标记包括
*
(无序),.
(有序),[1-9].
(有序),-
(无序),以及<([1-9][0-9]|\.)>
(标注)-
*` 和
.
列表标记可以无限重复。(`-`标记呢?)
-
-
列表标记(项目符号)或编号是通过列表样式控制的。
-
列表标记可能会被缩进。
-
我们是否要强制第一级标记不能缩进(即,我们是否应该要求顶级列表与左边(开始)边距对齐)?
-
已折行的文本可能会有缩进,但是这种缩进在处理时将会归一化为等同于单个空格的语义。
-
-
列表项优先于描述列表项(即发现描述列表术语)。
-
一个列表项可以有一个框定的属性列表。
-
一个框架属性列表必须从列表标记之后开始,且该行不能有其他内容。
-
-
列表的末尾由一个中断线定义。
-
使用列表继续可以避免列表的中断,它将相邻的块附加到列表项上。
列表解剖
列表标记和深度
-
列表标记后面允许有多个空格吗?
主文本
-
在列表项的主文本中,我们可以有一个块属性行来为列表项分配属性吗?
-
一个列表项可以有多个连续的元数据行吗,还是应该将列表项限制为一行块属性?
组合列表
列表续接
-
应该对样式化段落(例如,段落上的`[NOTE]
或
[example]`)使用续行符来打断列表吗?Asciidoctor和AsciiDoc Python在这条规则的实现上有所不同。 -
FI 我们是否应该在分隔块直接紧邻主文本时推断列表项的延续?
列出亲和性/边界
无序列表
支持的样式
-
SDR 澄清我们使用的术语:“子弹”、“标记”、“输出标志”,还是其他什么?
清单
-
无序列表的一种特殊形式。(那有序列表呢?)
-
如果无序列表中至少有一个项目是清单项,则会隐式创建。
-
清单项目被识别的条件是主文本以投票框开头,
[ ]
(未选中),[x]
(已选中)或`[*]`(已选中)。
有序列表
自动编号
支持的样式
呼叫列表
与呼叫号码的关系
描述列表
-
一种描述列表(dlist)类似于一个列表,但是它的列表项有一个根本不同的结构。
-
一个*描述列表*是一种复合隐式块,其中包含一个或多个列表项。
-
描述列表可以嵌套到任何深度,并与其他列表类型混合使用。
-
描述列表的开始由第一个列表项定义。
-
一个*描述列表项*由一个或多个术语和一个描述组成。
-
列表继续的工作方式对于附加块和列表是相同的。
术语"任何列表"指的是列表和描述列表的超集。这一点之所以会出现,是因为在解析过程中,列表和描述列表有很多相同的行为。当我们说“列表”或“标准列表”时,我们并不是指描述列表。
描述列表结构
术语、分隔符和深度
-
列表项的启动至少需要有一个术语后面跟一个定义列表标记(也称为术语分隔符)。
-
一个术语也被称作主题。
-
一个条目可以包含多个术语。
-
定义列表的标记符包括
::
,:::
,::::
, 和;;
。 -
条款可以缩进。
-
FI 我们是否应该放弃分号作为标记,并使定义列表的标记一致(
::
、:::
、::::
、:::::
)(不使用`;;`)? -
我们应该允许dlist项目嵌套到任意深度吗?
主文本
-
紧跟在术语之后的文本,无论是同一行上还是相邻的下一行。
-
定义列表项的主要文本可以从下一行开始,不同于标准列表。
描述
方向
-
FI 需要指定dlist的`水平`方向吗?也许它应该是一个属性或选项,比如`orientation=horizontal`或者`%horizontal`。将水平作为一个选项(
%horizontal
)而不是一种风格看起来可能更适合模型;这样它就可以像`glossary`这样的真正风格那样使用。
用记号笔
问与答
桌子
-
一张表格是一个由界定符区分的复合块,它包含一个或多个单元格。
格式 (psv, dsv, csv)
-
定界符分隔值
-
psv` = 竖线分隔值;
csv
= 逗号分隔值(或者制表符分隔值);dsv
= 数据分隔值-
我们能否且是否应该停止使用`dsv`表数据格式?
-
-
每种格式都有一些不同的解析规则/约束。
-
FI 明确并细化表格的解析方式(以便行注释能够根据其封闭上下文进行处理,例如在AsciiDoc表格单元格中的逐字块内或在CSV/DSV数据内部)。
-
默认格式是`psv`。
-
格式可以通过使用`format`属性或使用专用的块定界符(
,===`和
:===`)来指定。 -
csv``` 主要用于包含来自 CSV 文件的数据,而不是用于在 AsciiDoc 文档中编写;基本上是基于 RFC 4180 标准。
基于细胞的结构
-
单元格排列和定界符
-
细胞被发现后根据列数分布到各行中。
-
-
解释细胞是如何组织成行和列的
-
从技术上讲,不需要换行符;只有单元格分隔符才是界限;但是有些功能需要使用换行符。
-
分隔符的优先级以及如何转义它
-
单元格分隔符可以通过separator属性自定义;必须是一个字符。
-
头部(Header)/主体(Body)/尾部(Footer)
-
SDR 请澄清是指“表头”还是“标题”; “表尾”还是“底部”。
-
-
列是如何被隐式确定的?
-
头部是如何隐式确定的?
-
描述如果单元格数量与预期的单元格数量不匹配会发生什么情况
列和列规格
-
columns属性可以指定有多少列
-
如果是数字类型,则使用默认的列规格。
-
columns属性可以为每一列指定列规范;列规范之间用逗号或分号分隔。
-
colspec 控制每列的样式、对齐方式和宽度比例。
-
colspec的所有部分都是可选的
-
宽度可以被指定为自动
-
colspec可以有重复器(用于指定多次的简写)
-
FI 阐明表格中colspan与colspecs之间的关系;当存在一个colspan时,colspec条目应如何映射?
细胞
内容模型
-
单元格的内容模型是一个段落(叶子节点,不包含块级内容)
-
AsciiDoc 表格单元格将单元格内容模型更改为复合块;仅在 psv 格式中支持。
-
AsciiDoc表格单元格本质上是一个独立的文档(需要澄清这种关系)。
-
只有AsciiDoc表格单元格可以容纳嵌套表格
-
AsciiDoc单元格样式(例如,
a|
)需要标记在单元格本身上才能完全遵守预处理器的语义吗;换句话说,当标记在列规范上时,它将被解析为普通单元格,然后提升为AsciiDoc表格单元格;因此,行为可能会有所不同。
风格
-
默认(d),强调(s),重点(e),等宽字体(m),字面(l),asciidoc(a)
细胞规格
-
在PSV中,cellspec直接指定在单元格分隔符前面。
-
默认情况下,单元格从列继承属性
-
cellspec可以在单元格上指定,以覆盖大多数继承的属性;仅在psv中支持。
-
colspec 控制样式、对齐、跨度(行和列)(不能改变宽度)
-
我们应该丢弃手机复制吗?
元数据 / 属性(建议的)
-
在psv中,一个单元格可以有一个框起来的属性列表(单元格元数据)。
-
被框起来的属性列表必须直接开始于单元格的分隔符之后,在单元格的该行中不得有其他任何内容。
-
一个单元格应该能担任一个角色吗?
-
一个单元格能有多个连续的元数据行吗?
-
FI 我们应该允许一行拥有一个带边框的attrlist吗?
-
一行应该能够有一个角色吗?
表格宽度和列比率
-
默认情况下,列宽将根据列上的比率值分布在整个页面(100%)上。
-
通过指定宽度属性可以减少表格的宽度;值是一个百分比(最大值为100%)。
-
在表格中添加`autowidth`选项可以使内容决定表格的宽度(适应内容)。
-
如果没有指定比例,宽度将均匀分布
-
列宽只是一个提示;内容可以调整宽度的分配(我们可以建议使用固定的表格布局来强制执行)
-
如果指定列为自动宽度,则其宽度将完全由内容决定(没有分配的宽度)。
-
通过设置自动宽度选项和拉伸角色,表格将扩展至页面的宽度,但列的宽度将由内容决定。
-
一个宽度小于100%的表格可以通过使用float属性配置为向左或向右浮动。
装饰(框架,网格,条纹)
-
桌面装饰可以使用`frame`、`grid`和`stripes`属性来控制。
-
默认情况下,一个表格会有全部的边框和网格线(所有边界)。
-
frame` 值:全部,两端,侧边,无
-
grid` 值:全部,行,列,无
-
stripes` 值:none(无)、even(偶数)、odd(奇数)、all(全部)、hover(悬停,适用于支持此交互的情况)
-
这些属性可以通过使用带有前缀 table- 的文档属性实现全局控制(例如,
table-stripes
)。
方向
-
表格可以通过添加`rotate`选项来旋转(如果支持的话)。
-
可以通过使用`orientation`属性来明确指定表格的方向(纵向或横向)。
嵌套表格
-
一个表格可以嵌套在父表格的单元格中
-
仅支持一级嵌套。
-
父级单元格必须具有
a
表格样式(AsciiDoc) -
嵌套表格必须使用分隔线
!===
以及不同的单元格分隔符(默认为!
)。 -
AsciiDoc表格单元的所有规则在这里都适用。
警告
-
====` 块分隔符
-
从下列列表中选择所需的块样式:
NOTE
、TIP
、WARNING
、CAUTION
、`IMPORTANT-
FI 提议只允许在冒号后使用空格,而不是制表符,来分隔警告名称和文本。
-
-
内容模型:复合
例子
-
====` 块分隔符
-
没有样式
-
内容模型:复合
侧边栏
-
****` 块分隔符
-
没有样式
-
内容模型:复合
引用和诗句
-
____
`
块定界符 -
引用:无样式或`引用`样式
-
节:
verse
风格 -
题词:`题词`风格
-
内容模型:引用为复合类型,诗歌和墓志铭为简单类型
-
我们能否使用诗歌块来创建一个地址元素?
-
提议将citetitle重命名为citation或仅仅是cite?
代码(清单,来源,字面)
-
----
(列表/源代码)或 `....
(文本)块分隔符 -
清单:如果未设置`source-language`文档属性,则为`listing`样式或无样式。
-
来源:如果设置了`source-language`文档属性,则为`source`样式,否则没有样式。
-
字面意思:无风格
-
如果使用替代的块分隔符,则必须指定样式。
-
当启用图表集成时,文字块打算用于图表源。
-
如果块是空的,内容应该是空字符串(不是null)
-
内容模型:逐字
科技、工程、数学
-
++++
`
块分隔符 -
如果设置了`stem`文档属性并且有值,则使用`stem`风格;否则使用`latexmath`或`asciimath`。
-
如果块是空的,内容应该是空字符串(不是null)
-
内容模型:通过,需要根据STEM适配器的要求进行一些处理
打开
-
~~~~` 或
--
(传统)块定界符。 -
无法伪装成另一个内置块。
-
样式可用于创建自定义块。
-
内容模型:复合
可折叠
-
====
` 块定界符或
>===``
(建议)作为块定界符 -
collapsible`或`disclosure`样式(提议的)或`%collapsible`选项(遗留的)
-
FI 建议将`collapsible`设为示例块的一种样式。
-
-
内容模型:复合
图像宏(块)
-
块图像宏将图片和图形插入到文档中。
-
使用命名块宏形式`image::<target>[<attrlist>?]`来构建。
-
所需的宏名称是`image`。
-
需要一个目标。
-
目标可以是相对路径、绝对路径或URL(使用默认资源解析器时)。
-
目标可能包含空格字符;这些字符在HTML输出中被URL编码(
%20
)。 -
目标的解释取决于处理器设置和/或输出格式。
-
如果转换器生成的输出引用了图像,该路径必须与发布文档相关联。
-
如果转换器在输出文档中嵌入了图像(例如,设置了`data-uri`,直接转换为PDF),目标必须在转换时可以解析;在这种情况下,如果处理器的安全设置允许(例如,
allow-uri-read
),则只会解析URL。
-
-
-
框内的attrlist可以为空或指定一个逗号分隔的可选属性列表。
可选属性
-
alt`(第一个位置)
-
width`(第二个位置)
-
height`(第三个位置)
-
链接
-
fallback`;值:相对于`imagesdir`的路径,绝对路径或URL
-
目标必须是SVG并且`opts=interactive
-
-
格式
-
只有当目标不以文件扩展名结尾或无法通过其他方式检测时才必要。
-
-
标题
-
window`; values: `_blank
-
scale`(仅限DocBook)
-
scaledwidth`(仅限DocBook和PDF)
-
pdfwidth` (仅适用于PDF)
-
align` 对齐方式;可选值:左、中、右
-
float`;值:左,右
-
内置的`role`值:左,右,表头,缩略图,相关,关联
-
内置的`opts`值:none(无),nofollow(不跟随),noopener(无来源),inline(仅限SVG),interactive(仅限SVG)
可选标题和说明标签
-
可选的区块标题会以标题标识*Figure*作前缀,并自动编号。
-
标签由`figure-caption`文档属性或各个块级别的`caption`控制。
-
参见 signifier FI。
-
视频宏
-
使用命名块宏形式
video::<target>[<attrlist>?]
构建。-
必需的宏名称是`video`。
-
需要一个目标。
-
目标可以是视频服务的一个ID。
-
可选属性
音频宏
-
使用命名块宏格式
audio::<target>[<attrlist>?]
构建。-
所需的宏名称是`audio`。
-
需要一个目标。
-
目标可以是音频服务的一个ID。
-
可选属性
目录宏
-
在宏的位置插入内置目录。
-
采用正式的块宏形式
toc::[]
来构建。-
必须的宏名称是
toc
。 -
禁止使用目标和属性。
-
分页宏
-
分页符宏不是使用正式的块宏形式指定的,而是用三个小于号字符(
<<<
)来指定。 -
宏必须至少用一个空行与前后的块相隔开。
-
它为面向页面的/可打印输出格式(如DocBook、PDF和打印模式下的HTML)插入一个分页符。
-
如果宏在空白页面的顶部,它将被忽略;这种行为可以通过在块属性行中为宏设置`always`选项来覆盖。
-
一些转换器支持在页面分隔宏上额外的选项。
主题分隔宏
-
主题分隔宏不是使用正式的块宏形式来指定的,而是通过三个单引号(
'''
)来指定。 -
宏必须至少用一个空行与前后的块相隔开。
-
它在输出中插入了一个主题分隔线(水平规则)。
直通 (或者 传递)
-
++++
`
块分隔符 -
内容模型:通过
-
标记原始内容,该内容应按原样传递到输出(或由转换器解释为原始代码)
-
一个穿透块是一个逃生舱口,用于离开AsciiDoc语法并嵌入不会被其他方式解释的内容。
-
可能被块扩展使用来解析或以不同方式理解内容(例如嵌入的Markdown或LaTeX)。
-
通透应谨慎使用,因为它们可能会损害AsciiDoc文档的可移植性。
-
类似于SVG中的foreignObject。
Part IV: 内联-elements
内联结构
-
常规文本(例如一个段落)可能包含被解释的标记。
-
标记是添加到内容中的额外字符,旨在添加语义或指定格式;这些字符是处理器的提示。
-
标记是以标记文本、宏或查找引用的形式存在的。
-
当普通文本被解释时,它会产生一组节点(即`node*`),被称为“内联节点”或简称“内联”。
-
这可以是一个嵌套结构(一些内联元素可能包含其他内联元素)。
-
-
内联解析可以分为四个一般类别:文本、跨度(强调、着重等)、宏(外推内容)和替换(属性引用、排版替换、特殊字符、硬换行符)。
-
解析器将尝试匹配指定的内联语法,例如一对跨度/格式化标记。
-
如果语法匹配失败(例如,当解析器遇到不平衡的标记时),解析器将继续匹配下一个规则。
-
如果在一串字符中没有任何语法规则可以匹配,那么这些文本会被当作普通的、未解释的文本处理;处理器不会发出任何警告。
内联名称
-
内联节点有两种类型:内联和字符串。
-
有几种内联名称:文本,字符引用,原始数据,跨度(或标记),引用,图像等。
-
该变体进一步专门化了名称:对于span来说是strong,对于ref来说是xref,等等。
-
内联代码可能还有一种形式来指示它在源代码中是如何构建/表达的(例如,宏,非限制性的等等)。
-
一个非元素表示普通文本,例如文本、字符引用、原始文本、硬换行符。
-
内联元素是具有属性的内联节点。
-
内联元素可以是叶子节点(例如,图像)或非叶子节点(例如,span)。
-
非叶子内联元素包含内联元素。
-
-
Span是“标记的连续运行”;具体来说,它是被封闭/界定的文本(我们正在逐渐不使用“引用文本”这个术语)。
-
在语法中,我们可能将其称为标记文本;在节点模型中,这是一个跨度。
-
-
Span和macro是元素,这意味着它们可以有属性,并且在许多情况下可以包含内联元素(子元素)。
-
文本属性:类型=字符串,名称=文本,值
-
span的常见属性:类型=内联,名称,变体,(来源)形式,属性(包括id和角色)
-
宏的常见属性包括:类型=内联,名称,(来源)形式,属性(包括ID和角色)。
-
将使用非命名语法表达的宏引用为速记宏(或速记符号);它仍然是一个宏,只是没有那样表达。
-
-
所有格式化的文本是一个跨度(span); 但并不是所有的跨度都是格式化文本。
-
不强制要求一种打字系统,但处理器/转换器必须能够区分不同内联内容的上下文。
从替换到内联解析
-
AsciiDoc语言最棘手的方面之一是它依赖搜索和替换来处理内联元素。
-
这种原始的内联处理方法不会产生一个树结构,而且解释通常与输出格式以及替换顺序紧密相关且彼此交织。
-
它不仅会导致许多意料之外的行为,无法进行准确描述;它还使得无法从文档中提取出结构以及它存储的信息。
-
该规范从使用替代法过渡到内联解析语法。
-
在这样做的过程中,我们的目标是尽可能地匹配替代模型的行为,以便现存内容可以以相同的方式解释,或者在不可能的情况下,以一种不失去信息的方式来解释。
-
被接受的内联解析方法描述在[SDR-5: 使用正式语法描述内联语法]。
内联预处理器
-
为了实现与原始替换模型的兼容性,内联解析需要分两阶段进行;请参见 https://gitlab.eclipse.org/eclipse/asciidoc-lang/asciidoc-lang/-/blob/main/spec/sdrs/sdr-005-formal-grammar-for-inline-syntax.adoc [SDR-5: 使用正规语法描述内联语法]。
-
在第一阶段,通过内容被识别和/或提取出来,并且属性引用被扩展。
-
处理直通文本的最简单方法是提取它们并留下一个占位符;在第二次解析阶段,必须将直通文本恢复到占位符的位置。
-
-
内联预处理器是唯一允许属性引用按照今天的方式引入内联语法的方法。
-
内联预处理器必须跟踪所有字符的原始位置,以便可以追踪到内联的来源。
-
通过属性引用所引入的所有字符应该被归到属性引用最左端的位置(换句话说,它们不占用空间)。
-
一旦第一阶段完成,就可以从输入文本到解析树的转换开始了。
内联解析
-
在第二阶段,扩展的输入被解析成一个内联元素树(该树的根是顶层内联元素的父元素)。
-
解析器应当追踪每个内联节点的位置(起始行号和列号,结束行号和列号)。
-
解析器必须使用内联预处理器提供的信息,将节点映射回原始源代码中的位置,而不是扩展后的源代码位置。
-
属性引用
-
文档属性的值是通过属性引用来引用的;引用指向一个文档属性。
-
属性引用的格式为
{name}
,其中name
是属性名。 -
属性引用被内联解析器(特别是内联预处理器)替换为指定属性的值。
-
插入值时不进行任何处理;它是按原样插入的。
-
-
属性引用可以在任何解释内联标记的地方使用。
-
如果文档属性没有设置,那么`attribute-missing`文档属性决定了应该做什么。
-
在正常操作下,如果引用的属性缺失(未设置),则引用会被丢弃,并且会发出警告。
-
直通 (或者 传递)
-
内联直通有类似于块直通的用途,但适用于内联上下文。
-
内联直通文本由内联预处理器处理;因此,它们不会被内联解析器看到。
-
通过方式是通过使用单个加号、双加号、三加号和pass宏来指定的。
-
透传阻止文本被解释(包括属性引用)。
-
三重加号和传递宏形式可以原样传递文本(在转换器中不替换特殊字符)。
-
单引号(受限的)和双引号(不受限的)加号形式会直接通过,文本内容不会被解释,但原始形式不适用(转换器将应用特殊字符替换)。
-
嵌套的直通是禁止的/不被识别的。
标记文本
-
一段被一对语义标记所包围的文本。
-
在过去,这被称为“文本格式化”或“格式化文本”(尽管格式化文本并不局限于这组语法)。
-
所用的标记决定了变体(例如,强调、重点)。
-
所有标记的跨度支持前置的框选属性列表;只有简写属性(id和角色)被识别。
受限制的与不受限制的
-
受限标记只能在满足某些条件的情况下使用。
-
两侧不能有字母字符,并且内容不能以空格开始或结束。
-
-
约束性标记旨在防止格式标记的不期望匹配;尽管它有时仍可能形成一个意料之外的匹配。
-
不受限的标记可以用在任何地方;不够简洁
-
如果不受约束的和受约束的都能匹配,那么不受约束的优先级更高。
-
同一变体内的受限内容不能以不受限内容开头(不受限标记占优势并结束跨度)
-
我们应该禁止相同变体的嵌套span吗?(无限制的强调内嵌有限制的强调,反之亦然?)
加粗(强调)
着重(斜体)
代码(等宽字体)
-
建议将等宽字体变体重命名为code(如在"代码跨度"中)。
双引号(智能双引号)
单引号(智能单引号)
上标
下标
打开
-
如果没有角色,则高亮显示/标记
-
如果是自定义角色,那么它就是具有该角色的通用跨度。
-
将
mark
指定为内置角色
内联宏
-
可以在文本流和其他内联元素中输入;如果是在内容流中输入的,那么将在内容流中显示。
-
通常遵循命名的内联宏格式,
name:<target>?[<attrlist>?]
,但一些链接和交叉引用宏除外。 -
"The
<attrlist>
is not interpreted the same way for all macros; it may be treated as inline content only; it may be a hybrid of inline content and an attribute list; it may have a complete custom interpretation" 这句话翻译成中文是:"`<attrlist>` 在所有宏中的解释不尽相同;它可能只被当作行内内容;它可能是行内内容与属性列表的混合体;它也可能有完全自定义的解释。" -
pass宏并不是一个宏;它是一个使用宏形式的内联直通。
-
除了预处理器指令外,宏的目标文本不会被解释。
-
图像
-
图标
-
键盘
-
菜单
-
按钮
-
stem(目前的行为类似于具有宏语法的专门的内联直通;我们可能不想在这里列出它)
-
自动链接(不遵循命名的宏结构)
-
链接(URL宏指令,链接宏指令,邮件宏指令)
-
交叉引用(xref 宏指令,xref 简写标记)
-
脚注
-
索引术语(索引项,索引简写)
内嵌图片宏
图标宏
键盘宏
-
'''FI 全面支持UI宏,因此,不再需要`experimental`来激活它们。'''
菜单宏
-
使用命名的内联宏格式,
menu:<target>[<attrlist>]
。 -
所需的宏名称是`menu`。
-
目标仅接受一个菜单项的用户定义文本。
-
可选的 attrlist 仅接受用户定义的文本。
-
attrlist中的每个项目都以一个大于号`>`分隔,并且每边都有一个空格,
+menu:Code[Folding > Expand to Level > 3]+
。
-
-
-
项目的文本可能包含空格。
-
建议移除速记结构,例如,
"代码 > 折叠 > 展开到级别 > 3"
。 -
在宏形式中使目标变为禁止,以使菜单与其他UI宏对齐。
按钮宏
-
使用命名的内联宏格式,
btn:[<attrlist>]
。 -
所需名称为`btn`。
-
目标是被禁止的。
-
attrlist仅接受用户定义的文本。
自动链接(网址和电子邮件地址)
-
FI 是否可以关闭隐式自动链接?
-
FI 我们是否应该继续支持使用尖括号封闭来明确地创建自动链接?
链接和网址宏
交叉引用宏
STEM 宏观
-
FI 我们应该将
$$
作为简写符号重新指定给stem宏吗?
脚注宏
-
FI 我们是否应该默认总是在脚注前移除空白?这可能需要一个特殊的语法来创建一个宏的左边界,例如额外的冒号,空的
{}
等。(例如,:footnote:[note]
)。 -
将表格下方紧接的脚注限定于当前表格?
索引项宏
-
FI 建议我们将`indexterm2`合并入`indexterm`,并添加`visible`或`show`(可能作为目标?)来复现`indexterm2`的行为?
硬换行
字符引用
反斜杠转义和直通
-
标记字符可以通过前面的反斜线来中和。
-
透传是一种不需要单独转义字符就能粗暴地逃避/覆盖/批量转义标记的方法(可能需要将文本保持在一起,而不被修改)。
-
#25 如何转义不受约束的标记文本?目前,AsciiDoc要求开放的不受约束标记必须双重转义(
\\**stars**
)。然而,这既依赖于上下文也不明确(因为转义反斜杠理应生成一个文本反斜杠)。因此,我们可能必须改变这个规则为(\*\*stars**
)。这将引入一个轻微的不兼容性,但这是一个合理的解释,并且为了使反斜杠转义稳定是正当的目标。 -
以下问题应该在TCK中进行测试以指导转义规则。问题:反斜杠是否用于转义语法规则匹配,或者它仅仅是用来停用紧接着的字符?
从**foo**,我们得到<strong>*foo*</strong> 还是 <strong>*foo</strong>* ?
替换品
排版替换
-
为了方便起见,AsciiDoc 支持许多排版替代。
-
作者写下了速记等价物,处理器将这些序列替换为印刷标记。
-
一个典型的例子是三个点被替换为省略号。
-
这种转换是在转换过程中使用搜索和替换对内联中的文本节点应用的。
-
我们应该在解析树中包括这些替换跨度吗?
特殊字符替换
-
某些输出格式要求必须转义某些字符以便按字面意义呈现。
-
例如,HTML至少要求将<和&转义为字符引用(习惯上也将>转义)。
-
对于手册页,许多更多的字符必须使用groff转义系统来转义。
-
并非所有的输出格式都能理解字符引用,因此必须将它们转换为等价的Unicode字符。
-
转换器负责转义这些特殊字符,而需要转义哪些字符则由输出决定。
-
转换器不应在原始文本节点中转义字符,因为目的是原样传递内容。
Part V: 参考系统
资源和参考资料
-
AsciiDoc语言提供了一个寻址/参考系统。
-
参考系统由可引用位置(通过ID标识的参考)、参考目录、指向同一文档中其他位置的内部引用(交叉引用),以及指向其他资源的外部引用组成。
-
参考文献是文档中可引用的位置。
-
资源是AsciiDoc文档引用的资产(例如,一幅图像或另一个文档)。
身份证件号码 / 参考名称
-
文档中的任何元素节点都可以定义一个ID(也称为引用名称),该ID可以用来引用那个节点。
-
ID 同样充当了在渲染输出中该节点位置的锚点(就像在HTML中一样)。
-
锚点和ID是同义的; 从技术上讲,ID是锚点的名称,而锚点是那个ID的位置(节点、节点的位置等)。
-
也可以通过内联方式定义任意的、无内容的、浮动的锚点。
-
默认情况下,处理器会自动为所有标题生成并分配一个ID(可以使用`sectids`文档属性来切换)。
-
处理器必须为标题提供自动ID生成功能;这个例程应该是可插拔的(也就是说,它是一个扩展点)。
-
ID 名称通过使用 ID 值作为键,节点(引用节点或 ref)作为值存储在引用目录中。
-
文档中的ID必须唯一
交叉引用(xrefs)
-
AsciiDoc内容可以向前和向后引用这些ID(这称为交叉引用)。
-
如果输出格式支持,锚点也应该是公开的,这样它们可以通过片段标识符(例如URL中的片段)从外部引用。
-
这样的片段可以添加到资源引用的末尾,以便引用来自另一文档的ID;这被称为深层次的文档间交叉引用。
-
-
如果在引用链接时没有指定链接文本,应使用节点的引用文本。
-
默认情况下,节点的标题被用作xreftext(替换xref的链接文本)。
-
这个标题可以被提升以符合出版标准。
-
refsig属性(例如,
chapter-refsig
)控制在xreftext中使用的标识符。 -
我们必须思考这是如何影响内联元素的;它们是否被克隆到这个位置?
-
-
如果节点上设置了`reftext`属性,那么将使用该值而不是标题。
-
如果一个xref指向一个未找到的ID,那么应当将其视为未解决的(即,断开的)引用,处理器应该发出警告/错误。
-
提议/确认xref宏是一个用于引用其他AsciiDoc文档的通用宏;简写形式应该被限制为页面内锚点吗?
-
在解析整个文档之前,不应检查/验证交叉引用,尽管处理器可以选择作为优化,急切地验证它已知的引用。
-
参考文献条目也存储在相同的参考目录中;然而,它们的定义方式有所不同。
资源引用
-
对当前文档外部位置的任何引用都是资源引用。
-
通常情况下,资源的引用看起来像是一条路径;然而,处理器不得假设这一点。
-
相反,任何资源引用都必须通过一个资源解析器。
-
一些相对资源引用有预定义的前缀;例如,相对的图像引用是从`imagesdir`属性的值开始的。
-
如果没有指定资源解析器,则处理器应假定引用是一个路径;在这种情况下,
-
绝对路径应该按原样使用
-
相对路径应该从`docdir`(最外层文档的目录)解析,而不是从当前包含文件的目录解析。
-
异常包括目标,这些目标是相对于当前包含文件解析的。
-
访问监狱(jail)外的路径(通常是`docdir`)可能会根据安全模式被限制。
-
-
xref根据目标中前导字符`#`(始终是内部的)或文件扩展名的存在与否来区分内部引用和外部引用。
-
参见 FI for clarification 以获得澄清。
-
Part VI: 预处理器
Note
|
我们正在考虑不同的模型来定义预处理器,以使AsciiDoc更容易解析。可能的解决方案包括:纯净模型、优先级模型(嵌套限制)、混合模型(头部=优先级,正文=纯净模型)。 |
-
AsciiDoc 提供了指令,这些指令可以在文本被解析之前向源文本添加或移除行。
-
从技术上讲,AsciiDoc的预处理器不是一个真正的预处理器,而是一个具有上下文的优先级处理器。
-
预处理器可以访问在每一行定义的文档属性,但它并不知道文档的块结构。
-
预处理器处理以下内容(为这些内容制作章节):
-
线性归一化
-
属性条目(不消耗它们)
-
条件指令
-
包含指令
-
注释 ⇐ 到什么程度?
-
-
指令共享与块宏相同的语法(但本身并不是块宏)
-
有条件指令和包含指令。
-
指令能够识别到那一点为止所定义的任何文档属性。
-
线性归一化
-
将编码强制设置为 UTF-8(一个 AsciiDoc 处理器总是假设内容是以 UTF-8 编码的)
-
从每一行中去除尾随空格(包括任何行尾字符);或者在语法规则中忽略它们。
-
我们可能会决定不必移除末尾的空格字符,或者这可以由预处理器来处理。
-
-
将Windows换行格式更改为通用/Unix换行格式(或者以与通用换行格式相同的方式匹配Windows换行格式)
预处理指令
-
经预处理器处理的特殊线条,不受文档当前上下文的影响。
-
预处理指令可以出现在文档的任何位置。
-
预处理器指令必须用反斜杠转义,即使在逐字块中,以防止它被解释。
-
预处理指令具有块宏的语法,但本身并不是宏。
与文档属性的关系
-
预处理器指令必须能够看到直到指令行为止定义的所有文档属性。
-
预处理器可以看到属性条目的效果,但本身并不消耗这个属性条目。
-
预处理器指令可以使用属性引用。
条件指令
-
共享结束指令:endif
-
ifdef / ifndef
-
条件评估
-
FI 是否应该允许在ifdef/ifndef/ifeval中使用`else`?(参见 https://github.com/asciidoctor/asciidoctor/issues/514)
问题:如果发现了一个没有匹配的`endif::[]`,应该将其当作普通文本处理吗?或者处理器应该发出警告?这可能是一个linter的工作。
包含指令
-
我们应该为include添加indir/infile选项吗,如果可能的话?或者有没有什么方法可以从当前的include解析目标?
评论
-
注释是块级节点和行内节点还是预处理指令?如果它们是预处理指令,它们需要被预处理器捕获,还是可以简单地忽略或丢弃?
-
线路
-
提议非保留标识行(分隔线或块属性线)可包含行尾注释;我们正在考虑是否可以将此规则放宽到所有非逐字行;与#26有关。
-
-
块
Part VII: 扩展点
-
AsciiDoc语言赋予了作者在一定边界内扩展语法和解释语法的能力。
-
由于AsciiDoc语言可能被任何语言处理,因此这个扩展系统只能用伪代码来定义。
-
处理器应当通过提供TCK适配器来提供这些扩展点,以证明它们是被支持的。
-
语法中将如何描述语法扩展?我们可能需要重新思考解析和扩展之间的关系;它可能不适用于在Asciidoctor中使用的模型。
生命周期扩展
-
我们能否继续支持生命周期延期? 如果可以,它们将如何与解析集成,以及我们能支持哪些延期? 目前尚不清楚我们是否能够匹配我们过去所做的。
-
我们可能可以支持的有:树处理器、后处理器和文档信息处理器。
语法扩展
自定义区块
问题:自定义块或块宏应该能够开始新的章节吗?
自定义块宏
自定义内联宏
资源解析器
-
资源解析器的返回值是转换器要使用的资源的地址(例如,href)。
-
'''FI 或者它应该是一个包含 a) 可引用位置,b) 具体位置,c) 资源读取器的对象'''
-
-
目前为止,没有针对解释和解析资源引用所必需的语法。
-
资源解析器必须能够访问正被解析的资源的名称(例如,包括、图像、交叉引用、视频等)。
-
资源解析器可以过滤它选择解析的资源;它可以覆盖某些名称的行为,并允许其他名称使用默认行为(一个过滤器)。
-
资源解析器必须提供用于解析资源的上下文;这可能是资源解析器为了自身的使用而存储在文档上的信息。
ID生成器
-
生成标题(章节标题和独立标题)的ID。
-
如果文档设置了`sectids`属性且元素没有显式ID,则会调用该方法。
Part VIII: 合规性 / 技术兼容性套件
TCK介绍
-
验证实现是否符合标准
-
对实现语言/平台不可知(面向doctest)
-
目前专注于语言解析/解释。
input input |engine| <-> |adapter| <-> |impl| actual ASG actual ASG = 预期的ASG
ASG / 节点模型
-
TCK通过验证一个实现能否产出一个预期的ASG来工作。
-
ASG是抽象语义图,本质上是一个语义解析树。
-
一个ASG(抽象语法图)只包含具体节点;它不包含非语义的空行;那些是暗示的。
-
为了验证ASG, 实现应该产生一个节点模型。
-
节点模型是抽象语法树 ASG 的 JSON 表示形式。
-
TCK将会把它的节点模型与实现产生的节点模型进行比较。
-
ASG将要求至少足够的源位置(源映射)实现来验证文档是否已正确解析;不会做得过分。
-
代码块的结束位置是最后一行的最后一列,而不是下一行的第一列。
-
-
我们将如何以与语言无关的方式定义API(包括DOM),例如,来自XML DOM Core的IDL、UML等(参见https://en.wikipedia.org/wiki/Language-independent_specification)?
自我认证过程
-
在这里描述自我认证过程
Appendix A: 转换和预期行为
在AsciiDoc中写作意味着内容将被转换为可发布的格式。使用AsciiDoc写作的好处在于,你可以使用与展现形式无关的输入格式,并能够发布到多种格式(例如,HTML、PDF、manpage等)。处理器的目的是既要解析/解释AsciiDoc内容到文档模型中,也要将文档模型转换成输出格式。转换器目前还不属于这个规范的一部分(可能是伴随规范)。然而,这个规范确实确定了由AsciiDoc源控制的已发布文档的期望(例如,目录表)。本节在较高层面解释了转换过程,并对这些期望进行了目录。并不是所有的输出格式都能满足所有期望,但它们应该尽可能多地覆盖。
Appendix B: 淘汰过程
-
FI 定义规范第一版中所定义的语法、能力等的废弃过程。
-
列出Asciidoctor中存在的任何语法、行为等,这些在规范的第一个版本中未被定义,因此已被弃用。我们可能会决定在该问题中也将语法列在规范文档的附录中,或者仅将其维护为一个问题或以某种其他形式维护。