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.
# 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.
[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.
[source,ruby]
----
include::core.rb[tags=timings;parse]
----
It’s also possible to have fine-grained tagged regions inside larger tagged regions.
In the next example, tagged regions are defined behind line comments. By putting each tag behind a line comment, regardless of how the content is included, you don’t have to worry about those lines appearing in the rendered document.
// tag::snippets[]
// tag::snippet-a[]
snippet a
// end::snippet-a[]
// tag::snippet-b[]
snippet b
// end::snippet-b[]
// end::snippets[]
Let’s assume 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
You could also include the whole file without worry that the tags will be rendered:
include::file-with-snippets.adoc[]
Now let’s consider the case when the tags are not placed behind line comments. In this case, you need to ensure that tag filtering is being used or else those tags will be visible in the rendered document.
text a
tag::snippet-b[]
snippet b
end::snippet-b[]
text c
If you only want to include a specific tagged region of the file, use the following include directive:
include::file-with-snippets.adoc[tag=snippet-b]
The following lines will be selected and displayed:
snippet b
If you want to include the whole file, but also filter out any include tags, use the following include directive:
include::file-with-snippets.adoc[tag=**]
The following lines will be selected and displayed:
text a snippet b text c
If you did not specify g filtering, tag directives that aren’t behind a line comment (e.g., tag::snippet-b[]
) will also be printed too.
Tag filtering is explaied in more detail in the next section.
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.