include指令允许你选择包含文件的某些部分,而不是包含整个文件。使用`lines`属性来包含单独的行或一系列行(通过行号)。使用`tags`属性(或`tag`属性,用于单数情况)来选择位于用户定义标签标记区域之间的行。

当包含多个行范围或多个标签时,列表中的每个条目必须用逗号或分号分隔。如果使用逗号,整个值必须用引号括起来。你可以通过使用分号作为数据分隔符来消除这个要求。

标记区域

当您想要标识文件中特定区域以便包含时,标签非常有用。然后,您可以选择`include`标签/`end`指令的边界之间的行,使用`tags`属性来包含。

通过标签包含将包括所有用该标签标记的区域。这使得可以使用单一标签包含文档不同区域的一组行。

Tip
如果目标文件中包含了标记过的行,而你只想忽略这些行,可以使用`tags`属性来过滤。详细信息请参考[标签过滤]

下面的例子展示了如何在一个包含多个代码示例的文件中标记内容区域。

在名为core.rb的文件中标记代码片段
Unresolved directive in include-tagged-regions.adoc - include::example$include.adoc[tag=tag-co]
  1. 要表示标记区域的开始,在代码中插入一行注释。

  2. 为`tag`指令指定一个名称。在这个例子中,标签被命名为_timings_。

  3. 在您希望标记区域结束的地方再插入一个注释行。

  4. 将您想要终止的区域名称分配给`end`指令。

  5. 这是一个名为_parse_的标记片段的开始。

  6. 这是标记为 parse 的代码片段的结尾。

Important
tag::[]` 和 end::[] 指令应该放在源文件语言定义的行注释之后。这些指令也必须出现在行的末尾。在前面的例子中,我们选择使用井号(#)作为前缀,因为那是 Ruby 中行注释的开始。
Tip
对于只有围绕型注释的语言,比如XML,你可以使用各自的围绕型注释标记来包围标签和结束指令。例如,在XML文件中,你可以使用 <!-- tag::name[] --><!-- end::name[] -->(标签周围的空格是必需的)。

在下一个示例中,include 指令选择了标记为 parse 的区域。

从文档中选取_parse_代码片段
Unresolved directive in include-tagged-regions.adoc - include::example$include.adoc[tag=target-co]
  1. 在指令的括号中,设置`tag`属性,并将其分配一个你在代码文件中标记的代码片段的唯一名称。

你可以从同一个文件中包含多个标签。

从文档中选择 timingsparse 代码片段
Unresolved directive in include-tagged-regions.adoc - include::example$include.adoc[tag=target-co-multiple]

也可以在更大的标记区域内部拥有细粒度的标记区域。

例如,如果你的包含文件有以下内容:

// tag::snippets[]
// tag::snippet-a[]
snippet a
// end::snippet-a[]

// tag::snippet-b[]
snippet b
// end::snippet-b[]
// end::snippets[]

并且您可以使用以下include指令来包含这个文件:

include::file-with-snippets.adoc[tag=snippets]

以下行将被选中并显示:

代码片段 a

代码片段 b

注意,所有带有标签指令的行都不会显示。

标签过滤

前一节展示了如何明确选择标记的区域,但你也可以使用通配符和排除法。这些表达式让你有能力大量地包含或排除标签。例如,下面是如何包含所有未被标签包围的行:

include::file-with-snippets.adoc[tag=!*]

当使用标签过滤时,包含标签指令的行_总是被丢弃_(像行注释一样)。即使你没有通过标签包含内容,你也可以指定双通配符(**)来过滤掉包含文件中所有包含标签指令的行。

您可以使用的过滤器修饰符如下:

*

单个通配符。选择所有标记的区域。只能指定一次,不管是否取反。

**

双通配符。选择文档中的所有行*除了包含标签指令的行*。如果您想要包含一个有标签指令的文件,但您想要丢弃包含标签指令的行,请使用这个符号。只能指定一次,是否取反都可以。

!

否定通配符或标签。

双通配符始终首先应用,无论它出现在列表中的哪个位置。如果双通配符没有被否定(即 **),它应该只与排除项结合使用(例如,**;!foo)。一个被否定的双通配符(即 !**),其选择没有任何行,通常作为起点是默认的。否定的单个通配符,根据它是出现在标签名称之前(例如,!*;foo)还是至少一个标签名称之后(例如,foo;!*),其含义有所不同。

假设我们有一个标记为`foo`的区域,其中嵌套了一个标记为`bar`的区域。以下是一些你可以使用的排列方式(以及它们隐含的长格式形式):

**

选择文档中的所有行(标签指令所在的行除外)。(意味着 **;*)

*

选中文档中的所有带标签的区域。不会选择标签区域之外的行。 (意味着 !**;*

!*

仅选中文档中标签之外的区域(即非标签区域)。 (意味着使用 **;!*)

foo

仅选择标记为_foo_的区域。(意味着 !**;foo)

foo;!bar

仅选择标记为_foo_的区域,但排除任何标记为_bar_的嵌套区域。(意味着 !**;foo;!bar)

foo;!*

选择只标记了 foo 的区域,但排除任何嵌套的标记区域。 (意味着 !**;foo;!*)

*;!foo

选中所有带标签的区域,但排除所有标记为_foo_的区域(无论是否嵌套)。 (意味着 !**;*;!foo)

!foo

选择文档中除了标记为_foo_的区域之外的所有行。(意味着`**;!foo`)

!foo;!bar

选择文档中除了被标记为_foo_或_bar_之外的所有行。(意味着`**;!foo;!bar`)

!*;foo

选择文档中标签外部的区域(即非标签区域)以及标记为 foo 的内部区域,但不包括任何嵌套的标记区域。要包括嵌套的标记区域,必须明确指出每一个区域的名称。(暗含 **;!*;foo)

如果过滤器以一个否定标签或单个通配符开始,这意味着模式以`**开始。未被包含的排除隐式地首先选定所有不包含标签指令的行。否则,它意味着模式以!**`开始。一个领先的包含隐式地首先选择没有行。