Provided by: yodl_2.15.1-1_i386

#### NAME

       yodlbuiltins - Builtins for the Yodl converters



#### SYNOPSIS

       This manual page lists the standard builtins of the Yodl package.



#### DESCRIPTION

       The  following  list  shows the builtins defined by the Yodl converters
define and which can be used in Yodl documents. Refer to the Yodl  user
guide, distributed with the Yodl package, for a full description.

The  following  list  shows all builtins of the package in alphabetical
order.

Yodl’s builtin commands
As mentioned previously, YODL’s input consists of  text  and  of
commands.  YODL supports a number of built-in commands which may
either be used in a YODL document,  or  which  can  be  used  to
create a macro package.

Don’t  despair  if you find that the description of this section
is too technical. Exactly for this  reason,  YODL  supports  the
macro  packages  to  make  the  life  of  a documentation writer
easier. E.g., see chapter [MACROPACKAGE] that describes a  macro
package for YODL.

Most  built-in  functions and macros expand the information they
receive  the  way  they  receive  the  information.  I.e.,   the
information   itself  is  only  evaluated  by  the  time  it  is
eventually inserted into an  output  medium  (usually  a  file).
However,  some builtin functions will evaluate their argument(s)
once the argument is processed. They are:

o      The ERROR() built-in function (see section [ERROR]);

o      The EVAL() built-in function (see section [EVAL]);

o      The FPUTS() built-in function (see section [FPUTS]);

o      The   INTERNALINDEX()    built-in    function    (see    section
[INTERNALINDEX]);

o      The TYPEOUT() built-in function (see section [TYPEOUT]);

o      The UPPERCASE() built-in function (see section [UPPERCASE]);

o      The  WARNING()  built-in  function  (see section [WARNING]); All
other built-in functions will not evaluate their arguments.  See
the  mentioned  functions  for details, and in particular EVAL()
for a description of this evaluation process.

The ADDTOCOUNTER function adds a given value to  a  counter.  It
expects  two parameter lists: the counter name, and the value to
add. The counter must be previously created with  DEFINECOUNTER.

The  value  to  add can be negative; in that case, a value is of
course subtracted from the counter.

See further section [COUNTERS].

Since Yodl version 2.00 symbols can be manipulated. To add  text
to  an  existing symbol the builtin ADDTOSYMBOL is available. It
expects two parameter lists: the symbol’s name, and the text  to
add  to  the  symbol.  The symbol must have been created earlier
using DEFINECOUNTER (see section [DEFINECOUNTER]).  The  macro’s
second argument is not evaluated while ADDTOSYMBOL is processed.
Therefore, it is easy to add the text of another symbol  or  the
expansion of a macro to a symbol value. E.g.,

This will add the text of symbol two, followed by a new line, to
the contents of symbol one only when symbol  one  is  evaluated,
not when ADDTOSYMBOL is evaluated.

Example:

ADDTOSYMBOL(LOCATION)(this is appended to LOCATION)

ATEXIT ATEXIT  takes  one  parameter  list as argument. The text of the
parameter list is appended to the output file.  Note  that  this
text is subject to character table translations etc..

An  example  using this function is the following. A document in
the LaTeX typesetting language requires \end{document} to  occur
at  the end of the document. To automatically append this string
to the output file, the following specification can be used:

ATEXIT(NOEXPAND(\end{document}))

Several ATEXIT lists can be defined. They are  appended  to  the
output  file  in  the  reverse order of specification; i.e., the
first ATEXIT list is appended to  the  output  file  last.  That
means that in general the ATEXIT text should be specified when a
‘matching’ starting command is sent to the output file; as in:

COMMENT(Start the LaTeX document.)
NOEXPAND(\begin{document})

COMMENT(Ensure its proper ending.)
ATEXIT(NOEXPAND(\end{document}))

CHAR   The command CHAR takes one argument, a number  or  a  character,
and  outputs  its  corresponding  ASCII  character  to the final
output file.  This command is built for ‘emergency  situations’,
where  you  need to typeset a character despite the fact that it
may  be  redefined  in  the  current  character  table  (for   a
discussion  of  character  tables,  see [CHARTABLES]). Also, the
CHAR function can be used to circumvent Yodl’s way  of  matching
parentheses in a parameter list.

The following arguments may be specified with CHAR (attempted in
this order):

o      A decimal number indicating the number of the character  in  the
ascii-table (for example CHAR(41));

