TOC | 21 June 2004

# Zoem User's Manual

The size of this manual is getting ridiculous. Working on it (the doc macros need chapter mode).

## 1 Introduction

Zoem: <Dutch> The sound made by electrical devices and flying bugs. Pronounced: zoom or zum; the vowel is short.

Zoem is a general macro/programming language with filtering capabilities. One of its uses is the creation of little high-level mark-up languages. It is a new inhabitant of two niches swarming with creatures already.

Zoem was first created to make mark-up languages that solve particular problems. One such problem is posed by the wish to create good-looking cross-referenced manual pages for output with either troff, html, or yet other devices, while having the ease of control and brevity of expression as in TeX, as opposed to, say, DocBook. Other problems descend from similar desiderata for FAQ authoring and technical documentation in general. Some software developers need brevity and control, lest the documentation suffers in its evolution. Zoem itself has virtually no features supporting mark-up. It has two components.

One compoment is a macro/programming language with many constructs put together in a coherent design. A few to name are dictionary stacks, IO facilities, an arithmetic environment, delayed and inside-out evaluation, multi-dimensional data storage, iteration and control support, system interaction, regular expressions, and an interactive environment. An interesting feature is the combination of anonymous macros, lists, and the `\apply#2` primitive, constituting a kind of callback mechanism in zoem. Another feature is the automatic popping and pushing of dictionaries with the begin/end environment, providing shadowing and localization.

The other component is a simple filtering language that distinguishes between two types of zoem scopes. Device scope is used to encode device specific mark-up sequences. Plain scope is used to encode running text. Filtering mechanisms are provided for both.

Zoem processes text by first applying the macro component, followed by applying the filtering component. Macro packages use the zoem primitives to construct mark-up languages that are designed to map to different devices in a bottom-up fashion. The resulting languages are generally clean, extendible, and perform well.

Examples
The zmm_generic package provides generic support for both troff and html (lists, paragraphs, typefaces, references). It contains some 550 spacious lines, with 25 characters on average. The intended substance conveyed by those counts is that the package is small. The man.zmm package consists of 300 additional lines. The faq.zmm package (which uses the man.zmm package) contains 200 additional lines.

