----A System for Typesetting Mathematics
Brian W. Kernighan and Lorinda L. Cherry
Bell Laboratories
Murray Hill, New Jersey 07974

ABSTRACTThis paper describes the design and implementation of a system for typesetting mathematics. The language has been designed to be easy to learn and to use by people (for example,
secretaries and mathematical typists) who know neither mathematics nor typesetting. Experience
indicates that the language can be learned in an hour or so, for it has few rules and fewer exceptions. For typical expressions, the size and font changes, positioning, line drawing, and the likenecessary to print according to mathematical conventions are all done automatically. For example, the input
sum from i=0 to infinity x sub i = pi over 2
produces∞πΣxi = _2_i =0
The syntax of the language is specified by a small context-free grammar; a compilercompiler is used to make a compiler that translates this language into typesetting commands.
Output may be produced on either a phototypesetter or on a terminal with forward and reverse
half-line motions. The system interfaces directly with text formatting programs, so mixtures oftext and mathematics may be handled simply.
This paper is a revision of a paper originally published in CACM, March, 1975.

1. Introduction‘‘Mathematics is known in the trade asdifficult, or penalty, copy because it is slower, moredifficult, and more expensive to set in type than any
other kind of copy normally occurring in books andjournals.’’ [1]One difficulty with mathematical text is themultiplicity of characters, sizes, and fonts. An
expression such aslim (tan x )sin 2x = 1

x →π⁄2requires an intimate mixture of roman, italic andgreek letters, in three sizes, and a special character or
two. (‘‘Requires’’ is perhaps the wrong word, butmathematics has its own typographical conventions
which are quite different from those of ordinary text.)
Typesetting such an expression by traditional methods
is still an essentially manual operation.
A second difficulty is the two dimensional
character of mathematics, which the superscript andlimits in the preceding example showed in its simplest
form. This is carried further by
b1
a 0+ ________________b2
a 1+ ____________b3
a 2+ ________
a 3+ . . .
and still further by√a e mx −√b1
 _______ log __________
mx √
√


√


b
2m
ab
a
e
+


√
a
dx
1
__________=  ______ tanh−1( ____ e mx )
∫ _ae
mx
√


√
b
−be −mx
m
ab


√
a
−1
 ______
coth−1( ____ e mx )

√
b
 m√
ab
These examples also show line-drawing, built-up
characters like braces and radicals, and a spectrum of
positioning problems. (Section 6 shows what a user
has to type to produce these on our system.)

--

--

-2-

2. Photocomposition
Photocomposition techniques can be used tosolve some of the problems of typesetting mathematics. A phototypesetter is a device which exposes apiece of photographic paper or film, placing characters wherever they are wanted. The Graphic Systems
phototypesetter[2] on the UNIX operating system[3]works by shining light through a character stencil.
The character is made the right size by lenses, andthe light beam directed by fiber optics to the desired
place on a piece of photographic paper. The exposed
paper is developed and typically used in some formof photo-offset reproduction.
On UNIX, the phototypesetter is driven by aformatting program called TROFF [4]. TROFF was
designed for setting running text. It also provides allof the facilities that one needs for doing mathematics,
such as arbitrary horizontal and vertical motions,line-drawing, size changing, but the syntax for
describing these special operations is difficult to learn,
and difficult even for experienced users to typecorrectly.
For this reason we decided to use TROFF as an‘‘assembly language,’’ by designing a language fordescribing mathematical expressions, and compiling it
into TROFF.
3. Language Design
The fundamental principle upon which webased our language design is that the language shouldbe easy to use by people (for example, secretaries)
who know neither mathematics nor typesetting.
This principle implies several things. First,‘‘normal’’ mathematical conventions about operator
precedence, parentheses, and the like cannot be used,
for to give special meaning to such characters meansthat the user has to understand what he or she is typing. Thus the language should not assume, forinstance, that parentheses are always balanced, forthey are not in the half-open interval (a ,b ]. Norshould it assume that that √a +b can be replaced by1(a +b ) ⁄ , or that 1⁄(1−x ) is better written as ____ (or1−xvice versa).
1

2