o      A plain, single character  (for example CHAR(#)).

So, when you’re sure that you want to send a printable character
that is not a closing parenthesis to the output  file,  you  can
use  the  form  CHAR(c), c being the character (as in, CHAR(;)).
To send a non-printable character or a  closing  parenthesis  to
the  output file, look up the ASCII number of the character, and
supply that number as argument to the CHAR command.

Example: The following two statements send an A  to  the  output
file.

CHAR(65)
CHAR(A)

The following statement sends a closing parenthesis:

CHAR(41)

Another  way  to  send  a  string  to  the  output  file without
expansion by character tables or by macro interpretation, is  by
using  the function NOTRANS (see section [NOTRANS]). If you want
to send a string to the output without macro interpretation, but
with  character  table  translation,  use  NOEXPAND (see section
[NOEXPAND]).

CHDIR  The command CHDIR takes one argument, a directory to change  to.
This  command  is  implemented  to  simplify  the  working  with
includefile  (see   includefile   in   yodlmacros(7)).    As   a
demonstration by example, consider the following fragment:

includefile(subdir/onefile)
includefile(subdir/anotherfile)
includefile(subdir/yetanotherfile)

This fragment can be changed to:

CHDIR(subdir)
includefile(onefile)
includefile(anotherfile)
includefile(yetanotherfile)
CHDIR(..)

The  current  directory,  as  given  to  CHDIR, only affects how
includefile will search for its files.

Note  that  this  example  assumes  that  the  current   working
directory is a member of Yodl’s include-path specification (cf.,
Yodl’s --include option).

COMMENT
The COMMENT function takes one parameter list. The text  in  the
list is treated as comment. I.e., it is ignored. The text is not
copied to the final output file.

COUNTERVALUE
COUNTERVALUE expands to the  value  of  a  counter.  Its  single
parameter  list must contain the name of a counter.  The counter
must have been created earlier using the builtin  DEFINECOUNTER.
Example:

The counter has value COUNTERVALUE(MYCOUNTER).

DECWSLEVEL
DECWSLEVEL  requires one (empty) parameter list.  It reduces the
current white-space level. The white-space  level  typically  is
used  in  files  that  only  define  Yodl macros. When no output
should  be  generated  while   processing   these   files,   the
white-space  level  can  be  used  to  check  for  this.  If the
white-space level exceeds zero, a warning will be  generated  if
the  file  produces  non-whitespace output. The builtin function
DECWSLEVEL is used to reduce the whitespace  level  following  a
previous call of INCWSLEVEL.

Once  the  white  space  level  exceeds  zero, no output will be
generated. White space, therefore will effectively  be  ignored.
The  white  space  level cannot be reduced to negative values. A
warning is issued  if  that  would  have  happened  if  it  were
allowed.

Example:

INCWSLEVEL()
DEFINESYMBOL(....)
DEFINEMACRO(...)(...)(...)
DECWSLEVEL()

Without   the   INCWSLEVEL  and  DECWSLEVEL,  calls,  the  above
definition would generate four empty lines to the output stream.

The  INCWSLEVEL  and  DECWSLEVEL  calls  may be nested. The best
approach is to  put  an  INCWSLEVEL  at  the  first  line  of  a
macro-defining  Yodl-file, and a matching DECWSLEVEL call at the
very last line.

DEFINECHARTABLE
DEFINECHARTABLE is used to define a character translation table.
The  function expects two parameterlists, containing the name of
the character table and character table translations on separate
lines. These character table  translations are of the form

character = quoted-string

Here,  character  is always a value within single quotes. It may
be a single character, an octal character value or a hexadecimal
character  value.  The  single  character  may  be prefixed by a
\-character (e.g., ’\\’). The octal character value  must  start
with  a backslash, followed by three octal digits (e.g., ’\045’.
The hexadecimal character value starts with 0x, followed by  two
hexadecimal  characters.  E.g., ’0xbe’. The double quoted string
may contain anything (but the  string  must  be  on  one  line),
possibly  containing  escape-sequences  as  well:  in the double
quoted string the standard C escape  sequences  \a  (alert),  \b
(beep),  \f  (formfeed),  \n (newline), \r (carriage return), \t
(tab), and \v (vertical tab) are  recognized  and  automatically
converted  to  their special meanings. Starting with Yodl 2.14.0
octal  and  hexadecimal  constants  may  also  be  used.   E.g.,
character  Y may also be specified using the octal value \131 or
the hexadecimal value \x59.  Any  other  character  following  a
defines itself: \\ represents a single backslash character.

Example:

DEFINECHARTABLE(demotable)(
’&’     = "&amp;"
’\\’    = "\\backslash"
’\045’  = "oct(45)"
’0xa4’  = "hex(a4)"
)

The  builtin  function  DEFINECHARTABLE  does  not  activate the
table. The table is merely defined. To  activate  the  character
translation table, use USECHARTABLE. The discussion of character
tables is postponed to section [CHARTABLES].

DEFINECOUNTER
DEFINECOUNTER creates a new counter, to be subsequently used by,
e.g,   the   USECOUNTER   function.  DEFINECOUNTER  expects  two
parameter list: the  name  of  the  counter  to  create  and  an
optional   initial   value.  By  default  the  counter  will  be
initialized to zero.

Examples:

DEFINECOUNTER(YEAR)(1950)
DEFINECOUNTER(NTIMES)()

DEFINEMACRO
DEFINEMACRO is used to define new macros. This function requires
three parameter lists:

o      An  identifier,  being  the  name  of  the macro to define. This
identifier  may  only  consist   of   uppercase   or   lowercase
characters. Note that it can not contain numbers, nor underscore
characters.

o      A number, stating the number of arguments that  the  macro  will
require once used. The number must be in the range 0 to 61.

o      The text that the macro will expand to, once used. This text may
contain the strings ARGx, x being 1, 2, etc..  At  these  places
the  arguments  to the macro will be pasted in. The numbers that
identify the arguments are 1 to 9, then A to Z and finally a  to
z.  This  gives  a  range  of  61 expandable arguments, which is
enough  for  all  real-life  applications.   For  example,   the
following fragment defines a macro bookref, which can be used to
typeset a reference to a book. It requires three arguments; say,
an author, a title and the name of a publisher:

DEFINEMACRO(bookref)(3)(
Author(s):           ARG1
Book title:          ARG2
)

Such a macro could be used as follows:

bookref(Sobotta/Becher)
(Atlas der Anatomie des Menschen)
(Urban und Schwarzenberg, Berlin, 1972)

When called, it would produce the following output:

Author(s):           Sobotta/Becher
Book title:          Atlas der Anatomie des Menschen
Published by:        Urban und Schwarzenberg, Berlin, 1972

While  applying a macro, the three parameter lists are pasted to
the places where ARG1, ARG2 etc. occur in the definition.

Note the following when defining new macros:

o      The parameter  list  containing  the  name  of  the  new  macro,
(bookref)   in   the  above  example,  must  occur  right  after
DEFINEMACRO. No spaces are allowed in between. Space  characters
and  newlines  may  however occur following this first parameter
list.

This behavior of the yodl program is similar to the usage of the
defined   macro:   the  author  information  must,  enclosed  in
parentheses,  follow  right  after  the  bookref  identifier.  I
implemented  this  feature to improve the distinguishing between
macros and real text. E.g., a macro me might be defined, but the
text

I like me (but so do you)

still  is  simple  text;  the  macro me only is activated when a
parenthesis immediately follows it.

o      Be careful when placing newlines or spaces in the definition  of
a new macro. E.g., the definition, as given:

DEFINEMACRO(bookref)(3)(
Author(s):           ARG1
Book title:          ARG2
)

introduces  extra  newlines  at  the beginning and ending of the
macro, which will be copied to the output each time the macro is
used.  The  extra  newline  occurs,  of course, right before the
sequence Author(s): and following  the  evaluation  of  ARG3.  A
simple  backslash  character  at the end of the DEFINEMACRO line
would prevent the insertion of extra newline characters:

DEFINEMACRO(bookref)(3)(\
Author(s):           ARG1
Book title:          ARG2
)

o      Note that when a macro is used which requires  no  arguments  at
all,  one empty parameter list still must be specified. E.g., my
macro package (see chapter [MACROPACKAGE]) defines  a  macro  it
that  starts  a  bullet  item  in  a  list.  The  macro takes no
arguments, but still must be typed as it().

This  behavior  is  consistent:  it  helps   distinguish   which
identifiers are macros and which are simple text.

o      Macro  arguments  may  evaluate to text. When a \ is appended to
the macro-argument, or in the default input  handling  within  a
non-zero  white-space  level (see section [INCWSLEVEL]) this may
invalidate a subsequent macro call. E.g., the macro

DEFINEMACRO(oops)(1)(
ARG1
XXnl()
)

will, when called as oops(hello world), produce the output:

hello worldXXnl()

To prevent this gluing to  arguments  to  subsequent  macros,  a
single + should be prepended to the macro call:

DEFINEMACRO(oops)(1)(
ARG1
+XXnl()
)

See also section [PLUSIDENT] obout the ‘+identifier’-sequence.

o      Note  the preferred layout of macro definitions and macro calls.
Adhere  to  this  form,  to  prevent  drowning   in   too   many
parentheses. In particular:

o      Put all elements of the macro definition on one line, except for
the macro-expansion itself. Each expansion element should be  on
a line by itself.

o      When  calling  macros  put  the macro parameter lists underneath
each other. If the macrolists  themselves  contain  macro-calls,
put  each  call  again  on  a  line  of  its  own, indenting one
tab-position beyond the location of the opening  parenthesis  of
the argument.

o      No  continnuation  backslashes  are  required  between parameter
lists. So, do not use them there to prevent unnecessary clutter.

o      With  complex  calls,  indent  just  the  arguments, and put the
parentheses in their required of logical locations.  Example  of
a complex call:

complex(
first(
ARG1
)(
ARG2
+XXnl()
)
ARG3
+nop()
ARG4
+XXnl()
)

o      Macro expansion proceeds as follows:

o      The parameter lists are read from the input

o      The   contents   of  the  parameters  then  replace  their  ARGx
references in the macro’s definition (in some exceptional cases,
clearly  indicated  as  such when applicable, the arguments will
themselves  be  evaluated  first,  and  then   these   evaluated
arguments  are used as replacements for their corresponding ARGx
references).

o      The now modified macro is read by Yodl’s lexical  scanner.  This
may  result  in  yet another macro expansion, which will then be
evaluated recursively.

o      Eventually, all expansion is completed (well,  should  complete,
since  Yodl  doesn’t test for eternal recursion) and scanning of
the  input  continues  beyond  the  original  macro  call.   For
example, assume we have the following two macros:

DEFINEMACRO(First)(1)(
Hello ARG1
+XXnl()
)
DEFINEMACRO(Second)(1)(
First(ARG1)
First(ARG1)
)

and the following call is issued:

Second(Yodl)

then the following will happen:

o      Second(Yodl) is read as encountered.

o      ARG1 in Second is replaced by YODL, and the resulting macro body
is sent to the lexical scanner for evaluation: It will see:

First(Yodl)First(Yodl)

o      The first call to First() is now evaluated. This will put (after
replacing ARG1 by YODL) the following on the scanner’s input:

Hello Yodl+XXnl()First(Yodl)

o      Hello  Yodl  contains  no  macro  call,  so it is written to the
output stream. Remains:

+XXnl()First(Yodl)

o      Assume XXnl() merely contains  a  newline  (represented  by  \n,
here),  so  +XXnl()  is  now replaced by \n. This results in the
following input for the lexical scanner:

\nFirst(Yodl)

o      The \n is now written to the  output  stream,  and  the  scanner
sees:

First(Yodl)

o      The  second  call to First() is now evaluated. This will put the
following on the scanner’s input:

Hello Yodl+XXnl()

o      Hello Yodl is written to the output stream. Remains:

+XXnl()

o      +XXnl() is now replaced by \n. The lexical scanner sees:

\n

o      The newline is printed and we’re done.

DEFINESYMBOL
NOTE: this function has changed at the release of Yodl 2.00.  It
now expects two parameter lists, rather than one

DEFINESYMBOL  expects two arguments. An identifier, which is the
name of the symbol to define,  and  the  textual  value  of  the
symbol.  If the second argument is empty, the symbol is defined,
but has an empty value.

The earlier interpretation of a Yodl symbol as  a  logical  flag
can  still  be  used,  but  allowing it to obtain textual values
greatly simplifies various Yodl macros.

Example:

DEFINESYMBOL(Yodl)(Your own document language)
DEFINESYMBOL(Options)()

DELETECHARTABLE
DELETECHARTABLE removes a definition of a character  table  that
was  defined  by  DEFINECHARTABLE.  This  function  expects  one
argument: the name of the character table remove.

It’s an error to attempt to delete a  character  table  that  is
currently  in  use  or  to  attempt  to  delete  a  non-existing
character table.

Example:

DELETECHARTABLE(mytable)

DELETECOUNTER
DELETECOUNTER removes a definition of a counter that was defined
by  DEFINECOUNTER.  This function expects one argument: the name
of the counter to remove.

If the counter does not exist, a warning is issued.  It  is  not
considered an error to try to delete a counter that has not been
defined earlier.

Example:

DELETECOUNTER(mycounter)

DELETEMACRO
DELETEMACRO removes a definition of a macro that was defined  by
DEFINEMACRO. This function takes one argument: the macro name to
remove.

There is no error condition (except for syntax errors): when  no
macro  with a matching name was previously defined, no action is
taken.

For example, the  safe  way  to  define  a  macro  is  by  first
undefining  it.  This ensures that possible previous definitions
are removed first:

Example:
DELETEMACRO(mymacro)

DELETENOUSERMACRO
DELETENOUSERMACRO  removes  a  ‘nousermacro’   definition.   The
function  expects  one  argument:  the name of the ‘nousermacro’
identifier to be removed from the nousermacro-set.

There is no error condition (except for syntax errors): when the
identifier  wasn’t stored as a ‘nousermacro’ no action is taken.

Example:
DELETENOUSERMACRO(mymacro)

DELETESYMBOL
DELETESYMBOL removes the definition of  a  symbol  variable.  It
expects  one parameter list, holding the name of the variable to
deleted.

This macro has no error condition (except  for  syntax  errors):
the  symbol  in  question may be previously defined, but that is
not necessary.

Example:

DELETESYMBOL(Options)

DUMMY  This function is obsolete. It does nothing, and may  be  removed
in future versions of Yodl.

ENDDEF ENDDEF  is  obsolete,  and should be replaced by DECWSLEVEL.  It
may be removed in future versions of Yodl.

ERROR  The ERROR function takes one argument: text to  display  to  the
standard  error  stream.  The current input file and line number
are also displayed. After displaying the text, the yodl  program
aborts with an exit status of 1.

The  text  passed  to  the  function  is expanded first. See the
example.

The ERROR function is an example of a  function  that  evaluates
its parameter list itself.

This  command  can  be  used,  e.g.,  in a macro package when an
incorrect macro is expanded. In my macro  package  (see  chapter
[MACROPACKAGE])  the  ERROR function is used when the sectioning
command chapter()  is  used  in  an  article  document  (in  the
package, chapter’s are only available in books or reports).

An  analogous  builtin  function is WARNING, which also prints a
message but does not exit (see section [WARNING]).

Example: In the following call, COUNTERVALUE(NTRIES) is replaced
by its actual value:

ERROR(Stopping after COUNTERVALUE(NTRIES) attempts)

EVAL   The  EVAL function takes one argument: the text to be evaluated.
This function allows you to perform an  indirect  evaluation  of
Yodl  commands.  Assume that there is a symbol varnam containing
the name of a counter variable, then the following will  display
the value of the counter, incrementing it first:

EVAL(NOTRANS(USECOUNTER)(SYMBOLVALUE(varnam)))

The actions of the EVAL function can be described as follows:

o      First,   the   NOTRANS(USECOUNTER)   is   evaluated,   producing
USECOUNTER.

o      Next, the open parentheses  is  processed,  producing  the  open
parenthesis itself

o      Then,  SYMBOLVALUE(varnam) is evaluated, producing the name of a
counter, e.g. ‘counter’.

o      Eventually the closing parentheis is  processed,  producing  the
closing parenthesis itself.

o      All this results in the text

USECOUNTER(counter)

o      This  text is now presented to Yodl’s lexical scanner, resulting
in incrementing the  counter,  and  displaying  its  incremented
value.   It  should  be realized that macro arguments themselves
are usually not evaluated. So, a construction like

USECOUNTER(EVAL(SYMBOLVALUE(varnam)))

will fail, since EVAL(SYMBOLVALUE(varnam)) is not a  legal  name
for  a  counter:  the  EVAL()  call is used here as an argument,
which is not expanded. The distinction is subtle, and is  caused
by   the   fact   that  builtin  functions  receive  unprocessed
arguments, and may impose certain  requirements  on  them  (like
USECOUNTER requiring the name of a counter).

Summarizing: EVAL acts as follows:

o      Its argument is presented to Yodl’s lexical scanner

o      The  output  produced  by the processing of the argument is then
inserted into the input stream in  lieu  of  the  original  EVAL
call.

Mosy  built-in  functions  will not evaluate their arguments. In
fact, only ERROR, EVAL, FPUTS, INTERNALINDEX, TYPEOUT, UPPERCASE
and WARNING() will evaluate their arguments.

Postponing evaluations allows you to write:

DEFINESYMBOL(later)(SYMBOLVALUE(earlier))

Eventually, and not when later is defined, a statement like

SYMBOLVALUE(later)

will    produce   the   value   of   earlier   at   the   moment
SYMBOLVALUE(later) is processed. This is,  in  all  its  complex
consequences, what would be expected in most cases. It allows us
to write general macros producing output that is only  evaluated
when  the  text  of  symbols  and  values  of  arguments  become
eventually, rather than when the macro is defined, available.

Decisions like these invariably result in questions  like  ‘what
if  I  have to keep original values in some situation?’ In those
situations EVAL() must be used. The following example shows  the
definition  of three symbols: one receives an initial value, two
will return one’s actual value when two’s  value  is  displayed,
three will, using EVAL(), store one’s initial value. The example
also shows yet another way to suppress macro  calls. It uses the
macro  nop()  which  is  defined  in the all standard conversion
types.

DEFINESYMBOL(one)(This is one, before)
DEFINESYMBOL(two)(SYMBOLVALUE(one))
EVAL(DEFINESYMBOL+nop()(three)(SYMBOLVALUE(one)))
SETSYMBOL(one)(this is one, after)
SYMBOLVALUE(two)
SYMBOLVALUE(three)

FILENAME
The  function  FILENAME()  produces  an  absolute  path  to  the
currently  processed  Yodl  file.  This  is  not necessarily the
canonical path name, as it may contain current- and  parent-path
directories.

FPUTS  The  function  FPUTS expects two arguments: the first argment is
information to be appended to a file, whose name is given as the
second  argument. The first argument is processed by Yodl before
it is appended to the requested  filename,  so  it  may  contain
macro calls.

For  example, the following statement will append a countervalue
to the mentioned file:

FPUTS(There have been COUNTERVALUE(attempts) attempts)(/tmp/logfile)

The second argument (name of the file) is not evaluated, but  is

IFBUILTIN
The  IFBUILTIN  function tests whether its first argument is the
name of a builtin function. If so, the second parameter list  is
evaluated,  else,  the  third  parameter  list is evaluated. All
three parameter lists  (the  variable,  the  true-list  and  the
false-list)  must  be  present;  though the true-list and/or the
false-list may be empty parameter lists.

Example:

IFBUILTIN(IFBUILTIN)(\
‘BUILTIN’ is a builtin - function
)(\
‘BUILTIN’ is NOT a builtin - function
)

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFCHARTABLE
The IFCHARTABLE function tests whether its first argument is the
name  of  a  character  table.  The character table needs not be
active.  If the name is the  name  of  a  character  table,  the
second  parameter  list  is evaluated, else, the third parameter
list is evaluated. All three parameter lists (the name, the true
list  and  the false list) must be present; though the true list
and/or the false list may be empty parameter lists.

Example:

IFCHARTABLE(standard)(\
‘standard’ is a character tablebuiltin - function
)(\
‘standard’ is NOT a character tablebuiltin - function
)

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFDEF  The IFDEF function  tests  for  the  definition  status  of  the
argument in its first parameter list. If it is a defined entity,
the  second  parameter  list  is  evaluated,  else,  the   third
parameter  list  is  evaluated.  All  three parameter lists (the
entity, the true list and  the  false  list)  must  be  present;
though  the  true  list  and/or  the  false  list  may  be empty
parameter lists.

The true list is evaluated if the first argument is the name of:

o      a built-in function, or

o      a character table, or

o      a counter, or

o      a no-user-macro symbol, or

o      a symbol, or

o      a user-defined macro, or Example:

IFDEF(someName)(\
‘someName’ is a defined entity
)(\
‘someName is not defined.
)

Please note the preferred layout: The first argument immediately
follows the function name, then the second  argument  (the  true
list)  is  indented,  as  is  the false list. The layout closely
follows the preferred  layout  of  if-else  statements  of  many
programming languages.

IFEMPTY
IFEMPTY  expects  three  arguments:  a symbol, a true-list and a
false-list. IFEMPTY evaluates to the true-list if the symbol  is
an empty string; otherwise, it evaluates to the false-list.

The  function does not further evaluate its argument. Its use is
primarily to test whether a macro has received  an  argument  or
not. If the intent is to check whether a symbol’s value is empty
or not, IFSTREQUAL [IFSTREQUAL] should be used, where the  first
argument  is  the  name  of a symbol, and the second argument is
empty.

Example:

IFEMPTY(something)(\
‘something’ is empty...
)(\
‘something’ is not an empty string
)

In the same way, IFEMPTY can be used to test whether an argument
expands  to a non-empty string. A more elaborate example follows
below. Say you  want  to  define  a  bookref  macro  to  typeset
information  about  an  author,  a  book  title  and  about  the
publisher. The publisher information may be  absent,  the  macro
then typesets unknown:
\
DEFINEMACRO(bookref)(3)(\
Author(s):      ARG1
Title:          ARG2
IFEMPTY(ARG3)
(\
Unknown\
)(\
ARG3\
)
)

Using the macro, as in:
\
bookref(Helmut Leonhardt)
(Histologie, Zytologie und Microanatomie des Menschen)
()

would  now  result  in the text Unknown behind the Published by:
line.

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFEQUAL
IFEQUAL expects four argument lists. It tests whether its  first
argument  is  equal  to  its  second  argument. If so, the third
parameter list is evaluated, else, the fourth parameter list  is
evaluated.  All  four argument lists must be present, though all
can be empty lists.

The first two arguments of IFEQUAL should be integral  numerical
arguments. In order to determine whether the first two arguments
are equal, their values are determined:

o      If the argument starts with an integral  numerical  value,  that
value is the value of the argument.

o      If the argument is the name of a counter, the counter’s value is
the value of the argument

o      If the values of the  first  two  arguments  van  be  determined
accordingly, their equality will determine whether the true list
(when the values are equal) or the false list (when  the  values
are unequal) will be evaluated.

o      Otherwise, IFEQUAL will evaluate the false list.

Example:

IFEQUAL(0)()(\
0 and an empty string are equal
)(\
0 and an empty string are not equal
)

Please note the preferred layout: The first argument immediately
follows the function name, then the second  argument  (the  true
list)  is  indented,  as  is  the false list. The layout closely
follows the preferred  layout  of  if-else  statements  of  many
programming languages.

IFGREATER
IFGREATER  expects  four  argument  lists.  It tests whether its
first argument is greater to its second  argument.  If  so,  the
third  parameter  list  is evaluated, else, the fourth parameter
list is evaluated. All four  argument  lists  must  be  present,
though all can be empty lists.

The   first  two  arguments  of  IFGREATER  should  be  integral
numerical arguments. In order to determine whether the first two
arguments are equal, their values are determined:

o      If  the  argument  starts with an integral numerical value, that
value is the value of the argument.

o      If the argument is the name of a counter, the counter’s value is
the value of the argument

o      If  the  values  of  the  first  two arguments van be determined
accordingly, their order relation  will  determine  whether  the
true  list  (when  the  first  value  is greater than the second
value) or the false list (when the first  value  is  smaller  or
equal than the second value) will be evaluated.

o      Otherwise, IFGREATER will evaluate the false list.

Example:

IFGREATER(counter)(5)(\
counter exceeds the value 5
)(\
counter does not exceeds the value 5, or counter is no Yodl-counter.
)

Please note the preferred layout: The first argument immediately
follows the function name, then the second  argument  (the  true
list)  is  indented,  as  is  the false list. The layout closely
follows the preferred  layout  of  if-else  statements  of  many
programming languages.

IFMACRO
The  IFMACRO  function  tests  whether its first argument is the
name of a macro. If the name is the name of a macro, the  second
parameter  list  is evaluated, else, the third parameter list is
evaluated. All three parameter lists (the name,  the  true  list
and the false list) must be present; though the true list and/or
the false list may be empty parameter lists.

Example:

IFMACRO(nested)(\
‘nested’ is the name of a macro
)(\
There is no macro named ‘nested’
)

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFSMALLER
IFSMALLER expects four argument  lists.  It  tests  whether  its
first  argument  is  smaller  to its second argument. If so, the
third parameter list is evaluated, else,  the  fourth  parameter
list  is  evaluated.  All  four  argument lists must be present,
though all can be empty lists.

The  first  two  arguments  of  IFSMALLER  should  be   integral
numerical arguments. In order to determine whether the first two
arguments are equal, their values are determined:

o      If the argument starts with an integral  numerical  value,  that
value is the value of the argument.

o      If the argument is the name of a counter, the counter’s value is
the value of the argument

o      If the values of the  first  two  arguments  van  be  determined
accordingly,  their  order  relation  will determine whether the
true list (when the first  value  is  smaller  than  the  second
value)  or  the false list (when the first value is greater than
or equal to the second value) will be evaluated.

o      Otherwise, IFSMALLER will evaluate the false list.

Example:

IFSMALLER(counter)(5)(\
counter is smaller than the value 5, or counter is no Yodl-counter
)(\
counter exceeds the value 5
)

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFSTREQUAL
IFSTREQUAL tests for the equality of  two  strings.  It  expects
four  arguments:  two  strings to match, a true list and a false
list. The true list is only evaluated when the contents  of  the
two string arguments exactly match.

The first two arguments of IFSTREQUAL are partially evaluated:

o      If  the  argument is the name of a symbol, the symbol’s value is
the value of the argument

o      Otherwise, the argument itself is used.

In the degenerate case  where  the  string  to  be  compared  is
actually  the  name of a SYMBOL, use a temporary SYMBOL variable
containing the name of that symbol, and compare it  to  whatever
you  want to compare it with. Alternatively, write a blank space
behind the arguments, since the arguments are  then  interpreted
‘as  is’.  In practice, the need for these constructions seem to
arise seldomly, however.

Example:

IFSTREQUAL(MYSYMBOL)(Hello world)(
The symbol ‘MYSYMBOL’ holds the value ‘Hello world’
)(
The symbol ‘MYSYMBOL’ doesn’t hold the value ‘Hello world’
)

IFSTRSUB
IFSTRSUB tests whether a  string  is  a  sub-string  of  another
string.  It acts similar to IFSTREQUAL, but it tests whether the
second string is part of the first one.

The first two arguments of IFSTREQULA are partially evaluated:

o      If the argument is the name of a symbol, the symbol’s  value  is
the value of the argument

o      Otherwise, the argument itself is used.

In  the  degenerate  case  where  the  string  to be compared is
actually the name of a SYMBOL, use a temporary  SYMBOL  variable
containing  the  name of that symbol, and compare it to whatever
you want to compare it with. Alternatively, write a blank  space
behind  the  arguments, since the arguments are then interpreted
‘as is’. In practice, the need for these constructions  seem  to
arise seldomly, however.

Example:

IFSTRSUB(haystack)(needle)(
‘needle’ was found in ‘haystack’
)(
)

Note  that  both  ‘haystack’  and  ‘needle’  may be the names of
symbols. If they are, their contents  are  is  compared,  rather
than the literal names ‘haystack’ and ‘needle’

IFSYMBOL
The  IFSYMBOL  function  tests whether its first argument is the
name of a symbol. If it is the name  of  a  symbol,  the  second
parameter  list  is evaluated, else, the third parameter list is
evaluated. All three parameter lists (the name,  the  true  list
and the false list) must be present; though the true list and/or
the false list may be empty parameter lists.

Example:

IFSYMBOL(nested)(\
‘nested’ is the name of a symbol
)(\
There is no symbol named ‘nested’
)

Please note the preferred layout: The first argument immediately
follows  the  function  name, then the second argument (the true
list) is indented, as is the  false  list.  The  layout  closely
follows  the  preferred  layout  of  if-else  statements of many
programming languages.

IFZERO IFZERO expects three parameter lists. The first argument defines
whether  the  whole  function expands to the true list or to the
false list.

The first argument of IFZERO should  be  an  integral  numerical
value. Its value is determined as follows:

o      If  the  argument  starts with an integral numerical value, that
value is the value of the argument.

o      If the argument is the name of a counter, the counter’s value is
the value of the argument

o      Otherwise, IFZERO will evaluate the false list.

Note that, starting with Yodl version 2.00 the first argument is
not evaluated any further.  So,  COUNTERVALUE(somecounter)  will
always be evaluated as 0. If the value of a counter is required,
simply provide its name as the  first  argument  of  the  IFZERO
function.

Example:

DEFINEMACRO(environment)(2)(\
IFZERO(ARG2)(\
NOEXPAND(\end{ARG1})\
)(\
NOEXPAND(\begin{ARG1})\
)\
)

Such a macro may be used as follows:

environment(center)(1)
Now comes centered text.
environment(center)(0)

which  would  of  course  lead  to  \begin and \end{center}. The
numeric second argument is used here as a on/off switch.

INCLUDEFILE
INCLUDEFILE  takes  one  argument,  a  filename.  The  file   is
processed  by  Yodl.  If  a  file  should  be  inserted  without
processing     the     builtin     function      NOEXPANDINCLUDE
[NOEXPANDINCLUDE]  or  NOEXPANDPATHINCLUDE [NOEXPANDPATHINCLUDE]
should be used.

The yodl program supplies, when necessary, an extension  to  the
filename.    The  supplied  extension  is  .yo,  unless  defined
otherwise during the compilation of the program.

Furthermore, Yodl tries to locate the file in the Yodl’s include
path  (which  may be set using the --include option). The actual
value of the include path is shown  in  the  usage  information,
displayed when Yodl is started without arguments.

Example:

INCLUDEFILE(latex)

will  try to include the file latex or latex.yo from the current
include parth. When the file is not found, Yodl aborts.

INCLUDELIT, INCLUDELITERAL
INCLUDELIT and  INCLUDELITERAL  are  obsolete.   NOEXPANDINCLUDE
[NOEXPANDINCLUDE]  or  NOEXPANDPATHINCLUDE [NOEXPANDPATHINCLUDE]
should be used instead.

INCWSLEVEL
INCWSLEVEL requires one (empty) parameter  list.   It  increases
the  current  white-space level. The white-space level typically
is used in files that only define Yodl macros.  When  no  output
should   be   generated   while   processing  these  files,  the
white-space level  can  be  used  to  check  for  this.  If  the
white-space  level  exceeds zero, a warning will be generated if
the file produces non-whitespace output.  The  builtin  function
DECWSLEVEL  is  used  to reduce the whitespace level following a
previous call of INCWSLEVEL.

Once the white space level  exceeds  zero,  no  output  will  be
generated.  White  space, therefore will effectively be ignored.
The white space level cannot be reduced to  negative  values.  A
warning  is  issued  if  that  would  have  happened  if it were
allowed.

Example:

INCWSLEVEL()
DEFINESYMBOL(....)
DEFINEMACRO(...)(...)(...)
DECWSLEVEL()

Without  the  INCWSLEVEL  and  DECWSLEVEL,  calls,   the   above
definition would generate four empty lines to the output stream.

The INCWSLEVEL and DECWSLEVEL calls  may  be  nested.  The  best
approach  is  to  put  an  INCWSLEVEL  at  the  first  line of a
macro-defining Yodl-file, and a matching DECWSLEVEL call at  the
very last line.

INTERNALINDEX
INTERNALINDEX  expects  one  argument list. The argument list is
evaluated and written to the index file.

The index file is defined since Yodl version 2.00, and  contains
the  fixup  information  which  was previously written to Yodl’s
output as the .YODLTAGSTART.  ... .YODLTAGEND. sequence.

The index file allows  for  greated  processing  speed,  at  the
expense   of   an   additional  file.  The  associated  yodlpost
postprocessing program will read and process the index file, and
will fixup the corresponding yodl-output accordingly.

The  index  file  is  not  created when output is written to the
standard output name, since Yodl is unable to request the system
for the current file offset.

The   entries  of  the  index  file  always  fit  on  one  line.
INTERNALINDEX will alter newline characters in its argument into
single blank spaces. Each line starts with the current offset of
Yodl’s output file, thus indicating the exact location  where  a
fixup is requested. An example of a produced fixup line could be

3004 ref MACROPACKAGE

indicating that at offset 3004 in the  produced  output  file  a
reference  to  the  label  MACROPACKAGE is requested. Assuming a
html  conversion,  The  postprocessor   will   thereupon   write
something like

<a href="outfile04.html#MACROPACKAGE">4.3.2.</a>

into the actual output file while processing Yodl’s output up to
offset location 3004.

Consequently, producing Yodl-output  normally  consists  of  two
steps:

o      First,  Yodl  itself  is  started, producing, e.g., out.idx (the
index file) and out.yodl (Yodl’s raw output).

o      Then, Yodl’s  post-processor  processes  out.idx  and  out.yodl,
producing  one or more final output files, in which the elements
of the index file have been properly handled. This may result in
multiple   output   file,   like   report.html,   report01.html,
report02.html etc.

NEWCOUNTER
NEWCOUNTER is obsolete. DEFINECOUNTER [DEFINECOUNTER] should  be

NOEXPAND
NOEXPAND  is  used to send text to the final output file without
being expanded by Yodl (the other methods are  the  CHAR  macro,
see   section   [CHAR],  and  the  NOTRANS  macro,  see  section
[NOTRANS]).  NOEXPAND takes one  parameter  list,  the  text  in
question.  Whatever  occurs  in  the  argument is not subject to
parsing or expansion by Yodl, but is simply copied to the output
file  (except  for  CHAR  functions  in  the argument, which are
expanded. If  CHAR-expansion  is  not  required  either  NOTRANS
[NOTRANS] can be used).

Furthermore, the contents of the parameter list are also subject
to character table  translations,  using  the  currently  active
table.  This  should  come  as  no  surprise. Ignoring character
tables would make both the processing  of  CHAR  calls  and  the
NOTRANS function superfluous.

So, the following situations are recognized:

----------------------------------------------
support chartables
and CHAR
------------------------------
Macro expansion   yes          no
----------------------------------------------

Yes               (standard)   Push chartable
(standard)
Pop chartable
No                NOEXPAND     NOTRANS
----------------------------------------------

E.g.,  let’s  assume that you need to write in your document the
following text:

INCLUDEFILE(something or the other)
IFDEF(onething)(
...
)(
....
)
NOEXPAND(whatever)

The way to accomplish this is by prefixing the text by  NOEXPAND
followed  by  an  open  parenthesis,  and  by postfixing it by a
closing parenthesis.  Otherwise, the text would be  expanded  by
Yodl while processing it (and would lead to syntax errors, since
the text isn’t correct in the sence of the Yodl language).

For this function, keep the following caveats in mind:

o      There is only one thing that  a  NOEXPAND  cannot  protect  from
expansion: an ARGx in a macro definition. The argument specifier
is always processed. E.g., after

DEFINEMACRO(thatsit)(1)(
That is --> NOEXPAND(ARG1) <-- it!
)
thatsit(after all)

the ARG1 inside the NOEXPAND statement is  replaced  with  after
all.

o      The  NOEXPAND  function must, as all functions, be followed by a
parameter list. The parentheses of the list  must  therefore  be
‘balanced’.   For  unbalanced lists, use CHAR(40) to set an open
parenthesis, or CHAR(41) to typeset a closing parenthesis.

NOEXPANDINCLUDE
NOEXPANDINCLUDE takes one argument,  a  filename.  The  file  is
included.

The  filename is uses ‘as is’. The include path is not used when
locating this file.

The argument to NOEXPANDINCLUDE is partially evaluated:

o      If the argument is the name of a symbol, the symbol’s  value  is
the value of the argument

o      Otherwise,  the argument itself is used.  The thus obtained file
name is not further evaluated: in particular,  it  will  not  be
subject to character translations.

The  contents of the file are included literally, not subject to
macro expansion. Character translations are  performed,  though.
If character translations are not appropriate, PUSHCHARTABLE can
be used to suppress character table translations temporarily.

The  purpose  of  NOEXPANDINCLUDE  is  to  include  source  code
literally in the document, as in:

NOEXPANDINCLUDE(literal.c)

The  function  NOEXPANDPATHINCLUDE  can be used to insert a file
which is located in one of the directories specified  in  Yodl’s
include path.

NOEXPANDPATHINCLUDE
NOEXPANDPATHINCLUDE  takes one argument, a filename. The file is
included. The file is searched for in the directories  specified
in Yodl’s includepath.

The argument to NOEXPANDPATHINCLUDE is partially evaluated:

o      If  the  argument is the name of a symbol, the symbol’s value is
the value of the argument

o      Otherwise, the argument itself is used.  The thus obtained  file
name  is  not  further  evaluated: in particular, it will not be
subject to character translations.

Like the NOEXPANDINCLUDE function, the contents of the file  are
included  literally,  not  subject to macro expansion. Character
translations are performed, though.  If  character  translations
are  not  appropriate, PUSHCHARTABLE [PUSHCHARTABLE] can be used
to suppress character table translations temporarily.

The purpose of NOEXPANDPATHINCLUDE is to include source code  as
defined in a macro package literally into the document, as in:

NOTRANS
NOTRANS  copies  its  one argument literally to the output file,
without expanding macros  in  it  and  without  translating  the
characters  with  the  current  translation  table.  The NOTRANS
function is typically used  to  send  commands  for  the  output
format to the output file.

For example, consider the following code fragment:

COMMENT(--- Define character translations for \, { and } in LaTeX. ---)
DEFINECHARTABLE(standard)(
’\\’    =    "$\\backslash$"
’{’     =    "\\verb+{+"
’}’     =    "\\verb+}+"
)

COMMENT(--- Activate the translation table. ---)
USECHARTABLE(standard)

COMMENT(--- Now two tests: ---)

NOEXPAND(\input{epsf.tex})
NOTRANS(\input{epsf.tex})

NOEXPAND will send

$\backslash$input\verb+{+epsf.tex\verb+}+

since  the  characters  in  its argument are translated with the
standard translation  table.  In  contrast,  NOTRANS  will  send
\input{epsf.tex}.

The  parameter  list of NOTRANS must be balanced with respect to
its parentheses. When using an unbalanced  set  of  parentheses,
use CHAR(40) to send a literal (, or CHAR(41) to send a ).

The   NOEXPAND   description   summarizes  all  combinations  of
character translations and/or macro expansion, and how they  are
handled and realized by Yodl.

NOUSERMACRO
NOUSERMACRO  controls yodl’s warnings in the following way: When
Yodl is started with the -w  flag  on  the  command  line,  then
warnings  are  generated  when  Yodl encounters a possible macro
name, followed by a parameter list, without finding a  macro  by
that  name.   Yodl  then  prints  something  like  cannot expand
possible user macro.

Examples of such sequences are, The  necessary  file(s)  are  in
/usr/local/lib/yodl,  or  see  the  manual  page for sed(1). The
candidate macros are file and sed; these  names  could  just  as
well be ‘valid’ user macros followed by their parameter list.

When  a  corresponding NOUSERMACRO statement appears before yodl
encounters the candidate macros,  no  warning  is  generated.  A
fragment might therefore be:

NOUSERMACRO(file sed)
The necessary file(s) are in ...
See the manual page for sed(1).

The  NOUSERMACRO  accepts  one  or  more  names in its argument,
separated by white space, commas, colons, or semi-colons.

OUTBASE
OUTBASE inserts the current basename of the output file into the
output  file.  The basename is the name of the file of which the
directory components and extension were stripped.

If the output file is the standard output file, - is inserted.

OUTDIR OUTDIR inserts the current path name of the output file into the
output  file.  The  path  name  is  a, not necessarily absolute,
designator of the directory in which the output file is located.
If  the  output  file is indicated as, e.g., -o out, then OUTDIR
simply inserts a dot.

If the output file  is  the  standard  output  file,  a  dot  is
inserted too.

OUTFILENAME
OUTFILENAME inserts the current filename of the output file into
the output file. The filename is the name of the file  of  which
the directory components  were stripped.

If the output file is the standard output file, - is inserted.

PARAGRAPH
PARAGRAPH  isn’t really a builtin function, but as it is handled
especially by Yodl, it is described here nonetheless.   Starting
with Yodl 2.00  PARAGRAPH operates as follows:

If  the  macro is not defined, new paragraphs, defined as series
of consecutive empty lines written to the output stream, are not
handled  different  from  any other series of characters sent to
the output stream. I.e., they are inserted into that stream.

However, if the macro  has  been  defined,  Yodl  will  call  it
whenever  a  new  paragraph (defined as a series of at least two
blank lines) was recognized.

The empty lines that were actually recognized  may  be  obtained
inside  the PARAGRAPH macro from the XXparagraph symbol, if this
symbol has been be defined by that time.  If  defined,  it  will
contain  the  white space that caused Yodl to call the PARAGRAPH
macro.

Note that, in order to inspect XXparagraph  it  must  have  been
defined first. Yodl itself will not define this symbol itself.

The  PARAGRAPH macro should be  defined as a macro not expecting
arguments.  The macro is thus given  a  chance  to  process  the
paragraph  in a way that’s fitting for the particular conversion
type. If the PARAGRAPH macro  produces  series  of  empty  lines
itself,  then  those empty lines will not cause Yodl to activate
PARAGRAPH. So, Yodl itself will not recursively call  PARAGRAPH,
although  the  macro  could  call itself recursively. Of course,
such  recursive  activcation  of  PARAGRAPH  is  then  the  sole
responsibility of the macro’s author, and not Yodl’s.

Some  document  languages  do  not  need paragraph starts; e.g.,
LaTeX handles its own paragraphs. Other  document  languages  do
need it: typically, PARAGRAPH is then defined in a macro file to
trigger some special action. E.g., a HTML converter might define
a paragraph as:

DEFINEMACRO(PARAGRAPH)(0)(
XXnl()
NOTRANS(<p>)
)

A  sytem  like xml has more strict requirements. Paragraphs here
must be opened and closed using pairs of <p> and </p>  tags.  In
those cases an auxiliary counter can be used to indicate whether
there is an open paragraph or not.  The  PARAGRAPH  macro  could
check  for  this  as  follows,  assuming  the  availability of a
counter XXp:

DEFINEMACRO(PARAGRAPH)(0)(
XXnl()
IFZERO(XXp)(
)(
NOTRANS(</p>)
)
NOTRANS(<p>)
SETCOUNTER(XXp)(1)
)

Note that  the  above  fragment  exemplifies  an  approach,  not
necessarily  the  implementation  of  the PARAGRAPH macro for an
xml-convertor.

PIPETHROUGH
The builtin function PIPETHROUGH is, besides SYSTEM, the  second
function  with which a Yodl document can affect its environment.
Therefore, the danger  of  ‘live  data’  exists  which  is  also
described  in  the  section about SYSTEM (see section [SYSTEM]).
Nevertheless, PIPETHROUGH can be very useful. It is intended  to
use  external  programs to accomplish special features. The idea
is that an external command is started, to which a block of text
from within a Yodl document is ‘piped’. The output of that child
program is piped back into the Yodl document; hence, a block  of
text  is  ‘piped  through’  an  external  program.   Whatever is
received again in the Yodl run, is further processed.

The PIPETHROUGH function takes two arguments:

o      the command to run, and

o      the text to send to that command.

Functionally, the occurrence of the PIPETHROUGH function and  of
its  two  arguments  is  replaced  by whatever the child program
produces on its standard output.

An example might be the inclusion of the current date, as in:

The current date is:
PIPETHROUGH(date)()

In this example the command is date and the text to send to that
program is empty.

The  main  purpose of this function is to provide a way by which
external programs can be used to create, e.g., tables or figures
for a given output format.  Further releases of Yodl may contain
such dedicated programs for the output formats.

POPCHARTABLE
Character tables which are pushed onto  the  table  stack  using
PUSHCHARTABLE()  are restored (popped) using POPCHARTABLE(). For
a  description  of  this  mechanism  please  refer  to   section
[PUSHINGTABLES].

POPCOUNTER
POPCOUNTER  is  used  to  remove  the  topmost  counter from the
counter stack.  The values of counters may be pushed on a  stack
using  PUSHCOUNTER  [PUSHCOUNTER]. To remove the topmost element
of a counter’s stack POPCOUNTER is available. POPCOUNTER expects
one  argument:  the  name  of the counter to pop. The previously
pushed value then becomes  the  new  value  of  the  counter.  A
counter’s  value may be popped after defining it, whereafter the
stack will be empty, but the counter will still be  defined.  In
that case, using the counter’s value is considered an error.

Examples:

DEFINECOUNTER(YEAR)(1950)
POPCOUNTER(YEAR)
COMMENT(YEAR now has an undefined value)

POPMACRO
POPMACRO   is  used  to  remove  the  actual  macro  definition,
restoring a previously pushed definition.  The values of  macros
may  be pushed on a stack using PUSHMACRO. To remove the topmost
element of a  macro’s  stack  POPMACRO  is  available.  POPMACRO
expects  one  argument:  the  name  of  the  macro  to  pop. The
previously pushed value then becomes the new value of the macro.

A  macro’s value may be popped after defining it, whereafter the
stack will be empty, but the macro will  still  be  defined.  In
that case, using the macro is considered an error.

Example:

DEFINEMACRO(Hello)(1)(Hello, ARG1, this is a macro definition)
Hello(Karel)
PUSHMACRO(Hello)(1)(Hello, ARG1, this is the new definition)
Hello(Karel)
POPMACRO(Hello)
Hello(Karel)
COMMENT(The third activation of Hello() produces the same output
as the first activation)

POPSYMBOL
POPSYMBOL  is  used to remove the topmost symbol from the symbol
stack.  The values of symbols may be pushed  on  a  stack  using
PUSHSYMBOL  [PUSHSYMBOL].  To  remove  the  topmost element of a
symbol’s stack POPSYMBOL is available.

POPSYMBOL expects one argument: the name of the symbol  to  pop.
The  previously  pushed  value then becomes the new value of the
symbol. A symbol’s  value  may  be  popped  after  defining  it,
whereafter the stack will be empty, but the symbol will still be
defined. In that case, using the symbol’s value is considered an
error.

Example:

DEFINESYMBOL(YEAR)(This happened in 1950)
POPSYMBOL(YEAR)
COMMENT(YEAR now has an undefined value)

POPWSLEVEL
POPWSLEVEL  is  used  to  remove  the  topmost  wslevel from the
wslevel stack.  The values of wslevels may be pushed on a  stack
using  PUSHWSLEVEL  [PUSHWSLEVEL].  See  also section DECWSLEVEL
[DECWSLEVEL]

To remove the topmost element of a wslevel’s stack POPWSLEVEL is
available.  POPWSLEVEL  expects  one  argument:  the name of the
wslevel to pop. The previously pushed value then becomes the new
value  of  the  wslevel.  A  wslevel’s value may be popped after
defining it, whereafter the stack will be empty, but the wslevel
will  still  be defined. In that case, using the wslevel’s value
is considered an error.

Example:

COMMENT(Assume WS level is zero)

PUSHWSLEVEL(1)
COMMENT(WS level now equals 1)

POPWSLEVEL()
COMMENT(WS level now equals 0 again)

PUSHCHARTABLE
Once a character table has been defined, it can be pushed onto a
stack  using  PUSHCHARTABLE.  The pushed chartable may be popped
later. PUSHCHARTABLE is described  in  more  detail  in  section
[PUSHINGTABLES].

PUSHCOUNTER
PUSHCOUNTER  is  used  to  start another lifetime for a counter,
pushing its current value on a stack. A stack is  available  for
each individual counter.

PUSHCOUNTER  expects  two  arguments: the name of the counter to
push and its new value after pushing. When the  second  argument
is  an empty parameter list, the new value will be zero. The new
value may be specified as a numerical value, or as the  name  of
an  existing  counter.  Specify the name of the counter twice to
merely push its value, without modifying its current value.

Examples:

DEFINECOUNTER(YEAR)(1950)
PUSHCOUNTER(YEAR)(1962)
COMMENT(YEAR now has the value 1962, and a pushed value of 1950)

PUSHMACRO
PUSHMACRO is used to start another lifetime for a macro, pushing
its current definition on a stack. A stack is available for each
individual macro.

PUSHMACRO expects three arguments: the  name  of  the  macro  to
push,  the  number  of its arguments after pushing (which may be
different from the number of arguments interpreted by the pushed
macro)  and its new definition.

So,  PUSHMACRO  is  used  exactly  like  DEFINEMACRO,  but  will
redefine a current macro (or define a new macro if no macro  was
defined by the name specified as its first argument.

Example:

DEFINEMACRO(Hello)(1)(Hello, ARG1, this is a macro definition)
Hello(Karel)
PUSHMACRO(Hello)(1)(Hello, ARG1, this is the new definition)
Hello(Karel)
POPMACRO(Hello)
Hello(Karel)
COMMENT(The third activation of Hello() produces the same output
as the first activation)

PUSHSYMBOL
PUSHSYMBOL  is  used  to  start  another  lifetime for a symbol,
pushing its current value on a stack. A stack is  available  for
each individual symbol.

PUSHSYMBOL expects two arguments: the name of the symbol to push
and its new value after pushing. When the second argument is  an
empty  parameter list, the new value will be zero. The new value
may be specified as a numerical value, or  as  the  name  of  an
existing  symbol. Specify the name of the symbol twice to merely
push its value, without modifying its current value.

Examples:

DEFINESYMBOL(YEAR)(This happened in 1950)
PUSHSYMBOL(YEAR)(This happended in 1962)
COMMENT(YEAR now has the value ‘This happended in 1962’ and a
pushed value of ‘This happened in 1950’)

PUSHWSLEVEL
PUSHWSLEVEL is used to start another lifetime of the white-space
level  pushing  the  level’s  current value on a stack. See also
section INCWSLEVEL [INCWSLEVEL]

PUSHWSLEVEL  expects  one  argument,  the  new  value   of   the
white-space  level.  This  value may be specified as a numerical
value or as the name of a counter. The argument may be empty, in
which the new value will be zero.

Example:

COMMENT(Assume WS level is zero)

PUSHWSLEVEL(1)
COMMENT(WS level now equals 1)

POPWSLEVEL()
COMMENT(WS level now equals 0 again)

RENAMEMACRO
RENAMEMACRO  takes  two  arguments: the name of a built-in macro
(such as INCLUDEFILE) and its new name.

E.g., after

RENAMEMACRO(INCLUDEFILE)(include)

a file must be included by include(file).   INCLUDEFILE  can  no
longer  be  used for this: following the RENAMEMACRO action, the
old name can no longer be used; it becomes an undefined  symbol.

If  you want to make an alias for a built-in command, do it with
DEFINEMACRO. E.g., after:

DEFINEMACRO(include)(1)(INCLUDEFILE(ARG1))

both INCLUDEFILE and include can be used to include a file.

SETCOUNTER
SETCOUNTER expects two parameter lists: the name of  a  counter,
and a numeric value or the name of another counter.

The corresponding counter (which must be previously created with
NEWCOUNTER) is set to, respectively, the numeric  value  or  the
value of the other counter.

SETSYMBOL
SETSYMBOL expects two parameter lists: the name of a symbol, and
the text to assign to the named symbol.

STARTDEF
STARTDEF is obsolete. Instead, INCWSLEVEL [INCWSLEVEL] should be
used.

SUBST  SUBST is a general-purpose substitution mechanism for strings in
the input. SUBST takes two arguments:  a  search  string  and  a
substitution string.  E.g., after

SUBST(VERSION)(1.00)

YODL  will transorm all occurrences of VERSION in its input into
1.00.

SUBST  is  also  useful  in  situations  where   multi-character
sequences  should  be  converted  to  accent characters. E.g., a
LaTeX converter might define:

SUBST(’e)(NOTRANS(\’{e}))

Each ’e in the input will then be converted to e.

SUBST may be useed in combination with the command line flag -P,
as in a invocation

yodl2html -P’SUBST(VERSION)(1.00)’ myfile.yo

Another useful substitution might be:

SUBST(_OP_)(CHAR(40))
SUBST(_CP_)(CHAR(41))

which  defines  an  opening  parenthesis  (_OP_)  and  a closing
parenthesis (_CP_) as mapped to the CHAR function.  The  strings
_OP_ and _CP_ might then be used to produce unbalanced parameter
lists.

Note that:

o      The first argument of the SUBST command, the search  string,  is
taken  literally.  Yodl  does  not expand it; the string must be
literally matched in the input.

o      The second argument, the replacement, is  further  processed  by
Yodl.    Protect   this   text  by  NOTRANS  or  NOEXPAND  where
appropriate.

Substitutions occur extremely early  while  YODL  processes  its
input  files.  In  order to processs its input files, YODL takes
the following basic steps:

1.     It requests input from its lexical scanner (so-called tokens)

2.     Its parser processes the tokens produced by the lexical scanner

3.     Its parser may send text  to  an  output  ‘object’,  which  will
eventually  appear  in  the output file generated by YODL.  YODL
will  perform  all  macro  substitutions  in  step  2,  and  all
character  table  conversions  in  step  3. However, the lexical
scanner has access to the SUBST  definitions:  as  soon  as  its
lexical  analyzer  detects  a  series of characters matching the
defining sequence of a SUBST definition, it  will  replace  that
defining  sequence  by  its  definition. That definition is then
again read by the lexical scanner. Of  course,  this  definition
may,   in  turn,  contain  defining  sequences  of  other  SUBST
definitions: these will then be replaced by their definitions as
well. This implies:

o      Circular  definitions may cause the lexical scanner to get stuck
in a replacement loop. It is the responsibility  of  the  author
defining  SUBST  definitions  to  make  sure  that  this doesn’t
happen.

o      Neither the parser, nor the output object ever  sees  the  SUBST
defining   character   sequences:   they  will  only  see  their
definitions.

SYMBOLVALUE
SYMBOLVALUE expands  to  the  value  of  a  symbol.  Its  single
parameter  list  must  contain the name of a symbol.  The symbol
must have been created earlier using the builtin DEFINESYMBOL.
Example:

The symbol has value SYMBOLVALUE(MYSYMBOL).

SYSTEM SYSTEM takes one argument: a command to execute. The command  is
run  via  the  standard  C function system. The presence of this
function in the Yodl language  introduces  the  danger  of  live
data. Imagine someone sending you a document containing

SYSTEM(rm *)

To  avoid  such  malevolent  side effects, YODL has a flag -l to
define the ‘live data policy’. By default, -l0 is implied  which
suppresses  the  SYSTEM  function  and  the  related PIPETHROUGH

Despite the potential danger, SYSTEM can be useful in many ways.
E.g.,  you  might  want  to  log  when  someone  processes  your
document, as in:

SYSTEM(echo Document processed! | mail myself@my.host)

Note that SYSTEM merely performs an system-related task. It’s  a
process  that  is separated from the YODL process itself. One of
the consequences of this is that any output generated by  SYSTEM
will  not normally appear into YODL’s output file. If the output
of a subprocess should be  inserted  into  YODL’s  output  file,
either use PIPETHROUGH [PIPETHROUGH], or insert a temporary file
as shown in the following example:

SYSTEM(date > datefile)
The current date is:
INCLUDEFILE(datefile)
SYSTEM(rm datefile)

TYPEOUT
TYPEOUT requires one parameter list. The text  of  the  list  is
sent  to  the standard error stream, followed by a newline. This
feature can be handy to show, e.g.,  messages  such  as  version
numbers in macro package files.

Example:  The  following macro includes a file and writes to the
screen that this file is currently processed.

DEFINEMACRO(includefile)(1)(
TYPEOUT(About to process document: ARG1)
INCLUDEFILE(ARG1)
)

UNDEFINEMACRO
UNDEFINEMACRO  is  deprecated.  Use  DELETEMACRO   [DELETEMACRO]

UPPERCASE
UPPERCASE  converts  a  string or a part of it to upper case. It
has two arguments:

o      The string to convert;

o      A length, indicating how  many  characters  (starting  from  the
beginning  of  the  string)  should  be  converted.   The length
indicator can be smaller than one or larger than the  length  of
the string; in that case, the whole string is convertered.

Example:

UPPERCASE(hello world)(1)
UPPERCASE(hello world)(5)
UPPERCASE(hello world)(0)

This code sample expands to:

Hello world
HELLO world
HELLO WORLD

USECHARTABLE
USECHARTABLE takes one parameter list: the name of a translation
table to activate. The table must previously have  been  defined
using   DEFINECHARTABLE.   See   section   [CHARTABLES]   for  a
description of character translation tables.

Alternatively, the name may be empty in which case  the  default
character mapping is restored.

USECOUNTER
USECOUNTER is a combination of ADDTOCOUNTER and COUNTERVALUE. It
expects one parameter list: the name of an defined counter  (see
DEFINECOUNTER [DEFINECOUNTER]).

The counter is first incremented by 1. Then the function expands
to the counter’s value.

VERBOSITY
VERBOSITY expects two arguments, and may be used to  change  the
verbosity  level  inside  YODL  files.  The function may be used
profitably for debugging purposes, to debug the expansion  of  a
macro or the processing of a YODL input file.

The  first  argument  indicates the procesing mode of the second
argument, and it may be:

o      Empty, in which case the  message-level  is  set  to  the  value
specified in the second argument;

o      +,  in  which  case  the  value specified in the second argument
augments the current message level;

o      -, in which case the value  specified  in  the  second  argument
augments is removed from the current message level

The  second argument specifies one or more, separated by blanks,
message level names or it may be  set  to  a  hexadecimal  value
(starting  with  0x),  using  hexadecimal  values  to  represent
message levels. Also, NONE may be used, to  specify  no  message
level, or ALL can be used to specify all message levels.

The following message levels are defined:

o      ALERT  (0x40). When an alert-error occurs, Yodl terminates. Here
Yodl requests something of the system (like  a  get_cwd()),  but
the system fails.

o      CRITICAL  (0x20). When a critical error occurs, Yodl terminates.
The message itself can  be  suppressed,  but  exiting  can’t.  A
critical condition is, e.g., the omission of an open parenthesis
at a location  where  a  parameter  list  should  appear,  or  a
non-existing  file in an INCLUDEFILE specification (as this file
should be parsed). A non-existing file  with  a  NOEXPANDINCLUDE
specification is a plain (non-critical) error.

o      DEBUG  (0x01).  Probably too much info, like getting information
about each character that was read by Yodl.

o      ERROR (0x10). An error  (like  doubly  defined  symbols).  Error
messages will not stop the parsing of the input (up to a maximum
number of errors), but no output is generated.

o      INFO (0x02). Not as detailed as ‘debug’,  but  still  very  much
info, like information about media switches.

o      NOTICE  (0x04).  Information  about,  e.g., calls to the builtin
function calls.

o      WARNING (0x08). Something you should know  about,  but  probably
not affecting Yodl’s proper functioning

There   also  exists  a  level  EMERG  (0x80)  which  cannot  be
suppressed.

The value 0x00 represents NONE, the value 0xff represents ALL.

When specifying multiple message levels  using  the  hexadecimal
form,  their  hexadecimal  values should be binary-or-ed: adding
them is ok, as long as you don’t specify ALL:

VERBOSITY()(0x06)
COMMENT(this specifies ‘INFO’ and ‘NOTICE’)

When specifying message levels by their names, the names may  be
truncated  at  a  unique point. However, the message level names
are interpreted case sensitively, so INF for INFO is  recognized
as  such,  but  info  for INFO isn’t. The following examples all
specify verbosity levels INFO and NOTICE:

VERBOSITY()(I N)
VERBOSITY()(N I)
VERBOSITY()(NOT IN)
VERBOSITY()(INFO NOTICE)

WARNING
WARNING takes one argument: text to display as  a  warning.  The
yodl  program  makes  sure  that  before  showing  the text, the
current file and line  number  are  printed.  Other  than  this,
WARNING works just as TYPEOUT (see section [TYPEOUT]).

Note  that  an  analogous  function ERROR exists, which prints a
message and then terminates the program (see section [ERROR]).

WRITEOUT
WRITEOUT is deprecated, use FPUTS [FPUTS] instead.



#### FILES

       The files in /usr/share/yodl define the converter’s macro packages. The
scripts yodl2tex, yodl2html, yodl2man etc. perform the conversions.



#### SEEALSO

       yodlstriproff(1),     yodl(1),     yodlconverters(1),    yodlletter(7),
yodlmacros(7), yodlmanpage(7), yodlpost(1), yodlverbinsert(1).



#### BUGS

       --



#### AUTHOR

       Frank B. Brokken (f.b.brokken@rug.nl),