\eval allows you to use arbitrary
Scheme expressions, as opposed to just TeX macros, to
guide the course of the typesetter. The text written
to standard output by the Scheme code is substituted
for the \eval statement. E.g., consider the
following complete document, root2.tex:
\input tex2page
The square root of 2 is
\eval{
(display (sqrt 2))
}. \bye
Running TeX2page on root2.tex produces
the following HTML output:
The square root of 2 is 1.4142135623730951.
In effect, TeX2page processes the \eval call
using Scheme, producing some output in an auxiliary
TeX file, which is then re-inserted into the document at the location of
the \eval.
A definition for \eval that TeX can use
is provided in the macro file eval4tex.tex, which is available in
the eval4tex [42] distribution.
tex2page.tex will automatically load eval4tex.tex if it finds it in
TEXINPUTS.
Thus, running TeX on
root2.tex produces a DVI file whose
content matches the HTML version.
It is clear that Scheme code via \eval can serve as
a very powerful second extension language for
TeX, and that its benefits are available to both the
DVI and the HTML outputs. As we have seen, TeX2page
implements a subset of the TeX macro language, and for
those cases where this macro language isn’t enough,
Scheme can be used to fill the breach. More generally,
Scheme may be preferable to the TeX macro language even
for just DVI, where no HTML version of the document is
contemplated. We’ll explore both of these
aspects of \eval.
Let us 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 Scheme operator by presenting a prototypical
use of it.
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
(I.e., 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 Scheme:
\ifx\shipout\UnDeFiNeD
\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 "\\space")))
}} \endhtmlonly \fi
\eval’s argument is a balanced-brace
expression that is sent verbatim to Scheme, except that the pipe character
(‘|’) functions as the TeX escape. Use || to represent a single
pipe in the Scheme code. If you need to include an unmatched brace, simply
put a bogus matching brace inside a Scheme comment.
Later \evals can
use definitions introduced in previous \evals,
as with all-blanks? in our example.
If being processed by TeX2page only (as in our example),
the code inside \eval is allowed to use not just general Scheme
but also procedures like
ungroup and get-token, which are defined by
TeX2page.
\eval-call is replaced by whatever text the
Scheme code in that \eval-call writes to its
standard output. This approach will work whether the
document is being processed by TeX2page to produce HTML
or by TeX to produce DVI.
For those TeX documents that are not intended for HTML conversion, but
nevertheless use \eval, this macro is available in the macro file
eval4tex.tex. Run TeX (or LaTeX) on such a document, say
jobname.tex, and then evaluate
the resultant jobname.eval4tex in Scheme, to create the
necessary aux TeX files. Running TeX on the master document a second
time will
insert these aux TeX files at the location of the corresponding \eval
calls. This is quite analogous to how TeX2page would have processed the
\evals, except that TeX requires you to explicitly call Scheme to
create the aux files which it can use on its second run, whereas
TeX2page, being written in Scheme, creates and loads the aux files
immediately.
For complete details on using \eval with
TeX, please consult the companion manual,
An \eval for
TeX [42].