Bugs in Computers & Typesetting, 1987–1988 1

This is a list of all corrections made to Computers & Typesetting, Volumes A–E, between 16 June 1987 and 20 February 1989. Corrections made to the softcover version of The TEXbook are the same as corrections to Volume A. Corrections to the softcover version of The book are the same as corrections to Volume C. Some of these corrections have already been made in reprintings of the books. Some of these corrections affect the indexes and mini-indexes of Volumes B and D in ways not shown here. Corrections made up to 15 June 1987 appear in other files.

Page A159, line 22 (2/15/88)

‘\nolimits’ if the normal \displaylimits convention has been overridden; a Rad

Page A213, lines 34–35 (12/23/87)

text will be a single control sequence token, defined to be like \relax if its meaning is currently undefined.

Page A299, line 30 (7/6/88)

        Fatal format file error; I'm stymied.

Page A326, line 12 (12/12/87)

its natural width. The \hbox version also invokes \everymath.

Page A359, line 2 (11/6/88)

\mathchardef\ldotp="613A\mathchardef\cdotp="6201\mathchardef\colon="603A

Page A359, lines 35–38 (5/24/88)

\def\updownarrow{\delimiter"326C33F } \def\arrowvert{\delimiter"033C000 }
\def\Updownarrow{\delimiter"326D377 } \def\Arrowvert{\delimiter"033D000 }
\def\vert{\delimiter"026A30C }        \def\Vert{\delimiter"026B30D }
\def\backslash{\delimiter"026E30F }   \def\bracevert{\delimiter"033E000 }

Page A364, line 35 (11/6/88)

\def\fmtname{plain}\def\fmtversion{2.94} % identifies the current format

Page A379, line 15 (10/12/87)

        \def\deleterightmost#1{\edef#1{\expandafter\xyzzy#1\xyzzy}}

Page A383, lines 7–15 from the bottom (1/4/89)

        209 strings out of 1685
        1659 string characters out of 17636
        27618 words of memory out of 52821
        1172 multiletter control sequences out of 2500

Consequently there was plenty of room for more macros: 52821 − 27618 = 25203 unused cells of main memory, 2500−1172 = 1328 of name memory, 1685−209 = 1476 of string memory, and 17636 − 1659 = 15977 of character memory. But a fairly large TEX was being used, and only the macros of Appendices B and E were loaded; in other circumstances it might have been necessary to conserve space.

Page A454, lines 23–29 (8/13/87)

If a suitable starting letter is found, let it be in font f. Hyphenation is aban-

doned unless the \hyphenchar of f is between 0 and 255, and unless a character of that number exists in the font. If this test is passed, TEX continues to scan forward until coming to something that’s not one of the following three “admissible items”: (1) a character in font f whose \lccode is nonzero; (2) a ligature formed entirely from characters of type (1); (3) an implicit kern. The first inadmissible item terminates this part of the process; the trial word consists of all the letters found in admissible items. Notice that all of these letters are in font f.

Page A458, left column, line 19 (2/15/88)

\| ( ∥ ), 146–147, 171, \underline{361}, 435, 438.

Page A462, left column, line 7 (10/9/87)

152, 178, \underline{360}.

Page A463, left column (4/17/88)

*\day, 273, 349, 406.

Page A464, left column, under Displays (12/8/88)

non-centered, 186, 326, 375–376, 420–421.

Page A465, entry for \everymath (12/12/87)

[Include also a reference to page 326.]

Page A465, right column (7/6/88)

         Fatal format file error, 299.

Page A473, entry for ‘page builder’ (8/13/87)

when exercised, 122, 280–283, 286–287.

Page A474, left column (12/27/88)

*\parshape, 101–102, 214, 271, 277, 283,

Page A480, right column (2/15/88)

\vdots ( ⋮ ), 177, \underline{359}.

Page A481, right column (7/3/87)

\z@, \underline{347}, 348.

\z@skip, \underline{347}, 348.

Page B2, line 32 (2/20/89)

