Diversions are a way of temporarily saving output. The output of
m4 can at any time be diverted to a temporary file, and be
reinserted into the output stream, undiverted, again at a later
Numbered diversions are counted from 0 upwards, diversion number 0
being the normal output stream. The number of simultaneous diversions
is limited mainly by the memory used to describe them, because GNU
m4 tries to keep diversions in memory. However, there is a
limit to the overall memory usable by all diversions taken altogether
(512K, currently). When this maximum is about to be exceeded,
a temporary file is opened to receive the contents of the biggest
diversion still in memory, freeing this memory for other diversions.
So, it is theoretically possible that the number of diversions be
limited by the number of available file descriptors.
Output is diverted using
where number is the diversion to be used. If number is left out, it is assumed to be zero.
The expansion of
divert is void.
When all the
m4 input will have been processed, all existing
diversions are automatically undiverted, in numerical order.
divert(1) This text is diverted. divert => This text is not diverted. =>This text is not diverted. ^D => =>This text is diverted.
Several calls of
divert with the same argument do not overwrite
the previous diverted text, but append to it.
If output is diverted to a non-existent diversion, it is simply discarded. This can be used to suppress unwanted output. A common example of unwanted output is the trailing newlines after macro definitions. Here is how to avoid them.
divert(-1) define(`foo', `Macro `foo'.') define(`bar', `Macro `bar'.') divert =>
This is a common programming idiom in
Diverted text can be undiverted explicitly using the builtin
undivert(opt number, ...)
which reinserts the diverted output given by the arguments into the current output stream, in the order given. If no arguments are supplied, all diversions are undiverted, in numerical order.
The expansion of
undivert is void.
divert(1) This text is diverted. divert => This text is not diverted. =>This text is not diverted. undivert(1) => =>This text is diverted. =>
Notice the last two blank lines. One of them comes from the newline
undivert, the other from the newline that followed the
divert! A diversion often starts with a blank line like this.
When diverted text is undiverted, it is not reread by
but rather copied directly to the current output, and it is therefore
not an error to undivert into a diversion.
When a diversion has been undiverted, the diverted text is discarded, and it is not possible to bring back diverted text more than once.
divert(1) This text is diverted first. divert(0)undivert(1)dnl => =>This text is diverted first. undivert(1) => divert(1) This text is also diverted but not appended. divert(0)undivert(1)dnl => =>This text is also diverted but not appended.
Attempts to undivert the current diversion are silently ignored.
m4 allows named files to be undiverted. Given a non-numeric
argument, the contents of the file named will be copied, uninterpreted, to
the current output. This complements the builtin
(see section Including named files). To illustrate the difference, assume the file
`foo' contains the word `bar':
define(`bar', `BAR') => undivert(`foo') =>bar => include(`foo') =>BAR =>
expands to the number of the current diversion.
Initial divnum =>Initial 0 divert(1) Diversion one: divnum divert(2) Diversion two: divnum divert => ^D => =>Diversion one: 1 => =>Diversion two: 2
The last call of
divert without argument is necessary, since the
undiverted text would otherwise be diverted itself.
Often it is not known, when output is diverted, whether the diverted
text is actually needed. Since all non-empty diversion are brought back
on the main output stream when the end of input is seen, a method of
discarding a diversion is needed. If all diversions should be
discarded, the easiest is to end the input to
`divert(-1)' followed by an explicit `undivert':
divert(1) Diversion one: divnum divert(2) Diversion two: divnum divert(-1) undivert ^D
No output is produced at all.
Clearing selected diversions can be done with the following macro:
define(`cleardivert', `pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')') =>
It is called just like
undivert, but the effect is to clear the
diversions, given by the arguments. (This macro has a nasty bug! You
should try to see if you can find it and correct it. See section Answers.)
Go to the first, previous, next, last section, table of contents.