9  Scheme as TeX's extension language

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 \evals can use definitions introduced in previous \evals, as with all-blanks? in our example.

9.1  \eval without regard to HTML

The 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.