define banner ≡ ´ This␣is␣TeX,␣Version␣2.97´ { printed when TEX starts }

Page B38, lines 7–9 from the bottom (11/6/88) [Delete this paragraph; it is being moved to page B214.] Page B38, line 5 from the bottom (12/14/88)

begin if log opened then selector ← term and log

Page B39, line 5 (12/14/88)

if log opened then error ;

Page B52, line 5 (8/13/87) cannot be done, i.e., if hi mem min = lo mem max + 1, we have to quit. Page B54, lines 34–35 (7/9/88)

begin if hi mem min − lo mem max ≥ 1998 then t ← lo mem max + 1000

else t ← lo mem max +1+(hi mem min −lo mem max ) div 2; { lo mem max +2 ≤ t < hi mem min }

Page B108, new line after line 8 (5/24/88)

d: integer ; { number of characters in incomplete current string }

Page B108, lines 31–33 (5/24/88)

str room (l); d ← cur length ; while pool ptr > str start [str ptr ] do

begin decr (pool ptr ); str pool [pool ptr + l] ← str pool [pool ptr ];

end; { move current string up to make room for another } for k ← j to j + l − 1 do append char (buffer [k]); text (p) ← make string ; pool ptr ← pool ptr + d;

Page B115, line 12 (4/28/88)

group code = 0 . . max group code; { save level for a level boundary }

Page B141, line 19 (4/28/88)

par token : halfword ; { token representing ‘\par’ }

Page B150, line 24 (4/28/88)

358. The present point in the program is reached only when the expand routine has inserted

Page B151, mini-index (4/28/88)

Delete the entry for ‘no expand ’; replace it by:

expand : procedure, §366.

Page B154, lines 25, 29, 34 respectively (9/20/87)

cvl backup, radix backup, co backup: small number ; { to save cur val level , etc. } co backup ← cur order ; backup backup ← link (backup head ); cur order ← co backup; link (backup head ) ← backup backup;

Page B155, new entry for mini-index (9/20/87)

cur order : glue ord , §447.

Page B156, line 28 (12/23/87)

begin eq define(cur cs , relax , 256);

Page B157, mini-index (12/23/87)

Delete the entries for ‘eqtb’ and ‘frozen relax ’; replace them by the following:

eq define: procedure, §227.

relax = 0, §207.

Page B162, lines 12–14 (4/30/88)

repeat link (temp head ) ← null ; if (info(r) > match token + 127) ∨ (info(r) < match token ) then s ← null else begin match chr ← info(r) − match token ; s ← link (r); r ← s; p ← temp head ; m ← 0;

Page B177, bottom line before mini-index (7/13/88)

cur val ← 0; cur val level ← int val ; radix ← 0; cur order ← 0;

Page B181, line 31 (4/28/88)

[Change ‘x units per sp’ to ‘x sp per unit’! This change also should be made on line 1 of page B183 and line −8 of page B590.]

Page B188, line 8 (5/25/88)

function str toks (b : pool pointer ): pointer ; { changes the string str pool [b . . pool ptr ] to a token list }

Page B188, line 13 (5/25/88)

begin str room (1); p ← temp head ; link (p) ← null ; k ← b;

Page B188, line 20 (5/25/88)

pool ptr ← b; str toks ← p;

Page B188, new line after line 28 (5/25/88)

b: pool pointer ; { base of temporary string }

Page B188, line 31 (5/25/88)

else begin old setting ← selector ; selector ← new string ; b ← pool ptr ;

Page B188, line 41 (5/25/88)

selector ← old setting ; the toks ← str toks (b);

Page B190, lines 16–18 (5/25/88)

b: pool pointer ; { base of temporary string } begin c ← cur chr ; ⟨ Scan the argument for command c 471 ⟩; old setting ← selector ; selector ← new string ; b ← pool ptr ; ⟨ Print the result of command c 472 ⟩; selector ← old setting ; link (garbage) ← str toks (b); ins list (link (temp head ));

