Provided by: yodl_3.00.0-6ubuntu1_amd64

#### 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.

NOTE:  Starting  with  Yodl  version  3.00.0  Yodl’s  default  file inclusion behavior has
changed. The current working directory no longer remains fixed at the directory  in  which
Yodl  is  called,  but  is  volatile,  changing  to  the directory in which a yodl-file is
located. This has the advantage that Yodl’s file inclusion behavior now  matches  the  way
C’s  #include  directive  operates; it has the disadvantage that it may break some current
documents. Conversion, however is simple but  can  be  avoided  altogether  if  Yodl’s  -L
(--legacy-include)   option   is  used.  The  builtins  INCLUDEFILE,  NOEXPANDINCLUDE  and
NOEXPANDPATHINCLUDE are affected by this new behavior.

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

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

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

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

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

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

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

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

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

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

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

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

See further section [COUNTERS].

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

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

Example:

ADDTOSYMBOL(LOCATION)(this is appended to LOCATION)

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

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

ATEXIT(NOEXPAND(\end{document}))

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

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

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

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

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

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

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

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

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

CHAR(65)
CHAR(A)

The following statement sends a closing parenthesis:

CHAR(41)

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

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

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

This fragment can be changed to:

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

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

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

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

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

The counter has value COUNTERVALUE(MYCOUNTER).

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

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

Example:

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

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

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

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

character = quoted-string

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

Example:

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

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

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

Examples:

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

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

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

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

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

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

Such a macro could be used as follows:

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

When called, it would produce the following output:

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

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

Note the following when defining new macros:

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

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

I like me (but so do you)

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

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

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

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

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

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

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

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

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

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

hello worldXXnl()

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

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

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

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

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

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

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

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

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

o      Macro expansion proceeds as follows:

o      The parameter lists are read from the input

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

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

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

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

and the following call is issued:

Second(Yodl)

then the following will happen:

o      Second(Yodl) is read as encountered.

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

First(Yodl)First(Yodl)

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

Hello Yodl+XXnl()First(Yodl)

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

+XXnl()First(Yodl)

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

\nFirst(Yodl)

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

First(Yodl)

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

Hello Yodl+XXnl()

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

+XXnl()

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

\n

o      The newline is printed and we’re done.

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

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

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

Example:

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

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

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

Example:

DELETECHARTABLE(mytable)

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

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

Example:

DELETECOUNTER(mycounter)

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

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

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

Example:
DELETEMACRO(mymacro)

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

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

Example:
DELETENOUSERMACRO(mymacro)

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

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

Example:

DELETESYMBOL(Options)

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

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

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

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

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

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

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

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

ERROR(Stopping after COUNTERVALUE(NTRIES) attempts)

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

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

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

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

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

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

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

o      All this results in the text

USECOUNTER(counter)

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

USECOUNTER(EVAL(SYMBOLVALUE(varnam)))

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

Summarizing: EVAL acts as follows:

o      Its argument is presented to Yodl’s lexical scanner

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

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

Postponing evaluations allows you to write:

DEFINESYMBOL(later)(SYMBOLVALUE(earlier))

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

SYMBOLVALUE(later)

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

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

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

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

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

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

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

The second argument (name of the file) is not evaluated, but is used as received.

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

Example:

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

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

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

Example:

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

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

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

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

o      a built-in function, or

o      a character table, or

o      a counter, or

o      a no-user-macro symbol, or

o      a symbol, or

o      a user-defined macro, or Example:

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

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

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

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

Example:

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

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

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

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

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

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

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

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

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

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

o      Otherwise, IFEQUAL will evaluate the false list.

Example:

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

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

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

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

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

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

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

o      Otherwise, IFGREATER will evaluate the false list.

Example:

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

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

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

Example:

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

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

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

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

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

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

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

o      Otherwise, IFSMALLER will evaluate the false list.

Example:

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

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

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

The first two arguments of IFSTREQUAL are partially evaluated:

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

o      Otherwise, the argument itself is used.

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

Example:

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

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

The first two arguments of IFSTREQULA are partially evaluated:

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

o      Otherwise, the argument itself is used.

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

Example:

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

