The command \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. Eg, 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
file, which is inserted into the document. This
auxiliary file can be used by TeX too, so 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
(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 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 "\\space")))
}} \endhtmlonly
Note that \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.)
The code inside \eval
uses not just general Scheme
but also procedures like
ungroup
and get-token
, which are defined by
TeX2page. Furthermore, subsequent \eval
s can
use definitions introduced in previous \eval
s,
as with all-blanks?
in our example.
\eval
without regard to HTMLThe key thing to remember is that
an \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.
There are however some concerns with the use of \eval
as a
mainstream TeX command. The way we have described it,
\eval
inserts text generated by the Scheme code
of TeX2page, so a document containing \eval
must not only \input tex2page.tex
but also be
processable by TeX2page. This would be too stringent a
requirement if \eval
is to be usable in TeX
documents that are not intended for HTML at all, and
that may fail to be processable by TeX2page for reasons
unrelated to \eval
. Fortunately, this requirement
isn't necessary: Generic TeX documents that cannot be
converted by TeX2page can still make use of the
\eval
feature. For the use of \eval
in its
full generality, please see the companion manual,
An \eval
for
TeX.