Page B210, line 36 (5/25/88)

begin if (pool ptr + name length > pool size) ∨ (str ptr = max strings ) ∨ (cur length > 0) then

Page B211, new line of code before the mini-index (12/14/88)

log opened : boolean ; { has the transcript file been opened? }

Page B212, line 5 (12/14/88)

job name ← 0; name in progress ← false; log opened ← false;

Page B213, line 24 (12/14/88)

log name ← a make name string (log file); selector ← log only ; log opened ← true;

Page B214, lines 2 and 3 (12/14/88)

messages or even to show context . The prompt file name routine can result in a fatal error , but the error routine will not be invoked because log opened will be false.

The normal idea of batch mode is that nothing at all should be written on the terminal. However, in the unusual case that no log file could be opened, we make an exception and allow an explanatory message to be seen.

Page B214, lines 7–11 reduce to a single line (12/14/88)

begin selector ← term only ;

Page B224, second-last line (4/28/87)

done: if file opened then b close(tfm file); read font info ← g;

Page B229, lines 6–8 (11/17/87)

than 2^{27}. If z < 2^{23}, the individual multiplications b · z, c · z, d · z cannot overflow; otherwise we will divide z by 2, 4, 8, or 16, to obtain a multiplier less than 2^{23}, and we can compensate for this later. If z has thereby been replaced by z′ = z/2^{e}, let β = 2^{4−e}; we shall compute

Page B229, lines 11–12 (11/17/87)

if a = 0, or the same quantity minus α = 2^{4+e}z′ if a = 255. This calculation must be done exactly, in order to guarantee portability of TEX between computers.

Page B230, lines 2–5 (11/17/87)

begin alpha ← 16;

while z ≥ ´ 40000000 do

begin z ← z div 2; alpha ← alpha + alpha ; end; beta ← 256 div alpha ; alpha ← alpha ∗ z;

Page B245, new entry for mini-index (8/7/87)

cur s : integer , §616.

Page B254, line 29 (8/7/87)

cur s : integer ; { current depth of output box nesting, initially −1 }

Page B254, line 31 (8/7/87)

[Remove the statement ‘cur s ← −1;’ and put it on page B244 at the end of line 31.]

Page B259, line 13 (11/9/87)

begin rule wd ← rule wd + 10; { compensate for floating-point rounding } edge ← cur h + rule wd ; lx ← 0; ⟨ Let cur h be the position of the first box, and set

Page B259, line 17 (11/9/87)

cur h ← edge − 10; goto next p;

Page B263, line 21 (11/9/87)

begin rule ht ← rule ht + 10; { compensate for floating-point rounding } edge ← cur v + rule ht ; lx ← 0; ⟨ Let cur v be the position of the first box, and set

Page B263, line 25 (11/9/87)

cur v ← edge − 10; goto next p;

Page B266, line 8 (8/7/87)

dvi out (eop); incr (total pages ); cur s ← −1;

Page B266, new code between lines 31 and 32 (8/7/87)

while cur s > −1 do begin if cur s > 0 then dvi out (pop) else begin dvi out (eop); incr (total pages )

end; decr (cur s ); end;

Page B285, line 21 (4/28/88)

is subsidiary to the nucleus field of some noad; the dot is replaced by ‘_’ or ‘^’ or ‘/’ or ‘\’ if p is

Page B338, second-last line (8/19/87)

q ← link (head ); s ← head ;

Page B339, line 4 (8/19/87)

s ← q; q ← link (q);

Page B339, new code to insert after line 10 (8/19/87)

if o ≠ 0 then begin r ← link (q); link (q) ← null ; q ← hpack (q, natural ); shift amount (q) ← o; link (q) ← r; link (s) ← q; end;

[These new lines also imply changes to the index that aren’t shown in this errata list.]

Page B387, line 2 (5/24/88) is quite short. In the following code we set hc[hn + 2] to the impossible value 128, in order to

Page B387, line 8 (5/24/88)

