Divert - Text Diversion Filter
divert [-o outputfile] [-q]
[-v] [inputfile]
The divert program reads inputfile or from
"stdin" and applies a 2-pass diversion
filter to its contents. In pass 1 all diversion locations are accumulated
and in pass 2 these locations are recursively expanded at their dump
positions. The diversion filter is controlled by directives found in the
input data:
- {#NAME#} (or
<<NAME>>)
- This defines the dump position of the location NAME. All
accumulated data which finally has to been diverted to NAME
is inserted at this data position. Notice: the final data of a location
NAME has not to be known at this point, because the expansion of
such location dumps are done in pass 2. You can also dump a location more
than once, but the contents is always the same, independent of the data
position where the location dump tag stays. The NAME can be any
symbolic name matching
"[a-zA-Z][a-zA-Z0-9_]*".
- {#[!]NAME[!]#: (or
..[!]NAME[!]>>)
- This enters the location NAME (or diverts the data flow to
it, hence the name for this filter). In other words: the data flow now
goes on at location NAME. All following data (up to end of file or
the next location leave tag) gets appended to location NAME. You
can nest diversions by entering other locations at any point, because the
locations are remembered on a stack. The default entered location is named
``"main"''. The top most location is
named ``"null"'' which neither can be
entered nor leaved explicitly. But of course the
``"null"'' diversion can be manually
dumped, for instance when using it for error messages.
There are two special features for diverting data which are
controlled by the ""!""
characters preceding or following the NAME identifier:
- !NAME
- This sets the data flow position to the begin of location
NAME, i.e. it actually discards the current (already diverted)
contents of location NAME before entering it. Use this to overwrite
a locations contents.
- NAME!
- This marks this location entry as overwritable, i.e. it enters
location NAME but when the corresponding leave tag is found, the
data-flow position for NAME gets automatically reset to its begin.
Use this if you want to set the default contents for a location which only
gets used if no other diversions occur to it (because any following
diversions to this location will be overwrite the contents). This feature
is usually used for a template scheme.
- !NAME!
- Just the combination of the above two features. Use this to both discard
the current contents of location NAME and set a new default for
it.
- :#[NAME]#} (or
<<[NAME]..)
- This leaves the current location, i.e. enters again the location which was
active when this location was entered. There is no need to leave all
locations at the end of the input data. All still entered locations are
automatically left at end of file because this is essential for a template
scheme.
Notice that there are two ways of using (and thinking) about the
filtering mechanism this program provides:
- Macro
Mechanism
- This is the "predefined" way of thinking here. Use it like this:
FOO
{#BAR#}
QUUX
{#BAR#:
BAZ
:##}
Here you are thinking of the mechanism as a macro mechanism
where you expand a macro at one data position while you define it
via begin and end tags.
- Diversion
Mechanism
- This is the alternative way of thinking. Use it like this:
FOO
<<BAR>>
QUUX
..BAR>>
BAZ
<<..
In other words: You are thinking of the mechanism as a
diversion mechanism where you dump a location at one data
position while you divert to it by entering end leaving
the location (here BAR) at other positions.
You can even intermix both ways because both are just alternative
syntax variants which are treated the same.
{#HEAD#}
{#BODY#}
{#FOOT#}
{#FOOT#:
Quux
:##}
{#BODY#:
Bar
:##}
{#HEAD#:
Foo
:##}
- -o outputfile
- This redirects the output to outputfile. Usually the output will be
send to stdout if no such option is specified or outputfile
is ``"-"''.
- -q
- This sets quiet mode where warnings are suppressed.
- -v
- This sets verbose mode where some processing information will be given on
stderr.
Ralf S. Engelschall
rse@engelschall.com
www.engelschall.com
Denis Barbier
barbier@engelschall.com