Provided by: yodl_4.03.03-1_amd64 bug

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  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 `PUSHSUBST’ built-in function (see section `[PUSHSUBST]’);

       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]’);

       o      The `XXSUBST’ internal use only built-in function;  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.

       `ADDTOCOUNTER’
              The `ADDTOCOUNTER’ function adds a  given  value  to  a  counter.  It  expects  two
              arguments:  the counter name, and an additive expression defining the value to add.
              The counter must be previously created with `DEFINECOUNTER’.

              The additive expression may not contain blank spaces and may use + and - operators,
              its  operands may either be integral numeric values or names of (defined) counters.
              The resulting value can be negative; in that case, a value is subtracted  from  the
              destination counter.

              For example, if `one’ and `two’ are counters, then

                  ADDTOCOUNTER(one)(-two)\//    subtracts two’s value from one
                  ADDTOCOUNTER(one)(two+two)\// adds 2 x two’s value to one

              See further section `[COUNTERS]’.

       `ADDTOSYMBOL’
              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.,

                  ADDTOSYMBOL(one)(SYMBOLVALUE(two)XXnl())

              This  adds  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’  expects  one  argument. The argument 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 requirement that open- and close-parentheses must match.

              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, 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’ searches
              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 defines one parameter list.  The  text  that  is  passed  as
              argument  is treated as comment. I.e., it is ignored; it is not copied to the final
              output file.

              As an alternative to (short) `COMMENT’ the triplet `\’`//’ can be used.  It  starts
              `end  of line’ comment, ignoring all characters on a line starting at `\’`//’ up to
              the first non-blank character encountered on the next  line.  If  the  next  line’s
              first  non-blank  characters  are  `\’`//’,  then  that  begins another end of line
              comment, which will therefore also be skipped.

              To actually write `\’`//’ or, using the  current  font:  \//  in  a  yodl-converted
              document,  write,  e.g.,  `tt(\)tt(//)’  or,  using the current font: nop(/)// in a
              yodl-source file, and write `\CHAR’`(/)/’ in `verb’ sections.

              Example:

                  Hello world\// producess Hello world, skipping the rest
                      \// this line is completely ignored
                     s\// at this point Hello worlds has been produced.

       `COUNTERVALUE’
              `COUNTERVALUE’s’ argument expands to the value of a counter.  Its  single  argument
              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).

              See also section `[COUNTERS]’.

       `DECWSLEVEL’
              `DECWSLEVEL’ requires one (empty) argument.  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 is 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  effectively  is  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 backslash character (`\’)
              defines itself: `\\’ represents a single backslash character.

              Example:

                  DEFINECHARTABLE(demotable)(
                      ’&’     = "&"
                      ’\\’    = "\\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. This builtin function expects two arguments:
              the  name  of  the  counter  and  an  additive  expression  whose  value is used to
              initialize the counter.

              The additive expression may not contain blank spaces and may use + and - operators,
              its  operands may either be integral numeric values or names of (defined) counters.
              The resulting value can be negative; in that case, a value is subtracted  from  the
              destination counter.

              Examples:

                  DEFINECOUNTER(year)(1950)
                  DEFINECOUNTER(nTimes)(year+12)\// initializes nTimes to 1962

              See  also  section  `[COUNTERS]’  and  the  `USECOUNTER’ and `ADDTOCOUNTER’ builtin
              functions.

       `DEFINEMACRO’
              `DEFINEMACRO’ is used to define new macros. This function expects three arguments:

       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  it’s
              used. The number must be in the range 0 to 61.

       o      The  text  that  the macro expands to, once used. This text may contain the strings
              `ARG’x, x being 1, 2, etc.. At these places the arguments to the macro  are  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
                      Published by:        ARG3
                  )

              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 values of the three arguments are pasted to the places
              where `ARG1’, `ARG2’ etc. occur in the definition.

              Note the following when defining new macros:

       o      The argument 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 argument.

              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
                      Published by:        ARG3
                  )

              introduces  extra  newlines  at  the  beginning  and ending of the macro, which are
              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
                      Published by:        ARG3
                  )

       o      Note  that  when  a  macro  is  used  which requires no arguments at all, one empty
              argument  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()
                  )

              when called as `oops(hello world)’, produces 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’s  arguments  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 arguments.

       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 arguments are read from the input

       o      The contents of the arguments then replace their `ARGx’ references in  the  macro’s
              definition  (in  some exceptional cases, clearly indicated as such when applicable,
              the arguments themselves are 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 happens:

       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 puts (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 puts 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’
              `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
              argument, 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)

       `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 argument
              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 `book’s or `report’s).

              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
              displays the counter’s value, after having incremented it:

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

              Here, `EVAL’ performs the following steps:

       o      First, `NOTRANS(USECOUNTER)’ is evaluated, producing `USECOUNTER’.

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

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

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

       o      All this results in the text

                  USECOUNTER(counter)

       o      This  text  is  presented  to Yodl’s lexical scanner, resulting in incrementing the
              counter, and displaying its incremented value.

              b(Caveat): macro arguments themselves are usually not evaluated. So, a construction
              like

                  USECOUNTER(EVAL(SYMBOLVALUE(varnam)))

              fails, as ``EVAL(SYMBOLVALUE(varnam))’’ is not a legal name for a counter. Here the
              `EVAL()’ call is used as an argument, and is therefore not expanded.

              The distinction is subtle, and is a consequence of the fact that builtin  functions
              receive unprocessed arguments. Builtin functions may impose certain requirements on
              their arguments (like `USECOUNTER’ requiring the  name  of  a  counter)  and  these
              requirements are checked on the arguments as received.

              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.

              Most built-in functions do not evaluate their  arguments.  In  fact,  only  `ERROR,
              EVAL,  FPUTS,  INTERNALINDEX,  PUSHSUBST,  TYPEOUT,  UPPERCASE,  WARNING’  and  the
              iinternally used `XXSUBST’ functions 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)

              produces 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  define
              variables  using  values of other variables?’ In those cases `EVAL()’ must be used.
              The following example shows the definition of  three  symbols:  `one’  receives  an
              initial  value, `two’ returns `one’’s actual value when `two’’s value is displayed,
              `three’, using `EVAL()’, stores `one’’s initial value.

              The example also shows yet another way to suppress macro  calls,  using  the  macro
              `nop()’ which is defined in the all standard conversion types:

                  DEFINESYMBOL(one)(One’s first value)
                  DEFINESYMBOL(two)(SYMBOLVALUE(one))
                  EVAL(DEFINESYMBOL+nop()(three)(SYMBOLVALUE(one)))
                  SETSYMBOL(one)(One’s second value)
                  "SYMBOLVALUE(two)"      COMMENT(displays "One’s second value")
                  "SYMBOLVALUE(three)"    COMMENT(displays "One’s first value")

       `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 argument 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 appends 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 used as received.

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

              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 argument is evaluated, else, the third argument is
              evaluated. All three arguments (the name, the true list and the false list) must be
              present; though the true list and/or the false list may be empty.

              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
              argument. If it is a defined entity, the second argument is  evaluated,  else,  the
              third argument is evaluated. All three arguments (the entity, the true list and the
              false list) must be present; though the true list and/or  the  false  list  may  be
              empty.

              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
                      Published by:   \
                      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 argument is evaluated, else, the fourth
              argument is evaluated. All four argument lists must be present, though all  can  be
              empty.

              The first two arguments of `IFEQUAL’ should be integral numeric 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 determines whether the true list (when the values are equal) or the  false
              list (when the values are unequal) will be evaluated.

       o      Otherwise, `IFEQUAL’ evaluates 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  than  its  second  argument. If so, the third parameter list is evaluated,
              otherwise its fourth argument  is  evaluated.  All  four  argument  lists  must  be
              present, though all can be empty.

              The  first  two  arguments  of `IFGREATER’ should be integral numeric 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 determines 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) is evaluated.

       o      Otherwise, `IFGREATER’ evaluates 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 argument is evaluated, else, the  third
              argument  is  evaluated. All three arguments (the name, the true list and the false
              list) must be present; though the true list and/or the false list may be empty.

              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 than its second argument. If so, the third  parameter  list  is  evaluated,
              otherwise  its  fourth  argument  is  evaluated.  All  four  argument lists must be
              present, though all can be empty.

              The first two arguments of `IFSMALLER’ should be  integral  numeric  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 determines 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) is evaluated.

       o      Otherwise, `IFSMALLER’ evaluates 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 seldom, 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 seldom, however.

              Example:

                      IFSTRSUB(haystack)(needle)(
                          `needle’ was found in `haystack’
                      )(
                          `needle’ was not 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 argument is evaluated, otherwise the
              third argument is evaluated. All three arguments (the name, the true list  and  the
              false  list)  must  be  present;  though the true list and/or the false list may be
              empty.

              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.

              C(  FBB consider additive expressions   )

       `IFZERO’
              `IFZERO’  expects  three  arguments. If the first argument is zero (0) the function
              expands to the true list (the second argument). Otherwise it expands to  the  false
              list (the third argument).

              The  first  argument  of `IFZERO’ should be an integral numeric 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, the first arguments evaluates as 0, and the false list is used.

              Note that, starting with Yodl version 2.00 the first argument is not evaluated.  So
              `COUNTERVALUE(somecounter)’  always  evaluates  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)

              Here,  Yodl  attempts  to  include  the file `latex’ or `latex.yo’ from the current
              include path. When the file is not found, Yodl aborts.

       `INCWSLEVEL’
              `INCWSLEVEL’ requires one (empty) argument.

              It increments 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 is generated if the file produces
              non-whitespace output. The builtin function `DECWSLEVEL’ is used to  decrement  the
              whitespace level following a previous `INCWSLEVEL’ call.

              Once  the  white  space  level  exceeds  zero, no output is generated. White space,
              therefore is effectively 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 greater processing speed, at the expense of an additional
              file.  The  associated  `yodlpost’  postprocessing  program reads and processes the
              index file, and modifies 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’ changes
              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
              thereupon writes 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.

       `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 argument, 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’ and
              (iinternally used) `XXSUBST’ functions in the  argument,  which  are  expanded.  If
              `CHAR’-expansion is not required either NOTRANS `[NOTRANS]’ can be used).

              Furthermore,  the  contents  of  the  argument  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 sense 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 `ARG’x
              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  argument.  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 specified. 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 is not affected by available 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 is not affected by available 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:

                  NOEXPANDPATHINCLUDE(rug-menubegin.xml)

       `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’ sends

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

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

              The argument 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 `)’.

              While converting Yodl-documents to target document types Yodl frequently  uses  the
              (not further documented) builtin function `XXSUBST’. In the unlikely event that the
              text `XXSUBST(...)’ must be written in a document, the sequence

                  XXSUBST+CHAR(40)...CHAR(41)

              can be used.

              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, warnings are generated when Yodl encounters
              a  possible  macro name, i.e., a name that is followed by a parenthesized argument,
              while no macro by that name has been defined.   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 argument.

              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 Yodl handles  paragraphs  in  a
              special  way it is probably useful to describe paragraph handling 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 calls  it  whenever  a  new  paragraph
              (defined as a series of at least two blank lines) has been 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 contains 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 does 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 do 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 system 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-converter.

       `PIPETHROUGH’
              The  builtin  function `PIPETHROUGH’ is, besides `SYSTEM’, the second function with
              which a Yodl document can affect its environment. `PIPETHROUGH’ can be very useful.
              It  uses  an  external  program 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 is 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)

              See also section `[COUNTERS]’.

       `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, after which its stack is empty. In
              that  case,  using  the  macro  (although  the  macro’s  name  is still defined) 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)

       `POPSUBST’
              `POPSUBST’ is used to revert to a  previous  level  of  interpretation  of  `SUBST’
              definitions.  Refer  to  the  descriptions  of  the `PUSHSUBST’ and `SUBST’ builtin
              commands below for details.

              There is no limit to the number  of  times  `POPSUBST’  can  be  called.  Once  the
              ``PUSHSUBST’ stack’ is empty `SUBST’ definitions are automatically interpreted  (so
              no stack-underflow error is ever encountered).

       `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, after which its stack is empty.
              In that case, using the symbol (although the symbol’s name  is  still  defined)  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, emptying  the  stack,  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  an
              additive  expression whose value becomes the counter’s new value (after pushing the
              current value)

              The additive expression may not contain blank spaces and may use + and - operators,
              its  operands may either be integral numeric values or names of (defined) counters.
              The resulting value can be negative; in that case, a value is subtracted  from  the
              destination counter.

              When  the  second  argument is empty, then the new value will be zero.  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)

              See also section `[COUNTERS]’.

       `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 redefines 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)

       `PUSHSUBST’
              `PUSHSUBST’ can be used to (temporarily) suppress  the  interpretation  of  `SUBST’
              definitions   (the  `SUBST’  built-in  command  is  covered  below,  refer  to  its
              description for an example).

              `PUSHSUBST’ expects one argument: an integral number which is either 0 or  non-zero
              (commonly:   1).   After  calling  `PUSHSUBST’`(0)’  `SUBST’  definitions  are  not
              interpreted  anymore;  use  `POPSUBST’`()’  to  revert  to  the  previous  type  of
              interpretation.  Alternatively, `PUSHSUBST’`(0)’ can be used to stack another level
              of `SUBST’ interpretations on top of the last-used one.

              On a 64-bit computer the `PUSHSUBST’ stack can hold slightly more than  60  `SUBST’
              interpretation  levels. When more levels are pushed, the oldest levels are silently
              forgotten. Calling `POPSUBST’ once  the  `PUSHSUBST’  stack  is  empty  results  in
              activating  the `SUBST’ interpretations (and so a stack-underflow error will not be
              encountered).

       `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 text
              after pushing. When the second argument is an empty argument, the new text will  be
              empty.  The  new  text  may  be  specified  as a literal text, 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 happened in 1962)
                  COMMENT(YEAR now has the value `This happened 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 case 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  arguments:  the  name  of  a  counter,  and  an  additive
              expression  defining  the  value  to assign. The counter must be previously created
              with `DEFINECOUNTER’.

              The additive expression may not contain blank spaces and may use + and - operators,
              its  operands may either be integral numeric values or names of (defined) counters.
              The resulting value can be negative; in that case, a negative value is assigned  to
              the destination counter.

              For example, if `one’ and `two’ are counters, then

                  SETTOCOUNTER(one)(-two)\//    assigns -two’s value to one
                  SETTOCOUNTER(one)(two+two)\// assigns 2 x two’s value to one

              See also section `[COUNTERS]’.

       `SETSYMBOL’
              `SETSYMBOL’  expects two arguments: the name of a symbol, and the text to assign to
              the named symbol. The symbol must previously have been defined by `DEFINESYMBOL’.

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

                  SUBST(VERSION)(1.00)

              YODL transforms all occurrences of `VERSION’ in its input into `1.00’.

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

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

              Each `’e’ in the input will subsequently be converted to `e’.

              `SUBST’  may  be  used  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 arguments.

              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 process its input files, YODL takes the following 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 eventually appears in the
              output file generated by YODL.  YODL performs 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 replaces
              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  are  then  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 only see their definitions.

              In some cases substitutions must be suppressed. Consider double quoted text strings
              that  are frequently used in programming languages. E.g., `"hello world"’. The text
              inside the string should not be converted by Yodl, but unless substitutions can  be
              suppressed the string
              "\"evil code"

              appears as
              "evil code"

              To  suppress  the  interpretation  of  `SUBST’  definitions `PUSHSUBST’, introduced
              earlier, can be used. The predefined macro `verb’ suppresses the interpretation  of
              `SUBST’   definitions   by   starting   with   `PUSHSUBST’`(0)’   and  ending  with
              `POPSUBST’`()’.

       `SYMBOLVALUE’
              `SYMBOLVALUE’ expands to the value of a symbol. Its single  argument  must  be  the
              name of a symbol.  The symbol must have been created earlier using `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’.

              `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’ not normally appears 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 argument. 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)
                  )

       `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 argument: 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
              argument: 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.

              See also section `[COUNTERS]’.

       `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 processing 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 parenthesized argument 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]’).

FILES

       The files in tmp/wip/macros define the converter’s macro packages. The  scripts  yodl2tex,
       yodl2html, yodl2man etc. perform the conversions.

SEE ALSO

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

BUGS

       --

AUTHOR

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