The command \eval allows you to use arbitrary
Scheme
expressions, as opposed to just TeX macros, to guide
the course of the typesetter. Note that by typesetter
we mean both TeX (which produces DVI output) and
TeX2page (which produces HTML output).
Since there are two outputs to distinguish, we cannot
get by with just one standard output port in the Scheme
code introduced by \eval. So, we will use the
regular standard output port for \eval's TeX output
(which eventually becomes DVI), and the port *html*
for \eval's TeX2page output (which eventually
becomes part of the final HTML). We can use this
feature to play to a medium-selected gallery.
\eval{ (display "Paper beats screen.") (newline) (display "Screen beats paper." *html*) (newline *html*) }
\eval allows the document writer access to full
Scheme, including the Scheme definitions inside the
TeX2page implementation. This serves as a very
powerful second extension language. The
first extension language is the TeX macro
language, or rather, TeX2page's implementation of
a subset of the TeX macro language.
Note that the extensions possible through \eval
and Scheme are not restricted to the HTML output
only. The print output is equally maneuverable via
Scheme.
Indeed, we can use \eval to
introduce new functionality that is used consistently
in both the browsable and printable outputs.
But first we will first look at a simple example where
\eval lets you define an HTML version of an
already existing TeX macro that is either impossible
or at least prohibitively difficult to process using
TeX2page's mimicry of TeX. Consider a
hypothetical \proto macro, used to introduce the
description of a Lisp operator by giving a prototypical call. Typical calls to \proto are:
\proto{cons}{a d}{procedure}
\proto{car}{c}{procedure}
\proto{cdr}{c}{procedure}
which typeset as follows:
(cons a d) ;procedure
(car c) ;procedure
(cdr c) ;procedure
The macro \proto takes three arguments: the
operator name; the metavariables for its operands;
and the operator kind. In particular, it typesets
the operator and the operands in different fonts,
surrounding the call in parens. Note the
intervening space between operator and operands.
In the case where there are no operands, the intervening space should not. Thus,
\proto{gentemp}{}{procedure}
should not produce
(gentemp ) ;procedure
but rather
(gentemp) ;procedure
(Ie, no space between gentemp and the
closing paren.)
The \proto macro can be written
in TeX as follows:
\def\proto#1#2#3{\noindent
\hbox{{\tt(#1}\spaceifnotempty{#2}{\it#2}{\tt)}%
\qquad ;#3}\par}
where, \spaceifnotempty is a helper macro
that expands to a space only if its argument is
not empty. TeX2page can expand this definition
for \proto, provided it knows how to deal
with the \spaceifnotempty.
One way to write \spaceifnotempty in TeX
is:
\newdimen\templen
\newbox\tempbox
\def\spaceifnotempty#1{%
\setbox\tempbox\hbox{#1}%
\templen\wd\tempbox
\ifdim\templen>0pt{\ }\fi}
This piece of box-measuring contortion is too much for TeX2page's mimicry of the TeX macro system. However it's easy enough to achieve the same effect using the string-processing capabilities of TeX2page's extension language, Scheme:
\htmlonly \eval{ (define all-blanks? (lambda (s) (andmap char-whitespace? (string->list s)))) } \def\spaceifnotempty{\eval{ (let ((x (ungroup (get-token)))) (if (not (all-blanks? x)) (display " " *html*))) }} \endhtmlonly
\eval's argument is a balanced-brace
expression that can contain any character at all,
including %. (If you need to include an unmatched
brace in \eval's argument, simply
put a bogus matching brace inside a Scheme comment.)