Second, there should be relatively few rules,
keywords, special symbols and operators, and thelike. This keeps the language easy to learn andremember. Furthermore, there should be few exceptions to the rules that do exist: if something works inone situation, it should work everywhere. If a variable can have a subscript, then a subscript can have asubscript, and so on without limit.
Third, ‘‘standard’’ things should happen
automatically. Someone who types ‘‘x=y+z+1’’
should get ‘‘x =y +z +1’’. Subscripts and superscripts
should automatically be printed in an appropriately
smaller size, with no special intervention. Fraction

bars have to be made the right length and positioned
at the right height. And so on. Indeed a mechanism
for overriding default actions has to exist, but its
application is the exception, not the rule.
We assume that the typist has a reasonable picture (a two-dimensional representation) of the desired
final form, as might be handwritten by the author of apaper. We also assume that the input is typed on acomputer terminal much like an ordinary typewriter.
This implies an input alphabet of perhaps 100 characters, none of them special.
A secondary, but still important, goal in ourdesign was that the system should be easy to implement, since neither of the authors had any desire to
make a long-term project of it. Since our design was
not firm, it was also necessary that the program beeasy to change at any time.
To make the program easy to build and tochange, and to guarantee regularity (‘‘it should work
everywhere’’), the language is defined by a contextfree grammar, described in Section 5. The compiler
for the language was built using a compiler-compiler.
A priori, the grammar/compiler-compiler
approach seemed the right thing to do. Our subsequent experience leads us to believe that any othercourse would have been folly. The original language
was designed in a few days. Construction of a working system sufficient to try significant examples
required perhaps a person-month. Since then, we
have spent a modest amount of additional time over
several years tuning, adding facilities, and occasionally changing the language as users make criticisms
and suggestions.
We also decided quite early that we would let
TROFF do our work for us whenever possible.
TROFF is quite a powerful program, with a macro

facility, text and arithmetic variables, numerical computation and testing, and conditional branching. Thus
we have been able to avoid writing a lot of mundane
but tricky software. For example, we store no text
strings, but simply pass them on to TROFF. Thus weavoid having to write a storage management package.
Furthermore, we have been able to isolate ourselvesfrom most details of the particular device and character set currently in use. For example, we let TROFF
compute the widths of all strings of characters; weneed know nothing about them.
A third design goal is special to our environment. Since our program is only useful for typesetting mathematics, it is necessary that it interface
cleanly with the underlying typesetting language forthe benefit of users who want to set intermingled
mathematics and text (the usual case). The standard
mode of operation is that when a document is typed,
mathematical expressions are input as part of the text,
but marked by user settable delimiters. The program
reads this input and treats as comments those things

--

--

-3-

which are not mathematics, simply passing themthrough untouched. At the same time it converts themathematical input into the necessary TROFF commands. The resulting ioutput is passed directly to
TROFF where the comments and the mathematicalparts both become text and/or TROFF commands.
4. The Language
We will not try to describe the language precisely here; interested readers may refer to the appendix for more details. Throughout this section, we will
write expressions exactly as they are handed to thetypesetting program (hereinafter called ‘‘EQN’’),
except that we won’t show the delimiters that the user
types to mark the beginning and end of the expression. The interface between EQN and TROFF isdescribed at the end of this section.
As we said, typing x=y+z+1 should produce
x =y +z +1, and indeed it does. Variables are madeitalic, operators and digits become roman, and normal
spacings between letters and operators are alteredslightly to give a more pleasing appearance.
Input is free-form. Spaces and new lines in
the input are used by EQN to separate pieces of the
input; they are not used to create space in the output.
Thusx

a+b over c+d+e = 1
producesa +b_______=1
c +d +e
Similarly, subscripts and superscripts are introduced by the keywords sub and sup:x 2+y 2=z 2
is produced by
x sup 2 + y sup 2 = z sup 2
The spaces after the 2’s are necessary to mark the endof the superscripts; similarly the keyword sup has tobe marked off by spaces or some equivalent delimiter.
The return to the proper baseline is automatic. Multiple levels of subscripts or superscripts are of coursezallowed: ‘‘x sup y sup z’’ is x y . The construct‘‘something sub something sup something’’ is recognized as a special case, so ‘‘x sub i sup 2’’ is xi 2
instead of xi 2.
More complicated expressions can now be
formed with these primitives:
22y2
f _x___∂___= 2 + ___2
2
b
a
∂x