Zoem has a rigorous syntax similar to TeX's with no more than a single first-level meta character. The syntax's rigor combined with the callback mechanism enables a near-complete separation of mark-up and content, maximizing flexibility. Here is an example from the section Inhabitants of the authoring ecosphere. Take note that the itemize environment seen below and all macros except `\apply` do not belong to the zoem language; they are part of packages built on top of zoem.

    \begin{itemize}{
       {compact}{1}
       {contiguous}{1}
       {margintop}{1}
       {marginleft}{4}
    }
    \apply{_#3\!{{
       \item{\aref{\1}{\bf{\2}}}
          \3
       }
    }}{
     {http://www.google.com/search?q=aft+almost+free+text}
     {aft}
     {almost free text}

     {http://www.google.com/search?q=chakotay+chpp+macro+preprocessor}
     {chakotay}
     {chakotay/chpp}

     {http://www.google.com/search?q=empy+template+embedding+python+text}
     {EmPy}
     {embedded python [in text]}

     \""{ some thirty-odd triples omittted. }

     {http://www.google.com/search?q=yodl+yet+oneOther+Documentation+Language}
     {yodl}
     {yet oneOther Documentation Language}
    }
    \end{itemize}

This manual covers the whole zoem language. A large part of it is only interesting for someone writing a reusable macro package. A smaller part is still interesting for someone who is just using such a package, but might want to add some utilities and shortcuts of his own. The part where file inclusion, macro definitions, and macro expansions are explained is required reading for anyone considering or planning to use zoem. The manual also covers an example manual page written using the zoem manual macros, and the results after conversion to html and (PostScript generated from) troff (Section 10, see the table of contents below).

### 1.1 Other documentation

* |  | The manual page of the zoem interpreter
* |  | The zoem manual macros documented
* |  | The zoem faq macros documented
* |  | The zoem generic macros documented

### 1.2 Examples

Small examples are littered throughout this manual. If you want to see examples of what can be achieved using zoem, visit Section 10.

### 1.3 The habitat

Information about comparable and related applications is collected in section 3.6, Inhabitants of the authoring ecosphere. It lists a number of macro processors, authoring tools, mark-up languages, and software documentation projects.

Some more itchy prose about documentation tools can be found in Section 3.1.

### 1.4 About this document

Clicking on the number to the left of a section title (e.g. the 1.4 to the left of the title About this document of this section) will get you to the corresponding section of the table of contents.

Zoem input and zoem output are both generally shown in a typeface font, `like this`.

Links that point to locations within this document are shown in blueish colors. Links that point to documents originating from the same package (project) or perhaps the same site are shown in in greenish colors. Links that point to other stations on the internet or perhaps other packages on the same site are shown in in reddish colors.

#### 1.4.1 About this subsection

The zoem doc macros provide arbitrarily deeply nesting sections. This silly section is a level 3 section.

## 2 Table of Contents

TOP |  |
1. |  | Introduction
1.1. |  | Other documentation
1.2. |  | Examples
1.3. |  | The habitat
1.4. |  | About this document
1.4.1. |  | About this subsection
2. |  | Table of Contents
3. |  | Zoem in a nutshell
3.1. |  | Itches
3.2. |  | Examples
3.3. |  | Expressive power (features)
3.4. |  | Limitations and difficulties
3.5. |  | Premises and generalizing zoem
3.6. |  | Inhabitants of the authoring ecosphere
4. |  | zzello world
4.1. |  | The macro file
4.2. |  | The document file
4.3. |  | The output
5. |  | Invoking zoem from the command line
6. |  | Zoem syntax and parsing
6.1. |  | Syntax and nomenclature
6.2. |  | List of escape sequence classes
6.3. |  | Parsing stages
6.4. |  | File read
6.5. |  | File search path
6.6. |  | Macro expansion
6.7. |  | File inclusion
6.8. |  | Protection
6.9. |  | Scope dichotomy
6.10. |  | Device scope
6.10.1. |  | Device scope resulting from mapping special characters
6.10.2. |  | Device scope resulting from glyph definitions
6.11. |  | SGML/HTML/XML syntactic sugar cubes
7. |  | Zoem miscellanea
7.1. |  | Key signatures
7.2. |  | Anonymous keys
7.3. |  | Tree data
7.4. |  | Of blocks and varargs
7.5. |  | Session keys
7.6. |  | Built-in macros
7.7. |  | Dictionary stacks
8. |  | A zoem tour
9. |  | The zoem language
9.1. |  | Alphabetic index
9.2. |  | Topic index
9.3. |  | Primitives
10. |  | The zoem manual macros
10.1. |  | An example zoem manual page
10.2. |  | What it looks like in html
10.3. |  | What it looks like as PostScript generated from troff
10.4. |  | Full fledged manual pages and FAQ
11. |  | Pitfalls
12. |  | Glossary

## 3 Zoem in a nutshell

Zoem was first used for generating manual pages and FAQ documents in both HTML and troff from the same source. A table of contents is automatically added if desired and cross-references show up as links in HTML. This functionality is not directly supported by Zoem; it is obtained by assembling Zoem primitives into higher-level units. These particular units comprise one possible set of Zoem man or FAQ macros. Normally, not a single zoem primitive is encountered in a zoem manual page or FAQ - it should consist of high-level macros only. The largest part of this manual is concerned with the zoem primitives and how to assemble them into macro packages that facilitate mapping input to different devices.

A simple hello world example shows the basic idea behind zoem. For an example manual page view (in this document) the zoem source, the rendered html resulting from that source, and (external document) the rendered PostScript compiled from the troff source compiled from the zoem source. An annotated list of the manual macros is given in the man_zmm manual page.

Zoem supports several programming constructs, immediate and postponed expansions, stream character filtering, easy I/O facilities, integer arithmetic, and a whole lot more. Its four main aims are:

* |  | Providing the building blocks for a structural and programmable approach. Section 3.3 contains an overview of the zoem primitives and their use.
* |  | Accepting a pleasant syntax that does not require much thinking, favouring simplicity and rigor over looseness and context dependent rules.
* |  | Creation from the keyboard while minimizing on key-strokes.
* |  | Few meta characters. Zoem achieves this by having a single first-level meta character.
* |  | Adding filtering capabilities so that multiple devices can be addressed.

Zoem's biggest advantage: you can accomplish almost anything you want. One price you pay is that the source document must obey zoem syntax. One price that you don't pay is that zoem is not a mark-up language in itself. Zoem knows nothing whatsoever about paragraphs, lay-out, font weights, slant, sections, and headers. There are two sides to this.

On the one hand, every aspect of authoring has to be encoded somewhere, e.g. lists, verbatim environments, et cetera. Making this work for multiple devices can be quite challenging. You have to teach zoem, or perhaps somebody else has already taught it before, or perhaps someone has already done something similar that only needs a little adjusting. Zoem distinctly enables and promotes reuse and the creation of macro packages. All the same, making a zoem paragraph macro or a zoem boldface macro and mapping those to both html and troff is quite easy; making a general purpose zoem list macro and mapping that is a lot more difficult.

On the other hand, this difficulty is exactly what makes most authoring solutions for multiple devices fail somewhere. By keeping authoring issues out of the core zoem language, and focussing on small and powerful building blocks, zoem makes the playing field very large. If two devices support the same kind of authoring construct, then you really should be able to unify them in zoem.

One can (and should) isolate device specific instructions from authoring specific instructions, and those should again be encapsulated in macro packages. Reuse is essential: I use the same set of zoem man macros for all the manual pages that I write. The macro definitions themself are not too pretty (nor horrid) to look at, but the zoem source for the manual pages themself (importing the macros) looks a lot like TeX and may even be somewhat easier on the eye.

In general, low-end macros have to be defined and mapped onto each output device. Device-specific macros must be written by someone whose knowledge about output devices matches the desired level of typesetting sophistication. This is a pain on the one hand, on the other hand, this will ensure that you succeed in what you are aiming at. Moreover, high-end macros generally do not need device-specific instructions, so these need only be defined once.

If the output device has no macro facilities (HTML) or has interesting syntax and whitespace restrictions (troff), zoem may be a gain even if you need only one device. It is very easy to (conditionally) include device-specific material in the running zoem text itself.

### 3.1 Itches

Zoem was created because several of the author's itches were scratched by other approaches. I disliked existing ways of generating manual pages in both troff and html. These are always about converting from one mark-up language to one or more others, and they are invariably broken. More often than not it is a hugely unwieldy Perl script. Zoem was designed with the explicit goal of device forking, and zoem is not a mark-up language. It's a way of creating dummy mark-up languages with a TeX-like syntax. The notion of mapping the dummy language to a real mark-up language is built into the very DNA of zoem. For small mark-up languages, such as a (UNIX) manual language or a FAQ language, this is a feasible approach.

I was inspired by the leaden-footed approach of the SGML/XML/DocBook setup, which makes me nearly crave for a GUI because the typing is so cumbersome, with tags all over the place and no good macro facilities. That does something to a vim/tex/mutt/nn user, wondering whether he should use a GUI for flushing his writings. It's more like pulling a leg than scratching an itch. I need to type my documents and I need to have powerful macro facilities - as I need semantic mark-up that will do multiple things at the same time. So I disagree somewhat with what demigod James Clark (of groff, expat, SP, and XML fame) has to say about this:

> One lesson I drew from TeX and groff is that you want a real programming language, not a macro processing language. When you look at the thousands of lines of TeX macros or troff macros that people produce, it's a monument to the human intellect, but it's not really the right way to solve the problem.

For my everyday document, I don't think I need something that has all the generality, power, and inconvenience of attribute grammars and feature structures mixed with relational databases. Of course, using zoem to output XML is a very viable option - for my everyday document again, I do understand that publishers and the likes have different needs.

I was inspired in a positive way by the TeX syntax and design. TeX really enables the rapid creation of documents over which the creator is able to maintain powerful control by creating his own semantic mark-up - I am not even mentioning TeX's superb typesetting capabilities here. Zoem syntax was copied in a modified form from TeX (please note that zoem is absolutely infinitesimal in aim and scope [then perhaps note that zoem's macro facilities go a lot further]).

Then there is troff, the language I would love to love. The more I get to know it, the more I marvel at its insane syntax. It goes much deeper than just being terse. It is, with all due respect, plain raving mad at all levels. I know, it was conceived by the Egyptians in the age when papyrus was at an all time scarcity high. But hey, how can anyone in their right mind and of their free will enter a document in raw troff as we speak? I am not being fair though, and must admit being awed by people who write their books in troff (they probably hand-assemble the circuitry of their computers as well). Troff is very powerful, and it has a charm very much missed by the following listee. The zoem macros map to troff macros that are really somewhat feeble and totally wanting of troff's true might. That is the price for using troff as a dumb mark-up device (as most of the clever stuff is done inside the zoem macros).

Finally, info was a big itch on its own. If ever I saw an attitude problem matched only by the absence of achievement (that's a gripe about info, not texinfo, mind you). Admittedly, RMS is a giant and me just a dwarf squashed beneath his feet, which may explain why I cannot look any further. Count me in with all the other dwarfs squeaking they don't like info one bit.

### 3.2 Examples

The zoem man macros for the two devices HTML and roff were written by Stijn van Dongen and use a straightforward subset of HTML and the troff man macros plus a little additional plain troff (thanks go to Jan van der Steen for teaching me the first insights). Zoem input written in these macros yields cross-referenced html including a table of contents if desired, while at the same time a classic-style manual page can be produced. The good thing of zoem is that you can easily modify, improve, and replace these macros to suit your own needs. The page you are currently reading was created using macros which were morphed from the man macros. See the zzello world and The zoem manual macros sections.

### 3.3 Expressive power (features)

Below you find some features of the zoem primitives. Note that there are in practice two kinds of zoem files. The first is a zoem macro file, which should contain macros defined in terms of lower-level macros, with zoem primitives at the lowest level. The second is a zoem document file, which should import such a macro file and only use the high-level macros defined in that macro file. Additionally, a document file can define some high-level macros of its own, in terms of low-level macros, zoem primitives, or a mixture of both.

* |  | Macros with arguments, overloading of key names allowed (i.e. different keys with the same name are distinguished by the number of arguments they take). (`\def#2`, `\set#2`, and `\setx#2`). Zoem primitives look like regular macros, but usually they expand their arguments before use. User macros can be equipped with this behaviour by wrapping them in `\apply#2`.
* |  | Support for variable number of arguments - see the vararg section.
* |  | Easy file, STDIN, STDOUT, and STDERR input/output, nested file inclusion (`\dofile#2`, `\write#3`, `\finsert#1`, and `\zinsert#1`).
* |  | A separate namespace for integer counters. Extensive support for arithmetic with the primitives `\let#1`, `\f#2`, `\f#3`, `\fv#2`, and `\eqt#3`.
* |  | A separate namespace for references. References can have up to five members: caption, number, level, type, and misc. They are set using `\refload#6`, and got using `\ref#2` (or one of the non-primitives `\refcaption#2`, `\refnumber#2` etc).
* |  | Operators returning booleans (`\defined#2`, `\cmp#3`, `\eqt#3`), control operators acting on those (`\while#2`, `\if#3`).
* |  | The for-like primitives `\apply#2` and `\table#5`.
* |  | Match and substitution capabilities using POSIX regexes (`\inspect#4`).
* |  | The switch primitive `\switch#2`, employing the vararg construct. Yes, zoem has a switch statement, and it takes arbitrary expressions too!
* |  | Localized expansions (`\eval#1`) and meta-zoem (`\!` and `\!#1`).
* |  | A user dictionary stack that can be manipulated using `\push#1` and `\pop#1`. An environment environment for doing `\begin{stuff}` `..` `\end{stuff}` stuff (see `\env#3`). This environment creates name scopes by pushing and popping to/from the dollar dictionary stack. Environments may take arguments, one particular useful application is that local variables (e.g. local to an itemize environment) can thus be specified by the user.
* |  | Storage of data by multiple string indexing - arbitrary data can be stored in a tree by indexing nodes with (arbitrary) strings. Refer to the Tree data section.
* |  | The ability to nicely format macros (see `\formatted#1`).
* |  | Syntactic sugar for writing SGML-style mark-up and having it checked.
* |  | Executing system commands, possibly sending data to STDIN and receiving data from STDOUT - `\system#3`.
* |  | And more.

### 3.4 Limitations and difficulties

If you want to do arbitrarily complex stuff, it will be difficult to map it onto multiple devices. That is true for any system however, and zoem can still be very useful for example when you like the TeX way of creating documents whereas you need HTML output.

Tables are notoriously difficult to maintain along multiple devices. With zoem one should be able to aim for a least common denominator. I have not yet attempted to create such a forked table enviroment (which would likely benefit from the `\table#5` and `\apply#2` primitives), mostly because tables are neither common nor easily implemented in manual pages that are meant to be read in terminals. The usual approach towards tables in manual pages is to use a verbatim environment like so:

       .-------.-------.-------.
       |       |       |       |
       |   8   |   1   |   6   |
       |       |       |       |
       .-------.-------.-------.
       |       |       |       |
       |   3   |   5   |   7   |
       |       |       |       |
       .-------.-------.-------.
       |       |       |       |
       |   4   |   9   |   2   |
       |       |       |       |
       .-------.-------.-------.

The zoem manual page macros provide a `verbatim` environment and a `verbatix` environment for this. The former will not be split over two pages by troff (if it fits on a single page).

The zoem manual pages posed interesting difficulties when I looked further than html under Netscape and troff under groff. Making things work for both Netscape and Internet Explorer (with respect to spacing in lists) and for both GNU troff (groff) and other (older and proprietary) troff versions (with respect to the `verbatim` environment) was interesting, to say the least. Some issues sprang from my own mistakes, and I learned a couple of things along the road. Notably the existence of `\e` and `\&` in troff, and the power of the `<div>` and `<span>` elements in HTML. The list issue seems unsolvable using orthodox methods, as the list environments are broken in different ways and degrees in the various browsers (e.g. mangling the margin attributes). The solution currently in use is that all zoem itemize variants are mapped onto html tables.

One unfortunate matter is the following. I have become quite attached to using italics in manual pages, as groff does a good job (in terminals) of rendering italic text as underlined - when groff produces PostScript it will simply render italics of course. Other and older versions of troff seem to render italics by switching to reverse video, which gives a horrendous effect. Beware of this, and avoid italics if you want to optimize the worst case user experience. Another thing is that older troffs don't seem to justify paragraphs as groff does.

### 3.5 Premises and generalizing zoem

The usefulness of zoem depends on the premise that mark-up languages like troff, html, and TeX possess certain orthogonality properties. One such property is that environments like lists can be nested freely. Luckily this is what everyone expects from a sane mark-up language, and most mark-up languages try to be sane. If a language fails to meet this requirement, you will have to work within the restricted area of the language that does meet the requirement.

Zoem's behaviour right now is pretty straightforward. It distinguishes two kinds of parse scopes, plain scope and device scope. When plain scope is output, any character that is special to the output device is translated to the corresponding 'magic sequence' for that device. Zoem has efficient provisions for different levels of magicality and the ability to switch between them. When device scope is output, nothing is mapped, and some additional primitives for regulating the output of white space are available. Parse scope is subject to macro expansion; device scope is not.

For example, the zoem manual macros map every period '`.`' encountered by zoem in plain scope onto the sequence '`\&.`' [sic], if the output device is troff. They map every ampsersand '`&`' onto the sequence '`&amp;`' if the output device is html. However, the first example is slightly overdoing it. In troff, a dot only has magic powers if it is the first character on a line. Zoem currently provides no way of recognizing this kind of subtlety. The natural generalization of the present scope model would be to equip zoem's output behaviour with a finite state automaton. I hope that this will never be necesary though, as the simplicity of the present model is gratifying and promotes robustness when constructing high-level macros.

### 3.6 Inhabitants of the authoring ecosphere

If zoem is not what you are looking for, you might be interested in one of the following. The links are to Google searches, as I am lazy and the items are in varying states of being supported.

aft |  | almost free text
Aptconvert |  | convert almost plain text
chakotay |  | chakotay/chpp
deplate |  | wiki-like document markup for LaTeX/HTML output
Dita-XML |  | Darwin Information Typing Architecture
doclifter |  | translate troff requests into DocBook
EmPy |  | embedded python [in text]
gellmu |  | generalized extensible LaTeX-like markup
gema |  | gema, the general purpose macro preprocessor
gpp |  | gpp, generic preprocessor
grutaxt |  | grutaxt, a plain text to HTML converter
hsc |  | HTML s*cks completely [sic modulo s/*/u/]
htlatex |  | hypertext LaTeX
info |  | GNU info, from the folks that abhor man pages and love topic splatter
jamal |  | Jamal, Just Another Macro Language
latex2html |  | latex to html, on my system a 17032 line Perl-script
latex2man |  | latex to man
latte |  | latte
m4 |  | a Unix macro processor
man2html |  | man to html
ManEdit |  | edit man pages with an "integrated XML interface"
manServer |  | convert manual pages to HTML
ManStyle |  | documentation for HTML and PS from a simple XML format
ML/I |  | A general purpose macro processor
mtex |  | manual TeX [by Mike Sofka]
mtex |  | manual TeX [by Compaq]
pod |  | plain old documentation (Perl's documentation format)
PolyglotMan |  | parses and maps troff source to other devices
PYM |  | PYM (A Macro Preprocessor based on Python)
reStructuredText |  | reStructuredText, not unlike aft and pod
smartHTML |  | smart HTML
tei |  | text encoding initiative
tex4ht |  | TeX for hypertext?
troffcvt |  | translator for troff to various other formats
txt2docbook |  | simple text format, docbook output
txt2tags |  | txt2tags, not unlike reStructuredText, aft, and pod
wlatex |  | web LaTeX?
WML |  | Website Meta Language
yodl |  | yet oneOther Documentation Language

Really, the number of inhabitants is stupifyingly mindboggling. Even when restricting attention to proposed solutions for the manual/troff/html problem, there are many applications. A few Net searches turn up plenty (more).

Christopher Browne has a section on macro languages: http://www.cbbrowne.com/info/macros.html

You might also be interested in these Freshmeat sections: Text-Processing::Markup, Text-Processing::General, Software-Development::Documentation, and Documentation,

The Debian text section http://packages.debian.org/unstable/text/ has many interesting entries.

## 4 zzello world

A not entirely trivial hello world example, featuring the concepts of plain scope and device scope. The latter should only be seen in macro packages. The distinction between these parse scopes is essential to zoem, and is thoroughly explained in the Scope dichotomy and Device scope sections. The sequence `\@{..}` encloses device scope, the sequence `\:` introduces a comment until the end of line. `\switch#2`, `\def#2`, and `\special#1` are zoem primitives. `\__device__` is a normal macro conventionally used to divide and rule over different devices. The mappings defined by `\special#1` live in device scope.

### 4.1 The macro file

Say this macro file is named `simple.zmm`.

    \: -----------------------------------------------------------------
    \: Stuff such as this belongs in a (reusable) macro file.
    \: \bf#1 and \par need device specific sequences.
    \: \special#1 maps characters with meta meaning in plain scope.
    \: \@{..} encloses device scope: nothing is mapped therein.
    \: -----------------------------------------------------------------
    \switch{\__device__}{
       {html}{
          \def{bf#1}{\@{<b>}\1\@{</b>}}
          \def{par}{\@{<p>\N}}
          \special{             \: how to map characters in plain scope.
             {38}  {&amp;}      \: 38 is ascii character '&'
             {60}  {&lt;}       \: 60 -> '<'
             {62}  {&gt;}       \: 62 -> '>'
          }
       }
       {roff}{
          \def{bf#1}{\@{\\fB}\1\@{\\fP}}
          \def{par}{\@{\P}}
          \special{             \: how to map characters in plain scope.
             {46}  {\\&.}       \: a dot.
             {96}  {\\&`}       \: backquote.
             {39}  {\\&'}       \: quote

             {92}  {\\e}        \: backslash (default troff escape character).
                                \: escaping by backslash may fail in
                                \: diversions [for old roffs].

          }
       }
    }

### 4.2 The document file

    \import{simple.zmm}
    \def{greet}{\bf{greetings}}
    \def{greet#1}{\bf{hello \1!}}
    \def{greet#2}{\bf{\1 \2!}}

    \: Use the keys just defined. Some kind of overloading there.
    \: the '&' will be automatically mapped and so will '<' and '>'.

    \par
    The other day I said \greet{Venus & Serena},
    and they said cheerfully
    \greet{<morning>}{Truman},
    give Laura our best \greet please.

### 4.3 The output

This is the html output:

    <p>
    The other day I said <b>hello Venus &amp; Serena!</b>,
    and they said cheerfully
    <b>&lt;morning&gt; Truman!</b>,
    give Laura our best <b>greetings</b> please.

which renders of course as

The other day I said hello Venus & Serena!, and they said cheerfully <morning> Truman!, give Laura our best greetings please.

The troff output is not shown here. You can look at several comprehensive and much more sophisticated examples in the The zoem manual macros section. The output formats shown in that section are html, PostScript, troff, and plain t(e)xt.

## 5 Invoking zoem from the command line

You use zoem by invoking it from the command line. The normal mode of operation is that you specify a file for zoem to chew up and spit out. This is called the entry file, and its name usually has the extension `.azm`. The other thing you normally specify is the device, which will just assign a value to the `\__device__` key. A common invocation thus looks as follows:

    zoem -i mcl.azm -d html

The `-i` flag specifies the entry file and the `-d` flag sets the `\__device__` key. It is not necessary to write the `.azm` extension, zoem will append it for you. The preceding could also have been entered as

    zoem -i mcl -d html

In either case, zoem will set the session key `\__fnbase__` to the base name of the entry file, i.e. the name stripped of its `.azm` suffix. In this example, the key `\__fnbase__` will get the value `mcl`. If you have an input file without the `.azm` extension, you need to use the `-I` option.

Zoem writes its output to a default output file which is named according to three rules. The rules are:

* |  | If the `-o` flag was given the value say `somestr`, zoem will write to the file named `somestr`.
* |  | If `-o` was not supplied but the `-d` flag was used with argument say `zyx`, zoem will write to the file named `\__fnbase__.zyx`.
* |  | If neither `-d` nor `-o` was given, zoem will write to the file named `\__fnbase__.ozm`.

It is possible to change the default output file from within the document; this is achieved with the `\writeto#1` primitive. Zoem can mingle default output with output to other files, use the `\write#3` primitive for that.

Both the `-i` and `-o` flag accept a hyphen as argument, meaning respectively that zoem will read from STDIN and write to STDOUT.

Specifying just zoem and entering a return will cause zoem to enter interactive mode, in which it reads from STDIN and writes to STDOUT. Interactive mode currently should catch any errors occurring, so it is a good way of experimenting and testing. By default, interactive mode reads chunks that are ended by a single dot on a line by itself. This behaviour can be changed by setting the session variable `\__parmode__` using the `-s` option. Using `zoem -l parmode` shows the bits that can be set in this variable. It is for example possible to make zoem read paragraphs (ended by two or more consecutive newlines).

NOTE
There is a difference between specifying no output stream (i.e. not using the `-o` option) and explicitly specifying `-o -`. In the latter case, zoem will never enter interactive mode. Should you need to insert zoem into some pipe sequence, then you need to use `-o -`.

TRACING ERRORS
If your document contains erroneous input (e.g. using a macro that was never defined), zoem will by default print the approximate corresponding line number of the current input file and the last key it saw, and then exit. If that does not suffice in tracking down the error, you have a choice of options. One possibility is to use one of the various tracing modes described below and in the zoem interpreter manual. Another possibility is to specify the `-x` option which says to enter interactive mode should an error occur. This enables you to inspect the values of keys defined or used in the problematic area.

A selection of other options is given below. For the full story, consult the manual page of the zoem interpreter.

`-h`
|  | lists all flags accepted by zoem with a short description for each.
`-s <foo>=<bar>`
|  | Sets key `\foo` to `bar`.
`-e <any>`
|  | Zoem will evaluate `<any>`, writing any result text to STDOUT, and then exit.
`-E <any>`
|  | Zoem will evaluate `<any>`, writing any result text to STDOUT, and then proceed.
`-x`
|  | If an error occurs, zoem stops processing and enters interactive mode.
`-l <str>`
|  | lists all entities specified by `<str>`. It can be any of `all`, `filter`, `legend`, `macro`, `session`, `trace`, or `zoem`. Repeated use is allowed. In fact, zoem will only check whether the target is present as a substring, so
    zoem -l legendzoem
will print the legend and the list of zoem primitives.
`--trace`
|  | This traces (prints) all keys encountered, and prints possibly truncated arguments. Zoem has several other tracing flags, use the `-h` flag or refer to the zoem manual page for more information. Tracing can be set from within the document using the `\trace#1` primitive. Part or whole of the data tree can be output from within the document using the `\%dump` primitive (refer to the Tree data section).
`--stats`
|  | When zoem is done, it prints statistics about the primitive name table and about the user name table.

## 6 Zoem syntax and parsing

### 6.1 Syntax and nomenclature

Zoem parses text which may contain zoem escape sequences, these are sequences that have special meaning and cause zoem to do special processing. Each and every escape sequences starts with a backslash, no exceptions. There are three kinds of sequences that are macros, which may or may not take arguments. These are zoem primitives, user keys, and dollar keys. There are currently about sixty zoem primitives, these are listed in the The zoem language section. Sixty is quite a lot; it includes oddball entries such as `\roman#1`, convenience sibling sets such as `\set#2`, `\setx#2`, `\def#2`, and `\def#2`, and entries covering a variety of areas such as I/O, arithmetic, testing, control, string conversions, formatting, shadowing (scopes), counters, and all the other stuff listed in the Topic index section. User keys and dollar keys are discussed in the Macro expansion section. Arguments are shipped by delimiting them with curly braces, as in

    \thiskey{takes}{\bf{two}\it{arguments}}.

No characters are allowed inbetween (the delimiting curlies of) two arguments (but take note of the handy `\formatted#1` primitive). See the Macro expansion section for more information. Zoem is very strict in the syntax it accepts, but it garantuees to accept a text in which each backslash `\` is escaped as `\\` (i.e. a text in which all consecutive runs of backslashes have even length).

An active backslash is any backslash that is not made inactive by an active backslash immediately preceding it. The first backslash seen by zoem (proceeding sequentially through the text) is active. This is one incomprehensible way of stating the obvious, and I bet you know what I mean anyway. An active backslash must always have a meaning known to zoem. If zoem does not get it, it will complain and exit. The meaning (i.e. class) of the escape sequence introduced by an active backslash is determined by the character immediately following it. A list is given below.

Within arguments, curlies not functioning as argument delimiters must also be escaped if they are not balanced. It is best practice to escape all non-argument-delimiting curlies, but I never do so myself unless they are not balanced. An escaped curly is a curly preceded by an active backslash. An active curly is a curly that is not escaped. A pair of balanced curlies consists of an active left curly that matches an active right curly, where inbetween all escaped curlies are disregarded. A block is anything delimited by balanced curlies. The word scope is most often used to distinguish between device scope and plain scope, these are the two kinds of parse scopes. An environment scope refers to the stuff enclosed by instances of the `\begin#2` and `\end#1` primitives. So called name scopes are entered and exited by `\push#1` and `\pop#1`.

### 6.2 List of escape sequence classes

This is a list of escape sequence classes recognized by zoem, indexed by the (set of) character(s) triggering the class(es) - this assumes that the character in question is preceded by an active backslash.

`$[_a-zA-Z]*`
|  | [dollar key] A sequence starting with a dollar sign possibly continued with underscores and alphanumeric characters. Introduces a dollar key. No dollar signs are allowed in the remainder, and the first non-alphanumeric non-underscore character terminates the sequence. The primary use of dollar keys is that they are set by `\begin#2` and `\end#1`. Dollar keys live in the dollar dictionary stack, which is pushed and popped by `\begin#2` and `\end#1`. Nested `begin/end` scopes can thus safely associate different values with the same key name. Refer also to the Macro expansion section, the The zoem language section, and the Dictionary stacks section. Note: `\$#2` is a zoem primitive.
`[_a-zA-Z][_a-zA-Z0-9]*`
|  | [user key/zoem primitive] A sequence starting with an underscore or an alphabetic character, with only underscores and alphanumeric characters in the remainder. Introduces a user key or a zoem primitive. The first non-alphanumeric non-underscore character terminates the sequence. These keys live in the user dictionary stack, which the user can control with the `\push#1` and `\pop#1` primitives. Refer also to the Macro expansion, The zoem language, and Dictionary stacks sections. A sequence consisting of a single underscore (i.e. not followed by an alphanumeric character) introduces an anonymous key.
`"`
|  | [user key] Starts a user key, which is only different from the user keys mentioned above in that it looks different. The sequence is terminated by a closing `"`. Inbetween, anything is allowed except a backslash or curly. This is used for creating mnemonic names such as
       \"man::author"
       \"man::section"
       \"man::version"
       \"html::title"
       \"html::charset"
These keys live in the user dictionary stack. See the Macro expansion section and the Dictionary stacks section.
`%`
|  | [grape key] A sequence starting with a percent sign. The percent sign is followed by a number of scopes. This is used to access multi-dimensional data storage. Such data is stored using the `\def#2` primitive or one of its siblings.
`[1-9]`
|  | [positional parameter] A single (character encoding a) positive digit. The sequence backslash followed by digit is called a positional parameter. It is only interpreted in the second argument of `\set#2`, `\setx#2`, `\def#2`, and `\defx#2`, and in the definition part of an anonymous key (which can be an argument to `\apply#2` and `\inspect#4`). In all these instances, the sequence denotes a positional parameter into which the corresponding argument will be interpolated when a key with arguments is used. It is allowed in other places though, as it is possible in zoem to create key definitions dynamically (see e.g. the `\setx#2` primitive). NOTE during interpolation, positional parameters that are enclosed by the delay scope `\!{..}` will not be interpolated (see `\!#1`). The status of this feature is not entirely clear.
`<newline>`
|  | [strip newline] The newline will be stripped during the interpretation stage. If you want the newline to be stripped during the file-read preprocessing stage use the sequence `\:/`, which is a special case of the comment sequence (see below).
`:`
|  | [preprocessing sequence] There are a few preprocessing sequences, which are evaluated during file read (cf the File read section). The most important preprocessing sequence is simply the sequence `\:` followed by whitespace, an alphanumeric character, or a backslash. It introduces a comment up till and excluding the next newline, which is stripped.
`|`
|  | [zoem glyph] Comprises a special two-character sequence that can be given a device-specific meaning. It is customarily used to encode a line break. To zoem, this sequence is more or less the same as a 'normal' character. See the `\special#1` primitive.
`~`
|  | [zoem glyph] It is customarily used to encode a non-breaking space. See the entry above.
`-`
|  | [zoem glyph] It is customarily used to encode a long dash. See two entries back.
`\`
|  | [backslash] Denotes a literal backslash.
`{`
|  | [left curly] Denotes a literal left curly.
`}`
|  | [right curly] Denotes a literal right curly.
`*`
|  | [glyph sequence] Starts a glyph sequence or constant sequence. Refer to the Device scope section and to the `\constant#1` primitive.
`<`
`>`
|  | [syntactic sugar] This introduces syntactic sugar for directly writing SGML-style mark-up, such as HTML and XML (e.g. DocBook). Refer to the anchor section for that topic.
`@`
|  | [at scope] Typically seen in macro package files only. Starts a special instance of device scope called at scope. The sequence `\@` must immediately be followed by a pair of balanced curlies, so at scope always appears as `\@{..}`. Refer to the Scope dichotomy and Device scope sections for more information.
`&`
|  | [and scope] Typically seen in macro package files only. May only be used within device scope, and implements a limited form of macro expansion within that scope. The sequence `\&` must immediately be followed by a pair of balanced curlies. so and scope always appears as `\&{..}`. Refer to the Scope dichotomy and Device scope sections for more information.
```
|  | [back quote - formatting escape] Typically seen in macro package files only. Starts a formatting sequence (that is terminated by another ```). This is only recognized within the `\formatted#1` primitive. This primitive removes all literal whitespace it encounters in its argument; the formatting sequences are transformed to the whitespace character encoded by them.
`,`
|  | [comma - atomic separator] Typically seen in macro package files only. This is interpreted during filter time, and is always mapped to nothing. Use it for glueing things as in `\foo\,1`, which will result in `theresultoffoo1`.
`!`
|  | [delay sequence] Typically seen in macro package files only. Introduces a zoem meta sequence. Such a sequence consists of a maximal run of consecutive backslashes, possibly followed by a single block. It can be used to delay interpretation during any number of interpretation stages, and is useful to delay interpretation, perhaps even in a nested fashion, for arguments in keys such as `\apply#2` that expand one or more of their arguments before use. The run of exclamation marks (or 'bangs' as they are internally called) actually comprises an argument to the underlying primitive, so the two primitives (one taking a single block argument) internally have respective signatures `!#1` and `!#2`. Externally though, they are just refered to as `\!` and `\!#1`.
`=`
|  | [inline files] Rarely used feature. Starts either a sequence of the form `\={fname}`, which begins a so called inline file named `fname`, or a sequence of the form `\==`, which ends such an inline file. Refer to the File read section.

This leaves `0'()[]?^#/.;` for future use, hopefully very few of these will ever acquire meaning. If the sequence `\#` acquires meaning, it will probably be for encoding Unicode scalar values.

### 6.3 Parsing stages

Parsing is separated into three stages, conceptually. Zoem knows two different parse scopes, plain scope and device scope. These are mentioned below, and explained in the Scope dichotomy section. The three stages are:

* |  | File read
* |  | Macro expansion / file inclusion - only plain scope is seen.
* |  | Filtering - both plain scope and device scope are filtered. Device directives that lay hidden in device scope are interpreted during output.

In reality, as soon as a piece of text is no longer subject to the second stage, it is immediately filtered and output.

Macro expansion is done recursively. Whenever a macro is encountered, it is replaced by its expansion, and the result is again fed to the parser. Evaluatation is not necessarily lazy, that is, during macro expansion the expander may expand arguments before they are interpolated and substituted in the macro definition. This inside-out evaluation can recurse if necessary. Many zoem primitives evaluate one or more of their arguments before use. The default behaviour for user macros is lazy evaluation. This can be changed however by wrapping both the macro and its arguments in `\apply#2`. Expansion can be delayed using `\!` and `\!#1`, so different arguments can be treated differently.

Important is that the result from the second stage is still valid zoem input. If you re-feed it to zoem, file read and macro expansion are usually no-ops (unless some interpretation delay-magic was used), and the syntax is garantueed to be acceptable to zoem. This is because device scope is not touched during the first two stages, and device specific text (which is most likely not conforming to zoem syntax) lies always hidden in that scope. There are three kinds of escape sequences introducing device scope; these are described in the Device scope section.

This is used for example when creating a table of contents; you can write expanded but unfiltered content to a file and read it in during the following run. It is important that such content is fully expanded, because you want things like index numbers and references as they are at the time of macro invocation. It is equally important that what you read back in is still valid zoem input; this is simply achieved by witholding filtering. When the table of contents is read in, it can be subjected to filtering, and this is the right way to do toc stuff in Zoem.

### 6.4 File read

File read - stripping comments, reading inline files.

Zoem searches for files included via `\dofile#2` or one of its aliases in a number of places if it cannot find the file in the current directory. The precise way of searching is documented in section File search path .

`\:` |  | In most cases, this sequence introduces a comment, namely where it is followed by whitespace, an alphanumeric character, or a backslash. It introduces a comment up until and excluding the next newline, which is stripped. The sequence `\:/` introduces a comment up till and including the newline. This feature can be useful within the `\protect#1` primitive, as it is the only way to delete actual newlines within the argument of that primitive. The sequence `\:!` is replaced by a backslash. The single use currently known is to make it easy to quote zoem input containing comment sequences. This
    \foo
       \bar
       \zut     \:!:  this will end up as a comment.
will result in the following
    \foo
       \bar
       \zut     \:  this will end up as a comment.
`\={fname}`
|  | starts inline file named fname at the next line, removes remainder of line after the `\={fname}` sequence. When using the `\dofile#2` primitive or one of its four aliases, an inline file takes precedence over regular files in the file system, whether it is present (as a regular file) or not. See below. This feature can be used to ship zoem input in one piece while putting the macro parts at the end. Currently, `\finsert#1` and `\zinsert#1` cannot refer to inline files. The future will probably bring a zoem option that creates such a self-contained file automatically from the zoem entry file.
`\==` |  | ends inline file, removes remainder of line.

The above applies to any file read at any stage. Inline files may occur in any file included at any time, but they do not nest.

The zoem entry file is the single file that is specified on the command line. This is the main file, from which other files can be included if desired.

Zoem entry files usually have the extension `.azm`, which is memnonic for A ZoeM file. This is required if the `-i` option is used. Arbitrary entry file names can be specified using the `-I` option. It is not uncommon to generate sibling files with `.roff`, `.html`, `.zmt` (zoem table of contents), and `.zmr` (zoem references) extensions - however, this is all configurable in user space and not part of zoem itself. There are no restrictions on names of files that are included from the entry file. Inclusion is done recursively.

The future will probably bring a second extension that is allowed, namely `.ezm` for Expanded ZoeM file, which is a self-contained file in which every included file is present as an inline file.

### 6.5 File search path

If zoem cannot find a file in the current directory, it attempts to find the file in one of three different ways. These are, in the order in which they are attempted:

* |  | The environment variable `$ZOEMSEARCHPATH` is checked. It may contain a listing of paths separated by whitespace or colons.
* |  | The zoem variable `\__searchpath__` is checked. It must contain a listing of paths stored as a vararg, i.e. a sequence of paths where each path is delimited by curly brackets. DO NOT overwrite this variable, but rather append or prepend to it. Most likely zoem was configured and compiled locally on your system, in which case `\__searchpath__` contains the path necessary to find the macro packages `man.zmm`, `faq.zmm`, and `doc.zmm`.
* |  | The path of the file currently being parsed is used. Assume that file `foo` contains `\import{/a/b/c/bar}`. If file `bar` wants to include file `zut`, which is in the same `/a/b/c/` directory, it need not prepend a path but can just issue `\import{zut}`. Should the previous search mechanisms fail to find zut, then zoem will as a last resort deduce the path from `/a/b/c/bar`. This feature is probably rarely needed, if ever at all.

### 6.6 Macro expansion

Macro expansion consists of recursive file inclusion and macro expansion. All zoem primitives and user keys are recursively expanded until none remains. Zoem primitives and user keys take one of the following forms:

`\abc_0123_`
|  | A key with alphanumerics and underscores only. Ends with any other character. All zoem primitives but one have this form. Note: `\_` denotes an anonymous key, see the Anonymous keys section. These keys live in the user dictionary stack. Initially, there is only one dictionary. The stack can be manipulated using the `\push#1` and `\pop#1` primitives.
`\"abc::def-ghi.jkl,mno+qrs"`
|  | A quoted key. Almost anything inbetween quotes is allowed. Always ends with a quote. No zoem primitive has this form. These keys live in the same user dictionary stack as the keys above.
`\$abc_0123_`
|  | A key introduced with a dollar sign. The name may further consist of alphanumerics and underscores and it ends with any other character. These keys live in the dollar dictionary stack. A dictionary is pushed with every occurrence of `\begin#2`, and that dictionary is popped with the corresponding occurrence of `\end#1`. Further note: `\$#2` is a zoem primitive.

All three types of keys may take arguments, and overloading is allowed:

       \foo                          \: signature foo
       \foo{bar}                     \: signature foo#1
       \foo{bar}{bop}                \: signature foo#2
       \$foo{bar}{baz}               \: signature $foo#2
       \"foo::oof"{zut}{zit}{zot}    \: signature "foo::oof"#3

is an ensemble of valid and unique keys, which can be defined for example by

       \def{foo}{FOO}
       \def{foo#1}{The FOO of \1}
       \def{foo#2}{The FOO of \1 and \2}
       \def{$foo#2}{The $FOO of \1 and \2}
       \def{"foo::oof"#3}{\foo{\1}{\2}\foo{\2}{\3}}

Additionally, zoem allows the definition of constant keys that map directly into device space and are ignored during macro expansion. Usage of such keys looks like `\*{'e}` or `\*{(c)}` and is detailed later on.

A sequence `\k` where k is in 1-9 is allowed within anonymous keys (as used for example in `\apply#2` and `\inspect#4`) and in the definition argument of the `\def#2` primitive and its siblings `\defx#2`, `\set#2`, and `\setx#2`. It indicates the position(s) where arguments should be interpolated. NOTE during interpolation, positional parameters that are enclosed by the delay scope `\!{..}` will not be interpolated (see `\!#1`). The status of this feature is not entirely clear.

A feature that should only rarely be needed is that zoem allows name scopes. Refer to the Dictionary stacks section.

### 6.7 File inclusion

There is one zoem primitive which has four different uses. For each of those uses, an alias exists.

    \dofile#2 use      alias          meaning

    \dofile{expr}{!+}  \input{expr}   require file, interpret and output
    \dofile{expr}{!-}  \import{expr}  require file, interpret only
    \dofile{expr}{?+}  \read{expr}    permit absence, interpret and output
    \dofile{expr}{?-}  \load{expr}    permit absence, interpret only

The `\dofile#2` primitive and its four aliases are perhaps a little funny interface-wise - better ideas are welcome. The `expr` argument is digested, that is, expanded until no macro's remain. It is thus possible to specify `\__fnbase__.zmt` and include a table of contents file that has been written to in a previous run. `\dofile#2` and its aliases have the property that zoem really descends into the files, and on error will emit a message containing the approximate line number where it occurred.

Additionally, the contents of a file can be placed inline using `\finsert#1` and `\zinsert#1`.

Note: wherever `key` is written, it means that something of the form `\foo`, `\$foo`, or `\"foo"` has to be provided, so you would use `\setx#2` e.g. as `\setx{foo}{\finsert{\__fnbase__.zyx}}`.

### 6.8 Protection

The `\dofile#2` primitive requires that the files to be included satisfy zoem syntax. It will descend into the files and proceed parsing them.

The `\finsert#1` and `\zinsert#1` primitives do not descend, but rather act as if the contents of the file specified were pasted into the place of macro invocation.

`\finsert#1` will protect the contents of the inserted file, that is, all backslashes and curlies are escaped by preprending them with a backslash. `\zinsert#1` will include the file unchanged, assuming that its contents satisfy zoem syntax.

The `\system#3` primitive is able to pipe data to a system command's STDIN stream and retrieve data from the command's STDOUT stream. This primitive will unprotect the data it sends, and it will protect the data it receives. NOTE the security implications of this feature as discussed at the `\system#3` entry.

Data can be explicitly protected using the `\protect#1` primitive.

Protected data can (currently) never result in it being expanded again. This is because escaped backslashes are only interpreted at filter time, and never during expansion. If you only need temporary delay of expansion, use the `\!` primitive or the `\!#1` primitive.

### 6.9 Scope dichotomy

Zoem knows two parse scopes: plain scope and device scope. The latter is also called 'at scope' because `\@{..}` is one (but not the only) way of entering device scope. In plain scope, every character represents itself as a glyph, i.e. as something that should show that way in print/on screen (after the zoem output/device input is fed to the device interpreter).

For example, if you write the less than sign `<` in plain scope, it should show up as a readable less than glyph, like in this very sentence. In order to make this happen, zoem provides the `\special#1` primitive, so that the less than sign can be automatically mapped to the html entity sequence `&lt;`.

In device scope, nothing is mapped except for a double backslash should it occur. If you enter this particular sequence of mixed scope: `\@{<b>}<hello world>\@{</b>}` as zoem input, the zoem output/device input is (provided the `\special#1` primitive was correctly used for the html device): `<b>&lt;hello world&gt;</b>` and what you finally see on screen is: <hello world>. In device scope, every character (except for the escape sequences available in that scope) represents itself as the ASCII character that should be present in the zoem output/device input. Device scope should normally only be seen in macros and not in running zoem input.

In plain space you type characters just as you want to see them eventually - when you read the document after the zoem output was run through a device interpreter (such as a browser or printer, or postscript previewer). The only exceptions are the backslash and the two curlies, these should be entered as `\}`, `\{`, and `\}`, respectively. Those escape sequences are interpreted as the characters or glyphs `\`, `{`, and `}`. For all characters, including these three, it is checked whether they should be further mapped according to the `\special#1` primitive. If a mapping is found, it is retrieved and interpreted by the device scope filter. Read on.

### 6.10 Device scope

There are three kind of strings which are interpreted by the generic device filter, and which are said to live in device scope:

* |  | The strings embedded in `\@{..}` sequences.
* |  | The strings mapped to by the `\special#1` primitive, including mappings of the zoem glyphs `\~`, `\|`, and `\-`.
* |  | The strings mapped to by the `\constant#1` primitive.

In a macro package that is meant to work for multiple devices, every use of any of these constructs will typically be embedded in something that tests the value of the active device. This can be done using either `\cmp#3` with `\if#3`, `\switch#1`, or `\$#2`, in conjuction with the pre-defined zoem key `\__device__`, containing the name of the active device (which can be specified on the command-line). The following are equivalent:

       \if{\cmp{eq}{\__device__}{html}}{ \@{<!-- (c) foo bar -->} }{}

       \: is equivalent with

       \${html}{ \@{<!-- (c) foo bar -->} }

The `\$#2` primitive is used if something needs to be done for one device only, and it may occasionally appear in documents. For example, the zoem man macros enable the creation of a table of contents (for both html and troff). My own convention is to have a table of contents only in html, and I specify this using the sequence

    \${html}{\"man::maketoc"}

When zoem enters device scope, it outputs all characters literally, except that the backslash still has special meaning. It is used for encoding the backlash itself (as `\\`), and for encoding the two curlies `{` and `}` (as `\{` and `\}`). This is the same as in plain scope (except that in plain scope the resulting character may again be mapped onto something else, for example, in troff the backslash also needs encoding as `\\`).

In device scope the sequence `\"` maps to a double quote. This is an additional feature to allow zoem input to be more susceptible to some editors moving features. It is not necessary though; simply using the double quote without escaping it is sufficient.

Additionally, the backslash can be followed by a single letter from a prescribed set listed below. Such a backslash+letter combination is called a device directive. By default, zoem will never print consecutive newlines, and it will never print consecutive spaces or spaces at the beginning of a line. The device directives allow this to be altered.

N |  | garantuee a newline
P |  | garantuee a paragraph skip (two consecutive newlines)
S |  | garantuee a space (except if next char is newline)
I |  | increase indent by one (indent is printed after each newline)
J |  | decrease indent by one
C |  | set indent to zero
n |  | print newline
s |  | print space
t |  | print tab
w |  | stop managing white space (squashing spaces and newlines)
W |  | start managing white space (use after `w`)
& |  | start and scope (see further below)
+ |  | set the special level (see further below)

Note that the directives mainly affect the lay-out of the device text (which is zoem output), not the look of the interpreted device text. The '`N`' directive is rather important when constructing troff macros, as many special troff commands are encoded by a dot as the first character on a line, i.e. a newline followed by a dot. Since troff attaches special meaning to two consecutive newlines as well (interpreting it as a paragraph break), zoem needs to be able to specify print a newline only if the previous character was not a newline. This is exactly what the `N` directive means. The '`W`' and '`w`' directives are required for enabling the construction of a verbatim environment.

The sequence `\&{<almost any>}` can be used to avoid overly cumbersome constructions. It is for example illegal to write

    \@{<table width="\width">}

In the early days of zoem, you had to write

    \@{<table width="}\width\@{">}

- ugly by most standards. Today you write

    \@{<table width="\&{\width}">}

Which is not any shorter, but more pleasant to read. What happens is that the contents of and scope `\&{..}` is first fully expanded in plain scope, after which the result is passed back to device scope. You have to be careful though. The content of `\&{..}` should never expand to something containing the at sequence `\@{..}`, because device scope is not allowed to nest. It should also not expand to something containing the and sequence `\&{..}` either, as this sequence is illegal in plain scope.

#### 6.10.1 Device scope resulting from mapping special characters

The first kind of zoem escape introducing device scope is `\@{..}`. The second kind comprises the `\special#1` mappings, including the three zoem glyphs `\~`, `\|`, and `\-`. Conventionally, these are used to encode a non-breaking space (`&nbsp;` in html), a line break (`<br>` in html), and a long dash (emdash, not present in html). You would for example put

    \if{\cmp{eq}{\__device__}{html}}{
       \special{
          {38}  {&amp;}           \: 38 is ascii character '&'
          {60}  {&lt;}            \: 60 -> '<'
          {62}  {&gt;}            \: 62 -> '>'
          {256} {&nbsp;}          \: the zoem escape \~
          {257} {<br>\N}          \: the zoem escape \|
          {258} {-}               \: the zoem escape \-
       }
    }{
    }

All `\special#1` definitions are interpreted in device scope. For every character encountered in plain scope, it is checked whether a `\special#1` definition exists, if so, the corresponding string is retrieved and this is filtered through the device scope filter. Note that the three zoem glyphs described here may not be used in device scope, they can only be used in plain scope. In device scope you will have to write the explicit, device-specific sequence such as `<br>` (in html).

The `\special#1` primitive allows different levels of mappings to be defined simultaneously. Several definitions of the same character are allowed; these are placed on a stack particular to that character (cf. the `\special#1` entry). When zoem encounters a character for which one or more mappings exist, it retrieves a mapping using the special level. This is an integer that has by default the value `1`. Each open output stream has a unique special level associated with it. [Output streams exist for the default output file (see e.g. `\writeto#1`) and for each file openend by `\write#3`]. A mapping is retrieved using this rule: The deepest element is fetched for which the depth does not exceed the level. The most visible element (which is the element first occurring in the `\special#1` invocation) has depth `1`.

The presence of different levels comes in handy e.g. when the troff device is used. In some contexts, the double quote is a special character in troff (and a printable quote is then mysteriously represented by two consecutive double quotes), in most contexts it is not. This is combatted by including these two specifications in the `\special#1` call preparing for troff output (note that 34 is the ASCII value representing the double quote):

    \special{
       ...
       {34}{"}
       {34}{""}
       {92}{\e}
       ...
    }

The first pair shown simply maps the double quote onto itself, and the second pair maps it onto a double double quote. As long as the special level is `1`, the second definition is not used. The backslash (with ASCII value `92`) needs only one definition as it is escaped in the same way in all troff contexts.

The special level can be set using the `\+` directive, which must be followed immediately by a digit in the range `0-9` enclosed by curly brackets, e.g. `\@{\+{2}}` will set the special level to `2`. The special level can be set to `0` (zero) and this means that no character will be mapped.

Example
Whenever a troff context is entered where the quotes needs escaping, the controlling zoem macro issues a sequence

    \@{\+{2}"} ... funny quote context ... \@{"\+{1}}

Such a macro is typically defined in a package and its definition should never be visibile to the user of the package. Note that the double quotes embedded in at scope in the example above are not susceptible to special mapping -- mapping is only applied in plain scope.

#### 6.10.2 Device scope resulting from glyph definitions

The third kind of device scope strings are those mapped to by the `\constant#1` primitive. An example of (toy) usage is this:

    \constant{
       {'e}  {&eacute;}     \: Use e.g. as \*{'e}l\*{`e}ve (élève)
       {(c)} {&copy;}       \: Use e.g. as \*{(c)} DEEDEE (© DEEDEE)
       {+-}  {&plusmn;}     \: Use e.g. as \*{+-} a few (± a few)
    }

This is largely convenient syntactic sugar. These constants could also have been defined as

       \def{"'e"}{\@{&eacute;}}
       \def{"(c)"}{\@{&copy;}}
       \def{"+-"}{\@{&plusmn;}}

The idea is that the `\*{..}` namespace is used for glyph-like device-specific bindings, whereas the `\".."` namespace is used for semantic purposes that are device-independent, but nothing prohibits you from fiddling with this.

### 6.11 SGML/HTML/XML syntactic sugar cubes

Zoem provides a shorthand for entering SGML-style tags. It is checked by zoem for well-formedness of the resulting SGML code, and it can be freely mixed with other modes of entering tags. Normally you would have to enter SGML-style tags in device scope, or write a macro for doing that. For example, a macro `x#2` that expands `\x{b}{be bold}` to `\@{<b>}be bold\@{</b>}` is a likely candidate. However, this would be inelegant for constructions that span a long distance, and it does not provide for letting zoem expressions expand within an xml tag.

Zoem provides the `\<` and `\>` tokens. The `\<` token can be used in several ways:

       \<foo>            \: foo can be an expression.
          Some <content> \: of course, expressions may occur here as well.
          over here.
          \<bar>{zut}    \: bar can be an expression too;
                         \: this syntax will close itself.
          Some <content> \: again, expressions may occur here as well.
          over there.
       \<>               \: this is a closing tag for the first foo.

       \<tim x=y/>       \: zoem knows this closes itself.
       \<br!>            \: zoem converts this to <br>

Suppose that foo, bar, and zut are zoem expressions expanding to strings FOO, BAR, and ZUT respectively (FOO and BAR might be of the form `tag a="b" c="d"`). Provided that the characters `<`, `>`, and `&` are automatically mapped in plain scope (as a result of correct `\special#1` usage), the above will result in

       <FOO>
          Some &lt;content&gt;
          over here.
          <BAR>
             ZUT
          </BAR>
          Some &lt;content&gt;
          over there.
       </FOO>

       <tim x=y/>
       <br>

The `foo` part inside the `\<foo>` syntax should never expand to something containing a `>`. This is entirely the responsibility of the user or macro package author.

Both kinds of syntax, `\<foo>` and `\<bar>{zut}`, are kept as they are during the expansion stage, and they can be subjected to multiple levels of expansion (which may be the case if such syntax is used inside e.g. `\setx#2` or `\apply#2`). It is only at the output stage that the syntax is transformed to actual SGML code and that well-formedness is checked. So, the two examples just seen will first transform to `\<FOO>` and `\<BAR>{ZUT}` (please note that foo, bar, and zut all denote expressions here). If they are at that point no longer subject to expansion they enter the output stage where they are converted to `<FOO>` and `<BAR>ZUT</BAR>` (plus some additional formatting/indenting) respectively.

Zoem pushes on a stack of opening tags whenever it encounters `\<foo>` syntax during the output stage. It naturally knows that a tag can be followed by attributes. It also knows that a tag such as `\<tag a=b/>` closes itself (XML syntax). As a special case, `\<tag foo bar zut!>` is converted to `<tag foo bar zut>` to allow encoding of HTML tags such as `<br>`. These two kinds of tags are not considered opening tags. Note that you should only use `\<p>` if you are going to use `\</p>` or `\<>` as well (because zoem requires closing tags for opening tags).

Zoem does not know about other ways of entering tags, so `\@{<body>}` would not affect the stack just mentioned. `\<>` automatically closes the top level opening tag from the stack. Again, syntax such as `\@{</body>}` does not interact with the stack. This is actually useful; I mainly use the `\<foo>` syntax for more complicated stuff such as nested material in tables (e.g. the table of contents in this document).

It is possible to explicitly close a tag by simply using `\</foo>` syntax. Zoem will check whether the closing tag matches the top level opening tag. As seen before, `\<>` does the same thing, but rather than doing a check, zoem will use the top level opening tag to construct the corresponding closing tag. Finally, `\>` does the same as `\<>`.

## 7 Zoem miscellanea

### 7.1 Key signatures

Several keys take another key as argument, e.g. they store a value in a second key or check whether the second key exists. The full list of these meta keys is `\def#2`, `\defx#2`, `\set#2`, `\setx#2`, `\undef#1`, `\defined#2`, `\apply#2`, and `\inspect#4`. In all cases, the argument key is passed as the first argument, by means of the key signature.

For a key `\key` taking `k` (`k`>0) arguments its signature is `key#k`. The signature of a key `\key` taking no arguments is simply `key`. The rule is: Key usage always includes a single leading backslash (this activates the key). When a key is subject of inspection, it is always referred to by its signature.

Throughout this text, a key with signature `key#k` is mentioned by means of its key mention `\key#k`, that is, for extra clarity the backslash is prepended to the signature.

### 7.2 Anonymous keys

A single underscore introduces an anonymous key. It is optionally followed by a `#k` tag (for `k` in `1..9`), denoting the number of arguments the anonymous key takes. An occurrence of the latter is called a tagged anonymous key. The first argument to the key should be a key definition, the other arguments are the arguments for that key definition. If a tag is present, it is used for verifying that the anonymous key is used properly.

       \_{\1 the \2}{row}{boat}
       \_#2{\1 the \2}{row}{boat}

results in

       row the boat
       row the boat

Anonymous keys may occur in the first argument of `\apply#2`, within the first argument of `\inspect#4`, and they may occur freely in running text. The presence of a tag is required when an anonymous key is used within either of `\apply#2` and `\inspect#4`. An example of usage in `\apply#2`:

    \apply{_#2{\1 kisses \2\|}}{{bill}{max}{max}{bill}}
    bill kisses max
    max kisses bill

or even

    \set{%foo}{{{\1 hugs \2\|}}}
    \apply{_#2\%{foo}}{{bill}{max}{max}{bill}}
    bill hugs max
    max hugs bill

Note that in order to store a block with `\set#2`, an extra pair of curlies has to be used, as blocks can only be passed as a sub-argument of a single-element vararg. Also note that in a vararg it is allowed to put white space inbetween the constituting elements.

### 7.3 Tree data

Data can be organized in a global tree with a specialized use of `\set#2` and its siblings, as shown further below. The data is retrieved from the tree using so called grape keys. Such a key is started using a percent sign, immediately followed by zero, one, or more blocks, e.g. `\%`, `\%{..}`, and `\%{...}{...}{...}` would all be allowable invocations. If more than one block follows the percent sign, there must be no interleaving white space.

The underlying primitive has signature `%#1`, as the trailing scopes are congregated into a single argument before they are further processed. The two sibling primitives `%free#1` and `%dump#1` serve for freeing and dumping parts or whole of the tree, as described further below.

When applied to grape keys, `\set#2` and its siblings set one or more values in a global multi-dimensional associative array that we shall refer to here as `ROOT`. Please note that `ROOT` is for explanatory purposes only. This associative array is best viewed as a tree, in which every node can have branches to higher nodes. A node may or may not contain a value. Let us denote the value contained by a node `some-node` as `*(some-node)`. The fact that `beta` is a node one branch higher than `alpha`, which is in turn one branch higher than `ROOT`, is denoted as `ROOT->"alpha"->"beta"`. In this path notation, strings indexing nodes in the trees are written inbetween quotes. This has the advantage that the empty string, which is a valid index string, has the representation `""`. Combining these conventions, we write the value associated with `beta` as `*(ROOT->"alpha"->"beta")`. Consider these examples.

    \set{%{foo}{bar}{zut}}{lez}
          \: now *(ROOT->"foo"->"bar"->"zut") is "lez"

    \set{%{foo}{bar}{zut}}{{a}{b}{x}{y}}
          \: now *(ROOT->"foo"->"bar"->"zut"->"a") is "b"
          \: and *(ROOT->"foo"->"bar"->"zut"->"x") is "y"
          \: and *(ROOT->"foo"->"bar"->"zut") still is "lez"

       \: some special cases
    \set{%{foo}{bar}{zut}}{{{c}}}
          \: now *(ROOT->"foo"->"bar"->"zut") is "{c}"
    \set{%{foo}{bar}{zut}}{{c}}
          \: now *(ROOT->"foo"->"bar"->"zut") is "c"
    \set{%{foo}{bar}{zut}}{c}
          \: now *(ROOT->"foo"->"bar"->"zut") is "c"

    \set{{foo}{bar}{zut}}{{c}{d}{e}}
          \: This does nothing, because the second argument
          \: must either be an *even* vararg, a 1-element vararg,
          \: or a simple argument.

    \set{%{{tiger}}}{in the woods}
          \: now *(ROOT->"{tiger}") is "in the woods"
    \set{%{tiger}}{in the woods}
          \: now *(ROOT->"tiger") is "in the woods"
    \set{%tiger}{on the loose}
          \: now *(ROOT->"tiger") is "on the loose"
          \: stripping curlies from a vararg with one argument
          \: does not make a difference with the exception of
          \: the case shown below.

    \set{%{}}{empty}
          \: now *(ROOT->"") is "empty".
    \set{%}{root}
          \: now *(ROOT) is "root".

Take note of the rule governing the second argument. If the first non-white space character is a left curly, `\set#2` expects a vararg. The vararg must either be even or it must contain exactly one argument. An even vararg is interpreted as a sequence of key-value pairs. Each key induces a new branch from the node specified in the first argument, and each value is associated with the node at the end of that branch. If the vararg contains exactly one argument, that argument is simply used as a value. This is the only way to specify a block as the value. If the first non-white space character is not a curly, `\set#2` will simply interpret the second argument as a value to append to the node specified in the first argument.

If you want the data to be stored to be expanded before it is bound, use `\setx#2` or `\defx#2`.

Data is retrieved simply by prefixing the path with the `\%` token. Example:

    \set{%{foo}{bar}{zut}}{{a}{b}{x}{y}}
    \%{foo}{bar}{zut}{a}
    \%{foo}{bar}{zut}{x}

will print `b` and `y`. If the path is not an existing path in the current tree it will simply be ignored, although an error message will be emitted.

Whole or part of the data tree can be freed using the `\%free` primitive. Again, simply append the access sequence in which you are interested. For freeing the entire tree, use `\%free` without trailing scopes. The `\%free` primitive largely exists for testing purposes to ensure that zoem gets its internal data manipulation right.

Whole or part of the data tree can be output for debugging purposes using the `\%dump` primitive. Simply append the access sequence in which you are interested. For printing the entire tree, use `\%dump` without trailing scopes. This can be used for debugging if your data manipulation does not work out as expected. There is no result text as far as usual processing is concerned. The underlying primitive dumps its findings to STDOUT in a line-based textual representation of the data-tree.

The future might bring support for using localized data trees, e.g. by means of `\push{grape}` and `\pop{grape}`. It should also become possible to specify the behaviour if a grape key access sequence does not exist.

### 7.4 Of blocks and varargs

A block is a string beginning with a left curly and ending with a right curly, the curlies being balanced. This is a convenient naming convention. Blocks can be used in constructing anonymous keys; refer to the Anonymous keys section.

Some keys take a vararg argument, which is a single argument (enclosed by curlies as are all arguments), which can contain any number of sub-arguments, that is, a list consisting of blocks. Inbetween the blocks white space may occur. The `\special#1` and `\constant#1` keys both take a single vararg argument, and the `\apply#2` and `\switch#2` keys each take a vararg as their second argument. For `\apply#2` the first argument is a key that is applied to subsequent batches of arguments from that vararg. The `\table#5` primitive takes a vararg as its last argument. For examples, see the A zoem tour section and the `\apply#2` entry.

An even vararg is a vararg with an even number of elements, An odd vararg is a vararg with an odd number of elements.

### 7.5 Session keys

       \__device__           \: the session's output device
       \__fnbase__           \: the base name of the entry file
       \__fnentry__          \: the name of the entry file
       \__fnin__             \: the name of the current input file
       \__fnout__            \: the current default output file
       \__lc__               \: expands to a left curly (only for magic)
       \__line__             \: the line number in the file currently parsed
       \__parmode__          \: slurp setting for interactive mode
       \__rc__               \: expands to a right curly (only for magic)
       \__searchpath__       \: search path for included files
       \__split__            \: user space chapter mode indicator

This manual is littered with examples of the usage of `\__device__`. The `\__fnbase__` key is useful for creating sibling files of the entry file, i.e. a table of contents file or a file containing reference information. I have the habit of naming those `\__fnbase__.zmt` and `\__fnbase__.zmr`, respectively. The `\__fnin__` key is useful for emitting log, warning, or error messages particular to the file currently being parsed.

The `\__parmode__` macro affects the way in which zoem reads chunks in interactive mode (refer to Section Invoking zoem from the command line ).

The `\__searchpath__` macro is one of the ways in which zoem can be instructed to search for files in a set of locations, when confronted with `\dofile#2` or one of its aliases. Refer to Section File search path .

### 7.6 Built-in macros

This is the result from doing `zoem -l macro`:

    Built-in aliases and macro's
    \def{input#1}{\dofile{\1}{!+}}
    \def{import#1}{\dofile{\1}{!-}}
    \def{read#1}{\dofile{\1}{?+}}
    \def{load#1}{\dofile{\1}{?-}}
    \def{refcaption#1}{\ref{\1}{c}}
    \def{refnumber#1}{\ref{\1}{n}}
    \def{reflevel#1}{\ref{\1}{l}}
    \def{refmisc#1}{\ref{\1}{m}}
    \def{reftype#1}{\ref{\1}{t}}
    \def{ctrinc#1}{\ctradd{\1}{1}}
    \def{ctrdec#1}{\ctradd{\1}{-1}}
    \def{throw#1}{\throw{\1}{}}
    \def{inform#1}{\write{stderr}{device}{\1\@{\N}}}
    \def{and#1}{\fv{and}{\1}}
    \def{or#1}{\fv{or}{\1}}
    \def{and#2}{\f{and}{\1}{\2}}
    \def{or#2}{\f{or}{\1}{\2}}
    \def{not#1}{\if{\1}{0}{1}}
    \def{begin#1}{\begin{\1}{}}
    \def{""#1}{}
    \def{group#1}{\1}
    \def{system#2}{\system{\1}{\2}{}}
    \def{system#1}{\system{\1}{}{}}
    \def{div#2}{\f{div}{\1}{\2}}
    \def{mod#2}{\f{mod}{\1}{\2}}
    \def{PI}{3.1415926536}
    \def{E}{2.71828182846}
    \def{"+"#2}{\f{+}{\1}{\2}}
    \def{"*"#2}{\f{*}{\1}{\2}}
    \def{"%"#2}{\f{%}{\1}{\2}}
    \def{"-"#2}{\f{-}{\1}{\2}}
    \def{"/"#2}{\f{/}{\1}{\2}}
    \def{""}{}

Cf `\dofile#2`, `\ref#2`, `\ctradd#2`, `\f#2`, `\f#3`, `\fv#2`, and `\system#3`.

### 7.7 Dictionary stacks

By default, when using `\def#2` and `\set#2`, keys and their values are put in a global user dictionary. It could be useful to shadow keys by entering a new name scope. Zoem facilitates this by providing the `\push#1` and `\pop#1` keys. These push and pop a new dictionary onto the user dictionary stack.

A second dictionary stack is the dollar dictionary stack, which contains all keys that start with a dollar sign. The `\begin#2` primitive pushes a dollar dictionary each time it is invoked, and that dictionary is popped by the corresponding `\end#1` invocation. This is typically useful for creating nested environments that need access to the same type of information - by storing such information in dollar keys, it can be shadowed and recovered. Refer to the `\begin#2` entry.

When a key is used its definition is searched in all dictionaries, starting from the top-level dictionary. The key `\undef#1` has only access to the top-level dictionary, and will never delete a key in any other dictionary.

## 8 A zoem tour

What follows is an informal tour through zoem's offerings. The next section contains a comprehensive overview of the zoem primitives.

Let us start with how filtering in plain space is configured. An example was given above for a single device (namely html). A more realistic approach, used in the zoem man macros, is this.

    \switch{\__device__}{
       {html}{
          \special{
             {38}  {&amp;}
             {60}  {&lt;}
             {62}  {&gt;}
             {256} {&nbsp;}          \: the zoem escape \~
             {257} {<br>\N}          \: the zoem escape \|
             {258} {-}               \: the zoem escape \-
          }
       }
       {roff}{
          \special{
             {46}  {\\.}
             {96}  {\\`}
             {92}  {\\\\}            \: a single backslash
             {256} {\\ }             \: the zoem escape \~
             {257} {\N.br\N}         \: the zoem escape \|
             {258} {\\-}             \: the zoem escape \-
          }
       }
       {\write{stderr}{txt}{No such device: \__device__\|}
        \write{\__fnbase__.err}{txt}{No such device: \__device__\|}
        \exit
       }
    }

Take note of the number of backslashes. In order to print a backslash in troff, the troff input must contain two consecutive backslashes. In order to specify a backslash in zoem, we must also provide two, thus we need four backslashes in all (in order to create this example I needed eight backslashes in the zoem input).

Also note the use of the `\switch#2` primitive, which takes an expression in the first argument and an arbitrary number of pairs plus an optional clause in the second argument. The optional clause was in this case used as a failure test.

`\special#1` is an example of a zoem key taking an argument that may contain arbitrarily many sub-arguments (i.e. a vararg). In this particular case the sub-arguments must be paired, each pair defining how certain ascii characters that are special to the device must be represented. There is a very limited number of additional tokens that can be mapped in this way:

The `\write#3` and `\exit` need little comment, they work as expected. Zoem opens output files as needed, and closes them when it is done. The file name `-` is equivalent to either `STDOUT` or `STDIN`, depending on the context, the file name `stderr` denotes `STDERR`.

`\exit` is considered a failure (and will cause zoem to stop and complain), but `\done` is not. `\done` will merely quit parsing the current stack, so if you specify it at top level in a file - not nested in a key that does its own parsing such as `\setx#2`, zoem will stop parsing the current file and transfer control back to the file from which it was included.

The previous example introduces the keys `\__device__` and `\__fnbase__`. They are so called session variables described in section Session keys.

A sibling primitive to `\special#1` is `\constant#1`. The following is an example of use.

    \constant{
       {'e}  {&eacute;}     \: Use e.g. as \*{'e}l\*{`e}ve (élève)
       {(c)} {&copy;}       \: Use e.g. as \*{(c)} DEEDEE (© DEEDEE)
       {+-}  {&plusmn;}     \: Use e.g. as \*{+-} a few (± a few)
    }

The main thing to note here is that the target string (e.g. `&eacute;`) is always interpreted in device space. Inbetween the asterisks almost anything is allowed, except a backslash or a curly, and it is obviously not allowed to use an asterisk in one of the definition parts of `\constant#1`.

There are three zoem tokens representing the characters that have meaning to zoem syntax, the backslash and the two curlies. Those zoem tokens are just like any other plain characters: they can be mapped in plain space, and they are printed literally in device space.

       \\            \: A backslash; possibly mapped in plain space.
       \{            \: A curly; possibly mapped in plain space.
       \}            \: A curly; possibly mapped in plain space.
       \,            \: The atomic separator (vanishes).

These tokens are mapped only during the (final) filter stage. The atomic separator can be useful when you want to glue together items some of which will be the result of macro expansion.

       \def{foo}{bar}
       \foo\,1                    \: \foo1 would be the key \foo1

This will result in bar1. The tokens `\\`, `\{`, and `\}` are really the corresponding ordinary ASCII characters. They can be mapped in plain space via `\special#1` using their ASCII values 92, 123, and 125 as was seen above for the backslash. In device space, they will result in `\`, `{`, and `}`.

Let us now continue with device scope by implementing a `\bf#1` key. Below you find two possible definitions:

       \def{bf}{1}{\@{<b>} \1 \@{</b>}}    \: Ok
       \def{bf}{1}{\@{<b> \1 </b>}}        \: Wrong! Wrong!

The second is wrong because the contents of `\1` end up in device space. If the expansion of `\1` still contains keys they will not be expanded (and cause a fatal syntax error when device space is filtered), and additionally any special characters in `\1` will not be mapped.

## 9 The zoem language

### 9.1 Alphabetic index

`\!` `\!#1` `\$#2` `\alpha#1` `\apply#2` `\begin#2` `\catch#2` `\cmp#3` `\constant#1` `\ctradd#2` `\ctrset#2` `\ctrput#1` `\def#2` `\defx#2` `\defined#2` `\dofile#2` `\done` `\dowhile#2` `\end#1` `\env#3` `\eqt#3` `\branch#1` `\eval#1` `\exit` `\f#2` `\f#3` `\fv#2` `\finsert#1` `\format#2` `\formatted#1` `\if#3` `\inspect#4` `\length#1` `\let#1` `\pop#1` `\protect#1` `\push#1` `\ref#2` `\refload#6` `\roman#1` `\set#2` `\setx#2` `\special#1` `\switch#2` `\system#3` `\table#5` `\throw#2` `\tr#4` `\trace#1` `\try#1` `\ucase#1` `\undef#1` `\vanish#1` `\while#2` `\write#3` `\writeto#1` `\zinsert#1`

### 9.2 Topic index

This is an overlapping categorization in topics.

Using and inspecting keys
|  | `\apply#2` `\constant#1` `\def#2` `\defx#2` `\defined#2` `\inspect#4` `\pop#1` `\push#1` `\set#2` `\setx#2` `\table#5` `\undef#1` These primitives affect or use either user keys that are stored in the user dictionary, dollar keys that are stored in the dollar dictionary, or anonymous keys. Dictionaries are discussed in Section 7.7.
Control, booleans, testing and comparison
|  | `\$#2` `\apply#2` `\branch#1` `\cmp#3` `\eqt#3` `\defined#2` `\dowhile#2` `\if#3` `\length#1` `\switch#2` `\undef#1` `\while#2`
Expansion, delay
|  | `\!` `\!#1` `\eval#1` `\apply#2` `\defx#2` `\setx#2`
Meta-zoem, introspection, exceptions, errors
|  | `\try#1` `\catch#2` `\throw#2` `\done` `\exit`
Execution, tracing
|  | `\trace#1`
Input/output
|  | `\dofile#2` `\write#3` `\finsert#1` `\format#1` `\zinsert#1` `\vanish#1` `\writeto#1`
Filtering
|  | `\special#1` `\vanish#1`
Environment scopes
|  | `\begin#2` `\end#1` `\env#3`
Name scopes
|  | `\pop#1` `\push#1`
Data storage
|  | `\%`, `\%free`, and `\%dump` are primitives described elsewhere - refer to the Tree data section.
String conversions
|  | `\alpha#1` `\format#2` `\inspect#4` `\length#1` `\roman#1` `\tr#4` `\ucase#1`
Arithmetic
|  | `\f#2` `\f#3` `\fv#2` `\let#3`
Counters
|  | `\ctradd#2` `\ctrput#1` `\ctrset#2`
References
|  | `\ref#2` `\refload#6`
Glyphs
|  | `\constant#1`
Syntactic sugar
|  | `\formatted#1` `\vanish#1` `\<>#1` `\<>#2`

### 9.3 Primitives

Zoem primitives may expand (which is the same as evaluate) one, several, or all of their arguments before using them. Such arguments are enclosed by double angle brackets in the listing below. The inside-out type evaluation is done recursively and works for arbitrary levels of nesting. An argument which is first expanded and is then interpreted as a label is thus written `<<label>>` in the primary entry. In the definition text accompanying the entry, the expanded argument is simply refered to as `<label>`, so the extra pair of brackets is dropped.

Each primitive below has a little paragraph with the caption Result text. It gives a summary of 'what comes out'. Note that the result of macro expansion is always passed to the parser again, so the result text is again subject to expansion.

`\<>#1`
`\<>#2`
|  | These are special. Refer to section SGML/HTML/XML syntactic sugar cubes. The angle brackets are part of the syntax, do not confuse them with the angle brackets used below to enclose arguments. These primitives are respectively used as `\<*any*>` and `\<*any*>{*any*}`, so the positioning of arguments is different from all other zoem primitives.
`\!`
|  | This primitive is triggered by an active backslash followed by a consecutive run of exclamation marks, which is not followed by an opening curly. The sequence is called a delay sequence, and its arity is the count of backslashes. A single exclamation mark is stripped (i.e. the arity is decremented) and the sequence is no longer subject to the current expansion stage. It is used to construct valid zoem input, which is usually redirected to file with the copy filter, stored using `\setx#2`, or used in nested occurrences of `\apply#2`, `\inspect#4`, and other primitives. Other uses are possible, the main thing is that one should keep a clear view of the meta-programming implied by `\!`. Refer also to the `\eval#1` primitive. Example The primitive `\eval#1` evaluates its argument a single time, and passes it on for further evaluation. The following are fully equivalent:
    \set{foo}{zut}
    \eval{\!foo}
    \foo
whereas `\!foo` would pass the sequence `\foo` to the filtering stage, where it will yield a (non-fatal) error message. Similarly, `\eval{\eval{\!!foo}}` is equivalent to the above. Result text A delay sequence of decremented arity.
`\!#1`: `\!{<any>}`
|  | This primitive is triggered by an active backslash followed by a consecutive run of exclamation marks, which is in turn followed by a block. The block is called a delay scope. The arity of the delay scope is the count of backslashes found in the run. A single exclamation mark is stripped (i.e. the arity is decremented); if no further exclamation marks remain (i.e. the arity becomes zero) then the introducing backslash and the delimiting curlies are stripped as well. The result (including the contents of the block) is passed on and is no longer subject to the current expansion stage. The same observations hold as those made for the previous entry. Refer also to the `\eval#1` primitive. Additionally, blocks that are protected by the delay primitive will be skipped during parameter interpolation. Result text `<any>`, if the arity of the delay scope just found was equal to one, otherwise, `<any>` put in a decremented delay scope. `<any>` will in both case no longer be subject to the current expansion stage.
`\$#2`: `\${<str>}{<any>}`
|  | This is a shortcut for activating output for a particular device. If `\__device__` expands to `<str>`, `<any>` is passed on for expansion, otherwise it is ignored. The following two are equivalent:
    \${html}{Seen only in the html device}

    \if{\cmp{eq}{\__device__}{html}}{Seen only in the html device}{}
Result text Either none or `<any>`.
`\alpha#1`: `\alpha{<<int>>}`
|  | Transforms the integer to a string over the alphabet `_a-z`, i.e. all the set of all lowercase letters with the underscore added. This set is simply used for counting in base 27, with the underscore playing the role of zero. Result text The integer written down in base 27 using symbols in the set `_a-z`.
`\apply#2`: `\apply{<<key-sig|anon-key>>}{<<vararg>>}`
|  | The first argument is expanded before use. It should expand either to the signature of a user key taking arguments, or to a tagged anonymous key. Examples of the first are `foo#k` and `"bar::baz"#k`, the latter takes the form `_#k{..}`. If you use an anonymous key containing macro sequences, be sure to escape whole or part of the anonymous key, depending on your needs. The expansion of `_#2\!{{<any>}}` for example, will result in `_#2{<any>}`. The second argument should result in a vararg. `\apply#2` extracts `k` elements at a time from `<vararg>`, and applies the key resulting from the first argument to each vector of `k` elements successively. Any elements remaining in `<vararg>` are ignored. `apply#2` has really turned out to be an all-round workhorse. For an interesting application see Example II in the `\begin#2` entry below. Result text Entirely depending on the key specified in the first argument.
`\begin#2`: `\begin{<label>}{<<vararg>>}`
|  | `\begin#2` pushes a new dictionary onto the dollar dictionary stack which is popped by the matching `\close#1`. `\begin#1` is an alias which invokes `\begin#2` with an empty `<vararg>` argument. `\begin#2` pushes the begin expression associated with `<label>` via `\env#3`. The `<label>` part is not expanded. The second argument `<vararg>` consists of consecutive scopes denoting key-value pairs. It is expanded before use and is allowed to be empty. The keys (which are the odd-numbered scopes, starting with one) in `<vararg>` must be such that prepending a dollar sign (`$`) to them yields a valid key signature. That signature will be used to set a dollar key in the newly pushed dollar dictionary that expands to the `value` part associated with the key (specified as the consecutive even-numbered scope in `<vararg>`). The pushing of a dictionary provides a means for shadowing and localization with nested `\begin#2` statements. By associating dollar keys with an environment, these keys can be given different meanings in nested environments - the previous meaning will be restored once an environment is closed. The advantages are that the environment does not have to exercise `\push#1` and `\pop#1` itself, that the user dictionary stack is not unnecessarily extended (saving look-up time), and that the 'dollar' look of a key such as `\$align` signals that it will automagically work in nested enviroments. Of course, the latter is still the responsibility of the author of the environment. The begin definition (as created by `\env#3`) must use `\defined{lkey}{...}` rather than `\defined{key}{...}` when it wants to check whether a `\begin#2` invocation did set a particular key. Result text The string associated with `<label>` via `\env#3`. Example I The zoem faq macros define a `faqsec` environment, for which two additional arguments are required. It is used for example as
    \begin{faqsec{ref}{misc}{cap}{Miscellaneous questions}}
     ...
    \end{faqsec}
The `ref` key introduces the label, the `cap` key introduces the caption. Example II The itemize environment in the zoem generic package allows one additional and optional argument. This argument, if present, must contain a vararg, and is used to set options related to the itemize environment. It is used for example as
    \begin{itemize}{
       {contiguous}{1}
       {compact}{1}
       {mark}{\*bullet*}
       {align}{right}
    }
     ...
    \end{itemize}
Internally, the itemize environment maps these options to dollar keys. Because a unique dollar dictionary is associated with each environment, this makes it possible for nested itemize instances to have separate namespaces. Several more options than those given here are supported by the itemize environment. All listings in the present text were created with it. This is approximately how the itemize environment does initialization:
          \apply{_#2\!{{\if{\defined{lkey}{\1}}{}{\def{\1}{\2}}}}}{
             {$contiguous}{0}
             {$compact}{0}
             {$w1}{2}
             {$w2}{1}
             {$f1}{16}
             {$f2}{8}
             {$mark}{\*{bullet}}
             {$margintop}{1}
             {$align}{left}
             {$debug}{0}
             {$lp}{}
             {$rp}{}
             {$type}{mark}
             {$itemcount}{0}
          }
This is clearly programming close to the metal, but it works very well. Result text Either the first block associated with a condition evaluating to true (c.q. nonzero), the else clause (if present), or nothing at all.
`\catch#2`: `\catch{<type>}{<any>}`
|  | This will process `<any>`. Depending on `<type>` the result is accepted as succesful. If `<type>` is `towel`, any occurrence of `\throw{towel}` in `<any>` is caught, and the truncated result is further processed. For `towel`, zoem errors are not caught but cascade/escalate further down/up. If `<type>` is `error`, any error in `<any>` is caught, and the truncated result is further processed. If `<type>` is `ok`, no exception is accepted. See also `\throw#2`. Output will be truncated in case an error or exception was caught. The status, currently one of `ok`, `towel`, or `error`, is written in the session macro `\__zoemstat__`. Result text The possibly truncated result of expanding `<any>` in case of a caught exception or error, else the full result.
`\cmp#3`: `\cmp{<str>}{<<any>>}{<<any>>}`
|  | The last two arguments are expanded. Their results are compared as strings. The first argument must be one of the labels `lt|lq|eq|gq|gt|ne|cp`. In case it equals one of the six labels `lt|lq|eq|gq|gt|ne`, this primitive puts in place the associated boolean as a string (i.e. either `0` or `1`). In case the label equals `cp`, it puts in place the result of the string compare (as a string), namely one of `-1`, `0`, or `1`. Result text Either the string enconding of a boolean (`0` or `1`) or the string encoding of the ternary value resulting from a string compare (`-1` or `0` or `1`).
`\constant#1`: `\constant{<vararg>}`
|  | `<vararg>` must have an even number of arguments. These are interpreted as pairs. The first of each pair must enclose a string that does not contain any of the characters `*`, `\`, `{`, or `}`, say string `<keystr>`. The second encloses a string that will be interpreted in device space, say string `<valstr>`. When a sequence `\*``<keystr>``*` is encountered, it is interpreted as `\@{``<valstr>``}`. This is done at filter time only, the sequence is skipped during macro expansion. It is not allowed to use a sequence `\*``<keystr>``*` in device scope, e.g. `\@{\*``<keystr>``*}` is illegal. For furtherh information see section Device scope. Result text None.
`\ctradd#2`: `\ctradd{<<label>>}{<<amount>>}`
|  | The first argument is expanded, yielding some string `<label>`. This string is used as a counter and `<amount>` is added to this counter. If the counter does not exist, it is first autovivified with a value of zero. The expansion of the first argument is useful, because it allows counters that otherwise count the same thing to be attached to different scopes, simply by appending a string representing the level to the counter. Result text None.
`\ctrset#2`: `\ctrset{<<label>>}{<<quantity>>}`
|  | The first argument is expanded, yielding some string `<label>`. This string is used as a counter which is set to the value `<quantity>`. The counter may or may not exist beforehand. Result text None.
`\ctrput#1`: `\ctrput{<<label>>}`
|  | Puts in place the counter associated with `<label>` as a string. If counter does not exist, the value zero is assumed. Result text The string encoding of an integer.
`\def#2`: `\def{<key-sig|grape-seq>}{<any>}`
|  | Bind second argument to the key or access sequence in the first argument. This primitive will complain if a binding exists already, but it will overwrite the previous binding and continue anyway. Use `\set#2` if you do no want to be warned for overwriting. Examples of usage:
       \def{foo}{FOO}
       \def{foo#1}{The FOO of \1}
       \def{foo#2}{The FOO of \1 and \2}
       \def{$foo#2}{The $FOO of \1 and \2}
       \def{"foo::oof"#3}{\foo{\1}{\2}\foo{\2}{\3}}
These examples are all of type `key-sig`. See the Tree data section for examples of type `grape-seq` (this pertains to multi-dimensional data storage). See the Macro expansion section for the forms that keys may take. A key signature is the name of a key with appended to it the number of argument that the key takes, if any. If the key takes no arguments, than the key signature is identical to the key name. If you want the value to be bound to be expanded before binding it, use either `\defx#2` or `\setx#2`. This works the same for grape keys. Result text None.
`\defx#2`: `\defx{<key-sig>}{<<any>>}`
|  | The second argument is expanded and stored in the key `<key-name>`. This primitive will complain if a binding for that key exists already, but it will overwrite the previous value anyway. Result text None.
`\defined#2`: `\defined{<type>}{<<access>>}`
|  | `<type>` is one string of `key`, `lkey`, or `data`. The second argument is expanded before use. For the type `key`, the result is looked up as a key signature in either the user dictionary stack or the dollar dictionary stack. For the type `lkey`, it is looked up only in the top level dictionary. For the type `data`, the result is interpreted as a data access sequence. This primitive pushes the string `1` if the result is indeed a valid reference, it pushes the string `0` otherwise. Result text The string encoding of a boolean (`0` or `1`).
`\dofile#2`: `\dofile{<<file name>>}{<char[!?]><char[+-]>}`
|  | Open a file and process its contents while keeping track of line numbers. Depending on the second argument, absence of the file is either allowed or not, and its interpreted contents are output or not. The fact that `<file name>` is first expanded allows you to specify file names such as `\__fnbase__.zyx`. Zoem may search for a file in several locations until it is found. The process of locating a file is described in section File search path . When found, the file is opened according to the specification in the second argument. This argument must contain exactly two characters, the first one of [`!?`], the second one of [`+-`]. The first character indicates whether the file is allowed to be absent. A ´`!`' implies that absence is fatal, a '`?`' permits absence. The latter is useful e.g. when creating a Table Of Contents file. The second character indicates whether the interpreted file should be filtered and output or not ('`+`' for yes and '`-`' for no). Macro packages typically need interpretation only, whereas concatenation of document parts (c.q. chapters) stored in different files requires that the interpreted content is also filtered and output. The following aliases are available:
    \input{fname}        \dofile{fname}{!+}
    \import{fname}       \dofile{fname}{!-}
    \read{fname}         \dofile{fname}{?+}
    \load{fname}         \dofile{fname}{?-}
The contents of `<file name>` cannot be captured. If you need to capture the contents of a file, use `\finsert#1` or `\zinsert#1`. Result text Technically none. Of course the processing of `<file name>` may result in output, depending on the mode of opening. However, this result text cannot be captured. For example,
    \setx{foo}{\dofile{bar}{!+}}
will result in the file `<bar>` being processed and output via the standard output mechanisms, while the key `\foo` will have the empty string as value.
`\done`
|  | Be done with parsing current stack. Use this primarily to quit parsing the current file, meaning that one can pile up heaps of obsolete rubbish following this primitive, without needing to outcomment it. Result text None, affects result text of the current interpretation stack.
`\dowhile#2`: `\dowhile{<any>}{<condition>}`
|  | `<any>` is expanded and concatenated to the result text until `<condition>` exands to something that is nonzero when interpreted as an integer. `<any>` is expanded at least one time.
`\end#1`: `\end{<label>}`
|  | Expands the end definition associated with `<label>` via `\env#3`. Result text The string associated with `<label>` via `\env#3`.
`\env#3`: `\env{<label>}{<any1>}{<any2>}`
|  | Stores unexpanded `<any1>` for later use with `\begin#2` (when given argument `<label>`) and unexpanded `<any2>` for later use with `\end#1` (when given argument `<label>`). Result text None.
`\eqt#3`: `\eqt{<str>}{<<num1>>}{<<num2>>}`
|  | The last two arguments are expanded. Their results are compared as numbers. The first argument must be one of the labels `lt|lq|eq|gq|gt|ne|cp`. In case it equals one of the six labels `lt|lq|eq|gq|gt|ne`, this primitive pushes the associated boolean as a string (i.e. either `0` or `1`). In case the label equals `cp`, this primitive pushes the result of the integer compare, namely one of `-1` (if the result of `<any1>` is smaller than the result of `<any2>`), `0` (equal to), or `1` (greater than). Result text Either the string enconding of a boolean (`0` or `1`) or the string encoding of the ternary value resulting from a string compare (`-1` or `0` or `1`).
`\branch#1`: `\branch{<<vararg>>}`
|  | Two arguments are successively taken from `<vararg>`. The first is expanded and then evaluated as an integer. If the integer is nonzero, the second argument is expanded and everything else is ignored. Otherwise the procedure is repeated. If no (odd) argument matches, and the `<vararg>` has an odd number of arguments, the last argument is put in place. It can be considered a default, else, or failure clause.
`\eval#1`: `\eval{<<any>>}`
|  | Expands `<any>` and passes it on for further evaluation. This can come in handy when complicated requirements demand zoem acrobatics. This primitive used to be implemented as a macro; it is fully equivalent to
    \set{eval#1}{\apply{_#1{\!1}}{\1}}
The above macro works as follows. First, `\apply#2` expands both of its arguments. The second argument is the data it received from `\eval`, i.e. the latter's single argument. At this stage, the data is thus expanded for the first time. `\apply#2` also expands its first argument. The sequence `\!1` is contracted to the sequence `\1`. The `\1` needed by `\apply#2` needs to be protected by the interpolation that occurs when `eval#1`'s argument is interpolated. Expansion of `\apply#2`'s first argument thus yields the anonymous key `_#1{\1}` - a key that simply copies it argument and passes it on for further expansion. Example `\foo` and `\eval{\!foo}` are fully equivalent. `\!foo` on the other hand, expands to `\foo` and is then passed to the filter stage. See also `\!`, `\!#1`. Result text `<any>` gone through two stages of interpretation.
`\exit`
|  | goodbye world. This is a disgraceful exit for use when some error test presumably yields true. Result text None.
`\f#2`: `\f{<fun>}{<<num1>>}`
|  | Expand the last argument, interprets the result as a number, applies the operand specified by `<fun>`, and puts the result in place. `<fun>` can be one of `floor`, `ceil`, `round`, `abs`, `sign`, `inc`, `dec`, `not`, and that's about it. For a wider range of mathematical functions, refer to the `\let#1` primitive. Result text The string encoding of a number.
`\f#3`: `\f{<fun>}{<<num1>>}{<<num2>>}`
|  | Expands the last two arguments, interprets the results as numbers, applies the operand specified by `<fun>`, and puts the result in place. Most arithmetic is done using floating point arithmetic (with the C double type). Integers are preserved if possible. Since nearly everything is treated as a string in zoem, this simply means that no decimal fraction is printed when the number is output. A number is considered integer if the difference with the integer nearest by is less than the precision (1e-8) and if it can be represented as an integer using the C long type. Otherwise it is output in decimal representation of the underlying floating point representation. `<fun>` can be one of
* |  | Multiplication.
+ |  | Addition.
- |  | Subtraction.
/ |  | Does true division, returns real.
% |  | Modulus.
and |  | Boolean and, results in `0` or `1`.
or |  | Boolean or, results in `0` or `1`.
div |  | Does integer division.
mod |  | Same as `%`.
pow |  | Power.
max |  | Maximum.
min |  | Minimum.
ceil |  | Nearest by higher multiple, e.g. `\f{ceil}{12}{5}=15`.
floor |  | Nearest by lower multiple, e.g. `\f{floor}{12}{5}=10`.
For a wider range of mathematical functions, refer to the `\let#1` primitive. NOTE `and` and `or` short-circuit. Result text The string encoding of a number.
`\fv#2`: `\fv{<fun>}{<<vararg>>}`
|  | Expands the second argument and interprets it as vararg, and applies the operator specified by `<fun>` to the elements of vararg. `<fun>` can be one of
* |  | Multiplication.
+ |  | Addition.
and |  | Boolean and.
or |  | Boolean or.
max |  | Maximum.
min |  | Minimum.
NOTE `and` and `or` short-circuit. Result text The string encoding of a number.
`\finsert#1`: `\finsert{<file name>}`
|  | The argument is expanded and interpreted as file name. The file is read, and every `\`, `{`, and `}` is escaped (resulting in one of `\\`, `\{`, and `\}`) The altered contents are then put in place. See also `\zinsert#1`. If file can not be opened, the empty string results. Result text The escaped contents of `<file name>` or the empty string if file can not be opened.
`\format#2`: `\format{<<fmt>>}{<<varag>>}`
|  | Formats elements from `<vararg>` according to the format specification in `<fmt>`. A format string may contain normal characters that will be output, and meta sequences. A meta sequence is started with the percent character `%`. For each `<arg>` in `<vararg>`, the next applicable meta sequence is sought in `<fmt>`. A meta sequence consisting of two consecutive percent signs (`%%`) will be skipped and result in the output of a single percent sign. Otherwise, the meta sequence may consists of a number of subsequences that may occur in any order. These are
`~{..}{..}`
|  | i.e. a tilde followed by two blocks. The content of the first block is used as the padding string. By default spaces are used for padding. Padding is applied if the width of the field exceeds the width of `<arg>` plus the width of the optional delimiter(s) encoded in the second block. The content of the second block is inserted inbetween the padding and `<arg>`. If centered alignment is used, this will be done on both sides. By default no such delimiter is used.
one of `<`, `>`, or `=`
|  | These respectively denote left, centered, and right alignment.
<num>
|  | A positive integer number denoting the desired width of the field on which `<arg>` is to be printed.
`*{..}{..}`
|  | i.e. an asterisk sign followed by two blocks. This is for when you want to use a virtual length. The second block should contain a string. The length of this string will be used to do the computations, but the actual string that is inserted into the formatted result is taken from `<vararg>`. This allows you for example to do alignment in `<pre>` formatted blocks in html, while keeping the possibility to insert elements that do not take up any width (e.g. links). The first block should contain the name of a macro, which is used to compute the length of the string in the second block. A likely candidate is `\length#1`, which should be specified simply as `length`.
`@{..}{..}`
|  | i.e. an at sign followed by two blocks. This is used to specify alignment. The content of the first block is used as the string on which to align. The content of the second block is used as the width on which the first part of `<arg>` (up to and including the alignment substring) will be right-aligned. If the asterisk sequence is used, the length macro specified therein will be used to compute the width of the string specified in the first block.
The meta sequence must currently end with the character `.` (a dot). Result text The formatted string.
`\formatted#1`: `\formatted{<any>}`
|  | This removes and adds white space from its arguments via the following rules:
* |  | It skips any `\@{..}` enclosed sequence.
* |  | It skips any `\<..>` enclosed sequence - note that the contents eventually will end up in `\@{..}` (at) scope.
* |  | It removes all spaces, tabs, and newlines it encounters otherwise.
* |  | It inspects and (after inspection) removes all `\`..`` enclosed sequences it encounters. During inspection, `\formatted#1` maps '`s`' to a space, '`t`' to a tab, and '`n`' to a newline.
* |  | If the sequence `\`[`` is encountered (not in at scope), `\formatted#1` starts copying literally without munging whitespace; it resumes its normal mode of operation after encountering the sequence `\`]``.
This is useful for writing legible macro files while exercising full control over whitespace (modulo Zoem's white space munging rules). Result text The argument in its unformatted form.
`\if#3`: `\if{<<condition>>}{<any1>}{<any2>}`
|  | The first argument is expanded and interpreted as an integer. If it is nonzero, `<any1>` is pushed on the interpretation stack and `<any2>` is ignored, vice versa if it is zero. Result text Either `<any1>` or `<any2>`.
`\inspect#4`: `\inspect{<mods{<reg>}{<any|anon key>}>}{<<any>>}`
|  | All arguments except `mods` are expanded before use. The expansion of `<reg>` is followed by an unprotect and should result in a POSIX regular expression. The unprotect action unescapes escaped backslashes and curlies, so that those can be passed to the regex engine (although it interprets backslashes, so you need to quadruple those if you don't want them interpreted). The expansion of `<any|anon key>` can either result in plain data or in an anonymous key. The third expansion results in data to which the regex `<reg>` is successively applied. If the second expansion results in something recognizable as an anonymous key, then the subpatterns from the matched pattern are interpolated by the key, and the entire matched pattern is substituted by the interpolation. Else, the matched pattern is simply replaced by the expansion. `mods` must contain the keyword `posix`, it may further contain a subset of the keywords `count dotall grep grepc icase lines look skip snip vararg`. This primitive has not yet been blessed by exhaustive stress-testing, so perhaps not all of these work flawlessly. `skip` prohibits non-matching part from being output. `icase` induces case insensitive matching. `dotall` makes the dot `.` match any character, including the newline. `lines` causes matching to be applied to lines shifted from the data (i.e. data is split on newlines). `vararg` causes matching to be applied to blocks shifted from the data (which should obviously be a vararg). `count` replaces the data by the count of matches, and works in conjunction with both `lines` and `vararg`. `snip` removes any lines or blocks which are empty after inspect is done with it. `grep` outputs only matching elements (only in conjunction with `lines` or `vararg`). `grepc` outputs only non-matching elements (only in conjunction with `lines` or `vararg`). `look` does not substitute, works in conjunction with grep -- matching elements are kept intact. Example Section 10.2, What it looks like in html contains an example of html output generated from the Zoem man macros. This section is automatically included from an external file by matching the contents inbetween the `<body>`, `</body>` tags. Those contents are then entered in device scope so that no further interpretation by Zoem would occur. This is how it is done:
    \formatted{
       \setx{buzzz}{
          \inspect
             {posix, dotall, skip}
             {DOCTYPE(.*)PUBLIC}
             {_#1{\1}}
             {\finsert{buzzz.html}}
       }
    }

    \<div class=indent>
    \apply{_#1{\@{\w\1\W}}}{{\buzzz}}
    \</div>
Note the use of `\apply#2` in order to get the contents of a macro into device scope, and note that in device scope white space munging is turned off using `\w` (and resumed using `\W`). This is done so that verbatim environments are preserved in the included text. Bugs The GNU implementation of POSIX regexes is known to be very buggy for long strings and/or long matches. There are many possible combinations of modifiers, and not all of them work together. It is mainly a bug in this documentation that forbidden combinations are not yet listed here. It is possible that certain combinations should work together but fail to do so. However, no such cases are known at the moment. A search pattern consisting of a single word boundary or the start-of-string token (`^`) will match at each position, because after a succesful match `\inspect#4` simply resumes searching for a new match by skipping to the end of the previous match (and adding a single position if the match had width zero and offset zero). Similar but not yet noticed bugs may exist. Nevertheless, this can be a very useful primitive for the occasional odd job, and it should always work except for the cases just mentioned. If you have a complicated instance of `\inspect#4`, test it first in isolation. Consider sending a bug report in case you find one (a bug, or a bug report). Result text Depending on the presence of a match and the modifiers given.
`\length#1`: `\length{<<any>>}`
|  | Computes the length of `<any>` and puts this in place. It takes into account the zoem escape sequences `\\`, `\{`, and `\}`. The future may bring a generalized `\length#2` primitive that provides different ways of measuring string length. Result text The length of any `<any>`.
`\let#1`: `\let{<<let expression>>}`
|  | The `\let#1` primitive puts zoem in arithmetic mode and the contents are parsed accordingly. All of C's operators are supported including the logical, bitwise, and comparison operators as well as the ternary operator. The operators `**` and `//` are added, which respectively denote exponentiation and integer division. Operations or functions resulting in integers are tracked, and the result will be stored in the integer type used (typically long) if possible. Thus one may find that
    \let{2**42}
    \let{2**22}
respectively result in `4398046511104.0` and `2097152`. The precedence rules used by Zoem are simpler than C's. The respective groups of logical, bitwise, and comparison operators all have identical precedence internally, and associate from left to right. Most of the ANSI C math functions are supported, with in addition `max` and `min`. The functions `round`, `sign`, and `abs` behave slightly different from their C counterparts, as they result in integer results if no overflow occurs. At any place where an atomic type is expected one is allowed to insert a zoem macro invocation. It will be evaluated and the result will be interpreted as a number. Evaluation will take place in the order as dictated by the precedence rules governing the expression. The logical operators shortcircuit and the ternary operator evaluates only one of its branches. This can be used to create side effects, such as in
       \let{\bar && \group{\set{foo}{zut}1}}
This sets `foo` only if `bar` evaluates to a non-zero number. The trailing `1` in the `group` macro is good practice because `\let#1` expects a number to be the result of any macro it encounters. It could have been any other number, or a macro or sequence of macros evaluating to a number. The `group` macro is a predefined macro that does nothing except passing its arguments. It is necessary in this concocted example because any occurrence of a macro within `\let#1` is interpreted as a number by itself. The sequence `\bar \bar` would for example be syntactically identical to `1 1`, which is incorrect. Result text A number.
`\pop#1`: `\pop{<label>}`
|  | Pops a dictionary from the user dictionary stack if `<label>` is the character `u`. Result text None.
`\protect#1`: `\protect{<<any>>}`
|  | The argument is expanded. Subsequently, all backslashes and curlies are escaped. The resulting text is put in place. Result text `<any>` with backslashes and curlies escaped.
`\push#1`: `\push{<label>}`
|  | Pushes a new dictionary onto the user dictionary stack if `<label>` is the character `u`. Note that `\defined#2` with the `lkey` label checks only the top-level dictionary, whereas `\defined#2` with the `key` label checks the whole stack of dictionaries. Also, `\undef#1` only removes a key from the top-level dictionary. There is currently not a way to remove a key from all dictionaries. Result text None. Example of usage:
    \def{num}{1}
    \push{u}
       \def{num}{2}
       \push{u}
          \def{num}{3}
          \push{u}
             \def{num}{4}
          \pop
          num is \num
       \pop
       num is \num
    \pop
    num is \num
results in
    num is 3
    num is 2
    num is 1
`\ref#2`: `\ref{<str>}{<char[ltncm]>}`
|  | Put one of the fields associated with the label `<str>` in place. The second argument is a single character identifying the field to retrieve. Use l for the level field, t for the type field, n for the number field, c for the caption field, and m for the misc field. Result text The stored field if the label is found, some funny string otherwise.
`\refload#6`: `\refload{<a>}{<l>}{<t>}{<n>}{<c>}{<m>}`
|  | Associates several fields with an anchor for later retrieval using `\ref#2`. Here `<a>`, `<l>`, `<t>`, `<n>`, `<c>`, and `<m>` stand for anchor, level, type, number, caption, and misc respectively. For a section, the fields other than the anchor field could for example be `3`, `Section`, `6.2.1`, `How to peel potatoes`, `this field not used`. This primitive is clearly meant to support index and table of content macros. Result text None.
`\roman#1`: `\roman{<<int>>}`
|  | Puts the corresponding letter in place, e.g. `\roman{1999}` results in `mcmxcix`. Used in the itemize environment defined in the generic package. Use `\ucase#1` to obtain capitals.
`\set#2`: `\set{<key-sig>}{<any>}`
|  | As `\def#2` above, except that `\set#2` will not complain if the key labeled by `<key-sig>` already exists. Result text None.
`\setx#2`: `\setx{<key-sig>}{<<any>>}`
|  | The second argument is expanded and stored in the key `<key-name>`. Besides simply storing the expansion of an expression, it can also be used to do trickier things as
       \def{bar}{klaas}
       \setx{foo#2}{\bar says \1 and \2}
       \foo{x}{y}
       klaas says x and y
If you need lambda-like capabilities, take note that you can use `\!k` or `\!{\k}` to construct a positional parameter `\k`, if you want to interpolate arguments into a key that will later take other arguments. Like this:
       \: is there any use for this wacky stuff?
       \def{lambda#2}{\setx{\1#1}{\2 says \!1}}
       \lambda{foo}{bar}
       \foo{moo}
       bar says moo
Take care: the `\dofile#2` key outputs to the default output file. If you need to include the contents of a file within a `\setx#2` call, you need to use `\finsert#1` or `\zinsert#1` in conjunction with `\setx#2`. Result text None.
`\special#1`: `\special{<vararg>}`
|  | `<vararg>` must have an even number of arguments. These are interpreted as pairs. The first of each pair must enclose an integer in the range 0-258. The first 256 integers in this range are interpreted as character indices according to the ASCII (American Standard Code for Information Interchange) standard. The characters indexed 256, 257, and 258 correspond with the zoem glyphs `\~`, `\|`, and `\-` respectively. The second element in each pair defines the string to which the character specified by the first element must be mapped. This string is interpreted in device scope. See the zzello world and Device scope sections for simple uses. A key may occur multiple times. The corresponding definitions are stacked away and will be accessed according to the current special level (cf. the section on mapped characters in device scope). Repeated use of `\special#1` does not cause the removal of previous definitions, with one exception: If `\special#1` is invoked with no arguments at all then all definitions are removed. Result text None.
`\switch#2`: `\switch{<<pivot>>}{<vararg>}`
|  | The first argument is expanded. Subsequently, two arguments are successively taken from `<vararg>`. The first is expanded and string compared with `<pivot>`. If they match, the second argument is expanded and everything else is ignored. If they do not match, the procedure is repeated. If no (odd) argument matches, and the `<vararg>` has an odd number of arguments, the last argument is put in place. It can be considered a failure clause. This primitive does not have fall-through behaviour; at most one branch will be handed to the parser. Result text Either the first block associated with a matching case of `<pivot>`, the failure clause, or nothing at all.
`\system#3`: `\system{<cmd>}{<<args>>}{<<data>>}`
|  | By default this primitive is disallowed. The first argument is the name of a system command. The environment variable PATH is used in tracing the location of the command. If `<data>` is non-empty, it is first unprotected, that is, escaped backslashes and curlies are unescaped. The resulting text is then fed to command `<cmd>` with arguments `<args>`. The latter, if non-empty, must be specified as a vararg, even if only a single argument is present. Should execution of the command (be it with or without data) result in output on STDOUT then the latter is captured, backslashes and curlies are escaped (i.e. the output is protected), and the result is put in place. STDERR is the same as it is for the parent (zoem). NOTE the security implications of this feature. By default zoem will ignore `\system`. The command line option `--unsafe` will cause zoem to prompt for user confirmation (if prompting is not possible it will ignore again) for each encountered `\system` invocation. The option `--unsafe-silent` will silently allow all `\system` invocations. The option `--allow=cmd[:cmd]*` explicitly specifies which commands to allow silently. It is also possible to use this option repeatedly rather than separate different commands by colons. If the zoem command line option `--system-honor` is used, zoem will exit if a system command fails or is ignored. A simple exit status is written in the variable `\__sysval__`: it is zero (`0`) on success, and one (`1`) on failure. Refer to the manual page of the zoem interpreter for more information on `--unsafe`, `--unsafe-silent`, `--allow=`, and `--system-honor`. Built-in macros `\system#2` and `system#1` exist. The former drops the `<data>` argument, the latter also drops the `<args>` argument. Example
    \system{sort}{{-n}}{\finsert{foo}}
    \system{ls}{{-l}{-a}}
    \system{date}
Result text The output captured (and then protected) from `<cmd>`'s STDOUT, if any.
`\table#5`: `\table{<<row length>>}{<any1>}{<any2>}{<any3>}{<<vararg>>}`
|  | The first argument is expanded and interpreted as an integer, say `k`. Successively, vectors of `k` elements are shifted from `<vararg>`. Each vector is bordered on the left with `<any1>`, bordered on the right with `<any3>`, and all elements in the vector are separated with `<any2>`. This primitive is perhaps not really needed as its functionality is largely covered by `\apply#2`. Result text The blocks from `<vararg>` interspersed in a table-like manner with `<any1>`, `<any2>`, and `<any3>`.
`\throw#2`: `\throw{<towel|error>}{<<any>>}`
|  | Quit parsing, unwind stacks until some occurrence of `\catch#2` or `\try#1` captures this throw. `<any>` is digested; if it has positive length the result is issued as error message. Result text None, affects the result text of the embedding scopes.
`\tr#4`: `\tr{<[cds]*>}{<<list1>>}{<<list2>>}{<<any>>}`
|  | If no modifiers (one or more of `[cds]`) are specified, map characters from `<any>` which are in `<list1>` to the corresponding character in `<list2>`. `<list1>` and `<list2>` may contain ranges of characters such as `a-z` and `0-9`, but syntactically the two lists must be identical, i.e. the combination {1a-z}{A-Z0} is illegal. There is one exception, namely `<list1>` is allowed to be longer than `<list2>`. The characters for which no mapping is specified will be deleted. An example of legal use would be {A-Z #@$%}{a-z_} which maps uppercase to lowercase, space to underscore, and removes some ugly characters. Characters can be specified using octal notation, e.g. `\012` encodes the newline. Use `\173` for the opening curly, `\175` for the closing curly, and `\134` for the backslash. DON'T use `\\`, `\{`, or `\}` in this case! The `s` modifier squashes translated sequences consisting of the same character repeated into one occurrence of that character. The `d` modifier simply deletes all entries in `<list1>` found in `<any>`. The `c` modifier only works in conjunction with one of the other two modifiers. It means that the complement is taken of `<list1>`. When using this in conjunction with `s`, `<list2>` must have at least one character and only the first character is considered. Result text The expanded `<any>` subjected to the `tr` operator as specified.
`\trace#1`: `\trace{<<int>>}`
|  | The argument is expanded and interpreted as an integer. This integer encodes an ensemble of flags controlling the trace output. The different modes are exactly the same as those that can be set from the command line. Refer to the corresponding section for more information. Special values are `0` (switch off all tracing), `-1` (switch on all tracing modes in short mode), `-2` (switch on all tracing modes in long mode), `-3` (switch to the previous tracing value), and `-4` emit a listing of tracing bits. The third can be useful to switch tracing on for a short while and then off again if you need to debug your document. Additionally and redundantly, `\trace#1` puts the previous tracing value in place. Result text The previous tracing value.
`\try#1`: `\try{<any>}`
|  | This will process the content and output is written in the macro `\__zoemput__`. Output will be truncated in case `\throw#2` was used or an error occurred. The status, currently one of `ok`, `towel`, or `error`, is written in the session macro `\__zoemstat__`. Result text None.
`\ucase#1`: `\ucase{<<any>>}`
|  | Translates `a-z` to `A-Z` in (the expansion of) `<any>`. This is a special case of `\tr#4` Result text The translated text.
`\undef#1`: `\undef{<key-sig>}`
|  | Deletes the key with signature `<key-sig>` from the top level dictionary. Complains (but does not fail) if the key does not exist in that dictionary. Result text None.
`\vanish#1`: `\vanish{<any>}`
|  | This will only process the content for its side effects. Any result text is disregarded. This allows easy free-style commenting of sequences of definitions. By comparison, `\formatted#1` provides the means to give a formatted presentation of the definitions themselves. Result text None.
`\while#2`: `\while{<condition>}{<any>}`
|  | While `<condition>` exands to something that is nonzero when interpreted as an integer, `<any>` is expanded and concatenated to the result text. The following piece of zoem asks the user for an integer and writes all Fibonacci numbers smaller than that integer plus one extra to STDOUT.
    \def{fib#1}{
       \ctrset{a}{1}
       \ctrset{b}{1}
       \ctrset{c}{0}
       \while{\eqt{lq}{\ctrput{c}}{\1}}{
          \ctrset{c}{\ctrput{a}}
          \ctrset{a}{\"+"{\ctrput{a}}{\ctrput{b}}}
          \write{-}{txt}{\ctrput{c}\|}
          \ctrset{b}{\ctrset{c}}
       }
    }

    \write{-}{txt}{Enter a number please, }
    \write{-}{txt}{then press <cr> and <ctl-d>\|}
    \setx{num}{\finsert{-}}    \:  this reads from STDIN.
    \fib{\num}
Note The strings built up by `\while#2` are internally concatenated until it is done, so the result from `\while#2` can be captured. This will make `\while#2` work for `\setx#2`. If you want to output 100M worth of lines or paragraphs in a while loop, embed the stuff to be output in a `\write#3` call, and make sure that no whitespace results from the loop (for example by using `\formatted#1`). Result text Whatever is built up in the while loop.
`\write#3`: `\write{<<file name>>}{<str>}{<<any>>}`
|  | The first argument is expanded and used as a file name. It is a fatal error if the file has either not been opened by a previous `\write#3` call or cannot be opened for writing. Two special file names or 'streams' are recognized, namely `-` and `stderr`. They map to `STDOUT` and `STDERR`. The third argument is expanded, filtered, and written to file. The second argument indicates the filter to be used. It must be one of the (literal) strings `copy`, `device`, or `txt`. The `copy` filter does not filter anything at all (neither plain scope nor device scope) and does not touch any of the zoem escape sequences remaining after expansion. The `device` filter does a full-fledged filtering of both parse scopes. It respects the settings according to the `\special#1` primitive. The write primitive associates unique metadata with each file it opens, so at directives such as `\N`, `\W`, and `\+` for different output files do not interfere with one another. Refer to the Device scope section for more information on at directives. The `txt` filter maps `\\` to `\` (i.e. a single backslash), `\~` to a single space, `\-` to a single hyphen, `\,` (the atomic separator) to nil, `\|` to a newline, `\{` to `{`, and `\}` to `}`. It copies everything else verbatim. Result text Technically none, as the output of `\write#3` cannot be captured.
`\writeto#1`: `\writeto{<<file-name>>}`
|  | Closes the current default output stream, and changes it to point to file `<file name>`. Useful when splitting a document into chapters, or god forbid, nodes. Note Zoem will recognize if `\writeto#1` is issued more than once for the same file `<file-name>`. On the first occassion, it will simply open the file and truncate any previous contents. On the second occasion and onwards, it will append to the file. There is currently no option to vary this behaviour. Result text None.
`\zinsert#1`: `\zinsert{<<file name>>}`
|  | The contents of file `<file name>` are put in place unaltered enclosed by the `\!#1` delay primitive. The contents must necessarily satisfy zoem syntax. If the file can not be opened, the empty string results. See also `\finsert#1`. Example
    \setx{foo}{\zinsert{mydata}}
    \setx{foo}{\eval{\zinsert{mydata}}}
In the first case, `\foo` will contain the exact contents of file `mydata`. Those contents are first enclosed within the `\!#1` primitive by `\zinsert#1`. The resulting text is evaluated by `\setx#2` - the only thing this does is strip the enclosing `\!{}` scope. In the second case, `\foo` will contain the evaluated contents of file `mydata`, as `\eval#1` adds an additional layer of evaluation. Result text The contents of file `file name` or the empty string if file can not be opened.

## 10 The zoem manual macros

This section contains a manual page for the fictitious buzzz utility. Several things are shown, including references to options and sections that show up as hyperlinks in html, while resulting in normal text in troff. This requires some authoring discipline, as one has to write the text such that it makes sense in the absence of hyperlinks. This section contains the following subsections:

10.1 |  | An example zoem manual page
10.2 |  | What it looks like in html
10.3 |  | What it looks like as PostScript generated from troff
10.4 |  | Full fledged manual pages and FAQ

The last section has several links to the full-fledged mcl manual page and the mcl FAQ.

### 10.1 An example zoem manual page

The buzzz manual page is shipped with the zoem source, as are the manual macros. They are in the files respectively named `buzzz.azm` and `man.zmm`.

    \def{"man::synstyle"}{long}
    \def{"man::defstyle"}{long}
    \import{man.zmm}

    \: customized command for the synopsis section.
    \def{fileopt#2}{\bf{\1} (\it{\2})}

    \set{"man::year"}{2002}
    \set{"man::month"}{Feb}
    \set{"man::day"}{4}
    \set{"man::name"}{buzzz}
    \set{"man::html-title"}{What's the buzzz}
    \set{"man::author"}{Stijn van Dongen}
    \set{"man::section"}{1}
    \set{"man::tag"}{1.00}

    \"man::preamble"
    \${html}{\"man::maketoc"}

    \def{buzzz}{\bf{buzzz}}

    \sec{name}{NAME}
    \NAME{buzzz}{go buzzz.}

    \: the NAME macro makes the output apropos compatible under troff.

    \sec{synopsis}{SYNOPSIS}
       \par
       \buzzz
          \synreqopt{-l}{i}{loudness}
          \synreqopt{-d}{f}{duration}
          \synoptopt{-f}{f}{frequency}
          \synoptopt{--dragonfly}{dragon style}
          \synoptopt{--bumblebee}{bumble style}
          \synoptopt{--disk}{computer style}
          \synoptopt{-style}{some style}
          \synoptopt{--scan}{scan mode}
          \synoptopt{-sd}{i}{scan duration}
          \fileopt{<file.bzz|dir>}{tune source}

    \sec{description}{DESCRIPTION}

    \par
       \buzzz buzzes. It can do so in different styles, at different base
       frequencies, and at different volumes. See the \secref{options} section
       for a description of all options.

    \par
       The \optref{-l}{\genopt{-l}{loudness}} and
       \optref{-d}{\genopt{-d}{duration}} options
       are both mandatory. The last argument given must be a file containing
       the tune to buzz, or a directory containing such tune files.
       The tune must be contained in an interval of at most
       five tones. Non-conforming tunes may damage your soundcard.

    \sec{options}{OPTIONS}

    \begin{itemize}

       \item{\defopt{-f}{f}{frequency}}
          Frequency in Hertz, can be specified as a positive real number.

       \item{\defopt{-l}{i}{loudness}}
          Loudness, which is specified as an integer inbetween 0 and 100.

       \item{\defopt{-d}{f}{duration}}
          Duration in hours, can be specified as a positive real.

       \intermezzo{
          The following options are discussed as a group:
       }

       \items{
          {\defopt{--dragonfly}{dragon style}}
          {\defopt{--bumblebee}{bumble style}}
          {\defopt{--disk}{computer style}}
          {\defopt{--mosquito}{sting style}}
       }
          These are unary options specifying the style in which to buzz.

       \item{\defopt{-style}{str}{buzz style}}
          \genarg{str} should be one of \v{bumblebee}, \v{dragonfly},
          \v{mosquito}, or \v{disk}.

       \item{\defopt{--scan}{scan mode}}
          This will buzz 10 seconds for each tune specified.
          Refer also to the \optref{-sd}{\genopt{-sd} option}.

       \item{\defopt{-sd}{i}{scan duration}}
          Sets the scan time in (an integer number of) seconds. This affects the
          \optref{--scan}{\genopt{--scan} option}.
    \end{itemize}

    \sec{files}{FILES}
    \par
       /etc/zoem/foriamzoem.bzz contains the zoem jingle.\|
       /etc/zoem/zoem.ascii-art contains zoem related ascii art.
       An excerpt is shown below.

    \verbatim{
    .-----------------------------.
    |                             |
    |                  _ " _      |
    |     (\\"/)       (_\\|/_)     |
    |     (/|\\)       (_/|\\_)     |
    |       |            |        |
    |             ()     |        |
    |          -----%             |
    |             ()              |
    |                          ejm|
    .-----------------------------.
    }

    \sec{environment}{ENVIRONMENT}
    \par
       Currently, no environmental issues with \buzzz.

    \sec{diagnostics}{DIAGNOSTICS}
    \par
       If the tune spans an interval larger than 5 tones, buzzz will
       emit little beeps. If the interval exceeds an octave, buzzz
       will fork and exec \bf{bell}.

    \sec{bugs}{BUGS}
    \par
       Some do.

    \sec{author}{AUTHOR}
    \par
       Bugs Bunny.

    \sec{history}{HISTORY}
    \par
       repeats itself, especially from a buzzing point of view.
       Refer to \publref{foobar} for an in-depth analysis.
       A different point of view is presented in \publref{barfoo}.

    \sec{seealso}{SEE ALSO}

    \par
       The \sibref{bell}{bell(1) manual}.
    \${html}{This reference is not going anywhere; it just demonstrates
    a way of implementing references to other utilities. Troff can not link anyway,
    so this warning is strictly html.}

    \${html}{\par
    On the www it is difficult to show a manual page as compiled for rendering in a
    terminal, but one can view a manual page as compiled for rendering by a
    postscript interpreter.
    Lo and behold \httpref{buzzz.ps}.}

    \par
       \aref{http://www.google.com/search?hl=en&amp;q=zoem+macro}{http://www.google.com/search?hl=en&q=zoem+macro} .
       \: zoem has no good provision for url encoding, alas.
       \: zoem also provides \httpref#1, which prints and links to a URL.
       \: in this case it would fail, because of the '&' character.

    \par
       \publanch{foobar}
       Bugs Bunny. Foo Bar.
       A history of making, maintenance, repair, and disposal.

    \par
       \publanch{barfoo}
       Donald Duck. The futile mistake, and how it changes my life every day.

    \"man::postamble"

### 10.2 What it looks like in html

4 Feb 2002 buzzz 1.00

1. |  | NAME
2. |  | SYNOPSIS
3. |  | DESCRIPTION
4. |  | OPTIONS
5. |  | FILES
6. |  | ENVIRONMENT
7. |  | DIAGNOSTICS
8. |  | BUGS
9. |  | AUTHOR
10. |  | HISTORY
11. |  | SEE ALSO

## NAME

buzzz - go buzzz.

## SYNOPSIS

buzzz -l i (loudness) -d f (duration) [-f f (frequency)] [--dragonfly (dragon style)] [--bumblebee (bumble style)] [--disk (computer style)] [-style (some style)] [--scan (scan mode)] [-sd i (scan duration)] <file.bzz|dir> (tune source)

## DESCRIPTION

buzzz buzzes. It can do so in different styles, at different base frequencies, and at different volumes. See the OPTIONS section for a description of all options.

The -l loudness and -d duration options are both mandatory. The last argument given must be a file containing the tune to buzz, or a directory containing such tune files. The tune must be contained in an interval of at most five tones. Non-conforming tunes may damage your soundcard.

## OPTIONS

-f f (frequency)
|  | Frequency in Hertz, can be specified as a positive real number.
-l i (loudness)
|  | Loudness, which is specified as an integer inbetween 0 and 100.
-d f (duration)
|  | Duration in hours, can be specified as a positive real.
The following options are discussed as a group:
--dragonfly (dragon style)
--bumblebee (bumble style)
--disk (computer style)
--mosquito (sting style)
|  | These are unary options specifying the style in which to buzz.
-style str (buzz style)
|  | str should be one of `bumblebee`, `dragonfly`, `mosquito`, or `disk`.
--scan (scan mode)
|  | This will buzz 10 seconds for each tune specified. Refer also to the -sd option.
-sd i (scan duration)
|  | Sets the scan time in (an integer number of) seconds. This affects the --scan option.

## FILES

/etc/zoem/foriamzoem.bzz contains the zoem jingle.
/etc/zoem/zoem.ascii-art contains zoem related ascii art. An excerpt is shown below.

    .-----------------------------.
    |                             |
    |                  _ " _      |
    |     (\"/)       (_\|/_)     |
    |     (/|\)       (_/|\_)     |
    |       |            |        |
    |             ()     |        |
    |          -----%             |
    |             ()              |
    |                          ejm|
    .-----------------------------.

## ENVIRONMENT

Currently, no environmental issues with buzzz.

## DIAGNOSTICS

If the tune spans an interval larger than 5 tones, buzzz will emit little beeps. If the interval exceeds an octave, buzzz will fork and exec bell.

## BUGS

Some do.

## AUTHOR

Bugs Bunny.

## HISTORY

repeats itself, especially from a buzzing point of view. Refer to [1] for an in-depth analysis. A different point of view is presented in [2].

## SEE ALSO

The bell(1) manual. This reference is not going anywhere; it just demonstrates a way of implementing references to other utilities. Troff can not link anyway, so this warning is strictly html.

On the www it is difficult to show a manual page as compiled for rendering in a terminal, but one can view a manual page as compiled for rendering by a postscript interpreter. Lo and behold buzzz.ps.

http://www.google.com/search?hl=en&q=zoem+macro .

[1] Bugs Bunny. Foo Bar. A history of making, maintenance, repair, and disposal.

[2] Donald Duck. The futile mistake, and how it changes my life every day.

### 10.3 What it looks like as PostScript generated from troff

A link to the PostScript version of the manual page was provided in the buzzz document itself and here is another one. Note that this PostScript was compiled by groff from the troff output that was compiled by zoem from the zoem input.

### 10.4 Full fledged manual pages and FAQ

The example from the previous sections is not so impressive as the manual page is a bit skinny. A full fledged (and not necessarily impressive) manual page written in zoem is for example the mcl manual page. If you like, have a look at

mcl.azm |  | The source for the manual.
mcx.zmm |  | A resource file used by mcl and its sibling applications.
mcl.html |  | The html generated from the source by zoem.
mcl.1 |  | The troff generated from the source by zoem.
mcl.ps |  | The PostScript generated from mcl.1 by groff.
mcl.txt |  | The text version generated from mcl.1 by groff.
mclfaq.azm |  | The source for the mcl FAQ.
mclfaq.html |  | The html generated by zoem.
mclfaq.ps |  | The PostScript generated by groff from the zoem troff output.

## 11 Pitfalls

This is a young section, with only few entries yet.

* |  | [`\system#3`] Beware that the argument/option list (the second argument of `\system#3`) is encoded as a vararg. If you have a single argument, it is easy to forget the enclosing curlies. In that case, zoem ignores the argument altogether. Zoem protects the data returned by `\system#3`. So you may e.g. think (as I once did) that
    \system{date}{{%e}{%B}{%Y}}
Is a neat way to create a vararg, but you will end up with something like
    \{24\}\{April\}\{2004\}
* |  | [Package authors] Beware of using and scope within at scope within a `\write#3` invocation that uses the copy filter.
    \write{file}{copy}{ foo \\@{ zut \\&{ bar }}}
The `bar` part will not be evaluated as the copy filter does not apply the filtering stage. If the stuff written is read back in from some other part of the document, or from another document alltogether, the `bar` part will be evaluated in a different context than the one in which it was created.

## 12 Glossary

For user keys, dollar keys, and dictionary stacks, refer to the Dictionary stacks section and the Macro expansion section. For grape keys, refer to the Tree data section.

For key signatures and key mention, refer to the Key signatures section. For anonymous keys: the Anonymous keys section.

Session variables are described in the Session keys section.

For varargs, arguments in which a variable number of sub-arguments can be stored, and for blocks: the Of blocks and varargs section.

For plain scope, device scope, at scope, and glyph sequences: The Scope dichotomy and Device scope sections.

For file read and inline files: the File read section.

Sometimes zoem protects or unprotects data. Refer to the Protection section.