YODL V1.22(1996)

YODL V1.22

K. Kubat (karel@icce.rug.nl)

1996
    YODL is a package that implements a pre-document language and tools to convert this language to many output formats, which can then be further processed. The purpose of this package was to convert YODL documents to either LaTeX for printing or to HTML for publishing via W3, but the package has since then grown. The package is designed to be very easy to use for those who write documents and to be extensible in respect to new commands or output formats.

Contents
Chapter 1: Introduction
1.1: Why use YODL?
1.2: Legalese
Chapter 2: YODL User Guide
2.1: Using the yodl program
2.2: The YODL grammar
2.2.1: Language elements
2.2.1.1: Unbalanced parameter lists
2.2.2: Line continuation
2.2.3: The +identifier sequence
2.3: YODL's builtin commands
2.3.1: ADDTOCOUNTER
2.3.2: ATEXIT
2.3.3: CHAR
2.3.4: CHDIR
2.3.5: COMMENT
2.3.6: COUNTERVALUE
2.3.7: DEFINECHARTABLE
2.3.8: DEFINEMACRO
2.3.9: DEFINESYMBOL
2.3.10: DUMMY
2.3.11: ENDDEF
2.3.12: ERROR
2.3.13: IFDEF
2.3.14: IFEMPTY
2.3.15: IFSTREQUAL
2.3.16: IFSTRSUB
2.3.17: IFZERO
2.3.18: INCLUDEFILE
2.3.19: INCLUDELITERAL
2.3.20: NEWCOUNTER
2.3.21: NOEXPAND
2.3.22: NOTRANS
2.3.23: NOUSERMACRO
2.3.24: PARAGRAPH
2.3.25: PIPETHROUGH
2.3.26: POPCHARTABLE
2.3.27: PUSHCHARTABLE
2.3.28: RENAMEMACRO
2.3.29: SETCOUNTER
2.3.30: SUBST
2.3.31: STARTDEF
2.3.32: SYSTEM
2.3.33: TYPEOUT
2.3.34: UNDEFINEMACRO
2.3.35: UNDEFINESYMBOL
2.3.36: UPPERCASE
2.3.37: USECHARTABLE
2.3.38: USECOUNTER
2.3.39: WARNING
2.4: Character tables
2.4.1: Defining a translation table
2.4.2: Using a translation table
2.4.3: Pushing and popping character tables
2.5: Sending literal text to the output
2.6: Counters
2.6.1: Creating a counter
2.6.2: Using counters
Chapter 3: A macro package for YODL
3.1: Files of the macro package
3.1.1: Conversion script invocations
3.2: Macros of the package
3.2.1: Conversion defines and literal commands
3.2.2: Document types
3.2.2.1: Pagebreaks after the title and table of contents
3.2.3: Typesetting modifiers
3.2.4: Sectioning
3.2.5: Lists and environments
3.2.6: Fonts and sizes
3.2.7: Accents
3.2.8: Labels, links, references and URLs
3.2.9: Figures
3.2.10: Miscellaneous commands
3.2.10.1: National language support
3.3: The manpage document type
3.4: Alphabetical list of the macros
3.5: General structure of a YODL document
3.6: Pecularities of conversions
3.6.1: Notes on the LaTeX converter
3.6.1.1: Direct commands to LaTeX
3.6.1.2: Verbatim text
3.6.2: Notes on the HTML converter
3.6.2.1: Direct commands to HTML
3.6.2.2: Numbering of sections
3.6.2.3: The htmlbodyopt macro
3.6.2.4: The yodl2html-post postprocessor
3.6.3: Notes on the groff converter
3.6.3.1: The groff postprocessors
3.6.4: Notes on the SGML converter
3.6.5: Notes on the ASCII converter
Chapter 4: Technical information
4.1: Obtaining and installing YODL
4.1.1: Configuring the yodl program
4.1.2: Installing the yodl program
4.1.2.1: Prerequisites for the installation
4.2: Internal workings of the YODL package
4.2.1: A single-pass interpreter
4.2.2: Macros of the converters
4.2.2.1: Adding a new macro

Chapter 1: Introduction
YODL stands for `Yet Oneother Document Language' and is basically a pre-processor to convert document files in a special macro language (the YODL language) to any output format. The YODL language is not a `final' language, in the sense that it can be viewed or printed directly. Rather, a document in the YODL language is a `pre-document', that is converted with some macro package to an output format, to be further processed.

In this, YODL somewhat resembles SGML (Standard Generalized Markup Language) but is designed to be more transparent and easier to use.

I wrote YODL because I needed a good document preprocessor to convert output to either LaTeX (for printing) or to HTML (HyperText Markup Language, used in WWW documents) for publishing via a WWW site. Although SGML does this too, I wanted something that is used `intuitively' and with greater ease. This is reflected in the syntax of the YODL language, in the available macros of the YODL macro package, and very probably also in other aspects of YODL. However, YODL is designed to convert to any output format; so it is possible to write a macro package that converts YODL documents to, say, the man format for manual pages. I am not very familiar with the man format, but I've put some work into this too; resulting in the `manpage' document type and its converter.

A few highlights of YODL are:

o   YODL allows the inclusion of files. This makes it easier to split up a document into `logical' parts, each kept in a separate file. Thus, a `main document' file can include all the sub-parts. (Imagine that you're the editor of a journal. Authors are likely to send in their submissions in separate files; inclusion can then be very handy!)

o   Files which are included are searched for either `as-is', or in a given `system-wide include' directory, similar to the workings of the C preprocessor. Therefore, it is possible to create a set of include files holding macros, and to place them into one macro directory. (See also chapter 3, where a macro package that is distributed with YODL is described.)

o   For all the handled files (either stated on the commandline or included), YODL supplies an extension if none is present. The default extension is .yo, but can be defined to anything in the compilation of the yodl program.

o   YODL supports conditional parsing of its input, controlled by defined symbols. This resembles the #ifdef / #else / #endif preprocessor macros of the C language. YODL also supports other if clauses, e.g., to test for the presence of an argument to a macro.

o   YODL offers hooks to define counters, to modify them, and to use them in a document. Thereby YODL offers the possibility for automatic numbering of e.g., sections. Of course, some document languages (e.g., LaTeX) offer this too; but some don't. When converting a YODL document to, say, HTML, this feature is very handy.

o   YODL is designed to be easy to use: YODL uses `normal' characters to identify commands in the text, instead of insisting weird-looking tags or escape characters. Editing a document in the YODL macro language is designed to be as easy as possible.

o   Similar to other document languages, YODL supports `character conversion tables' which define how a character should appear in the output.

This document first describes YODL from the point of the user: how can macros be defined, how is the program used etc.. Next, my own macro package is presented and the macros therein described. Finally, this document holds technical information about the installation and the inner workings of YODL.

1.1: Why use YODL?
YODL is not a word processor, not even an editor. At first glance you might say, yeah, YODL is just yet oneother document language.. why learn it?

First of all, YODL may lower the threshold of new users to start writing documents. An example of an excellent, though not very user-friendly document language is LaTeX. Typing all the backslash and curly brace characters in LaTeX and remembering that an asterisk must be typed as $*$ may be hard at first. In such situations, a properly configured YODL macro set removes these obstacles and thereby helps novices. Yodl is designed to be easy to learn. As the YODL package is growing, so is the manual. The ease of `learning YODL' may thus somewhat diminish, but just keep in mind: as long as you need just plain texts, YODL does OK. If you want more functionality, e.g., the composition of manual pages for Unix, dig into the documentation.

Second, YODL permits to create more than one macro set, defining the same commands, but leading to different output actions. Thereby, the same input file can be converted to several output formats, depending on the loaded macro set. In this, YODL is a `general front' document language, which converts a YODL document to a specialized language for further processing. This was of course one of my reasons to write YODL: I needed a good converter for either LaTeX or HTML.

Third, YODL always allows an `escape route' to the output format. Most situations can be handled with YODL macros, but sure enough, some users will want special actions for a given output format. A typical example for the necessity of such an escape route is the typesetting of mathematical formulas. Say you want to use YODL for a document that is converted either to LaTeX (being a very good mathematical typesetter) or to HTML (a very poor mathematical typesetter). An approach might be to decide inside the document how to typeset a mathematical formula. YODL provides conditional command processing to accomplish this. The decision would be based on the output format: for LaTeX, you'd typeset the formula using all the facilities that LaTeX offers, and for HTML you'd use poor-mans typesetting. Typically, other pre-processors for documents don't allow such escape routes. Well, YODL does.

1.2: Legalese
The YODL package consists of the sources for the YODL program, this documentation, all macro packages which are written by me and which are also in the distribution, and all post-processors of YODL's output. I hereby reserve the copyright for the whole YODL package, as described above. You are allowed to redistribute the package, as long as you provide all distribution files (including this message). You are allowed to use the package for any non-commercial activity. If you wish to use the package in a commercial setting, contact me first. (There is no reason at all why YODL shouldn't be used commercially. Consider contacting me as a small compliment to the author and maintainer.)

I cannot force you to leave all files of the YODL distribution unmodified. However, I do kindly request that you don't modify any of the files prior to (re)distribution. The reason for this is that I'd like to have the latest version too. If you have useful additions to the package, please mail me and I'll incorporate the changes (when I find the time). I can be reached as karel@icce.rug.nl. Or, if you find bugs and have the fix, mail me a description of the bug, the general idea of the fix, and if possible the diffs.

As for warranties: YODL is free of charge, so don't expect any. If you think that YODL crashed your hard disk and destroyed years of work then you're out of luck (very highly unlikely.. I wrote YODL without malevolent intentions and it's just a translation program after all..).

The YODL package isn't shareware, it isn't beggarware, it isn't freeware. First of all, it's megahard-ware, because, who wants a picosoft. Second, it's postcardware! That means, send me a postcard (preferably from a far-away place) if you like it. But mostly, it's GPL-ware, see one of the files COPYING on your disk.

Incase you decide to send me a postcard: I can be reached as

    Karel Kubat
    Rietveldlaan 37
    9731 MJ Groningen
    The Netherlands

Chapter 2: YODL User Guide
This section describes the yodl program from the point of a meta-user, one who is interested in how macro files work, or one who wants to write a new converter. If you're just interested in using YODL with the pre-existing converters and macro files, skip this chapter and continue with the macro package description (chapter 3).

The yodl program the main converter of the YODL package. The basic usage of the yodl program, yodl's built-in macros, and the syntax of the YODL language is described here.

2.1: Using the yodl program
The yodl program is reads one or more input files, interprets the commands therein, and writes one output file. The program is started as:

yodl flags inputfile [inputfile...]

In this specification, the flags are optional and may be:

o   -D name: Defines name as a symbol. This flag is similar to the DEFINESYMBOL statement which may appear in the text. The purpose of defining symbols is described later.

o   -I directory: This defines the system-wide include directory where yodl searches for its input files when they cannot be located by their bare name. E.g. a statement to include a given file:

    INCLUDEFILE(latex)

    will search for the file latex in the current directory, and when that fails, in the system-wide include directory. The system-wide include directory is typically the place where the maintainer of a system stores macro-files for YODL. This searching process applies to files that are included inside a document but also applies to filenames on the command line when invoking the yodl program.

    The name of the included file (latex in the above example) is the bare name, the yodl program will supply a default extension if necessary.

    The -I flag overrules YODL's built-in name for the system-wide include directory. The built-in name is defined when compiling YODL, and is usually /usr/local/lib/yodl.

o   -l number: This flag controls the live data policy; number is default 0. This means that macros that can access your operating system (these are the macros SYSTEM and PIPETHROUGH) are disabled. The number valuse can be:

o   0: (the default): No potentially harmful macros are allowed.

o   1: The macros can be executed, but only after user confirmation is obtained. The macros in question are shown while the YODL document is processed.

o   2: The macros are executed, but also shown during the YODL run.

o   3: The macros are executed, and not shown during the run. Use -l3 only when a document has proven `unharmful'.

    These macros are further discussed in the sections 2.3.32 (the SYSTEM macro) and 2.3.25 (the PIPETHROUGH macro).

o   -o file: This option causes YODL to write its output to file. By default, the output goes to the standard output stream. E.g., you can use the yodl program to read a file input and to write to output with the following two commands:

    yodl input > output yodl -ooutput input

o   -P cmd: This flag `pre-loads' the string cmd to the yodl processor. It is as if the cmd were before any actual input.

    More than one -P cmd flags may be present on the command line. Each of the commands is sent to the processor before any input is read.

o   -p maxpass: This flag causes YODL to abort when the number of parsing cycles exceeds maxpass, which is usually 20. Exceeding this number usually means a circular definition somewhere in the document. This is the case when, e.g., a macro a expands to b, and b expands again to a. Alternatively, the maxpass cycle can be exceeded when a file a.yo includes b.yo, while b.yo includes a.yo etc..

o   -t: This flag enables tracing: while parsing, YODL writes its output to the standard error stream. As is the case with the -k flag, this option is for debugging purposes.

o   -v: This flag increases YODL's `verbosity level' and may occur more than once. The presence of one -v causes YODL to show which files are parsed; four -v's show the inner workings of YODL's lexical analyzer.

o   -w: The presence of this flag caused YODL to warn when, e.g., symbols are redefined.

The inputfile elements on the command line specify which files YODL should process. All names are supplied with an extension (this extension is defined in the installation of YODL and is usually .yo). The files are then searched for `as-is', or in the system-wide include directory.

Note that all filenames on the command line are input files. To define an output file, either use the -o flag or redirect the output.

2.2: The YODL grammar
The grammar which is used by the YODL system mixes `real' text that should appear on the output with commands for YODL. The commands must follow a certain grammar, which is described in this section.

2.2.1: Language elements
The basic elements of the YODL grammar are identifiers, names, numbers and parameter lists.

Identifiers
    are names that can have a special meaning in the YODL language. E.g., the sequence INCLUDEFILE is such an identifier: when followed by a filename in parentheses, YODL will take some special action (in this case, read the file).

    Identifiers may consist of uppercase or lowercase characters. No other characters may appear in them.

