A Proposal for TEX \special Commands and dvi Driver Paper Specification

Nelson H. F. Beebe

1 Introduction

TEX is now a de facto standard; its source code development is now frozen, with the version number converging to π as increasingly rare bugs are fixed [14]. TEX has been implemented on nearly every computer architecture commercially available today, from personal computers to supercomputers, on a wide variety of operating systems.

TEX’s principal output is a device-independent file, the dvi file, which contains a compact description of where to set characters on the page. It does not contain any descriptions of the characters themselves, only a reference to the fonts in which they are found. A few other programs besides TEX also produce dvi files.

It is the job of separate programs, known as dvi drivers, to translate this description into a form suitable for some output device, which might be a printer, a display screen, a phototypesetter, or even another dvi file.

Because a separate dvi driver is needed for each output device, and each operating system, there is the potential for an explosion in the number of auxiliary programs that may be required to obtain usable output from TEX, and regrettably, that seems to have happened.

2 The dvi driver problem

I have previously espoused the view [5] that prevention of dvi driver program proliferation is properly addressed by writing a family of drivers that supports a wide variety of output devices, sharing common source code as much as possible. The code must be highly portable, so as to work on a wide variety of operating systems. My implementation of such a family of drivers has been well-received, and many thousands of copies of the programs are in use around the world.

The last public release, version 2.10 of October 1988, consists of about 30 000 lines of code for 19 drivers, together with about 8400 lines of documentation, corresponding to about 150 typeset pages. Five major operating environments (Atari, DEC TOPS-20, DEC VAX VMS, IBM PC, and UNIX) are supported, with several different compilers. Ports have been carried out to other operating systems as well, but the changes have not been made generally available.

The widespread use of those programs has confirmed my thesis, but has also demonstrated that they have some deficiencies. This is to be expected in any software product, whether public or commercial. Even TEX has evolved from its original design.

Consequently, in the fall of 1988 I set out to redesign the driver family to remedy all of the deficiencies, to further enhance portability to new operating systems and new compilers, to make it easier to modify existing driver code to support other output devices, and to extend and enhance the documentation. The development version is known as 3.0.

This work is, alas, far from complete, and I sometimes wonder whether Don Knuth will finish Volume 4 of the Art of Computer Programming before I finish the new driver family. However, considerable progress has been made. The number of output devices and operating environments supported has more than doubled. The source code is now over 55 000 lines; for comparison, TEX and are each about 20 000 lines when prettyprinted. There are 23 500 lines of documentation, corresponding to about 400 typeset pages. The ‘manual pages’ are written in a subset of L^{A}TEX, then converted automatically to UNIX troff format, VAX VMS help file format, Emacs TEXinfo format, and a simple ASCII text file format.

3 Standardization of dvi drivers

As should be expected, the proliferation of dvi driver code written by many authors has led to considerable variation in driver interfaces and operation. While human interfaces unavoidably depend somewhat on the operating environment, one can demand that the same capabilities (e.g. page selection and order, paper sizes, page origin offset, file paths, startup-file support, …) be available in all drivers.

Operational differences are less excusable. For example, most programs, including TEX, have fixed limits arising from compile-time choices of internal storage sizes. User annoyance and frustration results when those limits are reached prematurely. Even on the same output device, slight variations in page positioning, and placement of rules and characters will be found in different drivers. Worse, some drivers may refuse to print certain dvi files, because internal limits are reached, or a particular font cannot be found.

To address these problems, a committee of the TEX Users Group was established to develop a standard for dvi drivers. Completion of a level-0 draft is imminent.

preliminary draft, 15 May 1995 16:47  preliminary draft, 15 May 1995 16:47 1002  preliminary draft, 15 May 1995 16:47  TUGboat, Volume 0 (2001), No. 0

This draft is intended to define minimal standards that all dvi drivers should adhere to. It does not address some of the thornier issues, particularly the TEX \special command, which will be covered in a higher-level draft standard yet to be prepared.

4 The TEX \special command

When TEX was first defined in 1977–78, its author realized that there would be a need for extensibility. He chose to provide this in a very simple form— an arbitrary string provided as the argument to the \special command is macro-expanded, then passed verbatim to the dvi file without further interpretation.

To guide TEX users and authors of dvi drivers, he offered this advice [13, pp. 228–229]:

The ⟨token list⟩ in a \special command should consist of a keyword followed if necessary by a space and appropriate arguments. For example,

    \special{halftone pic1}

might mean that a picture on the file pic1 should be inserted on the current page, with its reference point at the current position.

⋮ Software programs that convert dvi files to printed or display output should be able to fail gracefully when they don’t recognize your special keywords.

