3  SLaTeX’s control sequences

You’ve already seen the SLaTeX control sequence \scheme and the environment {schemedisplay}.1 These suffice for quite a few instances of handling code. However, you will occasionally require more control on the typesetting process. To help you in such situations, here is a complete list of SLaTeX control sequences with examples. These include commands for manipulating output positioning, enhancing the database, changing the fonting defaults, adding special symbols, and selective disabling of SLaTeX.

{schemedisplay}

Typesets the enclosed code, which is typically several lines of code indented as is common in Scheme files. Eg,

\begin{schemedisplay} 
(define compose 
  ;this is also known as $B$ 
  (lambda (f g) 
    (lambda (x) 
      (apply f (g x))))) 
\end{schemedisplay} 
is the ``compose'' function. 

produces

(define compose
  ;this is also known as B
  (lambda (f g)
    (lambda (x)
      (apply f (g x)))))

is the “compose” function.

As with all LaTeX environment enders, if the line after \end{schemedisplay} contains non-whitespace text, the paragraph continues. Otherwise — ie, when \end{schemedisplay} is followed by at least one blank line — a fresh paragraph is started. Similarly, in plain TeX, a fresh paragraph is started after a {schemedisplay} only if \endschemedisplay is followed by at least one blank line.

Comments in Scheme are usually introduced by “;” (semicolon). The rest of the line after a “;” is set in paragraph mode.

Separate blocks of code can either be introduced in different {schemedisplay} environments or put in a single {schemedisplay} and separated by a line with a “;” in the first column. This “;” is not typeset and anything following it on the line is set in paragraph mode. Consecutive lines with “;” in the first column are treated as input for a TeX paragraph, with words possibly moved around from line to line to ensure justification. When in paragraph mode, the first line that has no leading “;” signals a fresh block of Scheme code within the {schemedisplay}. (The {schemedisplay} may end, or commence, on either a paragraph or a Scheme code block.)

Eg,

\begin{schemedisplay} 
(define even? 
  ;testing evenness 
  (lambda (n) 
    (if (= n 0) #t 
        (not (odd? (- n 1)))) 
  )) 
; The procedures {\it even?\/} 
; above and {\it odd?\/} below 
; are mutually recursive. 
(define odd? 
  ;testing oddness 
  (lambda (n) 
    (if (= n 0) #f 
        (not (even? (- n 1)))) 
  )) 
\end{schemedisplay} 

produces

(define even?
  ;testing evenness
  (lambda (n)
    (if (= n 0) #t
        (not (odd? (- n 1))))
  ))
 The procedures  even?
 above and  odd? below
 are mutually recursive.
(define odd?
  ;testing oddness
  (lambda (n)
    (if (= n 0) #f
        (not (even? (- n 1))))
  ))

SLaTeX can recognize that blocks of code are separate if you have at least one empty line separating them. Ie, there is no need for empty “;” lines. This convenience is to accommodate Scheme files where definitions are usually separated by one or more blank lines.

Intervening paragraphs, either with lines with a leading “;”, or with blank lines, are ideal spots for {schemedisplay} to allow pagebreaks. In fact, the default setting for {schemedisplay} also allows pagebreaks within a Scheme block, but it is easy to disable this (see entry for \rightcodeskip).

The space surrounding displayed Scheme code can be modified by setting the skips \abovecodeskip, \belowcodeskip, \leftcodeskip, and \rightcodeskip (qv).

Note: see {schemeregion}.

{schemeresponse}

This is like {schemedisplay}, except that the code is displayed as the output of a Scheme evaluation, ie, as data. In other words, keyword and variable fonts are disabled.

Note: see \schemeresult and {schemeresponsebox}.

\scheme

Typesets its argument, which is enclosed in arbitrary but identical non-alphabetic and non-{ characters, as in-text code. Special case: \scheme{...} is a convenience (provided the ‘...’ doesn’t contain a ‘}’). Eg, \scheme|(call/cc (lambda (x) x))| and \scheme{(call/cc (lambda (x) x))} both produce (call/cc (lambda (x) x)).