A name
    is a `one-word' sequence, i.e., a series of characters where no spaces, tabs or newlines appear. E.g., the YODL language requires a name to follow the INCLUDEFILE identifier, enclosed in parentheses.

Numbers
    consist of digits. YODL seldom uses numbers, but they are required.

Parameter lists
    are the arguments that names or numbers that are arguments to a YODL command. A parameter list must be enclosed by parentheses.

Basically, YODL only does `something special' when it encounters a recognized identifier, followed by a parameter list. Sometimes an identifier may be followed by more than one parameter list, in that case, the action requires more than one argument. The grammar of YODL requires that the identifier and its first parameter list follow right after each other, without intervening spaces. That means that

somemacro (argument)

will not start any YODL action (supposing that somemacro is the name of a defined macro), since the parameter list and the identifier are separated by a space. The YODL grammar is very strict in this sence; this rule however simplifies the parsing process of the input.

To make life easier for those who write documentation using YODL, there may be spaces or newlines between the parameter lists (i.e., between the first and second parameter list, between the second and third, and so on). Therefore, assuming that somemacro now is defined as a macro having three arguments, the following will work:

somemacro(argument one)
    (and another argument, number two)
    (and the last one)

Summarized, an identified macro is only expanded by YODL when it is followed by a parameter list without spaces in between. Further parameter lists may follow separated by spaces, tabs or newline characters. All required parameter lists must however be in the same input file.

2.2.1.1: Unbalanced parameter lists
YODL recognizes the arguments to a macro as parameter lists, i.e., delimited by ( and ). As long as the number of opening and closing parentheses matches, YODL will correctly recognize the list. E.g., given a hypothetical macro somemacro, the following code sample shows the macro followed by one parameter list:

somemacro(Here is a chunk of text.) somemacro(Here is a some (more) text.)

A problem arises when the number of parentheses is unbalanced: i.e., when the parameter list consists of more opening than closing parentheses or v.v.. To handle such situations, YODL offers a `literal-character' mechanism (see the CHAR macro in 2.3.3) and a `global substitution' mechanism (see the SUBST macro in 2.3.30). For example, to send the text

here's a ")" closing parenthesis

as an argument to our hypothetical macro somemacro, the following can be used:

COMMENT(-- Alternative 1: using CHAR --) somemacro(here's a "CHAR(41)" closing parenthesis) COMMENT(-- Alternative 2: using SUBST --) SUBST(closepar)(CHAR(41)) . . somemacro(here's a "closepar" closing parenthesis)

Both methods have disadvantages: the CHAR method requires you to remember that an ASCII 41 is a closing parenthesis. The SUBST method defines a string closepar that is always expanded to a closing parenthesis, wherever in the text it occurs. Nevertheless, unbalanced parameter lists can be handled by YODL. (If the here described method proves to be too much of a pain, I'll think of something. As for myself, I've never yet have felt the need to use an unbalanced parameter list -- except in this document..) Also, remember that unbalanced parenthesis pairs are only relevant in argument lists. YODL handles parentheses in normal text as ordinary characters.

2.2.2: Line continuation
To make the typing of input easier, YODL allows you to end a line with a backslash character \ and to continue it on the next line. That way you can split long lines to fit your screen. When processing its input, YODL will treat these lines as one long line, and will of course ignore the \ character. This feature only works when the \ character is the last one on the line (no spaces may follow).

When the line following the one with the \ character has leading spaces, then these are omitted. This allows you to `indent' a file as you wish, while the space characters of the indentation are ignored by the yodl program.

A trivial example is the following:

Grampa and\
    grandma are sitting on the sofa.

Due to the occurrence of the \ character in the sequence and\, YODL will combine the lines into

Grampa andgrandma are sitting on the sofa.

Note that the spaces before grandma are ignored, since this is the second line following a \ character.

If you do want one or more spaces while joining lines with \, put the spaces before the \ character.

Summarized:

o   A Line that ends in a backslash character is merged with the following line.

o   This only occurs if the \ character is the last character of the line, no spaces may occur after the character.

o   When merging lines, YODL ignores leading spaces of the second line.

The question is of course, how do you accomplish that a line really ends with a \, when you do not want YODL to merge it with the following line? In such a case, type a space character following your \: YODL won't combine the lines. Or set the \ character as CHAR(\) or CHAR(92) (see section 2.3.3 for the CHAR macro). In my opinion, the ease of line continuation in YODL files outweighs the extra necessary actions to typeset a real \ character at the end of a line.

2.2.3: The +identifier sequence
One more feature of the YODL language remains to be described. There may be situations in which you must type a macro name right after a sequence of characters, while YODL should recognize this. Imagine that someone wrote a great macro footnote for you (someone did, in fact, see the next chapter), to typeset footnotes. If you'd type in a document:

The C Programming Languagefootnote(as defined by Kernighan and Ritchie) ...

then of course YODL would fail to see the start of a macro in the sequence Languagefootnote. You could say

The C Programming Language footnote(as defined by Kernighan and Ritchie) ...

but that would introduce a space between Language and the footnote. Probably you don't want that, since spaces between a word and a footnote number look awful and because of the fact that the footnote number might be typeset on the following line.

For these special situations, YODL recognizes the +identifier sequence as the start of a macro, while the + sign is effectively ignored. In the above example you could therefore use

The C Programming Language+footnote(as defined by Kernighan and Ritchie) ...

The +identifier recognition only works when the identifier following the + sign is a macro. In all other situations, a + is just a plus-sign.

(The +identifier sequence furthermore plays an important role in macro packages. If you're interested, see the file shared.yo which is by default installed to /usr/local/lib/yodl.)

2.3: 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 3 that describes a macro package for YODL.

2.3.1: ADDTOCOUNTER
The ADDTOCOUNTER macro 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 NEWCOUNTER.

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

See further section 2.6.

2.3.2: ATEXIT
The macro 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..

A good example of the usage of this macro 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(Make sure that the ending is
        on time.) ATEXIT(NOEXPAND(\end{document}))

2.3.3: 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 2.4). Also, the CHAR macro can be used to circumvent YODL's way of matching parentheses in a parameter list.

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 macro NOTRANS (see section 2.3.22). If you want to send a string to the output without macro interpretation, but with character table translation, use NOEXPAND (see section 2.3.21).

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

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

This fragment can be changed to:

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

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

2.3.5: COMMENT
The COMMENT macro takes one parameter list. The text in the list is treated as comment; i.e., nothing is done with it. The text is not copied to the final output file; this command is meant as comment for YODL files only.

2.3.6: COUNTERVALUE
The macro COUNTERVALUE expands to the value of a counter. Its only parameter list is a counter name. The counter must be previously created by NEWCOUNTER.

See further section 2.6.

2.3.7: DEFINECHARTABLE
The macro DEFINECHARTABLE is used to define a character translation table. Its complement, USECHARTABLE, activates the table. The discussion of character tables is postponed to section 2.4.

2.3.8: DEFINEMACRO
The macro DEFINEMACRO lets you define new macros. This macro requires three parameter lists:

o   An identifier, being the name of the macro to define. This identifier must only consist of uppercase or lowercase 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, that should be enough for most 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:

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

It would of course lead to:

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.

A few caveats when defining new macros are:

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

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

    introduces an extra newline, that will be copied to the output each time that the macro is used. The extra newline occurs, of course, right before the sequence Author(s):. A simple backslash character at the end of the DEFINEMACRO line would prevent the insertion of an extra newline character.

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 3) 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.

2.3.9: DEFINESYMBOL
The macro DEFINESYMBOL takes one argument, an identifier, which is treated as a symbol that is set to the logic value `true'. The true-ness or false-ness of this symbol may subsequently be tested with IFDEF (see section 2.3.13).

The corresponding macro UNDEFINESYMBOL removes the definition of a symbol.

Example:

Definining "somesymbol"... DEFINESYMBOL(somesymbol) IFDEF(somesymbol)
    (Symbol "somesymbol" is true.)
    (Symbol "somesymbol" is false.) Removing definition of "somesymbol"... UNDEFINESYMBOL(somesymbol) IFDEF(somesymbol)
    (Symbol "somesymbol" is true.)
    (Symbol "somesymbol" is false.)

This produces output similar to:

Definining "somesymbol"... Symbol "somesymbol" is true. Removing definition of "somesymbol"... Symbol "somesymbol" is false.

2.3.10: DUMMY
This macro takes one argument, which is not interpreted. The macro is a real dummy, it does nothing.

(I implemented the macro in order to provide a simple debugging hook. After inserting DUMMY() somewhere in the macro file, I can start the yodl program under a debugger and set a breakpoint in the dummy-routine; then watch what happens from there.)

2.3.11: ENDDEF
The macro ENDDEF takes one (empty) parameter list. It signals the ending of a YODL definition section. See the description of STARTDEF, 2.3.31.

2.3.12: ERROR
The ERROR macro 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.

This command can be used, e.g., in a macro package when an incorrect macro is expanded. In my macro package (see chapter 3) the ERROR macro 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 macro is WARNING, which also prints a message but does not exit (see section 2.3.39).

2.3.13: IFDEF
The IFDEF macro tests for the logical true value of the argument in its first parameter list. If `true', 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.

The variable in the first parameter list evaluates the macro to `true' when the first argument is:

o   a built-in macro,

o   a user-defined macro (see DEFINEMACRO, section 2.3.8),

o   a logical symbol (see DEFINESYMBOL, section 2.3.9),

o   a counter (see NEWCOUNTER, section 2.3.20).

For an example, see the description of DEFINESYMBOL, section 2.3.9.

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

A trivial example is the following:

IFEMPTY(something) \
    ("something" is supposedly nothing ?!?")
    ("something" is not an empty string)

In the same way, IFEMPTY can be used to test whether a macro 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 of course supply Unknown in the Published by: line.

2.3.15: IFSTREQUAL
The macro 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 two string arguments match exactly.

2.3.16: IFSTRSUB
The IFSTRSUB macro tests whether a string is a sub-string of another string. It is similar to IFSTREQUAL (see section 2.3.15), except that the test is whether the second string is part of the first one. Hence:

IFSTRSUB(some piece of text)(ce o)
    (truelist)
    (falselist)

evaluates to truelist.

2.3.17: IFZERO
The IFZERO macro expects three parameter lists, just as the other IF... macros: a symbol, a true-list and a false-list.

The first argument defines whether the whole macro expands to the true-list or to the false-list. The first argument may be:

o   Nothing (empty): the macro expands to the true-list.

o   A number: when zero, the macro expands to the true-list.

o   The name of a counter: when the value of the counter is zero, the macro expands to the true-list.

o   Anything else: the macro expands to the false-list.

You can use COUNTERVALUE(somecounter) as the argument to IFZERO, it is treated in the same manner as the corresponding counter name.

Example: The IFZERO macro offers a very simple way to pass a flag-argument (an on/off switch) to a macro. E.g., in LaTeX you start environments with \begin{environment} and end them with \end{environment}; environment being e.g., center, flushright, flushleft. A possible meta-macro for the environments might be:

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

Such a macro may be used as:

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.

2.3.18: INCLUDEFILE
The command INCLUDEFILE takes one argument, a filename. The file is included.

The yodl program supplies, when necessary, an extension to the filename. The supplied extension is .yo, unless defined otherwise in the compilation of the program. Furthermore, yodl prefixes the file with the system-wide include directory if necessary. This directory is normally /usr/local/lib/yodl, unless overruled by the command line flag -I or defined otherwise in the compilation.

E.g., if you install a macro package in a file latex.yo in the directory /usr/local/lib/yodl, then the command

INCLUDEFILE(latex)

will include it.

2.3.19: INCLUDELITERAL
The command INCLUDELITERAL takes one argument, a filename. The file is included.

The filename is not changed in any way.

Furthermore the contents of the file is included literally, not subject to macro expansion. Character translations are allowed.

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

INCLUDELITERAL(literal.c)

This example shows how to put the contents of C file literal.c into the document.

2.3.20: NEWCOUNTER
The macro NEWCOUNTER creates a new counter, to be subsequently used by, e.g, the USECOUNTER macro. NEWCOUNTER expects one parameter list: the name of the counter to create. See further section 2.6.

2.3.21: NOEXPAND
The macro NOEXPAND is one of the ways in which text can be sent to the final output file without being expanded by YODL (the other methods are the CHAR macro, see section 2.3.3, and the NOTRANS macro, see section 2.3.22). The macro 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 macros in the argument, which are expanded). The contents of the parameter list are subject to character table translations, using the currently active table (see section 2.4).

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 macro, 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 expanded. 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 macro must, as all macros, 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.

2.3.22: NOTRANS
The macro NOTRANS copies its one argument literally to the output file, without expanding macros in it (except for CHAR, which is expanded) and without translating the characters with the current translation table. The NOTRANS macro 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 \{} 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})

The NOEXPAND macro in this example will send

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

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

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

2.3.23: NOUSERMACRO
The macro NOUSERMACRO controls yodl's warnings in the following respect. 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, but fails to lookup the macro. The yodl program 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 hee 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 spaces, commas, colons, or semi-colons.

2.3.24: PARAGRAPH
The PARAGRAPH macro is defined by the YODL program, but is had normally no actions. The macro works as follows.

If you define the macro, then YODL's parser will trigger it whenever a new paragraph is started. The macro must be defined as one with zero arguments, but leading to some (necessary) action. New paragraphs are -by definition- indicated in the source file as two or more consecutive newline characters, optionally separated by spaces. I.e., in the text

Here is a line of text. And here's another one.

one new paragraph occurs: the first line is terminated by a newline, then one newline follows right behind. Given such input, the PARAGRAPH macro is triggered right before the parsing process of the line starting with And.

Some macro packages do not need paragraph starts; e.g., LaTeX does its own paragraph handling. Other macro packages 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)(<p>)

Note that the definition of the action of the PARAGRAPH macro is again parsed and expanded by YODL. Therefore, if you put two consecutive newlines in the definition itself, the definition will again trigger the PARAGRAPH macro, etcetera, ad infinitum. If you want the PARAGRAPH redefinition to insert a blank line, protect the line in a NOEXPAND, as in:

DEFINEMACRO(PARAGRAPH)(0)(NOEXPAND( )<p>)

2.3.25: PIPETHROUGH
The builtin macro PIPETHROUGH is, besides SYSTEM, the second macro 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 2.3.32). 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 PIPETHROGUH macro takes two arguments:

o   the command to run, and

o   the text to send to that command.

