Include Content by Tagged Regions

The include directive enables you to select portions of a file to include instead of including the whole file. Use the lines attribute to include individual lines or a range of lines (by line number). Use the tags attribute (or tag attribute for the singular case) to select lines that fall between regions marked with user-defined tags.

When including multiple line ranges or multiple tags, each entry in the list must be separated by either a comma or a semi-colon. If commas are used, the entire value must be enclosed in quotes. You can eliminate this requirement by using the semi-colon as the data separator instead.

Tagging regions

Tags are useful when you want to identify specific regions of a file to include. You can then select the lines between the boundaries of the include tag/end directives to include using the tags attribute.

In the include file, the tag directives (e.g., tag::name[] and end::name[]) must follow a word boundary and precede a space character or the end of line. The tag name must not be empty and must consist exclusively of non-space characters.

Typically, the tag directives will be placed after a line comment as defined by the language of the source file. For languages that only support circumfix comments, such as XML, you can enclose the tag directives between the circumfix comment markers, offset by a space on either side. For example, in XML files, you can use <!-- tag::name[] --> and <!-- end::name[] -->.

Including by tag includes all regions marked with that tag. This makes it possible to include a group of lines from different regions of the document using a single tag.

If the target file has tagged lines, and you just want to ignore those lines, use the tags attribute to filter them out. See Tag filtering for details.

The example below shows how you tag a region of content inside a file containing multiple code examples. The tag directives are preceded by a hash (#) because that’s the start of a line comment in Ruby.

Example 1. Tagged code snippets in a file named core.rb
# tag::timings[] (1) (2)
if timings
  timings.record :read
  timings.start :parse
end
# end::timings[] (3) (4)
# tag::parse[] (5)
doc = (options[:parse] == false ? (Document.new lines, options) :
    (Document.new lines,options).parse)
timings.record :parse if timings
doc
# end::parse[] (6)
1 To indicate the start of a tagged region, insert a comment line in the code.
2 Assign a name to the tag directive. In this example, the tag is named timings.
3 Insert another comment line where you want the tagged region to end.
4 Assign the name of the region you want to terminate to the end directive.
5 This is the start of a tagged snippet named parse.
6 This is the end of the tagged snippet named parse.

In the next example, the tagged region named parse is selected by the include directive.

Example 2. Selecting the parse code snippet from a document
[source,ruby]
----
include::core.rb[tag=parse] (1)
----
1 In the directive’s brackets, set the tag attribute and assign it the unique name of the code snippet you tagged in your code file.

You can include multiple tags from the same file.

Example 3. Selecting the timings and the parse code snippets from a document
[source,ruby]
----
include::core.rb[tags=timings;parse]
----

It is also possible to have fine-grained tagged regions inside larger tagged regions.

For example, if your include file has the following content:

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

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

And you include this file using the following include directive:

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

The following lines will be selected and displayed:

snippet a

snippet b

Notice that none of the lines with the tag directives are displayed.

Tag filtering

The previous section showed how to select tagged regions explicitly, but you can also use wildcards and exclusions. These expressions give you the ability to include or exclude tags in bulk. For example, here’s how to include all lines that are not enclosed in a tag:

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

When tag filtering is used, lines that contain a tag directive are always discarded (like a line comment). Even if you’re not including content by tags, you can specify the double wildcard (**) to filter out all lines in the include file that contain a tag directive.

The modifiers you can use for filtering are as follows:

*

The single wildcard. Select all tagged regions. May only be specified once, negated or not.

**

The double wildcard. Select all the lines in the document except for lines that contain a tag directive. Use this symbol if you want to include a file that has tag directives, but you want to discard the lines that contain a tag directive. May only be specified once, negated or not.

!

Negate the wildcard or tag.

The double wildcard is always applied first, regardless of where it appears in the list. If the double wildcard is not negated (i.e., **), it should only be combined with exclusions (e.g., **;!foo). A negated double wildcard (i.e., !**), which selects no lines, is usually implied as the starting point. A negated single wildcard has different meaning depending on whether it comes before tag names (e.g., !*;foo) or after at least one tag name (e.g., foo;!*).

Let’s assume we have a region tagged foo with a nested region tagged bar. Here are some of the permutations you can use (along with their implied long-hand forms):

**

Selects all the lines in the document (except for lines that contain a tag directive). (implies **;*)

*

Selects all tagged regions in the document. Does not select lines outside of tagged regions. (implies !**;*)

!*

Selects only the regions in the document outside of tags (i.e., non-tagged regions). (implies **;!*)

foo

Selects only regions tagged foo. (implies !**;foo)

foo;!bar

Selects only regions tagged foo, but excludes any nested regions tagged bar. (implies !**;foo;!bar)

foo;!*

Selects only regions tagged foo, but excludes any nested tagged regions. (implies !**;foo;!*)

*;!foo

Selects all tagged regions, but excludes any regions tagged foo (nested or otherwise). (implies !**;*;!foo)

!foo

Selects all the lines in the document except for regions tagged foo. (implies **;!foo)

!foo;!bar

Selects all the lines in the document except for regions tagged foo or bar. (implies **;!foo;!bar)

!*;foo

Selects the regions in the document outside of tags (i.e., non-tagged regions) and inside regions tagged foo, excluding any nested tagged regions. To include nested tagged regions, they each must be named explicitly. (implies **;!*;foo)

If the filter begins with a negated tag or single wildcard, it implies that the pattern begins with **. An exclusion not preceded by an inclusion implicitly starts by selecting all the lines that do not contain a tag directive. Otherwise, it implies that the pattern begins with !**. A leading inclusion implicitly starts by selecting no lines.