hc[0] ← 127; hc[hn + 1] ← 127; hc[hn + 2] ← 128; { insert delimiters }

Page B390, lines 17–18 (5/24/88)

⟨ Enter as many hyphenation exceptions as are listed, until coming to a right brace; then return 961 ⟩; [The same change applies to lines 20–21, and to page 582.]

Page B396, new line after line 34 (5/24/88)

trie link (trie size) ← 0; trie back (0) ← trie size; { wrap around }

Page B396, bottom line (12/12/87)

trie link (0) ← 0; trie char (0) ← 0; trie op(0) ← min quarterword ;

Page B397, lines 15–17 (5/24/88)

begin c ← trie c[p]; if c < trie min then trie min ← c; if trie min = 0 then z ← trie link (trie size) else z ← trie link (trie min − 1); { get the first conceivably good hole }

Page B400, lines 3–4 (5/24/88)

⟨ Enter all of the patterns into a linked trie, until coming to a right brace 961 ⟩ ≡ [The same change applies to page B399, lines 29–30, and to page 582.]

Page B402, line 10 (5/24/88)

r ← trie size; { finally, we will zero out the holes }

Page B406, line 9 from the bottom (1/23/89)

shrink order (r) ← normal ; delete glue ref (q); glue ptr (p) ← r; q ← r;

Page B417, line 10 (1/23/89)

q ← new skip param (top skip code); { now temp ptr = glue ptr (q) }

Page B418, line 14 (1/23/89)

shrink order (r) ← normal ; delete glue ref (q); glue ptr (p) ← r; q ← r;

Page B507, line 13 (12/14/88)

if log opened then selector ← selector + 2;

Page B527, line 21 (12/14/88)

if log opened then

Page B528, line 5 (12/14/88)

if log opened then

Page B547, right column (9/20/87)

co backup: \underline{366}.

Page B548, right column (9/20/87)

cur order : 366, \underline{447}, 448, 454, 462.

Page B548, right column (8/7/87)

cur s : 593, \underline{616}, 619, 629, 640, 642.

Page B551, both columns (12/23/87)

[Remove ‘372’ from eqtb and put it into eq define.]

Page B552, left column (4/28/88)

[Insert ‘358’ into expand .]

Page B554, left column (12/23/87)

[Remove ‘372’ from frozen relax .]

Page B559, new entry (12/14/88)

log opened , 92–93, \underline{527}, 528, 534–535, 1265, 1333–1334.

Page B559, right column (8/13/87)

[Delete the entry for low mem max .]

Page B562, left column (4/28/88)

[Remove ‘358’ from no expand .]

Page B565, left column (8/7/87)

pop: 584–585, \underline{586}, 590, 601, 608, 642.

Page B567, left column (12/23/87)

[Insert ‘372’ into relax .]

Page B568, left column (4/28/88)

[Move ‘269’ from save index to save level .]

Page C26, bottom line (7/18/87) What angle corresponds to the direction North-Northwest? Page C107, line 13 (10/7/87)

pickup penrazor xscaled heavyline rotated (angle(z_{32} − z_{31}) + 90); Page C164, line 10 (4/27/88)

y_{$c} = top y_{$l}; y_{$d} = y_{$r}; x_{$c} = x_{$l} − left jut ; x_{$d} = x_{$r} + right jut ;

Page C175, line 23 (1/11/88)