Functionally, the occurrence of the PIPETHROUGH macro 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: PIPETHROGH(date)()

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

The main purpose of this macro 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.

2.3.26: 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 2.4.3.

2.3.27: PUSHCHARTABLE
After a character table has been defined, it can be "pushed" onto a stack; to be "popped" later. This discussion is postponed to section 2.4.3.

2.3.28: RENAMEMACRO
The command 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), and no longer using INCLUDEFILE.

Note that following the RENAMEMACRO action, the old name can no longer be used; it is then an unknown 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 read in a file.

2.3.29: SETCOUNTER
The SETCOUNTER macro expects two parameter lists: one counter name, and one numeric value. The corresponding counter (which must be previously created with NEWCOUNTER) is set to the numeric value.

See also section 2.6.

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

SUBST(VERSION)(1.00)

the yodl program will output 1.00 for each occurence of VERSION in its input.

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

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

Each 'e in the input would then be converted to e.

The SUBST macro may also be useful in combination with the command line flag -P, as in a invocation

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

A further useful substitution may be the following:

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

which defines an opening parenthesis (_OP_) and a closing parenthesis (_CP_) as mapped to the CHAR macro. The strings _OP_ and _CP_ might then be used in 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.

2.3.31: STARTDEF
The STARTDEF macro typically occurs in files that define a macro package for YODL. The macro signals the yodl program that the following input holds only the definitions of macros, symbols etc..

When yodl is inside a definition, the generation of empty lines on the output is suppressed, and yodl warns when non-whitespace output is generated. Using STARTDEF is never obligatory, but it is useful in a macro file. Macro files tend to define a lot of symbols or commands, leading to unnecessary spaces and newlines.

The definition section is ended with the ENDDEF macro.

Example:

STARTDEF() DEFINESYMBOL(....) DEFINEMACRO(...)(...)(...) ENDDEF()

Without the STARTDEF and ENDDEF, the above definition would generate four empty lines in the output.

2.3.32: SYSTEM
The SYSTEM macro takes one argument: a command to execute. The command is run via the standard C function system. The presence of this macro in the YODL language introduces the danger of live data; imagine someone sending you a document with

SYSTEM(rm *)

in it. To avoid such malevolent side effects, the yodl program has a flag -l to define the `live data policy'. By default, -l0 is implied which suppresses the SYSTEM macro and the related PIPETHROUGH macro. See also section 2.1.

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)

2.3.33: TYPEOUT
The macro 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))

2.3.34: UNDEFINEMACRO
The macro UNDEFINEMACRO removes a definition of a macro that was defined by DEFINEMACRO. This macro 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:

UNDEFINEMACRO(mymacro) DEFINEMACRO(mymacro)(1)(This is my macro with argument ARG1.)

2.3.35: UNDEFINESYMBOL
The macro UNDEFINESYMBOL removes the definition of a logical symbol. It expects one parameter list, holding the variable to undefined.

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

2.3.36: UPPERCASE
The UPPERCASE macro convderts 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

2.3.37: USECHARTABLE
The macro USECHARTABLE takes one parameter list: the name of a translation table to activate. The table must be previously defined using DEFINECHARTABLE. See section 2.4 for a description of character translation tables.

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

2.3.38: USECOUNTER
The macro USECOUNTER is a combination of ADDTOCOUNTER and COUNTERVALUE. It expects one parameter list: a counter name, that must be previously created with NEWCOUNTER.

The counter is first increased by 1. Then the macro expands to the number of the counter.

See also section 2.6.

2.3.39: WARNING
The WARNING macro 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 2.3.33).

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

2.4: Character tables
The YODL language provides a way to define character translation tables, to activate them, and to deactivate them. A character translation table defines how a character in the input will appear in the output.

There are two main reasons for the need of character translation tables. First, a document language becomes much easier to use when you can type an asterisk as * instead of $*$ or \verb/*/ (these are sequences from the LaTeX document language). Hence, a mechanism that expands a * in the input to to \verb/*/ on the output, saves the users a lot of typing.

Second, forcing users to type weird sequences won't work if you're planning on converting the same YODL document to a different output format. If the user types \verb/*/ in the input to typeset an asterisk in the output, how should he or she arrive at a single * in the output in another output format?

The solution is of course to define the translation for an input character like * given the output format.

2.4.1: Defining a translation table
The built-in macro DEFINECHARTABLE defines a character translation table. It takes two parameter lists: the name of the table and the character translations. Hence, each table is defined by its own name.

As an example of a table, consider the following fragment. It defines a table that translates the upper case characters A to E to their lower case equivalents:

DEFINECHARTABLE(tolower)(
    'A' = "a"
    'B' = "b"
    'C' = "c"
    'D' = "d"
    'E' = "e" )

Each DEFINECHARTABLE statement must have a non-empty second parameter. "Empty" character tables cannot be defined, though one non-translation table is built-in.

The syntaxis of the second parameter list is as follows:

o   On separate lines, input characters are mapped to a sequence to appear on the output.

o   Per line, the input character is specified as 'c', c being any character. Escape-sequences from the C programming language can be used in this specification; YODL supports the sequences \a (alert), \b (beep), \f (formfeed), \n (newline), \r (carriage return), \t (tab), and \v (vertical tab). Any other character following a \ defines itself: \\ defines one backslash character.

o   Following the character specification, a = must appear.

o   Following that, a sequence of one or more characters appears, enclosed in double quotes, defining the translation. Again, escape sequences can be used, as in:

    '\n' = "End of line\n"

    Such a mapping adds the text End of line to each line, since each newline character in the input is replaced by the text End of line, followed by the newline itself.

Translations which are not specified in the table are left to the default, which is to output the character as-is.

Note that the character table translation is something that the yodl program does as one of its last actions, just before sending text to the output file. The expansion text is not further processed by yodl, except for the conversion of C-type escape sequences to ordinary characters. The expansion text should therefore not be protected by, e.g., NOTRANS (unless of course you want some character to generate the text NOTRANS on the output).

2.4.2: Using a translation table
A defined translation table is activated by the macro USECHARTABLE. This macro takes one parameter list, which may be:

o   empty, in which case the default mapping is restored,

o   a name of a previously defined character table.

The default mapping, selected when an empty parameter list is given, means that YODL enters its `zero translation state', meaning no character translation at all.

2.4.3: Pushing and popping character tables
Besides the previously described macro USECHARTABLE(), Yodl has one other mechanism of activating and deactivating character translation tables. This mechanism uses a stack, and hence, the related macros are appropriately named PUSHCHARTABLE() and POPCHARTABLE().

o   PUSHCHARTABLE(name) pushes the currently active translation table onto a stack, and activates the table identified by name. The argument may be emtpy; in that case, the zero-translation table is activated (analogously to USECHARTABLE()).

o   POPCHARTABLE() activates the translation table that was last pushed. There is no argument to this macro.

Using the push/pop mechanism is handy when a table must be temporarily activated, but when it is not known which table exacty is active prior to the temporary activation. E.g., imagine that you need to use a character table called listing to typeset a listing, but that you do not know the current table. The pushing and popping mechanism is then used as follows:

COMMENT(First, we save the current table on the stack and
        we activate our "listing" table.) PUSHCHARTABLE(listing) COMMENT(Now the text is question is typeset.) ... COMMENT(The previously active table is re-activated, whatever its name.) POPCHARTABLE()

2.5: Sending literal text to the output
The YODL program has three built-in macros to send literal text to the output file. The macros are listed in the above section 2.3 and are furthermore described here.

o   The CHAR macro takes one argument: the ASCII number of a character or the character itself. The character is sent to the output file without being translated with the currently active character translation table.

o   The NOTRANS macro takes one argument: the text in question. The text is neither parsed (i.e., macros in it are not expanded), nor translated with the current character translation table.

    The NOTRANS macro is conceptually like a series of CHAR macros.

o   The NOEXPAND macro takes one argument: the text in question. The text is not parsed, but it is translated with the current character translation table.

To illustrate the need for the distinction between NOTRANS and NOEXPAND, consider the following. The HTML converter (described in chapter 3) must be able to send HTML commands to the output file, but must also be able to send literal text (e.g., a source file listing). The HTML commands of course must be neither translated with any character table, nor must they be expanded in regard to macros. In contrast, a source file listing must be subject to character translations: the &, < and > characters can cause difficulties. Two possible macros for a HTML converter are:

COMMENT(--- htmlcommand(cmd) sends its argument as a HTML command
            to the output ---) DEFINEMACRO(htmlcommand)(1)(NOTRANS(ARG1))

COMMENT(--- verb(listing) sends the listing to the output ---) DEFINECHARTABLE(list)(
    '&' = "&amp;"
    '<' = "&lt;"
    '>' = "&gt;" ) DEFINEMACRO(verb)(1)( \
    USECHARTABLE(list) \
    NOTRANS(<listing>) \
    NOEXPAND(ARG1) \
    NOTRANS(</listing>) \
    USECHARTABLE(standard))

In this example it is assumed that a character translation table standard exists, defining the `normal' translations. This table is re-activated in the verb macro.

2.6: Counters
Some document languages (notably LaTeX) automatically prefix numbers when typesetting sections, subsections, tables, figures etc.. Other document languages (e.g. HTML) unfortunately don't.

Therefore, a macro package that converts a YODL document to LaTeX doesn't need to provide the numbering of sections etc.. However, if you do want the numbering and if you want to convert documents to, say, HTML, then you must take care of the numbering yourself.

This section describes the counters in YODL: how to create a new counter, how to use it, etc..

2.6.1: Creating a counter
Before a counter can be used, it must be created with the macro NEWCOUNTER. This macro expects one parameter list: the name of the counter. The initial value of the counter is set to zero.

As for an example, let's say that our macro package should provide two sectioning commands: section and subsection. The sections should be numbered 1, 2, etc., and the subsections 1.1, 1.2, 1.3 etc.. Hence we'd need two counters:

NEWCOUNTER(sectcounter) NEWCOUNTER(subsectcounter)

2.6.2: Using counters
YODL has four macros to modify and/or to set the values of counters. The macros are:

o   COUNTERVALUE(somecounter): This macro expands to the value of somecounter. E.g., if the current value is 2, then the macro writes 2 on the output file.

o   SETCOUNTER(somecounter)(number): This macro sets the value of somecounter to the value of number. The second parameter list must be an integer number (i.e., consisting of the characters 0 to 9, optionally prefixed by a - sign). The macro does not expand to anything; i.e., it does not write to the output file.

o   ADDTOCOUNTER(somecounter)(number): This macro adds the value of number to somecounter. The number may be negative.

o   USECOUNTER(somecounter): This macro first increases the value of somecounter by 1, and then writes the value of the counter to the output file.

    This command is particularly useful in combination with NEWCOUNTER: since NEWCOUNTER initializes a counter to zero, USECOUNTER can be used to increase the value and to output it. The first time that USECOUNTER is used on a new counter, the number 1 appears on the output file. The next time, number 2 appears on the output file etc..

Given the numbering requirements of the hypothetical commands section and subsection (see the previous section), we can now complete the definitions:

NEWCOUNTER(sectcounter) NEWCOUNTER(subsectcounter) DEFINEMACRO(section)(1)(\ SETCOUNTER(subsectcounter)(0)\ USECOUNTER(sectcounter) ARG1) DEFINEMACRO(subsection)(1)(\ COUNTERVALUE(sectcounter).USECOUNTER(subsectcounter) ARG1)

Chapter 3: A macro package for YODL
The macro package which is distributed with the YODL package is described in this chapter. The macro package consists of a number of definition files, which convert a YODL document that follows a certain syntax to an output format. The main supported output formats are LaTeX (just plain LaTeX, no latex2e included) and HTML 2 (some features of the HTML converter may use HTML 3.0), the groff `man' format which is used for man pages and the groff `ms' format which is more expressive. More formats may be made available as the need arises.

Two primitive output formats are also available. First, the output format SGML is included in the package, though the converter is not very stable nor complete: I wrote the converter for backward-compatibility for our existing Linuxdoc-SGML programs. The SGML converter is not really for public consumption. Second, the plain ASCII output converter creates a `bare' text file, stripping the YODL input files of its commands. The ASCII converter is the most rudimentary of the set; a `last-resort' option.

The macro files may not be yet perfect, but I'm working on it as I'm using it. If you find errors or omissions in the macro package, don't hesitate to contact me.

3.1: Files of the macro package
The files of which the macro package consists are by default installed to the directory /usr/local/lib/yodl during YODL's installation process (your system administrator may have chosen another location, though). The files in this directory are, e.g., tex.yo and html.yo, and by their name define the output format: tex for LaTeX and html for HTML. The names are also expected by the conversion shell scripts; e.g,, yodl2tex will expect the file tex.yo, yodl2html will expect the file html.yo, etc.. This directory furthermore holds several post-processors (described later) and a subdirectory chartables, where character conversion tables are located.

The programs of the YODL package are the yodl program itself and auxiliary scripts such as yodl2tex, yodl2html. All programs are normally installed to /usr/local/bin.

3.1.1: Conversion script invocations
The YODL package is distributed with scripts yodl2tex, yodl2html and other yodl2... drivers. Basically, an invocation like

yodl2tex file

starts the yodl program to process file.yo and to write output to file.tex. The extension of the input file, .yo, is the default YODL extension; the extension of the output file, .tex, is given by the name of the shell script. The script yodl2html hence writes to a file with the extension .html.

Furthermore, the conversion scripts auto-load the right macro file: tex.yo for LaTeX conversions, html.yo for HTML conversions, etc.. The macro files are of course found in the system-wide include directory.

When the conversion scripts are started without arguments, usage information is shown.

The output files are, depending on the conversion:

o   For LaTeX conversions, one output file with the extension .tex is written.

o   For HTML conversions, several files may be written holding the separate chapters of the original document. When the document is not sectioned by chapters, only one output file is created.

    The `main' output file always has the name of the input file but with extension .html. This file holds the document title and the table of contents. When more than one output files are created, then they are named name01.html, name02.html etc., where name is the original name of the input file. E.g., a document prog.yo might lead to prog.html, prog01.html etc..

o   For groff conversions two output formats are supported: the man format (invoked by yodl2man and resulting in a file .man), and the ms format (invoked by yodl2ms and resulting in a file .ms). The differences between the man and ms macro sets of groff make different converters and output files necessary.

o   For SGML conversions, one output file with the extension .sgml is written.

o   For ASCII conversions, the converter is named yodl2txt and one output file with the extension .txt is created.

The YODL package furthermore holds `second-step' scripts, which are:

