Templates provide a more versatile text substitution mechanism. Templates come in handy when you need to create parameterizable, multi-line, boilerplate text that you specify once and expand many times. Templates accept one or more arguments. These arguments act like place-holders for text replacement. Unlike simple macros, which are limited to phrase level markup, templates can contain block level markup (e.g. paragraphs, code blocks and tables).
Example template:
[template person[name age what] Hi, my name is [name]. I am [age] years old. I am a [what]. ]
Template identifiers can either consist of:
Template formal arguments are identifiers consisting of an initial alphabetic character or the underscore, followed by zero or more alphanumeric characters or the underscore. This is similar to your typical C/C++ identifier.
A template formal argument temporarily hides a template of the same name
at the point where the template
is expanded. Note that the body of the person
template above refers to name
age
and what
as [name]
[age]
and [what]
. name
age
and what
are actually templates that exist in the duration
of the template call.
The template body can be just about any QuickBook block or phrase. There are actually two forms. Templates may be phrase or block level. Phrase templates are of the form:
[template sample[arg1 arg2...argN] replacement text... ]
Block templates are of the form:
[template sample[arg1 arg2...argN] replacement text... ]
The basic rule is as follows: if a newline immediately follows the argument list, then it is a block template, otherwise, it is a phrase template. Phrase templates are typically expanded as part of phrases. Like macros, block level elements are not allowed in phrase templates.
You expand a template this way:
[template_identifier arg1..arg2..arg3]
At template expansion, you supply the actual arguments. The template will be expanded with your supplied arguments. Example:
[person James Bond..39..Spy] [person Santa Clause..87..Big Red Fatso]
Which will expand to:
Hi, my name is James Bond. I am 39 years old. I am a Spy.
Hi, my name is Santa Clause. I am 87 years old. I am a Big Red Fatso.
Caution | |
---|---|
A word of caution: Templates are recursive. A template can call another template or even itself, directly or indirectly. There are no control structures in QuickBook (yet) so this will always mean infinite recursion. QuickBook can detect this situation and report an error if recursion exceeds a certain limit. |
Each actual argument can be a word, a text fragment or just about any
QuickBook phrase. Arguments
are separated by the double dot ".."
and terminated
by the close parenthesis.
Note that templates and template parameters can't be expanded everywhere, only where text is interpreted as a phrase. So they can't be expanded in places such as table titles and link's urls. If you want to use a template to generate a link based of the template parameter, you can't use a normal link and will need to use escaped docbook instead. Example:
[template boost_ticket[key] '''<ulink url="https://svn.boost.org/trac/boost/ticket/'''[key]'''">#'''[key]'''</ulink>'''] [boost_ticket 2035]
will expand to:
Caution | |
---|---|
Since quickbook doesn't understand the context where the parameter is being used, it will interpret it as quickbook markup, so when writing a template like this, you'll need to escape any meaningful punctuation. |
Nullary templates look and act like simple macros. Example:
[template alpha[]'''&#945;'''] [template beta[]'''&#946;''']
Expanding:
Some squigles...[*[alpha][beta]]
We have:
Some squiggles...αβ
The difference with macros are
The empty brackets after the template identifier (alpha[]
)
indicates no arguments. If the template body does not look like a template
argument list, we can elide the empty brackets. Example:
[template aristotle_quote Aristotle: [*['Education is the best provision for the journey to old age.]]]
Expanding:
Here's a quote from [aristotle_quote].
We have:
Here's a quote from Aristotle: Education is the best provision for the journey to old age..
The disadvantage is that you can't avoid the space between the template
identifier, aristotle_quote
, and the template body "Aristotle...".
This space will be part of the template body. If that space is unwanted,
use empty brackets or use the space escape: "\
".
Example:
[template tag\ _tag]
Then expanding:
`struct` x[tag];
We have:
struct
x_tag;
You have a couple of ways to do it. I personally prefer the explicit empty brackets, though.
As mentioned, arguments are separated by the double dot ".."
.
Alternatively, if the double dot isn't used and more than one argument
is expected, QuickBook uses whitespace to separate the arguments, following
this logic:
'',
'\n', \t' or '\r'
).
For example:
[template simple[a b c d] [a][b][c][d]] [simple w x y z]
will produce:
wxyz
"w x y z" is initially treated as a single argument because we
didn't supply any ".."
separators. However,
since simple
expects 4 arguments, "w x y z"
is broken down iteratively (applying the logic above) until we have "w",
"x", "y" and "z".
QuickBook only tries to get the arguments it needs. For example:
[simple w x y z trail]
will produce:
wxyz trail
The arguments being: "w", "x", "y" and "z trail".
Caution | |
---|---|
The behavior described here is for QuickBook 1.5. In older versions you could use both the double dot and whitespace as separators in the same template call. If your document is marked up as an older version, it will use the old behavior, which is described in the QuickBook 1.4 documentation. |
With templates, one of our objectives is to allow us to rewrite QuickBook in QuickBook (as a qbk library). For that to happen, we need to accommodate single character punctuation templates which are fairly common in QuickBook. You might have noticed that single character punctuations are allowed as template identifiers. Example:
[template ![bar] <hey>[bar]</hey>]
Now, expanding this:
[!baz]
We will have:
<hey>baz</hey>