⋮ However, the author anticipates that certain standards for common graphics operations will emerge in the TEX user community, after careful experiments have been made by groups of people; then there will be a chance for some uniformity in the use of \special extensions. As Knuth noted, the most common use of

\special is to inform the dvi driver that a graphics file is to be inserted in the output. Many other possibilities exist, including paper specification, operator messages, grey shading, change bars, color selection, page overlays, and output device control.

With very few exceptions, existing drivers, including my own 2.10 version, have adopted ad hoc syntax for the \special string. The result is that the dvi file is no longer device-independent; it depends both on the output device, and on the particular driver that is expected to process it.

5 Improving the handling of \special commands

In the 3.0 dvi driver development, I had to solve the \special problem. This section will describe how, and why, I did so.

While the complete source code for the 3.0 drivers will not be released for some time, the part described in this article for \special strings and paper specifications is complete, and I am making it available immediately, and without any restrictions whatsoever, to authors of dvi drivers for incorporation in their programs.

The source code is written in ANSI C [4]. C is already used for many dvi driver programs; for drivers that are not written in C, it should be considerably easier to start with this code and reprogram it in some other modern language, such as Pascal or Modula-2, than to redevelop equivalent code from scratch.

The previous section observed that most existing drivers have chosen an arbitrary syntax for the \special strings they support. This is undesirable, for at least these reasons:

• The chosen syntax is mostly unique to a particular driver, and therefore seriously compromises document portability.

• The syntax is not obviously extensible.

• The syntax cannot always be unambiguously parsed.

• The output device, or driver, to which the \special applies is not determinable.

• The capabilities are weak, and fail to address many of the potential uses of the \special command. The syntax that I have developed completely resolves these objections. It has the following features:

• The \special command string is defined to contain a program written in a small language that consists of sequences of assignment statements, possibly with embedded comments.

• The \special language is rigorously defined by a programming language grammar, based on the C language grammar [4, 10]. Correct parsers for the language can be developed using any of several standard methods that are wellknown in computer science [2, 3, 11, 18] and the UNIX world [12, 15]. Implementations of some of these are available from several sources, and for several operating systems [1, 6, 7, 11, 16, 17].

• The language is extensible. An assignment statement consists of a keyword/value pair.

Several keywords are already defined, and new ones can be added without invalidating existing uses of the language.

• Keywords are typed, and constant values assigned to them must be of the same type. The supported types are scalar strings, numbers, and dimensions. The latter include all of TEX’s standard dimensional units.

• There is no limit (other than host memory) on the length of a constant string.

• Value string concatenation is supported in the style of ANSI C [4], avoiding the often severe line length limitations of text editors, operating systems, and file systems.

• Provision is made for encoding all characters in the host character set, so that, e.g. binary printer control sequences can be incorporated as printable, and portable, text in TEX documents.

• A particular keyword, language, is provided to permit the user to specify the output device language, or the dvi driver, to which the \special command is directed.

• The language is general enough that it can be used for other purposes. In my 3.0 dvi driver software, the complex issue of paper specification is handled by the same language, and importantly, by the same parser that is used for

\special strings.

In the actual implementation of the parser, I chose not to use one of the above-cited parser generators. There are two important reasons for this.

• Parser generators convert a grammar file to an output program that is impossible to modify by hand. Portability and extensions of the drivers would be compromised if part of their source code could only be generated on certain systems, or with proprietary software.

• Parser generators encode the language keywords into the parser code, usually in incomprehensible forms; examine the parsing tables in a yacc-generated parser [12] to see why. By suitable abstractions, it has proven possi-

ble to create a recursive-descent parser [2, 3] for the language in which the keywords and value storage locations are provided in a table passed to the parser. The parser code is therefore completely portable, and independent of the keywords in the language it parses. The same code is used for both the \special command strings, and for paper specification.

6 A proposed syntax for the \special command