o   The conversion script yodl2dvi is one more step on top of yodl2tex: it also runs LaTeX on the resulting .tex file. This script tries to be smart about it; when LaTeX' logfile indicates warnings about unresolved labels, the LaTeX process is started once again. This process is repeated up to three times.

o   The script yodl2manless is an extra step to yodl2man: it converts a .yo file to .man format, and runs groff on it, piping the output to a less-like pager for viewing.

o   Similar to yodl2manless, the script yodl2msless starts the ms converter and pipes the groff output through a pager.

o   The script yodl2msps is an extra step on top of the ms converter; it converts the ms output file into PostScript format.

The scripts yodl2manless and yodl2msless start groff with the instruction to produce plain ASCII text. The groff program then (usually) outputs boldface as overstrike, and italics as underlined. This convention is most often used, and is meant to provide some degree of font alternation for printed ASCII documents. If you want to convert a YODL document to true ASCII, without overstrikes or underlines, take a look at the C program striproff which is included in the YODL distribution as misc/striproff.c. This program is not compiled and installed by the default YODL installation process, but is only distributed as an example. If you choose to compile and install it, you can use it as follows, assuming that you have a manpage document mymanpage.yo and an article myarticle.yo:

% yodl2manless mymanpage | striproff > mymanpage.txt % yodl2msless myarticle | striproff > myarticle.txt

3.2: Macros of the package
The following sections describe the macros that are defined in the macro package by groups. Following the description, the macros are listed in alphabetical order.

3.2.1: Conversion defines and literal commands
According to the format of the output file, the macro package defines a given symbol:

o   latex when the output format is LaTeX,

o   html when the output format is HTML,

o   man when the output format is groff in conjunction with the man macro package,

o   ms when the output format is groff with the ms package,

o   sgml when the output format is SGML,

o   txt when the output format is plain ASCII.

The defined symbol can be tested in a document to determine the conversion type.

Furthermore, the package defines the following macros to send litteral text (commands in the output format) to the output file:

o   latexcommand(cmd): sends the LaTeX command cmd when in LaTeX conversion mode. The cmd is not further expanded.

o   htmlcommand(cmd): sends the HTML command cmd when in HTML conversion mode. The cmd is not further expanded.

o   htmltag(tag)(onoff): sends <tag> to the output when onoff is nonzero, or sends </tag> when onoff is zero. Only active in HTML conversions.

o   mancommand(cmd): sends cmd to the output when in man conversion mode. The cmd is not further expanded.

o   mscommand(cmd): sends cmd to the output when in ms conversion mode. The cmd is not further expanded.

o   roffcmd(dotcmd)(trailer)(secondline)(thirdline): sends a command to the output when in man or ms conversion mode. The dotcmd is the typical groff command that starts with a dot. All other arguments may be empty, but when given are interpreted as follows. The trailer follows the dotcmd on the same line. The secondline is sent on a separate line following the dotcmd and trailer. The thirdline is sent after that. Of the four arguments, dotcmd and thirdline are not subject to further expansion. All other arguments are further expanded if necessary.

    The roffcmd macro illustrates the complexity of dot-commands for the divers groff macro packages. E.g., a section title for the man package should look as

    .SH "Section Title"

    while the same command for the ms macro package must be sent as

    .SH Section Title .PP

    The roffcmd macro can be used to send these commands to the output file as follows:

    COMMENT(For the man output format:) roffcmd(.SH)("Section Title")()() COMMENT(For the ms output format:) roffcmd(.SH)()(Section Title)(.PP)()

o   sgmlcommand(cmd): sends the SGML command cmd when in SGML conversion mode. The cmd is not further expanded.

o   sgmltag(tag)(onoff): sends <tag> when onoff is nonzero, or sends </tag> when onoff is zero. Only active in SGML conversions.

o   txtcommand(cmd): implemented for compatibility reasons, though a `command' in plain ASCII output doesn't make much sense. The usefulness of this macro is rather in the fact that it only produces output when in ASCII conversion mode.

The above commands can be used to quickly implement a macro. E.g., the macro package implements the it macro (which starts an item in a list) as:

DEFINEMACRO(it)(0)(\
        latexcommand(\item )\
        htmlcommand(<li> )\
        ....)

Depending on the output format, it() will lead to one of the above expansions.

The above described formatcommand() macros are implemented to send not further expanded strings (i.e., commands) to the output. The macro package also implements whenformat() macros to send any text, which is then subject to further expansion. These when...() macros are:

o   whenlatex(text): sends text when in LaTeX conversion mode,

o   whenhtml(text): sends text when in HTML conversion mode,

o   whenman(text): sends text when in man conversion mode,

o   whenms(text): sends text when in ms conversion mode,

o   whentxt(text): sends text when in ASCII conversion mode,

o   whensgml(text): sends text when in SGML conversion mode.

Note again that the difference between the whenformat() macros and the formatcommand() macros is, that the former will expand their argument while the latter will not. As an example, consider the following code fragment:

You are now reading
        whenlatex(a LaTeX-generated
                  footnote(LaTeX is a great
                   document language!)
                  document)
        whenhtml(a HTML document via your
                 favorite browser)

The whenformat() macros are used here to make sure that the arguments to the macros are further expanded; this makes sure that the footnote macro in the whenlatex block gets treated as a footnote.

3.2.2: Document types
The macro package supports four document types: article, report, book and the manual page. Note that document types have nothing in common with output formats; a book can be converted to each of the output formats, and a manual page can be converted to a .dvi file. Nevertheless, some formats are more useful for some document types. A book that is converted to the man output format to be later processed with groff won't look too good; a better conversion to ASCII would be via the ms output format.

Each document must be started by specifying the document type. The relevant macros are:

o   article(title)(author)(date): The article document type is meant for short documents. The macro arguments specify the title of the document, the author and the date.

    In articles, the title page is numbered and the table of contents is on the title page. The sectioning commands sect, subsect etc. are available.

o   report(title)(author)(date): The report document type differs from an article in that it has a separate unnumbered title page, a table of contents on its own page, and the sectioning command chapter. A report is meant for larger documents.

o   book(title)(author)(date): The book type is for still larger documents. It supports the sectioning command part.

o   manpage(title)(section)(date)(source)(manual): The manpage document type is specifically meant to write manual pages, as found on Unix systems. It uses its own sectioning commands to reflect the necessary sections in a manual page. This document format is described separately in 3.3.

o   plainhtml(title): This document type is typically used in HTML output. It's implemented for situations where you only need to create a HTML file, but want to use the YODL package to help you with handy macros. Except for the fact that no author and date arguments are necessary, this document type is similar to article. (In fact, you can emulate plainhtml by using an article, but without author and date information for the title.)

    plainhtml is available for other output formats, though it doesn't really make sense to use it. If you want the most `portable' document type, use one of article, report or book.

The function of these macros is, globally, threefold. First, the macros must send any commands that need to appear before `real' text to the output file. E.g., the LaTeX output needs the right \documentstyle preamble, HTML output needs <html> and <body> tags.

Second, the macros define appropriate document-dependent settings. E.g., this means that the LaTeX converter defines the title, author and date using \title etc..

Third, the actual document is started. In LaTeX this means a \begin{type}, followed by the appropriate commands to generate a the document title and the table of contents. The title setting in the above macros defines the document title which always appears on the front page of the document. For HTML output, this is also the title of the HTML file (or files), as appearing in the HTML <title> tag.

The fact that the macros which define the document type perform many functions, means that once the macro is started, nothing `extra' can be put say between the generated title and the table of contents. Sometimes however this is what you'd like; as is the case with an abstract. The YODL package therefore implements modifiers, that appear before the document type macros.

3.2.2.1: Pagebreaks after the title and table of contents
In respect to the occurrence of pagebreaks in documents, YODL has the following default behavior:

o   A pagebreak is generated after the title information in book and report documents.

o   A pagebreak is generated after a table of contents in all documents.

That means, that when a document has both title information and a table of contents whatever follows next will normally be starting on a separate page. Furthermore, if the document is a book or a report, the title and table of contents will also be separated by a pagebreak.

This behavior can be modified using the (no)titleclearpage() and (no)tocclearpage() directives. This is further described in section 3.2.3.

3.2.3: Typesetting modifiers
This section lists a number of macros that can be used to modify the looks of your document. When used, these macros must appear before stating the document type with article, report, book, manpage or plainhtml.

o   abstract(text): This macro is relevant for all output formats. The text is added to the document after the title, author and date information, but before the table of contents. The abstract is usually set as a quote, in italics font (though this depends on the output format). Abstracts are supported in articles and reports, but not in other document types. I.e., if you need introductory text in a book, you should start with a non-numbered chapter that holds this text.

o   affiliation(site): This macro is relevant for article, report and book documents. It defines the affiliation of the author. The site information appears in the title, below the author's name.