Example:

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

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

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

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

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

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

o      Otherwise, IFZERO will evaluate the false list.

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

Example:

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

Such a macro may be used as follows:

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

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

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

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

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

NOTE:  Starting with Yodl version 3.00.0 Yodl’s default file inclusion behavior has
changed. The current working directory no longer remains fixed at the directory  in
which  Yodl  is  called,  but  is  volatile,  changing  to the directory in which a
yodl-file is located. This has the advantage that Yodl’s  file  inclusion  behavior
now  matches  the way C’s #include directive operates; it has the disadvantage that
it may break some current documents. Conversion,  however  is  simple  and  can  be
avoided altogether if Yodl’s -L (--legacy-include) option is used.

Example:

INCLUDEFILE(latex)

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

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

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

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

Example:

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

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

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

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

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

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

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

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

3004 ref MACROPACKAGE

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

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

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

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

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

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

NEWCOUNTER
NEWCOUNTER is obsolete. DEFINECOUNTER [DEFINECOUNTER] should be used instead.

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

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

So, the following situations are recognized:

──────────────────────────────────────────────
support chartables
and CHAR
──────────────────────────────
Macro expansion   yes          no
──────────────────────────────────────────────
Yes               (standard)   Push chartable
(standard)
Pop chartable
No                NOEXPAND     NOTRANS
──────────────────────────────────────────────

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

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

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

For this function, keep the following caveats in mind:

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

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

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

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

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

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

NOTE:  Starting with Yodl version 3.00.0 Yodl’s default file inclusion behavior has
changed. The current working directory no longer remains fixed at the directory  in
which  Yodl  is  called,  but  is  volatile,  changing  to the directory in which a
yodl-file is located. This has the advantage that Yodl’s  file  inclusion  behavior
now  matches  the way C’s #include directive operates; it has the disadvantage that
it may break some current documents. Conversion,  however  is  simple  and  can  be
avoided altogether if Yodl’s -L (--legacy-include) option is used.

The argument to NOEXPANDINCLUDE is partially evaluated:

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

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

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

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

NOEXPANDINCLUDE(literal.c)

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

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

NOTE:  Starting with Yodl version 3.00.0 Yodl’s default file inclusion behavior has
changed. The current working directory no longer remains fixed at the directory  in
which  Yodl  is  called,  but  is  volatile,  changing  to the directory in which a
yodl-file is located. This has the advantage that Yodl’s  file  inclusion  behavior
now  matches  the way C’s #include directive operates; it has the disadvantage that
it may break some current documents. Conversion,  however  is  simple  and  can  be
avoided altogether if Yodl’s -L (--legacy-include) option is used.

The argument to NOEXPANDPATHINCLUDE is partially evaluated:

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

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

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

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

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

For example, consider the following code fragment:

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

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

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

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

NOEXPAND will send

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The PIPETHROUGH function takes two arguments:

o      the command to run, and

o      the text to send to that command.

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

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

The current date is:
PIPETHROUGH(date)()

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

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

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

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

Examples:

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

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

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

Example:

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

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

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

Example:

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

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

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

Example:

COMMENT(Assume WS level is zero)

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

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

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

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

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

Examples:

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

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

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

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

Example:

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

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

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

Examples:

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

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

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

Example:

COMMENT(Assume WS level is zero)

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

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

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

E.g., after

RENAMEMACRO(INCLUDEFILE)(include)

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

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

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

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

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

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

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

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

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

SUBST(VERSION)(1.00)

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

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

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

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

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

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

Another useful substitution might be:

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

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

Note that:

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

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

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

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

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

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

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

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

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

The symbol has value SYMBOLVALUE(MYSYMBOL).

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

SYSTEM(rm *)

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

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

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

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

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

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

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

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

UNDEFINEMACRO
UNDEFINEMACRO is deprecated. Use DELETEMACRO [DELETEMACRO] instead.

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

o      The string to convert;

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

Example:

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

This code sample expands to:

Hello world
HELLO world
HELLO WORLD

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

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

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

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

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

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

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

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

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

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

The following message levels are defined:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



#### FILES

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



#### SEEALSO

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



#### BUGS

       --



#### AUTHOR

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