is produced by

= y
+z+1

also gives x =y +z +1. Free-form input is easier totype initially; subsequent editing is also easier, for an
expression may be typed as many short lines.
Extra white space can be forced into the output
by several characters of various sizes. A tilde ‘‘ ˜ ’’gives a space equal to the normal word spacing in
text; a circumflex gives half this much, and a tab
charcter spaces to the next tab stop.
Spaces (or tildes, etc.) also serve to delimit
pieces of the input. For example, to getf (t )=2π ∫ sin(ωt )dt
we writef(t) = 2 pi int sin ( omega t )dt
Here spaces are necessary in the input to indicate thatsin, pi, int, and omega are special, and potentiallyworth special treatment. EQN looks up each suchstring of characters in a table, and if appropriate gives
it a translation. In this case, pi and omega become
their greek equivalents, int becomes the integral sign
(which must be moved down and enlarged so it looks‘‘right’’), and sin is made roman, following conventional mathematical practice. Parentheses, digits andoperators are automatically made roman wherever
found.
Fractions are specified with the keyword over:{partial sup 2 f} over {partial x sup 2} =x sup 2 over a sup 2 + y sup 2 over b sup 2
Braces {} are used to group objects together; in thiscase they indicate unambiguously what goes overwhat on the left-hand side of the expression. The
language defines the precedence of sup to be higher
than that of over, so no braces are needed to get thecorrect association on the right side. Braces canalways be used when in doubt about precedence.
The braces convention is an example of thepower of using a recursive grammar to define thelanguage. It is part of the language that if a construct
can appear in some context, then any expression inbraces can also occur in that context.
There is a sqrt operator for making squareroots of the appropriate size: ‘‘sqrt a+b’’ produces√a +b , andx = {−b +− sqrt{b sup 2 −4ac}} over 2ais
−b ±√b 2−4acx = ____________
2a
Since large radicals look poor on our typesetter, sqrt
is not useful for tall expressions.
Limits on summations, integrals and similar
constructions are specified with the keywords fromand to. To get∞Σxi →0
i =0

--

--

-4-

inch; this paper is set in 9 point type.)

we need only typesum from i=0 to inf x sub i −> 0Centering and making the Σ big enough and the limits
smaller are all automatic. The from and to parts areboth optional, and the central part (e.g., the Σ) can infact be anything:
lim from {x −> pi /2} ( tan˜x) = inf
isIf necessary, an input string can be quoted in"...", which turns off grammatical significance, andany font or spacing changes that might otherwise bedone on it. Thus we can say
lim˜ roman "sup" ˜x sub n = 0
to ensure that the supremum doesn’t become a superscript:
lim sup xn =0

lim (tan x )=∞x →π⁄2

Again, the braces indicate just what goes into thefrom part.
There is a facility for making braces, brackets,
parentheses, and vertical bars of the right height,
using the keywords left and right:
left [ x+y over 2a right ]˜=˜1makes x +y 
 ____  = 1
 2a 
A left need not have a corresponding right, as weshall see in the next example. Any characters may
follow left and right, but generally only various
parentheses and bars are meaningful.
Big brackets, etc., are often used with anotherfacility, called piles, which make vertical piles ofobjects. For example, to get 1 if x >0
sign (x ) ≡  0 if x =0
−1 if x <0