o   htmlbodyopt(option)(value): This macro adds option="value" to the <body> tag that will be generated for HTML output. The HTML converter generates <body> tags each time that a new file is started; i.e., at the top of the document and at each chapter-file. Different HTML browsers support different <body> tag options, but useful ones may be e.g.:

    htmlbodyopt(fgcolor)(#000000) htmlbodyopt(bgcolor)(#FFFFFF)

    This defines the foreground color as pure white (red/green/blue all 0) and the background color as black (red/green/blue all hexadecimal FF, or 255). Another useful option may be htmlbodyopt(background) (some.gif), defining some.gif as the page background.

    See the documentation on HTML for more information.

    Note that the value is automatically surrounded by double quotes when this macro is used. There is no need to type them.

o   latexdocumentstyle(style): This macro forces the \documentstyle{...} setting in LaTeX output to style. E.g., at the ICCE we have a local article-derivate called artikel1. Using

    latexdocumentstyle(artikel1) article(..title..)
           (..author..)
           (..date..)

    will start an article as far as Yodl is concerned, but will use artikel1 in the LaTeX output.

o   latexlayoutcmds(commands): This macro can be used to specify your own LaTeX layout commands. When present, the commands are placed in LaTeX output following the \documentstyle stanza. (Thanks, Bernhard Reiter <breiter@mathematik.Uni-Osnabrueck.DE>).

o   latexoptions(options): This macro is only relevant for LaTeX output formats, it is not expanded in other formats. The options are used in LaTeX's \documentstyle preamble; e.g., useful options may be dina4 or epsf. To specify several options, separate them by a comma (this is a LaTeX convention).

    Backward compatibility note: At the ICCE, we've used Linuxdoc-SGML for some time. The modifier

    latexoptions(linuxdoc-sgml,qwertz)

    approximates the LaTeX output that this SGML variant produces. The style files linuxdoc-sgml.sty and qwertz.sty must of course be in one of the TEXINPUTS directories.

o   mailto(email): The mailto macro is only expanded in HTML documents. It defines where mail about the document should go to.

o   nosloppyhfuzz(): By default, the LaTeX output contains the text

    \hfuzz=4pt

    which is placed there by the macro package. This suppresses overfull hbox warnings of LaTeX when the overfull-ness is less than 4pt. I find this useful.

    This macro has no consequences for non-LaTeX formats.

    Use nosloppyhfuzz() to get `plain' LaTeX warnings about overfull hboxes.

o   notableofcontents(): As the name suggests, this macro suppresses the generation of the table of contents. For HTML that means that no clickable index of sections appears after the document title.

    The table of contents is by default suppressed in plainhtml and manpage documents.

o   notitleclearpage(): Normally, YODL inserts a clearpage() directive after typesetting title information in book or report documents, but not in article documents. Use notitleclearpage to suppress this directive.

o   notocclearpage() (Read as: no-toc-clearpage, read toc as table of contents.): In all document types, YODL inserts a clearpage() directive following the table of contents. Use notocclearpage() to suppress that.

o   noxlatin(): The LaTeX output contains by default the stanza to include the file xlatin1.tex, distributed with YODL. This file maps Latin-1 characters to LaTeX-understandable codes and makes sure that you can type characters such as ü, and still make them processable by LaTeX. If you don't want this, put noxlatin() in the preamble.

o   standardlayout(): This is another LaTeX option. I like my paragraph starts not to be indented, and I like more space between paragraphs. Use standardlayout() to get `vanilla' LaTeX layout.

    This macro has no consequences for non-LaTeX formats.

o   titleclearpage(): Forces the insertion of a clearpage() directive after the title information has been typeset. This behavior is the default in book and report documents. See also notitleclearpage().

o   tocclearpage(): Forces the insertion of a clearpage() directive following the table of contents. This behavior is default in all document types; the macro is provided for consistency reasons with (no)titleclearpage().

Note again that when present, the modifiers must appear before the document type definition.

3.2.4: Sectioning
This section describes the sectioning commands for articles, reports, books and for plainhtml. The document type manpage defines its own sectioning commands which are described in section 3.3.

o   part(title): Starts a new part. Only available in book documents.

o   chapter(title): Starts a new chapter. Only available in book or report documents.

o   sect(title): Starts a section.

o   subsect(title): A subsection.

o   subsubsect(title): A sub-subsection.

o   subsubsubsect(title): An even smaller sectioning command.

The macros generate entries in the table of contents and use numbering, which means that each section is prefixed with a number (1, 1.1, 1.2, and so on). The macros are also available with an n prefix (npart, nchapter, nsect etc.) which generate neither entries in the table of contents nor numbers. The n-versions can be used in, e.g., an article where you only want to use the sectioning commands to set captions, but aren't interested in numbering.

The sectioning should start at the top level sections of the available document: chapter for reports, sect for articles, etc.. If you start a document with a lower sectioning command (e.g., when you start an article with a subsect), the numbering of sections may go haywire. The only exception to this rule is the part of a book document: parts are optional, in books, chapters may be the top sectioning commands. Summarized, in a book or report you should start at least with a chapter. In an article you should start with a section.

The sectioning commands have a further function: when label statements appear after the sectioning command, then a label name is used as a placeholder for the last generated number. This is further described in section 3.2.8.

3.2.5: Lists and environments
The macro package supports the following lists and environments:

Itemizing:
    An itemized lists consists of indented items, usually preceded by a bullet.

    There are two ways to indicate an itemized list: one is to start the list with itemize and an open parenthesis and to close it with a closing parenthesis. The other way is to start the list with startit() and to end it with endit().

    The items in the list are indicated with it().

    Example:

    One version of itemized list: itemize(
        it() One item.
        it() Another item. )

    Second version: startit()
        it() One item.
        it() Another item. endit()

Description lists:
    A description list is similar to an itemized list, except that the items in the list have a short description (as in this list). The description list is either inside a description() or is started with startdit() and ended with enddit().

    The items in the list are marked with dit(), this macro expects the short description of the item.

    Example:

    One version of a description list: description(
        dit(First this:) One item.
        dit(Then this:) Another item. )

    Second version: startdit()
        dit(First this:) One item.
        dit(Then this:) Another item. enddit()

Enumerated lists:
    An enumerated list is like an itemized list, except that the items are numbered. The list must be inside a enumerate(), or it must start with starteit() and end with endeit().

    The elements in the list must be indicated with eit().

    Example:

    One version of an enumerated list: enumerate(
        eit() One item.
        eit() Another item. )

    Second version: starteit()
        eit() One item.
        eit() Another item. endeit()

Centered text:
    Centering text may not be available in all output formats. When unavailable, the text is typeset left-flushed.

    Centered text is either either inside center(), or starts with startcenter() and ends with endcenter(). Separate lines in a centered block must be terminated by nl(), otherwise they are merged with subsequent lines.

    Example:

    center(\
        Centered text. nl()
        Another line of centered text.)

    startcenter()
        Centered text. endcenter()

Verbatim text:
    Verbatim text appears on the output exactly in the same layout as it is in the input file. Typesetting text in verbatim mode is useful for, e.g., source files. Depending on the output format, the font of the verbatim text is changed to a teletype font.

    The text must either be inside verb():

    verb(
        This is totally verbatim text.
        It is not further processed by YODL. )

    The text in question is of course not subject to macro expansion by YODL. However, global string substitution as defined by SUBST always occurs, see section 2.3.30.

Quotes:
    Long quotes can be set by the quote macro. It has one argument, the quote to set, as in:

    quote(DOS: n., A small annoying boot virus that causes random spontaneous system crashes, usually just before saving a massive project. Easily cured by UNIX. See also MS-DOS, IBM-DOS, DR-DOS.

    (from David Vicker's .plan))

3.2.6: Fonts and sizes
The macro package supports the following macros to change fonts:

o   bf(text): sets text in boldface.

o   em(text): sets text emphasized, usually in italics.

o   tt(text): sets text in teletype.

The tt() macro furthermore causes YODL not to expand macros which are within the parentheses. That means that you can safely type:

In Yodl, you can use tt(includefile(somefile)) to include a file in your document.

The tt() macro is not suited for long listings; use verb() to set code samples etc..

Currently the macro package has no commands to change font sizes, as the size is changed internally when appropriate (e.g., in section titles). I'll implement such commands when the need arises.

3.2.7: Accents
The macro converters offer two ways of putting characters with accents in the output file. First, Latin-1 characters may appear as they are in the input. E.g., when a YODL input file contains the character ü, then that character will appear on the output in such a way that the final document will show a ü. YODL handles this via the character translation tables (see section 2.4): e.g, a ü might lead to \"{u} in LaTeX output or to &uuml; in HTML output. The YODL macro package supports most vowels with the following accents: ` ' " ^ (e.g., àäâ). Exceptions are the characters that I couldn't generate with my editor (umm ;-), for a full list see e.g., the file html.tables.yo that is distributed with the YODL package. Ergo, if you need such characters, and if your editor can generate them, you can just go ahead and type them in (as in, Meine Frau mag überhaupt kein Bier).

You can also create all these characters and other accent characters using multi-character sequences. This method is implemented because many editors (or tty-lines) cannot handle 8-bits characters. The sequence that defines a character with an accent consists of three characters:

o   one backslash (\), followed by

o   the accent character, one of ' " ` ~ ^ or o, followed by

o   the character in question.

E.g., the sequence \"u leads to ü, and \oA leads to A. The one exception to this rule is the German `scharfes Ess', the ss character. This character is produced by the sequence \ss.

Such multi-character sequences are handled by YODL via the SUBST mechanism (see section 2.3.30). Therefore, such substitutions are `global' in the sense that wherever they occur in the input file, they are recognized and substituted. If you need to set \"u literally, use e.g., the CHAR macro (see section 2.3.3) to `protect' the backspace; as in:

CHAR(\)"u

In the same vein, you could protect any other characters of a multi-character sequence to protect from the substitution mechanism.

The multi-character accents are supported in all output formats but txt (plain ASCII) and in groff output, which send un-accented characters to the output. These ASCII and groff converers map accent characters `back', i.e., \"u appears as u. However, Latin-1 characters when present in the input go to the output unaffected.

3.2.8: Labels, links, references and URLs
References such as see ... for more information are very common in documents. The YODL package supports three mechanisms to accomplish such references:

Labels and references:
    Labels can be defined in a document as a placeholder for the last number that was used in a sectioning command. At other points in the document, references to those labels are used. The reference expands to the number, as in see section 1.3.

    This mechanism is available in all but the most primitive output formats (e.g, the ASCII converter will ignore the requests). Furthermore, the numeric reference (1.3 in the example of the previous paragraph) is in HTML a clickable reference that leads to the mentioned section.

Labels and links:
    This mechanism can be used to set links in a document without using the number of a sectioning command, as in see the introduction for more information, with the introduction being a clickable link to some label.

    This mechanism of course only leads to a clickable link in HTML: in other formats the text see the etc. is just typeset as is.

URLs:
    Universal Resource Locators (URLs) are used to create links to other HTML documents or services, a la the HTML <a href=..> method. The URLs of course only lead to clickable links in HTML output; in other output formats only some descriptive text appears.

The following macros implement the above mechanisms:

o   The macro label(name) defines a label named name. The name of the label can be used in a ref or link macro.

o   The macro ref(name) sets a reference to the label named name. The text of the reference is the number of the last sectioning command that was active during the creation of the label. When using references it is therefore important to define the corresponding labels right after a sectioning command, as in

    section(How to install my program) label(howtoinstall) This section describes... . . See section ref(howtoinstall) for installation instructions.

    The macro ref(howtoinstall) would then expand to the number of the section named How to install my program.

o   The macro link(description)(name) always expands to the description. In HTML output, a clickable link is created pointing to a label called name. For example:

    label(megahard) The YODL package isn't shareware, it isn't beggarware, it isn't freeware, it's bf(megahard-ware). . . Who wants a link(picosoft)(megahard)?

    This code fragment would always set the text picosoft, but under HTML a clickable link would appear pointing to the text.

o   The macro url(description)(location) always expands to the description, but creates a hyperlink pointing to location in HTML. For example,

    If you have W3 access, take a look at my url(homepage) (http://www.icce.rug.nl/we/karel/karel.html).

    The text homepage always appears, but only in HTML it is a link. (Note that the double quotes, which are necessary in HTML around the location, are not needed in YODL.) To use a different font in the description part, surrond it inside the url paramater list, as in:

    The YODL package can be obtained at the site tt(ftp.icce.rug.nl) in the directory url(tt(/pub/unix))
       (ftp://ftp.icce.rug.nl/pub/unix).

o   The macro email(address) is a special case of url: under HTML, the address appears as a clickable link in slanted font to mail address. For example:

    I can be reached as email(karel@icce.rug.nl).

    I can be reached as karel@icce.rug.nl.

Always keep in mind that the name of a label must be exactly identical in both the label macro and in the ref or link macro. Other than that, the name is irrelevant.

Note also the macro package also implements a macro includefile, that includes a file and automatically creates a label. That means that a YODL file like:

chapter(Introduction)
    sect(Welcome)
    includefile(welcome) chapter(Technical information) includefile(techinfo)

implicitly creates two labels, named welcome and techinfo.

Below are some randoms dont's about labels and references:

o   Don't put `weird' characters in label names. Generally, don't use spaces and tabs; though punctuation characters should work.

o   The name of the label is always only an internal symbol; it does not appear in the output. Therefore, constructions such as the following are not correct:

    ref(em(labelname))

    The reason for the incorrectness is, what internal name should em(labelname) generate? Here probably an attempt is made to set a reference in italics. The right construction is of course to set whatever ref() returns in italics, as in:

    em(ref(labelname))

o   The label macro should not appear nested inside another macro. There is no strict reason for this as far as YODL is concerned; however, the processors of YODL's output might go haywire. E.g., beware of the construction

    section(Introduction label(intro))

    The right stanza is of course

    section(Introduction) label(intro)

3.2.9: Figures
Figures in format-independent documents are a problem. You cannot avoid contact with the final format (HTML, LaTeX or whatever) if you want to include figures in a text.

The way YODL approaches figures, is currently the folloowing.

o   Figures can only be included in LaTeX or in HTML documents.

o   For LaTeX, you must prepare a picture in an external file that is included in the document as en encapsulated PostScript file. Incidentally, that means that epsf must be stated as one of the LaTeX styles using latexoptions macro.

    The file in question is stated in YODL without an extension. YODL provides a default extension, being .ps.

o   For HTML, you must prepare a picture in an external file that is placed in the document using the <img src=...> stanza. The file must be a GIF file. The file is -again- stated without the filename extension; YODL supplies .gif.

o   All other output formats do not include pictures in the document, but typeset something like insert figure .. here.

The macro to include a figure is called, appropriately, figure. It takes three arguments:

o   The first argument is the filename. This name may include directories, but may not include the filename extension. The reason for this is, that YODL supplies the correct extension once the output format is known.

o   The second argument is the figure title, or the caption. YODL prefixes this caption with the text Figure xx:, where xx is a number.

o   The last argument is a label, which YODL defines as a placeholder for the figure number.

For example, you might draw a picture or scan a photo and put it in a .gif file, for usage with HTML documents. The conversion to PostScript could be automated, e.g., using a YODL macro:

SYSTEM(giftopnm picture.gif | pnmtops > picture.ps)

See the discussion of the SYSTEM macro (section 2.3.32) for the danger of live data and how YODL handles them.

After this, you would be reasonably safe that the picture is available for both HTML and LaTeX output. The picture would be typeset in a figure using:

figure(picture)
      (A photo of me.)
      (photo)

Note how the first argument, the filename, does not contain an extension. The third argument, which is a label, can be used in, e.g.,

See figure ref(photo) for a photograph.

YODL has a few auxiliary macros, which are:

o   fig(label): This macro is a shorthand for getfigurestring() ref(label). It just makes typing shorter, and is used as e.g.: See fig(photo) for a photograph. Note that the string figure that is generated by this macro can be (re)defined, see below.

o   setfigurestring(name): This macro is similar to setchapterstring etc.. It defines the string that is used to identify a figure, and is (appropriately) figure by default. The macro getfigurestring() expands to the string in question. See also section 3.2.10.1 for a discussion of national language support.

o   sethtmlfigureext(.new): This macro redefines the filename extension for HTML conversions from .gif to .new. Note that you must include a leading dot in the redefinition.

    The new extension is used in the first following figure statement.

o   sethtmlfigurealign(align): This redefines the alignment of figures in HTML, which is default bottom. Check your HTML handbook for possible options; top and center should be fairly standard.

o   setlatexfigureext(.new): Redefines the extension from .ps to .new.

Finally, an example of a picture is shown in figure 1. The picture is also distributed with the YODL package as doc/world.gif.

------------------------------------------------------------------ Insert Figure 1 (Sample picture in a figure.) about here (file: world) ------------------------------------------------------------------

3.2.10: Miscellaneous commands
The following is a list of commands that don't fall in one of the above categories.

o   clearpage(): This macro starts a new page in LaTeX. For HTML, a horizontal rule is shown. (Note that the macro package sometimes inserts new pages by itself; e.g., following a table of contents. See also section 3.2.3 for a discussion of (no)titleclearpage() and (no)tocclearpage().)

o   def(macro)(nrofarguments)(definition): This defines a new macro macro having nrofarguments arguments, and expanding to definition. The markers ARGx, where x is 1, 2, etc., can be used in the definition part to indicate where arguments should be pasted in. This macro is a shorthand for DEFINEMACRO, see section 2.3.8.

o   footnote(text): This macro sets text as a footnote when the output format allows it. When not, the text is set in parentheses.

o   gagmacrowarning(name name ...): This macro suppresses yodl's warnings cannot expand possible user macro name, where name is a candidate macro name. gagmacrowarning is a synonym for NOUSERMACRO, described in section 2.3.23.

    E.g., if your document contains "as for manpages, see sed(1), tr(1) and awk(1)", and if you get tired of warnings about possible user macros sed, tr and awk, try the following:

    gagmacrowarning(sed tr awk) . . As for manpages, see sed(1), tr(1) and awk(1).

o   htmlnewfile(): Starts a new subfile in HTML output. This stanza as also automatically generated when the HTML converter encounters a chapter() directive. Using htmlnewfile(), the output can be split at any point. However make sure that the subfile is still reachable; e.g., by creating a clickable link with label and ref, or label and link.

o   includefile(file): Includes file and defines a label (see the label macro) with the same name. Furthermore, a message about the inclusion is shown on the screen. The file is searched for relative to the directory where the yodl run was started and in the system-wide include directory. The default extension .yo is supplied if necessary.

    This macro is handy in the following situation:

    chapter(Introduction) includefile(intro)

    This fragment starts a chapter and includes a file. The label name intro can also be used to refer to the chapter. The includefile stanza should therefore appear immediately following the corresponding sectioning command.

o   nl(): Forces a new line. Some output formats may produce an error upon the usage of nl() in `unexpected' places; e.g., LaTeX won't allow new lines in the footnote text (as defined in the footnote macro). Using nl() in running text should however be ok.

    Example:

    This line is nl() broken in two.

    This line is
    broken in two.

o   redefinemacro(macro)(nrofargs)(redef): This command (re)defines a macro, expecting nrofargs arguments, to redef. If a previous definition of the macro existed, it is overruled.

    Example:

    redefinemacro(clearpage)(0)(\
        em(---New page starts here---))

    Use ARGx in the redef part to indicate where all arguments should occur, as in the following imaginary macro to typeset a literature reference:

    redefinemacro(litref)(3)(\
        Title: bf(ARG1) nl()\
        Author(s): em(ARG2) nl()\
        Published by: ARG3) . . . litref(Java in a Nutshell)
          (David Flanagan)
          (O'Reilly & Associates, Inc.)

    The redefinemacro statement also has a shorthand called redef.

3.2.10.1: National language support
YODL includes rudimentary national support, in the sense that it allows you to redefine the strings that are used to identify a sections of the level chapter or part, or the strings that are used to identify a figure. E.g., a command chapter(Introduction) will yield for example the text Chapter 1: Introduction.

Using the setchapterstring(text) macro, the Chapter text can be redefined. E.g., in a Dutch text you might put

setchapterstring(Hoofdstuk)

somewhere near the beginning of your document. Similar to setchapterstring, a macro getchapterstring exists that returns the text to identify a chapter. (Internally, getchapterstring is of course used to actually set the text). To redefine the text to identify a part, use setpartstring(text); to redefine the text to identify a figure, use setfigurestring(text).

The set....string macros only affect how YODL names chapters or parts in HTML, man, ms or txt output. LaTeX output is not affected, since LaTeX does its own NLS. Usually, NLS is present for LaTeX as a `style file' named, e.g., dutch.sty. Therefore, if you want a Dutch document, you need to:

o   put dutch in the latexoptions macro in the preamble of the document. This makes sure that LaTeX uses Dutch names.

o   redefine the chapter and part names for non-LaTeX output, as in:

    setpartstring(Deel) setchapterstring(Hoofdstuk) setfigurestring(figuur)

o   Finally, you should probably type your text in Dutch.

YODL may not be totally complete in respect to NLS; e.g., you might see Contents instead of Inhoudsopgave. But I'm working on it.

3.3: The manpage document type
The document type manpage is implemented for the creation of Unix-style manual pages. A manpage document must be organized as follows:

1.  The manual page itself is defined, using the macro

    manpage(short title)
                (section)
                (date)
                (source)
                (manual)

    where the arguments are:

Short title:
    This should be the program name or something similar; i.e., whatever the manpage is describing.

Section:
    A number, stating the manpage section. The Linux man (7) page states in respect to sections, that section 1 is for commands, 2 for system calls, 3 for library calls, 4 for special files (e.g., devices), 5 for file formats, 6 for games, 7 for macro packages and conventions, 8 for system management commands and 9 for other manpages, such as kernel commands.

Date:
    The date of release.

Source:
    The package where the manpage belongs to.

Manual:
    The manual to which the package belongs.

    The arguments to the manpage macro define, e.g., the headers and footers of the manual page. The date, source and manual arguments can be empty.

2.  The subject of the manpage is stated using

    manpagename(name)(short description)

    The name argument should be a short name (e.g., the program name), and the short description should state the function. The descriptive argument is used by, e.g., the whatis database.

3.  The synopsis is started with

    manpagesynopsis()

    after which an abbreviated usage information is presented. This information should show, e.g., the possible program flags and required arguments; but no more.

4.  The description is presented using

    manpagedescription()

    followed by some descriptive text. The descriptive text can e.g. show what the program is supposed to do.

5.  The options may be listed following

    manpageoptions()

    The options are typically a descriptive list of possible flags and their meaning. This section lists the information of the synopsis, but also gives an in-depth description. The manpageoptions() section is optional.

6.  Necessary files are listed following

    manpagefiles()

7.  The `see also' entry is started with

    manpageseealso()

    followed by a list of related manual pages.

8.  The diagnostics are described following

    manpagediagnostics()

    Diagnostics can state, e.g., what error messages are produced by the program and what the cure is.

9.  Next, known bugs can be described following

    manpagebugs()

    This section is optional.

10. Finally the author is stated after

    manpageauthor()

The manpage document type requires you to strictly follow the above order of commands and to state all the necessary sections (and optionally, to state the not required sections but in their right order). Furthermore, sectioning commands that are available in other document types (sect, subsect etc.) are not allowed in a manpage. You can however insert other sections in the manual page with the macro manpagesection. This macro takes one argument: the title of the extra section. It is suggested that you type the section name in upper case, to conform to the `standard'.

As an example, the manual page for the yodl program follows (the actual manual page may differ):

manpage(yodl)
       (1)
       (1996)
       (The Yodl Package)
       (Yet Oneother Document Language) manpagename(yodl)(main YODL convertor) manpagesynopsis()
    bf(yodl) [-DNAME] [-IDIR] [-oFILE] [-PCMD] [-pPASS] [-t] [-v] [-w] [-h]
    [-?] inputfile [inputfile...] manpagedescription()
    This manual page describes the bf(yodl) program, the main converter of the
    YODL package. This program is used by the bf(yodl2....) shell scripts,
    e.g., bf(yodl2tex) or bf(yodl2html). manpageoptions() startdit()
    dit(-DNAME) Defines symbol em(NAME).

    dit(-IDIR) Overrules the standard include directory (default
    em(/usr/local/lib/yodl)) with em(DIR).

    dit(-oFILE) Specifies em(FILE) as the output file (default is stdout).

    dit(-PCMD) `Preloads' command em(CMD), as if em(CMD) was the first line
    of the input.

    dit(-pPASS) Defines em(PASS) as the maximum number of `passes'; when this
    number is exceeded, bf(yodl) aborts.

    dit(-t) Enables tracing mode. Useful for debugging.

    dit(-v) Raises the verbosity mode. Useful for debugging.

    dit(-w) Enables warning. When enabled, bf(yodl) will warn when it sees
    inconsistencies.

    dit(-h, -?) Shows usage information.

    dit(inputfile) File to process, use em(-) to instruct bf(yodl) to read
    from stdin.

enddit() manpagefiles()
    The bf(yodl) program requires no files, but `normal' usage of the YODL
    package requires macro files installed in bf(/usr/local/lib/yodl). The
    files in this directory are included by the converters bf(yodl2txt) etc.. manpageseealso()
    bf(yodl2tex), bf(yodl2html), bf(yodl2man), etc.. manpagediagnostics()
    Warnings and errors of bf(yodl) are too many to enumerate, but all errors
    are printed to em(stderr) after which bf(yodl) exits with a non-zero
    status. manpagebugs()
    There may be bugs in the bf(yodl) program, but that's not very likely.
    More likely you'll encounter bugs or omissions in the macro package
    itself. manpageauthor()
    Karel Kubat (karel@icce.rug.nl)

3.4: Alphabetical list of the macros

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

o   abstract(text):
    Defines an abstract for an article or report document. Abstracts are not implemented for books or manpages. Must appear before starting the document with the article or report macro.

o   affiliation(site):
    Defines an affiliation, to appear in the document titlepage below the author field. Must appear before starting the document with article, report or book. The affiliation is only printed when the author field is not empty.

o   article(title)(author)(date):
    Starts an article. The top-level sectioning command is (n)sect. In HTML conversions only one output file is written.

o   bf(text):
    Sets text in boldface.

o   book(title)(author)(date):
    Starts a book document. The top-level sectioning command is (n)chapter, (n)part being optional. In HTML output files are created for each chapter.

o   center(text):
    Sets text centered, when the output format permits. Use nl() in the text to break lines.

o   chapter(title):
    Starts a new chapter in books or reports.

o   lchapter(label)(title):
    Starts a new chapter in books or reports, setting a label at the beginning of the chapter.

o   clearpage():
    Starts a new page, when the output format permits. Under HTML a horizontal line is drawn.

o   def(macroname)(nrofargs)(redefinition):
    Defines macroname as a macro, having nrofargs arguments, and expanding to redefinition. This macro is a shorthand for DEFINEMACRO. An error occurs when the macro is already defined. Use redef() to unconditionally define or redefine a macro.

o   description(list):
    Sets list as a description list. Use dit(item) to indicate items in the list.

o   dit(itemname):
    Starts an item named itemname in a descriptive list. The list is either enclosed by startdit() and enddit(), or is an argument to description().

o   eit():
    Indicates an item in an enumerated list. The list is either enclosed by starteit() and endeit(), or is an argument to enumerate().

o   em(text):
    Sets text as emphasized, usually italics.

o   email(address):
    In HTML, this macro sets the address in a <a href="mailto=.."> locator. In other output formats, the address is sent to the output. The email macro is a special case of url.

o   endcenter():
    Ends centered text that is started with startcenter().

o   enddit():
    Ends a descriptive list that is started with startdit().

o   endeit():
    Ends an enumerated list that is started with starteit().

o   endit():
    Ends an itemized list that is started with startit().

o   enumerate(list):
    Sets list as an enumerated list. Use eit() to indicate items in the list.

o   fig(label):
    This macro is a shorthand for figure ref(label) and just makes the typing shorter, as in see fig(schematic) for .. See getfigurestring() and setfigurestring() for the figure text.

o   figure(file)(caption)(label):
    Sets the picture in file as a figure in the current document, using the descriptive text caption. The label is defined as a placeholder for the figure number and can be used in a corresponding ref statement. Note that the file must be the filename without extension: YODL will supply .gif when in HTML mode, or .ps when in LaTeX mode. Figures in other modes are not (yet) implemented.

o   footnote(text):
    Sets text as a footnote, or in parentheses when the output format does not allow footnotes.

o   gagmacrowarning(name name ...):
    Prevents the yodl program from printing cannot expand possible user macro. E.g., if you have in your document the file(s) are .. then you might want to put before that: gagmacrowarning(file). Synonym for NOUSERMACRO.

o   getchapterstring():
    Expands to the string that defines a `chapter' entry, by default Chapter. Can be redefined for national language support by setchapterstring().

o   getfigurestring():
    Returns the string that defines a `figure' text, in captions or in the fig() macro. The string can be redefined using the setfiguretext() macro.

o   getpartstring():
    Expands to the string that defines a `part' entry, by default Part. Can be redefined for national language support by setpartstring().

o   htmlbodyopt(option)(value):
    Adds option="value" to the options of the <body ...> tag in HTML files. Useful options are, e.g., fgcolor and bgcolor, whose values are expressed as #rrggbb, where rr are two hexadecimal digits of the red component, gg two hexadecimal digits of the green component, and bb two hexadecimal digits of the blue component.

o   htmlcommand(cmd):
    Sets cmd when converting to HTML. The cmd is not further parsed by YODL.

o   htmlnewfile():
    In HTML output, starts a new file. All other formats are not affected. Note that you must take your own provisions to access the new file; say via links. Also, it's safe to start a new file just befoore opening a new section, since sections are accessible from the clickable table of contents. The HTML converter normally only starts new files prior to a chapter definition.

o   htmltag(tagname)(start):
    Sets tagname as a HTML tag, enclosed by < and >. When start is zero, the tagname is prefixed with /.

o   includefile(file):
    Includes file and defines a label with the same name. The default extension .yo is supplied if necessary.

o   it():
    Indicates an item in an itemized list. The list is either surrounded by startit() and endit(), or it is an argument to itemize().

o   itemize(list):
    Sets list as an itemized list. Use it() to indicate items in the list.

o   label(labelname):
    Defines labelname as an anchor for a link command, or to stand for the last numbering of a section or figure in a ref command.

o   latexcommand(cmd):
    Writes cmd to the output when converting to LaTeX. The cmd is not further expanded by YODL.

o   latexdocumentstyle(style):
    Forces the LaTeX \documentstyle{...} setting to style. Normally the style is defined by the macros article, report or book. This macro is an escape route incase you need to specify your own document style for LaTeX. This option is a modifier and must appear before the article, report or book macros.

o   latexoptions(options):
    Sets the LaTeX processing options, a useful option is, e.g., dina4,epsf. This command must appear before the document type is stated by article, report, etc..

o   latexlayoutcmds(latexcommands):
    This macro is provided incase you want to put your own LaTeX layout commands into LaTeX output. The latexcommands are pasted right after the \documentstyle stanza. The default is, of course, no local LaTeX commands. Note that this macro does not overrule my favorite LaTeX layout. Use nosloppyhfuzz() and standardlayout() to disable my favorite LaTeX layout.

o   link(description)(labelname):
    In HTML output a clickable link with the text description is created that points to the place where labelname is defined using the label macro. Using link is similar to url, except that a hyperlink is set pointing to a location in the same document. For output formats other than HTML, only the description appears.

o   mailto(address):
    Defines the default mailto address for HTML output. Must appear before the document type is stated by article, report, etc..

o   mancommand(cmd):
    Writes cmd to the output when converting to man. The cmd is not further expanded by YODL.

o   manpage(title)(section)(date)(source)(manual):
    Starts a manual page document. The section argument must be a number, stating to which section the manpage belongs to. Most often used are commands (1), file formats (5) and macro packages (7). The sectioning commands in a manpage are not (n)sect etc., but manpage...(). The first section must be the manpagename, the last section must be the manpageauthor. The standard manpage for section 1 contains the following sections (in the given order): manpagename, manpagesynopsis, manpagedescription, manpageoptions, manpagefiles, manpageseealso, manpagediagnostics, manpagebugs, manpageauthor. Optional extra sections can be added with manpagesection. Standard manpageframes for several manpagesections are provided in /usr/local/share/yodl/manframes.

    )

o   manpageauthor():
    Starts the AUTHOR entry in a manpage document. Must be the last section of a manpage.

o   manpagebugs():
    Starts the BUGS entry in a manpage document.

o   manpagedescription():
    Starts the DESCRIPTION entry in a manpage document.

o   manpagediagnostics():
    Starts the DIAGNOSTICS entry in a manpage document.

o   manpagefiles():
    Starts the FILES entry in a manpage document.

o   manpagename(name)(short description):
    Starts the NAME entry in a manpage document. The short description is used by, e.g., the whatis database.

o   manpageoptions():
    Starts the OPTIONS entry in a manpage document.

o   manpagesection(SECTIONNAME):
    Inserts a non-required section named SECTIONNAME in a manpage document. This macro can be used to augment `standard' manual pages with extra sections, e.g., EXAMPLES. Note that the name of the extra section should appear in upper case, which is consistent with the normal typesetting of manual pages.

o   manpageseealso():
    Starts the SEE ALSO entry in a manpage document.

o   manpagesynopsis():
    Starts the SYNOPSIS entry in a manpage document.

o   mscommand(cmd):
    Writes cmd to the output when converting to ms. The cmd is not further expanded by YODL.

o   nchapter(title):
    Starts a chapter (in a book or report) without generating a number before the title and without placing an entry for the chapter in the table of contents.

o   nl():
    Forces a newline; i.e., breaks the current line in two.

o   nosloppyhfuzz():
    By default, LaTeX output contains commands that cause it to shut up about hboxes that are less than 4pt overfull. When nosloppyhfuzz() appears before stating the document type, LaTeX complaints are `vanilla'.

o   notableofcontents():
    Prevents the generation of a table of contents. This is default in, e.g., manpage and plainhtml documents. When present, this option must appear before stating the document type with article, report etc..

o   notitleclearpage():
    Prevents the generation of a clearpage() instruction after the typesetting of title information. This instruction is default in all non article documents. When present, must appear before stating the document type with article, book or report.

o   notocclearpage():
    Prevents the generation of a clearpage() instruction after the typesetting of a table of contents. This instruction is default in all documents. When present, must appear before stating the document type with article, book or report.

o   noxlatin():
    When used in the preamble, the LaTeX converter disables the inclusion of the file xlatin1.tex. Normally this file gets included in the LateX output files to ensure the conversion of high ASCII characters (like é) to LaTeX-understandable codes. (The file xlatin1.tex comes with the YODL distribution.)

o   npart(title):
    Starts a part in a book document, but without numbering it and without entering the title of the part in the table of contents.

o   nsect(title):
    Starts a section, but does not generate a number before the title nor an entry in the table of contents. Further sectioning commands are nsubsect, nsubsubsect and nsubsubsubsect.

o   nsubsect(title):
    Starts a non-numbered subsection.

o   nsubsubsect(title):
    Starts a non-numbered sub-subsection.

o   nsubsubsubsect(title):
    Starts a non-numbered sub-sub-subsection.

o   part(title):
    Starts a new part in a book document.

o   plainhtml(title):
    Starts a document for only a plain HTML conversion. Not available in other output formats. Similar to article, except that an author- and date field are not needed.

o   quote(text):
    Sets the text as a quotation. Usually, the text is indented, depending on the output format.

o   redef(macro)(nrofarguments)(redefinition):
    Defines macro macro to expand to redefinition. Similar to def, but any pre-existing definition is overruled. This command is a shorthand for redefinemacro.

o   redefinemacro(nrofargs)(redefinition):
    Defines macro macro to expand to redefinition. Similar to def, but any pre-existing definition is overruled. Use ARGx in the redefinition part to indicate where the arguments should be pasted. E.g., ARG1 places the first argument, ARG2 the second argument, etc..

o   ref(labelname):
    Sets the reference for labelname. Use label to define a label.

o   report(title)(author)(date):
    Starts a report type document. The top-level sectioning command in a report is chapter.

o   roffcmd(dotcmd)(sameline)(secondline)(thirdline):
    Sets a t/nroff command that starts with a dot, on its own line. The arguments are: dotcmd - the command itself, e.g., .IP; sameline - when not empty, set following the dotcmd on the same line; secondline - when not empty, set on the next line; thirdline - when not empty, set on the third line. Note that dotcmd and thirdline are not further expanded by YODL, the other arguments are.

o   sect(title):
    Starts a new section.

o   lsect(label)(title):
    Starts a new section, setting a label at the beginning of the section.

o   setchapterstring(name):
    Defines name as the `chapter' string, by default Chapter. E.g., after setchapterstring(Hoofdstuk), YODL gains some measure of national language support for Dutch. Note that LaTeX support has its own NLS, this macro doesn't affect the way LaTeX output looks.

o   setfigurestring(name):
    Defines the name as the `figure' text, used e.g. in figure captions. E.g., after setfigurestring(Figuur), YODL uses Dutch names for figures.

o   sethtmlfigureext(ext):
    Defines the filename extension for HTML figures, defaults to .gif. Note that a leading dot must be included in ext. The new extension takes effect starting with the following usage of the figure macro.

o   sethtmlfigurealign(alignment):
    Redefines the alignment for figures in HTML. The default is bottom. Other options depend on the client browser, but top and center should be universal.

o   setlatexfigureext(ext):
    Defines the filename extension for encapsulated PostScript figures in LaTeX, defaults to .ps. The dot must be included in t new extension ext. The new extension takes effect starting with a following usage of the figure macro.

o   setpartstring(name):
    Defines name as the `part' string, by default Part. E.g., after setpartstring(Teil), YODL identifies parts in the German way. Note that LaTeX output does its own national language support; this macro doesn't affect the way LaTeX output looks.

o   sgmlcommand(cmd):
    Writes cmd to the output when converting to SGML. The cmd is not further expanded by YODL.

o   sgmltag(tag)(onoff):
    Similar to htmltag, but used in the SGML converter.

o   standardlayout():
    Enables the default LaTeX layout. When this macro is absent, then the first lines of paragraphs are not indented and the space between paragraphs is somewhat larger. The standardlayout() directive must appear before stating the document type as article, report, etc..

o   startcenter():
    Starts centered text. Use endcenter() to stop centering text.

o   startdit():
    Starts a descriptive list. Use dit(item) to set items in the list, and use enddit() to end the list.

o   starteit():
    Starts an enumerated list. Use eit() in the list to indicate items, and use endeit() to end the list.

o   startit():
    Starts an itemized list. Use it() in the list to indicate items, and use endit() to end the list.

o   subsect(title):
    Starts a new subsection. Other sectioning commands are subsubsect and subsubsubsect.

o   lsubsect(label)(title):
    Starts a new subsection. Other sectioning commands are subsubsect and subsubsubsect. A label is added just before the subsection.

o   subsubsect(title):
    Starts a sub-subsection.

o   lsubsubsect(label)(title):
    Starts a sub-subsection, a label is added just before the section

o   subsubsubsect(title):
    Starts a sub-sub-sub-subsection. This level of sectioning is not numbered, in contrast to `higher' sectionings.

o   lsubsubsubsect(label)(title):
    Starts a sub-sub-sub-subsection. This level of sectioning is not numbered, in contrast to `higher' sectionings. A label is added just before the subsubsubection.

o   titleclearpage():
    Forces the generation of a clearpage() directive following the title of a document. This is already the default in books and reports, but can be overruled with notitleclearpage(). When present, must appear in the preamble; i.e., before the document type is stated with article, book or report.

o   tocclearpage():
    Forces the generation of a clearpage() directive following the table of contents in a document. This is already the default in all document types, but can be overruled with notocclearpage(). When present, must appear in the preamble; i.e., before the document type is stated with article, book or report.

o   tt(text):
    Sets text in teletype font, and prevents it from being expanded. For unbalanced parameter lists, use CHAR(40) to get ( and CHAR(41) to get ).

o   txtcommand(cmd):
    Writes cmd to the output when converting to ASCII. The cmd is not further expanded by YODL.

o   url(description)(locator):
    In LaTeX documents the description is sent to the output. For HTML, a link is created with the descriptive text description and pointing to locator. The locator should be the full URL, including service; e.g, http://www.icce.rug.nl, but excluding the double quotes that are necessary in plain HTML. Use the macro link to create links within the same document. For other formats, something like description [locator] will appear.

o   verb(text):
    Sets text in verbatim mode: not subject to macro expansion or character table expansion. The text appears literally on the output, usually in a teletype font (that depends on the output format). This macro is for larger chunks, e.g., listings. For unbalanced parameter lists, use CHAR(40) to get ( and CHAR(41) to get ).

o   verbinclude(filename):
    Reads filename and inserts it literally in the text, set in verbatim mode. not subject to macro expansion.The text appears literally on the output, usually in a teletype font (that depends on the output format). This macro is an alternative to verb(...), when the text to set in verbatim mode is better kept in a separate file.

o   whenhtml(text):
    Sends text to the output when in HTML conversion mode. The text is further expanded if necessary.

o   whenlatex(text):
    Sends text to the output when in LaTeX conversion mode. The text is further expanded if necessary.

o   whenman(text):
    Sends text to the output when in man conversion mode. The text is further expanded if necessary.

o   whenms(text):
    Sends text to the output when in ms conversion mode. The text is further expanded if necessary.

o   whensgml(text):
    Sends text to the output when in SGML conversion mode. The text is further expanded if necessary.

o   whentxt(text):
    Sends text to the output when in ASCII conversion mode. The text is further expanded if necessary.

o   starttable(nColumns)(LaTexAllignment):
    The arguments are the number of columns in the table, and the alignment specifications for LaTeX, which should consist of nColumns characters (l, r, or c). It is used internally by table()

o   endtable():
    This macro ends the definition of a table. It is used internally by table()

o   table(nColumns)(LaTeXallignment)(Contents):
    The table()-macro defines a table. Its first argument specifies the number of columns in the table. Its second argument specifies the LaTeX-alignment specifications: use l for left-alignment, r for right alignment, c for centered-alignment. The third argument defines the contents of the table which are the rows, each containing column-specifications.

o   row(Cells):
    The argument Cells contains the cells of one row of the table

o   cell(element):
    Set a table cell, i.e., one element in a row.

o   cells(nColumns)(element):
    Set a table cell centered over nColumns columns. See also leftcells() and rightcells().

o   columnline(from)(to):
    Sets a horizontal line over a column in a row. See also rowline().

o   rowline():
    Sets a horizontal line over the width of the table. See also cellsline().

3.5: General structure of a YODL document
This section describes the general format of a YODL document.

First of all, a document in the YODL language needs a preamble. This part of the document must be at the top, and must define the modifiers and the document type The modifiers, when present, must appear first.

The modifiers may be, e.g., latexoptions, mailto, affiliation, etc.. A very useful modifier is abstract. All modifiers are listed in section 3.2.3. In general, you should use as many modifiers as appropriate; e.g., you should define a mailto even when you're not planning to convert your document to HTML. The reason is twofold: first, you might later decide that a HTML version isn't a bad idea after all. Second, later versions of the converters might use mailto even for non-HTML output formats.

Following the modifiers, you need to define the document type. This type is either article, report, book, plainhtml or manpage. Except for the manpage document type, which is described in section 3.3, the following rules apply:

You should decide on the document type by counting the top-level sectioning commands that you need. E.g., if you write an article with 20 sections, it might be a good idea to switch to a report and group some of the sections into chapters. Similarly, a report with 30 chapters might be better off as a book with parts. As a rule of thumb, a document should have no more than 10 top-level sectionings, and each top-level sectioning should have no more than 10 subsectionings, etc..

The document type also affects the way YODL formats the output. An article (or plainhtml) leads to one output file; which means under HTML one final document. If your article is way too long, then the loading of the HTML document will be long too. In HTML output, YODL splits reports and books into files that hold the separate chapters. These can then be reached via the table of contents. Ergo, the document length can also be relevant when you contemplate switching to a report or book.

If your document uses special macros, then these must be defined before they are used. I myself usually define such macros following the preamble. E.g., see the file doc/yodl.yo that is distributed with the YODL package. This is the main file of this manual and follows the syntax described herein.

To answer yes-but-what-if oriented minds, here are two results of the wrong order of text, preamble and modifiers:

o   If you put text before the preamble, i.e., before stating the document type, chances are that YODL will happily translate the file, but that the following stages will fail. E.g., the <html> tag would come too late in a HTML conversion, causing the HTML viewer to become confused. Or, the \documentstyle definition would be seen too late by the LaTeX typesetter.

o   If you put modifiers, such as latexoptions, after the document type, then the modifiers will have no effect; though YODL won't complain either. The reason for this is the definition of such modifiers will be seen following the stage where they are needed..

3.6: Pecularities of conversions
Each macro package that handles a conversion from YODL to a given output format has its pecularities. I tried to make the different conversion packages as uniform as possible, but given the characteristics of output formats, differences still exist.

I tried to limit these pecularities to a minimum for obvious reasons. Normal usage of the YODL language and of its converters should have no problems with these pecularities, but they are listed in this section for completeness.

3.6.1: Notes on the LaTeX converter
The LaTeX converter is, in YODL's viewpoint, the easiest one: since LaTeX has a wide functionality, a YODL document is basically just re-mapped to LaTeX commands.

3.6.1.1: Direct commands to LaTeX
To send LaTeX commands directly to the output, use the latexcommand macro (see section 3.2.1), or use NOTRANS (see section 2.3.22). The advantage of the latexcommand macro is that it only outputs its argument when in LaTeX mode.

The following two code fragments both output \pagestyle{plain} when in LaTeX mode:

COMMENT(-- First alternative: --) latexcommand(\pagestyle{plain}) COMMENT(-- Second alternative: --) IFDEF(latex)\
    (NOTRANS(\pagestyle{plain}))\
    ()

3.6.1.2: Verbatim text
The YODL macro packages offer two ways of putting verbatim text (e.g., source code listings) in the output. These ways are also described in the following sections.

The verb macro
The first way is the verb macro and is meant for longer listings (whole files); as in:

verb(\ #include <stdio.h> int main (int argc, char **argv) {
    printf ("Hello World!\n");
    return (0); })

The verb command in LaTeX leads to \begin{verbatim} and \end{verbatim}. That means that the verb macro has only one caveat: you cannot put \end{verbatim} in it.

The tt macro
The second way to put verbatim text in LaTeX is the tt macro, used for short in-line strings (e.g, **argv). The LaTeX converter doesn't actually use a verbatim mode, but sets the characters in teletype font. I just hope that the character conversion tables are complete..

3.6.2: Notes on the HTML converter
The HTML converter is, from YODL's point of view, somewhat harder. HTML doesn't support automatic section numbering or resolving of label/reference pairs. The converter must take care of this.

3.6.2.1: Direct commands to HTML
Similar to the LaTeX converter, you can use either NOTRANS or htmlcommand to send HTML commands to the output. Or, since the only `difficult' characters are probably only < and >, you can also resort to CHAR for these two characters.

Furthermore, the HTML converter defines the macro htmltag, expecting two arguments: the tag to set, and an `on/off' switch. E.g., htmltag(b)(1) sets <b> while htmltag(b)(0) sets </b>.

E.g., the following code sends a HTML command <hr> to the output file when in HTML mode:

COMMENT(-- alternative 1, using htmlcommand --) htmlcommand(<hr>) COMMENT(-- alternative 2, using NOTRANS --) IFDEF(html)\
    (NOTRANS(<hr>))\
    () COMMENT(-- alternative 3, using CHAR --) IFDEF(html)\
    (CHAR(<)hrCHAR(>))\
    ()

COMMENT(-- alternative 4, using htmltag --) htmltag(hr)(1)

3.6.2.2: Numbering of sections
The HTML converter numbers its own sections. This is handled internally. However, the current converter only can number sections as starting at 1, and outputs the numbers in arabic numerals (you can't number with A, B, etc..).

3.6.2.3: The htmlbodyopt macro
The macro htmlbodyopt(option)(value), which is described earlier, can be repeated up to six times: the HTML converter currently supports up to 6 option/value settings. When the need arises, I'll implement more.

3.6.2.4: The yodl2html-post postprocessor
The HTML converter necessarily uses a post-processor, which re-parses the output of the yodl program. The post-processor is necessary for a variety of reasons: the HTML output is split into several files, a table of contents is created, labels and references to labels are resolved.

The post-processor is a program yodl2html-post and is automatically activated when the shellscript yodl2html is used. I therefore strongly urge you to convert YODL documents to HTML using this script.

The usage of the post-processor has one important drawback. The yodl program sec places tags for the post-processor in its output. The post-processor takes actions according to the tags.

The tags start with .yodltagstart. and end with .yodltagend. (though in upper case, guess why I typed them here in lowercase?). Therefore, you cannot put these strings in a YODL document that should be converted to HTML. The tags would however be harmless in other output formats. (If this setup that uses tags proves to be a problem, I'll implement a way around it. Besides, the tags can be configured in the top-level Makefile when installiong the YODL package.)

3.6.3: Notes on the groff converter
The two converters that write groff output are the man and ms converters.

In respect to the output, the following applies. You can start lines with a single dot, since all dots are converted by the active character conversion table to \&.. However that also means that you cannot easily paste groff commands into an output file. If you want to send commands, use the macro roffcmd().

3.6.3.1: The groff postprocessors
The post-processors for groff output are quite complex. Similar to the HTML postprocessor, labels and references need to be fixed and a table of contents must be created. Furthermore, groff and its macros require an unusually strict and unreadable input (well, in my opinion they do). The complexity of the groff conversions lies therefore in the post-processor.

The labels and references are resolved via a post-processor which is similar to the HTML postprocessor: the .yodltagstart. and .yodltagend. strings, though in uppercase, are reserved. The converters also introduce an extra internal label for usage in the table of contents generation: .yoldtoccommand..

An in-depth description of the post-processor would be beyond this document. The post-processor is a C program yodlfixlabels.

3.6.4: Notes on the SGML converter
I implemented the definition of the SGML converter for reasons of backward compatibility at our site (the ICCE). The SGML converter is by no means complete, or indeed usable unless you're using the SGML system at the ICCE. It outputs an SGML file which is suitable for our SGML implementation, which is a hacked Linuxdoc-SGML mutant.

For these reasons, the SGML converter only supports the article document type. Therefore, the top-level sectioning command can only be sect.

The SGML converter adds two macros to the set: sgmltag(tag)(onoff) and sgmlcommand(cmd), which work similarly to the htmltag and htmlcommand macros.

3.6.5: Notes on the ASCII converter
As stated before, the ASCII converter basically only strips macronames in its input. This converter is so rudimentary, that the groff converters are a better path to generate plain ASCII output. As it is, the ASCII converter is now only usable as a last resort, when neither LaTeX, nor a HTML browser, nor groff is available.

The layout of the input file is very important in the ASCII converter, since the output is basically the same as the input. The only exception to this rule are multiple empty lines, which are eaten up by a post-processor yodl2txt-post and replaced by one empty line each.

For example, you should format your sections in the following way to make sure that the titles start at the leftmost column:

chapter(Some chapter) Text of the chapter. Text of the chapter. Text of the chapter. Text of the chapter. Text of the chapter. Text of the chapter. sect(A section within the chapter) Text of the section. Text of the section. Text of the section. Text of the section. Text of the section. sect(A second section) More text.

This ensures that the chapter and section titles appear `left-flushed'. Optionally you might want to try the following layout:

chapter(Some chapter)
    Text of the chapter. Text of the
    chapter. Text of the chapter. Text
    of the chapter. Text of the
    chapter. Text of the chapter.
    sect(A section within the chapter)
        Text of the section. Text of
    the section. Text of the section.
    sect(A second section)

        More text.

Similarly, you should choose a `good-looking' way to format your lists, as in:

Text before an itemized list. itemize(
    it() Some item. Some item. Some
    item. Some item. Some item.
    it() Another item. Another item.
    Another item. Another item. Another
    item.

) Text following the list.

This makes sure that (a) the itemized list is `indented' relative to the other text, and (b) that the lines within one item of the list are indented to the same level.

Don't blame YODL as a package for the ugliness of the ASCII converter. Rather, blame me: I wrote the ASCII converter when I was too lazy to dig into the groff format. Now that there's a man and a ms output format, you're probably better off using that.

Chapter 4: Technical information

The following information describes the YODL package from the point of the system administrator. Issues such as the installation of the package are addressed here.

4.1: Obtaining and installing YODL
The YODL program and the distributed macro package can be obtained at the ftp site ftp.icce.rug.nl in the directory /pub/unix. Look for the file yodl-1.22.tar.gz, which is a gzipped archive containing all sources, documentation and macro files. The version string (1.22 in this example) may have been upgraded by the time you read this; so always get the archive with the highest version number.

If you have an older yodl source tree, remove it first. Then uncompress and untar it in a `sources' directory, e.g., in /usr/local/src. This creates a subdirectory yodl-X.YY/ under which all necessary files are located.

Please note: YODL has evolved from a previous program dom, which is no longer supported or maintained. If you have a version of the predecessor program dom, then issue the following commands:

rm /usr/local/bin/dom /usr/local/bin/dom2* rm /var/man/cat3/yodl.3.gz rm -r /usr/local/lib/dom

Also note: Pre-1.03 versions of YOLD had a command yodl2less, which is now obsolete. This command has been replaced with yodl2manless and yodl2msless. If you have a pre-1.03 installation, run the command

rm /usr/local/bin/yodl2less

4.1.1: Configuring the yodl program
Once you unpack the archive, edit the Makefile in the yodl-X.YY/ subdirectory. At the top you will find a number of macros that may need adaptation (e.g., BINDIR is where make install puts the program). You can also set compiler options in this file.

Next, edit the file config.h. A number of relevant macros for the inner workings of yodl can be defined here. If you're unsure about the macros, leave them to their defaults.

4.1.2: Installing the yodl program
Once configured, type make install to build and install the program. The executable, which is built as src/yodl is created and copied to a system-wide program directory. The macro package from lib/yodl and divers post-processors are also placed in a public directory, which is /usr/local/lib/yodl by default (you can change this directory name in the Makefile too). Furthermore, a number of shell scripts (drivers of the yodl program) are copied to your programs directory.

The make install command only installs necessary executables and macrofiles. Use make installman to create and install manpages which go under /usr/man/man*, or use make installcat to create and install formatted manpages which go under /var/man/cat*. Available manual pages include descriptions of the executables, an abbreviated list of macros, and a description of the manpage document type. Optionally, you can install the whole YODL manual under /usr/man/man5/yodl.5 with make installmanual, or you can install the manual in preformatted form under /usr/man/cat5/yodl.5.gz using make installcatual. Note that all make commands that install documentation, also implicitely make install. This is not a bug! A working YODL set is required to create and install the documentation.

If you want yodl to create full documentation about itself, type make latexdoc (for LaTeX-style documentation) or make htmldoc (for HTML-style documentation). The documentation is written to doc/yodl.tex or doc/yodl.html respectively. You can also make flat ASCII documentation via the ms converter with

cd doc yodl2msless yodl > /tmp/yodl.txt

(Note that yodl.html already comes with the distribution, just start your favorite HTML browser on doc/yodl.html. Similarly, ASCII docs are provided in gzipped format as doc/yodl.txt.gz.)

If you can neither process LaTeX nor HTML nor ms documentation, try make txtdoc to produce a flat ASCII file yodl/yodl.txt (but then, if you can only view plain ASCII, why get YODL in the first place?).

4.1.2.1: Prerequisites for the installation
To successfully build and install the YODL package, the following tools must be present.

o   First, you'll of course need a C compiler and run-time environment. A POSIX-compliant compiler, libraries and set of header files should work without problems. The gcc compiler 2.6 and above should work without a flaw.

o   Second, the Makefiles in the YODL source tree use typical building programs, such as, install. Most Unixes will have these.

o   Third, the installation and also scripts in the YODL package require a POSIX-compliant shell interpreter /bin/sh. The GNU shell interpreter bash works without problems. You can define the path to your bash shell in the top-level Makefile. I've been told that ksh works just as well.

o   Fourth, a number of `standard' tools should be present: awk, sed, grep, etc.. These tools must furthermore include the code generators bison and flex (yacc- and lex lookalikes) to genererate the grammar parsers. The GNU implementations of these tools work like a charm.

o   Finally, you'll need a command that converts groff input into viewable format. The default setting for this command in the top level Makefile is groff -Tascii -man and groff -Tascii -gms.

If you have problems building YODL on your particular system, please mail me the problem description (and, if you have it, the solution) -- I will adapt YODL for a wider variety of Unix blands.

4.2: Internal workings of the YODL package
This section describes the internal workings of the yodl package, for those who are interested (and of course, for the maintainer).

4.2.1: A single-pass interpreter
The yodl program is a single-pass interpreter of its input files. The program does not build an internal data representation of the text and commands that it encounters; therefore, all actions must be completed in one pass. The basic way by which yodl does this, is by reading input, taking actions and possibly `pushing back' information on the input.

This is best illustrated with an example. Given the code,

DEFINESYMBOL(sym) IFDEF(sym)
    (Symbol sym is defined!
     DEFINEMACRO(testmac)(0)(Testmac now stands for one thing.)
    )
    (Symbol sym is not defined!
     DEFINEMACRO(testmac)(0)(Testmac now stands for another thing.)
    )

testmac()

yodl will take the following actions:

o   The DEFINESYMBOL command updates an internal table of symbols, no other action is necessary here.

o   When the IFDEF command is parsed, yodl eats up all of the necessary parts from the input: the keyword itself, and three parameter lists. The IFDEF test obviously yields `true', and therefore yodl `pushes back' the true-list

    Symbol sym is defined! DEFINEMACRO(testmac)(0)(Testmac now stands for one thing.)

o   Next, yodl sees normal text (Symbol sym is etc.). This is sent to the output file.

o   After this, the DEFINEMACRO statement is seen, which defines testmac() as a placeholder for one thing.

o   Finally, testmac() is seen. The parser recognizes a user-defined macro having no arguments, which conforms to the definition. The text

    Testmac now stands for one thing.

    is pushed back.

o   Finally, yodl reads this last string from its input and sends it to the output.

The most complex part of the program is therefore the tokenizer (lexical analyzer): that part is responsible for matching tokens such as identifiers in the input, and for pushing back text. The pushing back is implemented as a relocatable buffer, which is expanded as text is pushed into it and which shrinks as the lexical analyzer processes input. I already achieved about 100% speed gain by optimizing the tokenizer, but this implementation can still be somewhat of a CPU hog. (But hey, premature optimzation is the root of all evil, says D.E. Knuth. So why optimize, as long as you don't know whether you're being premature about it?)

The lexical analyzer is furthermore responsible for the line continuation feature (see section 2.2.2) and for the SUBST mechanism (see section 2.3.30). These mechanisms are also implemented with the push-back method.

4.2.2: Macros of the converters
The macro files for all converters are (by default) installed to a directory /usr/local/lib/yodl. This is a good place to look if you want to see how a converter works, or if you want to write a new converter.

The place to start looking is the file shared.yo, which is used by all converters. This file defines most commands that are `global' in the sense that all converters implement them: e.g., bf, em and so on. The implementation is per macro as follows, illustrated for e.g., bf (the actual implementation may be slightly different):

DEFINEMACRO(bf)(1)(\
        whenlatex(latexcommand({\bf )ARG1+latexcommand(}))\
        whenhtml(htmlcommand(<strong>)ARG1+htmlcommand(</strong>))\
        whenman(mancommand(\fB)ARG1+mancommand(\fP))\
        whensgml(sgmlcommand(<bf>)ARG1+sgmlcommand(</bf>))\
        whentxt(ARG1))

The macro expands to a set of commands that are active per output format, using latexcommand, htmlcommand etc..

The file shared.yo is included in its turn by tex.yo, html.yo and so on. These separate files are very short; their function is to:

o   define the conversion type with an appropriate symbol (latex for latex conversions, html for HTML, and so on),

o   activate character tables (when necessary),

o   include shared.dm,

o   define special macros for the particular conversion (when necessary).

4.2.2.1: Adding a new macro
This section describes how to add a new user-defined macro. For the sake of simplicity, a macro fname(name) is defined to typeset a filename. The macro maps to em() in LaTeX output or to bf() in other formats.

o   The place to insert the macro is lib/yodl/shared.yo.in in the Yodl source tree. This is the `master file' from which both the final macrofile and relevant documentation is created.

o   The macro must appear in alphabetical order in the list of all other macros, this is relevant for the documentation. Hence, the fname macro would appear somewhere near footnote() though before it.

o   The documentation about the hypothetical macro must be set between two tags @startdoc and @enddoc. The make process looks for these tags. The documentation itself must appear as a macro which is (appropriately) called macro, and expects two arguments: the new macro that is being defined, and its description:

    @startdoc macro(fname(file)) (Sets a filename in either boldface or italics, depending on the output format.) @enddoc

o   Following the documentation, the macro itself is defined using whenformat() commands and/or formatcommand():

        DEFINEMACRO(fname)(1)(\
            whenlatex(em(ARG1))\
            whenhtml(bf(ARG1))\
            whenman(bf(ARG1))\
            whenms(bf(ARG1))\
            whentxt(bf(ARG1))\
            whensgml(bf(ARG1)))

The new macro is now in place. A new make job should install it all, and if necessary, make the appropriate new documentation files.

After this, please kindly mail me your addition to the YODL package. I will include it (if it's worth while), stating full credits too.