It is permitted to intermix calls to {schemedisplay} and \scheme. Thus,

\begin{schemedisplay} 
(define factorial 
  (lambda (n) 
    (if (= n 0) 
        ;\scheme{(zero? n)} 
        ;also possible 
        1 (* n (factorial 
                 (- n 1)))))) 
    ;or \scheme{... (sub1 1)} 
\end{schemedisplay} 

produces

(define factorial
  (lambda (n)
    (if (= n 0)
        ;(zero? n)
        ;also possible
        1 (* n (factorial
                 (- n 1))))))
   ;or ... (sub1 1)

Note: see {schemeregion}.

\schemeresult

Typesets its argument, which is enclosed in arbitrary but identical non-alphabetic and non-{ characters, as in-text Scheme “result” or data: ie, keyword and variable fonts are disabled. Special convenient case (as for \scheme): \schemeresult{...}. Eg,

\scheme|((lambda () (cons 'lambda 
'cons)))| yields 
\schemeresult|(lambda . cons)|. 

produces

((lambda () (cons 'lambda 'cons))) yields (lambda . cons).

{schemebox}

The {schemebox} environment is similar to {schemedisplay} except that the code is provided as a “box” (ie, it is not “displayed” in the standard way). Indeed, when the appropriate skip parameters are set, {schemedisplay} itself may2 use a {schemebox} to create a box of code that is set off with all-round space as a display.

Saving a {schemebox} in an explicit box allows you to move your typeset code arbitrarily.

Note: see {schemeregion}.

{schemeresponsebox}

This is like {schemebox}, except that the contents are displayed as Scheme data. See also \schemeresult and {schemeresponse}.

\schemeinput

This can be used to input Scheme files as typeset code. (Unlike (La)TeX’s \input, \schemeinput’s argument must always be grouped.) The Scheme file can be specified either by its full name, or without its extension, if the latter is .scm, .ss or .s. Eg,

\schemeinput{evenodd.scm} 
% the .scm is optional! 

(where evenodd.scm is the name of a Scheme file containing the code for even? and odd? above) produces the same effect as the {schemedisplay} version.

Note: see {schemeregion}.

{schemeregion}

Calls to \scheme, \schemeresult, {schemedisplay}, {schemebox} or \schemeinput can be nested in (a Scheme comment) of other calls. In (La)TeX source, they can occur in bodies of environments or be otherwise grouped. However, they cannot normally be passed as arguments to macros or included in bodies of macro definitions (even though these are complete calls and not parameterized with respect to macro arguments). To be able to do these things, you should first cordon off such a text with the {schemeregion} environment. SLaTeX is fairly generous about where exactly you throw the cordon.

Eg, you cannot have

... 
The code fragment $\underline 
{\hbox{\scheme{(call/cc I)}}}$ is ... 
... 

but you can have

\begin{schemeregion} 
... 
The code fragment $\underline 
{\hbox{\scheme{(call/cc I)}}}$ is ... 
... 
\end{schemeregion} 

and this will produce

...

The code fragment (call/cc I) is ...

...

Thus, the {schemeregion} environment makes it possible to put SLaTeX-specific commands inside macro arguments or macro definitions without causing rupture. Normally, this can’t be done since once SLaTeX is done preprocessing your text, all SLaTeX-specific commands correspond to comment-like regions — the actual typeset code is in an external, temporary file. These comment regions share the characteristic of LaTeX’s verbatim regions, which also can’t appear in macro arguments or definitions.

To solve this, you enclose the offending text in a {schemeregion} environment. This “inlines” all the the enclosed calls to SLaTeX as actual typeset code instead of treating such calls as comment regions — thus escaping the fate described above. A {schemeregion} is a perfect no-op as far as the enclosed non-SLaTeX commands are concerned.

However, while a {schemeregion} allows its enclosed SLaTeX commands to be included in macro arguments and bodies, it itself cannot be so included. This is because {schemeregion} is now a super-comment. The solution is simple: just pull the {schemeregion} cordon as outward as possible so that all the SLaTeX calls that you need treated specially are enclosed. A safe approach is to call {schemeregion} at the “top level”, ie, outside any nesting of groups — it does not hurt that the cordon is too wide. Indeed, you may even wrap each of your TeX files in one huge {schemeregion} if you so wish. This will cover any obscure “non-robust”3 use of the SLaTeX primitives — the only downside is that SLaTeX may run slower.

Note: TeX files that are loaded using \input from within a {schemeregion} will not automatically inherit the robust lifestyle. A SLaTeX command is made robust only by an enclosing {schemeregion} in the same file as itself. In other words, region markers have textual or “lexical” scope, not “dynamic” scope.

\setkeyword

\setconstant

\setvariable

\setdata

SLaTeX has a database containing information about which code tokens are to be treated as keywords, which as constants, which as variables, and which as data. However, it is very likely that you will want to add your own tokens to these categories. The control sequences that enable you to do this are \setkeyword, \setconstant, \setvariable, and \setdata. Their arguments are entered as a (space-separated) list enclosed in braces ({}): SLaTeX learns that these are henceforth to be typeset in the appropriate category. Eg,

\setconstant{infinity -infinity} 

tells SLaTeX that infinity and ‑infinity are to be typeset as constants.

The user need not use \setkeyword to specify such new keywords as are introduced by Scheme’s and Common Lisp’s syntactic definition facilities (define‑syntax/syntax‑rules, defmacro, extend‑syntax, define‑macro!.) SLaTeX automatically recognizes new macros and auxiliary keywords defined using these facilities.

In addition, quoted material is recognized as “constant”, and strings, numbers, booleans and characters are recognized as “data” without the need to identify them with \setconstant and \setdata respectively.

\setspecialsymbol

\unsetspecialsymbol

These commands are useful to generate “mathematical”-looking typeset versions of your code, over and beyond the fonting capabilities provided by default. Although your program code is naturally restricted to using ascii identifiers that follow some convention, the corresponding typeset code could be more mnemonic and utilize the full suite of mathematical and other symbols provided by TeX. This of course should not require you to interfere with your code itself, which should run in its ascii representation. It is only the typeset version that has the new look. For instance, you might want all occurrences of lambda, and, equiv?, below?, above?, a1 and a2 in your code to be typeset as [slatxdoc-Z-G-D-1.png], [slatxdoc-Z-G-D-2.png], [slatxdoc-Z-G-D-5.png], [slatxdoc-Z-G-D-3.png], [slatxdoc-Z-G-D-4.png], a1 and a2 respectively. To do this, you should \setspecialsymbol the concerned identifier to the desired TeX expansion, viz.,

\setspecialsymbol{lambda}{$\lambda$} 
\setspecialsymbol{and}{$\land$} 
\setspecialsymbol{equiv?}{$\equiv$} 
\setspecialsymbol{below?}{$\subseteq$} 
\setspecialsymbol{above?}{$\supseteq$} 
\setspecialsymbol{a1}{$a_1$} 
\setspecialsymbol{a2}{$a_2$} 

Now, typing

\begin{schemedisplay} 
(define equiv? 
  (lambda (a1 a2) 
    (and (below? a1 a2) 
         (above? a1 a2)))) 
\end{schemedisplay} 

produces

(define [slatxdoc-Z-G-D-5.png]
  ([slatxdoc-Z-G-D-1.png] (a1 a2)
    ([slatxdoc-Z-G-D-2.png] ([slatxdoc-Z-G-D-3.png] a1 a2)
         ([slatxdoc-Z-G-D-4.png] a1 a2))))

Note that with the above settings, lambda and and have lost their default keyword status, ie, they will not be typed boldface. To retrieve the original status of special symbols, you should use \unsetspecialsymbol, eg,

\unsetspecialsymbol{lambda and} 

lambda and

Typing the same program after unsetting the special symbols as above produces, as expected:

(define [slatxdoc-Z-G-D-5.png]
  ([slatxdoc-Z-G-D-1.png] (a1 a2)
    ([slatxdoc-Z-G-D-2.png] ([slatxdoc-Z-G-D-3.png] a1 a2) 
         ([slatxdoc-Z-G-D-4.png] a1 a2))))

In effect, \setspecialsymbol extends the basic “fonting” capability to arbitrarily special typeset versions.

\schemecasesensitive

SLaTeX always typesets output that is of the same case as your input, regardless of the setting of the \schemecasesensitive command. However, this command can be used to signal to SLaTeX that all case variations of an identifier are to be treated identically. Eg, typing \schemecasesensitive{false} ensures that Lambda, LAMBDA and LaMbDa will all be treated as keywords, just as lambda. \schemecasesensitive{true} reverts to the default mode where case is significant in determining the class of a token.

Note that the status \schemecasesensitive also affects the “special symbols” of the previous item. Thus, in the default case-sensitive setting, only the case-significant symbol as mentioned in the call to \setspecialsymbol will be replaced by the corresponding TeX expansion. In a case-insensitive setting, all case variations of the special symbol will be replaced.

\abovecodeskip

\belowcodeskip

\leftcodeskip

\rightcodeskip

These are the parameters used by {schemedisplay} for positioning displayed code. The default values are

\abovecodeskip \medskipamount 
\belowcodeskip \medskipamount 
\leftcodeskip 0pt 
\rightcodeskip 0pt 

This produces a flushleft display. The defaults can be changed to get new display styles. Eg, this manual sets

\leftcodeskip\parindent 

which shifts the display from the left by the same amount as a paragraph indentation.

In both the above cases, the {schemedisplay} environment will be broken naturally across page boundaries at the right spot if the code is too long to fit a single page. In fact, automatic pagebreaks within the Scheme code are allowed if and only if \rightcodeskip is 0pt (its default value). For all other values of \rightcodeskip, each Scheme code block in a {schemedisplay} is guaranteed to be on the same page. If you have decided on a left indentation, and you’re not sure what value to give to \rightcodeskip, but nevertheless don’t want Scheme code broken across pages, you could set

\rightcodeskip=0.01pt %or 
\rightcodeskip=0pt plus 1fil 

To understand why this would disable pagebreaks within the Scheme block, suppose instead you’d set

\leftcodeskip=0pt plus 1fil 
\rightcodeskip=0pt plus 1fil 

This will get you a centered display style. This is of course because the skip on each side of the code produces a “spring”4 that pushes the code to the center. But for this spring action to work nicely, the code must have been collected into an unbreakable box — which is precisely what {schemedisplay} does for each of its code blocks whenever it notices that the prevailing value of \rightcodeskip is not the default zero.5 Clearly, such unbreakable boxes cannot tolerate pagebreaks.

Thus, the behind-the-scenes selective boxing dictates whether a {schemedisplay} block can or cannot be broken across a page boundary. And the value of \rightcodeskip is used to govern this selection in a “reasonable” manner.

\keywordfont

\constantfont

\variablefont

\datafont

These decide the typefaces used for keywords, constants, variables, and data. The default definitions are:6

\def\keywordfont#1{{\bf#1}} 
\def\constantfont#1{{\sf#1}} 
\def\variablefont#1{{\it#1\/}} 
\let\datafont\constantfont 

This is close to the Little Schemer [23] style. Redefine these control sequences for font changes. As an extreme case, defining all of them to {{\tt#1}} typesets everything in monospace typewriter font, as, for instance, in SICP [1].

Note that “constants” and “data” can be distinguished, although by default SLaTeX does not do so. Typically, primitive data such as booleans, numbers, characters and strings are set as “data”; whereas quoted material is set as “constant”.

The control sequences \keywordfont, &c., can be defined to be anything at all, not just font switches. For instance, if you use Rokicki’s dvips, you can use these SLaTeX sequences to color-code your programs! Simply use:

\input colordvi 
\def\keywordfont#1{\Red{#1}} 
\def\variablefont#1{\Blue{#1}} 
\def\constantfont#1{\Green{#1}} 

The following example will appear in color if you’ve processed this document with dvips and have a color-capable viewer or printer:

(define factorial
  ([slatxdoc-Z-G-D-1.png] (n)
    (if (= n 0) 1
        (* n (+ n 1)))))

\defschemedisplaytoken

\defschemetoken

\defschemeboxtoken

\defschemeresulttoken

\defschemeresponsetoken

\defschemeresponseboxtoken

\defschemeinputtoken

\defschemeregiontoken

These define the tokens used by SLaTeX to trigger typesetting of in-text code, displayed code, boxed code, Scheme program files and robust regions. The default tokens are, as already described, {schemedisplay}, \scheme, {schemebox}, \schemeresult, {schemeresponse}, {schemeresponsebox}, \schemeinput and {schemeregion} respectively. You can use the \defscheme*token control sequences to get alternate tokens, eg, shorter or more mnemonic ones. Thus, if you want \code to be your new control sequence for in-text code, use \defschemetoken{code}. All instances of \code+...+ after this definition produce in-text code, unless overridden by an \undefschemetoken command.

One can have at any time any number of tokens for the same activity. One consequence of this is that one can have nested {schemeregion}s, provided one has different names for the nested call. Otherwise, the \end of an inner region will prematurely terminate an outer region.

\undefschemedisplaytoken

\undefschemetoken

\undefschemeboxtoken

\undefschemeresulttoken

\undefschemeresponsetoken

\undefschemeresponseboxtoken

\undefschemeinputtoken

\undefschemeregiontoken

These undefine the tokens used for triggering the typesetting of in-text code, displayed code, boxed code, Scheme program files, and robust regions. Typically, tokens are undefined so you can use the names for other purposes without tripping up the SLaTeX system.

\defschememathescape

\undefschememathescape

\defschememathescape{$} defines the character $ as a mathematical escape character to be used within Scheme code. (Any character other than } and whitespace may be chosen instead of $.) This allows one to use TeX mathematical subformulas within Scheme code, eg,

\defschememathescape{$} 
 
\begin{schemedisplay} 
(define $\equiv$ 
  (lambda (a$_1$ a$_2$) 
    ($\land$ 
      ($\subseteq$ a$_1$ a$_2$) 
      ($\supseteq$ a$_1$ a$_2$)))) 
\end{schemedisplay} 

produces

(define [slatxdoc-Z-G-D-5.png]
  ([slatxdoc-Z-G-D-1.png] (a1 a2)
    ([slatxdoc-Z-G-D-2.png]
      ([slatxdoc-Z-G-D-3.png] a1 a2)
      ([slatxdoc-Z-G-D-4.png] a1 a2))))

\undefschememathescape{$} disables the math-escape nature, if any, of $.

\slatexdisable

The tokens for typesetting code, as also the token \input (which is sensitive to SLaTeX, since the latter uses it to recursively process files within files), can only be used as calls. If they occur in the bodies of macro definitions, or their names are used for defining other control sequences, SLaTeX could misprocess them. Sometimes, one wants TeX to \input a file, without wanting SLaTeX to process the inputted file. Or the name \scheme can occur in a verbatim environment, and we don’t want such an occurrence to cause SLaTeX to look for and “find” Scheme code that is not really there.

Avoiding such uses altogether can be unduly restrictive.7 One way out is to judiciously employ the \undefscheme*token commands to temporarily remove the SLaTeX-specificity of these names. Even this can be painful. SLaTeX therefore provides the command \slatexdisable. This takes one argument word and makes the corresponding control sequence out of it. Further, from this point in the text, SLaTeX is disabled until the manufactured control sequence shows up. This mechanism makes it possible to restrict SLaTeX to only appropriate portions of the text. Note that the token \slatexdisable itself can appear in the text succeeding its call. The only token that can restore SLaTeX-sensitivity is the one created during the call to \slatexdisable.

The following is a typical example of the \slatexdisable approach. You want the names \scheme and \begin{schemedisplay} in a verbatim environment:

\slatexdisable{slatexenable} 
\begin{verbatim} 
SLaTeX provides the command \scheme 
and the pair \begin{schemedisplay} 
and \end{schemedisplay} to typeset 
in-text and displayed Scheme code 
respectively. 
\end{verbatim} 
\slatexenable 

produces the required

SLaTeX provides the command \scheme 
and the pair \begin{schemedisplay} 
and \end{schemedisplay} to typeset 
in-text and displayed Scheme code 
respectively. 

\slatexignorecurrentfile

This is a SLaTeX pragma included to improve efficiency. If you’re sure that the remaining portion of a certain (La)TeX file (including the files that would be \inputed by it) don’t contain any SLaTeX commands, then you may place this control sequence in it at this point to signal SLaTeX that no preprocessing is necessary for the rest of the file.

\defslatexenvstyle

As shown previously, the differences in SLaTeX usage between plain TeX and LaTeX is simply a matter of the difference in the “environment” styles of the two formats. It is easy get the behavior of the one format with the other.

1. If you wish to use the plain-TeX style in LaTeX, type

\defslatexenvstyle{tex} 

before first such use.

2. Similarly, if you wish to use the LaTeX \begin/\end style in plain TeX, use

\defslatexenvstyle{latex} 

provided you have already defined \begin and \end appropriately! One way to accomplish this is:

\def\begin#1{\begingroup 
  \csname#1\endcsname 
  \let\end\endenvironment} 
\def\endenvironment#1{% 
  \csname end#1\endcsname 
  \endgroup} 

Here, \end is defined within a group because TeX already has an \end command whose global definition is used by commands such as \bye and therefore should not be changed lightly.

In either case, you can revert to the default style with \defslatexenvstyle{latex} and \defslatexenvstyle{tex} respectively.

\slatexseparateincludes

By default, the temporary files of SLaTeX use the name of the topmost TeX file, ie, the name stored under \jobname. In large LaTeX documents using \include, this may be unduly restrictive.

To recapitulate, the slatex command creates temporary files to store typeset code and then passes the baton on to TeX or LaTeX. If no significant change has been made to the Scheme code (either in content or in relative positioning) in the document, then successive calls to (La)TeX could be made directly using the old temporary files. This could be a time-saver, since it avoids calling up the Scheme typesetter.

However, in a large LaTeX document with \includes, these successive calls to LaTeX often entail juggling the \includes that are chosen. In this case, even though the relative position of the Scheme code is preserved within each \included file, the sequence perceived by the main file changes. This spoils the invariance we needed if we’d wanted to avoid calling SLaTeX unnecessarily.

To solve this, the SLaTeX command sequence \slatexseparateincludes — which must be called before the first occurrence of Scheme code in your document — guarantees that each \included file will generate its own pool of temp files. Thus, if the SLaTeX files are created once for each \include, they will be correctly loaded no matter what sequence of \includes is taken.

\schemecodehook

The user can define \schemecodehook to be anything. The hook will be evaluated inside each subsequent call to {schemedisplay} and {schemebox}. Eg, if you have \tiny defined (as in LaTeX) to reduce font size, then

\let\schemecodehook\tiny 

converts your Scheme displays and boxes into small print.

The default value of the hook is \relax, a no-op.


1 The notation {envname} is used to denote an environment named envname. Usually, in plain TeX, this is the pair \envname and \endenvname, while in LaTeX, it is the environment formed with \begin{envname} and \end{envname}. But see \defslatexenvstyle.

2 Yes, may: Not all {schemedisplay}s invoke {schemebox}, and if you’re curious why, see entry for \rightcodeskip. It is a matter of whether pagebreaks within Scheme code are allowed or not.

3 The term “robust” is not necessarily used in the same sense as in the LaTeX manual [5].

4 Springs, or rather “glue”, are discussed in detail in The TeXbook [4, pp 70ff].

5 0pt plus 1fil [slatxdoc-Z-G-D-6.png] 0pt

6 \sf in LaTeX is the sans-serif font. Since plain TeX does not define \sf, you may define one before \inputing slatex.sty. If no \sf is found, slatex.sty has \let\sf=\rm. You may redefine it before or after to an appropriate font of your choice. This manual set \font\sf=cmss10. Of course, you could redefine \constantfont itself to not rely on (the name) \sf.

7 Especially when one is writing a “How to ...” manual like this where one both uses and mentions the control sequences!