we can typesign (x) ˜==˜ left {rpile {1 above 0 above −1}˜˜lpile {if above if above if}
˜˜lpile {x>0 above x=0 above x<0}
The construction ‘‘left {’’ makes a left brace big
enough to enclose the ‘‘rpile {...}’’, which is a rightjustified pile of ‘‘above ... above ...’’. ‘‘lpile’’ makes
a left-justified pile. There are also centered piles.
Because of the recursive language definition, a pilecan contain any number of elements; any element of apile can of course contain piles.
Although EQN makes a valiant attempt to use
the right sizes and fonts, there are times when thedefault assumptions are simply not what is wanted.
For instance the italic sign in the previous example
would conventionally be in roman. Slides and transparencies often require larger characters than normal
text. Thus we also provide size and font changing
commands: ‘‘size 12 bold {A˜x˜=˜y}’’ will produce
A x = y. Size is followed by a number representing a character size in points. (One point is 1/72

Diacritical marks, long a problem in traditional
typesetting, are straightforward:.. 
.
_x +x̂ +ỹ +X̂ +Y =z +Z
is made by typing
x dot under + x hat + y tilde+ X hat + Y dotdot = z+Z bar
There are also facilities for globally changing
default sizes and fonts, for example for making viewgraphs or for setting chemical equations. The
language allows for matrices, and for lining up equations at the same horizontal position.
Finally, there is a definition facility, so a user
can saydefine name "..."
at any time in the document; henceforth, any
occurrence of the token ‘‘name’’ in an expression will
be expanded into whatever was inside the double
quotes in its definition. This lets users tailor the
language to their own specifications, for it is quitepossible to redefine keywords like sup or over. Section 6 shows an example of definitions.
The EQN preprocessor reads intermixed text
and equations, and passes its output to TROFF. Since
TROFF uses lines beginning with a period as control
words (e.g., ‘‘.ce’’ means ‘‘center the next output
line’’), EQN uses the sequence ‘‘.EQ’’ to mark the
beginning of an equation and ‘‘.EN’’ to mark the end.
The ‘‘.EQ’’ and ‘‘.EN’’ are passed through to TROFF
untouched, so they can also be used by a knowledgeable user to center equations, number them automatically, etc. By default, however, ‘‘.EQ’’ and ‘‘.EN’’are simply ignored by TROFF, so by default equations
are printed in-line.
‘‘.EQ’’ and ‘‘.EN’’ can be supplemented by
TROFF commands as desired; for example, a centereddisplay equation can be produced with the input:.ce.EQ
x sub i = y sub i ...
.EN
Since it is tedious to type ‘‘.EQ’’ and ‘‘.EN’’around very short expressions (single letters, for

--

--

-5-

instance), the user can also define two characters toserve as the left and right delimiters of expressions.
These characters are recognized anywhere in subsequent text. For example if the left and right delimiters have both been set to ‘‘#’’, the input:

The grammar makes it obvious why there arefew exceptions. For example, the observation thatsomething can be replaced by a more complicatedsomething in braces is implicit in the productions:eqn : box  eqn box
box : text  { eqn }Let #x sub i#, #y# and #alpha# be positive
produces:
Let xi , y and α be positive
Running a preprocessor is strikingly easy on
UNIX. To typeset text stored in file ‘‘f ’’, one issues
the command:
eqn f  troff
The vertical bar connects the output of one process(EQN) to the input of another (TROFF).
5. Language Theory
The basic structure of the language is not aparticularly original one. Equations are pictured as aset of ‘‘boxes,’’ pieced together in various ways. For
example, something with a subscript is just a box followed by another box moved downward and shrunkby an appropriate amount. A fraction is just a box
centered above another box, at the right altitude, witha line of correct length drawn between them.
The grammar for the language is shown below.
For purposes of exposition, we have collapsed someproductions. In the original grammar, there are about
70 productions, but many of these are simple ones
used only to guarantee that some keyword is recognized early enough in the parsing process. Symbols
in capital letters are terminal symbols; lower casesymbols are non-terminals, i.e., syntactic categories.
The vertical bar  indicates an alternative; the brackets [ ] indicate optional material. A TEXT is a stringof non-blank characters or any string inside double
quotes; the other terminal symbols represent literaloccurrences of the corresponding keyword.
eqn : box  eqn box
box : text
 { eqn } box OVER box
 SQRT box
 box SUB box  box SUP box
 [ L  C  R ]PILE { list } LEFT text eqn [ RIGHT text ] box [ FROM box ] [ TO box ] SIZE text box
 [ROMAN  BOLD  ITALIC] box
 box [HAT  BAR  DOT  DOTDOT  TILDE] DEFINE text textlist

: eqn  list ABOVE eqn

text : TEXT

Anywhere a single character could be used, any legal
construction can be used.
Clearly, our grammar is highly ambiguous.
What, for instance, do we do with the input
a over b over c ?
Is it{a over b} over cor is ita over {b over c} ?
To answer questions like this, the grammar is
supplemented with a small set of rules that describe
the precedence and associativity of operators. In particular, we specify (more or less arbitrarily) that overassociates to the left, so the first alternative above isthe one chosen. On the other hand, sub and sup bindto the right, because this is closer to standardbmathematical practice. That is, we assume x a isbx (a ), not (x a )b .
The precedence rules resolve the ambiguity ina construction likea sup 2 over b
We define sup to have a higher precedence than over,_2_
a2
so this construction is parsed as ___ instead of a b .
b
Naturally, a user can always force a particularparsing by placing braces around expressions.
The ambiguous grammar approach seems to bequite useful. The grammar we use is small enough tobe easily understood, for it contains none of the productions that would be normally used for resolving
ambiguity. Instead the supplemental information
about precedence and associativity (also small enoughto be understood) provides the compiler-compiler with
the information it needs to make a fast, deterministic
parser for the specific language we want. When thelanguage is supplemented by the disambiguating
rules, it is in fact LR(1) and thus easy to parse[5].
The output code is generated as the input isscanned. Any time a production of the grammar isrecognized, (potentially) some TROFF commands are
output. For example, when the lexical analyzer
reports that it has found a TEXT (i.e., a string of contiguous characters), we have recognized the production:
text: TEXT

--

--

-6-

The translation of this is simple. We generate a local
name for the string, then hand the name and thestring to TROFF, and let TROFF perform the storage
management. All we save is the name of the string,its height, and its baseline.
As another example, the translation associatedwith the production
box: box OVER box

is:
Width of output box =slightly more than largest input width
Height of output box =slightly more than sum of input heights
Base of output box =slightly more than height of bottom input box
String describing output box =move down;
move right enough to center bottom box;
draw bottom box (i.e., copy string for bottom box);
move up; move left enough to center top box;
draw top box (i.e., copy string for top box);
move down and left; draw line full width;
return to proper base line.
Most of the other productions have equally simple
semantic actions. Picturing the output as a set ofproperly placed boxes makes the right sequence of
positioning commands quite obvious. The maindifficulty is in finding the right numbers to use for
esthetically pleasing positioning.
With a grammar, it is usually clear how toextend the language. For instance, one of our users
suggested a TENSOR operator, to make constructions
like
k j
l
mT
ni

Grammatically, this is easy: it is sufficient to add a
production likebox

: TENSOR { list }Semantically, we need only juggle the boxes to theright places.
6. Experience
There are really three aspects of interest—howwell EQN sets mathematics, how well it satisfies its
goal of being ‘‘easy to use,’’ and how easy it was tobuild.
The first question is easily addressed. This
entire paper has been set by the program. Readers
can judge for themselves whether it is good enoughfor their purposes. One of our users commented that
although the output is not as good as the best handset material, it is still better than average, and muchbetter than the worst. In any case, who cares?
Printed books cannot compete with the birds andflowers of illuminated manuscripts on esthetic
grounds, either, but they have some clear economic
advantages.
Some of the deficiencies in the output could becleaned up with more work on our part. For example, we sometimes leave too much space between aroman letter and an italic one. If we were willing tokeep track of the fonts involved, we could do thisbetter more of the time.
Some other weaknesses are inherent in our output device. It is hard, for instance, to draw a line ofan arbitrary length without getting a perceptible overstrike at one end.
As to ease of use, at the time of writing, thesystem has been used by two distinct groups. One
user population consists of mathematicians, chemists,
physicists, and computer scientists. Their typicalreaction has been something like:(1)

It’s easy to write, although I make the following mistakes...

(2)

How do I do...?

(3)

It botches the following things.... Why don’t
you fix them?

(4)

You really need the following features...

The learning time is short. A few minutes
gives the general flavor, and typing a page or two ofa paper generally uncovers most of the misconceptions about how it works.
The second user group is much larger, thesecretaries and mathematical typists who were the original target of the system. They tend to be enthusiastic converts. They find the language easy to learn(most are largely self-taught), and have little trouble
producing the output they want. They are of course
less critical of the esthetics of their output than users
trained in mathematics. After a transition period,
most find using a computer more interesting than aregular typewriter.
The main difficulty that users have seems to beremembering that a blank is a delimiter; even experienced users use blanks where they shouldn’t and omit
them when they are needed. A common instance istypingf(x sub i)which produces
f (xi )
instead off (xi )
Since the EQN language knows no mathematics, itcannot deduce that the right parenthesis is not part ofthe subscript.
The language is somewhat prolix, but this

--

--

-7-

doesn’t seem excessive considering how much is
being done, and it is certainly more compact than thecorresponding TROFF commands. For example, hereis the source for the continued fraction expression in
Section 1 of this paper:a sub 0 + b sub 1 over{a sub 1 + b sub 2 over{a sub 2 + b sub 3 over{a sub 3 + ... }}}This is the input for the large integral of Section 1;
notice the use of definitions:define emx "{e sup mx}"
define mab "{m sqrt ab}"define sa "{sqrt a}"define sb "{sqrt b}"
int dx over {a emx − be sup −mx} ˜=˜left { lpile {1 over {2 mab} ˜log˜{sa emx − sb} over {sa emx + sb}
above
1 over mab ˜ tanh sup −1 ( sa over sb emx )above−1 over mab ˜ coth sup −1 ( sa over sb emx )}As to ease of construction, we have alreadymentioned that there are really only a few personmonths invested. Much of this time has gone into
two things—fine-tuning (what is the most estheticallypleasing space to use between the numerator anddenominator of a fraction?), and changing things
found deficient by our users (shouldn’t a tilde be adelimiter?).
The program consists of a number of small,essentially unconnected modules for code generation,a simple lexical analyzer, a canned parser which we
did not have to write, and some miscellany associatedwith input files and the macro facility. The program
is now about 1600 lines of C [6], a high-level
language reminiscent of BCPL. About 20 percent ofthese lines are ‘‘print’’ statements, generating the output code.

7. Conclusions
We think we have shown that it is possible todo acceptably good typesetting of mathematics on a
phototypesetter, with an input language that is easy tolearn and use and that satisfies many users’ demands.
Such a package can be implemented in short order,
given a compiler-compiler and a decent typesetting
program underneath.
Defining a language, and building a compiler
for it with a compiler-compiler seems like the only
sensible way to do business. Our experience with theuse of a grammar and a compiler-compiler has been
uniformly favorable. If we had written everything
into code directly, we would have been locked into
our original design. Furthermore, we would havenever been sure where the exceptions and special
cases were. But because we have a grammar, we canchange our minds readily and still be reasonably surethat if a construction works in one place it will work
everywhere.
Acknowledgements
We are deeply indebted to J. F. Ossanna, theauthor of TROFF, for his willingness to modify
TROFF to make our task easier and for his continuous
assistance during the development of our program.
We are also grateful to A. V. Aho for help withlanguage theory, to S. C. Johnson for aid with thecompiler-compiler, and to our early users A. V. Aho,
S. I. Feldman, S. C. Johnson, R. W. Hamming, andM. D. McIlroy for their constructive criticisms.
References[1]

A Manual of Style, 12th Edition. University of
Chicago Press, 1969. p 295.

[2]

Model C/A/T Phototypesetter.
tems, Inc., Hudson, N. H.

[3]

Ritchie, D. M., and Thompson, K. L., ‘‘The
UNIX time-sharing system.’’ Comm. ACM 17,
7 (July 1974), 365-375.

[4]

Ossanna, J. F., TROFF User’s Manual. Bell
Laboratories Computing Science Technical
Report 54, 1977.

[5]

Aho, A. V., and Johnson, S. C., ‘‘LR Parsing.’’ Comp. Surv. 6, 2 (June 1974), 99-124.

[6]

B. W. Kernighan and D. M. Ritchie, The C
Programming Language. Prentice-Hall, Inc.,1978.

The semantic routines that generate the actual
TROFF commands can be changed to accommodate

other formatting languages and devices. For example,
in less than 24 hours, one of us changed the entire
semantic package to drive NROFF, a variant of
TROFF, for typesetting mathematics on teletypewriterdevices capable of reverse line motions. Since manypotential users do not have access to a typesetter, but
still have to type mathematics, this provides a way to
get a typed version of the final output which is closeenough for debugging purposes, and sometimes evenfor ultimate use.

Graphic Sys-