expand into a sequence of tokens. (The language SIMULA67 demonstrated that it is

Page C241, line 11 (5/25/88)

numeric ht^{#}, dp^{#}; ht^{#} = body height^{#}; .5[ht^{#}, −dp^{#}] = axis^{#};

Page C248, line 21 becomes two lines (1/24/89)

which might not be numerically stable in the presence of rounding errors.) Another case, not really desirable, is left jut = right jut = 0.

Page C262, line 15 (12/23/88)

string base_name, base_version; base_name="plain"; base_version="1.7";

Page C271, line 12 (1/4/89)

the user and ’s primitive picture commands. First, some important program

Page C271, line 4 from the bottom (12/23/88)

def cutdraw expr p = % caution: you may need autorounding=0

Page C272, lines 5 and 6 (12/23/88)

  (cut_scaled (1+max(pen_lft,pen_rt,pen_top,pen_bot))
   rotated theta shifted z)t_;

Page C273, lines 20 and 22 (9/26/88)

(z_+(0,pen_top))t_=round((z+(0,pen_top))t_); z_enddef;
(z_+(0,pen_bot))t_=round((z+(0,pen_bot))t_); z_enddef;

Page C290, line 6 from the bottom (12/23/88)

(2) A throwaway variable, ‘whatever ’, nullifies an unwanted equation at the beginning

Page C331, just below the illustration (7/18/87)

Such a pattern is, of course, rather unlikely to occur in a gf file, but GFtoDVI would

Page C337, line 11 (4/28/88)

An online “menu” of the available test routines will be typed at your terminal

Page C346, entry for autorounding (12/23/88)

212, 262, 264, 271–272.

Page C350, left column (7/6/88)

      Fatal base file error, 226.

Page C356, left column (1/11/88)

SIMULA67 language, 175.

Page C358, right column (2/15/88)

*yoffset, 212, \underline{220}, 315, 324.

Page D2, line 27 (12/14/88)

define banner ≡ ´ This␣is␣METAFONT,␣Version␣1.7´ { printed when starts }

Page D36, lines 3–5 (11/6/88) [Delete this paragraph; it is being moved to page D349.]

Page D36, line 7 (12/14/88)

begin if log opened then selector ← term and log

Page D36, line 16 (12/14/88)

if log opened then error ;

Page D66, lines 34–35 (7/9/88)

begin if hi mem min − lo mem max ≥ 1998 then t ← lo mem max + 1000 else t ← lo mem max +1+(hi mem min −lo mem max ) div 2; { lo mem max +2 ≤ t < hi mem min }

Page D347, new line of code after line 5 (12/14/88)

log opened : boolean ; { has the transcript file been opened? }

Page D347, line 11 (12/14/88)

job name ← 0; log opened ← false;

Page D348, line 4 from the bottom (12/14/88)

log name ← a make name string (log file); selector ← log only ; log opened ← true;

Page D349, lines 6 and 7 (12/14/88) print error messages or even to show context . The prompt file name routine can result in a fatal error , but the error routine will not be invoked because log opened will be false.

The normal idea of batch mode is that nothing at all should be written on the terminal. However, in the unusual case that no log file could be opened, we make an exception and allow an explanatory message to be seen. Page D349, lines 11–15 reduce to a single line (12/14/88)

begin selector ← term only ;

Page D420, bottom line (5/25/88)

if txx mod unity = 0 then

Page D441, delete line 2 and change line 12 as follows (5/25/88)

done: if eq type(x) ≠ tag token then clear symbol (x, false); if equiv (x) = null then new root (x); scan declared variable ← h;

Page D444, line 8 from the bottom (12/14/88)

if log opened then selector ← selector + 2;

Page D510, line 14 (12/14/88)

if log opened then

Page D511, line 11 (12/14/88)

if log opened then

Page D530, new entry (12/14/88)

log opened , 87–88, \underline{782}, 783, 788–789, 1023, 1205, 1208.

Page D545, left column (10/31/87)

zscaled primitive: \underline{893}. Zabala Salelles, Ignacio Andres: 812.

Page E32, second-last line (9/20/87) after which comes ‘math axis^{#}; generate mathsy’ (which we won’t bother to

Page E111, line 29 (10/16/88)

lft x_{11} = hround u; x_{1l} − x_{11} = x_{2l} − x_{12} = x_{22} − x_{2r} = hround 1.6cap jut ;

Page E285, bottom line (12/1/87)

Due to Technical Developments (1968)

Page E333, lines 9–11 (1/9/89)

lft x_{1l} = hround(2.5u − .5mfudged.stem ); x_{1l} = x_{1′l} = x_{2l} = x_{2′l}; lft x_{3l} = hround(.5w − .5mfudged.stem ); x_{5} − x_{3} = x_{3} − x_{1}; if not monospace: r := hround(x_{5} + x_{1}) + r − w; fi % change width for better fit

Page E353, lines 38–39 (8/12/87)

else: fill diag end (6r, 5r, 1, 1, 5l, 6l) - - .9[z_{5l}, z_{6l}] . . {z_{5} − z_{6}} .1[z_{5r}, z_{6r}] - - cycle; % middle stem

Page E387, line 13 (8/12/87)

pickup tiny .nib; bulb(3, 4, 5); % bulb

Page E413, lines 37–38 (8/12/87)

else: fill diag end (6r, 5r, 1, 1, 5l, 6l) - - .9[z_{5l}, z_{6l}] . . {z_{5} − z_{6}} .1[z_{5r}, z_{6r}] - - cycle; % middle stem

Page E459, line 24 (8/7/87)

[Delete the ‘=’ sign between ‘lft ’ and ‘x_{5}’.]

Page E471, line 5 (12/11/88)

x_{2} = good .x .5w; center on (x_{2});

Page E471, insert two lines below the rule at bottom of page (12/11/88)

def center on (expr x) = if not monospace: % change width for symmetric fit r := r + 2x − w; w := 2x; fi enddef;

Page E477, line 20 (12/11/87)

x_{4} = x_{8} = good .x .5w; center on (x_{4}); x_{2} = w − x_{6} = good .x(x_{4} + a);

Page E483, third line of elementary division operator (12/11/88)

x_{3} − .5dot size = hround(.5w − .5dot size); center on (x_{3});

Page E485, line 4 (8/7/87)

[Delete the ‘=’ sign between ‘lft ’ and ‘x_{5}’.]

Page E487, line 17 (8/4/88)

fill fullcircle scaled (bold + 3.8dw + eps ) shifted (.5[z_{4}, z_{8}]); % dot [Also remove page 487 from the index entry for dot size, and add it to the entries for bold and dw .]

Page E515, lines 5 and 12 (12/11/88)

.5[x_{1}, x_{2}] = x_{3} = good .x .5w; center on (x_{3}); lft x_{1} = hround(.5w − u ∗ sqrt48);

Page E515, line 21 (1/23/89)

labels(5, 6); zero width ; endchar; [Also put labels ‘5’ and ‘6’ on the upper right figure, page E514.]

Page E521, lines 4 and 14 (12/12/88)

x_{1} = x_{2} = good .x .5w; center on (x_{1}); lft x_{3} = hround u; x_{4} = w − x_{3};

Page E537, line 6 (12/11/88)

x_{1} = x_{2} = x_{3} = x_{4}; x_{1} − .5stem = hround(.5w − .5stem ); center on (x_{1});

Page E537, line 19 (12/11/88)

x_{1} = x_{2} = x_{3}; x_{1} − .5stem = hround(.5w − .5stem ); center on (x_{1});

Page E539, line 4 (12/11/88)

x_{1} = x_{4} = x_{30} = x_{33} = good .x .5w; center on (x_{1});

Page E539, line 21 (12/11/88)

x_{1} = x_{4} = good .x .5w; center on (x_{1});

Page E541, line 4 (12/11/88)

x_{1} = x_{5} = good .x .5w; center on (x_{1});

Page E541, line 17 (12/11/88)

x_{1} = x_{10} = good .x .5w; center on (x_{1});

Page E550, new line after line 23 (8/15/87)

forsuffixes $ = notch cut , cap notch cut : if $ < 3: $ := 3; fi endfor [To make room for this, combine lines 38 and 39 into a single line.]

Page E550, line 29 (7/9/88)

define whole vertical blacker pixels(vair , bar , slab, cap bar , cap band );

Page E572, new entry at bottom (12/11/88)

center on , \underline{471}, 477, 483, 515, 521, 537–541.