The preceding section has described the motivation for a new approach to the definition of a \special language. What does the language look like? Some examples will give the general flavor before we describe the details of the grammar. Here are some fragments of TEX input with \special commands intended for a dvi driver that produces PostScript; each of these works with dvialw in the version 3.0 development.

                                          % Display a picture with the
                                          % upper-left corner at the current
                                          % point
                                          \special{language "PostScript",
                                                   include "pict.eps"}
                                          % Display a picture at its original
                                          % absolute page position
                                          \special{language "PostScript",
                                                   overlay "pict.eps"}
                                          % Use literal PostScript to draw a
                                          % 1in box with lower-left corner at
                                          % TeX's current point
                                          \special{language "PostScript",
                                            literal
                                              "newpath
                                                  % move origin from upper-left
                                                  % to lower-left
                                                  0 -72 translate
                                                  0 0 moveto
                                                  0 72 rlineto
                                                  72 0 rlineto
                                                  0 -72 rlineto
                                                  -72 0 rlineto
                                              closepath
                                              4 setlinewidth
                                              stroke
                                              showpage"}
                                          % Display a figure at half size
                                          \special{language "PostScript",
                                            literal "0.5 0.5 scale",
                                            include "pict.eps"}
                                          % Display the figure in landscape
                                          % mode by rotating the coordinates
                                          % about the center of the bounding
                                          % box
                                          \special{language "PostScript",
                                            literal
                                             "BoxWidth 2 div

BoxHeight 2 div translate
90 rotate
BoxWidth -2 div
BoxHeight -2 div translate",
include "pict.eps"}

Naturally, the details of a \special command invocation should be hidden away in suitable macros that are easy to use. Here are some examples from a recent document illustrating the incorporation by dvialw of PostScript figures from a variety of sources:

\newcommand{\FIGPLOT}[4]{%
% Arg 1 = EPS file to plot
% Arg 2 = figure caption
% Arg 3 = width in inches
% Arg 4 = height in inches
\begin{figure}[htb]
\Figrule\smallskip
\begin{center}
\setlength{\unitlength}{1.0in}
\begin{picture}(#3,#4)(0,0)%
\put(0,0){\special{
language "PostScript",
position "bottom left",
literal
"/SX {#3 72 mul BoxWidth div} def
/SY {#4 72 mul BoxHeight div} def
1 SX sub BoxLLX mul
1 SY sub BoxLLY
mul translate
SX SY scale",
include "#1"}}%
\put(0,0){\circle*{0.5}}%
\put(0,0){\dashbox{0.1}%
(#3,#4)[t]{}}%
\end{picture}%
\end{center}
\caption{\tolerance=6000
\emergencystretch=3pt
#2
File: {\tt #1}.
Picture size: #3in wide by
#4in high.}
\label{#1}
\smallskip\Figrule
\end{figure}
}
\newcommand{\Figrule}{\hrule
width \linewidth
height 2pt
depth 2pt \relax}

\FIGPLOT{roseart.ps}{Adobe Illustrator
                    1.0b2 rose art
                    (scaled 1:2)}
        {3.4861}{4.625}
\FIGPLOT{golfart.ps}{Test of golfart
                    scaling
                    (scaled $1:2$).}
        {3.95833}{4.82639}
\FIGPLOT{tiger.ps}{A bitmapped image.}
        {4.5}{3.0107}

The literal string makes use of PostScript macros output by dvialw to define the posi-

tion (BoxLLX, BoxLLY, BoxURX, and BoxURY) and

size (BoxHeight and BoxWidth) of the bounding box. The current page position is also available as (CurrentX, CurrentY), and the paper size as

PaperHeight and PaperWidth. All of these are in

standard PostScript units of big points. These quantities are needed to support things like figure transformations, landscape mode, change bars, and grey shading.

If a \special contains both a literal and an include or overlay statement, then the literal string is output before the inserted file. Should the reverse order be required, then the literal string must be specified in a separate following \special.

Finally, here are some examples of the same language, now used to parse paper specifications. The first is a command-line, or startup-file, switch which provides a paper program as the switch value:

-paper:{paper="letter";width=8.5in;
        height=11in;dev_init="...";}

In a startup file, such options can be written more clearly:

-paper:
{
  % standard US paper size
  paper = "letter";
  width = 8.5in;
  height = 11in;
  % printer origin is off by 0.05in
  x_origin = 1.05in;
  y_origin = 1in;
  % printer wraps coordinates, so
  % we need clipping turned on
  x_clip = 1;
  y_clip = 1;

% not all of page is imageable
x_left = 0.3in;
x_right = 0.3in;
y_top = 0.5in;
y_bottom = 0.5in;
% print pages from last to first
output_order = -1;
% adjacent strings are concatenated
dev_init = "...."
"...."
"....";
% final formfeed and printer reset
dev_term = "\f\033E";
page_init = "....";
page_term = "....";
}
-paper=
{
paper         = "ALW-note";
use           = "letter";
x_left        = 0.41in;
x_right       = 0.41in;
y_top         = 0.42in;
y_bottom      = 0.42in;
}

The last example illustrates a feature of the paper specification language; the use keyword references a paper type defined elsewhere whose specifications are copied into the internal data structures for the new type before the new values are installed. This makes it easy to prepare modifications of base forms. For example, most laser printers use the same size paper, but differ in the imageable area and output stacking order. The example above defines a paper type known to the Apple LaserWriter in terms of a standard paper type.

Comments are from percent to end-of-line (like TEX), and letter case is not significant in variable names. Whitespace is ignored, so the specification can be formatted for readability, or for compactness.

Dimensions can be given in any unit known to TEX (bp cc cm dd in mm pc pt sp).

The presence of a left brace following the paper switch signals that a forms definition follows; otherwise, the following token is a paper name. To facilitate collection of the complete specification at a higher level without having to parse it in detail when the switch and its value are collected, braces must be balanced; escape sequences and comments provide ways to ensure this.

7 The language grammar

The grammar for the language is based on the C programming language grammar given in Appendix B of [10], with changes affecting hexadecimal escape sequences in strings, and concatenation of adjacent strings, as specified in the ANSI C standard [4].

Adjacent string concatenation is a convenient way of working around limitations on line length when long strings are needed, and adding support for it took only four lines of code. Hexadecimal escape sequences of arbitrary length permit transparent support for character sizes larger than 8 bits. Octal escape sequences remain limited to 3 digits for backward compatibility; hexadecimal escape sequences are new with ANSI C.

In the following grammar, the suffix -opt means that the item is optional. For brevity, numeric constants are not specified in grammatical form here. They are parsed by the ANSI C library routine, strtod(), which expects numbers in the form ([ ] marks optional fields, {|} marks alternatives):

[whitespace][sign][digits][. digits]
  [{e|E}[sign]digits]

Except in quoted strings, tokens may not contain embedded blanks. Thus, 210mm is legal input, but 210␣mm is not.

Here is the grammar, in standard Backus-Naur form:

program:
  statement
statement:
  assignment-statement
  compound-statement
  null-statement
assignment-statement:
  name = constant
  name : constant
  name   constant
compound-statement:
  { statement-list-opt }
null-statement:
  ,
  ;
statement-list:
  statement
  statement ; statement-list
  statement , statement-list

constant:
dimension-constant
float-constant
string-constant
name
dimension-constant:
float-constant dimension-unit
dimension-unit: one of
bp cc cm dd in mm pc pt sp
string-constant:
simple-string-constant
string-constant simple-string-constant
simple-string-constant:
" character-sequence-opt "
' raw-character-sequence-opt '
character-sequence:
character
character-sequence character
raw-character-sequence:
raw-character
raw-character-sequence character
character:
printing-character
escape-character
raw-character:
printing-character
\'
printing-character: one of
(note that " and \ are omitted,
and ' may be specified by \'
as well)
<space> !   # $ % &   ( ) * + , -
. / 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z [   ] ^_
` a b c d e f g h i j k l m
n o p q r s t u v w x y z { | } ~
escape-character:
\ escape-code
escape-code:
character-escape-code
octal-escape-code

                                              hexadecimal-escape-code
                                            character-escape-code:
                                              a b f n r t v \ ' "
                                            octal-escape-code:
                                              octal-digit
                                              octal-digit octal-digit
                                              octal-digit octal-digit octal-digit
                                            hexadecimal-escape-code:
                                             x hexadecimal-digit
                                             hexadecimal-escape-code hexadecimal-digit
                                            octal-digit: one of
                                              0 1 2 3 4 5 6 7
                                            hexadecimal-digit: one of
                                              0 1 2 3 4 5 6 7 8 9
                                              A B C D E F
                                              a b c d e f
                                            name:
                                              letter
                                              letter extended-letter-sequence
                                            extended-letter-sequence:
                                              extended-letter
                                              extended-letter-sequence extended-letter
                                            letter: one of alphabetic or
                                              underscore characters
                                              A B C D E F G H I J K L M
                                              N O P Q R S T U V W X Y Z
                                              a b c d e f g h i j k l m
                                              n o p q r s t u v w x y z
                                              _
                                            extended-letter:
                                              0 1 2 3 4 5 6 7 8 9
                                              A B C D E F G H I J K L M
                                              N O P Q R S T U V W X Y Z
                                              a b c d e f g h i j k l m
                                              n o p q r s t u v w x y z
                                              - . _

For readers unfamiliar with programming language grammars, a short explanation is in order. The beginning rules

                                            program:
                                              statement
                                            statement:
                                              assignment-statement

compound-statement
null-statement

say that a program is a statement, and that a

statement is either an assignment-statement, or
a compound-statement, or a null-statement. Fur-

ther rules in turn define what each of these are. The last rule says that an extended-letter is a digit, letter, hyphen, dot, or underscore.

The characters permitted in extended-letter are chosen

• to avoid conflict with characters otherwise significant in the grammar, and

• to cover the most common filename syntax, so as to allow unquoted simple filenames to be collected as single constant name tokens for assignments. This grammar supports two kinds of quoted

strings. The normal kind is delimited by double quotes, and inside it are recognized all the escape sequences supported by the C language. The raw kind is delimited by single quotes; only escape-single-quote pairs are recognized inside it. This is more convenient when it is necessary to have strings with several backslashes, since it then avoids having to double all of them. Once normal and raw strings are parsed, they are stored identically.

German TEX styles often change the syntax of the quotation mark to add an umlaut accent to the following character; users of such styles can happily use the raw string form to avoid conflict.

Backslashes in literal strings and filenames pose a small problem for the user, because TEX will ordinarily try to interpret control sequences triggered by backslashes in the argument of the \special command.

For filenames, IBM PC DOS is the only operating system that normally would use backslashes, and then only as a directory separators. In most cases, you should omit directory paths anyway, and rely instead on the DVIINPUTS search path to let the drivers find the files at run time; doing so will enhance document portability. If you still wish to use a directory path in the \special command, you can exploit an unadvertised feature of PC DOS; namely, system calls accept forward slashes as equivalent to backslashes, so you can use forward slashes instead. This is normally not possible with PC DOS commands that accept filenames on the command line, because their simplistic parsing confuses such names with option switches.

Literal strings are therefore likely to be the only place where backslashes may be unavoidable. Although it would have been possible to choose another escape character than backslash for such strings, this would likely prove confusing to those users who are used to C and UNIX, where the backslash escape character is firmly entrenched.

Fortunately, the solution is not difficult, because TEX does not have backslash hardcoded as a control sequence prefix; you can change it by altering TEX’s catcodes. Thus instead of writing something like

\special{literal = "\033[I"}

which would raise a TEX Undefined control sequence error, you can instead write

{
  \catcode`\@=0
  \catcode`\\=12
  @special{literal = "\033[I"}
}

This changes the TEX control sequence prefix from backslash to at-sign, and gives backslash a meaning that will not cause problems. The surrounding braces ensure that the changes disappear when the braced group is exited. The catcodes are of course ugly magic numbers, so if you do this more than once, you should hide them in a macro with a more meaningful name, and use that macro in place of the first two lines in the group.

The grammar supports statement separators (rather than terminators), and they may be either commas or semicolons. In a simple language, it is convenient to allow both kinds of separators. Since there is a null statement, the separator is optional after the last statement in a sequence.

Drivers will supply an implicit brace pair surrounding the \special string retrieved from the dvi file, to ensure that multi-statement text looks like the compound statement required by the grammar.

Finally, note that the assignment statement may use either the equals or colon operator, or the operator may be omitted altogether. This supports the common forms

keyword = value
keyword : value
keyword   value

Because the values have very limited syntactical possibilities, there is no ambiguity created by this.

8 The \special language

The preceding section defined the grammar for the \special language. We now need to define what keywords will be recognized. As emphasized above, the language is extensible, and the parser that I have implemented for it makes it very easy to add new keywords without touching a single line of the parser code itself. For example, only a short specification like

{
{"include", 7},
(symbol_value*)&spec.include,
T_STRING
},

needs to be added to a table to define a new keyword, together with a small amount of code to do something with the value returned by the parser for that keyword.

The current set of keywords recognized is given in the following table:

Keyword Value Action

boundingbox string Define the coordinates of the lower-left and upper-right corners of the box which bounds the figure input by an include or overlay command.

graphics string Execute the generic graphics primitives in string (not yet defined).

include filename Insert file contents with relative page positioning.

language string Name the outputdevice language for which this \special is intended.

literal string Insert literal output

device code.

message string Supply an operator message to be sent to the terminal and log file.

options string Not yet defined.

overlay filename Insert file contents with absolute page positioning.

position string Specify the reference point on an inserted figure which is to be mapped to the current page position.

In a series of assignment statements, the order of the keywords is not significant, except that if duplicate keywords are specified, the value of the last one is used. It is not necessary to supply a final newline in the strings or files; one will be provided implicitly to ensure correct parsing.

The graphics keyword value is intended to be used to support a simple generic graphics language, yet to be defined. Such a language would make it possible to obtain simple line graphics on virtually any output device.

The options keyword value could be used to supply device-dependent information; no particular values have yet been defined in my 3.0 dvi driver code.

The message string provides a means for operator communication; for example,

message "Thesis bond paper for this job"

The message is sent verbatim to the terminal and the log file.

The position keyword specifies a string that should contain two blank-separated words. The first should be one of top, middle, or bottom, and the second should be one of left, center, or right. These words may be abbreviated to a single letter if desired. Together, they select on the bounding box one of nine points (four corners, four edge centers, and the box center) which is to be placed at the TEX current point. If this keyword is not given, the default is

position = "top left"

The point selected by this keyword (or by default) will be the reference point for the insertion of graphics files.

The following remarks are particular to Post-Script devices, but the possible generalizations to others should be evident.

Literal PostScript code from a file or a literal string is expected to be well-behaved, and preferably, should conform to Adobe’s Encapsulated Post-Script File format version 2.0 or later [9], and to Adobe’s PostScript Document Structuring Conventions, version 2.0 or later [8]. It may contain a showpage, which is disabled temporarily by the dvi driver during the execution of the \special strings, but it should not contain any of these operators:

 banddevice   initgraphics  setdevice
 copypage     initmatrix    setmatrix
 erasepage    note          setpageparams
 exitserver   nulldevice    setsccbatch
 framedevice  quit          setscreen
 grestoreall  renderbands   settransfer

 initclip

If it does, erroneous output is virtually certain. While these commands could be disabled like showpage is, Adobe’s Encapsulated PostScript guidelines do not recommend doing so.

The imported PostScript should write into its own dictionary if it needs to define objects. Because dictionary sizes must be specified when they are created, it is not possible to define a standard one in advance in the macros that mark the start and end of the imported PostScript (called SB and SE in dvialw) to protect from corruption of the dictionary used by the dvi driver.

The language keyword should specify "PS" or "PostScript"; letter case does not matter. If any other non-empty value is found, the \special command is ignored by a PostScript driver, since it presumably applies to some other output device. However, if no language keyword is given, the driver assumes it should process the rest of the \special command.

Files specified by include and overlay keywords are searched for in the DVIINPUTS path.

In the common include filename case, the upper-left corner of the PostScript bounding box will be placed at the current point. The PostScript file must then contain (usually near the start) a comment of the form

%%BoundingBox: llx lly urx ury

specifying the bounding box lower-left and upperright coordinates in standard PostScript units (big points, 1bp = 1/72 inch).

Alternatively, if the comment

%%BoundingBox: (atend)

is found in the file, the last 4096 characters of the file will be searched to find a bounding box comment that specifies the coordinates of the two corners. The last such comment found is the one used; this requirement permits correct handling of inserted files that themselves contain nested Post-Script files.

In the overlay filename case, the PostScript file to be included will be mapped onto the page at precisely the coordinates it specifies, where the page origin is in the lower-left corner, x increasing to the right, and y increasing upward. Any %%BoundingBox specification is ignored, since it is not required for positioning. This option might be used to print an overlay page. For actions that are to be done on every page, such as printing a logo, or

a string like Draft or Company Confidential, it is

more efficient to redefine the PostScript showpage command instead.

If the PostScript file cannot be opened, or the \special command string cannot be recognized, or for relative positioning, the bounding box cannot be determined, a warning message is issued and the \special command is ignored.

Numerous drivers already support \special command strings of the form include filename; this parser will recognize them.

A key point here is the language keyword. If it is not given, the dvi driver must assume that the \special command is intended for it, and attempt to process it. Thus,

                                              \special{include tiger.eps}

will be handled as before. However, when the language keyword is found, then its value determines whether the dvi driver will process the \special, or ignore it.

Every dvi driver must recognize a generic language choice relevant to its output device, such as PostScript or Epson. In addition, each driver must recognize its own name as a language value.

The reason for this requirement is as follows. When startup files are supported, their names are derived from the driver names. In my 3.0 dvi driver code, a driver named dvialw will search for startup files named dvialw.ini in a list of standard places. The default behavior of a particular driver can be changed merely by storing a copy of its executable program under a different name, and providing a corresponding startup file. Typically, this would be done to provide easy-to-use variants of a basic driver for different paper types, or different page orientations. If the user wishes to incorporate driverspecific \special strings, permitting the language value to be the driver name provides that flexibility. Existing mini-languages for graphics, such as eepic, epic, tpic, and xpic, are properly handled using the graphics and language keywords together:

                                              \special{language = "tpic",
                                                       graphics = "..."}

The dvi Driver Standards Committee has debated whether drivers should issue warning messages about \special commands that they are unable to process. In the absence of the language keyword, I believe that such warnings are desirable, although the driver should provide an option to suppress such warnings.

However, when a language value is found, it is important that the driver silently ignore ones that it is not prepared to process. The presence of that value is sufficient evidence to conclude that the user intends it to be ignored by some drivers, and certainly does not want those drivers to complain about it.

I expect that with more powerful, and standardized, \special command support of the type described in this paper, use of \specials will increase. Consider, for example, a document that makes heavy use of color or grey-scale requests via \special commands; there could be hundreds, or even thousands, of them in a document of modest size. Were the driver to issue warnings for all of them, the terminal output or log file would be flooded with mostly useless warning messages that obscure much more important information. The language value provides a standard means to prevent this.

9 Paper specification

Paper handling and specification is a complex issue, and may require future extensions. Thus, it is desirable to have a flexible means of specifying paper characteristics, and a reasonable scheme seems to be to use a small extensible language to define it. The assignment-statement language whose grammar was presented above is suitable for this purpose.

Some examples of the paper specifications supported by my 3.0 dvi driver work were given earlier. Here, we define the keywords recognized.

Keyword  Type  Description
dev_init  string  initiate device use

of paper

dev_term string terminate device

use of paper

height  dimension paper height

output_order number negative for print-

ing last to first

paper  string  paper form name
use  string  name of copied

paper form

width  dimension paper width

x_clip number clip in x direction

if non-zero

x_left dimension width of left un-

printable margin

x_right dimension width of right un-

printable margin

x_origin dimension horizontal offset of

TEX (0,0) point

y_bottom dimension width of bottom

unprintable margin

y_clip number clip in y direction

if non-zero

y_origin dimension vertical offset of

TEX (0,0) point

y_top dimension width of top un-

printable margin

The paper keyword defines a name that is used to tag the collected parameters. If the form name already exists, assignments will replace previous values. Otherwise, a new form is created.

The use keyword names an existing form whose parameters are to be copied to a new one named by the paper keyword in the same program. This copying happens before any of the other keyword assignments are done. The order of the statements in the program does not matter, because the results of the assignments are collected in a temporary form before copying to the specified form. Recursive forms references are supported; just don’t make them circular! The use keyword should normally be employed to make private modifications of standard forms types.

Some printers misbehave if they are presented with data that are off the page, or too close to the margins; for example, the Hewlett-Packard Laser-Jet wraps such coordinates horizontally. For such devices, the x_clip and y_clip values should be set non-zero.

Few printers place the (0,0) origin exactly in the upper-left page corner; instead, they have it slightly offset at some other point, which we call (x_origin,y_origin). The standard L^{A}TEX file, testpage.tex, can be used to determine the correct settings of these values. If you print its typeset output, the upper-left corner of the inner frame should be exactly one inch from the page edges. Suppose you actually find that that corner lies 0.75in from the left edge, and 1.1in from the top edge. This means the printer’s (0,0) point is to the left, and just below, the upper-left corner. Setting x_origin =

-0.25in and y_origin = 0.1in will compensate,

so the next time you print the test page, the inner frame should be correctly positioned.

Most printers are incapable of printing very close to the edges of the physical page; the mar-

gin values x_left, x_right, y_bottom, and y_top

should be set to indicate the relevant limits. Sometimes these values can be found in the printer documentation. However, if the physical paper position relative to the printing mechanism is adjustable, as it is for most dot-matrix printers, you may have to experiment. If you print the testpage.tex typeset output, the tick marks in the four margins will usually not print near the paper edges; use them as a guide to setting reasonable values for the margin values.

dvi drivers that require a page bitmap will allocate memory corresponding to the paper surface inside of these margins. Wide margin settings can therefore reduce the amount of memory required; that in turn can reduce the number of bitmap strips that must be processed for high-resolution printers, speeding the output.

The standard TEX and L^{A}TEX macro packages are parametrized to assume that the TEX (0,0) point will be exactly one inch in from the left, and one inch down from the top. They also usually assume American paper sizes. Text widths and heights are then chosen to ensure identical top and bottom margins, and except for two-sided printing styles, identical left and right margins. While the dvi driver -x and -y command line options can be used to adjust the output position, it is usually better to do so by setting paper parameters.

For example, ISO A4 paper is 210mm (8.2677in) wide; TEX macro packages assume 6.5in text width with 1in left and right margins. To center that text on A4 paper, the 1in margins need to be reduced by (8.5 - 8.2677)/2 = 0.1161in, so we could put x_origin = +0.1161in. Similarly, the A4 height of 297mm (11.6929in) exceeds the 11in U. S. paper height, and requires adding (11.6929 - 11.0)/2 = 0.3465in to the top and bottom margins. That can be accomplished by setting y_origin = -0.3465in. Of course, if you already have non-zero values of these parameters, you will have to adjust them accordingly; just add the above offsets to the existing values.

If you routinely use non-American paper sizes, then you probably should be using a style file modification that accounts for the different page dimensions, rather than fiddling with paper positioning on your output device.

The output_order value should be set negative if you want pages printed from last to first. This provides an alternate to the -backwards command line option, but affects only the paper forms types it is defined for. If output_order is negative, the dvi drivers will simply flip the current setting of the backwards-printing switch, which may have already been set from the command line.

If the printer needs to receive some magic codes to select an alternate paper type (e.g. some highspeed laser printers support multiple input paper trays), it will be necessary for the dvi driver to write them into the output file. The dev_init and dev_term strings provide for this. The dvi drivers output the initialization string at the start of the job, and the termination string at the end. These are output verbatim with nothing added, not even a newline.

For example, if you are using the PostScript driver, dvialw, on a system that does not have a PostScript printer spooler, you might want the end of the file to have the PostScript serial line job terminator character, Ctl-D. You could arrange that by setting

                                              dev_term = "\004";

in a paper program.

The DVI drivers already know how to initialize and terminate their output devices under normal conditions, so you should rarely need to specify

                                              dev_init and dev_term values.

References

[1] Abraxas Software, Inc. PCYACC 2.0, 1987. 7033 SW Macadam Ave., Portland, OR 97219.

[2] Alfred V. Aho, Ravi Sethi, and Jeffrey D. Ullman. Compilers—Principles, Techniques, and Tools. Addison-Wesley, 1986.

[3] Alfred V. Aho and Jeffrey D. Ullman. Principles of Compiler Design. Addison-Wesley, 1977. See also the much expanded subsequent book [2].

[4] American National Standards Institute, 1430 Broadway, New York, N. Y., 10018. American National Standard Programming Language C, ANSI X3.159-1989, December 14 1989.

[5] Nelson H. F. Beebe. Public domain TEX DVI driver family. TUGboat, 8(1):41, April 1987.

[6] Charles Donnelly and Richard M. Stallman. Bison—the yacc-compatible parser generator. Technical report, Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, Tel:

(617) 876-3296, 1988. Bison was largely written by Robert Corbett, and made yacc-com-patible by Richard Stallman. Electronic mail: rms@prep.ai.mit.edu. Software also available via ANONYMOUS FTP to prep.ai.mit.edu. See also [17].

[7] Robert W. Gray. γ-GLA—a generator for lexical analyzers that programmers can use. In Summer USENIX ’88, pages 147–160, June 20– 24 1988.

[8] PostScript Developer Support Group. Document Structuring Conventions specification, version 2.1. Technical Report PN LPS5001, Adobe Systems Incorporated, 1585 Charleston Road, P. O. Box 7900, Mountain View, CA 94039-7900, USA, Tel: (415) 961-4400, January 16 1989. Available electroni-

                                                  cally from ps-file-server@adobe.com in re-

sponse to an e-mail request send Documents

                                                  struct.ps.Zba. The request send Index will

return a complete index for the server.

[9] PostScript Developer Support Group. Encapsulated PostScript Files specification version 2.0. Technical Report PN LPS5002, Adobe Systems Incorporated, 1585 Charleston Road, P. O. Box 7900, Mountain View, CA 94039-7900, USA, Tel: (415) 961-4400, June 5 1989. Available electronically from

ps-file-server@adobe.com in response to an
e-mail request send Documents EPSF.ps.Zba.

The request send Index will return a complete index for the server.

[10] Samuel P. Harbison and Guy L. Steele Jr. C— A Reference Manual. Prentice-Hall, second edition, 1987.

[11] Allen I. Holub. Compiler Design in C. Prentice-Hall, 1990. Prentice-Hall Software Series, Editor: Brian W. Kernighan.

[12] Steven C. Johnson. Yacc: Yet another compiler compiler. In UNIX Programmer’s Manual, volume 2, pages 353–387. Holt, Reinhart, and Winston, 1979. AT&T Bell Laboratories Technical Report July 31, 1978.

[13] Donald E. Knuth. The TEXbook. Addison-Wes-ley, 1984.

[14] Donald E. Knuth. The future of TEX and . TUGboat, 11(4):???–???, December 1990.

[15] Michael E. Lesk and Eric Schmidt. Lex—a lexical analyzer generator. In UNIX Programmer’s Manual, volume 2, pages 388–400. Holt, Reinhart, and Winston, 1979. AT&T Bell Laboratories Technical Report in 1975.

[16] Mortice Kern Systems, Inc. MKS LEX & YACC, 1987. 35 King Street North, Waterloo, Ontario, Canada, Tel: (519) 884-2251.

[17] Vern Paxson. flex—fast lexical analyzer generator. Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, Tel: (617) 876-3296, 1988. Electronic mail: vern@lbl-csam.arpaor vern@lbl-rtsg.arpa). Software also available via ANONYMOUS FTP to lbl-csam.arpa,

lbl-rtsg.arpa, or prep.ai.mit.edu. See also

[6].

[18] Axel T. Schreiner and H. George Friedman, Jr.

Introduction to Compiler Construction Under UNIX. Prentice-Hall, 1985.

⋄ Nelson H. F. Beebe Center for Scientific Computing Department of Mathematics 220 South Physics Building University of Utah Salt Lake City, UT 84112 USA Tel: (801) 581-5254 FAX: (801) 581-4148

             Internet: Beebe@math.utah.edu