summaryrefslogtreecommitdiff
path: root/Master/texmf-doc/doc/english/knuth
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2005-12-29 00:34:36 +0000
committerKarl Berry <karl@freefriends.org>2005-12-29 00:34:36 +0000
commit41ceff5a615ab4e3d46b1c94bd26d9dcf9d6c1f8 (patch)
treec710ef0b82f65ae0f818e6ea8f10c2f40f2decf3 /Master/texmf-doc/doc/english/knuth
parent2293d6885b754133151c14be7e01ad81baf0afbf (diff)
doc/english/i-l
git-svn-id: svn://tug.org/texlive/trunk@21 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-doc/doc/english/knuth')
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/README69
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/cm85.bug1860
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.eight610
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.five1108
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.four1052
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.nine226
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.one751
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.seven821
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.six528
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.ten1289
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.tex736
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.three1898
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata.two491
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata1.tex751
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata2.tex491
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata3.tex1898
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata4.tex1052
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata5.tex1108
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata6.tex528
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata7.tex821
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata8.tex525
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errata9.tex226
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/errorlog.tex2924
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/index.html60
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/logmac.tex107
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/mf84.bug2279
-rw-r--r--Master/texmf-doc/doc/english/knuth/errata/tex82.bug9006
-rw-r--r--Master/texmf-doc/doc/english/knuth/errorlog.tex2914
-rw-r--r--Master/texmf-doc/doc/english/knuth/expr.mf5
-rw-r--r--Master/texmf-doc/doc/english/knuth/index.html193
-rw-r--r--Master/texmf-doc/doc/english/knuth/io.mf23
-rw-r--r--Master/texmf-doc/doc/english/knuth/mfman.mf2474
-rw-r--r--Master/texmf-doc/doc/english/knuth/primes.web414
-rw-r--r--Master/texmf-doc/doc/english/knuth/story.tex18
-rw-r--r--Master/texmf-doc/doc/english/knuth/trap.mf170
-rw-r--r--Master/texmf-doc/doc/english/knuth/trap.pl490
-rw-r--r--Master/texmf-doc/doc/english/knuth/trapman.tex400
-rw-r--r--Master/texmf-doc/doc/english/knuth/trip.pl833
-rw-r--r--Master/texmf-doc/doc/english/knuth/trip.tex448
-rw-r--r--Master/texmf-doc/doc/english/knuth/tripman.tex413
-rw-r--r--Master/texmf-doc/doc/english/knuth/web.tex1477
-rw-r--r--Master/texmf-doc/doc/english/knuth/webman.tex1672
42 files changed, 45159 insertions, 0 deletions
diff --git a/Master/texmf-doc/doc/english/knuth/errata/README b/Master/texmf-doc/doc/english/knuth/errata/README
new file mode 100644
index 00000000000..07c2bd816d7
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/README
@@ -0,0 +1,69 @@
+Notes on the Computer Modern parameters
+
+Dimensions are mostly in units of 1/36pt, because I originally worked
+on graph paper with 36 pixels per point (in 1977). This experience made
+me familiar with such units, so I later decided to make METAFONT produce
+proofmode output at the same scale.
+
+The basic fonts cmr5--cmr17 scale proportionately in most vertical
+dimensions (e.g., the x_height in 5pt is half that in 10pt), but
+horizontally the smaller fonts are more extended and have relatively
+heavier weight (especially in hairlines).
+
+The slanted fonts cmsl8--cmsl12 are identical to their unslanted
+counterparts except that they have slant=1/6.
+
+Font cmdunh10 is the same as cmr10 except that body_height, asc_height,
+cap_height, and fig_height have been drastically increased.
+
+The bold fonts cmbx5--cmbx12 have similar vertical dimensions to the ordinary
+roman (except that the x_height is a bit taller and bar_height is lower);
+they use bolder pen strokes, of course, and they are rather more extended.
+Font cmb10 is like cmbx10 except not extended (i.e., 1em=10pt in cmb10,
+but 1em=11.5pt in cmbx10); it also has slightly shorter cap serifs. Font
+cmbxsl10 is like cmbx10 but slanted.
+
+The typewriter fonts cmtt8--cmtt12 have the same x_heights as their
+roman counterparts, but they have shorter ascenders and longer descenders.
+Their math_axis is based on ascenders only. The stroke weights are
+almost all identical to the corresponding roman stem weight.
+Font cmsltt10 is a slanted version of cmtt10; cmvtt10 is non-monospaced.
+
+The sans serif fonts cmss8--cmss17 are analogous to cmr8--cmr17; they have
+slanted counterparts with slant of 12 degrees. A few other isolated sans
+serif fonts appear in the standard set, as demonstrations of how other
+varieties could be made: There's a demibold condensed version, cmssdc10,
+and a bold extended version, cmssbx10. (The title pages in The TeXbook use
+cmssdc10 at 40pt and a magnified version of cmssbx10 called cminch; to
+save font storage space, cminch is restricted to digits and uppercase
+letters only.) Finally, there's a pair of fonts called cmssq8 and cmssqi8;
+these are in a rather different style (extended, with short ascenders
+and descenders), used for the end-of-chapter quotations in The TeXbook.
+
+The font cmfib8 is another `demonstration' of parameters; it's a serifed
+font whose proportions are based on Fibonacci numbers. Also, the font
+cmff10 is a weird concoction of little use except for testing.
+
+The text italic fonts cmti7--cmti12 have parameters like their roman
+cousins, except that they are more condensed and slightly lighter.
+The math italic fonts cmmi5--cmmi12 are not condensed and not
+quite as light.
+
+Four special italic fonts are provided as demonstrations of further
+possibilities: cmbxti10 is a bold extended text italic; cmmib10 is
+a bold math italic; cmit10 is an italic typewriter font; cmu10 is
+an unslanted italic with the same stem weights as cmr10.
+
+The math symbol fonts, cmsy5--cmsy10, have the same parameters
+as the corresponding math italic; these fonts also have special
+parameters of their own. There's a bold math symbols font for
+demonstration purposes: cmbsy10.
+
+The math extension font, cmex10, has the parameters of cmr10.
+
+The extended ASCII font, cmtex10, has the parameters of cmtt10, except
+that the slant is positive (for a few characters that will be slanted).
+
+And finally there are two caps-and-small-caps fonts, cmcsc10 (to match cmr10)
+and cmtcsc10 (to match cmtt10). These fonts are unusual in having two
+sets of parameters, one for the upper uppercase and one for the lower uppercase.
diff --git a/Master/texmf-doc/doc/english/knuth/errata/cm85.bug b/Master/texmf-doc/doc/english/knuth/errata/cm85.bug
new file mode 100644
index 00000000000..2fd56f503af
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/cm85.bug
@@ -0,0 +1,1860 @@
+This file is a log of changes made to the "new generation" of Computer Modern
+fonts, after the first output proofs were ready. I had a great deal of
+advice from Neenie Billawala, Matthew Carter, and Richard Southall while
+I was making these revisions.
+
+Entries are in chronological order; thus the most recent news appears
+at the bottom of the file.
+
+-------------------------------------------------------------------------------
+ Changes based on the proofsheets of April 26, 1985
+ACCENT.MF:
+ lower the idots, umlauts, and tilde (MC)
+ Polish ell cross: longer stroke in bold
+CMBASE.MF:
+COMLIG.MF:
+ double quotes too close together in bold (MC)
+CSCSPU.MF:
+ SS made from two S's
+GREEKU.MF:
+ Gamma: .25u longer arm
+ Lambda: too narrow (MC,NB)
+ Xi: 1u wider; shorten middle serifs (MC)
+ top and bottom strokes to be arms (NB)
+ Psi: more super; thin the lower curve (MC)
+ add points 3' and 7' for crisp sans
+ Omega: redo the bottom, curl 0 becomes vertical (MC)
+ thin from hair to vair at points 3 and 5
+PUNCT.MF:
+ Monospace period, comma, colon, semicolon made heavier (MC)
+ROMAN.MF:
+ ligs=2 gets ff, fi, etc.; ligs=1 gets only --, '', etc.
+ II kerning introduced
+ kern between a and ' in csc
+ROMAND.MF:
+ 0: med_curve decreased to curve; y2l and y4l raised
+ 1: cap_bar changed to bar in the top stroke
+ sans-serif serifs also use bar as the slab height
+ 2: lighten cap_curve and cap_stem slightly (RS)
+ move point 3 down by .5vair (MC)
+ 4: thin the diagonal still more (NB)
+ bar line moves up one pixel when there's a serif below it
+ 6: move bulb to the right (MC)
+ make the lower left curve more_super (RS,NB)
+ 9: make the upper right curve more_super (RS,NB)
+ROMANL.MF:
+ a: bulb positioned by its center rather than the left (MC)
+ c: right terminals moved closer to the edge (MC,NB)
+ more pull on the inside left (RS)
+ e: less left sidebar in monospace (MC)
+ bold versions to be wider (MC)
+ more pull on inside left (MC,RS)
+ g: lower edge of loop goes one pixel lower
+ varg: point 6 raised above baseline (MC)
+ y0 calculated so that it works when x7l=stem_edge
+ lower arc goes one pixel lower
+ i: monospace version gets more left sidebar (MC)
+ dot moves slightly right (NB)
+ stem'' increased to stem' (MC,RS,NB)
+ slab replaces tiny in correction for dot-too-close
+ j: diminish monospace sidebars (MC)
+ shift slightly to right (MC)
+ k: serif right_jut decreased .8 to .6
+ bug fixed in alpha2 (had y1 not y11)(MC,RS,NB)
+ decreased diagonal weights
+ "if abs(angle(z3-z4)-45)<2:y4:=y3-(x3-x4);fi" rejected; moves y4 down too much
+ n: omit pull inside the arch (MC,RS)
+ introduce stem_shift, shifts this character and others slightly right (MC)
+ o: raise y2l and y4l (RS)
+ s: reduced sidebearing in sans (MC)
+ increased thickness at edges (.35 to .5) (RS)
+ changed to super_arc, and made it more_super (RS)
+ raised the top of upper barb to equal top of the character (RS)
+ removed typo (`tiny' for `fine')
+ reduced flare in upper terminal of sans, and rounded it properly
+ t: width to grow in bold case
+ height made independent of bar_height
+ slightly longer bar (MC)
+ v: decreased left stem (RS)
+ w: decreased stems (MC,RS)
+ monospace version drops middle from 2/3 to .6 and lengthens inner serifs
+ x: decreased left stem
+ y: decreased left stem
+ z: lighter diagonal, longer upper arm (MC,RS,NB)
+ROMANP.MF:
+ $: tau eliminated
+ROMANU.MF:
+ A: decrease right stem (MC)
+ make the bar thinner (MC,NB)
+ bar position based on y0 rather than bar_height
+ C: use cap_band instead of vair' at top and bottom (RS)
+ correct typo: x2l to be reset, not y2l
+ E: middle arm .35u longer, but beak reduced from .7 to .6 (MC)
+ F: top arm .25u longer; middle arm as E (MC)
+ G: same as C; also the bar is raised one pixel
+ J: slightly longer upper left serif
+ K: lower diagonal thinned and moved outward
+ M: monospace version raised still more in middle
+ N: diagonal thinned (MC,RS)
+ O: y2l and y4l raised
+ R: tail should move to the right (MC,RS,NB)
+ bold case gets wider (RS,NB)
+ S: changed as s (RS)
+ V: took stem_corr off the left stem (MC)
+ W: monospace version takes center down from 2/3 to .6, lengthens inner jut
+ X: took stem_corr off the left stem (MC)
+ Y: took stem_corr off the left stem (MC)
+ Z: diagonal made lighter in sans (MC)
+ upper arm made longer (MC,RS)
+ROMLIG.MF:
+ equalize stem weights (RS,NB)
+ROMSPL.MF:
+ ae, oe: incorporate changes of a and e and o
+ ss: more stem weight, less curve weight, less bulb (MC,NB)
+ dotless i,j: see i,j
+ROMSPU.MF:
+ AE: middle arm changes as E (MC)
+ if hefty and monospace, avoid the serif on middle arm
+ bars not aligned if hefty
+ if monospace, middle stem moves to right
+ OE: middle arm changes as in AE (MC)
+ middle stem lightened
+ROMSUB.MF:
+ blankspace: not so close to sides
+SYM.MF:
+CMR10.MF etc:
+ bar_height raised in the quote and bold fonts (MC,NB)
+ comma_depth in cmtt10 increased from 40 to 50 (MC)
+ cap_notch_cut decreased in cmsc10, cmsx10
+ apex_o decreased in cmr10, cmb10, cmbx10, cmbx5, cmcsc10, cmtt10
+ o decreased in cmb10
+ cap_jut decreased from 39 to 34 in cmb10; cap_serif_fit increased 5 to 6
+ cmbx5 gets smaller beak, fudge, cap_ess; more apex_corr
+GENERAL:
+ "robustness" added when points like x8r of "a" are calculated
+ (this affects a,b,d,varg,j,p,q,t,u,dj,ae,6,9,f_stroke)
+ "robustness" also added to avoid curl at end of paths
+ (this affects c,e,s,C,G,S,1,5,ae,oe,breve,parens)
+ "term" subroutine adds robustness for sans-serif terminals
+ (this affects C,G,J,S,f_stroke,j,ss,ae,oe,2,3,5,6,9,$,&,?,@)
+ code revised to use "pos" instead of "penpos" when possible
+ Changes based on the proofsheets of May and June, 1985
+ROMAND.MF:
+ 1: use o instead of apex_o
+ 4: bar line height shouldn't depend on bar_height
+ 5: sans-serif lower terminal position raised; depends on upper left edge
+ bug in arm at top (0 for 90) made all hefty arms too small
+ 9: disappears at link
+ROMANU.MF:
+ B: middle bar positioned by its middle, not its bottom (RS)
+ serifed lobes thickened slightly at bottom (RS)
+ C: lower terminal is tilted the other way
+ C,G: upper terminal in sans-serif is tilted slightly
+ upper barb is darkened
+ J: tilt the lower terminal
+ K: lighten the main diagonal (serif case) (RS)
+ lighten the upper diagonal (sans-serif case) (RS)
+ M: remove apex_corr (RS)
+ N: lighten the diagonal
+ P: too light below counter (RS)
+ Q: sharpen upper right corner of sans-serif tail (RS)
+ top of tail thickened and moved slightly left
+ S: less super at upper left and lower right (MC)
+ barb to go below baseline
+ barbs darkened
+ add weight at top, bottom in sans_serif version (RS)
+ tilt the lower terminal like the upper one
+ top weight needs to be maxed with fine.breadth
+ W: top middle stems allowed to overlap in serifed case
+ second inner serif made no longer than left outer serif (MC)
+ ceiling must become floor, to ensure that x5r>=x4r-mid_corr
+ Z: diagonal still too heavy, because previous change was ineffective
+ beaks made darker
+ better positioning of y2 and y3 when tiny is zero
+CSCSPU.MF:
+ J,SS: changes from J and S
+ROMANL.MF:
+ a: inappropriate uses of "fine" are removed
+ bh introduced to guard against "wild" bar heights
+ thin_join introduced at point 9
+ robustness logic changed so that x8l-x8r<=u
+ c: too much weight constrast between strokes in sans_serif (RS)
+ top terminal lowered to match a
+ bottom terminal tilted the other way
+ d: fine.breadth should have been thin_join as in b, p, q
+ e: 1+xpart changed to xpart
+ bottom terminal tilted the other way
+ g: sans-serif ear to use z0l and z0r
+ h,m,n: left inner serifs stay at jut length
+ i,l: mod_width for better fit at lowres
+ j: reposition stem for better fit (use .5w+2.5u, not w-2.5u)
+ remove bug in "pos" change
+ k: upper diagonal serif lengthened from 1.2jut to 1.4jut (RS)
+ diagonals made still lighter
+ r: thin_join introduced
+ s: barb to go below baseline
+ barbs darkened
+ add weight at top, bottom in sans_serif version (RS)
+ tilt the lower terminal like the upper one (RS)
+ top weight needs to be maxed with fine.breadth
+ t: bar extended still more at right (RS)
+ v: decreased the width by .25width_adj#
+ w: overlap allowed as in W
+ second inner serif made no longer than left outer serif (MC)
+ ceiling must become floor, to ensure that x5r>=x4r-mid_corr
+ x: decreased the width by .5width_adj# (RS)
+ y: sans-serif tail curls up too far (RS)
+ z: beaks too light; decrease the diagonal to compensate (RS)
+ better positioning of y2 and y3 when tiny is zero
+ROMSPL.MF:
+ dotless i and j: as i and j
+ ae and oe: bottom terminal tilted the other way
+ ae: corrected as a
+ROMSPU.MF:
+ AE: x12 based on x1l rather than x1, works better in bold cases (RS)
+ OE: left curve not to be pulled
+GREEKU.MF:
+ Phi and Psi: middle parts must keep away from the serifs
+ROMANP.MF:
+ $: strengthened the terminals in sans-serif case, and tilted them
+ &: opened the eye by moving point 8 left .5u (RS)
+ ?: tilted the sans-serif terminal and moved it down a little more
+PUNCT.MF:
+ %: move the diagonal a bit left at the top
+ ( and ): 3.5( changed to 3(.
+ [ and ]: round changed to ceiling and floor, avoids disappearing brackets
+ @: inner a placed by its edges instead of its stem centers (RS)
+ITALL.MF:
+ f: lower bulb moved left; .5 changed to .6 between bulb and stem
+ k: bug in lower right stroke (missing e's)
+ l: bug in italic correction for math fitting (u not u#)
+ m: avoid hooks in monospace version
+ p: lengthed left serif at bottom from .5jut to .75jut
+ x: bulbs moved .25u further out; .5 used between bulb and stem
+ w: avoid hook in monospace version
+ITALIG.MF:
+ all five: changed like f
+ fi: made 1u less wide
+ fl,ffl: made .5u less wide, bulb now touches the l stem
+ ffi: made .75u less wide
+GREEKL.MF:
+ beta, gamma, zeta, xi, omega, varepsilon: +eps at the tight turns
+ gamma: final diagonal should be more slanted (MC)
+ zeta: as tall as xi, shallower diagonal slant (MC)
+ kappa: bug in lower right stroke (missing e's)
+ xi: raise the bottom diagonal and distort arc slightly (MC)
+ chi: introduce slight curve in main diagonal stroke
+ varphi: too wide at right half bowl (MC)
+ITALMS.MF:
+ wp: bulb smaller, bottom a little more open
+ITALD.MF:
+ 5: changed like 5 in ROMAND
+OLDDIG.MF:
+ 2: top a bit narrower, bottom a bit wider (MC)
+ 5: changed like 5 in ROMAND
+SYM.MF:
+ plus-minus: shift depends on u not asc_height
+SYMBOL.MF:
+ minus-plus: shift depends on u not asc_height
+ up-and-down arrows (characters '154 and '155): taller and deeper
+ clubsuit: wider
+ spadesuit: y1+1 changed to y1+.75 (also in clubsuit)
+ROMAN.MF:
+ eliminated kerning between L and O,C,G,Q,U (also in TEXTIT and CSC)
+MATHEX.MF:
+ font_x_height needed to be set, for positioning of accents
+CMB10.MF:
+ dishing is too much (on all bold fonts)
+CMR5.MF:
+ letter_fit decreased 10 to 5
+CMBX5.MF:
+ fudge should be 1 (cap_stem 8=:7 in aps mode was too much)
+ decrease letter_fit drastically; this means f-ligatures must come back
+ lowercase parameters increased by 2/36
+CMBI10.MF:
+ lowercase serifs too short. (same change to all the italic fonts)
+CMSX10.MF:
+ decrease `ess' (RS)
+CMTC10.MF:
+ fudge is too much in lowercase
+CMCC10.MF:
+ lowercase more extended
+ much less letterspace in caps
+ increase lower.cap_curve, decrease lower.o
+CMSQI8.MF:
+ slope shouldn't be so much (RS)
+ increase `ess' (RS)
+
+GENERAL:
+ serif-abutment corrections changed to +1 instead of +2
+ vround used for vertical rounding
+
+CMBASE.MF:
+ new way to set shrink_fit (0,1,2) for monotonicity with letter_fit
+ letter_fit not included in mono_charwd
+ fine must be positive (else we lose barbs)
+ thin_join must be positive (else h_stroke gives a bad pos)
+ Changes based on the `version 0' test fonts of July 12
+[not showing hundreds of changes to the `typography' of the programs]
+
+Driver files in general:
+Frequency info (from MANUAL.TEX[tex,dek]) was used to order the ligtables
+font_xheight changed to font_x_height (a change to PLAIN.MF)
+
+Program files in general:
+ use `hround' instead of `round' wherever granularity might be wanted
+ less_rounded was taken out; autorounded occasionally put in
+ arm($,$$,...), the value of y$$ was adjusted by eps (lower) or -eps (upper)
+
+Parameter files in general:
+ new 12pt and 17+pt fonts; more sans serif fonts
+ new comment at bottom of all parameter files: `switch to the driver file'
+
+ACCENT.MF:
+ ^: eps subtracted from y1 (helps avoid degenerate equations in ultralowres)
+ '`: eps added to y1
+
+ROMAN.MF:
+ kern entry for gj had the wrong sign
+ kerns for v removed in sans serif
+ new kern for aj in serif case
+ new kern for ar in sans serif
+
+ROMAND.MF:
+ 3: pos3 needed to be maxed with fine.breadth
+ y1r,y9r needed to be adjusted by eps
+ 6,9: keep x1 on the correct side of x2 at lowlowres
+ (this change also affects OLDDIG, ITALD, and ITALMS partial sign)
+
+ROMANP.MF:
+ $: less_tense bulbs
+
+ROMSPL.MF:
+ ss: ensure x5 not > x4l at low resolutions
+
+ROMLIG.MF:
+ itc shouldn't include the slant...
+
+COMLIG.MF:
+ em dash should be one em wide (add letter_fit# to the adjustments)
+
+BIGOP.MF:
+ \displaystyle coproduct sign had 1.2bracket instead of 1.8bracket
+ charlist syntax changed from commas to colons
+
+BIGDEL.MF:
+ extensible double arrow: position wasn't computed as in top and bottom
+ charlist syntax changed from commas to colons
+
+BIGACC.MF:
+ charlist syntax changed from commas to colons
+
+ITALL.MF:
+ c: point 1 made definitely greater than point 2, for lowlowres
+ q: x4 increased by eps, for lowlowres path intersection
+ r: x4 based on w, not 5u
+ s: max(ess,fine.breadth)
+ add eps and 2eps for lowlowres case (cmmi6 at 100/in)
+
+ITALMS.MF:
+ wp: x6r must not be less than x1r at lowlowres
+
+TSETSL.MF:
+ gamma: last time's bugfix from GREEKL needs to be here too
+
+GREEKL.MF:
+ omega: add 2eps to x4-x6
+ lambda: make sure that y3>y4 at lowlowres
+ zeta: make sure that x2>x0 at lowlowres
+ varsigma: make sure that x1>x2 at lowlowres
+
+CMFIB8.MF:
+ decreased serif_fit, cap_serif_fit; increased curve, cap_curve
+
+CMBASE.MF:
+ l,r made newinternals
+ serif darkness and skew switches now done with boolean variables
+ comma and ammoc: 2eps addedto/subtractedfrom position of x@2
+ mod_width now called change_width
+ ess and cap_ess initialized to preserve ratios with stem and cap_stem
+ mode="string" had to be handled properly
+ ^ and ! changed to t_ and o_, as per new PLAIN conventions
+ make cmchar "outer"
+ t_ is now `relaxed' if it is useless
+ soft is now softjoin in PLAIN (we must set join_radius:=u)
+ eps is now in PLAIN
+ vair is vrounded but at least 1; also slab, etc.
+ cal nibs, yscaled by cap_hair not vair
+ autorounding and smoothing turned off
+
+ROMANL.MF:
+ a: `footed' version is .25u tighter at the right
+ b,d,varg,p,q: x4l position relative to .5(w-serif_fit) not 5u
+ e: testpath uses .r not .l (because of cmss10)
+ f: added 1 at right for monospace lowres versions
+ varg: robust sans-serif terminal at tail
+ m: missing `round' in r adjustment caused noninteger chardx
+ r: x4 based on w, not 5.25u
+ s: watch out that ess isn't so small that badpos error occurs (also ROMANU)
+ barbs made longer; based on middle stroke not just h
+ t: sans-serif terminal made more robust in extreme cases
+ w: in non-monospace hefty serif case, the middle point comes to .8h not h
+ y: robust sans-serif terminal at tail
+
+ROMANU.MF:
+ E: good.y used in y9
+
+PUNCT.MF:
+ []: side_thickness needed to be maxed with crisp.breadth
+ +1 or -1 makes lowres versions more distinctive
+ #: tricky part lost at low resolution
+
+SYMBOL.MF:
+ angle brackets: +1 and -1 to make lowres versions more distinctive
+ aleph: eps added so that y5 will be well defined at lowlowres
+
+SYM.MF:
+ integral sign: bulbs need to be in right direction at lowlowres
+
+CALU.MF:
+ A: apex moved slightly down
+ D: less flat at top, slightly lower lobe
+ F: u less right sidebar
+ H: soft corner at upper left
+ I: middle stroke more like J, upper bar a little further right
+ K: introduce t_ in case of aspect_ratio
+ L: darker
+ M: lighter first diagonal; clean the joins
+ N: lighter diagonal; clean bottom right; .5u less right sidebar
+ O: shortened the inner stroke
+ P: stem comes lower
+ Q: tail not so long at left
+ R: not so flat at top; diagonal less tense; tail less high
+ T: narrower, also changed like I, .5u less right sidebar,
+ heavier, not so high at right
+ U: less extreme curve at lower left
+ V: cleaned up at bottom; lighter first diagonal; slightly wider
+ W: changed like V, but double
+ X: new design, less rigid
+ Y: new design based more on V than U
+ Z: tighter at right, heavier at top and bottom
+
+CMSS10.MF:
+ decreased notch_cut and bar_height
+
+%Note: The following can presumably be deleted; I removed it from CMBASE because
+% I don't think it is used any more:
+vardef parallel_pos(expr d,u,v,w) = % point at distance $d$ from $u$,
+ % on the line through $w$ that's parallel to |u..v|
+ pair p_; p_=w+whatever*(u-v)=u+whatever*(u-v) rotated 90;
+ numeric d_; d_=length(u-p_); % distance from $w$ to |u..v|
+ if d_>=d: p_ else: p_+(d+-+d_)*unitvector(v-u) fi enddef;
+ Changes subsequent to `Version 1' as released on October 7, 1985.
+
+1. thin_join should be subject to blacker:
+@x in CMBASE.MF, the font_setup routine
+ define_whole_pixels(letter_fit,thin_join,fine,crisp,tiny);
+ define_whole_vertical_pixels(body_height,asc_height,
+ cap_height,fig_height,x_height,comma_depth,desc_depth,serif_drop);
+ define_whole_blacker_pixels(hair,stem,curve,flare,
+@y
+ define_whole_pixels(letter_fit,fine,crisp,tiny);
+ define_whole_vertical_pixels(body_height,asc_height,
+ cap_height,fig_height,x_height,comma_depth,desc_depth,serif_drop);
+ define_whole_blacker_pixels(thin_join,hair,stem,curve,flare,
+@z
+@x
+ if thin_join=0: thin_join:=1; fi
+@y
+@z
+[Note, December 11: My first correction also introduced the statement
+ if fine<thin_join: fine:=thin_join; fi
+in place of
+ if fine=0: fine:=1; fi
+but I can't understand why I would do such a stupid thing!]
+
+2. A new subroutine needed in CMBASE.MF (for cases with aspect_ratio<>1):
+vardef Vround primary y = y_:=vround y;
+ if y_<min_Vround: min_Vround else: y_ fi enddef;
+newinternal y_,min_Vround;
+
+@x related changes to the font_setup routine (in CMBASE.MF):
+ forsuffixes $=vair,bar,slab,cap_bar,cap_band:
+ $:=vround($.#*hppp+blacker); if $<=1: $:=1; fi endfor
+@y
+ define_whole_vertical_blacker_pixels(vair,bar,slab,cap_bar,cap_band);
+@z
+@x
+ vair':=max(1,vround(vair+vair_corr));
+ vstem:=max(1,vround .8[vair,stem]);
+ cap_vstem:=max(1,vround .8[vair,cap_stem]);
+@y
+ vair':=vround(vair+vair_corr);
+ vstem:=vround .8[vair,stem]; cap_vstem:=vround .8[vair,cap_stem];
+@z
+@x
+ pickup pencircle scaled rule_thickness; rule.nib:=savepen;
+@y
+ min_Vround:=max(fine.breadth,crisp.breadth,tiny.breadth);
+ forsuffixes $=vair,bar,slab,cap_bar,cap_band,vair',vstem,cap_vstem:
+ if $<min_Vround: $:=min_Vround; fi endfor
+ pickup pencircle scaled rule_thickness; rule.nib:=savepen;
+@z
+
+The Vround routine is substituted for vround in the programs for
+ Macron, line 6 (in ACCENT.MF)
+ Variant epsilon, line 5 (in GREEKL.MF)
+ Sigma, line 6 (in GREEKU.MF)
+ Omega, line 14 (in GREEKU.MF)
+ 2, line 6 (in OLDDIG.MF and ROMAND.MF)
+ 7, lines 6 and 8 (in OLDDIG.MF and ROMAND.MF)
+ g, lines 6 and 8 (in ROMANL.MF)
+ s, line 6 (in ROMANL.MF)
+ y, line 9 (in ROMANL.MF)
+ z, line 6 (in ROMANL.MF)
+ &, line 39 (in ROMANP.MF)
+ ?, line 18 (in ROMANP.MF)
+ Spanish open ?, line 17 (in ROMANP.MF)
+ Z, line 6 (in ROMANU.MF)
+ smile and frown, line 4 (in ROMMS.MF)
+
+3. Typo in program for oe ligature.
+@x in file ROMSPL.MF
+else: left_curve=max(tiny.breadth,hround(curve-2stem_corr));
+@y
+else: left_curve=max(fine.breadth,hround(curve-2stem_corr));
+@z
+
+4. Forgotten update to program for SS.
+@x in file CSCSPU.MF
+pickup fine.nib; pos2(max(fine.breadth,s_slab-vround vair_corr),-90);
+pos0(cap_ess,theta); pos7(s_slab,-90);
+x2+x7=2x0=w; x7-x2=if serifs: u else: 0 fi; top y2l=h+o; bot y7r=-o;
+y0=.52h; lft x3l=hround u; rt x6r=hround(w-u);
+x3r-x3l=x6r-x6l=hround .5[s_slab,cap_ess] -fine;
+@y
+numeric ess'; ess'=max(fine.breadth,cap_ess);
+pickup fine.nib; pos2(max(fine.breadth,s_slab-vround vair_corr),-90);
+pos0(ess',theta); pos7(s_slab,-90);
+x2+x7=2x0=w; x7-x2=if serifs: u else: 0 fi; top y2l=h+o; bot y7r=-o;
+y0=.52h; lft x3l=hround u; rt x6r=hround(w-u);
+x3r-x3l=x6r-x6l=hround .5[s_slab,ess']-fine;
+@z
+
+5. Hairline in `k' was overcorrected. (Pavel Curtis)
+@x in file ROMANL.MF
+stem3=max(tiny.breadth,hround(fudged.hair-4stem_corr));
+@y
+stem3=max(tiny.breadth,hround(fudged.hair if hefty:-\\4stem_corr fi));
+@z
+
+6. Too much kerning in "We", etc., in sans-serif fonts
+@x in file ROMAN.MF and TEXSET.MF
+ ligtable "F": "V": "W": "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+@y
+ ligtable "F": "V": "W": if serifs: "o" kern kk#, "e" kern kk#, "u" kern kk#,
+ "r" kern kk#, "a" kern kk#, "A" kern kkk#,
+ else: "o" kern k#, "e" kern k#, "u" kern k#,
+ "r" kern k#, "a" kern k#, "A" kern kk#, fi
+@z
+@x in file TITLE.MF
+ ligtable "F": "V": "W": "A" kern kkk#,
+@y
+ ligtable "F": "V": "W": "A" kern if serifs: kkk# else: kk#\\fi,
+@z
+@x in file CSC.MF
+ ligtable "F": "V": "W": "a" kern kkk#, "A" kern kkk#,
+@y
+ ligtable "F": "V": "W": if serifs: "a" kern kkk#, "A" kern kkk#,
+ else: "a" kern kk#, "A" kern kk#, fi
+@z
+@x in file CSC.MF
+ ligtable "f": "v": "w": "a" kern kkk#,
+@y
+ ligtable "f": "v": "w": "a" kern if serifs: kkk# else: kk#\\fi,
+@z
+
+7. dish serifs need to be more robust when dishing is very small.
+@x in file CMBASE.MF
+ if y$<y$$: dish_out=bot y$; dish_in=dish_out+dish;
+ else: dish_out=top y$; dish_in=dish_out-dish; fi
+ erase fill\\(x@1,dish_out)..(x$,dish_in){right}..(x@@1,dish_out)--cycle;
+@y
+ if y$<y$$: dish_out=bot y$; dish_in=dish_out+dish; let rev_=reverse;
+ else: dish_out=top y$; dish_in=dish_out-dish; let rev_=relax; fi
+ erase fill rev_
+ ((x@1,dish_out)..(x$,dish_in){right}..(x@@1,dish_out)--cycle);
+@z
+
+8. more robustness in case thin_join is too big
+@x in file ROMANL.MF, program for "b"
+pos4(vair,90); pos5(curve,0);
+pos6(vair,-90); penpos7(x3l-x3r,-180);
+rt x3l=1/3[rt x2,edge]; y3=1/8[bar_height,x_height];
+@y
+pos4(vair,90); pos5(curve,0); pos6(vair,-90); penpos7(x3l-x3r,-180);
+rt x3l=max(rt x3l-(lft x3r-tiny.lft x2l),1/3[rt x2,edge]);
+y3=1/8[bar_height,x_height];
+@z
+@x ibid, program for "d"
+pos4(vair,90); pos5(curve,180);
+pos6(vair,270); penpos7(x3r-x3l,360);
+lft x3l=1/3[lft x2,edge]; y3=1/8[bar_height,x_height];
+@y
+pos4(vair,90); pos5(curve,180); pos6(vair,270); penpos7(x3r-x3l,360);
+lft x3l=min(lft x3l-(rt x3r-tiny.rt x2r),1/3[lft x2,edge]);
+y3=1/8[bar_height,x_height];
+@z
+@x ibid, program for variant "g"
+pos4(vair,90); pos5(curve,180);
+pos6(vair,270); penpos7(x3r-x3l,360);
+lft x3l=2/3[lft x2,edge]; y3=bar_height;
+@y
+pos4(vair,90); pos5(curve,180); pos6(vair,270); penpos7(x3r-x3l,360);
+lft x3l=min(lft x3l-(rt x3r-tiny.rt x2r),2/3[lft x2,edge]); y3=bar_height;
+@z
+@x ibid, program for "p"
+rt x3l=1/3[rt x2,edge]; y3=1/8[bar_height,x_height];
+@y
+rt x3l=max(rt x3l-(lft x3r-tiny.lft x2l), 1/3[rt x2,edge]);
+y3=1/8[bar_height,x_height];
+@z
+@x ibid, program for "q"
+lft x3l=2/3[lft x2,edge]; y3=bar_height;
+@y
+lft x3l=min(lft x3l-(rt x3r-tiny.rt x2r),2/3[lft x2,edge]); y3=bar_height;
+@z
+@x ibid, proram for "q"
+x6l=x4l-.2u; bot y6r=-oo;
+lft x7l=1/3[lft x2,edge]; y7=min(y3,y6+y4-y3+.6vair);
+@y
+x6l=x4l-.2u; bot y6r=-oo; y7=min(y3,y6+y4-y3+.6vair);
+lft x7l=min(lft x7l-(rt x7r-tiny.rt x2r),1/3[lft x2,edge]);
+@z
+
+9. More robust "c" and "e" and "C"
+@x in file ROMANL.MF, program for "c"
+ (x,y4l)=whatever[z4r,z5l]; x4l:=x;
+@y
+ (x,y4l)=whatever[z4r,z5l]; x4l:=min(x,x4l+.5u);
+@z
+@x ibid, program for "e"
+ (x,y4l)=whatever[z4r,z5]; x4l:=x;
+@y
+ (x,y4l)=whatever[z4r,z5]; x4l:=min(x,x4l+.5u);
+@z
+@x in file ROMSPL.MF, programs for "ae" and "oe"
+ (x,y14l)=whatever[z14r,z15]; x14l:=x;
+@y
+ (x,y14l)=whatever[z14r,z15]; x14l:=min(x,x14l+.5u);
+@z
+@x in file ROMANU.MF, programs for "C" and "G"
+ (x2l',y2l)=whatever[z2r,z1l]; x2l:=x2l';
+ (x4l',y4l)=whatever[z4r,z5l]; x4l:=x4l';
+@y
+ (x2l',y2l)=whatever[z2r,z1l]; x2l:=min(x2l',x2l+.5u);
+ (x4l',y4l)=whatever[z4r,z5l]; x4l:=min(x4l',x4l+.5u);
+@z
+
+10. More robust foot in "a"
+@x in file ROMANL.MF
+ filldraw stroke z5'e---z10e...z11e{right}; % foot
+@y
+ pos12(shaved_stem,0); x11=x12; top y12=slab+eps;
+ filldraw z5'l---z10l...z11l{right}--z11r
+ --z12r{left}...z10r+.75(z12-z11)---z5'r--cycle; % foot
+@z
+
+11. Barbs less sharp
+@x in file ROMANU.MF, programs for "C" and "G"
+ x6=x1r; top y6=h+o; x1r-x1'=2cap_curve-fine; y1'=y1;
+ path upper_arc; upper_arc=z1{x2-x1,10(y2-y1)}..z2{left};
+ numeric t; t=xpart(upper_arc intersectiontimes (z6--z1'));
+ filldraw z1r--z6--subpath(t,0) of upper_arc--cycle; % barb
+@y [actually "G" had something similar but not identical]
+ pos6(.3[fine.breadth,cap_hair],0); x6r=x1r; top y6=h+o;
+ x1r-x1'=2cap_curve-fine; y1'=y1;
+ path upper_arc; upper_arc=z1{x2-x1,10(y2-y1)}..z2{left};
+ numeric t; t=xpart(upper_arc intersectiontimes (z6l--z1'));
+ filldraw z1r--z6r--z6l--subpath(t,0) of upper_arc--cycle; % barb
+@z
+@x ibid, program for "S"
+ x10=x1l; top y10=top y2l; x9=x8r; bot y9=bot y7r;
+ x1l-x1'=x8'-x8r=1.6cap_curve-fine; y1'=y1; y8'=y8;
+ numeric t; t=xpart(upper_arc intersectiontimes(z10--z1'));
+ filldraw z1l--z10--subpath(t,0) of upper_arc--cycle; % upper barb
+ t:=xpart(lower_arc intersectiontimes(z9--z8'));
+ filldraw z8r--z9--subpath(t,1) of lower_arc--cycle; % lower barb
+@y
+ pos10(.3[fine.breadth,cap_hair],0); pos9(.3[fine.breadth,cap_hair],0);
+ x10r=x1l; top y10=top y2l; x9l=x8r; bot y9=bot y7r;
+ x1l-x1'=x8'-x8r=1.6cap_curve-fine; y1'=y1; y8'=y8;
+ numeric t; t=xpart(upper_arc intersectiontimes(z10l--z1'));
+ filldraw z1l--z10r--z10l--subpath(t,0) of upper_arc--cycle; % upper barb
+ t:=xpart(lower_arc intersectiontimes(z9r--z8'));
+ filldraw z8r--z9l--z9r--subpath(t,1) of lower_arc--cycle; % lower barb
+@z [the same change goes into file CSCSPU.MF, the program for two S's]
+@x in file ROMANL.MF, program for "s"
+ x10=x1l; top y10=top y2l; x9=x8r; bot y9=bot y7r;
+ x1l-x1'=x8'-x8r=1.6curve-fine; y1'=y1; y8'=y8;
+ numeric t; t=xpart(upper_arc intersectiontimes(z10--z1'));
+ filldraw z1l--z10--subpath(t,0) of upper_arc--cycle; % upper barb
+ t:=xpart(lower_arc intersectiontimes(z9--z8'));
+ filldraw z8r--z9--subpath(t,1) of lower_arc--cycle; % lower barb
+@y
+ pos10(.3[fine.breadth,cap_hair],0); pos9(.3[fine.breadth,cap_hair],0);
+ x10r=x1l; top y10=top y2l; x9l=x8r; bot y9=bot y7r;
+ x1l-x1'=x8'-x8r=1.6cap_curve-fine; y1'=y1; y8'=y8;
+ numeric t; t=xpart(upper_arc intersectiontimes(z10l--z1'));
+ filldraw z1l--z10r--z10l--subpath(t,0) of upper_arc--cycle; % upper barb
+ t:=xpart(lower_arc intersectiontimes(z9r--z8'));
+ filldraw z8r--z9l--z9r--subpath(t,1) of lower_arc--cycle; % lower barb
+@z
+
+12. Italic ampersand more robust
+@x in file ITALP
+ & pulled_arc.e(9,10)...{dir(theta+90)}z11e; % bowls, loop, and stem
+@y
+ & {{interim superness:=more_super; pulled_arc.e(9,10)}}
+ ..tension .9 and 1..{dir(theta+100)}z11e; % bowls, loop, and stem
+@z
+
+13. h_stroke more robust (esp in case of typewriter-style m)
+@x in file CMBASE
+ pickup fine.nib; pos@0(thin_join,180);
+@y
+ penpos@0(min(rt x$r-lft x$l,thin_join)-fine,180); pickup fine.nib;
+@z
+
+14. eliminate dishing in conflict with arm.
+Put a new subroutine into CMBASE.MF:
+def nodish_serif(suffix $,$$,@)(expr left_darkness,left_jut)
+ (suffix @@)(expr right_darkness,right_jut) suffix modifier =
+ serif($,$$,@,left_darkness,-left_jut) modifier;
+ serif($,$$,@@,right_darkness,right_jut) modifier; enddef;
+
+Now use this instead of dish_serif in the following places:
+GREEKU: Gamma, upper serif
+ Pi, both upper serifs (fix erroneous comments!)
+SYMBOL: Amalgamation, both lower serifs (fix erroneous comments!)
+ROMANU: B, both serifs
+ D, both serifs
+ E, both serifs
+ F, upper serif
+ L, lower serif
+ P, upper serif
+ R, upper serif
+ T, upper bracketing
+ROMSPU: AE, upper and lower middle serifs
+
+15. Change #2 wasn't quite good enough!
+@x in CMBASE
+ min_Vround:=max(fine.breadth,crisp.breadth,tiny.breadth);
+@y
+ min_Vround:=max(fine.breadth,crisp.breadth,tiny.breadth);
+ if min_Vround<vround min_Vround: min_Vround:=vround min_Vround; fi
+ if flare<vround flare: flare:=vround flare; fi
+@z
+
+16. body_depth# is now called paren_depth#, since body_depth is
+computed differently. (This is a cosmetic change only; it affects
+files CMBASE, PUNCT, SYM, SYMBOL, and ROMMS.)
+
+17. more robust Sigma
+@x in GREEKU, page 9
+top y1=h; bot y2=h-slab; bot y4=0; x3l-x1l=4/11(w-2u); y3=.5h;
+@y
+top y1=h; bot y2=h-slab-eps; bot y4=0; x3l-x1l=4/11(w-2u); y3=.5h;
+@z
+@x in BIGOP, page 7
+top_arm_thickness=rule_thickness;
+@y
+top_arm_thickness=Vround rule_thickness;
+@z
+@x in BIGOP, page 7 (this change needed twice)
+top y1=0; bot y2=-top_arm_thickness; bot y4=-d; y3=-.5d;
+@y
+top y1=0; bot y2=-top_arm_thickness-eps; bot y4=-d; y3=-.5d;
+@z
+
+18. yet another refinement of change #2
+@x in CMBASE
+ forsuffixes $=vair,bar,slab,cap_bar,cap_band,vair',vstem,cap_vstem:
+@y
+ forsuffixes $=vair,bar,slab,cap_bar,cap_band,vair',vstem,cap_vstem,bold:
+@z
+
+19. slightly more robust `k'
+@x in ROMANL
+top y3=x_height; rt x3r=hround(r-letter_fit-.7u-right_jut);
+bot y6=0; rt x6r=hround(r-letter_fit-.3u-right_jut);
+@y
+top y3=x_height; rt x3r=hround(r-letter_fit-.7u-right_jut)+eps;
+bot y6=0; rt x6r=hround(r-letter_fit-.3u-right_jut)+eps;
+@z
+
+20. small parameter changes for consistency
+@x in CMBX6
+dish#:=.9/36pt#; % amount erased at top or bottom of serifs
+@y
+dish#:=.8/36pt#; % amount erased at top or bottom of serifs
+@z
+@x in CMBX5
+dish#:=.75/36pt#; % amount erased at top or bottom of serifs
+@y
+dish#:=.7/36pt#; % amount erased at top or bottom of serifs
+@z
+@x in CMSS9 and CMSSI9 [these two lines are not consecutive in the files!]
+notch_cut#:=23/36pt#; % maximum breadth above or below notches
+cap_notch_cut#:=29/36pt#; % max breadth above/below uppercase notches
+@y
+notch_cut#:=17/36pt#; % maximum breadth above or below notches
+cap_notch_cut#:=24/36pt#; % max breadth above/below uppercase notches
+@z
+@x in CMSS8 and CMSSI8 [these two lines are not consecutive in the files!]
+notch_cut#:=21/36pt#; % maximum breadth above or below notches
+cap_notch_cut#:=27/36pt#; % max breadth above/below uppercase notches
+@y
+notch_cut#:=16/36pt#; % maximum breadth above or below notches
+cap_notch_cut#:=22/36pt#; % max breadth above/below uppercase notches
+@z
+@x in CMTI9
+cap_hair#:=10/36pt#; % uppercase hairline breadth
+@y
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+@z
+@x in CMTI8
+cap_hair#:=9.5/36pt#; % uppercase hairline breadth
+@y
+cap_hair#:=11/36pt#; % uppercase hairline breadth
+@z
+@x in CMTI7
+cap_hair#:=9/36pt#; % uppercase hairline breadth
+@y
+cap_hair#:=10.5/36pt#; % uppercase hairline breadth
+@z
+@x in CMTCSC10
+lower.cap_notch_cut#:=24pt#; % max breadth above/below uppercase notches
+@y
+lower.cap_notch_cut#:=24/36pt#; % max breadth above/below uppercase notches
+@z
+
+21. New parameter file CMFI10 was added; font_identifier is "CMFI".
+Also changed the name `cmit10' to `cmitt10'; font_identifier is "CMITT".
+
+22. Still more changes for robustness (based on resolution h120 x v108).
+@x in ROMAND and ITALD, "5"
+bot y5=vround(.53h-vair); top y6r=vround .61803h+o;
+@y
+bot y5=vround(.53h-vair); top y6r=max(vround .61803h+o,top y6r+y5+eps-y6l);
+@z
+@x in OLDDIG, "5"
+bot y5=vround(.53[-d,h]-vair); top y6r=(vround .61803[-d,h])+o;
+@y
+bot y5=vround(.53[-d,h]-vair);
+top y6r=max((vround .61803[-d,h])+o,top y6r+y5+eps-y6l);
+@z
+@x in ROMANU, "C"
+ bot y1=vround max(.6h,x_height-.5vair); y5=good.y .95(h-y1);
+@y
+ bot y1=min(vround max(.6h,x_height-.5vair),bot y2l-eps);
+ y5=max(good.y .95(h-y1),y4l+eps);
+@z
+@x in ROMANU, "G"
+ bot y1=vround max(.6h,x_height-.5vair);
+@y
+ bot y1=min(vround max(.6h,x_height-.5vair),bot y2l-eps);
+@z
+@x in GREEKL page 6 and TSETSL page 8
+y1=.9h; top y2l=h+oo; top y8r=x_height+oo; y4=y8;
+@y
+top y2l=h+oo; y1=min(.9h,y2r-eps); top y8r=x_height+oo; y4=y8;
+@z
+@x in GREEKL page 16
+x6=x7=w-2u; x8=.5w+.5u; y6=-.3d; y8=-3/4d-oo; bot y7r=-d-oo;
+@y
+x6=x7=w-2u; x8=.5w+.5u; y6=-.3d; bot y7r=-d-oo; y8=max(-3/4d-oo,y7l);
+@z
+@x in ITALL page 12, ITALMS page 6, ITALSP page 4
+lft x5r=hround-.5u; x4=1/3(w-u);
+@y
+x4=1/3(w-u); lft x5r=min(hround-.5u,lft x5r+x4-x5l-eps);
+@z
+@x in ROMANL, "g"
+x11=x13=.5w; bot y13r=-d-oo-1; x14=w-x12; z10'l=z10l;
+@y
+x11=x13=max(.5w,x10+eps); bot y13r=-d-oo-1; x14=w-x12; z10'l=z10l;
+@z
+@x in ROMANL, "s"
+ filldraw stroke z1e..tension.9..{left}z2e; % upper arc and terminal
+ filldraw stroke z7e{left}..z8e; fi % lower arc and terminal
+@y
+ filldraw stroke term.e(2,1,right,.9,4); % upper arc and terminal
+ filldraw stroke term.e(7,8,left,1,4); fi % lower arc and terminal
+@z
+@x in ROMANL, "c"
+ filldraw stroke pulled_super_arc.e(2,3)(.7superpull)
+ & pulled_super_arc.e(3,4)(.5superpull)
+ ..tension .9 and 1..z5e; fi % arc and lower terminal
+@y
+ forsuffixes e=l,r: path p.e; p.e=z4e{right}..tension .9 and 1..z5e;
+ if angle direction 1 of p.e>75:
+ p.e:=z4e{right}..tension atleast.9 and 1..{dir 75}z5e; fi endfor
+ filldraw stroke pulled_super_arc.e(2,3)(.7superpull)
+ & pulled_super_arc.e(3,4)(.5superpull) & p.e; fi % arc and lower terminal
+@z
+@x in ROMSPL, page 5
+lft x8r=hround(stem_edge+.5u+1); x7=max(x8l+eps,.4[lft x8r,x6]);
+@y
+lft x8r=min(hround(stem_edge+.5u+1),lft x8r+x6r-2eps-x8l);
+x7=max(x8l+eps,.4[lft x8r,x6]);
+@z
+@x in ROMAND and OLDDIG, "2"
+ lft x1r=hround .75u; bot y1l=vround .7h; y1r:=good.y y1r; x1l:=good.x x1l;
+@y
+ lft x1r=hround .75u; bot y1l=vround .7h; y1r:=good.y y1r+eps; x1l:=good.x x1l;
+@z
+@x in SYMBOL, page 42 (Fraktur R)
+z=(z20{up}...{right}z21)intersectionpoint(z22l--z22l+(h,0) rotated theta);
+@y
+path p; p=z20{up}...(z21--(w,y21));
+z=p intersectionpoint(z22l--z22l+(h,0) rotated theta);
+@z
+
+23. Another consequence of change 2:
+"vround" should be "Vround" in the BIGDEL programs for extensible arrows
+(five times).
+Also five times in the BIGOP programs for summation, product, coproduct.
+
+24. Cosmetic change to bring CMBASE in line with PLAIN.
+@x in CMBASE.MF
+def pickup secondary q =
+ if numeric q: currentpen:=pen_[q];
+ pen_top:=pen_top_[q]; pen_bot:=pen_bot_[q];
+ pen_lft:=pen_lft_[q]; pen_rt:=pen_rt_[q];
+ currentpen_path:=pen_path_[q];
+ if known breadth_[q]: currentbreadth:=breadth_[q]; fi
+ else: currentpen:=q yscaled aspect_ratio;
+ pen_top:=(ypart penoffset left of currentpen)_o_;
+ pen_bot:=(ypart penoffset right of currentpen)_o_;
+ pen_lft:=xpart penoffset down of currentpen;
+ pen_rt:=xpart penoffset up of currentpen;
+ path currentpen_path;
+ fi enddef;
+@y
+def numeric_pickup_ primary q =
+ currentpen:=pen_[q];
+ pen_lft:=pen_lft_[q]; pen_rt:=pen_rt_[q];
+ pen_top:=pen_top_[q]; pen_bot:=pen_bot_[q];
+ currentpen_path:=pen_path_[q];
+ if known breadth_[q]: currentbreadth:=breadth_[q]; fi enddef;
+@z
+
+25. false italic correction in lambda of texset fonts (Feb 25, 1986)
+@x in TEXSET
+mode_setup; font_setup;
+@y
+mode_setup; font_setup; mono_charic#:=0;
+@z
+@x ibid
+slant:=mono_charic#:=0; % the remaining characters will not be slanted
+@y
+slant:=0; % the remaining characters will not be slanted
+@z
+[now remove the occurrences of `charic:=0;' in TSETSL, as they are unnecessary]
+
+*** The above changes are incorporated into the published book,
+*** Computer Modern Typefaces; this is "Version 2" (released March 5, 1986).
+ Changes subsequent to `Version 2' as published in C&T, Volume E:
+
+@x in GREEKU
+numeric shaved_stem; shaved_stem=hround .9[vair,.85cap_stem];
+@y
+numeric shaved_stem; shaved_stem=hround .9[vair,.85cap_stem];
+if shaved_stem<crisp.breadth: shaved_stem:=crisp.breadth; fi
+@z
+
+@x in CMSS9 [this affects the TFM file to a small extent!]
+fig_height#:=236/36pt#; % height of numerals
+@y
+fig_height#:=212/36pt#; % height of numerals
+@z
+
+@x in CMSSI9 [this affects the TFM file in ten hts and eleven italcorrs]
+fig_height#:=236/36pt#; % height of numerals
+@y
+fig_height#:=212/36pt#; % height of numerals
+@z
+
+@x in CMR17 [no change to TFM file]
+curve#:=41/36pt#; % lowercase curve breadth
+@y
+curve#:=40/36pt#; % lowercase curve breadth
+@z
+@x
+cap_stem#:=40/36pt#; % uppercase stem breadth
+cap_curve#:=48/36pt#; % uppercase curve breadth
+@y
+cap_stem#:=41/36pt#; % uppercase stem breadth
+cap_curve#:=47/36pt#; % uppercase curve breadth
+@z
+@x
+serif_drop#:=17/36pt#; % vertical drop of sloped serifs
+@y
+serif_drop#:=7/36pt#; % vertical drop of sloped serifs
+@z
+
+@x in ROMAND [this fixes the `disappearing hairline' in some lowres 8's]
+ lower_side=hround(.5[hair,stem]+stem_corr);
+@y
+ lower_side=hround(.5[hair,stem]+stem_corr);
+ if lower_side>1.2upper_side: upper_side:=lower_side; fi
+@z
+% Note: the SAME change should also be made in files ITALD and OLDDIG
+
+@x in ITALL [this fixes italic ell especially at low resolutions]
+top y1=h; x1=x2; filldraw stroke z1e--z2e; % stem
+@y
+top y1=h; x1=x2; filldraw stroke z1e--z2'e; % stem
+@z
+
+@x in SYM, the plus-or-minus character
+x1=x2=.5w; lft x3=lft=x5=hround u-eps; x4=x6=w-x3;
+@y
+x1=x2=.5w; lft x3=lft x5=hround u-eps; x4=x6=w-x3;
+@z actually the code worked but it was "infelicitous"
+
+@x in SYMBOL, the minus-or-plus character
+x1=x2=.5w; lft x3=lft=x5=hround u-eps; x4=x6=w-x3;
+@y
+x1=x2=.5w; lft x3=lft x5=hround u-eps; x4=x6=w-x3;
+@z actually the code worked but it was "infelicitous"
+
+@x in ROMANU, letter J [fixes a bug if dish=0 and crisp<tiny and serifs]
+ bulb(3,4,5); % bulb
+@y
+ pickup tiny.nib; bulb(3,4,5); % bulb
+@z
+
+@x in ROMANL, letter w [makes notch_cut more useful]
+ else: fill diag_end(6r,5r,1,1,5l,6l)--.5[z5l,z6l]
+ --.5[z5r,z6r]--cycle;% middle stem
+@y
+ else: fill diag_end(6r,5r,1,1,5l,6l)--.9[z5l,z6l]
+ ..{z5-z6}.1[z5r,z6r]--cycle; % middle stem
+@z the same change applies also to letter W in ROMANU
+
+@x in CMBASE, makes lowres types (especially TT) look better
+ define_blacker_pixels(notch_cut,cap_notch_cut);
+@y
+ define_blacker_pixels(notch_cut,cap_notch_cut);
+ forsuffixes $=notch_cut,cap_notch_cut: if $<3: $:=3; fi endfor
+@z
+
+@x in BIGOP, the \displaystyle coproduct sign
+lft x11=hround u; x1l-x11=x2l-x12=x22-x2r=hround cap_jut;
+@y
+lft x11=hround u; x1l-x11=x2l-x12=x22-x2r=hround 1.6cap_jut;
+@z
+
+@x in ROMANL, the letter m
+lft x1l=hround(2.5u-.5stem); x1l=x1'l=x2l=x2'l;
+lft x3l=hround(.5w-.5stem); x5-x3=x3-x1;
+if not monospace: r:=hround(x5+x1)-l; fi % change width for better fit
+@y
+lft x1l=hround(2.5u-.5stem); x1l=x1'l=x2l=x2'l; % stem, sic
+lft x3l=hround(.5w-.5mfudged.stem); x5-x3=x3-x1;
+if not monospace: r:=hround(x5+x1)+r-w; fi % change width for better fit
+@z
+
+@x a new routine for CMBASE, following change_width
+@y
+def center_on(expr x) = if not monospace: % change width for symmetric fit
+ r:=r+2x-w; w:=2x; fi enddef;
+@z
+@x in SYMBOL, the elementary division operator
+x3-.5dot_size=hround(.5w-.5dot_size); w:=r:=2x3;
+@y
+x3-.5dot_size=hround(.5w-.5dot_size); center_on(x3);
+@z
+Similarly, whenever the construction "w:=r:=2x*" appears, change it to
+"center_on(x*)". This happens in the programs for elementary division operator
+(as noted above), large triangle, large inverted triangle, lattice top,
+lattice bottom, dagger mark, double dagger mark, club/diamond/heart/spade suit
+(all in SYMBOL), plus the diamond operator and universal quantifier in SYM.
+The following additional change needs to be made in the programs
+for lattice top and lattice bottom:
+@x
+x1=x2=good.x .5w; center_on(x1); lft x3=hround u; x4=r-x3;
+@y
+x1=x2=good.x .5w; center_on(x1); lft x3=hround u; x4=w-x3;
+@z
+
+@x in SYMBOL, at end of zero-width slash
+labels(1,2); zero_width; endchar;
+@y
+labels(5,6); zero_width; endchar;
+@z
+
+@x in ROMANU, the letter Q (this change simply labels point 8 on proofs)
+math_fit(-.3cap_height#*slant-.5u#,ic#); penlabels(1,2,3,4,5,6,7); endchar;
+@y
+math_fit(-.3cap_height#*slant-.5u#,ic#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+@z
+
+@x in ROMANL, the letter i (this change by Jonathan Kew makes the dot rounder)
+if serifs: x3r=max(x1r,x1+.5(dot_diam-tiny)-.2jut) else: x3=x1-.5 fi;
+@y
+if serifs: x3r=max(x1r,hround(x1+.5dot_diam-.2jut)-.5tiny)
+else: x3=x1-.5 fi;
+@z
+
+-----------Improvements made in January 1992
+[No change to TFM files]
+@x in cmbase (improve lowres as suggested by John Hobby)
+def normal_adjust_fit(expr left_adjustment,right_adjustment) =
+ l:=-hround(left_adjustment*hppp)-letter_fit;
+ interim xoffset:=-l;
+ charwd:=charwd+2letter_fit#+left_adjustment+right_adjustment;
+ r:=l+hround(charwd*hppp)-shrink_fit;
+ w:=r-hround(right_adjustment*hppp)-letter_fit;
+ enddef;
+
+def mono_adjust_fit(expr left_adjustment,right_adjustment) =
+ numeric expansion_factor;
+ mono_charwd#=2letter_fit#
+ +expansion_factor*(charwd+left_adjustment+right_adjustment);
+ forsuffixes $=u,jut,cap_jut,beak_jut,apex_corr:
+ $:=$.#*expansion_factor*hppp; endfor
+ l:=-hround(left_adjustment*expansion_factor*hppp)-letter_fit;
+ interim xoffset:=-l;
+ r:=l+mono_charwd-shrink_fit;
+ w:=r-hround(right_adjustment*expansion_factor*hppp)-letter_fit;
+ charwd:=mono_charwd#; charic:=mono_charic#;
+ enddef;
+@y
+def do_expansion(expr expansion_factor) =
+ forsuffixes $=u,jut,cap_jut,beak_jut,apex_corr:
+ $:=$.#*expansion_factor*hppp; endfor
+enddef;
+
+def normal_adjust_fit(expr left_adjustment,right_adjustment) =
+ numeric charwd_in; charwd_in=charwd;
+ l:=-hround(left_adjustment*hppp)-letter_fit;
+ interim xoffset:=-l;
+ charwd:=charwd+2letter_fit#+left_adjustment+right_adjustment;
+ r:=l+hround(charwd*hppp)-shrink_fit;
+ w:=r-hround(right_adjustment*hppp)-letter_fit;
+ do_expansion(w/(charwd_in*hppp));
+ enddef;
+
+def mono_adjust_fit(expr left_adjustment,right_adjustment) =
+ numeric charwd_in; charwd_in=charwd;
+ numeric expansion_factor;
+ mono_charwd#=2letter_fit#
+ +expansion_factor*(charwd+left_adjustment+right_adjustment);
+ l:=-hround(left_adjustment*expansion_factor*hppp)-letter_fit;
+ interim xoffset:=-l;
+ r:=l+mono_charwd-shrink_fit;
+ w:=r-hround(right_adjustment*expansion_factor*hppp)-letter_fit;
+ charwd:=mono_charwd#; charic:=mono_charic#;
+ do_expansion(w/(charwd_in*hppp));
+ enddef;
+@z
+@x in SYM, Downward arrow
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1+.5rule_thickness=h;
+x0=x1=x2; bot y0=-d; x0-x3=x4-x0=3u+eps;
+y3=y4=y0+.24asc_height+eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y (make arrowheads heavier, as suggested by Zapf)
+pos3(rule_thickness,90); pos4(rule_thickness,90);
+lft x1l=hround(.5w-.5rule_thickness); y1+.5rule_thickness=h;
+x0=x1=x2; bot y0=-d; x0-x3=x4-x0=if monospace:3u else:4u fi+eps;
+y3=y4=y0+if monospace:.24 else:.36 fi asc_height+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYM, Upward arrow
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1-.5rule_thickness=-d;
+x0=x1=x2; top y0=h; x0-x3=x4-x0=3u+eps;
+y3=y4=y0-.24asc_height-eps;
+pos5(bar,angle(z4-z0)); z5l=z0;
+pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,90); pos4(rule_thickness,90);
+lft x1l=hround(.5w-.5rule_thickness); y1-.5rule_thickness=-d;
+x0=x1=x2; top y0=h; x0-x3=x4-x0=if monospace:3u else:4u fi+eps;
+y3=y4=y0-if monospace:.24 else:.36 fi asc_height-eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYM, Leftward arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
+x3=x4=x0+if monospace:3u else:4u fi+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYM, Rightward arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-4u-eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
+x3=x4=x0-if monospace:3u else:4u fi-eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYM, Left-and-right arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis if monospace:+vround.3asc_height fi; lft x0=hround u;
+if monospace: x1+.5rule_thickness=hround(w-u) else: x1=.5w fi;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis if monospace:+vround.3asc_height fi; lft x0=hround u;
+if monospace: x1+.5rule_thickness=hround(w-u) else: x1=.5w fi;
+y3-y0=y0-y4=if monospace:.24 else:.36 fi asc_height+eps;
+x3=x4=x0+if monospace:3u else:4u fi+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x ibid
+pos11(rule_thickness,90); pos12(rule_thickness,90); pos13(bar,0); pos14(bar,0);
+y10=y11=y12=math_axis if monospace:-vround.3asc_height fi;
+rt x10=hround(w-u);
+if monospace: x11-.5rule_thickness=hround u else: x11=.5w fi;
+y13-y10=y10-y14=.24asc_height+eps; x13=x14=x10-3u-eps;
+pos15(bar,angle(z14-z10)); z15l=z10; pos16(bar,angle(z13-z10)); z16l=z10;
+z19=.381966[.5[z13,z14],z10];
+@y
+pos11(rule_thickness,90); pos12(rule_thickness,90);
+pos13(rule_thickness,0); pos14(rule_thickness,0);
+y10=y11=y12=math_axis if monospace:-vround.3asc_height fi;
+rt x10=hround(w-u);
+if monospace: x11-.5rule_thickness=hround u else: x11=.5w fi;
+y13-y10=y10-y14=if monospace:.24 else:.36 fi asc_height+eps;
+x13=x14=x10-if monospace:3u else:4u fi-eps;
+pos15(rule_thickness,angle(z14-z10)); z15l=z10;
+pos16(rule_thickness,angle(z13-z10)); z16l=z10;
+z19=.2[.5[z13,z14],z10];
+@z
+@x in SYMBOL, Up-and-down arrow
+pos3(bar,90); pos4(bar,90);
+lft x1l=hround(.5w-.5rule_thickness); y1=.5[-d,h];
+x0=x1=x2; bot y0=-d-o; x0-x3=x4-x0=3u+eps;
+y3=y4=y0+.24asc_height+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,90); pos4(rule_thickness,90);
+lft x1l=hround(.5w-.5rule_thickness); y1=.5[-d,h];
+x0=x1=x2; bot y0=-d-o; x0-x3=x4-x0=4u+eps;
+y3=y4=y0+.36asc_height+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x ibid
+pos13(bar,90); pos14(bar,90);
+x10=x11=x12; top y10=h+o; x10-x13=x14-x10=3u+eps;
+y13=y14=y10-.36asc_height-eps;
+pos15(bar,angle(z14-z10)); z15l=z10;
+pos16(bar,angle(z13-z10)); z16l=z10;
+z19=.381966[.5[z13,z14],z10];
+@y
+pos13(rule_thickness,90); pos14(rule_thickness,90);
+x10=x11=x12; top y10=h+o; x10-x13=x14-x10=4u+eps;
+y13=y14=y10-.24asc_height-eps;
+pos15(rule_thickness,angle(z14-z10)); z15l=z10;
+pos16(rule_thickness,angle(z13-z10)); z16l=z10;
+z19=.2[.5[z13,z14],z10];
+@z
+@x in SYMBOL, Northeast arrow
+pos3(bar,theta); pos4(bar,theta);
+y3=y0; x4=x0; x0-x3=y0-y4=delta+eps;
+pos5(bar,-90); z5l=z0; pos6(bar,-180); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,theta); pos4(rule_thickness,theta);
+z3-z0=(-4u,.36asc_height) rotated theta;
+z4-z0=(-4u,-.36asc_height) rotated theta;
+pos5(rule_thickness,-90); z5l=z0; pos6(rule_thickness,-180); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYMBOL, Southeast arrow
+pos3(bar,theta); pos4(bar,theta);
+x3=x0; y4=y0; y3-y0=x0-x4=delta+eps;
+pos5(bar,180); z5l=z0; pos6(bar,90); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,theta); pos4(rule_thickness,theta);
+z3-z0=(-4u,.36asc_height) rotated theta;
+z4-z0=(-4u,-.36asc_height) rotated theta;
+pos5(rule_thickness,180); z5l=z0; pos6(rule_thickness,90); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYMBOL, Northwest arrow
+pos3(bar,-180+theta); pos4(bar,-180+theta);
+x3=x0; y4=y0; x4-x0=y0-y3=delta+eps;
+pos5(bar,0); z5l=z0; pos6(bar,-90); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,-180+theta); pos4(rule_thickness,-180+theta);
+z4-z0=(4u,.36asc_height) rotated theta;
+z3-z0=(4u,-.36asc_height) rotated theta;
+pos5(rule_thickness,0); z5l=z0; pos6(rule_thickness,-90); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in SYMBOL, Southwest arrow
+pos3(bar,-180+theta); pos4(bar,-180+theta);
+y3=y0; x4=x0; x3-x0=y4-y0=delta+eps;
+pos5(bar,90); z5l=z0; pos6(bar,0); z6l=z0;
+z9=.381966[.5[z3,z4],z0];
+@y
+pos3(rule_thickness,-180+theta); pos4(rule_thickness,-180+theta);
+z4-z0=(4u,.36asc_height) rotated theta;
+z3-z0=(4u,-.36asc_height) rotated theta;
+pos5(rule_thickness,90); z5l=z0; pos6(rule_thickness,0); z6l=z0;
+z9=.2[.5[z3,z4],z0];
+@z
+@x in ROMMS, Leftward top half arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.36asc_height+eps; x3=x4=x0+4u+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+@z
+@x in ROMMS, Leftward bottom half arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0+3u+eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1+.5rule_thickness=hround(w-u); lft x0=hround u;
+y3-y0=y0-y4=.36asc_height+eps; x3=x4=x0+4u+eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+@z
+@x in ROMMS, Rightward top half arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.24asc_height+eps; x3=x4=x0-3u-eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.36asc_height+eps; x3=x4=x0-4u-eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+@z
+@x in ROMMS, Rightward bottom half arrow
+pos1(rule_thickness,90); pos2(rule_thickness,90); pos3(bar,0); pos4(bar,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.asc_height+eps; x3=x4=x0-3u-eps;
+pos5(bar,angle(z4-z0)); z5l=z0; pos6(bar,angle(z3-z0)); z6l=z0;
+@y
+pos1(rule_thickness,90); pos2(rule_thickness,90);
+pos3(rule_thickness,0); pos4(rule_thickness,0);
+y0=y1=y2=math_axis; x1-.5rule_thickness=hround u; rt x0=hround(w-u);
+y3-y0=y0-y4=.36asc_height+eps; x3=x4=x0-4u-eps;
+pos5(rule_thickness,angle(z4-z0)); z5l=z0;
+pos6(rule_thickness,angle(z3-z0)); z6l=z0;
+@z
+@x in CALU, Calligraphic F
+top y1=top y6=h; z2=.5[z3,z1]+bend;
+bot y3=-o; y4=.1h; y5=y2; y7=.9h;
+draw flex(z1,z2,z3) softjoin (z3...{x4-x3,5(y4-y3)}z4); % stem
+draw z1-flourish_change{up}...z1---z6...{down}z7; % upper bar
+@y
+top y1=top y6=h; z2=.5[z3,z1]+1.2bend;
+bot y3=-o; y4=.1h; y5=y2; y7=.9h;
+draw flex(z1,z2,z3) softjoin (z3...{x4-x3,5(y4-y3)}z4); % stem
+draw z1-flourish_change{up}...(z1-(u,0))---z6...{down}z7; % upper bar
+@z
+@x in CALU, Calligraphic H
+lft x1=lft x3=0; rt x4=rt x6=.8w; rt x9=w;
+top y1=top y4=h; bot y3=-o; bot y6=bot_flourish_line; y9=y6+.1h;
+z2=.6[z3,z1]+bend; z5=.4[z6,z4]-2bend;
+path p[]; p1=flex(z1,z2,z3); p2=flex(z4,z5,z6);
+p3=(-w,.55h)--(2w,.55h);
+lft z7=p3 intersectionpoint p1; rt z8=p3 intersectionpoint p2;
+draw (z1-flourish_change{up}....z1-(u,0)---z1) softjoin p1; % left stem
+@y
+lft x1=lft x3=.5u; rt x4=rt x6=.8w-.6u; rt x9=w;
+top y1=top y4=h; bot y3=-.06h; bot y6=bot_flourish_line; y9=y6+.1h;
+z2=.6[z3,z1]+bend; z5=.4[z6,z4]-bend;
+path p[]; p1=flex(z1,z2,z3); p2=flex(z4,z5,z6);
+p3=(-w,.45h)--(2w,.45h);
+rt z7+2bend=p3 intersectionpoint p1; rt z8=p3 intersectionpoint p2;
+draw (z1-flourish_change-bend{curl2}....z1-(u,0)---z1) softjoin p1; % left stem
+@z
+@x in CALU, Calligraphic I
+lft x0=0; x1=.9w; x2=x4=.5w; x5=.2w; x6=.75w; rt x7=w;
+@y
+lft x0=0; x1=.9w; x2=x4=.5w; x5=.2w; x6=.8w; rt x7=1.05w;
+@z
+@x in CALU, Calligraphic T
+x1=x3=.5w; lft x4=0; x5=w-x6=.25w; rt x7=w;
+x1=.47w; x3=.5w; lft x4=0; x5=w-x6=.25w; rt x7=1.05w;
+z2=.5[z3,z1]+bend;
+x1-x8=x9-x1=2u; y8=y9=y3;
+z0=1/3[z1,z6];
+draw z0{left}...z2{down}...{left}z8; % stem
+draw z8--z9; % foot
+draw z4{up}...z5{right}...z6{right}...{up}z7; % arms
+math_fit(.5u#-5/7h#*slant,-u#); labels(1,2,3,4,5,6,7,8,9); endchar;
+@y
+x1=.47w; x3=.5w; lft x4=0; x5=.25w; x6=.85w; rt x7=1.05w;
+top y1=h; bot y3=-.1h; y4=3/4h; top y5=top y6=h; top y7=1.05h;
+z2=.3[z3,z1]+bend;
+top y0=y1; x0=x2;
+z8=(2u,.2h);
+draw z0---z2...z3; % stem
+draw z4{curl 2}...z5{right}...z6{right}...{up}z7; % arms
+math_fit(.5u#-5/7h#*slant,-u#); labels(1,2,3,4,5,6,7); endchar;
+@z
+@x in GREEKL, lowercase delta
+pos1(hair,-180); pos2(vair,-90);
+numeric theta; theta=angle(18u,-h);
+pos3(stem,theta+90); pos4(stem,theta+90); pos5(1/4[hair,stem],20);
+pos6(vair,-90); pos7(curve,-180); pos8(vair,-270);
+rt x1l=hround(w-2u+.5hair); x2=.5w; x3r=3u; rt x5r=hround(w-u);
+x4=x6=x8=.5w+.5u; lft x7r=hround(1.5u-.5curve);
+top y2l=h+oo; y1=min(.9h,y2r-eps); top y8r=x_height+oo; y4=y8;
+z4-z3=whatever*(18u,-h); y5=y7=.5[y6,y8]; bot y6=-oo;
+filldraw stroke z1e{x2-x1,3(y2-y1)}...z2e{left}...z3e---z4e
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+math_fit(-.3x_height#*slant+.5curve#-u#,.7x_height#*slant-.5u#);
+penlabels(1,2,3,4,5,6,7,8); endchar;
+@y
+x0=-u; y0=1.1h;
+numeric light_flare; light_flare=2/3[vair,flare];
+x1=w-2u-.5light_flare; y1=h-.5light_flare;
+numeric theta; theta=angle (z1-z0);
+pos1(light_flare,theta-90); pos2(.2[vair,light_flare],-90); pos3(vair,theta);
+x2=x3+u; y2=h;
+x4=x6=.5w+.5u; top y8r=x_height+oo; z4=z8;
+pos6(vair,-90); pos7(stem,-180); pos8(vair,-270);
+pos4(stem,angle(z4-z0)+90); pos5(stem,30);
+z3=.5[.5[z1,z4],z0];
+y5+.1x_height=y7=.5[y6,y8]; bot y6=-oo;
+lft x7r=hround(1.4u-.5stem); rt x5r=hround(w-u);
+filldraw stroke z1e{z0-z1e}....z2e....z3e{(z0-z1)rotated 90}
+ ...z4e{z4e-.8[z4,z0]}
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+filldraw z1r{z1r-z0}...z1l{z0-z1l}--cycle; % bulb
+math_fit(-.3x_height#*slant+.5curve#-u#,.7x_height#*slant-.5u#);
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+@z
+@x in TSETSL, lowercase delta for extended ASCII
+pos1(hair,-180); pos2(vair,-90);
+numeric theta; theta=angle(18u,-h);
+pos3(stem,theta+90); pos4(stem,theta+90); pos5(1/4[hair,stem],20);
+pos6(vair,-90); pos7(curve,-180); pos8(vair,-270);
+rt x1l=hround(w-2u+.5hair); x2=.5w; x3r=3u; rt x5r=hround(w-u);
+x4=x6=x8=.5w+.5u; lft x7r=hround(1.5u-.5curve);
+top y2l=h+oo; y1=min(.9h,y2r-eps); top y8r=x_height+oo; y4=y8;
+z4-z3=whatever*(18u,-h); y5=y7=.5[y6,y8]; bot y6=-oo;
+filldraw stroke z1e{x2-x1,3(y2-y1)}...z2e{left}...z3e---z4e
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+penlabels(1,2,3,4,5,6,7,8); endchar;
+@y this next line differs from GREEKL, but the other lines agree
+x0=-u; y0=1.05h;
+numeric light_flare; light_flare=2/3[vair,flare];
+x1=w-2u-.5light_flare; y1=h-.5light_flare;
+numeric theta; theta=angle (z1-z0);
+pos1(light_flare,theta-90); pos2(.2[vair,light_flare],-90); pos3(vair,theta);
+x2=x3+u; y2=h;
+x4=x6=.5w+.5u; top y8r=x_height+oo; z4=z8;
+pos6(vair,-90); pos7(stem,-180); pos8(vair,-270);
+pos4(stem,angle(z4-z0)+90); pos5(stem,30);
+z3=.5[.5[z1,z4],z0];
+y5+.1x_height=y7=.5[y6,y8]; bot y6=-oo;
+lft x7r=hround(1.4u-.5stem); rt x5r=hround(w-u);
+filldraw stroke z1e{z0-z1e}....z2e....z3e{(z0-z1)rotated 90}
+ ...z4e{z4e-.8[z4,z0]}
+ ....z5e{down}...pulled_arc.e(6,7) & pulled_arc.e(7,8); % hook and bowl
+filldraw z1r{z1r-z0}...z1l{z0-z1l}--cycle; % bulb
+penlabels(0,1,2,3,4,5,6,7,8); endchar;
+@z
+
+----------- Changes made after the fourth printing (1993) of Volume E
+
+@x in CSCSPU, letter J [fixes a bug if dish=0 and crisp<tiny and serifs]
+ bulb(3,4,5); % bulb
+@y
+ pickup tiny.nib; bulb(3,4,5); % bulb
+@z
+
+@x in BIGDEL, two harmless bugs caught by Robert Hunt
+"Extensible vertical arrow--extension module";
+@y
+cmchar "Extensible vertical arrow--extension module";
+@z
+@x
+"Extensible double vertical arrow--extension module";
+@y
+cmchar "Extensible double vertical arrow--extension module";
+@z
+
+@x in GREEKU, letter Phi (hi-res glitch found by Robert Hunt)
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+@y
+lft x1l=lft x2l=hround(.5w-.5shaved_stem); top y1=h; bot y2=0;
+@z
+@x in GREEKU, letter Psi similarly
+lft x1l=lft x2l=hround(.5w-.5cap_stem); top y1=h; bot y2=0;
+@y
+lft x1l=lft x2l=hround(.5w-.5shaved_stem); top y1=h; bot y2=0;
+@z
+
+@x in BIGOP, teststyle integral sign
+x5=.5[x4,x6]; x4-x6=1.2u; lft x5r=hround(.5w-.5stem);
+@y
+x5=.5[x4,x6]; x4-x6=1.2u; lft x5r=hround(.5w-.5curve);
+@z
+@x same, displaystyle integral sign
+x5=.5[x4,x6]; x4-x6=4.8u; lft x5r=hround(.5w-.5stem);
+@y
+x5=.5[x4,x6]; x4-x6=4.8u; lft x5r=hround(.5w-.5max_size);
+@z
+@x same, textstyle contour integral sign
+x5=.5[x4,x6]; x4-x6=1.2u; lft x5r=hround(.5w-.5stem);
+@y
+x5=.5[x4,x6]; x4-x6=1.2u; lft x5r=hround(.5w-.5curve);
+@z
+@x same, displaystyle contour integral sign
+x5=.5[x4,x6]; x4-x6=4.8u; lft x5r=hround(.5w-.5stem);
+@y
+x5=.5[x4,x6]; x4-x6=4.8u; lft x5r=hround(.5w-.5max_size);
+@z
+
+@x in ITALMS, the partial differential sign
+path p; p=pulled_super_arc.l(3,4)(pull);
+@y
+path p; {{interim superness:=more_super; p=pulled_super_arc.l(3,4)(pull)}};
+@z
+
+@x in SYMBOL, the elementary division operator
+beginarithchar(oct"004"); pickup rule.nib;
+x3-.5dot_size=hround(.5w-.5dot_size); center_on(x3);
+y3+.5dot_size=vround(math_axis+math_spread[.5x_height,.6x_height]+.5dot_size);
+@y note that pickup rule.nib leaves currentbreadth unchanged
+beginarithchar(oct"004"); pickup fine.nib; pickup rule.nib;
+numeric del; del=dot_size-currentbreadth; % currentbreadth=fine
+x3-.5del=good.x(.5w-.5del); center_on(x3);
+y3+.5del=good.y(math_axis+math_spread[.5x_height,.6x_height]+.5del);
+@z
+
+@x in CMBASE, compute_spread can force even spreads for better rounding
+ spread:=ceiling(spread#*hppp)+eps; enddef;
+@y
+ spread:=2ceiling(spread#*hppp/2)+eps; enddef;
+@z
+
+@x in CMBASE, better diag_ratio routine avoids overflow in hi-res chars
+ numeric a_,b_; b_=b/y; a_=a*a-b_*b_;
+ (a*(c++y*sqrt a_)-b_*c)/a_/y enddef;
+@y
+ numeric a_,b_,c_; b_=b/y; c_=c/y; a_=a*a-b_*b_;
+ (a*(c_++sqrt a_)-b_*c_)/a_ enddef;
+@z
+
+@x in ROMAND, numeral 3, allow hi-res cminch to run without overflow (MacKay)
+x4=1/3[x5,x3l]; z4=z5+whatever*(150u,h);
+@y
+x4=1/3[x5,x3l]; z4=z5+whatever*(15u,.1h);
+@z
+
+@x in ITALP, the Sterling sign (bug caught by Yannis Haralambous)
+lft x6r=hround u; x7=3u; x8=w-3.5u; rt x9r=hround(w-u);
+@y
+lft x6r=hround u; x7=3u; x8=w-3.5u; rt x9l=hround(w-u);
+@z
+
+@x in GREEKL, lowercase omega, I made minor changes for new edition of TAOCP:
+y1+.5hair=h; x1=x2+.75u; pos1(hair,angle(2(x1-x2),y1-y2)+90);
+@y
+y1+.5hair=h; x1=x2+.75u; pos1(hair+dw,angle(2(x1-x2),y1-y2)+90);
+@z
+@x
+x3=.5[x2,x4]; x7+.25u=.5[x6,x8]; rt x8r=hround(w-.5u);
+@y
+x3=.5[x2,x4]; x7-.25u=.5[x6,x8]; rt x8r=hround(w-.5u);
+@z
+
+@x in GREEKL, lowercase beta, I made minor changes for new edition of TAOCP:
+pos3(stem,0); pos4(vair,-90); pos5(hair,-180);
+pos6(vair,-270); pos7(curve,-360); pos8(vair,-450); pos9(hair,-540);
+x0=x1=x9; lft x0l=hround(1.5u-.5hair); x2=x4=x6=x8=.5w+.25u;
+rt x3r=hround(w-1.5u); rt x7r=hround(w-1.5u+.5curve); rt x5l=hround(x4-u);
+bot y0=-d; y1=top y6r=x_height; top y2r=h+oo; y3=.5[y2,y4];
+y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8=-oo; y7=y9=.5[y6,y8];
+@y (this change also is made in TSETSL)
+pos3(.8[hair,stem],0); pos4(vair,-90); pos5(hair,-180);
+pos6(vair,-270); pos7(stem,-360); pos8(vair,-450); pos9(hair,-540);
+x0=x1=x9; lft x0l=hround(1.5u-.5hair); x2=x4=x6=x8=.5w-.25u;
+rt x3r=hround(w-1.75u); rt x7r=hround(w-u); rt x5l=hround(x4-u);
+bot y0=-d; y1=top y6r=x_height; top y2r=h+oo; y3=.5[y2,y4];
+y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8=-oo; y7=y9=.55[y6,y8];
+@z
+
+@x in ROMANU, less overshoot on uppercase sans serif C (for Vol 2 of TAOCP)
+ top y1r=vround .95h+o; top y2r=h+o; y3=.5h;
+ bot y4r=-o; bot y5r=vround .08h-o; y5l:=good.y y5l; x5l:=good.x x5l;
+@y
+ top y1r=vround .95h+oo; top y2r=h+oo; y3=.5h;
+ bot y4r=-oo; bot y5r=vround .08h-oo; y5l:=good.y y5l; x5l:=good.x x5l;
+@z
+
+@x in ROMANU, likewise for G
+ top y1r=vround .93h+o; top y2r=h+o; y3=.5h;
+ bot y4r=-o; bot y5r=vround .07h-o;
+@y
+ top y1r=vround .93h+oo; top y2r=h+oo; y3=.5h;
+ bot y4r=-oo; bot y5r=vround .07h-oo;
+@z
+
+@x in SYMBOL, spade suit, a cosmetic change that doesn't affect any fonts:
+labels(1,2,3,5,6,10,11,12,13,14,15); endchar;
+@y
+labels(1,2,3,5,6,7,8,9,10,11,12,13,14,15); endchar;
+@z
+
+@x in CMBASE, sloped_serif.l never used $$ except rarely in letter p
+ y@0=max(y@2l-bracket,y$$)-eps;
+@y and in letter p, it was wrong to do so! (but not in any normal font)
+ y@0=y@2l-bracket-eps;
+@z
+@x sloped_serif.r never used $$ in any reasonable way at all
+ y@0=min(y@2l+bracket,y$$)+eps;
+@y
+ y@0=y@2l+bracket+eps;
+@z
+
+in ITALD, programs for 6 and 9: same change as above for partial derivative
+in OLDDIG, programs for 6 and 9: same change as above for partial derivative
+in ROMAND, programs for 6 and 9: same change as above for partial derivative
+in TSETSL, program for partial derivative: same change as above
+
+@x in ROMANL, slight change to cmss10 and cmssbx10 `g' improves meta-ness
+loop_top=Vround .77[vair,fudged.stem];
+@y
+loop_top=if serifs: Vround .77[vair,fudged.stem] else: vair fi;
+@z
+
+@x in CMBASE, recent change shouldn't clobber a_, b_, and c_ of plain.mf
+ numeric a_,b_,c_; b_=b/y; c_=c/y; a_=a*a-b_*b_;
+ (a*(c_++sqrt a_)-b_*c_)/a_ enddef;
+@y
+ numeric aa_,bb_,cc_; bb_=b/y; cc_=c/y; aa_=a*a-bb_*bb_;
+ (a*(cc_++sqrt aa_)-bb_*cc_)/aa_ enddef;
+@z
+
+@x in ITALMS, Arrow (vector) accent
+lft x1=hround .5u; x2=w-x1; y1=y2=good.x .7[x_height,asc_height];
+@y a correction of almost purely academic interest
+lft x1=hround .5u; x2=w-x1; y1=y2=good.y .7[x_height,asc_height];
+@z
+
+the following patches make the arrows more robust, but essentially unchanged
+@x in SYM, Downward arrow
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@y
+ ---z1r..z1l---subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@z
+@x in SYM, Upward arrow
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1r..z1l---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in SYM, Leftward arrow
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@z
+@x in SYM, Rightward arrow
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in SYM, Left-and-right arrow
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@z
+@x ibid
+ --z12l---z11l..z11r---z12r--subpath (t,0) of\\(z13l{z19-z13}..z15r)
+@y
+ ---z11l..z11r---subpath (t,0) of\\(z13l{z19-z13}..z15r)
+@z
+@x in SYMBOL, Up-and-down arrow
+ --z2r---z1r..z1l---z2l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@y
+ ---z1r..z1l---subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@z
+@x ibid
+ --z12r---z11r..z11l---z12l--subpath (t,0) of\\(z13l{z19-z13}..z15r)
+@y
+ ---z11r..z11l---subpath (t,0) of\\(z13l{z19-z13}..z15r)
+@z
+@x in SYMBOL, Northeast arrow
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in SYMBOL, Southeast arrow
+ --z2l---z1l..z1r---z2r
+ --subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in SYMBOL, Northwest arrow
+ --z2l---z1l..z1r---z2r--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in SYMBOL, Southwest arrow
+ --z2l---z1l..z1r---z2r
+ --subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ ---z1l..z1r---subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in ROMMS, Leftward top half arrow
+filldraw z0--(x0,y2l)---z1l..z1r---z2r
+ ..subpath (t,0) of\\(z3r..{2(x0-x3),y0-y3}z5r)
+@y
+filldraw z0--(x0,y2l)--z1l{right}..{left}z1r
+ --subpath (t,0) of\\(z3r..{2(x0-x3),y0-y3}z5r)
+@z
+@x in ROMMS, Leftward bottom half arrow
+filldraw z0{2(x4-x0),y4-y0}..z4l
+ --subpath (0,t) of\\(z4r..{2(x0-x4),y0-y4}z6r)
+@y
+ --z1l{right}..{left}z1r--(x0,y2r)--cycle; % arrowhead and stem
+@z
+@x in ROMMS, Rightward top half arrow
+filldraw z0--(x0,y2l)---z1l..z1r---z2r
+ ..subpath (t,0) of\\(z3l..{2(x0-x3),y0-y3}z5r)
+@y
+filldraw z0--(x0,y2l)--z1l{left}..{right}z1r
+ --subpath (t,0) of\\(z3l..{2(x0-x3),y0-y3}z5r)
+@z
+@x in ROMMS, Rightward bottom half arrow
+ ..z2l---z1l..z1r---(x0,y2r)--cycle; % arrowhead and stem
+@y
+ --z1l{left}..{right}z1r--(x0,y2r)--cycle; % arrowhead and stem
+@z
+@x in BIGDEL, Extensible vertical arrow--top
+ --z2r---z1r--z1l---z2l--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@y
+ --z1r--z1l--subpath (t,0) of\\(z3l{z9-z3}..z5r)
+@z
+@x in BIGDEL, Extensible vertical arrow--bottom
+ --z2r---z1r--z1l---z2l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@y
+ --z1r--z1l--subpath (t,0) of\\(z3r{z9-z3}..z5r)
+@z
+
+@x in ROMLIG, the ligature fi
+ x13=x11-.5; top y14r=min(2x_height,h+1); top y11=x_height;
+@y make the center of the dot consistent with ordinary i, in sans-serif fonts
+ x13=x11-.5; top y14r=min(10/7x_height+.5bulb_diam,h)+1; top y11=x_height;
+@z
+@x in ROMLIG, the ligature ffi
+ x23=x21-.5; top y24r=min(2x_height,h+1); top y21=x_height;
+@y same corrections as to fi
+ x23=x21-.5; top y24r=min(10/7x_height+.5bulb_diam,h)+1; top y21=x_height;
+@z
+
+@x in SYMBOL, the circle operator
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis;
+@y this correction makes it a circle even at small size, low resolution
+lft x6=hround u; x2=w-x6; top y8=h; y8-y4=x2-x6;
+@z
+@x in SYMBOL, the bullet
+lft x6=hround u; x2=w-x6; top y8=h; y2=math_axis; circle_points;
+@y likewise
+lft x6=hround u; x2=w-x6; top y8=h; y8-y4=x2-x6; circle_points;
+@z
+
+@x in ROMAND, the numeral 2
+ ..z3e{down}.. z4e---z5e--z6e; % stroke
+@y it's more robust to avoid --- next to -- (in case of tiny loops)
+ ..z3e{down}..{z5e-z4e}z4e--z5e--z6e; % stroke
+@z
+@x in OLDDIG, oldstyle numeral 2
+ ..z3e{down}.. z4e---z5e--z6e; % stroke
+@y likewise
+ ..z3e{down}..{z5e-z4e}z4e--z5e--z6e; % stroke
+@z
+
+@x in CSC, after the second font_setup
+extra_endchar:=extra_endchar&"charcode:=charcode+code_offset";
+@y
+extra_endchar:=extra_endchar&"charcode:=charcode+code_offset;";
+@z
+
+@x in ACCENT, in program for Breve
+numeric mid_thickness; mid_thickness=vround 1/3[vair,stem];
+@y
+numeric mid_thickness; mid_thickness=Vround 1/3[vair,stem];
+@z
+
+@x in CMBASE, a more robust arm routine fixes the 7 in cmbx5,6,7,8
+ filldraw z$$l{z@1-z$$l}...darkness[z@1,.5[z@2,z$$l] ]...z@2
+ ---z$l--z$r--z@0--z$$r--cycle; % arm and beak
+@y
+ path p_; p_= z$$l{z@1-z$$l}...darkness[z@1,.5[z@2,z$$l] ]...z@2
+ ---z$l--z$r--z@0--z$$r--cycle;
+ if (y$$>y$) <> (ypart precontrol 1 of p_ > ypart postcontrol 1 of p_):
+ p_:=z$$l{z@1-z$$l}...darkness[z@1,.5[z@2,z$$l] ]
+ ---z$l--z$r--z@0--z$$r--cycle; fi
+ filldraw p_; % arm and beak
+@z
+
+-----------Here I draw the line with respect to further changes
+
+(I sincerely believe there won't be any more!)
+
+I absolutely guarantee that the TFM files will never change again.
+(Otherwise I would consider zeroing the depth of italic 7,
+which I admit is strange... we can live with it.)
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.eight b/Master/texmf-doc/doc/english/knuth/errata/errata.eight
new file mode 100644
index 00000000000..f7ceafd9f69
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.eight
@@ -0,0 +1,610 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1992}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting\/} between 15 March 1992 and the publication of the final
+printed versions of those books.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Changes to Volume~B refer to the fourth printing
+(1991), which differs markedly from earlier printings because it includes
+all the revisions for \TeX3.0. Changes to Volume~D refer to the third
+printing (1991), which differs markedly from earlier printings because
+it includes all the revisions for \MF\kern1pt2.0. Changes to the mini-indexes
+and master indexes of Volumes B and~D are not shown here unless they are
+not obviously derivable from what has been shown.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A23, line 14 (9/1/92)
+
+\tenpoint\noindent
+a command and you type `|tex|' or `|run| |tex|' or something like that.)
+
+\bugonpage A53, line 23 (7/7/92)
+
+\tenpoint\noindent
+{\sl scientiarum imperialis petropolitan\ae\/}
+became {\sl Akademi\t\i a Nauk SSSR, Doklady}.
+
+\bugonpage A146, line 2 from the bottom (2/25/93)
+
+|$\bigl|\|| |\||x|\||-|\||y|\|| \bigr|\||$|\hskip1.25in
+ $\bigl\vert\vert x\vert-\vert y\vert\bigr\vert$
+
+\bugonpage A149, lines 3--5 (2/25/93)
+
+\noindent
+example, we used |\bigl| and |\bigr| to produce $\bigl\vert\vert x\vert-
+\vert y\vert\bigr\vert$ in one of the previous illustrations; |\left| and
+|\right| don't make things any bigger than necessary, so
+`|$\left|\||\left|\||x\right|\||-\left|\||y\right|\||\right|\||$|'
+yields only `$\left\vert
+ \left\vert x\right\vert -\left\vert y\right\vert \right\vert$'.\cutpar
+
+\bugonpage A158, line 18 from the bottom (2/25/93)
+
+\ninepoint
+are four possibilities for each of these fields.
+A field can be
+
+\bugonpage A282, line 9 from the bottom (7/8/92)
+
+\ninepoint\noindent
+category~4) are intercepted by the alignment
+process, en route to \TeX's stomach, so\cutpar
+
+\bugonpage A293, new paragraph after line 15 (4/9/92)
+
+\ninepoint
+\textindent{$\bull$}|\unhbox|\<8-bit number>, |\unhcopy|\<8-bit number>.\enskip
+The specified box register must be void. Nothing happens.
+
+\bugonpage A309, line 23 (7/7/92)
+
+\ninepoint\noindent
+|petropolitan\ae\/} became {\sl Akademi\t\i a Nauk SSSR, Doklady}.|
+
+\bugonpage A320, line 11 (1/26/93)
+
+\ninepoint
+\ansno17.12:
+|$\bigl(x+f(x)\bigr) \big/ \bigl(x-f(x)\bigr)$|. \ Notice especially the\cutpar
+
+\bugonpage A349, second line from the bottom (7/8/92)
+
+\ninepoint\noindent
+expand to a ^\<number> en route to \TeX's
+``stomach''; |\multiply| wouldn't work, because\cutpar
+
+\bugonpage A358, bottom line (2/3/93)
+
+\ninepoint\noindent
+it is easy to define ^|\ldots| and ^|\cdots| macros that
+give the proper spacing in most\cutpar
+
+\bugonpage A370, lines 28 and 29 (9/1/92)
+
+\def\Russiantt#1{{\tt\hbox to.5em{\hss\eighttt\char#1\hss}}}
+\ninepoint\noindent
+example, if \TeX\ is implemented for
+a purely ^{Cyrillic} ^^{Russian} keyboard, the letter `\Russiantt5' should be
+assigned to code \oct{160} and `\Russiantt{`T}' to code \oct{164}, so that
+`\Russiantt5\Russiantt{`T}' still means `|pt|'; or else control\cutpar
+
+\bugonpage A377, lines 17--24 (5/4/92)
+
+\ninepoint
+\begintt
+\def\sanswitch{\let\n@xt\endsanity \ifx\next\endsanity
+ \else\ifcat\noexpand\next\stoken\aftergroup\space\let\n@xt=\eat
+ \else\ifcat\noexpand\next\bgroup\aftergroup{\let\n@xt=\eat
+ \else\ifcat\noexpand\next\egroup\aftergroup}\let\n@xt=\eat
+ \else\let\n@xt=\copytok\fi\fi\fi\fi \n@xt}
+\def\eat{\afterassignment\sanitize \let\next= }
+\long\def\copytok#1{\ifcat\noexpand#1\relax\aftergroup\noexpand\fi
+ \ifcat\noexpand#1\noexpand~\aftergroup\noexpand\fi
+\endtt
+
+\bugonpage A455, line 25 (2/26/93)
+
+\ninepoint\noindent
+rent language'' is set equal to |\language|. Whenever a
+character is added to the cur-\cutpar
+
+\bugonpage A459, second line of entry for ampersand (3/22/92)
+
+\eightpoint\indent\qquad
+{\it231--248}, $\underline{282}$, {\it339}, 344, 385--386, 428.
+
+\bugonpage A461, right column (2/19/93)
+
+\eightpoint
+\newbox\astbox \setbox\astbox=\hbox to0pt{\hss\lower1pt\hbox{*}}
+\def\prim#1{\par\indent\copy\astbox{\tt\char`\\#1}}
+\prim{chardef}, 44, 121, 155, 210, 214, 215, 271,\par
+\indent\qquad $\underline{277}$, 336, {\it343}, {\it345}, {\it356}, 452.\par
+\indent\<chardef token>, $\underline{271}$, 283, 286, 289.
+
+\bugonpage A467, left column (2/25/93)
+
+\eightpoint
+Greek, 127--128, 137, 156, 164, 319,\par
+\indent\qquad 358, 430, 434.
+
+\bugonpage A470, left column (2/25/93)
+
+\eightpoint
+margins, {\sl see\/} |\hoffset|, |\hsize|, |\narrower|.
+
+\bugonpage A471, left column (2/19/93)
+
+\eightpoint
+\prim{mathchardef}, 155, 199, 214, 215, 271,\par
+\indent\qquad 277, 289, 336, {\it358}, {\it394}.\par
+\indent\<mathchardef token>, $\underline{271}$, 289.
+
+\bugonpage A474, right column (3/22/92)
+
+\eightpoint
+pound sterling, 54, {\it339}, 428.
+
+\bugonpage A477, right column (3/22/92)
+
+\eightpoint
+sterling, 54, {\it339}, 428.
+
+\bugonpage A480, left column (4/9/92)
+
+\eightpoint
+\prim{unhbox}, 120, 283, $\underline{285}$, 293, {\it354}, {\it356},
+ {\it399}.\par
+\prim{unhcopy}, 120, 283, $\underline{285}$, 293, {\it353}.
+
+\bugonpage A481, left column (2/25/93)
+
+\eightpoint
+whatsits, 95, 110, 157, 226--229, 455.
+
+\bugonpage A483, lines 15--21 (2/25/93)
+
+{\tt P.O. Box 869\par
+Santa Barbara, CA 93102-0869 USA.\par
+|}|}
+\smallskip\noindent
+Don't delay, write today! That number again is
+
+\smallskip
+{\obeylines
+\TeX\ Users Group
+P.O. Box 869
+Santa Barbara, CA 93102-0869 USA.
+}
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 10 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]3.1415\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B89, line 12 (2/27/93)
+
+\tenpoint
+\noindent\hskip10pt
+In horizontal mode, the \\{prev\_graf} field is used for initial language data.
+
+\bugonpage B89, line 20 (2/27/93)
+
+\ninepoint
+\noindent\hskip20pt
+\\{pg\_field}, \\{ml\_field}: \\{integer}; \ \\{aux\_field}: \\{memory\_word};
+\par
+\noindent [Also delete the definitions of \\{lhmin} and \\{rhmin}, lines
+32 and 33.]
+
+\bugonpage B90, line 13 (2/27/93)
+
+\ninepoint
+\noindent\hskip10pt
+$\\{prev\_depth}\gets\\{ignore\_depth}$; \ $\\{mode\_line}\gets0$; \
+$\\{prev\_graf}\gets0$;
+
+\bugonpage B91, top three lines (2/27/93)
+
+\ninepoint
+\noindent\hskip20pt
+{\bf if\/} $m=\\{hmode}$ {\bf then if\/} $\\{nest}[p].\\{pg\_field}\ne
+ \oct{40600000}$ {\bf then}\par\noindent\hskip40pt
+{\bf begin} \\{print}({\tt\char`\"\](language\char`\"}); \
+ \\{print\_int}(\\{nest}[$p$].\\{pg\_field} {\bf mod} \oct{200000});\par
+\noindent\hskip40pt
+ \\{print}({\tt\char`\":hyphenmin\char`\"}); \
+ \\{print\_int}(\\{nest}[$p$].\\{pg\_field} {\bf div} \oct{20000000}); \
+ \\{print\_char}({\tt\char`\",\char`\"});\par\noindent\hskip40pt
+\\{print\_int}((\\{nest}[$p$].\\{pg\_field} {\bf div} \oct{200000})
+ {\bf mod} \oct{100}); \ \\{print\_char}({\tt\char`\")\char`\"});
+
+\bugonpage B344, lines 21 and 22 (2/27/93)
+
+\tenpoint\noindent\hskip10pt
+This code assumes that a \\{glue\_node} and a \\{penalty\_node} occupy the
+same number of \\{mem}~words.
+
+\bugonpage B344, line 30 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+$\\{link}(\\{tail})\gets\\{new\_param\_glue}(\\{par\_fill\_skip\_code})$; \
+ $\\{init\_cur\_lang}\gets\\{prev\_graf}$ {\bf mod} \oct{200000};\par
+\noindent\hskip10pt
+$\\{init\_l\_hyf}\gets\\{prev\_graf}$ {\bf div} \oct{20000000}; \
+$\\{init\_r\_hyf}\gets(\\{prev\_graf}$ {\bf div} \oct{200000}) {\bf mod}
+ \oct{100}; \
+\\{pop\_nest};
+
+\bugonpage B353, line 4 (2/27/93)
+
+\tenpoint\noindent\hskip10pt
+Kern nodes do not disappear at a line break unless they are \\{explicit}.
+
+\bugonpage B353, lines 15 and 16 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+\\{math\_node}: $\\{break\_width}[1]\gets\\{break\_width}[1]-\\{width}(s)$;\par
+\noindent\hskip20pt
+\\{kern\_node}: {\bf if\/} $\\{subtype}(s)\ne\\{explicit}$
+ {\bf then goto} \\{done}\par\noindent\hskip30pt
+{\bf else} $\\{break\_width}[1]\gets\\{break\_width}[1]-\\{width}(s)$;
+
+\bugonpage B354, lines 6 and 7 (2/27/93)
+
+\tenpoint\noindent
+will be the background
+plus $l_1$, so the length from \\{cur\_p} to \\{cur\_p} should be
+$\gamma+l_0+l_1-l$.
+If the post-break text of the discretionary is empty, a break may also
+discard~$q$; in that unusual case we subtract the length of~$q$ and any
+other nodes that will be discarded after the discretionary break.
+
+\bugonpage B354, line 18 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} $\langle\,$Add the width of node $s$ to \\{break\_width}{\sevenrm
+ \kern.5em842}$\,\rangle$;
+
+\bugonpage B354, line 22 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{post\_break}(\\{cur\_p})=\\{null}$ {\bf then}
+ $s\gets\\{link}(v)$;\quad$\{\,$nodes may be discardable after the break$\,\}$
+
+\bugonpage B355, top line (2/27/93)
+
+\ninepoint\noindent
+{\tenbf842.\quad}$\langle\,$Add the width of node $s$ to
+ \\{break\_width}{\sevenrm\kern.5em842}$\,\rangle\equiv$
+
+\bugonpage B355, lines 9--14 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+$\\{hlist\_node},\\{vlist\_node},\\{rule\_node},\\{kern\_node}$:
+ $\\{break\_width}[1]\gets\\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt
+{\bf othercases} \\{confusion}({\tt\char`\"disc2\char`\"})\par
+\noindent\hskip20pt
+{\bf endcases}
+
+\bugonpage B364, line 10 (2/27/93)
+
+\tenpoint\noindent
+a glue node, penalty node, explicit kern node, or math node.
+
+\bugonpage B366, line 11 from the bottom (2/27/93)
+
+\ninepoint\noindent
+\\{kern\_node}: {\bf if\/} $\\{subtype}(\\{cur\_p})=\\{explicit}$
+ {\bf then} \\{kern\_break}\par\noindent\hskip10pt
+{\bf else} $\\{act\_width}\gets\\{act\_width}+\\{width}(\\{cur\_p})$;
+
+\bugonpage B367, line 21 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf else if\/} \\{precedes\_break}(\\{prev\_p}) {\bf then}
+ $\\{try\_break}(0,\\{unhyphenated})$\par\noindent\hskip20pt
+{\bf else if\/} $(\\{type}(\\{prev\_p})=\\{kern\_node})\land
+ (\\{subtype}(\\{prev\_p})\ne\\{explicit})$ {\bf then}
+ $\\{try\_break}(0,\\{unhyphenated})$;
+
+\bugonpage B372, lines 12 and 13 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $\\{type}(q)=\\{kern\_node}$ {\bf then}\par\noindent\hskip30pt
+{\bf if\/} $\\{subtype}(q)\ne\\{explicit}$ {\bf then goto} \\{done1};
+
+\bugonpage B376, line 3 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_lang}\gets\\{init\_cur\_lang}$; \
+$\\{l\_hyf}\gets\\{init\_l\_hyf}$; \
+$\\{r\_hyf}\gets\\{init\_r\_hyf}$;
+
+\bugonpage B377, lines 11 and 12 (2/27/93)
+
+\ninepoint\noindent
+$\\{cur\_lang},\\{init\_cur\_lang}$: \\{ASCII\_code};\quad
+ $\{\,$current hyphenation table of interest$\,\}$\par\noindent
+$\\{l\_hyf},\\{r\_hyf},\\{init\_l\_hyf},\\{init\_r\_hyf}$: \\{integer};\quad
+ $\{\,$limits on fragment sizes$\,\}$
+
+\bugonpage B378, line 5 from the bottom, overriding earlier change (2/27/93)
+
+\ninepoint\noindent\hskip30pt
+{\bf else if} $(\\{type}(s)=\\{kern\_node})\land(\\{subtype}(s)=\\{normal})$
+ {\bf then}\par\noindent\hskip50pt
+{\bf begin} $\\{hb}\gets s$; \ $\\{hyf\_bchar}\gets\\{font\_bchar}[\\{hf}]$; \
+ {\bf end}\par\noindent\hskip40pt
+{\bf else goto} \\{done3};
+
+
+\bugonpage B394, lines 12 and 13 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $n$: $0\to64$;\quad$\{\,$length of current word; not always
+ a \\{small\_number}$\,\}$\par\noindent\hskip20pt
+$j$: $0\to64$;\quad$\{\,$an index into \\{hc}$\,\}$
+
+\bugonpage B404, line 21 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $k,l$: $0\to64$;\quad$\{\,$indices into \\{hc} and \\{hyf};
+ not always in \\{small\_number} range$\,\}$
+
+\bugonpage B460, lines 21 and 22 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+\\{push\_nest}; \ $\\{mode}\gets\\{hmode}$; \ $\\{space\_factor}\gets1000$; \
+ \\{set\_cur\_lang}; \ $\\{clang}\gets\\{cur\_lang}$;\par\noindent\hskip10pt
+$\\{prev\_graf}\gets(\\{norm\_min}(\\{left\_hyphen\_min})\ast\oct{100}+
+ \\{norm\_min}(\\{right\_hyphen\_min}))\ast\oct{200000}+\\{cur\_lang}$;
+
+\bugonpage B492, line 6 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+\\{unsave}; \ $\\{prev\_graf}\gets\\{prev\_graf}+3$;\par\noindent\hskip10pt
+\\{push\_nest}; \ $\\{mode}\gets\\{hmode}$; \ $\\{space\_factor}\gets1000$; \
+ \\{set\_cur\_lang}; \ $\\{clang}\gets\\{cur\_lang}$;\par\noindent\hskip10pt
+$\\{prev\_graf}\gets(\\{norm\_min}(\\{left\_hyphen\_min})\ast\oct{100}+
+ \\{norm\_min}(\\{right\_hyphen\_min}))\ast\oct{200000}+\\{cur\_lang}$;
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C151, line 11 from the bottom (6/26/93)
+
+\ninepoint\indent
+\qquad scaled $1.42(1+\max(-\\{pen\_lft},\\{pen\_rt},\\{pen\_top},
+ -\\{pen\_bot}))$
+
+\bugonpage C262, line 15 (6/26/93)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="2.71";|
+
+\bugonpage C262, line 29 (6/26/93)
+
+\ninepoint\noindent
+|def |^|gobble|| primary g = enddef; def |^|killtext|| text t = enddef;|
+
+\bugonpage C271, bottom line (6/26/93)
+
+\ninepoint\noindent
+| culldraw p enddef;|
+
+\bugonpage C272, three new lines for top of page (6/26/93)
+
+{\ninepoint\parindent=0pt
+|def |^|culldraw|| expr p = addto pic_ doublepath p.t_ withpen currentpen;|\par
+| cull pic_ dropping(-infinity,0) withweight default_wt_;|\par
+| addto_currentpicture also pic_; pic_:=nullpicture; killtext enddef;|\par
+}
+
+\bugonpage C272, replacement for former line 5 (6/26/93)
+
+\ninepoint\noindent
+| (cut_ scaled (1+max(-pen_lft,pen_rt,pen_top,-pen_bot))|
+
+\bugonpage C296, line 24 (2/3/93)
+
+\ninepoint\noindent
+the definition of |rp| is changed to `|]..tension 4..|',
+and if `|scaled|~|5pt|' is inserted\cutpar
+
+\bugonpage C299, line 3 (5/15/92)
+
+\ninepoint\noindent
+a Bernshte{\u\i}n polynomial of order $n-1$.)
+
+\bugonpage C347, left column (5/15/92)
+
+\eightpoint
+Bernshte{\u\i}n, Serge{\u\i} \thinspace Natanovich, 14.
+
+\bugonpage C348, left column (6/26/93)
+
+\eightpoint
+|culldraw|, {\it271}, $\underline{272}$.
+
+\bugonpage C350, left column (6/26/93)
+
+\eightpoint
+exponential, {\sl see\/} |mexp|.
+
+\bugonpage C352, left column (6/26/93)
+
+\eightpoint
+|killtext|, $\underline{262}$, {\it 272}.
+
+\bugonpage C352, right column (6/26/93)
+
+\eightpoint
+logarithm, {\sl see\/} |mlog|.
+
+\bugonpage C361, lines 14 and 15 (2/25/93)
+
+P.O. Box 869\par
+Santa Barbara, CA 93102-0869 USA.
+
+
+ % Volume D
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Dxiv, line 13 (4/19/96)
+
+\noindent preprocessor converts these into numeric constants that are
+256 or more. This\cutpar
+
+\bugonpage Dxiv, line $-1$ (4/19/96)
+
+\ninepoint\noindent This file contains one line per string, starting with
+string number 256, then number 257,\cutpar
+
+\bugonpage Dxv, lines 10 and 11 (4/19/96)
+
+\ninepoint\noindent
+In this case, occurrences of |""| in the |WEB| program will be replaced by
+256; occurrences of |"This longer string"| will be replaced by 257.
+The symbol |@$| stands for the numeric\cutpar
+
+\hsize=35pc
+\bugonpage D2, line $-17$ (8/7/98)
+
+\def\RQ/{{\char'23}} % right quote in a string
+\ninepoint\noindent
+{\bf define} $\\{banner}\equiv\hbox{\tt\RQ/This\]is\]METAFONT,\]%
+ Version\]2.7182\RQ/}$\quad$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D50, line 26 (8/7/98)
+
+\ninepoint\noindent
+\quad{\bf if\/} $b>0$ {\bf then}
+
+\bugonpage D138, line 14 from the bottom (3/6/95)
+
+\tenpoint
+\textindent{$2'$)} Let $Z_k^{(j+1)}={1\over2}(Z_k^{(j)}+Z_{k+1}^{(j)})$, for
+$1\le k\le n-j$, for $1\le j<n$.
+
+\bugonpage D190, D191, D194, D195 (6/26/93)
+
+\noindent[Several changes to the code in sections 415, 416, 424, and 425
+were made to \MF\ version 2.71 in July~1991, too numerous to mention here.
+They are documented in file {\tt mf84.bug} as bug number 560. We also
+delete lines 4 and~5 of page D194.]
+
+\bugonpage D216, line 10 from the bottom (7/15/92)
+
+\tenpoint\noindent
+will be offset by $w_1$ or $w_2$, unless its slope drops to zero
+en route to the eighth octant; in the latter\cutpar
+
+\bugonpage D289, lines 9 and 10 (6/26/93)
+
+\ninepoint\noindent\hskip20pt
+$p\gets\\{dep\_list}(p)$; \ $r\gets\\{inf\_val}$;\par\noindent\hskip20pt
+{\bf repeat if\/} $\\{value}(\\{info}(p))\ge\\{value}(r)$ {\bf then}
+
+\bugonpage D296, lines 8 and 9 from the bottom (9/13/98)
+
+\ninepoint\noindent[Delete these spurious lines.]
+
+\bugonpage D297, mini-index (6/6/98)
+
+\eightpoint the meaning of {\it loc\/} should be `macro'
+
+\bugonpage D310, line 7 (8/7/98)
+
+\ninepoint\noindent
+\quad{\bf if\/} $(\\{loc}=k+1)\land(\\{length}(\\{buffer}[k])=1)$
+ {\bf then} $\\{cur\_mod}:=\\{buffer}[k]$
+
+\bugonpage D363, lines 10 and 11 (3/1/95)
+
+\ninepoint\noindent
+\quad {\bf begin if\/} $(\\{max\_c}[\\{dependent}]$ {\bf div}
+ $\oct{10000}\ge\\{max\_c}[\\{proto\_dependent}])$ {\bf then}
+ $t\gets\\{dependent}$
+
+\bugonpage D512, line 13 (11/23/98)
+
+\ninepoint\noindent
+\quad \\{print\_int}(\\{round\_unscaled}(\\{internal}[\\{year}])); \
+ \\{print\_char}(|"."|);
+
+\bugonpage D518, insert new material between lines 7 and 8 (3/20/95)
+
+\ninepoint\noindent
+\quad {\bf while} $\\{input\_ptr}>0$ {\bf do}\par\noindent
+\qquad {\bf if\/} \\{token\_state} {\bf then} \\{end\_token\_list}
+ {\bf else} \\{end\_file\_reading};\par\noindent
+\quad {\bf while} $\\{loop\_ptr}\ne\\{null}$ {\bf do} \\{stop\_iteration};
+
+\bugonpage D518, line 18 (3/20/95)
+
+\ninepoint\noindent
+\qquad $\\{loop\_ptr}\gets\\{cond\_ptr}$; \
+ $\\{cond\_ptr}\gets\\{link}(\\{cond\_ptr})$; \
+ $\\{free\_node}(\\{loop\_ptr},\\{if\_node\_size})$;
+
+\bugonpage D546, left column (4/11/96)
+
+\eightpoint
+Stern, Moritz Abraham: \ 526.
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.five b/Master/texmf-doc/doc/english/knuth/errata/errata.five
new file mode 100644
index 00000000000..4e2982f109a
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.five
@@ -0,0 +1,1108 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1989}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes \hbox{A--E}, between 20 February 1989 and
+30 September 1989 (when \TeX\ Version 3.0 and \MF\ Version 2.0 were
+fully defined). Corrections made to
+the softcover version of {\sl The \TeX book\/} are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+Some of these corrections have already been made in reprintings
+of the books. Several minor changes
+to Volumes A~and~C are not shown here because they simply
+make room for the more substantive changes needed to describe the new
+features of \TeX\ Version 3.0 and \MF\ Version 2.0. Hundreds of
+changes will soon be made to Volumes B~and~D because of the upgrades
+to \TeX\ and \MF\/; it will unfortunately be impossible to document all of those
+changes. Therefore, readers who need up-to-date information on the \TeX\ and
+\MF\ programs should refer to the |WEB| source files until new
+printings of Volumes B~and~D are issued.
+
+ % volume A
+
+\buginvol A, in general (9/23/89)
+
+\ninepoint\noindent
+[Change `127' to `255' and `128' to `256' in contexts referring to character
+codes. This happens on pages 37(twice), 39, 41, 43, 44(twice), 48, 93, 154,
+277, 305(twice), 308(twice), 313, and 343. Also change `7-bit' to `8-bit' on
+pages 214 and 277.]
+
+\bugonpage A23, line 16 (9/23/89)
+
+|This is TeX, Version 3.0 (preloaded format=plain 89.7.15)|
+
+\bugonpage A34, new copy for bottom of page (9/23/89)
+
+\ddanger If you use \TeX\ format packages designed by others, your
+error messages may involve many inscrutable two-line levels of macro
+context. By setting ^|\errorcontextlines||=0| at the beginning of your file,
+you can reduce the amount of information that is reported;
+\TeX\ will show only the top and bottom pairs of context lines
+together with up to |\errorcontextlines| additional two-line items. \ (If
+anything has thereby been omitted, you'll also see `|...|'.) \ Chances
+are good that you can spot the source of an error even when most of a
+large context has been suppressed; if not, you can say
+`|I\errorcontextlines=100\oops|' and try again. \ (That will usually
+give you an undefined control sequence error and plenty of context.) \
+Plain \TeX\ sets |\errorcontextlines=5|.
+
+\bugonpage A45, lines 9--15 (9/23/89)
+
+\ninepoint\noindent
+|^^| has an internal code between 64 and 127, \TeX\
+subtracts 64 from the code; if the code is between 0 and 63, \TeX\
+adds~64. Hence code 127 can be typed |^^?|, and
+the dangerous bend sign can be obtained by saying
+|{\manual^^?}|. However, you must change the category code of character
+127 before using it, since this character ordinarily has category~15
+(^{invalid}); say, e.g., |\catcode`\^^?=12|.
+^^{double hat} ^^{hat hat}
+The |^^| notation is different from |\char|, because |^^| combinations are
+like single characters; for example, it would not be permissible to say
+|\catcode`\char127|, but |^^| symbols can even be used as letters within
+control words.
+
+\bugonpage A45, new copy before line 20 (9/23/89)
+
+\danger There's also a special convention in which |^^| is
+followed by {\sl two\/} ``lowercase hexadecimal digits,'' |0|--|9| or |a|--|f|.
+With this convention, all 256 characters are obtainable in a uniform
+way, from |^^00| to |^^ff|. Character 127 is |^^7f|.
+
+\noindent
+[Also remove one of the two dangerous bend signs on line 20.]
+
+\bugonpage A45, bottom paragraph and footnote (9/23/89)
+
+\ddanger People who install \TeX\ systems for use with non-American alphabets
+can make \TeX\ conform to any desired standard. For example, suppose
+you have a ^{Norwegian keyboard} containing the letter {\tt\ae}, which
+^^{Scandinavian letters} ^^{foreign languages}
+comes in as code~241 (say). Your local format package should define
+|\catcode`|{\tt\ae}|=11|; then you could have control sequences like
+|\s|{\tt\ae}|rtrykk|. Your \TeX\ input files could be made readable by
+American installations of \TeX\ that don't have your keyboard, by
+substituting |^^f1| for character~241. \ (For example, the stated control
+sequence would appear as |\s^^f1rtrykk| in the file; your American
+friends should also be provided with the format that you used, with its
+|\catcode`^^f1=11|.) \ Of course you should also arrange your fonts
+so that \TeX's character 241 will print as {\ae}; and you should
+change \TeX's hyphenation algorithm so that it will do correct
+Norwegian hyphenation. The main point is that such changes are not
+extremely difficult; nothing in the design of \TeX\ limits it to the
+American alphabet. Fine printing is obtained by fine tuning to the
+language or languages being used.
+^^{keyboards, non-ASCII}
+
+\ddanger European languages can also be accommodated effectively with
+only a limited character set.
+For example, let's consider Norwegian again, but suppose that\parfillskip=0pt
+
+\noindent [Now continue with the text on line 11 of page 46.]
+
+\bugonpage A47, lines 9--21 (9/23/89)
+
+\ddanger If \TeX\ sees a superscript character (category 7) in any state,
+and if that character is followed by another identical character, and if
+those two equal characters are followed by a character of code
+$c<128$, then they
+are deleted and 64 is added~to or subtracted from the code~$c$.
+\ (Thus, |^^A| is
+replaced by a single character whose code is~1, etc., as explained earlier.) \
+However, if the two superscript characters are immediately followed by two
+of the lowercase hexadecimal digits |0123456789abcdef|, the
+four-character sequence is replaced by a single character having the
+specified hexadecimal code.
+The replacement is carried out also if such a trio or quartet of
+characters is encountered during steps (b) or~(c) of the control-sequence-name
+scanning procedure described above. After the replacement is made, \TeX\
+begins again as if the new character had been present all the time.
+If a superscript character is not the first of such a trio or quartet, it is
+handled by the following rule.
+
+\ddanger If \TeX\ sees a character of categories 1, 2, 3, 4, 6, 8, 11, 12,
+or~13,
+or a character of category~7 that is not the first of a special
+sequence as just
+described, it converts the character to a token by attaching the category
+code, and goes into state~$M$. This is the normal case; almost every
+nonblank character is handled by this rule.
+
+\bugonpage A48, line 15 (9/23/89)
+
+\ninepoint\noindent
+the input line
+`| $x^2$~ \TeX ^^62^^6|'\thinspace?
+
+\bugonpage A54, third line from the bottom (9/23/89)
+
+\ninepoint\noindent
+For example, a well-designed \TeX\ font for ^{French}
+might well treat accents as lig-\cutpar
+
+\bugonpage A76, lines 3--5 from the bottom (9/23/89)
+
+\ninepoint\noindent
+\TeX\ does not assign any value to
+|\sfcode'042|.
+
+\bugonpage A107, new copy for top of page (9/23/89)
+
+\ddanger If you want to avoid overfull boxes at all costs without
+trying to fix them manually, you might be tempted to set
+|tolerance=10000|; this allows arbitrarily bad lines to be acceptable
+in tough situations. But infinite tolerance is a bad idea, because
+\TeX\ doesn't distinguish between terribly bad and preposterously
+horrible lines. Indeed, a tolerance of 10000 encourages \TeX\ to
+concentrate all the badness in one place, making one truly unsightly
+line instead of two moderately bad ones, because a single
+``write-off'' produces fewest total demerits according to the rules.
+There's a much better way to get the desired effect: \TeX\ has a
+parameter called ^|\emergencystretch| that is added to the assumed
+stretchability of every line when badness and demerits are computed,
+in cases where overfull boxes are otherwise unavoidable. If
+|\emergencystretch| is positive, \TeX\ will make a third pass over a
+paragraph before choosing the line breaks, when the first passes did
+not find a way to satisfy the ^|\pretolerance| and ^|\tolerance|.
+The effect of\/ |\emergencystretch| is to scale down the badnesses so
+that large infinities are distinguishable from smaller ones. By
+setting |\emergencystretch| high enough (based on |\hsize|) you can be
+sure that the |\tolerance| is never exceeded; hence overfull boxes
+will never occur unless the line-breaking task is truly impossible.
+
+\bugonpage A116, lines 11--15 (6/7/89)
+
+\danger If you have two or more |\topinsert| or |\pageinsert| commands in
+quick succession, \TeX\ may need to carry them over to several subsequent
+pages; but they will retain their relative order when they are
+carried over. For example, suppose you have pages that are nine inches
+tall, and suppose you have already specified 4~inches of text for some
+page, say page~25. Then suppose you make seven topinserts in a row, of%
+{\parfillskip=0pt\endgraf}\endgroup
+
+\bugonpage A125, lines 13--29 (9/23/89)
+
+\ddanger \looseness=-1
+When the best page break is finally chosen, \TeX\ removes everything after
+the chosen breakpoint from the bottom of the ``current page,'' and puts it
+all back at the top of the ``recent contributions.'' The
+chosen breakpoint itself is placed at the very top of the recent contributions.
+If it is a penalty item, the value of the penalty is recorded in
+^|\outputpenalty| and the penalty in the contribution list is changed
+to $10000$; otherwise |\outputpenalty| is set to 10000.
+The insertions that remain on the current page are of three kinds: For
+each class~$n$ there are unsplit insertions, followed possibly by
+a single split insertion, followed possibly by others. If
+^|\holdinginserts|$\null>0$, all insertions remain in place (so that
+they might be contributed again); otherwise they are all removed from
+the current page list as follows: The unsplit insertions
+are appended to |\box|$\,n$, with no interline glue between them. \
+(^{Struts} should be used, as in the |\vfootnote| macro of
+Appendix~B\null.) \
+If a split insertion is present, it is effectively |\vsplit| to the size
+that was computed previously in Step~4; the top part is treated as an
+unsplit insertion, and the remainder (if any) is converted to an insertion
+as if it had not been split. This remainder, followed by any other floating
+insertions of the same class, is held
+over in a separate place. \ (They will show up on the ``current page'' if
+^|\showlists| is used while an ^|\output| routine is active; the total
+number of such insertions appears in ^|\insertpenalties| during an
+|\output| routine.) %\
+Finally, the remaining items before the best break on the current page are put
+together in a |\vbox|\parfillskip=0pt
+
+\bugonpage A131, line 12 (9/22/89)
+
+\ninepoint\noindent
+work fine; but sometimes you want to have uniformity
+between different members of a\cutpar
+
+\bugonpage A155, lines 3--5 (9/23/89)
+
+\ninepoint\noindent
+when it encounters a character that
+is given explicitly as ^|\char|\<number>.
+
+\bugonpage A214, lines 19--24 (9/23/89)
+
+\ninepoint
+\textindent\bull |\the|\<special register>, where \<special register> is
+one of the integer quantities ^|\prevgraf|, ^|\deadcycles|, ^|\insertpenalties|,
+^|\inputlineno|, ^|\badness|,
+or ^|\parshape| (denoting only the number of lines of\/ |\parshape|); or
+one of the dimensions ^|\pagetotal|, ^|\pagegoal|, ^|\pagestretch|,
+^|\pagefilstretch|, ^|\pagefillstretch|, ^|\pagefilllstretch|, ^|\pageshrink|,
+^|\pagedepth|. In horizontal modes you can also refer to a special integer,
+|\the\spacefactor|; in vertical modes there's a special dimension,
+|\the\prevdepth|.
+
+\bugonpage A229, new copy after line 11 (9/23/89)
+
+\ddanger \TeX\ will report the badness of glue setting in a box if
+you ask for the numeric quantity
+^|\badness| after making a box. For example, you might say
+\begintt
+\setbox0=\line{\trialtexta}
+\ifnum\badness>250 \setbox0=\line{\trialtextb}\fi
+\endtt
+The badness is between 0 and 10000
+unless the box is overfull, when |\badness=1000000|.
+
+\bugonpage A271, lines 17--20 (9/23/89)
+
+\ninepoint
+\beginsyntax
+ \alt<countdef token>\alt^|\count|<8-bit number>\alt<codename><8-bit number>
+ \alt<chardef token>\alt<mathchardef token>\alt^|\parshape|\alt^|\inputlineno|
+ \alt^|\hyphenchar|<font>\alt^|\skewchar|<font>\alt^|\badness|
+\endsyntax
+
+\bugonpage A272, lines 3--4 (9/23/89)
+
+\ninepoint\noindent
+value is between 0~and $2^8-1=255$; a ^\<4-bit number> is similar.
+
+\bugonpage A273, insert after lines 11, 20, 21, 21, 38 (9/23/89)
+
+\ninepoint
+\begindisplay
+|\holdinginserts|\quad(positive if insertions remain dormant in output box)\cr
+|\language|\quad(the current set of hyphenation rules)\cr
+|\lefthyphenmin|\quad(smallest fragment at beginning of hyphenated word)\cr
+|\righthyphenmin|\quad(smallest fragment at end of hyphenated word)\cr
+|\errorcontextlines|\quad(maximum extra context shown when errors occur)\cr
+\enddisplay
+
+\bugonpage A274, insert after line 4 (9/23/89)
+
+\ninepoint\indent
+|\emergencystretch|\quad(reduces badnesses on final pass of line-breaking)
+
+\bugonpage A275, line 13 (9/23/89)
+
+\ninepoint\noindent
+That makes a total of 103 parameters of all five kinds.
+
+\bugonpage A283, line 14 (9/23/89)
+
+\ninepoint
+\beginsyntax
+ \alt^|\noboundary|\alt^|\unhbox|\alt^|\unhcopy|\alt^|\valign|\alt^|\vrule|
+\endsyntax
+
+\bugonpage A286, lines 3--12 from the bottom (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+\<letter>, \<otherchar>, \kern-1pt^|\char|\<8-bit number>, \<chardef token>,
+\kern-1pt^|\noboundary|.\enskip
+The most common commands of all are the character commands that tell
+\TeX\ to append a character to the current horizontal
+list, using the current font.
+If two or more commands of this type occur in succession, \TeX\ processes
+them all as a unit, converting to ligatures and/or
+inserting kerns as directed by the font information. \ (Ligatures and
+kerns may be influenced by invisible ``boundary'' characters at the left
+and right, unless |\noboundary| appears.) \ Each character
+command adjusts ^|\spacefactor|, using
+the ^|\sfcode| table as described in Chapter~12.
+In unrestricted horizontal mode, a
+`|\discretionary{}{}{}|' item is appended after a character whose code is
+the ^|\hyphenchar| of its font, or after a ligature formed from a sequence
+that ends with such a character.
+
+\bugonpage A287, insert after line 19 (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+|\setlanguage|\<number>.\enskip See the conclusion of Appendix H.
+
+\bugonpage A289, lines 9--14 from the bottom (9/23/89)
+
+\ninepoint\noindent
+$2^{15}-1$. This is done by replacing the character number by its
+^|\mathcode| value. If the
+|\mathcode| value turns out to be $32768=\null$\hex{8000}, however,
+ the \<character>
+is replaced by an ^{active character} token having the original character
+code (0 to~255); \TeX\ forgets the original \<character> and expands this
+active character according to the rules of Chapter~20.
+
+\bugonpage A290, insert before 13th line from bottom (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+|\noboundary|. This command is redundant and therefore has no
+effect; boundary ligatures are automatically disabled in math modes.
+
+\bugonpage A296, line 16 from the bottom (9/22/89)
+
+\noindent[There should be a `|^|' just above the `|3|' in the line below.
+This was mistakenly dropped by the printer some time during 1985; it was
+correct in the first two printings and it has always been correct inside the
+computer!]
+
+\bugonpage A309, lines 3--5 (9/23/89)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss8.4.\enspace}\ignorespaces
+|$|$_{3}$ |x|$_{11}$ |^|$_7$ |2|$_{12}$ |$|$_{3}$ |~|$_{13}$ \]$_{10}$
+\cstok{TeX} |b|$_{12}$ |v|$_{12}$ \]$_{10}$. The final space comes from the
+\<return> placed at the end of the line. Code |^^6| yields |v| only
+when not followed by |0|--|9| or |a|--|f|.
+The initial space is ignored, because state~$N$
+governs the beginning of the line.
+
+\bugonpage A314, line 27 (9/23/89)
+
+\ninepoint\noindent
+The English word `eighteen' might deserve similar treatment.
+\TeX's hyphenation algorithm will not make such spelling changes automatically.
+
+\bugonpage A318, line 19 (3/3/89)
+
+\ninepoint
+|\def\clearnotenumber{\notenumber=0\relax}|
+
+\bugonpage A330, line 3 (8/25/89)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss20.10.\enspace}\ignorespaces
+|\def\overpaid{{\count0=\balance|
+
+\bugonpage A336, lines 4--8 from the bottom (9/23/89)
+
+\ninepoint\noindent
+badness rating of a
+box is at most 10000, except that the |\badness| of
+an overfull box is 1000000. |INITEX| initializes |\tolerance| to
+10000, thereby making all line breaks feasible. Penalties of 10000 or more
+prohibit breaks; penalties of $-10000$ or less make breaks mandatory. The
+cost of a page break is 100000, if the badness is 10000 and if the
+associated penalties are less than 10000 in magnitude (see Chapter~15).
+
+\bugonpage A337, lines 2--16 (9/23/89)
+
+\ninepoint\noindent
+ifies characters whose codes differ by~64
+from the codes of |?|, |@|, |A|; this convention applies only to
+characters with ASCII codes less than~128. There are 256 possible characters,
+hence 256 entries in each of the |\catcode|, |\mathcode|,
+|\lccode|, |\uccode|, |\sfcode|, and |\delcode| tables. All
+|\lccode|, |\uccode|, and |\char| values
+must be less than~256. A font has at most 256 characters. There are
+256~|\box| registers, 256~|\count| registers, 256~|\dimen| registers,
+256~|\skip| registers, 256~|\muskip| registers, 256~|\toks| registers,
+256~hyphenation tables.
+The ``at size'' of a font must be less than~$2048\pt$, i.e.,~$2^{11}\pt$.
+Math delimiters are encoded by multiplying the math~code of the ``small
+character'' by~$2^{12}$. The magnitude of
+a~\<dimen> value must be less than~$16384\pt$, i.e.,~$2^{14}\pt$;
+similarly, the \<factor> in a~\<fil dimen> must be less than~$2^{14}$.
+A~|\mathchar| or |\spacefactor| or |\sfcode| value must be less than~$2^{15}$;
+a~|\mathcode| or |\mag| value must be less than or equal to~$2^{15}$,
+and $2^{15}$ denotes an ``active'' math character. There
+are $2^{16}\rm\,sp$ per~pt. A~|\delcode| value
+must be less than~$2^{24}$; a~|\delimiter|, less than $2^{27}$.
+The |\end| command sometimes contributes
+a penalty of $-2^{30}$ to the current page. A~\<dimen> must be less than
+$2^{30}\rm\,sp$ in absolute value; a~\<number> must be
+less than $2^{31}$ in absolute value.
+
+\bugonpage A348, line 12 from the bottom (9/23/89)
+
+\ninepoint\noindent
+^|\showboxbreadth||=5 |^|\showboxdepth||=3 |^|\errorcontextlines||=5|
+
+\bugonpage A364, insert before line 18 from the bottom (9/23/89)
+
+\ninepoint\noindent
+^|\lefthyphenmin||=2 |^|\righthyphenmin||=3 % disallow x- or -xx breaks|
+
+\bugonpage A364, line 5 from the bottom (9/23/89)
+
+\ninepoint\noindent
+|\def|^|\fmtname||{plain}\def\fmtversion{3.0} % identifies the current format|
+
+\bugonpage A369, insert before line 5 from the bottom (9/23/89)
+
+\ninepoint
+Modern keyboards allow 256 codes to be input, not just 128; so \TeX\
+represents characters internally as numbers in the range 0--255 (i.e.,
+\oct{000}--\oct{377}, or \hex{00}--\hex{FF}). Implementations of \TeX\
+differ in which characters they will accept in input files and which
+they will transmit to output files; these subsets can be specified
+independently. A completely permissive version of \TeX\ allows full
+256-character input and output; other versions might ignore all
+but the visible characters of ASCII; still other versions might
+distinguish the tab character (code \oct{011}) from a space on input,
+but might output each tab as a sequence of three characters |^^I|.
+
+\bugonpage A370, lines 3--7 (9/23/89)
+
+\ninepoint\noindent
+close as possible to the ASCII conventions.
+\ (b)~Make sure that codes \oct{041}--\oct{046}, \oct{060}--\oct{071},
+\oct{141}--\oct{146}, and \oct{160}--\oct{171} are present and that
+each unrepresentable
+internal code $<\null$\oct{200} leads to a representable code when \oct{100} is
+added or subtracted; then all 256 codes can be input and output.
+\ (c)~Cooperate with everyone else who shares
+the same constraints, so that you all adopt the same policy.
+\ (See Appendix~J for information about the \TeX\ Users Group.)
+
+\bugonpage A370, bottom line (9/23/89)
+
+\ninepoint\noindent
+doesn't matter if these symbols have their plain
+\TeX\ meanings or not. \ (6)~There is a special convention for
+representing characters 0--255 in the hexadecimal forms
+|^^00|--|^^ff|, explained in Chapter~8. This convention is always
+acceptable as input, when |^| is any character of catcode~7. Text
+output is produced with this convention only when representing
+characters of code $\ge128$ that a \TeX\ installer has chosen not to
+output directly.
+
+\bugonpage A385, line 8 (5/14/89)
+
+\ninepoint
+|\def\beginbox{\setbox0=\hbox\bgroup}|
+
+\bugonpage A400, line 18 from the bottom (9/23/89)
+
+\ninepoint\noindent
+page prematurely if you want to pass a signal. \ (Set
+^|\holdinginserts| positive to pass a signal when the contents of\/
+|\box255| will be sent back through the page builder again, if any
+insertions are present.)
+
+\bugonpage A419, lines 4--6 (9/23/89)
+
+\ninepoint\noindent
+shortened or lengthened anyway;
+book preparation with \TeX, as with type, encourages interaction between
+humans and machines.) \
+The lines of the quotations are set ^{flush right} by using
+^|\obeylines| together with a stretchable ^|\leftskip|:
+
+\bugonpage A444, lines 21--26 (9/23/89)
+
+\ninepoint\noindent
+following one, using the specified family and the current size, then
+insert the ligature character and continue as specified by the font;
+two characters may collapse into one, or a new character may appear.
+Otherwise if the font information
+shows a kern between the current symbol and the next, insert a kern item
+after the current Ord atom and move to the next item after that.
+Otherwise (i.e., if no ligature or kern is specified between the present
+text symbol and the following character), go to Rule~17.
+
+\bugonpage A453, lines 12--14 from the bottom (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ninepoint\noindent
+Exception: The character
+`|.|'~is treated as if it were a \<letter> of code~0
+when it appears in a pattern. Code~0 (which obviously cannot match a nonzero
+|\lccode|) is used by \TeX\ to represent the
+left or right edge of a word when it is being hyphenated.
+
+\endgroup
+
+\bugonpage A454, lines 7--15 from the bottom (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger If a trial word $l_1\ldots l_n$ has been found by this process,
+hyphenation will still be abandoned unless $n\ge\lambda+\rho$, where
+$\lambda=\max(1,\hbox{|\lefthyphenmin|})$ and
+$\rho=\max(1,\hbox{|\righthyphenmin|})$.
+\ (Plain \TeX\ takes $\lambda=2$ and $\rho=3$.) \ Furthermore, the items
+immediately following the trial word must consist of zero or more
+characters, ligatures, and implicit kerns, followed immediately by
+either glue or an explicit kern or a penalty item or a whatsit or an
+item of vertical mode material from ^|\mark|, ^|\insert|, or ^|\vadjust|.
+Thus, a box or rule or math formula or discretionary following too closely
+upon the trial word will inhibit hyphenation. (Since \TeX\ inserts
+empty discretionaries after ^{explicit hyphens}, these rules imply that
+already-hyphenated compound words will not be further hyphenated by
+the algorithm.)
+
+\endgroup
+
+\bugonpage A455, new copy after line 13 (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger \looseness=-1
+So far we have assumed that \TeX\ knows only one style of
+hyphenation at a time; but in fact \TeX\ can remember up to 256
+distinct sets of rules, if you have enough memory in your computer. An
+integer parameter called ^|\language| selects the rules actually used;
+every ^|\hyphenation| and ^|\patterns| specification appends new rules
+to those previously given for the current value of\/ |\language|.
+\ (If\/ |\language| is negative or greater than 255, \TeX\ acts as if
+|\language|$\null=0$.) \ All |\patterns| for all languages must be
+given before a paragraph is typeset, if |INITEX| is used for
+typesetting.
+
+\ddanger \TeX\ is able to work with several languages in the same
+paragraph, because it operates as follows. At the beginning of a
+paragraph the ``current language'' is defined to be~0. Whenever a
+character is added to the current paragraph (i.e., in unrestricted
+horizontal mode), the current language is compared to |\language|; if
+they differ, the current language is reset and a whatsit node
+specifying the new current language is inserted before the character.
+Thus, if you say `|\def\french{\language1...}|' and `|mix| |{\french
+franc/ais}| |with| |English|', \TeX\ will put whatsits before the |f|
+and the~|w|; hence it will use language~1 rules when hyphenating
+|franc/ais|, after which it will revert to language~0. You can insert
+the whatsit yourself (even in restricted horizontal mode) by saying
+^|\setlanguage|\<number>; this changes the current language but it
+does not change |\language|.
+
+\endgroup
+
+\bugonpage A459, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\badness|, 214, {\it229}, 271.
+
+\bugonpage A461, right column (9/23/89)
+
+\eightpoint
+caron, {\sl see\/} h\'a\v cek.
+
+\bugonpage A464, line 10 (5/15/89)
+
+\eightpoint
+displays, 87, 103, {\it139--145}, {\it166--167},
+
+\bugonpage A464, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\emergencystretch|, $\underline{107}$, 274.
+
+\bugonpage A465, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\errorcontextlines|, $\underline{34}$, 273, {\it348}.
+
+\bugonpage A466, entry for `fractions' (9/23/89)
+
+\eightpoint[Add page 332 to this entry.]
+
+\bugonpage A466, entry for `French'' (9/23/89)
+
+\eightpoint[Add page 455 to this entry.]
+
+\bugonpage A467, entry for `hexadecimal' (9/23/89)
+
+\eightpoint[Add pages 45, 47--48 to this entry.]
+
+\bugonpage A467, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\holdinginserts|, $\underline{125}$, 273, 400.
+
+\bugonpage A467, bottom line (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\hyphenation|, 277, {\it419}, $\underline{452}$--$\underline{453}$, 455.
+
+\bugonpage A468, right column (9/23/89)
+
+\eightpoint
+infinite badness, 97, 107, 111, 229, 317.
+
+\bugonpage A468, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\inputlineno|, 214, 271.
+
+\bugonpage A469, entry for kerns (9/23/89)
+
+\eightpoint[Add pages 286 and 444 to this entry.]
+
+\bugonpage A469, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\language| (hyphenation method), 273, $\underline{455}$.
+
+\bugonpage A469, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\lefthyphenmin|, 273, {\it364}, $\underline{454}$.
+
+\bugonpage A470, entry for ligatures (9/23/89)
+
+\eightpoint[Add pages 286 and 444 to this entry.]
+
+\bugonpage A472, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\noboundary|, 283, $\underline{286}$, 290.
+
+\bugonpage A473, right column (9/23/89)
+
+\eightpoint
+overfull boxes, 27--30, 94, 229, 238,\par
+\indent\qquad 302--303, 307, 400.\par
+\indent\quad avoiding, 107.
+
+\bugonpage A474, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\patterns|, 277, $\underline{453}$, 455.
+
+\bugonpage A476, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\righthyphenmin|, 273, {\it364}, $\underline{454}$.
+
+\bugonpage A476, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\setlanguage|, 287, $\underline{455}$.
+
+\bugonpage A476, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\showboxbreadth|, 273, $\underline{302}$, 303, {\it348}.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\showboxdepth|, 79, 273, $\underline{302}$, 303, {\it348}.
+
+\bugonpage A479, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tolerance|, {\it29--30}, 91, 94, $\underline{96}$, 107, 272,\par
+\indent\qquad{\it317}, {\it333}, {\it342}, {\it348}, {\it364}, {\it451}.
+
+\bugonpage A481, right column, last six entries (9/23/89)
+
+\def\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}%
+\eightpoint
+\frac1/2, 67, 332.\par
+1/2, in unslashed form, 141, 186.\par
+\<4-bit number>, $\underline{271}$.\par
+\<8-bit number>, $\underline{271}$, 276--278.\par
+\<15-bit number>, $\underline{271}$, 277, 289, 291.\par
+\<27-bit number>, $\underline{271}$, 289, 291.\par
+
+\bugonpage A483, lines 15 and 21 (9/23/89)
+
+\noindent[Delete these two lines, as TUG's address is no longer c/o AMS.]
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Bvii, top two lines (4/21/89)
+
+{\hsize=29pc
+\tenpoint\noindent
+{\it {\sltt WEB} documentation for four utility programs that are
+often used in conjunction with \TeX: {\sltt POOLtype}, {\sltt TFtoPL},
+{\sltt PLtoTF}, and {\sltt DVItype}.}
+\par}
+
+\bugonpage B2, line 32 (6/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.991\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B118, lines 2--4 (3/2/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin if\/} $\\{cur\_level}>\\{level\_one}$ {\bf then}\par
+\noindent\hskip20pt{\bf begin} \\{check\_full\_save\_stack}; \
+ $\\{save\_type}(\\{save\_ptr})\gets\\{insert\_token}$;\par
+\noindent\hskip20pt$\\{save\_level}(\\{save\_ptr})\gets\\{level\_zero}$; \
+ $\\{save\_index}(\\{save\_ptr})\gets t$; \ \\{incr}(\\{save\_ptr});\par
+\noindent\hskip20pt{\bf end};
+
+\bugonpage B182, line 13 becomes two lines (6/20/89)
+
+\ninepoint\noindent
+$k,\\{kk}$: \\{small\_number};\quad
+ $\{\,$number of digits in a decimal fraction$\,\}$\par\noindent
+$p,q$: \\{pointer};\quad
+ $\{\,$top of decimal digit stack$\,\}$
+
+\bugonpage B182, line 15 from the bottom (6/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $k\gets0$; $p\gets\\{null}$; \\{get\_token};\quad
+ $\{\,$\\{point\_token} is being re-scanned$\,\}$
+
+\bugonpage B182, line 11 from the bottom (6/20/89)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} $q\gets\\{get\_avail}$; $\\{link}(q)\gets p$;
+ $\\{info}(q)\gets\\{cur\_tok}-\\{zero\_token}$;
+ $p\gets q$; $\\{incr}(k)$;
+
+\bugonpage B182, line 8 from the bottom (6/20/89)
+
+\ninepoint\noindent
+\\{done1}: {\bf for} $\\{kk}\gets k$ {\bf downto} 1 {\bf do}\par
+\noindent\hskip20pt
+{\bf begin} $\\{dig}[kk-1]\gets\\{info}(p)$; $q\gets p$; $p\gets\\{link}(p)$;
+ $\\{free\_avail}(q)$;\par
+\noindent\hskip20pt{\bf end};\par
+\noindent\hskip10pt$f\gets\\{round\_decimals}(k)$;
+
+\bugonpage B332, lines 11 and 12 from the bottom (4/8/89)
+
+\ninepoint
+\noindent\hskip10pt
+{\bf begin if\/} $\\{cur\_align}=\\{null}$ {\bf then}
+ \\{confusion}({\tt\char'23endv\char'23});\par\noindent\hskip10pt
+$q\gets\\{link}(\\{cur\_align})$; \ {\bf if\/} $q=\\{null}$ {\bf then}
+ \\{confusion}({\tt\char'23endv\char'23});
+
+\bugonpage B466, line 5 becomes three lines (6/7/89)
+
+\ninepoint
+\noindent
+$\\{mmode}+\\{halign}$: {\bf if\/} \\{privileged} {\bf then}\par\noindent
+\hskip20pt{\bf if\/} $\\{cur\_group}=\\{math\_shift\_group}$
+ {\bf then} \\{init\_align}\par\noindent\hskip20pt
+{\bf else} \\{off\_save};
+
+\bugonpage B518, line 25 (8/31/89)
+
+\ninepoint\noindent\hskip10pt
+$\\{undump}(\\{lo\_mem\_stat\_max}+1)(\\{lo\_mem\_max})(\\{rover})$; \
+$p\gets\\{mem\_bot}$; \ $q\gets\\{rover}$;
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\buginvol C, in general (9/23/89)
+
+\ninepoint\noindent
+[Change `127' to `255' and `128' to `256' in contexts referring to character
+codes. This happens on pages 188(thrice) and 251.]
+
+\bugonpage C91, lines 12 and 13 (8/31/89)
+
+\begintt
+\mode=cheapo; input newface
+\endtt
+and the same file should also produce a high-resolution font if we start with
+
+\bugonpage C204, line 4 (8/18/89)
+
+\ninepoint\noindent
+so that
+\\{currenttransform} multiplies all $y$~coordinates by
+\\{aspect\_ratio}, when paths are\cutpar
+
+\bugonpage C212, lines 24--27 (9/30/89)
+
+\ninepoint
+\begindisplay
+{\it boundarychar}\quad&the right boundary character for ligatures and kerns\cr
+\enddisplay
+All of these quantities are numeric. They are initially zero at the
+start of a job, except for {\it year\/}, {\it month\/},
+ {\it day\/}, and {\it time\/}, which
+are initialized to the time the run began; furthermore, {\it boundarychar\/} is
+initially~$-1$. A {\it granularity\/} of zero is equivalent to
+ $\hbox{\it granularity\/}=1$.
+A preloaded base file like plain \MF\ will usually give nonzero values to
+several other internal quantities on this list.
+
+\bugonpage C259, lines 16 and 17 from the bottom (5/14/89)
+
+\tenpoint
+\noindent
+|screenchars|; \ |screenstrokes|; \ |imagerules|; \ |gfcorners|; \
+|nodisplays|;\hfil\break
+|notransforms|; \ |input| \<filename>.
+
+\bugonpage C282, the three lines following the chart (9/30/89)
+
+\tenpoint\noindent
+\MF\ can also be configured to accept any or all of the character codes
+128--255.
+However, \MF\ programs that make use of anything in addition to the 95
+standard ASCII characters cannot be expected to run on other systems, so
+the use of extended character sets is discouraged.
+
+\bugonpage C316, bottom 14 lines and top 30 of page C317 (9/30/89)
+
+\ninepoint
+Ligature information and kerning information is specified in short
+``^{ligtable programs}'' of a particularly simple form. Here's an example
+that illustrates most of the features (although it is not a serious
+example of typographic practice):
+\beginlines
+^|ligtable|| "f": "f" =: oct"013", "i" |\||=: oct"020", skipto 1;|
+|ligtable "o": "b": "p": "e" kern .5u#, "o" kern .5u#, "x" kern-.5u#,|
+| 1:: "!" kern u#;|
+\endlines
+This sequence of instructions can be paraphrased as follows:
+\smallskip
+\hangindent 3pc
+Dear \TeX, when you're typesetting an~`f' with this font, and when the
+following character also belongs to this font, look at it closely because
+you might need to do something special: If that following character is
+another~`f', replace the two f's by character code |oct"013"|
+[namely `\char'13'\kern.5pt];
+if it's an `i', retain the `f' but replace the `i' by character code
+|oct"020"| [a dotless `\char'20'\kern.5pt];
+otherwise skip down to label `|1::|' for further instructions.
+When you're typesetting an `o' or~`b' or~`p', if the next input to \TeX\ is
+`e' or~`o', add a half unit
+of space between the letters; if it's an `x', subtract a half unit; if it's an
+exclamation point, add a full unit. The last instruction applies also
+to exclamation points following~`f' (because of the label `|1::|').
+\smallskip\noindent
+When a character code appears in front of a colon, the colon ``labels''
+the starting place for that character's ligature and kerning program,
+which continues to the end of the ligtable statement. A double colon denotes
+a ``local label''; a |skipto| instruction advances to the next matching local
+label, which must appear before 128 ligtable steps intervene. The special
+label \|\||:| can be used to initiate ligtable instructions for an invisible
+``left boundary character'' that is implicitly present just before every
+word; an invisible ``right boundary character'' equal to {\it boundarychar\/} is
+also implicitly present just after every word, if {\it boundarychar\/}
+ lies between
+0 and~255.
+
+The general syntax for ligtable programs is pretty easy to guess from
+these examples, but we ought to exhibit it for completeness:
+\beginsyntax \chardef\\=`\|
+<ligtable command>\is[ligtable]<ligtable program><optional skip>
+<ligtable program>\is<ligtable step>\alt<ligtable program>[,]<ligtable step>
+<optional skip>\is[,] [skipto]<code>\alt<empty>
+<ligtable step>\is<code><ligature op><code>
+ \alt<code>[kern]<numeric expression>
+ \alt<label><ligtable step>
+<ligature op>\is[=:]\alt[\\=:]\alt[\\=:>]\alt[=:\\]\alt[=:\\>]%
+ \alt[\\=:\\]\alt[\\=:\\>]\alt[\\=:\\>>]
+<label>\is<code>[:]\alt<code>[::]\alt[\\\\:]
+<code>\is<numeric expression>\alt<string expression>
+\endsyntax
+A \<code> should have a numeric value between 0 and 255, inclusive,
+after having been rounded to the nearest integer; or it should be a
+string of length~1, in which case it denotes the corresponding
+^{ASCII} code (Appendix~C\null). For example, |"A"| and |64.61| both
+specify the code value 65. Vertical bars to the left or right of `|=:|'
+tell \TeX\ to retain the original left and/or right character that invoked a
+ligature. Additional `|>|' signs tell \TeX\ to advance its focus of attention
+instead of doing any further ligtable operations at the current
+character position.
+
+\bugonpage C338, lines 21 and 22 (9/30/89)
+
+\ninepoint\noindent
+and 127--255 have to be specified with the `|#|' option,
+on non-fancy installations of \TeX,
+and so does code 35 (which is the ASCII code of `|#|' itself).
+
+\bugonpage C346, left column, after line 14 (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|, {\it316}, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|=:|\|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|=:|\||>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\||>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\||>>|, $\underline{317}$.\par
+
+\bugonpage C346, left column, after line 31 (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|::| (local label), $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\|\||:| (left boundary label), $\underline{317}$.\par
+
+\bugonpage C347, left column (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|boundarychar|, 212, 317.
+
+\bugonpage C352, left column (9/30/89)
+
+\eightpoint[Change `\<ligature replacement>' to `\<ligature op>'.]
+
+\bugonpage C354, left column (9/30/89)
+
+\eightpoint
+\<optional skip>, 217.
+
+\bugonpage C356, left column (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|skipto|, {\it316}, $\underline{317}$.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Dvi, bottom two lines, and top lines of page vii (4/21/89)
+
+{\hsize=29pc \tenpoint
+\textindent\bull ``\MF\/ware'' by Donald~E. Knuth, Tomas~G. Rokicki, and
+Ar\-thur~L. Samuel, Stanford Computer Science Report 1255 (Stanford,
+California, April 1989), 207~pp. \ {\it The {\sltt WEB} programs for
+four utility programs that are often used in conjunction with
+\slMF\kern1pt: {\sltt GFtype}, {\sltt GFtoPK}, {\sltt GFtoDVI},
+and {\sltt MFT}.}
+\par}
+
+\bugonpage D63, line 9 (8/31/89)
+
+\tenpoint\noindent
+\\{mem}, so we
+allow pointers to assume any \\{halfword} value. The minimum memory
+index represents\cutpar
+
+\bugonpage D63, line 28 (8/31/89)
+
+\tenpoint\centerline{$\\{null}=\\{mem\_min}<\\{lo\_mem\_max}<
+\\{hi\_mem\_min}<\\{mem\_top}\le\\{mem\_end}\le\\{mem\_max}$.}
+
+\bugonpage D67, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete line 7, which has a redundant `{\bf if\/} $r=p$ {\bf then}';
+ move line 8 to the left 10 points for alignment; and restore the following
+ line (which was deleted by mistake after line 8):
+
+ \noindent\hskip10pt
+ $\\{node\_size}(p)\gets q-p$\quad$\{\,$reset the size in case it grew$\,\}$
+
+ \noindent
+ These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D228, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete lines 14--15, which were inserted erroneously from a previous errata
+list; and restore the following lines (which were deleted by mistake):
+
+\noindent\hskip20pt
+{\bf begin} \\{double}(\\{max\_coef}); \
+\\{double}(\\{x0}); \
+\\{double}(\\{x1}); \
+\\{double}(\\{x2});\par\noindent\hskip20pt
+\\{double}(\\{y0}); \
+\\{double}(\\{y1}); \
+\\{double}(\\{y2});\par\noindent\hskip20pt
+{\bf end}
+
+\noindent
+These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D248, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete line 16, which begins with `$d\gets\\{take\_fraction}$';
+and restore the following line (which was deleted by mistake after line 22):
+
+\noindent\hskip10pt
+{\bf if\/} $d<\\{alpha}$ {\bf then} $d\gets\\{alpha}$
+
+\noindent
+These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D389, line 10 (6/20/89)
+
+\ninepoint\noindent\hskip20pt
+\\{help1}({\tt\char'23
+The\]expression\]above\]should\]have\]been\]a\]number\]>=3/4.\char'23});
+
+\bugonpage D504, line 25 (8/31/89)
+
+\ninepoint\noindent\hskip10pt
+$\\{undump}(\\{lo\_mem\_stat\_max}+1)(\\{lo\_mem\_max})(\\{rover})$; \
+$p\gets\\{mem\_min}$; \ $q\gets\\{rover}$;
+
+\bugonpage D510, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Move the 7th-to-last line, which begins with `\\{internal}[\\{fontmaking}]',
+one line down, and indent it to the right by 10 more points.
+This correction is needed only in the reprinting made July, 1987.]
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, bottom four lines (5/5/89)
+
+{\hsize=29pc \tenpoint
+\textindent\bull ``Metamarks: Preliminary studies for a Pandora's Box of
+shapes'' by Neenie Billawala,
+Stanford Computer Science Report 1256 (Stanford,
+California, May 1989), 132~pp. \ {\it Lavishly illustrated studies in
+parameter variation, leading to the design of a new family of
+typefaces called Pandora.}
+\par}
+
+\bugonpage E401, bottom line (5/16/89)
+
+\ninepoint\noindent
+{\bf \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+math\_fit}$(-.3\\{cap\_height}\0*\\{slant}-.5u\0,\\{ic}\0)$;\par\noindent
+{\bf penlabels}$(1,2,3,4,5,6,7,8)$; {\bf endchar\/};
+\smallskip\noindent
+[some points and labels are missing at the tip of the tail on page 400]
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.four b/Master/texmf-doc/doc/english/knuth/errata/errata.four
new file mode 100644
index 00000000000..11d0435e749
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.four
@@ -0,0 +1,1052 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1987--1988}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A--E\null, between
+16 June 1987 and 20 February 1989. Corrections made to
+the softcover version of {\sl The \TeX book} are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+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.
+ % volume A
+
+\bugonpage A159, line 22 (2/15/88)
+
+\ninepoint\noindent
+`|\nolimits|' if the normal |\displaylimits|
+convention has been overridden; a Rad\cutpar
+
+\bugonpage A213, lines 34--35 (12/23/87)
+
+\ninepoint\noindent
+text will be a single control sequence token, defined to be like |\relax| if
+its meaning is currently undefined.
+
+\bugonpage A299, line 30 (7/6/88)
+
+\ninepoint\indent\tt
+Fatal format file error; I'm stymied.
+
+\bugonpage A326, line 12 (12/12/87)
+
+\ninepoint\noindent
+its natural width. The |\hbox| version also invokes |\everymath|.
+
+\bugonpage A359, line 2 (11/6/88)
+
+\ninepoint\noindent
+|\mathchardef\ldotp="613A\mathchardef\cdotp="6201\mathchardef\colon="603A|
+
+\bugonpage A359, lines 35--38 (5/24/88)
+
+\ninepoint\noindent
+|\def\updownarrow{\delimiter"326C33F } \def\arrowvert{\delimiter"033C000 }|%
+ \par\noindent
+|\def\Updownarrow{\delimiter"326D377 } \def\Arrowvert{\delimiter"033D000 } |%
+ \par\noindent
+|\def\vert{\delimiter"026A30C } \def\Vert{\delimiter"026B30D } |%
+ \par\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"033E000 }|
+
+\bugonpage A364, line 35 (11/6/88)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.94} % identifies the current format|
+
+\bugonpage A379, line 15 (10/12/87)
+
+\ninepoint
+|\def\deleterightmost#1{\edef#1{\expandafter\xyzzy#1\xyzzy}}|
+
+\bugonpage A383, lines 7--15 from the bottom (1/4/89)
+
+\begintt
+ 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
+\endtt
+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.
+
+\bugonpage A454, lines 23--29 (8/13/87)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger If a suitable starting letter is found, let it be in font~$f$.
+Hyphenation is abandoned 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$.
+
+\endgroup % end the special hyphenation conventions
+
+\bugonpage A458, left column, line 19 (2/15/88)
+
+\eightpoint\indent
+|\|\| ( $\Vert$ ), {\it146--147}, {\it171}, $\underline{361}$, 435, 438.
+
+\bugonpage A462, left column, line 7 (10/9/87)
+
+\eightpoint\indent\qquad 152, 178, $\underline{360}$.
+
+\bugonpage A463, left column (4/17/88)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\day|, 273, 349, {\it406}.
+
+\bugonpage A464, left column, under Displays (12/8/88)
+
+\eightpoint\indent\quad
+non-centered, 186, 326, 375--376, 420--421.
+
+\bugonpage A465, entry for {\tt\char`\\everymath} (12/12/87)
+
+\eightpoint\indent[Include also a reference to page 326.]
+
+\bugonpage A465, right column (7/6/88)
+
+\eightpoint\indent{\tt Fatal format file error}, 299.
+
+\bugonpage A473, entry for `page builder' (8/13/87)
+
+\eightpoint\indent\quad when exercised, 122, 280--283, 286--287.
+
+\bugonpage A474, left column (12/27/88)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\parshape|, 101--102, 214, 271, 277, 283,
+
+\bugonpage A480, right column (2/15/88)
+
+\eightpoint\indent|\vdots| ( $\vdots$ ), {\it177}, $\underline{359}$.
+
+\bugonpage A481, right column (7/3/87)
+
+\eightpoint|\z@|, $\underline{347}$, 348.\par
+|\z@skip|, $\underline{347}$, 348.
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 32 (2/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.97\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B38, lines 7--9 from the bottom (11/6/88)
+
+\tenpoint\noindent[Delete this paragraph; it is being moved to page B214.]
+
+\bugonpage B38, line 5 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{term\_and\_log}$
+
+\bugonpage B39, line 5 (12/14/88)
+
+\ninepoint\noindent\kern50pt
+{\bf if\/} \\{log\_opened} {\bf then} \\{error};
+
+\bugonpage B52, line 5 (8/13/87)
+
+\tenpoint\noindent
+cannot be done, i.e., if $\\{hi\_mem\_min}=\\{lo\_mem\_max}+1$,
+we have to quit.
+
+\bugonpage B54, lines 34--35 (7/9/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} $\\{hi\_mem\_min}-\\{lo\_mem\_max}\ge1998$
+ {\bf then} $t\gets\\{lo\_mem\_max}+1000$\par\noindent\kern10pt
+{\bf else} $t\gets\\{lo\_mem\_max}+1+(\\{hi\_mem\_min}-\\{lo\_mem\_max})
+\,\mathbin{\bf div}\,2$;\quad\kern-4pt
+$\{\,\\{lo\_mem\_max}+2\le t<\\{hi\_mem\_min}\,\}$
+
+\bugonpage B108, new line after line 8 (5/24/88)
+
+\ninepoint\noindent\kern20pt
+$d$: \\{integer};\quad
+$\{\,$number of characters in incomplete current string$\,\}$
+
+\bugonpage B108, lines 31--33 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{str\_room}(l)$; $d\gets\\{cur\_length}$;\par\noindent\kern10pt
+{\bf while} $\\{pool\_ptr}>\\{str\_start}[\\{str\_ptr}]$ {\bf do}
+ \par\noindent\kern20pt
+{\bf begin} \\{decr}(\\{pool\_ptr});
+ $\\{str\_pool}[\\{pool\_ptr}+l]\gets\\{str\_pool}[\\{pool\_ptr}]$;
+ \par\noindent\kern20pt
+{\bf end};\quad$\{\,$move current string up to make room for another$\,\}$
+\par\noindent\kern10pt
+{\bf for} $k\gets j$ {\bf to} $j+l-1$ {\bf do} $\\{append\_char}(\\{buffer}[k])$;
+\par\noindent\kern10pt
+$\\{text}(p)\gets\\{make\_string}$; $\\{pool\_ptr}\gets\\{pool\_ptr}+d$;
+
+\bugonpage B115, line 12 (4/28/88)
+
+\ninepoint\noindent\hskip10pt
+$\\{group\_code}=0\to\\{max\_group\_code}$;\quad
+ $\{\,$\\{save\_level} for a level boundary$\,\}$
+
+\bugonpage B141, line 19 (4/28/88)
+
+\ninepoint\noindent
+\\{par\_token}: \\{halfword};\quad
+ $\{\,$token representing `|\par|'$\,\}$
+
+\bugonpage B150, line 24 (4/28/88)
+
+\tenpoint\noindent{\bf 358.\quad}%
+The present point in the program is reached only when the \\{expand}
+routine has inserted\cutpar
+
+\bugonpage B151, mini-index (4/28/88)
+
+\eightpoint\noindent
+Delete the entry for `\\{no\_expand}'; replace it by:
+
+\indent\\{expand}: {\bf procedure}, \S366.
+
+\bugonpage B154, lines 25, 29, 34 respectively (9/20/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cvl\_backup},\\{radix\_backup},\\{co\_backup}$: \\{small\_number};\quad
+ $\{\,$to save \\{cur\_val\_level}, etc.$\,\}$\par\noindent\hskip10pt
+$\\{co\_backup}\gets\\{cur\_order}$;
+ $\\{backup\_backup}\gets\\{link}(\\{backup\_head})$;\par\noindent\hskip10pt
+$\\{cur\_order}\gets\\{co\_backup}$;
+ $\\{link}(\\{backup\_head})\gets\\{backup\_backup}$;
+
+\bugonpage B155, new entry for mini-index (9/20/87)
+
+\eightpoint\indent
+\\{cur\_order}: \\{glue\_ord}, \S447.
+
+\bugonpage B156, line 28 (12/23/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{eq\_define}(\\{cur\_cs},\\{relax},256)$;
+
+\bugonpage B157, mini-index (12/23/87)
+
+\eightpoint\noindent
+Delete the entries for `\\{eqtb}' and `\\{frozen\_relax}'; replace them
+by the following:
+
+\indent\\{eq\_define}: {\bf procedure}, \S227.\par
+$\\{relax}=0$, \S207.\par
+
+\bugonpage B162, lines 12--14 (4/30/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf repeat} $\\{link}(\\{temp\_head})\gets\\{null}$;\par\noindent\hskip20pt
+{\bf if\/} $(\\{info}(r)>\\{match\_token}+127)\lor
+ (\\{info}(r)<\\{match\_token})$ {\bf then}
+ $s\gets\\{null}$\par\noindent\hskip20pt
+{\bf else begin} $\\{match\_chr}\gets\\{info}(r)-\\{match\_token}$; \
+ $s\gets\\{link}(r)$; \ $r\gets s$; \ $p\gets\\{temp\_head}$; \
+ $m\gets 0$;
+
+\bugonpage B177, bottom line before mini-index (7/13/88)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_val}\gets0$; \
+ $\\{cur\_val\_level}\gets\\{int\_val}$; \
+ $\\{radix}\gets0$; \
+ $\\{cur\_order}\gets0$;
+
+\bugonpage B181, line 31 (4/28/88)
+
+\ninepoint\noindent
+[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.]
+
+\bugonpage B188, line 8 (5/25/88)
+
+\ninepoint\noindent
+{\bf function} $\\{str\_toks}(b:\\{pool\_pointer})$: \\{pointer};\quad
+ $\{\,$changes the string \\{str\_pool}$[b\to\\{pool\_ptr}]$ to a token list$\,\}$
+
+\bugonpage B188, line 13 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin} \\{str\_room}(1); $p\gets\\{temp\_head}$;
+ $\\{link}(p)\gets\\{null}$; $k\gets b$;
+
+\bugonpage B188, line 20 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+$\\{pool\_ptr}\gets b$; $\\{str\_toks}\gets p$;
+
+\bugonpage B188, new line after line 28 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$b$: \\{pool\_pointer};\quad$\{\,$base of temporary string$\,\}$
+
+\bugonpage B188, line 31 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf else begin} $\\{old\_setting}\gets\\{selector}$;
+ $\\{selector}\gets\\{new\_string}$; $b\gets\\{pool\_ptr}$;
+
+\bugonpage B188, line 41 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$\\{selector}\gets\\{old\_setting}$; $\\{the\_toks}\gets\\{str\_toks}(b)$;
+
+\bugonpage B190, lines 16--18 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$b$: \\{pool\_pointer};\quad$\{\,$base of temporary string$\,\}$\par
+\noindent\kern10pt
+{\bf begin} $c\gets\\{cur\_chr}$;
+ $\langle\,$Scan the argument for command $c${\eightrm\kern.5em471}$\,\rangle$;
+\par\noindent\kern10pt
+$\\{old\_setting}\gets\\{selector}$;
+$\\{selector}\gets\\{new\_string}$; $b\gets\\{pool\_ptr}$;
+$\langle\,$Print the result of command~$c${\eightrm\kern.5em472}$\,\rangle$;
+\par\noindent\kern10pt
+$\\{selector}\gets\\{old\_setting}$;
+$\\{link}(\\{garbage})\gets\\{str\_toks}(b)$;
+$\\{ins\_list}(\\{link}(\\{temp\_head}))$;
+
+\bugonpage B210, line 36 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if} $(\\{pool\_ptr}+\\{name\_length}>\\{pool\_size})
+ \lor(\\{str\_ptr}=\\{max\_strings})\lor(\\{cur\_length}>0)$ {\bf then}
+
+\bugonpage B211, new line of code before the mini-index (12/14/88)
+
+\ninepoint\noindent
+\\{log\_opened}: \\{boolean};\quad$\{\,$has the transcript file been opened?$\,\}$
+
+\bugonpage B212, line 5 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{job\_name}\gets0$; \ $\\{name\_in\_progress}\gets\\{false}$; \
+$\\{log\_opened}\gets\\{false}$;
+
+\bugonpage B213, line 24 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{log\_name}\gets\\{a\_make\_name\_string}(\\{log\_file})$; \
+$\\{selector}\gets\\{log\_only}$; \
+$\\{log\_opened}\gets\\{true}$;
+
+\bugonpage B214, lines 2 and 3 (12/14/88)
+
+\tenpoint\noindent
+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.
+\par\noindent\hskip10pt
+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.
+
+\bugonpage B214, lines 7--11 reduce to a single line (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $\\{selector}\gets\\{term\_only}$;
+
+\bugonpage B224, second-last line (4/28/87)
+
+\ninepoint\noindent
+\\{done}: {\bf if} \\{file\_opened} {\bf then} \\{b\_close}(\\{tfm\_file});\par
+\noindent\hskip10pt $\\{read\_font\_info}\gets g$;
+
+\bugonpage B229, lines 6--8 (11/17/87)
+
+\tenpoint\noindent
+than $2^{27}$.
+If $z<2^{23}$, the individual multiplications $b\cdot z$,
+$c\cdot z$, $d\cdot 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^\prime=z/2^e$, let $\beta=2^{4-e}$; we shall compute
+
+\bugonpage B229, lines 11--12 (11/17/87)
+
+\tenpoint\noindent
+if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$.
+This calculation must be done exactly, in order to guarantee portability
+of \TeX\ between computers.
+
+\bugonpage B230, lines 2--5 (11/17/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf begin} $\\{alpha}\gets16$;\par
+\noindent\hskip10pt{\bf while} $z\ge\oct{40000000}$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $z\gets z\ {\bf div}\ 2$; \
+ $\\{alpha}\gets\\{alpha}+\\{alpha}$; \ {\bf end};\par
+\noindent\hskip10pt$\\{beta}\gets256\ {\bf div}\ \\{alpha}$; \
+ $\\{alpha}\gets\\{alpha}\ast z$;\par
+
+\bugonpage B245, new entry for mini-index (8/7/87)
+
+\eightpoint\indent
+\\{cur\_s}: \\{integer}, \S616.
+
+\bugonpage B254, line 29 (8/7/87)
+
+\ninepoint\noindent
+\\{cur\_s}: \\{integer};\quad
+$\{\,$current depth of output box nesting, initially $-1\,\}$
+
+\bugonpage B254, line 31 (8/7/87)
+
+\ninepoint\noindent
+[Remove the statement `$\\{cur\_s}\gets-1$;' and put it on page B244 at the
+end of line 31.]
+
+\bugonpage B259, line 13 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{rule\_wd}\gets\\{rule\_wd}+10$;\quad
+$\{\,$compensate for floating-point rounding$\,\}$\par\noindent\hskip20pt
+$\\{edge}\gets\\{cur\_h}+\\{rule\_wd}$; $\\{lx}\gets0$;
+$\langle\,$Let \\{cur\_h} be the position of the first box, and set
+
+\bugonpage B259, line 17 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cur\_h}\gets\\{edge}-10$; {\bf goto} \\{next\_p};
+
+\bugonpage B263, line 21 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{rule\_ht}\gets\\{rule\_ht}+10$;\quad
+$\{\,$compensate for floating-point rounding$\,\}$\par\noindent\hskip20pt
+$\\{edge}\gets\\{cur\_v}+\\{rule\_ht}$; $\\{lx}\gets0$;
+$\langle\,$Let \\{cur\_v} be the position of the first box, and set
+
+\bugonpage B263, line 25 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cur\_v}\gets\\{edge}-10$; {\bf goto} \\{next\_p};
+
+\bugonpage B266, line 8 (8/7/87)
+
+\ninepoint\noindent\hskip10pt
+\\{dvi\_out}(\\{eop}); \\{incr}(\\{total\_pages}); $\\{cur\_s}\gets-1$;
+
+\bugonpage B266, new code between lines 31 and 32 (8/7/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf while} $\\{cur\_s}>-1$ {\bf do}\par
+\noindent\hskip20pt{\bf begin if} $\\{cur\_s}>0$ {\bf then}
+ \\{dvi\_out}(\\{pop})\par
+\noindent\hskip20pt{\bf else begin} \\{dvi\_out}(\\{eop});
+ \\{incr}(\\{total\_pages})\par
+\noindent\hskip30pt{\bf end};\par
+\noindent\hskip20pt\\{decr}(\\{cur\_s});\par
+\noindent\hskip20pt{\bf end};\par
+
+\bugonpage B285, line 21 (4/28/88)
+
+\noindent\tenpoint
+is subsidiary to the \\{nucleus} field of some noad; the dot is replaced by
+`|_|' or `|^|' or `|/|' or `|\|' if $p$ is\cutpar
+
+\bugonpage B338, second-last line (8/19/87)
+
+\ninepoint\noindent\kern10pt
+$q\gets\\{link}(\\{head})$; $s\gets\\{head}$;
+
+\bugonpage B339, line 4 (8/19/87)
+
+\ninepoint\noindent\kern20pt
+$s\gets q$; $q\gets\\{link}(q)$;
+
+\bugonpage B339, new code to insert after line 10 (8/19/87)
+
+\ninepoint
+\noindent\kern10pt{\bf if} $o\ne0$ {\bf then}\par
+\noindent\kern20pt{\bf begin} $r\gets\\{link}(q)$; $\\{link}(q)\gets\\{null}$;
+ $q\gets\\{hpack}(q,\\{natural})$;\par
+\noindent\kern20pt$\\{shift\_amount}(q)\gets o$; $\\{link}(q)\gets r$;
+ $\\{link}(s)\gets q$;\par
+\noindent\kern20pt{\bf end};\par
+\noindent[These new lines also imply changes to the index that aren't
+ shown in this errata list.]
+
+\bugonpage B387, line 2 (5/24/88)
+
+\tenpoint\noindent
+is quite short. In the following code we set \\{hc}$[\\{hn}+2]$ to the
+impossible value 128, in order to\cutpar
+
+\bugonpage B387, line 8 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{hc}[0]\gets127$; $\\{hc}[\\{hn}+1]\gets127$;
+ $\\{hc}[\\{hn}+2]\gets128$;\quad$\{\,$insert delimiters$\,\}$
+
+\bugonpage B390, lines 17--18 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\langle\,$Enter as many hyphenation exceptions as are listed, until coming
+ to a right brace; then {\bf return\eightrm\kern.5em961}$\,\rangle$;
+
+\smallskip[The same change applies to lines 20--21, and
+to page~582.]
+
+\bugonpage B396, new line after line 34 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{trie\_link}(\\{trie\_size})\gets0$;
+$\\{trie\_back}(0)\gets\\{trie\_size}$;\quad
+$\{\,$wrap around$\,\}$
+
+\bugonpage B396, bottom line (12/12/87)
+
+\ninepoint\noindent\hskip10pt
+$\\{trie\_link}(0)\gets0$; $\\{trie\_char}(0)\gets0$;
+ $\\{trie\_op}(0)\gets\\{min\_quarterword}$;
+
+\bugonpage B397, lines 15--17 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin} $c\gets\\{trie\_c}[p]$;\par\noindent\kern10pt
+{\bf if} $c<\\{trie\_min}$ {\bf then} $\\{trie\_min}\gets c$;\par\noindent\kern10pt
+{\bf if} $\\{trie\_min}=0$ {\bf then} $z\gets\\{trie\_link}(\\{trie\_size})$\par
+\noindent\kern10pt
+{\bf else} $z\gets\\{trie\_link}(\\{trie\_min}-1)$;\quad
+$\{\,$get the first conceivably good hole$\,\}$
+
+\bugonpage B400, lines 3--4 (5/24/88)
+
+\ninepoint\noindent
+$\langle\,$Enter all of the patterns into a linked trie, until coming
+ to a right brace{\eightrm\kern.5em961}$\,\rangle\equiv$
+
+\smallskip[The same change applies to page B399, lines 29--30, and
+to page~582.]
+
+\bugonpage B402, line 10 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$r\gets\\{trie\_size}$;\quad
+$\{\,$finally, we will zero out the holes$\,\}$
+
+\bugonpage B406, line 9 from the bottom (1/23/89)
+
+\ninepoint\noindent\kern30pt
+$\\{shrink\_order}(r)\gets\\{normal}$; \ $\\{delete\_glue\_ref}(q)$; \
+$\\{glue\_ptr}(p)\gets r$; \ $q\gets r$;
+
+\bugonpage B417, line 10 (1/23/89)
+
+\ninepoint\noindent\kern10pt
+$q\gets\\{new\_skip\_param}(\\{top\_skip\_code})$; \quad
+$\{\,$now $\\{temp\_ptr}=\\{glue\_ptr}(q)\,\}$
+
+\bugonpage B418, line 14 (1/23/89)
+
+\ninepoint\noindent\kern30pt
+$\\{shrink\_order}(r)\gets\\{normal}$; \ $\\{delete\_glue\_ref}(q)$; \
+$\\{glue\_ptr}(p)\gets r$; \ $q\gets r$;
+
+\bugonpage B507, line 13 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{selector}+2$;
+
+\bugonpage B527, line 21 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage B528, line 5 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage B547, right column (9/20/87)
+
+\eightpoint
+\leftline{\\{co\_backup}:\quad $\underline{366}$.}
+
+\bugonpage B548, right column (9/20/87)
+
+\eightpoint
+\leftline{\\{cur\_order}:\quad 366, $\underline{447}$, 448, 454, 462.}
+
+\bugonpage B548, right column (8/7/87)
+
+\eightpoint
+\leftline{\\{cur\_s}:\quad 593, $\underline{616}$, 619, 629, 640, 642.}
+
+\bugonpage B551, both columns (12/23/87)
+
+\eightpoint[Remove `372' from \\{eqtb} and put it into \\{eq\_define}.]
+
+\bugonpage B552, left column (4/28/88)
+
+\eightpoint[Insert `358' into \\{expand}.]
+
+\bugonpage B554, left column (12/23/87)
+
+\eightpoint[Remove `372' from \\{frozen\_relax}.]
+
+\bugonpage B559, new entry (12/14/88)
+
+\eightpoint\noindent
+\\{log\_opened}, 92--93, $\underline{527}$, 528, 534--535, 1265, 1333--1334.
+
+\bugonpage B559, right column (8/13/87)
+
+\eightpoint[Delete the entry for \\{low\_mem\_max}.]
+
+\bugonpage B562, left column (4/28/88)
+
+\eightpoint[Remove `358' from \\{no\_expand}.]
+
+\bugonpage B565, left column (8/7/87)
+
+\eightpoint
+\leftline{\\{pop}:\quad 584--585, $\underline{586}$, 590, 601, 608, 642.}
+
+\bugonpage B567, left column (12/23/87)
+
+\eightpoint[Insert `372' into \\{relax}.]
+
+\bugonpage B568, left column (4/28/88)
+
+\eightpoint[Move `269' from \\{save\_index} to \\{save\_level}.]
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C26, bottom line (7/18/87)
+
+\tenpoint\noindent
+What angle corresponds to the direction North-Northwest?
+
+\bugonpage C107, line 13 (10/7/87)
+
+{\bf pickup penrazor} xscaled \\{heavyline}
+ rotated (angle$(z_{32}-z_{31})+90$);
+
+\bugonpage C164, line 10 (4/27/88)
+
+\ninepoint\indent
+\quad $y_{\$c}=\\{top}\,y_{\$l}$; \ $y_{\$d}=y_{\$r}$; \
+ $x_{\$c}=x_{\$l}-\\{left\_jut}$; \ $x_{\$d}=x_{\$r}+\\{right\_jut}$;
+
+\bugonpage C175, line 23 (1/11/88)
+
+\ninepoint\noindent
+expand into a sequence of tokens. \
+(The language {\eightrm{SIMULA67}} demonstrated that it is\cutpar
+
+\bugonpage C241, line 11 (5/25/88)
+
+\ninepoint\indent
+{\bf numeric} $\\{ht}\0,\\{dp}\0$; \
+ $\\{ht}\0=\\{body\_height}\0$; \
+ $.5[\\{ht}\0,-\\{dp}\0]=\\{axis}\0$;
+
+\bugonpage C248, line 21 becomes two lines (1/24/89)
+
+\ninepoint\noindent
+which might not
+be numerically stable in the presence of rounding errors.)
+Another case, not really desirable, is $\\{left\_jut}=\\{right\_jut}=0$.
+
+\bugonpage C262, line 15 (12/23/88)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="1.7";|
+
+\bugonpage C271, line 12 (1/4/89)
+
+\ninepoint\noindent
+the user and \MF's primitive picture commands.
+First, some important program\cutpar
+
+\bugonpage C271, line 4 from the bottom (12/23/88)
+
+\ninepoint\noindent
+|def |^|cutdraw|| expr p = % caution: you may need autorounding=0|
+
+\bugonpage C272, lines 5 and 6 (12/23/88)
+
+\ninepoint\noindent
+| (cut_ scaled (1+max(pen_lft,pen_rt,pen_top,pen_bot))|\par\noindent
+| rotated theta shifted z)t_;|
+
+\bugonpage C273, lines 20 and 22 (9/26/88)
+
+\ninepoint\noindent
+| (z_+(0,pen_top))t_=round((z+(0,pen_top))t_); z_ enddef;|\par\noindent
+| (z_+(0,pen_bot))t_=round((z+(0,pen_bot))t_); z_ enddef;|
+
+\bugonpage C290, line 6 from the bottom (12/23/88)
+
+\ninepoint\noindent
+(2)~A throwaway variable,
+`\\{whatever}', nullifies an unwanted equation at the beginning\cutpar
+
+\bugonpage C331, just below the illustration (7/18/87)
+
+\ninepoint\noindent
+Such a pattern is, of course, rather unlikely to occur in a |gf| file,
+but |GFtoDVI| would\cutpar
+
+\bugonpage C337, line 11 (4/28/88)
+
+\ninepoint
+An online ``menu'' of the available test routines will be typed at your
+terminal\cutpar
+
+\bugonpage C346, entry for {\tt autorounding} (12/23/88)
+
+\eightpoint\indent\hskip20pt
+212, {\it262}, {\it264}, 271--272.
+
+\bugonpage C350, left column (7/6/88)
+
+\eightpoint\indent
+|Fatal| |base| |file| |error|, 226.
+
+\bugonpage C356, left column (1/11/88)
+
+\eightpoint
+SIMULA67 language, 175.
+
+\bugonpage C358, right column (2/15/88)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|yoffset|, 212, $\underline{220}$, 315, 324.
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage D2, line 27 (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]1.7\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D36, lines 3--5 (11/6/88)
+
+\tenpoint\noindent[Delete this paragraph; it is being moved to page D349.]
+
+\bugonpage D36, line 7 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{term\_and\_log}$
+
+\bugonpage D36, line 16 (12/14/88)
+
+\ninepoint\noindent\kern50pt
+{\bf if\/} \\{log\_opened} {\bf then} \\{error};
+
+\bugonpage D66, lines 34--35 (7/9/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} $\\{hi\_mem\_min}-\\{lo\_mem\_max}\ge1998$
+ {\bf then} $t\gets\\{lo\_mem\_max}+1000$\par\noindent\kern10pt
+{\bf else} $t\gets\\{lo\_mem\_max}+1+(\\{hi\_mem\_min}-\\{lo\_mem\_max})
+\,\mathbin{\bf div}\,2$;\quad\kern-4pt
+$\{\,\\{lo\_mem\_max}+2\le t<\\{hi\_mem\_min}\,\}$
+
+\bugonpage D347, new line of code after line 5 (12/14/88)
+
+\ninepoint\noindent
+\\{log\_opened}: \\{boolean};\quad$\{\,$has the transcript file been opened?$\,\}$
+
+\bugonpage D347, line 11 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{job\_name}\gets0$; \
+$\\{log\_opened}\gets\\{false}$;
+
+\bugonpage D348, line 4 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{log\_name}\gets\\{a\_make\_name\_string}(\\{log\_file})$; \
+$\\{selector}\gets\\{log\_only}$; \
+$\\{log\_opened}\gets\\{true}$;
+
+\bugonpage D349, lines 6 and 7 (12/14/88)
+
+\tenpoint\noindent
+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.
+\par\noindent\hskip10pt
+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.
+
+\bugonpage D349, lines 11--15 reduce to a single line (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $\\{selector}\gets\\{term\_only}$;
+
+\bugonpage D420, bottom line (5/25/88)
+
+\ninepoint\noindent\kern30pt
+{\bf if\/} \\{txx} {\bf mod} $\\{unity}=0$ {\bf then}
+
+\bugonpage D441, delete line 2 and change line 12 as follows (5/25/88)
+
+\ninepoint\noindent
+\\{done}: {\bf if} $\\{eq\_type}(x)\ne\\{tag\_token}$ {\bf then}
+ $\\{clear\_symbol}(x,\\{false})$;\par\noindent\kern10pt
+{\bf if} $\\{equiv}(x)=\\{null}$ {\bf then} $\\{new\_root}(x)$;
+\par\noindent\kern10pt
+$\\{scan\_declared\_variable}\gets h$;
+
+\bugonpage D444, line 8 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{selector}+2$;
+
+\bugonpage D510, line 14 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage D511, line 11 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage D530, new entry (12/14/88)
+
+\eightpoint\noindent
+\\{log\_opened}, 87--88, $\underline{782}$, 783, 788--789, 1023, 1205, 1208.
+
+\bugonpage D545, left column (10/31/87)
+
+\eightpoint
+\leftline{{\bf zscaled} primitive:\quad $\underline{893}$.}
+\leftline{Zabala Salelles, Ignacio Andres:\quad 812.}
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage E32, second-last line (9/20/87)
+
+\tenpoint\noindent
+after which comes `\\{math\_axis}\0; {\bf generate} |mathsy|' (which we
+won't bother to\cutpar
+
+\bugonpage E111, line 29 (10/16/88)
+
+\ninepoint\noindent
+$\\{lft}\,x_{11}={\rm hround}\,u$; \
+ $x_{1l}-x_{11}=x_{2l}-x_{12}=x_{22}-x_{2r}={\rm hround}\,1.6\\{cap\_jut}$;
+
+\bugonpage E285, bottom line (12/1/87)
+
+\rightline{\eightssi Due to Technical Developments\/\enspace\eightss(1968)}
+
+\bugonpage E333, lines 9--11 (1/9/89)
+
+\ninepoint\noindent
+$\\{lft}\,x_{1l}={\rm hround}(2.5u-.5\\{mfudged.stem})$; \
+ $x_{1l}=x_{1'l}=x_{2l}=x_{2'l}$;\par\noindent
+$\\{lft}\,x_{3l}={\rm hround}(.5w-.5\\{mfudged.stem})$; \
+ $x_5-x_3=x_3-x_1$;\par
+\line{{\bf if\/} not \\{monospace}:
+ $r:={\rm hround}(x_5+x_1)+r-w$; {\bf fi}\hfill
+ \% change width for better fit}
+
+\bugonpage E353, lines 38--39 (8/12/87)
+
+\ninepoint
+\leftline{\kern10pt{\bf else}: {\bf fill} \\{diag\_end}$(6r,5r,1,1,5l,6l)
+ \dashto.9[z_{5l},z_{6l}]$}
+\line{\kern30pt$.\,.\,\{z_5-z_6\}\,.1[z_{5r},z_{6r}]\dashto\rm cycle$;\hfil
+ \% middle stem}
+
+\bugonpage E387, line 13 (8/12/87)
+
+\ninepoint
+\line{\kern10pt{\bf pickup} \\{tiny}.\\{nib}; \ \\{bulb}$(3,4,5)$;\hfil\% bulb}
+
+\bugonpage E413, lines 37--38 (8/12/87)
+
+\ninepoint
+\leftline{\kern10pt{\bf else}: {\bf fill} \\{diag\_end}$(6r,5r,1,1,5l,6l)
+ \dashto.9[z_{5l},z_{6l}]$}
+\line{\kern30pt$.\,.\,\{z_5-z_6\}\,.1[z_{5r},z_{6r}]\dashto\rm cycle$;\hfil
+ \% middle stem}
+
+\bugonpage E459, line 24 (8/7/87)
+
+\ninepoint\noindent[Delete the `$=$' sign between `\\{lft}' and `$x_5$'.]
+
+\bugonpage E471, line 5 (12/11/88)
+
+\ninepoint\noindent
+$x_2=\\{good}.x\,.5w$; \ $\\{center\_on}(x_2)$;
+
+\bugonpage E471, insert two lines below the rule at bottom of page (12/11/88)
+
+\ninepoint
+\line{{\bf def\/}
+\\{center\_on}({\bf expr} $x) =\null$
+{\bf if\/} not \\{monospace}:\hfill \% change width for symmetric fit}
+\leftline{\kern10pt
+ $r:=r+2x-w$; \ $w:=2x$; \ {\bf fi} {\bf enddef};}
+
+\bugonpage E477, line 20 (12/11/87)
+
+\ninepoint\noindent
+$x_4=x_8=\\{good}.x\,.5w$; \ $\\{center\_on}(x_4)$; \
+$x_2=w-x_6=\\{good}.x(x_4+a)$;
+
+\bugonpage E483, third line of elementary division operator (12/11/88)
+
+\ninepoint\noindent
+$x_3-.5\\{dot\_size}={\rm hround}(.5w-.5\\{dot\_size})$; \
+$\\{center\_on}(x_3)$;
+
+\bugonpage E485, line 4 (8/7/87)
+
+\ninepoint\noindent[Delete the `$=$' sign between `\\{lft}' and `$x_5$'.]
+
+\bugonpage E487, line 17 (8/4/88)
+
+\ninepoint\line{%
+{\bf fill} \\{fullcircle} scaled$\,(\\{bold}+3.8\\{dw}+\\{eps})\,$%
+ shifted$\,(.5[z_4,z_8])$;\hfill\% dot}
+\smallskip\noindent[Also remove page 487 from the index entry for
+\\{dot\_size}, and add it to the entries for \\{bold} and \\{dw}.]
+
+\bugonpage E515, lines 5 and 12 (12/11/88)
+
+\ninepoint\noindent
+$.5[x_1,x_2]=x_3=\\{good}.x\,.5w$; \
+$\\{center\_on}(x_3)$; \ $\\{lft}\,x_1={\rm hround}(.5w-u*{\rm sqrt}48)$;
+
+\bugonpage E515, line 21 (1/23/89)
+
+\ninepoint\noindent
+{\bf labels}$(5,6)$; \ \\{zero\_width}; \ {\bf endchar\/};
+\smallskip\noindent[Also put labels `{\tt5}' and `{\tt6}' on the
+upper right figure, page E514.]
+
+\bugonpage E521, lines 4 and 14 (12/12/88)
+
+\ninepoint\noindent
+$x_1=x_2=\\{good}.x\,.5w$; \
+$\\{center\_on}(x_1)$; \ $\\{lft}\,x_3={\rm hround}\,u$; \ $x_4=w-x_3$;
+
+\bugonpage E537, line 6 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_2=x_3=x_4$; \
+$x_1-.5\\{stem}={\rm hround}(.5w-.5\\{stem})$; \
+$\\{center\_on}(x_1)$;
+
+\bugonpage E537, line 19 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_2=x_3$; \
+$x_1-.5\\{stem}={\rm hround}(.5w-.5\\{stem})$; \
+$\\{center\_on}(x_1)$;
+
+\bugonpage E539, line 4 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_4=x_{30}=x_{33}=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E539, line 21 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_4=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E541, line 4 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_5=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E541, line 17 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_{10}=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E550, new line after line 23 (8/15/87)
+
+\ninepoint\noindent\kern10pt
+{\bf forsuffixes} $\hbox{\$}=\\{notch\_cut},\\{cap\_notch\_cut}$:
+ {\bf if\/} $\hbox{\$}<3$: $\hbox{\$}:=3$; {\bf fi endfor}
+\smallskip\noindent
+[To make room for this, combine lines 38 and 39 into a single line.]
+
+\bugonpage E550, line 29 (7/9/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+define\_whole\_vertical\_blacker\_pixels}$(\\{vair},\\{bar},\\{slab},
+ \\{cap\_bar},\\{cap\_band})$;
+
+\bugonpage E572, new entry at bottom (12/11/88)
+
+\eightpoint\noindent
+\\{center\_on}, $\underline{471}$, 477, 483, 515, 521, 537--541.
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.nine b/Master/texmf-doc/doc/english/knuth/errata/errata.nine
new file mode 100644
index 00000000000..3715cd813fc
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.nine
@@ -0,0 +1,226 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting A, 1996}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volume~A (also known as {\sl The \TeX book}),
+between 1992 and the publication of the final printed
+version of that book in September 1996.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A31, line 8 (3/6/95)
+
+\tenpoint\noindent
+\TeX\ begins its error messages with `|!|', and it shows what it was
+reading at the\cutpar
+
+\bugonpage A46, line 8 (1/22/95)
+
+\ninepoint\noindent
+out for
+the occasional times when the adjacent characters |aa|, |ae|, and |o/|
+should not be\cutpar
+
+\bugonpage A282, lines 11 and 12 (4/18/96)
+
+\ninepoint\noindent
+unadorned \<box> command, except that the new box
+being appended to the vertical list is also shifted left or right by the
+specified amount.
+
+\bugonpage A285, lines 15--17 from the bottom (4/18/96)
+
+\ninepoint
+\textindent{$\bull$}|\raise|\<dimen>\<box>, |\lower|\<dimen>\<box>.\enskip
+This acts just like an unadorned \<box> command, except that the new box
+being appended to the horizontal list is also shifted up or down by the
+specified amount.
+
+\bugonpage A290, lines 4--6 from the bottom (4/18/96)
+
+\ninepoint
+\textindent{$\bull$}|\raise|\<dimen>\<box>, |\lower|\<dimen>\<box>.\enskip
+This acts just like an unadorned \<box> command, except that the new box
+being put into the nucleus is also shifted up or down by the specified amount.
+
+\bugonpage A331, bottom two lines (6/25/93)
+
+\ninepoint\noindent
+if you know that the
+enclosing box is sufficiently small; and |\leaders\vrule\vfill| works fine in
+vertical mode.
+
+\bugonpage A354, lines 19--22 (3/5/95)
+
+\ninepoint\noindent
+|\def\sett@b{\ifx\next\+\def\nxt{\afterassignment\s@tt@b\let\nxt}%|\par
+\noindent
+| \else\let\nxt=\s@tcols\fi|\par\noindent
+| \let\next=\relax \nxt} % turn off \outerness|\par\noindent
+|\def\s@tt@b{\let\nxt=\relax \us@false\m@ketabbox}|
+
+\bugonpage A356, lines 13--20 from the bottom (3/5/95)
+
+\ninepoint
+{\parindent=0pt
+|\def\oalign#1{\leavevmode\vtop{\baselineskip0pt \lineskip.25ex|\par
+| \ialign{##\crcr#1\crcr}}} \def\o@lign{\lineskiplimit=0pt \oalign}|\par
+|\def\ooalign{\lineskiplimit=-\maxdimen \oalign} % chars over each other|\par
+|\def\sh@ft#1{\dimen0=.00#1ex \multiply\dimen0 by\fontdimen1\font|\par
+| \kern-.0156\dimen0} % compensate for slant in lowered accents|\par
+|\def|^|\d||#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{10}.\hidewidth}}}|\par
+|\def|^|\b||#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{29}%|\par
+| \vbox to.2ex{\hbox{\char'26}\vss}\hidewidth}}}|\par
+}
+
+\bugonpage A357, lines 7--12 (8/1/95)
+
+\ninepoint\noindent
+|\def|^|\rightarrowfill||{$\m@th \smash- \mkern-7mu|\par\noindent
+| \cleaders\hbox{$\mkern-2mu \smash- \mkern-2mu$}\hfill|\par\noindent
+| \mkern-7mu \mathord\rightarrow$}|\par\noindent
+|\def|^|\leftarrowfill|%
+ |{$\m@th \mathord\leftarrow \mkern-7mu|\par\noindent
+| \cleaders\hbox{$\mkern-2mu \smash- \mkern-2mu$}\hfill|\par\noindent
+| \mkern-7mu \smash-$}|
+
+\bugonpage A357, lines 16--20 (6/25/93)
+
+\ninepoint
+{\parindent=0pt
+| \setbox0=\hbox{$\braceld$}%|\par
+| \bracelu\leaders\vrule height\ht0 depth0pt\hfill\bracerd|\par
+| \braceld\leaders\vrule height\ht0 depth0pt\hfill\braceru$}|\par
+|\def|^|\downbracefill||{$\m@th|\par
+| \setbox0=\hbox{$\braceld$}%|\par
+| \braceld\leaders\vrule height\ht0 depth0pt\hfill\braceru|\par
+| \bracelu\leaders\vrule height\ht0 depth0pt\hfill\bracerd$}|\par
+\smallskip[Also delete lines 21 and 22, as the usage is no longer restricted.]
+}
+
+\bugonpage A359, line 25 (3/5/95)
+
+\ninepoint\noindent
+|\def|^|\skew||#1#2#3{{\muskip0=#1mu \mkern.5\muskip0|\par\noindent
+| #2{\mkern-.5\muskip0{#3}\mkern.5\muskip0}\mkern-.5\muskip0}{}}|
+
+\bugonpage A360, line 5 from the bottom (3/5/95)
+
+\ninepoint\noindent
+|\def\@vereq#1#2{\lower.5pt\vbox{\lineskiplimit\maxdimen \lineskip-.5pt|
+
+\bugonpage A361, lines 19 and 20 (3/5/95)
+
+\ninepoint\noindent
+|\def|^|\bmod||{\nonscript\mskip-\medmuskip \mkern5mu|\par\noindent
+| |^|\mathbin||{\rm mod} \penalty900 \mkern5mu \nonscript\mskip-\medmuskip}|
+
+\bugonpage A362, lines 14--18 (3/5/95)
+
+\ninepoint\noindent
+| |^|\everycr||{\noalign{\ifdt@p \global\dt@pfalse|%
+ | \ifdim\prevdepth>-1000pt|\par\noindent
+| \vskip-\lineskiplimit \vskip\normallineskiplimit \fi|\par\noindent
+| \else \penalty|^|\interdisplaylinepenalty|| \fi}}}|\par\noindent
+|\def\@lign{\tabskip=0pt\everycr={}} % restore inside \displ@y|\par\noindent
+|\def|^|\displaylines||#1{\displ@y \tabskip=0pt|
+
+\bugonpage A363, lines 8--9 from the bottom (12/8/89)
+
+{\ninepoint\parindent=0pt
+| \if@mid \dimen@=\ht0 \advance\dimen@ by\dp\z@ |%
+ |\advance\dimen@ by12\p@|\parbreak%
+| \advance\dimen@ by\pagetotal \advance\dimen@ by-\pageshrink|
+\par}
+
+\bugonpage A364, line 5 from the bottom (4/11/96)
+
+\ninepoint\noindent
+|\def\fmtname{plain}|\par\noindent
+|\def\fmtversion{3.141592} % identifies the current format|
+
+\bugonpage A374, line 3 (3/7/95)
+
+\ninepoint\indent
+|\begingroup\aftergroup\def\aftergroup\asts\aftergroup{|
+
+\bugonpage A410, line 23 (4/18/96)
+
+\ninepoint\noindent
+| Tema con variazione \(su un tema differente)|
+\smallskip\eightpoint\noindent
+(This implies a corresponding correction to page 411.)
+
+\bugonpage A451, line $16$ (8/8/93)
+
+\ninepoint\noindent
+But when plain \TeX\ is tried on the name of a famous ^{Welsh} village,
+
+\bugonpage A462, right column (3/5/95)
+
+\def\cong{\mathrel{\mathpalette\OvOreq\sim}} % congruence sign, index version
+\def\OvOreq#1#2{\lower.5pt\vbox{\baselineskip0pt\lineskip-.0pt
+ \ialign{$#1\hfil##\hfil$\crcr#2\crcr=\crcr}}}
+\eightpoint
+|\cong| ( $\cong$ ), 151, $\underline{360}$, 436.
+
+\bugonpage A463, right column (6/25/93)
+
+\eightpoint
+direct sum, {\sl see\/} |\oplus|.
+
+\bugonpage A464, left column (6/25/93)
+
+\eightpoint
+|\downbracefill| (\hbox to 4em{\downbracefill}), 225--226, $\underline{357}$.
+
+\bugonpage A483, lines 15--21 (4/29/97)
+
+\tenpoint
+\begintt
+email: {\tt TUG@tug.org}
+internet: {\tt http://www.tug.org/}
+}
+\endtt
+Don't delay, subscribe today! That address again is
+
+\smallskip
+{\obeylines
+\TeX\ Users Group
+email: {\tt TUG\char`\@ tug.org}
+internet: {\tt http://www.tug.org/}
+}
+
+\bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.one b/Master/texmf-doc/doc/english/knuth/errata/errata.one
new file mode 100644
index 00000000000..471971958c3
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.one
@@ -0,0 +1,751 @@
+% Bugs (sigh) in The TeXbook
+
+\input manmac
+\proofmodefalse
+\raggedbottom
+\output{\onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\rhead{Bugs in {\sl The \TeX book}, first printing}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule\line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule\nobreak\medskip}
+
+\noindent This is a list of all corrections made to {\sl The \TeX book\/}
+between the first and second printings. If your copy says `{\sl\kern-1pt Second
+printing (October 1984)\/}' on the copyright page, you've already got
+all of these things corrected. Otherwise, you're a lucky owner of the
+rare first edition; read on.
+
+\bugonpage 29, lines 31--32 (8/25/84)
+
+The underfull box that \TeX\ produces in the 1.5-inch case is really bad;
+with such narrow limits, an occasional wide space is unavoidable. But try
+
+\bugonpage 54, lines 5--6 (4/20/84)
+
+{\parfillskip=0pt
+\ddanger Appendix B shows that plain \TeX\ handles most of the accents
+by using \TeX's ^|\accent| primitive. For example, |\'#1| is equivalent
+to |{\accent19 #1}|, where\par}
+
+\bugonpage 63, seven lines below the first illustration (2/27/84)
+
+\line{points, a width of 5.5555 points, and a depth of zero;
+the letter `g' has a height}
+
+\bugonpage 72, line 35 (2/28/84)
+
+\ninepoint\noindent
+from |0pt|, but |0.00001filll| is infinitely greater than |16383.99999fill|.
+
+\bugonpage 79, line 12 (2/28/84)
+
+\ninepoint\indent
+|\hbox(6.25+1.94444)x312.0, glue set 0.5783, shifted 36.0 []|
+
+\bugonpage 98, line 24 (4/13/84)
+
+\ninepoint
+\line{and |\finalhyphendemerits=5000|. Demerits are in units of
+ ``badness squared,'' so the}
+
+\bugonpage 101, lines 29--30 (3/13/84)
+
+{\parfillskip=0pt
+\danger It's possible to control the length of lines in a much more general
+way, if simple changes to |\leftskip| and |\rightskip| aren't
+flexible enough for your\par}
+
+\bugonpage 113, bottom two lines (3/13/84)
+
+{\parfillskip=0pt
+\ddanger Notice that the first ``|%| line'' of our example says |t=10.0|;
+this is a consequence of another parameter, called ^|\topskip|. Glue
+disappears at a page break, but\par}
+
+\bugonpage 124, eighth-last line (8/25/84)
+
+\ninepoint
+{\parfillskip=0pt\noindent
+discarded, |\box100| will
+be void after the |\vsplit|. And if\/ |\box100| was void before the\par}
+
+\bugonpage 131, display in exercise 16.8 (3/16/84)
+
+\indent
+|If$ x = y$, then $x$ is equal to $y.$|
+
+\bugonpage 170, table in middle of the page (2/12/84)
+
+\ninepoint
+$$\baselineskip0pt\lineskip0pt
+\halign to\hsize
+ {\strut\hbox to\parindent{\it#\hfil}& % for the legend "Left atom"
+ #\hfil\quad& % for the row labels
+ #\hfil\tabskip 0pt plus 10pt& % for the rule at the left
+ \hbox to 25pt{\tt\hss#\hss}& % for column 1
+ \hbox to 25pt{\tt\hss#\hss}& % for column 2
+ \hbox to 25pt{\tt\hss#\hss}& % for column 3
+ \hbox to 25pt{\tt\hss#\hss}& % for column 4
+ \hbox to 25pt{\tt\hss#\hss}& % for column 5
+ \hbox to 25pt{\tt\hss#\hss}& % for column 6
+ \hbox to 25pt{\tt\hss#\hss}& % for column 7
+ \hbox to 25pt{\tt\hss#\hss}& % for column 8
+ #\hfil\tabskip0pt\cr % for the rule at the right
+\noalign{\vskip-6pt} % it just happens that there's extra white space
+&&&&\multispan7\hss\it Right atom\hss\cr
+\noalign{\vskip3pt}
+&&&\rm Ord&\rm Op&\rm Bin&\rm Rel&\rm Open&\rm Close&\rm Punct&\rm Inner\cr
+\noalign{\vskip2pt}
+\omit&&\multispan{10}\leaders\hrule\hfil\cr
+\omit\vbox to 2pt{}&&\vrule&&&&&&&&&\vrule\cr
+&Ord&\vrule&0&1&(2)&(3)&0&0&0&(1)&\vrule\cr
+&Op&\vrule&1&1&*&(3)&0&0&0&(1)&\vrule\cr
+&Bin&\vrule&(2)&(2)&*&*&(2)&*&*&(2)&\vrule\cr
+Left&Rel&\vrule&(3)&(3)&*&0&(3)&0&0&(3)&\vrule\cr
+atom&Open&\vrule&0&0&*&0&0&0&0&0&\vrule\cr
+&Close&\vrule&0&1&(2)&(3)&0&0&0&(1)&\vrule\cr
+&Punct&\vrule&(1)&(1)&*&(1)&(1)&(1)&(1)&(1)&\vrule\cr
+&Inner&\vrule&(1)&1&(2)&(3)&(1)&0&(1)&(1)&\vrule\cr
+\omit\vbox to 2pt{}&&\vrule&&&&&&&&&\vrule\cr
+\omit&&\multispan{10}\leaders\hrule\hfil\cr}$$
+
+\bugonpage 173, line 11 (1/2/84)
+
+\indent|Clearly $a_i<b_i$ for~$i=1, 2, \ldots, n$.|
+
+\bugonpage 176, bottom two lines (7/20/84)
+
+\def\chapno{ 18} \exno=23 % for exercise 18.24!
+\dangerexercise Typeset the display \ \lower12pt\null
+$\tenpoint\smash{\displaystyle
+\left\lgroup\matrix{a&b&c\cr d&e&f\cr}\right\rgroup
+ \left\lgroup\matrix{u&x\cr v&y\cr w&z\cr}\right\rgroup
+}$, \
+using ^|\lgroup| and ^|\rgroup|.
+
+\bugonpage 189, line 18 (2/13/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+when there is an overlap.] \ If $e=0$ and if there is an |\leqno|,
+the equation number is\par}
+
+\bugonpage 204, line 31 (2/13/84)
+
+\ninepoint\noindent
+of\/ |\a| is delimited by a left brace.
+
+\bugonpage 212, line 23 (7/8/84)
+
+\ninepoint\noindent
+it equals~2.) \
+Similarly, ^|\tracingmacros||=2| will trace |\output|, |\everypar|, etc.
+
+\bugonpage 216, first five lines (8/25/84)
+
+\ddanger Expanded definitions that are made with |\edef| or |\xdef| continue
+to expand tokens until only unexpandable tokens remain, except that
+token lists produced by `^|\the|' are not expanded further. Furthermore
+a token following `^|\noexpand|' will not be expanded, since its ability
+to expand has been nullified. These two operations can be used to control
+^^{expansion, avoiding} what gets expanded and what doesn't.
+
+\bugonpage 219, simplification of line 18 (2/15/84)
+
+\ninepoint\indent
+| \advance\count0 by\count2 \hexdigit}}|
+
+\bugonpage 223, lines 3--4 (3/13/84)
+
+{\parfillskip=0pt
+\ddanger Chapters 24 to 26 present summaries of all \TeX's operations
+in all modes, and when those summaries mention a `\<box>' they mean one
+of the seven\par}
+
+\bugonpage 242, line 29 (1/2/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+a relation, the solution is to insert `|{}|' ^^{lbrace rbrace}
+at the beginning of the right-hand formula; \TeX
+\par}
+
+\bugonpage 245, line 24 (2/15/84)
+
+\ninepoint\noindent
+of a box that spans columns $i$ through~$j$,
+hence the glue in such a box might shrink.
+
+\bugonpage 248, the fourth dangerous bend (2/15/84)
+
+{\parfillskip=0pt
+\ddanger You have to be careful with the use of |&| and ^|\span| and ^|\cr|,
+because these tokens are intercepted by \TeX's scanner even when it is
+not expanding macros.\par}
+
+\bugonpage 249, lines 20--26 (2/15/84)
+
+\ninepoint\noindent
+line (see Chapter~9).
+If you don't want a~|\cr| at the end of a certain line,
+just type `|%|' and the corresponding |\cr|
+will be ``commented out.'' ^^{percent} \ (This special mode doesn't
+work with ^|\+| lines, since |\+| is a macro whose argument is delimited
+by the token `|\cr|', not simply by a token that has the same meaning
+as~|\cr|. ^^{delimited arguments} But you can redefine |\+| to overcome
+this hurdle, if you want to. For example, define a macro |\alternateplus|
+that is just like |\+| except that its argument is delimited by the active
+character |^^M|; then include the command `|\let\+=\alternateplus|' as
+part of\/ |\obeylines|.)
+
+\bugonpage 253, lines 28--32 (4/25/84)
+
+\ninepoint\noindent
+vertical list at what it thinks is the best place, and at such times
+it enters internal vertical mode and begins to read the commands in the
+current |\output| routine. When the output routine begins, ^|\box255|
+contains the page that \TeX\ has completed; the output routine is supposed to
+do something with this vbox. When the output routine ends, the list of
+items that it has constructed in internal vertical mode is placed just%
+{\parfillskip=0pt\par}
+
+\bugonpage 254, lines 1--13 (3/13/84)
+
+\ddanger \TeX's primitive command |\shipout|\<box> is what actually
+causes output. It sends the contents of the box to the |dvi| file,
+which is \TeX's main output file; after \TeX\ has finished,
+the ^|dvi| file will contain a compact device-independent encoding of
+instructions that specify exactly what should be printed. When a
+box is shipped out, \TeX\ displays the values of\/ |\count0| through
+|\count9| on your terminal, ^^|\count0| as explained in Chapter~15; these
+ten counters are also recorded in the |dvi| file, where they can be used
+to identify the page. All of the ^|\openout|, ^|\closeout|, and ^|\write|
+commands that appear inside of the \<box> are performed in their natural
+order as that box is being shipped out. Since a |\write| command
+expands macros, as explained in Chapter~21, \TeX's scanning mechanism
+might detect syntax errors while a |\shipout| is in progress. If
+^|\tracingoutput| is nonzero at the time of a |\shipout|, the contents
+of the \<box> being shipped are written into your log file in symbolic
+form. You can say |\shipout| anywhere, not only in an output routine.
+
+\bugonpage 255, line 33 (4/25/84)
+
+\ninepoint\indent
+|\nointerlineskip|
+
+
+\bugonpage 256, starting with line $-17$ (11/1/83)
+
+\ninepoint
+\textindent{6)} Finally, the ^|\dosupereject| macro is designed to clear
+out any insertions that have been held over, whether they are illustrations
+or footnotes or both: ^^|\insertpenalties| ^^|\supereject|
+\begintt
+\ifnum\insertpenalties>0
+ \line{} \kern-\topskip \nobreak
+ \vfill\supereject\fi
+\endtt
+The mysterious negative ^|\kern| here cancels out the natural space of the
+^|\topskip| glue that goes above the empty |\line|; that empty line box
+prevents the ^|\vfill| from disappearing into a page break. The vertical
+list that results from |\dosupereject| is placed on \TeX's list of things
+to put out next, just after the straggling insertions have been
+reconsidered as explained in Chapter~15. Hence another super-eject will
+occur, and the process will continue until no insertions remain.
+
+\bugonpage 262, line 14 (2/12/84)
+
+\ninepoint\indent
+|\def\endindex{\mark{}\break\endgroup}|
+
+\bugonpage 262, lines 34 and 35 (2/12/84)
+
+\ninepoint\noindent
+if\/ |\next| is `|\endindex|',
+the next commands executed will be `|\vfill|\allowbreak
+|\mark{}|\allowbreak|\break|\allowbreak|\endgroup|';
+otherwise the line will be treated as a main entry.
+
+\bugonpage 269, line 23 becomes two lines (8/25/84)
+
+\ninepoint\noindent
+tokens like |+|$_{12}$;
+(3)~keywords like \[pt]; (4)~control sequence names like |\dimen|;
+or (5)~the special symbols |{|, |}|, |$|.
+
+\bugonpage 274, line 24 (2/15/84)
+
+\ninepoint\indent
+|\lineskip|\quad(interline glue if\/ |\baselineskip| isn't feasible)
+
+\bugonpage 289, slight clarification on lines 39--41 (3/10/84)
+
+\ninepoint
+A \<math character> defines a 15-bit number either by specifying it
+directly with ^|\mathchar| or in a previous ^|\mathchardef|, or by
+specifying a 27-bit |\delimiter| value; in the latter case, the least
+significant 12~bits are discarded.
+
+
+\bugonpage 307, a slightly more explicit answer (11/3/83)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss6.3.\enspace}%
+It represents the heavy bar that shows up in
+your output. \ (This bar wouldn't be present if\/ ^|\overfullrule| had been
+set to |0pt|, nor is it present in an underfull box.)
+
+\bugonpage 313, first four lines (3/13/84)
+
+{\ninepoint\parfillskip=0pt
+\ansno12.17:
+ You get `A' at the extreme left and `puzzle.\null' at the extreme right,
+because the space between words has the only stretchability that is finite;
+the infinite stretchability cancels out. \ (In this case, \TeX's rule
+about ^{infinite glue} differs from what you would get in the limit if the
+value of $1\,{\rm fil}$ were finite but getting larger and larger.
+The true\par}
+
+\bugonpage 315, first three lines (3/13/84)
+
+\ninepoint
+\ansno14.14:
+ Just say |\parfillskip|\stretch|=|\stretch|\parindent|. Of course,
+\TeX\ will not be able to find appropriate line breaks unless each
+paragraph is sufficiently long or sufficiently lucky; but with an
+appropriate text, your output will be immaculately
+symmetrical.{\parfillskip=\parindent\par}
+
+\bugonpage 324, line 16 (2/15/84)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss18.41.\enspace}%
+|$$\{\underbrace{\overbrace{\mathstrut a,\ldots,a}|
+
+\bugonpage 324, first line of answer 18.44 (4/11/84)
+
+\ninepoint
+\ansno18.44:
+ |$$\mathop{{\sum}'}_{x\in A}f(x)\mathrel{\mathop=^{\rm def}}|
+
+\bugonpage 333, beginning of the final paragraph (12/19/83)
+
+\ninepoint
+{\sl Note:\/} The stated preamble solves the problem and demonstrates
+that \TeX's line-breaking capability can be used within tables. But this
+particular table is not really a good example of the use of\/ |\halign|,
+because \TeX\ could typeset it directly, using ^|\everypar| in an
+appropriate manner to set up the hanging indentation, and using |\par|
+instead of\/ |\cr|. For example, one could say
+
+\bugonpage 341, the bottom line was left out! (2/9/84)
+
+\line{Footline\quad\dotfill\quad Page 1009}
+
+\bugonpage 345, top three lines (1/26/84)
+
+\ninepoint{\noindent\parfillskip=0pt
+A mathcode is relevant only when the corresponding category code is
+11 or~12; therefore many of these codes will rarely be looked at. For
+example, the math code for |^^M| specifies the character |\oplus|,
+but it's hard to imagine a user who would want |^^M|\par}
+
+\bugonpage 345, line 31 (2/29/84)
+
+\ninepoint\noindent
+|\delcode`\<="26830A \delcode`\\="26E30F \delcode`\>="26930B|
+
+\bugonpage 347, lines 1 and 2 (3/16/84)
+
+\ninepoint\noindent
+|\count18=3 % this counter allocates math families 4, 5, 6, ...|\hfil\break
+|\count19=255 % this counter allocates insertions 254, 253, 252, ...|
+
+\bugonpage 350, line 9 from the bottom (3/16/84)
+
+\ninepoint\noindent
+font, whose information does not have to be loaded again.
+
+\bugonpage 354, line 5 (6/7/84)
+
+\ninepoint\noindent
+|\def\ialign{\everycr={}\tabskip=0pt \halign} % initialized \halign|
+
+\bugonpage 355, lines 19--21 (7/3/84)
+
+\ninepoint\noindent
+subdivision in a document; to use it, you say
+`|\beginsection|\<section title>' followed by a blank line (or~|\par|).
+The macro first emits glue and penalties, designed to start a new page
+if the present page is nearly full; then it makes a ^|\bigskip| and
+puts the section{\parfillskip=0pt\par}
+
+\bugonpage 355, lines 27--29 (7/3/84)
+
+\ninepoint\noindent
+|\outer\def\beginsection#1\par{\vskip0pt plus.3\vsize\penalty-250|
+\par\noindent
+| \vskip0pt plus-.3\vsize\bigskip\vskip\parskip|
+\par\noindent
+| \message{#1}\leftline{\bf#1}\nobreak\smallskip\noindent}|
+
+\bugonpage 355, line 37 (4/24/84)
+
+\ninepoint\noindent
+|\outer\def\proclaim #1. #2\par{\medbreak|
+
+\bugonpage 356, seven lines from the bottom (4/11/84)
+
+\ninepoint\noindent
+|\def|^|\TeX||{T\kern-.1667em \lower.5ex\hbox{E}\kern-.125em X}|
+
+\bugonpage 359, starting with line 2 (11/16/83)
+
+\ninepoint
+\beginlines
+|\mathchardef\ldotp="602E\mathchardef\cdotp="6201\mathchardef\colon="603A|
+|\def\ldots{\mathinner{\ldotp\ldotp\ldotp}}|
+|\def\cdots{\mathinner{\cdotp\cdotp\cdotp}}|
+|\def\vdots{\vbox{\baselineskip=4pt \lineskiplimit=0pt|
+| \kern6pt \hbox{.}\hbox{.}\hbox{.}}}|
+|\def\ddots{\mathinner{\mskip1mu\raise7pt\vbox{\kern7pt\hbox{.}}\mskip2mu|
+| \raise4pt\hbox{.}\mskip2mu\raise1pt\hbox{.}\mskip1mu}}|
+\endlines
+
+\bugonpage 359, starting with line 19 (11/3/83)
+
+{\ninepoint\parindent=0pt
+|\def|^|\overbrace|%
+ |#1{\mathop{\vbox{\ialign{##\crcr\noalign{\kern3pt}|\parbreak%
+| \downbracefill\crcr\noalign{\kern3pt\nointerlineskip}|\parbreak%
+| $\hfil\displaystyle{#1}\hfil$\crcr}}}|^|\limits||}|
+
+|\def|^|\underbrace||#1{\mathop{\vtop{\ialign{##\crcr|\parbreak%
+| $\hfil\displaystyle{#1}\hfil$\crcr|%
+ |\noalign{\kern3pt\nointerlineskip}|\parbreak%
+| \upbracefill\crcr\noalign{\kern3pt}}}}\limits}|
+}
+
+\bugonpage 359, seventh line from the bottom (2/29/84)
+
+\ninepoint\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"000033E }|
+
+\bugonpage 361, line 3 (8/17/84)
+
+\ninepoint\noindent
+
+|\def\buildrel#1\over#2{\mathrel{\mathop{\null#2}\limits^{#1}}}|
+
+\bugonpage 363, line 10 (4/26/84)
+
+\ninepoint\noindent
+| \ifhmode\edef\@sf{\spacefactor=\the\spacefactor}\/\fi|
+
+\bugonpage 364, starting with line 10 (11/1/83)
+
+{\ninepoint\parindent=0pt
+|\def\dosupereject{\ifnum\insertpenalties>0 % something is being held over|%
+\parbreak
+| \line{}\kern-\topskip\nobreak\vfill\supereject\fi}|
+}
+
+\bugonpage 364, line 28 (7/8/84)
+
+\ninepoint\noindent
+| \tracingmacros=2 \tracingparagraphs=1 \tracingrestores=1 |
+
+\bugonpage 370, line 7 (3/16/84)
+
+\ninepoint\noindent
+information about the \TeX\ Users Group.)
+
+\bugonpage 374, line 23 (7/8/84)
+
+\ninepoint
+\line{log file when |\tracingmacros=2| and
+ |\tracingcommands=2|. One of the important ways}
+
+\bugonpage 379, line 1 (1/12/84)
+
+\ninepoint\noindent
+A particular item can be selected by its position number from the left:
+
+\bugonpage 381, line 6 (2/12/84)
+
+\ninepoint\indent
+|\newcount\lineno % the number of file lines listed|
+
+\bugonpage 381, lines 24 and 25 (12/15/83)
+
+\ninepoint
+{\parfillskip=0pt
+Instead of listing a file verbatim, you might want to define a |\verbatim|
+macro such that `|\verbatim{$this$|{\tt\ is }|{\it!}}|' yields
+`|$this$|{\tt\ is }|{\it!}|'. It's somewhat\par}
+
+\bugonpage 385, lines 22 and 23 (1/12/84)
+
+\ninepoint\noindent
+macro, a parameter, or a token list
+variable; (b)~when \TeX\ must determine whether the token
+|&|~or ^|\span| ^^{ampersand}
+or ^|\cr| or~^|\crcr| is the end of an entry within an ^{alignment}.
+
+\bugonpage 387, two paragraphs in right column (1/18/84)
+
+\setbox0=\vbox{
+\eightpoint
+\tolerance=9999
+\hbadness=2300
+\finalhyphendemerits=3000000
+\doublehyphendemerits=1000000
+\parskip=1pt
+\parindent=1.5em
+\frenchspacing
+\hsize=166.8125pt
+\def\\#1{\raise.5pt\hbox{$\scriptscriptstyle
+ \ifx#1`\langle\!\langle\else\rangle\!\rangle\fi$}% Spanish quote marks
+ \ifx#1`\nobreak\hskip0pt \fi} % allow hyphenation
+\item{A.} Exactamente. Pero los profesores son tan conservadores
+que temer\'\i an espantar al tipo de estudiante \\`apisonadora\\'
+que hace lo que le proponen para casa, obe\-dien\-te\-mente y de forma
+mec\'anica. Adem\'as, no creo que les gustase el trabajo adicional
+de calificar respuestas a preguntas abiertas.
+
+\item{}La forma tradicional es dejar la parte creativa para los cursos
+altos. Durante diecisiete a\~nos o m\'as se ense\~na al es\-tu\-diante a
+aprobar, luego de golpe, cerca de la graduaci\'on, se le pide que haga
+algo original.
+
+}\rightline{\box0}
+
+\bugonpage 395, lines 21 and 22 (1/12/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+Notice that the macros need to do their own checking for ligatures, and
+they also take appropriate actions when a paragraph begins with an opening
+quote. Since |\kern|\par}
+
+\bugonpage 399, line 1 (1/10/84)
+
+\ninepoint
+{\parfillskip=0pt
+Inside the output routine, |\box\footins| will now be a vbox of hboxes, and
+\par}
+
+\bugonpage 399, line 9 (2/28/84)
+
+\ninepoint\indent
+|.\hbox(7.6359+0.0)x269.62617 []|
+
+\bugonpage 407, line 4 (6/10/84)
+
+\ninepoint\noindent
+|\beginlinemode| and |\beginparmode| are defined to initiate these
+modes; and another%
+{\parfillskip=0pt\par}
+
+\bugonpage 408, line 15 (12/14/83)
+
+\noindent
+| P. O. Box 1009, Haga Alto, CA 94321 USA}|
+
+\smallskip\noindent\ninepoint
+[Also change the ZIP code in the return address on the envelope
+illustrated at the bottom of page 405.]
+
+\bugonpage 409, line 5 (2/18/84)
+
+\ninepoint\noindent
+|\font\twelveit=cmti10 at 12pt % (a cheap substitute for cmti12)|
+
+\bugonpage 417, last six lines (8/25/84)
+
+\ninepoint\noindent
+^|\parskip|
+of |0pt| |plus|~|.8pt| between adjacent entries, and since there is room for
+more than 50 lines per column; therefore the |manmac| balancing routine tries
+to make both the top and bottom baselines agree at the end of the index.
+In applications where the glue is not so flexible it would be more
+appropriate to let the right-hand column be a little short; the best
+way to do this is probably to replace the command `|\unvbox3|' by
+`|\dimen2=|^|\dp||3| |\unvbox3| |\kern-\dimen2| ^|\vfil|'.
+
+\bugonpage 422, lines 24--26 (2/9/84)
+
+\ninepoint\noindent
+(The last two lines use |\d@nger| and |\dd@nger|, which are non-|\outer|
+equivalents of\/ |\danger| and |\ddanger|; such duplication is necessary
+because control sequences of type ^|\outer| cannot appear within a |\def|.)
+
+\bugonpage 428, in the table of sixteen basic fonts (12/19/83)
+
+\ninepoint\noindent
+[The special fonts called |cmi10| and |cmi7| and |cmi5| should really be
+called |cmmi10| and |cmmi7| and |cmmi5|.]
+
+\bugonpage 433, last eight lines (8/17/84)
+
+\noindent
+explained in Appendix~G\null. If you want to increase
+the number of parameters past the number that actually appear in a font's
+metric information file, you can assign new values immediately after that font
+has been loaded. For example, if some font |\ff| with seven parameters
+has just entered \TeX's memory, the command |\fontdimen13\ff=5pt| will set
+parameter number~13 to $5\pt$; the intervening parameters, numbers 8--12,
+will be set to zero. You can even give more than seven parameters to
+^|\nullfont|, provided that you assign the values before any actual fonts
+have been loaded.
+
+\bugonpage 445, line 6 (11/11/83)
+
+\ninepoint
+\line{if $(a-{1\over2}\theta)-
+\bigl(h(z)-v\bigr)<\varphi$, increase~$v$ by the difference. Finally
+construct a vbox of}
+
+\bugonpage 449, line 12 (1/18/84)
+
+\line{immediately clear why the `n' should
+be attached to the `e' in one case but not}
+
+\bugonpage 459, left column, line 2 (1/18/84)
+
+\eightpoint
+al-Khw\^arizm\^\i, abu Ja`far Mu\d{h}ammad
+
+\bugonpage 460, index entry for Beethoven (8/16/84)
+
+\eightpoint
+Change `von' to `van'.
+
+\bugonpage 461, third line in left column (8/25/84)
+
+\eightpoint The entry for |\box255| should not be indented.
+
+\bugonpage 461, index entry for boxed material (8/2/84)
+
+\eightpoint Add `{\it 420}'.
+
+\bugonpage 462, index entry for {\tt\char`\\colon} (11/16/83)
+
+\eightpoint Add page \underbar{359} to this list.
+
+\bugonpage 462, right column, third-last line (5/21/84)
+
+\eightpoint\indent
+[Change `crochets' to `crotchets'; then move this entry down two lines.]
+
+\bugonpage 463, right column, line 16 (5/20/84)
+
+\eightpoint\indent
+design size, 16--17, 213.
+
+\bugonpage 464, index entry for {\tt\char`\\dump} (1/10/84)
+
+\eightpoint Add page {\it 344\/} to this list.
+
+\bugonpage 464, right column, line 5 (1/5/84)
+
+\eightpoint
+Dvo\v r\'ak, Anton\'\i n Leopold, 409.
+
+\bugonpage 464, index entry for {\tt\char`\\end} (8/25/84)
+
+\eightpoint Page number 264 should be underlined.
+
+\bugonpage 465, index entry for {\tt\char`\\everydisplay} (8/25/84)
+
+\eightpoint Add page {\it 326\/} to this list.
+
+\bugonpage 465, index entry for {\tt\char`\\filbreak} (7/3/84)
+
+\eightpoint Delete the reference to page number 355.
+
+\bugonpage 466, index entry for {\tt\char`\\footnote} (4/26/84)
+
+\eightpoint Page number 363 should be underlined.
+
+\bugonpage 467, index entry for {\tt\char`\\hidewidth} (7/3/84)
+
+\eightpoint Page number 354 should be underlined.
+
+\bugonpage 468, index entry for insertions (8/25/84)
+
+\eightpoint Add pages 115--117, 122--125 to this list.
+
+\bugonpage 469, index entry for {\tt\char`\\kern} (11/1/83)
+
+\eightpoint Add page {\it 256\/} to this list.
+
+\bugonpage 470, index entry for {\tt\char`\\limits} (11/3/83)
+
+\eightpoint Add page {\it 359\/} to this list.
+
+\bugonpage 472, right column, lines 10--11 (7/9/84)
+
+{\eightpoint
+\indent
+|\normalbaselines|\kern1pt,
+ {\it 325}, 349, $\underline{351}$, {\it 414--415}.\par
+\baselineskip=9.9pt
+\indent
+|\normalbaselineskip|\kern1pt,
+ $\underline{349}$, {\it 414--415}.\par
+}
+
+\bugonpage 472, index entry for {\tt\char`\\null} (7/3/84)
+
+\eightpoint Page number 351 should be underlined.
+
+\bugonpage 472, right column, line 28 (1/3/84)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\nullfont|, 14, 153, 271, 433.
+
+\bugonpage 476, a new index entry (8/25/84)
+
+\eightpoint\indent
+shifted output, {\sl see\/} |\hoffset|, |\voffset|.
+
+\bugonpage 476, index entry for shriek (8/25/84)
+
+\eightpoint It should not be capitalized.
+
+\bugonpage 478, index entry for \'Swierczkowski (9/15/84)
+
+\eightpoint
+The middle name should be `S\l awomir'.
+
+\bugonpage 479, last seven lines in the left column (8/23/84)
+
+\eightpoint
+{\baselineskip=9.9pt
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingmacros|, $\underline{205}$, $\underline{212}$, 273, {\it329}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingonline|, 121, 212, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingoutput|, $\underline{254}$, 273, {\it301--302}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingpages|, {\it112--114}, 124, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingparagraphs|, {\it98--99}, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingrestores|, 273, $\underline{301}$, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingstats|, 273, $\underline{300}$, $\underline{303}$, {\it383}.
+}
+
+\bugonpage 479, index entry for underlined text (8/2/84)
+
+\eightpoint Add `{\sl see also\/} |\underbar|'.
+
+\bugonpage 480, index entry for {\tt\char`\\vbox} (11/1/83)
+
+\eightpoint Delete page 256 from this list.
+
+\bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.seven b/Master/texmf-doc/doc/english/knuth/errata/errata.seven
new file mode 100644
index 00000000000..0866189da51
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.seven
@@ -0,0 +1,821 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1991}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A,~B, C, and D\null, between 1 January 1991 and
+15 March 1992.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Some of the corrections below have already been made in
+reprintings of the books. Changes to Volume~B refer to the fourth printing
+(1991), which differs markedly from earlier printings because it includes
+all the revisions for \TeX3.0. Changes to Volume~D refer to the third
+printing (1991), which differs markedly from earlier printings because
+it includes all the revisions for \MF\kern1pt2.0. Changes to the mini-indexes
+and master indexes of Volumes B and~D are not shown here unless they are
+not obviously derivable from what has been shown.
+Dozens of changes, too many to list
+here, have been made to Volume~E because of recent upgrades to the
+Computer Modern font source files.
+Those changes, which affect only the digitization at
+low resolution and the appearance of lowercase delta and
+some characters in the math symbols
+fonts (but not the {\tt TFM} files), are documented at
+the end of file {\tt cm85.bug}.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A96, lines 9--11 (9/18/91)
+
+\ninepoint
+Some ^{German} words traditionally change their spelling
+when they are split between lines. For example, `backen' becomes `bak-ken'
+and `Bettuch' becomes `Bett-tuch'. How can you instruct \TeX\ to produce
+such effects?
+
+\bugonpage A178, line 17 (11/19/91)
+
+\ninepoint
+If you say `|\phantom{|\<subformula>|}|' in any formula, plain
+\TeX\ will do its\cutpar
+
+\bugonpage A286, bottom two lines and continuing into A287 (11/21/91)
+
+\ninepoint\noindent
+stands for zero or more \<assignment>
+commands other than |\setbox|.
+If the assignments are not followed by a \<character>, where
+\<character> stands for any of the commands just discussed in the previous
+paragraph, \TeX\ treats |\accent| as if it were |\char|, except that
+the space factor is set to 1000. Otherwise the character that follows
+the assignment is accented by the character that corresponds to the
+\<8-bit number>. \ (The purpose of the intervening assignments is to
+allow the accenter and accentee to be in different fonts.) \ If the
+accent must be moved up or down, it is put into an hbox that is
+raised or lowered. Then the accent is effectively superposed on the
+character by means of kerns, in such a way that the width of the accent
+does not influence the width of the resulting horizontal list.
+Finally, \TeX\ sets |\spacefactor=1000|.
+
+\bugonpage A291, lines 6--8 (11/21/91)
+
+\ninepoint\noindent
+`|}|' may be followed by
+optional \<assignment> commands other than |\setbox|,
+after which `|$$|'~must conclude
+the display. \TeX\ will insert the |\abovedisplayskip| and
+|\belowdisplayskip| glue before and after the result of the alignment.
+
+\bugonpage A293, line 14 (9/18/91)
+
+\ninepoint\noindent
+explained in Appendix~G\null. \TeX\
+scans \<one optional space> after completing a displayed formula; this is
+usually the implicit space at the end of a line in the input file.
+
+\bugonpage A311, bottom four lines (9/18/91)
+
+\ninepoint
+\ansno12.7: 1000, except: 999 after |O|, |B|, |S|, |D|, and |J|; 1250 after the
+comma; 3000 after the exclamation point, the right-quote marks, and the
+periods. If a period had come just after the |B| (i.e., if the text had
+said `|B. Sally|'), the space factor after that period would have
+been~1000, not~3000.
+
+\bugonpage A314, lines 16--18 from the bottom (1/10/92)
+
+\ninepoint
+\ansno14.8: |ba\ck/en| and |Be\ttt/uch|, where the macros |\ck/| and |\ttt/|
+are defined by
+\begintt
+\def\ck/{\discretionary{k-}{k}{ck}}
+\def\ttt/{tt\discretionary{-}{t}{}}
+\endtt
+
+\bugonpage A354, line 8 (9/18/91)
+
+\ninepoint\noindent
+|\def\multispan#1{\omit\mscount=#1\relax\loop\ifnum\mscount>1 \sp@n\repeat}|%
+\kern-10pt\null
+
+\bugonpage A356, line 11 from the bottom (9/23/91)
+
+\ninepoint\noindent
+| \else{\ooalign{\unhbox0\crcr\hidewidth\char'30\hidewidth}}\fi}|
+
+\bugonpage A358, line 8 from the bottom (9/18/91)
+
+\ninepoint\noindent
+|\mathchardef\mapstochar="3237 \def\mapsto{\mapstochar\rightarrow}|
+
+\bugonpage A359, line 13 (11/4/91)
+
+\ninepoint\noindent
+|\def\overrightarrow#1{\vbox{\m@th\ialign{##\crcr|
+
+\bugonpage A359, line 16 (11/4/91)
+
+\ninepoint\noindent
+|\def\overleftarrow#1{\vbox{\m@th\ialign{##\crcr|
+
+\bugonpage A359, line 19 (11/4/91)
+
+\ninepoint\noindent
+|\def\overbrace#1{\mathop{\vbox{\m@th\ialign{##\crcr\noalign{\kern3pt}|
+
+\bugonpage A359, line 22 (11/4/91)
+
+\ninepoint\noindent
+|\def\underbrace#1{\mathop{\vtop{\m@th\ialign{##\crcr|
+
+\bugonpage A359, lines 7--14 from the bottom (1/11/92)
+
+\ninepoint\noindent
+|\def\lgroup{\delimiter"462833A } \def\rgroup{\delimiter"562933B }|%
+\par\noindent
+|\def\lmoustache{\delimiter"437A340 } \def\rmoustache{\delimiter"537B341 }|%
+ \kern-2pt\null\par\noindent
+|\def\uparrow{\delimiter"3222378 } \def\Uparrow{\delimiter"322A37E }|%
+\par\noindent
+|\def\downarrow{\delimiter"3223379 } \def\Downarrow{\delimiter"322B37F }|%
+\par\noindent
+|\def\updownarrow{\delimiter"326C33F } \def\arrowvert{\delimiter"026A33C }|%
+\par\noindent
+|\def\Updownarrow{\delimiter"326D377 } \def\Arrowvert{\delimiter"026B33D } |%
+\par\noindent
+|\def\vert{\delimiter"026A30C } \def\Vert{\delimiter"026B30D } |%
+\par\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"077C33E }|
+
+\bugonpage A360, line 13 (11/19/91)
+
+\ninepoint\noindent
+|\phantom|, |\smash|, |\root|, and other
+operations. (Actually |\phantom| and |\smash| are not perfect: They
+assume that the current style is uncramped.)
+
+\bugonpage A360, line 2 from the bottom (11/4/91)
+
+\ninepoint\noindent
+|\def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}|
+
+\bugonpage A361, top line (11/4/91)
+
+\ninepoint\noindent
+|\def\rlh@#1{\vcenter{\m@th\hbox{\ooalign{\raise2pt|
+
+\bugonpage A364, line 5 from the bottom (11/4/91)
+
+\ninepoint\noindent
+|\def|^|\fmtname||{plain}\def\fmtversion{3.141}|
+
+\bugonpage A377, the bottom 17 lines (9/18/91)
+
+\eightpoint\noindent\hangindent\parindent\hangafter-3
+story: Macro |\stest| decides whether or not
+a given token list register begins with
+a \<space token> as defined in Chapter~24. If so, the macro
+decides whether the token is explicit and/or funny and/or active.
+\begintt
+\newif\ifspace \newif\iffunny \newif\ifexplicit \newif\ifactive
+\def\stest#1{\funnyfalse \expandafter\s\the#1! \stest}
+\def\s{\global\explicitfalse \global\activefalse \futurelet\next\ss}
+\def\ss{\ifcat\noexpand\next\stoken\let\nxt\sx\else\let\nxt\ns\fi\nxt}
+\def\sx{\spacetrue\ifx\next\stoken\let\nxt\sss\else\let\nxt=\ssss\fi\nxt}
+\long\def\sss#1 #2\stest{\def\next{#1}%
+ \ifx\next\empty \global\explicittrue \else\testactive#1\s\fi}
+\long\def\ssss#1#2\stest{\funnytrue{\escapechar=\if*#1`?\else`*\fi\relax
+ \if#1\string#1\uccode`#1=`~ % we assume that ~ is an active character
+ \uppercase{\ifcat\noexpand#1}\noexpand~\global\activetrue
+ \else\global\explicittrue\fi
+ \else\testactive#1\s\fi}}
+\long\def\ns#1\stest{\spacefalse}
+\long\def\testactive#1#2\s{\expandafter\tact\string#1\s\tact}
+\long\def\tact#1#2\tact{\def\next{#2}\ifx\next\xs\global\activetrue
+ \else\ifx\next\empty \global\activetrue\fi\fi} \def\xs{\s}
+\endtt
+
+\bugonpage A444, lines 15--26 (3/26/91)
+
+\ninepoint
+\textindent{\bf14.}If the current item is an Ord atom,
+go directly to Rule~17 unless
+all of the following are true: The nucleus is a symbol; the subscript
+and superscript are both empty; the very next item in the math list is an
+atom of type Ord, Op, Bin, Rel, Open, Close, or Punct; and the nucleus of the
+next item is a symbol whose family is the same as the family in the present
+Ord atom. In such cases the present symbol is marked as a text symbol.
+If the font information shows a ligature between this symbol and the
+following one, using the specified family and the current size, then
+insert the ligature character and continue as specified by the font;
+in this process, two characters may collapse into a single Ord
+text symbol, and/or new Ord text characters may appear. If the font information
+shows a kern between the current symbol and the next, insert a kern item
+following the current atom.
+As soon as an Ord atom has been fully processed for ligatures and kerns,
+go to Rule~17.
+
+\bugonpage A446, lines 5 and 6 from the bottom (1/13/92)
+
+\ninepoint\noindent
+are used to change the current style just as
+in the first pass, so that both passes have the same value of~$C$ when
+they work on any particular atom.
+
+\bugonpage A447, in the parameter usage table (1/13/92)
+
+\ninepoint\noindent[Delete the entry for `$\sigma_2$'; the entry for
+`$\sigma_{17}$' moves down to the bottom of the left column.]
+
+\bugonpage A447, line 2 after the parameter usage table (1/13/92)
+
+\ninepoint\noindent
+to parameters in arbitrary families:
+Rule~17 uses |\fontdimen| parameter~2 (space) to de-\cutpar
+
+\bugonpage A467, entry for {\tt\char`\\hss} (9/18/91)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\hss}, 71--72, {\it82--83}, 233, 283, 285, 290, 442.
+
+\bugonpage A467, new subentry under hyphenation (9/18/91)
+
+\eightpoint\indent\quad
+suppressing, 93, 414, 424, 454.
+
+\bugonpage A476, right column (11/21/91)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\setbox}, 66--67, 77, 81, $\underline{120}$, 276, 279, 286,\par
+\indent\qquad 291, {\it386--392}.
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 10 from the bottom (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]3.141\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B18, lines 21 and 22 (10/12/91)
+
+\tenpoint\noindent
+must have an \\{xchr} equivalent in the local
+character set. (This restriction applies only to preloaded strings,
+not to those generated dynamically by the user.)
+
+\bugonpage B26, new line before fourth line from bottom (1/24/92)
+
+\ninepoint\noindent\hskip20pt
+\\{nl}: \\{integer};\quad$\{\,$new-line character to restore$\,\}$
+
+\bugonpage B26, bottom line and top 3 lines of B27 (1/24/92)
+
+\ninepoint\noindent\hskip30pt
+{\bf else begin if\/} $\\{selector}>\\{pseudo}$ {\bf then}\par
+\noindent\hskip50pt
+{\bf begin} \\{print\_char}($s$); \ {\bf return};\quad
+ $\{\,$internal strings are not expanded$\,\}$\par\noindent\hskip50pt
+{\bf end};\par\noindent\hskip40pt
+{\bf if\/} ($\langle\,$Character $s$ is the current new-line
+ character{\sevenrm\kern.5em244}$\,\rangle$) {\bf then}\par\noindent\hskip50pt
+{\bf if\/} $\\{selector}<\\{pseudo}$ {\bf then}\par\noindent\hskip60pt
+{\bf begin} \\{print\_ln}; \ {\bf return}; \
+{\bf end};\par\noindent\hskip40pt
+$\\{nl}\gets\\{new\_line\_char}$; \ $\\{new\_line\_char}\gets-1$;\quad
+ $\{\,$temporarily disable new-line character$\,\}$\par\noindent\hskip40pt
+$j\gets\\{str\_start}[s]$;\par\noindent\hskip40pt
+{\bf while} $j<\\{str\_start}[s+1]$ {\bf do}\par\noindent\hskip50pt
+{\bf begin} $\\{print\_char}(\\{so}(\\{str\_pool}[j]))$; \ $\\{incr}(j)$; \
+{\bf end};\par\noindent\hskip40pt
+$\\{new\_line\_char}\gets\\{nl}$; \ {\bf return};\par\noindent\hskip40pt
+{\bf end};
+
+\bugonpage B27, lines 9 and 10 (9/19/91)
+
+\tenpoint\noindent
+{\bf 60.\quad}%
+Control sequence names, file names, and strings constructed with
+{\tt\char`\\string} might contain \\{ASCII\_code} values that can't
+be printed using \\{print\_char}. Therefore we use
+\\{slow\_print} for them:
+
+\bugonpage B27, lines 13--26 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $j$: \\{pool\_pointer};\quad$\{\,$current character code
+ position$\,\}$\par\noindent\hskip10pt
+{\bf begin if\/} $(s\ge\\{str\_ptr})\lor(s<256)$ {\bf then} \\{print}(s)
+\par\noindent\hskip10pt {\bf else begin} $j\gets\\{str\_start}[s]$;\par
+\noindent\hskip20pt{\bf while} $j<\\{str\_start}[s+1]$ {\bf do}\par
+\noindent\hskip30pt{\bf begin} $\\{print}(\\{so}(\\{str\_pool}[j]))$; \
+ $\\{incr}(j)$;\par\noindent\hskip30pt
+{\bf end};\par\noindent\hskip20pt
+{\bf end};\par\noindent\hskip10pt
+{\bf end};
+
+\bugonpage B28, line 8 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf else begin} \\{slow\_print}(\\{format\_ident}); \ \\{print\_ln};
+
+\bugonpage B33, line 3 (1/11/92)
+
+\tenpoint\noindent
+recursively. A similar interlock is provided by \\{set\_box\_allowed}.
+
+\bugonpage B33, new line to come after line 14 (1/11/92)
+
+\ninepoint\noindent
+\\{set\_box\_allowed}: \\{boolean};\quad
+ $\{\,$is it safe to do a |\setbox| assignment?$\,\}$
+
+\bugonpage B33, new line to come after line 20 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{set\_box\_allowed}\gets\\{true}$;
+
+\bugonpage B36, line 12 (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} \\{print\_nl}({\tt\char`\"You\]want\]to\]edit\]file\]\char`\"});
+ \ \\{slow\_print}(\\{input\_stack}[\\{base\_ptr}].\\{name\_field});
+
+\bugonpage B46, lines 9 and 10 (5/24/91)
+
+\tenpoint\noindent
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+
+\bugonpage B47, lines 2 and 3 (5/24/91)
+
+\tenpoint\noindent
+structures on a \\{memory\_word}, which contains either a (signed) integer,
+possibly scaled, or a (signed) \\{glue\_ratio}, or a small number of
+fields that are one half or one quarter of the size used\cutpar
+
+\bugonpage B177, lines 10 and 11 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} \\{print\_err}({\tt\char`\"Bad\]mathchar\char`\"});\par
+\noindent\hskip20pt
+\\{help2}({\tt\char`\"A\]mathchar\]number\]must\]be\]between\]0\]%
+ and\]32767.\char`\"})
+
+\bugonpage B196, new lines after line 11 (1/13/92)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $\\{align\_state}<1000000$ {\bf then}\quad
+ $\{\,$unmatched `|}|' aborts the line$\,\}$\par\noindent\hskip30pt
+{\bf begin repeat} \\{get\_token}; \ {\bf until} $\\{cur\_tok}=0$;\par
+\noindent\hskip30pt$\\{align\_state}\gets1000000$; \ {\bf goto} \\{done};\par
+\noindent\hskip30pt{\bf end};
+
+\bugonpage B208, line 21 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{slow\_print}($a$); \ \\{slow\_print}($n$); \
+ \\{slow\_print}($e$);
+
+\bugonpage B214, line 14 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{wlog}(\\{banner}); \\{slow\_print}(\\{format\_ident}); \
+ \\{print}({\tt\char`\"\]\]\char`\"}); \
+ \\{print\_int}(\\{day}); \
+ \\{print\_char}({\tt\char`\"\]\char`\"});
+
+\bugonpage B214, line 2 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_char}({\tt\char`\"(\char`\"}); \
+\\{incr}(\\{open\_parens}); \
+\\{slow\_print}(\\{name}); \
+\\{update\_terminal}; \
+$\\{state}\gets\\{new\_line}$;
+
+\bugonpage B234, line 22 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+\\{print}({\tt\char`\"\]in\]font\]\char`\"}); \
+\\{slow\_print}(\\{font\_name}[$f$]); \
+\\{print\_char}({\tt\char`\"!\char`\"}); \
+\\{end\_diagnostic}(\\{false});
+
+\bugonpage B267, lines 7 and 8 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+\\{print\_nl}({\tt\char`\"Output\]written\]on\]\char`\"}); \
+\\{slow\_print}(\\{output\_file\_name});\par\noindent\hskip20pt
+\\{print}({\tt\char`\"\](\char`\"}); \
+\\{print\_int}(\\{total\_pages}); \
+\\{print}({\tt\char`\"\]page\char`\"});
+
+\bugonpage B296, new lines after line 8 of section 716 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $f<0$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} \\{decr}($n$); \ $f\gets f+\oct{200000}$;\par\noindent\hskip20pt
+{\bf end};
+
+\bugonpage B297, new lines after line 7 of section 717 (1/11/92)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $f<0$ {\bf then}\par\noindent\hskip30pt
+{\bf begin} \\{decr}($n$); \ $f\gets f+\oct{200000}$;\par\noindent\hskip30pt
+{\bf end};
+
+\bugonpage B348, bottom two lines (1/3/92)
+
+\tenpoint\noindent\hskip10pt
+Up to three passes might be made through the paragraph in an attempt to find at
+least one set of feasible breakpoints. On the first pass, we have
+$\\{threshold}=\\{pretolerance}$ and $\\{second\_pass}=$\cutpar
+
+\bugonpage B364, line 20 (1/3/92)
+
+\tenpoint\noindent
+{\bf 863.\quad}
+The `{\bf loop}' in the following code is performed at most
+thrice per call of \\{line\_break}, since\cutpar
+
+\bugonpage B377, insert new line after line 12 (9/19/91)
+
+\ninepoint\noindent
+\\{hyf\_bchar}:\enspace\\{halfword};\quad
+ $\{\,$boundary character after $c_n\,\}$
+
+\bugonpage B378, line 12 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+$\\{hyf\_bchar}\gets\\{character}(s)$; \
+$c\gets\\{qo}(\\{hyf\_bchar})$;
+
+\bugonpage B378, line 9 from the bottom (1/10/92)
+
+\ninepoint\noindent\hskip30pt
+$\\{hb}\gets s$; \ \\{incr}(\\{hn}); \ $\\{hu}[\\{hn}]\gets c$; \
+$\\{hc}[\\{hn}]\gets\\{lc\_code}(c)$; \
+$\\{hyf\_bchar}\gets\\{non\_char}$;
+
+\bugonpage B378, line 5 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf else if} $(\\{type}(s)=\\{kern\_node})\land(\\{subtype}(s)=\\{normal})$
+ {\bf then} $\\{hb}\gets s$\par\noindent\hskip40pt
+ {\bf else goto} \\{done3};
+
+\bugonpage B379, line 6 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+$j\gets\\{hn}$; \ $q\gets\\{lig\_ptr}(s)$; \
+{\bf if\/} $q>\\{null}$ {\bf then} $\\{hyf\_bchar}\gets\\{character}(q)$;
+
+\bugonpage B379, new line between lines 14 and 15 (1/10/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{odd}(\\{subtype}(s))$ {\bf then}
+$\\{hyf\_bchar}\gets\\{font\_bchar}[\\{hf}]$ {\bf else}
+$\\{hyf\_bchar}\gets\\{non\_char}$;
+
+\bugonpage B379, line 19 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{hn}<\\{l\_hyf}+\\{r\_hyf}$ {\bf then goto} \\{done1}; \
+\quad$\{\,$\\{l\_hyf} and \\{r\_hyf} are always $\ge1\,\}$
+
+\bugonpage B380, lines 9--11 from the bottom reduce to a single line (1/10/92)
+
+\ninepoint\noindent\hskip10pt
+$q\gets\\{link}(\\{hb})$; \ $\\{link}(\\{hb})\gets\\{null}$; \
+$r\gets\\{link}(\\{ha})$; \ $\\{link}(\\{ha})\gets\\{null}$; \
+$\\{bchar}\gets\\{hyf\_bchar}$;
+
+\bugonpage B436, lines 9 and 10 (3/15/92)
+
+\tenpoint
+$$\\{cur\_r}=\cases{\\{character}(\\{lig\_stack}),&if $\\{lig\_stack}>
+ \\{null}$;\cr
+ \\{font\_bchar}[\\{cur\_font}],&otherwise;\cr}$$
+except when $\\{character}(\\{lig\_stack})=\\{font\_false\_bchar}
+ [\\{cur\_font}]$. Several additional global variables are needed.
+
+\bugonpage B438, line 13 from the bottom (3/15/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_q}\gets\\{tail}$; \ $\\{cur\_l}\gets\\{character}(\\{lig\_stack})$;
+
+\bugonpage B507, line 6 of section 1241 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+\\{scan\_optional\_equals};\par\noindent\hskip10pt
+{\bf if\/} \\{set\_box\_allowed} {\bf then}
+$\\{scan\_box}(\\{box\_flag}+n)$\par\noindent\hskip10pt
+{\bf else begin} \\{print\_err}({\tt\char`\"Improper\]\char`\"});
+\ \\{print\_esc}({\tt\char`\"setbox\char`\"});\par\noindent\hskip20pt
+\\{help2}({\tt\char`\"Sorry,\]\char`\\setbox\]is\]not\]allowed\]after\]%
+\char`\\halign\]in\]a\]display,\char`\"})\par\noindent\hskip20pt
+({\tt\char`\"or\]between\]\char`\\accent\]%
+and\]an\]accented\]character.\char`\"});
+\ \\{error};\par\noindent\hskip20pt
+{\bf end};
+
+\bugonpage B511, new line inserted after line 3 (1/24/92)
+
+\ninepoint\noindent\hskip20pt
+\\{flushable\_string}: \\{str\_number};\quad
+ $\{\,$string not yet referenced$\,\}$
+
+\bugonpage B512, new line inserted after line 3 of section 1260 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{flushable\_string}\gets\\{str\_ptr}-1$;
+
+\bugonpage B512, the former line 6 of section 1260 (1/24/92)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin if\/} $\\{cur\_name}=\\{flushable\_string}$ {\bf then}
+\par\noindent\hskip40pt{\bf begin} \\{flush\_string}; \
+ $\\{cur\_name}\gets\\{font\_name}[f]$; \ {\bf end};
+\par\noindent\hskip30pt{\bf if\/} $s>0$ {\bf then}
+
+\bugonpage B512, line 10 from the bottom (9/19/91)
+
+\ninepoint\noindent
+\\{set\_font}:\enspace{\bf begin}
+\\{print}({\tt\char`\"select\]font\]\char`\"}); \
+\\{slow\_print}(\\{font\_name}[\\{chr\_code}]);
+
+\bugonpage B514, line 9 (1/11/92)
+
+\ninepoint\noindent\hskip20pt
+$\\{set\_box\_allowed}\gets\\{false}$; \
+\\{prefixed\_command}; \
+$\\{set\_box\_allowed}\gets\\{true}$;
+
+\bugonpage B515, line 19 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{slow\_print}($s$); \ \\{update\_terminal};
+
+\bugonpage B516, line 2 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{print\_err}({\tt\char`\"\char`\"}); \
+ \\{slow\_print}($s$);
+
+\bugonpage B531, lines 19 and 20 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"Beginning\]to\]dump\]on\]file\]\char`\"}; \
+\\{slow\_print}(\\{w\_make\_name\_string}(\\{fmt\_file})); \
+\\{flush\_string};\par\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"\char`\"}); \
+\\{slow\_print}(\\{format\_ident})
+
+\bugonpage B533, line 29 (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} \\{print\_nl}({\tt\char`\"Transcript\]written\]on\]\char`\"}); \
+\\{slow\_print}(\\{log\_name}); \
+\\{print\_char}({\tt\char`\".\char`\"});
+
+\bugonpage B538, line 13 (9/19/91)
+
+\ninepoint\noindent
+10:\enspace\\{slow\_print}($n$);
+
+\bugonpage B577, left column (12/23/91)
+
+\eightpoint\noindent[Add 798 to the index entries for `system dependencies'.]
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C262, line 15 (3/26/91)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="2.7";|
+
+\bugonpage C271, line 17 from the bottom (3/26/91)
+
+\ninepoint\noindent
+| currentpen_path shifted (z.t_) withpen penspeck enddef;|
+
+\bugonpage C347, Bront''e entry (1/29/91)
+
+\eightpoint\noindent
+[The accent was clobbered; her name should, of course, be Bront\"e.
+Fix the entries for D\"urer, M\"obius, and Stravinsky in the same way.]
+
+\bugonpage C348, left column (1/11/92)
+
+\eightpoint\indent
+compound statement, $\underline{155}$, 217.
+
+\bugonpage C353, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt numeric}, 55, $\underline{56}$, {\it65}, 88.
+
+\bugonpage C354, miscellaneous entries in both columns (1/11/92)
+
+\eightpoint
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt openwindow}, $\underline{191}$--$\underline{193}$, 220, {\it277},
+ {\it312--313}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt or}, {\it65}, $\underline{170}$, 210, 237, 288--289.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt pair}, 55, $\underline{56}$, 65.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt path}, 55, $\underline{56}$, 171.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt pen}, 55, $\underline{56}$, {\it65}, 170.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt picture}, 55, $\underline{56}$, {\it114}.
+
+\bugonpage C356, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt string}, 55, $\underline{56}$, 69.
+
+\bugonpage C357, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt transform}, 55, $\underline{56}$, 57, 141--143, {\it160}, 266.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage D2, last line of section 2 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]2.71\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D102, line 15 from the bottom (11/1/91)
+
+\tenpoint\noindent
+Then
+$\\{eq\_type}(h(x))=\\{tag\_token}$ and $\\{equiv}(h(x))=p$,
+where $p$~is a two-word value
+node with\cutpar
+
+\bugonpage D188, lines 16 and 17 (1/24/92)
+
+\tenpoint\noindent
+errors. Our subroutines also obey the identity $t[a,b]+t[b,a]=a+b$.
+
+\bugonpage D190, new copy before bottom four lines (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(r)<\\{x\_coord}(\\{pp})$ {\bf then}
+ $\\{x\_coord}(r)\gets\\{x\_coord}(\\{pp})$\par\noindent\hskip10pt
+{\bf else if\/} $\\{x\_coord}(r)>\\{dest\_x}$ {\bf then}
+ $\\{x\_coord}(r)\gets\\{dest\_x}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{left\_x}(r)>\\{x\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_x}(r)\gets\\{x\_coord}(r)$; \
+{\bf if\/} $\\{right\_x}(\\{pp})>\\{x\_coord}(r)$ {\bf then}
+$\\{right\_x}(\\{pp})\gets\\{x\_coord}(r)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_x}(r)<\\{x\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_x}(r)\gets\\{x\_coord}(r)$; \
+{\bf if\/} $\\{left\_x}(\\{qq})<\\{x\_coord}(r)$ {\bf then}
+$\\{left\_x}(\\{qq})\gets\\{x\_coord}(r)$; \ {\bf end};
+
+\bugonpage D191, new copy before bottom two lines of section 416 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(s)<\\{x\_coord}(r)$ {\bf then}
+ $\\{x\_coord}(s)\gets\\{x\_coord}(r)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{x\_coord}(s)>\\{dest\_x}$ {\bf then}
+ $\\{x\_coord}(s)\gets\\{dest\_x}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{left\_x}(s)>\\{x\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_x}(s)\gets\\{x\_coord}(s)$; \
+{\bf if\/} $\\{right\_x}(r)>\\{x\_coord}(s)$ {\bf then}
+$\\{right\_x}(r)\gets\\{x\_coord}(s)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_x}(s)<\\{x\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_x}(s)\gets\\{x\_coord}(s)$; \
+{\bf if\/} $\\{left\_x}(\\{qq})<\\{x\_coord}(s)$ {\bf then}
+$\\{left\_x}(\\{qq})\gets\\{x\_coord}(s)$; \ {\bf end};
+
+\bugonpage D194, lines 4 and 5 (1/24/92)
+
+\tenpoint\noindent[Delete those two lines; I no longer believe that the
+assertion has been proved (although it might be true).]
+
+\bugonpage D194, lines 7--13 of section 424 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{y\_coord}(r)<\\{y\_coord}(p)$ {\bf then}
+ $\\{y\_coord}(r)\gets\\{y\_coord}(p)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{y\_coord}(r)>\\{dest\_y}$ {\bf then}
+ $\\{y\_coord}(r)\gets\\{dest\_y}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(p)+\\{y\_coord}(r)>\\{dest\_x}+\\{dest\_y}$
+{\bf then} $\\{y\_coord}(r)\gets\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(p)$;\par
+\noindent\hskip10pt
+{\bf if\/} $\\{left\_y}(r)>\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{right\_y}(p)>\\{y\_coord}(r)$ {\bf then}
+$\\{right\_y}(p)\gets\\{y\_coord}(r)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(r)<\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(r)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(r)$; \ {\bf end};
+
+\bugonpage D194, lines 8--11 from the bottom (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(r)<\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(r)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(r)$; \ {\bf end};
+
+\bugonpage D195, lines 3--9 of section 425 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{y\_coord}(s)<\\{y\_coord}(r)$ {\bf then}
+ $\\{y\_coord}(s)\gets\\{y\_coord}(r)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{y\_coord}(s)>\\{dest\_y}$ {\bf then}
+ $\\{y\_coord}(s)\gets\\{dest\_y}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(r)+\\{y\_coord}(s)>\\{dest\_x}+\\{dest\_y}$
+{\bf then} $\\{y\_coord}(s)\gets\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(r)$;\par
+\noindent\hskip10pt
+{\bf if\/} $\\{left\_y}(s)>\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{right\_y}(r)>\\{y\_coord}(s)$ {\bf then}
+$\\{right\_y}(r)\gets\\{y\_coord}(s)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(s)<\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(s)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(s)$; \ {\bf end};
+
+\bugonpage D195, lines 3--7 from the bottom if section 425 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(s)<\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(s)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(s)$; \ {\bf end};
+
+\bugonpage D289, lines 9 and 10 (11/1/91)
+
+\ninepoint\noindent\hskip20pt
+$p\gets\\{dep\_list}(p)$; \ $r\gets\\{inf\_val}$;\par\noindent\hskip20pt
+{\bf repeat if\/} $\\{value}(\\{info}(p))\ge\\{value}(r)$ {\bf then}\par
+
+\bugonpage D486, line 18 (11/1/91)
+
+\tenpoint\noindent
+The \\{label\_loc}
+and \\{label\_char} arrays have been set up to record all the
+starting addresses; we have\cutpar
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.six b/Master/texmf-doc/doc/english/knuth/errata/errata.six
new file mode 100644
index 00000000000..ad7444d8600
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.six
@@ -0,0 +1,528 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1990}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A,~C, and E\null, between 30 September 1989 (when
+the revisions for \TeX\ Version 3.0 and \MF\ Version 2.0 were made) and
+December 31, 1990.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Some of the corrections below have already been made in
+reprintings of the books. Hundreds of changes, too many to list here,
+have been made to Volumes B~and~D because of the upgrades to \TeX\ and
+\MF\null. Readers who need up-to-date information on the \TeX\ and
+\MF\ programs should refer to the |WEB| source files until new
+printings of Volumes B~and~D are issued. \looseness=-1
+
+ % volume A
+
+\bugonpage A99, line 4 from the bottom (2/22/90)
+
+\ninepoint\indent
+to be chosen because there was no feasible
+way to keep total demerits small.
+
+\bugonpage A124, lines 18--21 (9/5/90)
+
+\ninepoint\noindent
+Floating insertions can be accommodated
+as a special case of split insertions, by making each floating topinsert
+start with a small penalty, and by having
+zero as the associated |\floatingpenalty|; non-floating insertions
+like footnotes are accommodated by associating larger penalties with
+split insertions (see Appendix~B).
+
+\bugonpage A137, lines 2 and 3 from the bottom (11/9/90)
+
+{\eightssi
+\rightline{and you shouldn't even be reading this manual,}
+\rightline{which is undoubtedly all English to you.}
+}
+
+\bugonpage A141, line 15 from the bottom (10/18/90)
+
+\tenpoint\noindent
+Thus if you type `|$1\over2$|' (in a text) you get $1\over2$, namely style
+$S$ over style~$S'$;\cutpar
+
+\bugonpage A156, line 2 (11/18/89)
+
+\ninepoint
+Commands like |\mathchardef\alpha="010B| are used in
+Appendix~B to define\cutpar
+
+\bugonpage A165, lines 2--3 (8/13/90)
+
+\ninepoint
+ Type the formula $\bf\bar x^{\rm T}Mx={\rm0}\iff x=0$,
+using as few keystrokes as possible.
+\ (The first `0' is roman, the second is bold. The superscript `T' is roman.)
+
+\bugonpage A171, lines 24--26 (3/13/90)
+
+\ninepoint\noindent
+formula produces a result exactly equivalent to
+`|\left(|\<subformula>|\right)|', when the \<subformula> doesn't end
+with Punct, except that the {delimiters} are forced to
+be of the |\big| size regardless of the height and depth of the subformula.
+
+\bugonpage A193, lines 16--18 (12/2/89)
+
+\ninepoint\noindent
+line if you insert
+`^|\noalign||{|^|\break||}|'
+after the |\cr| for that line. You can prohibit {\sl all\/} breaks
+in an |\eqalignno| if you set ^|\interdisplaylinepenalty||=10000|; or you
+can enclose the whole works in a ^|\vbox|:
+
+\bugonpage A233, bottom 9 lines, and top three on next page (12/2/89)
+
+\danger The |\+| macro in Appendix~B works
+by putting the \<text> for each column that's followed by~|&|
+into an hbox as follows:
+\begindisplay
+|\hbox to |\<column width>|{|\<text>|\hss}|
+\enddisplay
+The ^|\hss| means that the text is normally flush left, and that it can
+extend to the right of its box. Since |\hfill| is ``more infinite'' than
+|\hss| in its ability to stretch, it has the effect of right-justifying or
+centering as stated above. Note that |\hfill| doesn't shrink, but |\hss|
+does; if the text doesn't fit in its column, it will stick out at the right.
+You could cancel the shrinkability of |\hss| by adding ^|\hfilneg|; then
+an oversize text would produce an overfull box.
+You could also center some text by putting `|\hss|' before it and just
+`|&|' after it; in that case the text would be allowed to extend to the
+left and right of its column.
+ The last column of a |\+|~line (i.e., the column entry that is
+followed by |\cr|) is treated differently: The
+\<text> is simply put into an hbox with its natural~width.\looseness=-1
+
+\bugonpage A254, line 5 from the bottom (10/5/89)
+
+\ninepoint\noindent
+|\vsize| hasn't changed, and if all insertions have been
+held in place, the same page break\cutpar
+
+\bugonpage A286, lines 30--32 (3/13/90)
+
+\ninepoint\noindent
+reading and expanding this \cstok{par}
+token, \TeX\ will see the \<vertical command> token again. \ (The current
+meaning of the control sequence ^|\par| will be used; \cstok{par} might no
+longer stand for \TeX's |\par| primitive.)
+
+\bugonpage A290, lines 12--13 (3/24/90)
+
+\ninepoint\noindent
+simply a single Ord atom without subscripts or superscripts,
+or an Acc whose nucleus is an Ord, the
+enclosing braces are effectively removed.
+
+\bugonpage A317, line 17 (5/17/90)
+
+\ninepoint
+|\pretolerance=9999 \tolerance=9999 \parindent=0pt|
+
+\bugonpage A321, lines 16--17 (8/13/90)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss18.6.\enspace}\ignorespaces
+|$\bf\bar x^{\rm T}Mx={\rm0}\iff x=0$|. \ (If you typed a space between
+|\rm| and~|0|, you wasted a keystroke; but don't feel guilty about it.)
+
+\bugonpage A340, nonblank line 11 (3/13/90)
+
+\tenpoint\noindent
+|\topglue 1in % This makes an inch of blank space (1in=2.54cm).|
+
+\bugonpage A342, line 6 (3/13/90)
+
+\tenpoint\noindent
+|\topglue| but not |\hglue|. It does not
+illustrate |\raggedright| setting of para-\cutpar
+
+\bugonpage A346, lines 20--21 (12/3/89)
+
+\ninepoint\noindent
+streams used by ^|\read| and ^|\write|, to math
+^{families} used by ^|\fam|, to sets of hyphenation rules used by
+^|\language|, and to insertions (which require
+^|\box|, ^|\count|, ^|\dimen|, and ^|\skip| registers all having the
+same number).
+
+\bugonpage A346, line 20 from the bottom (12/3/89)
+
+\ninepoint\noindent
+manent value. These macros use registers
+|\count10| through |\count20| to hold the\cutpar
+
+\bugonpage A346, lines 8--13 from the bottom (12/3/89)
+
+\ninepoint\noindent
+number was allocated. The inside story of how allocation is actually performed
+should be irrelevant when the allocation macros are used at a higher level;
+you mustn't assume that |plain.tex| really does allocation in any
+particular way.
+\beginlines
+|\count10=22 % this counter allocates \count registers 23, 24, 25, ...|
+\endgroup
+
+\bugonpage A347, lines 2--5 (12/3/89)
+
+\ninepoint{\parindent=0pt
+|\count19=0 % this counter allocates language codes 1, 2, 3, ...|\parbreak
+|\count20=255 % this counter allocates insertions 254, 253, 252, ...|\parbreak
+|\countdef\insc@unt=20 % nickname for the insertion counter|\parbreak
+|\countdef\allocationnumber=21 % the most recent allocation|\parbreak
+|\countdef|^|\m@ne||=22 \m@ne=-1 % a handy constant|\par}
+
+\bugonpage A347, new line after former line 17 (12/3/89)
+
+\ninepoint\noindent
+|\outer\def|^|\newlanguage||{\alloc@9\language\chardef\@cclvi}|
+
+\bugonpage A352, new line before line 6 from the bottom (3/13/90)
+
+\ninepoint\noindent
+|\def\topglue{\nointerlineskip \vglue-\topskip \vglue} % for top of page|
+
+\bugonpage A355, line 8 from the bottom (12/3/89)
+
+\ninepoint\noindent
+| \noindent{\bf#1.\enspace}{\sl#2\par}%|
+
+\bugonpage A363, lines 8--9 from the bottom (12/8/89)
+
+{\ninepoint\parindent=0pt
+| \if@mid \dimen@=\ht0 \advance\dimen@ by\dp\z@ |%
+ |\advance\dimen@ by12\p@|\parbreak%
+| \advance\dimen@ by\pagetotal \advance\dimen@ by-\pageshrink|
+\par}
+
+\bugonpage A375, line 27 (10/30/89)
+
+\ninepoint\noindent
+depending on whether or not |\t|~contains
+an asterisk. \ (Do you see why?) \ And here's\cutpar
+
+\bugonpage A393, lines 3--5 from the bottom (12/3/89)
+
+\ninepoint
+|\hskip-.17em plus-3em minus.11em|\par
+|\vadjust{}\penalty10000|\par
+|\leaders\copy\dbox\hskip3.3\wd\dbox plus1fil minus.3\wd\dbox|
+
+\bugonpage A444, line 4 (3/13/90)
+
+\ninepoint\noindent
+Shift box~$x$ down by ${1\over2}\bigl(h(x)-d(x)\bigr)
+-a$, where $a=\sigma_{22}$, so that the operator character\cutpar
+
+\bugonpage A450, line 8 (12/3/89)
+
+\def\\#1{$_{\kern\scriptspace#1}$}
+\ninepoint\indent
+{\qquad\tt\\0h\\0e\\0n\\5a\\0t\\0 \\1n\\0a\\0 \\0n\\2a\\0t\\0
+ \\1t\\0i\\0o\\0 \\2i\\0o\\0 \\0o\\2n\\0}
+
+\bugonpage A450, line 14 (12/3/89)
+
+\ninepoint
+{\tt.\\0h\\0y$_3$p\\0h\\0e\\2n\\5a\\4t\\2i\\0o\\2n\\0.}
+
+\bugonpage A450, lines 19 and 20 (12/3/89)
+
+\ninepoint\vskip-10pt
+\begindisplay
+\tt\\0o\\2n\\0
+\\0o\\0n\\1c\\0
+\\1c\\0a\\0
+\\1n\\0a\\0
+\\0n\\2a\\0t\\0
+\\1t\\0i\\0o\\0
+\\2i\\0o\\0
+\\0o\\2n\\0
+\enddisplay
+and this yields `{\tt\\0c\\0o\\2n\\1c\\0a\\0t\\0e\\1n\\2a\\1t\\2i\\0o\\2n\\0}',
+i.e., `|con-cate-na-tion|'.
+
+\bugonpage A455, last lines before the quotes (11/30/89)
+
+\ninepoint\noindent
+sit yourself (even in restricted horizontal mode) by saying
+^|\setlanguage|\<number>;\break
+ this changes the current language but it
+does not change |\language|. Each what-\break
+sit records the current
+|\lefthyphenmin| and |\righthyphenmin|.
+
+\bugonpage A467, right column (12/3/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\hfilneg|, 72, 100, 233, 283, 285, 290, 397.
+
+\bugonpage A468, right column (12/2/89)
+
+\eightpoint
+|\interdisplaylinepenalty|, {\it193}, 349, 362.
+
+\bugonpage A469, left column (12/3/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\language| (hyphenation method), 273, 346, $\underline{455}$.
+
+\bugonpage A469, right column (10/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\lefthyphenmin|, 273, {\it364}, $\underline{454}$, 455.
+
+\bugonpage A472, left column (12/3/89)
+
+\eightpoint
+|\newlanguage|, 346, $\underline{347}$.
+
+\bugonpage A476, left column (10/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\righthyphenmin|, 273, {\it364}, $\underline{454}$, 455.
+
+\bugonpage A479, new entry (3/13/90)
+
+\eightpoint
+|\topglue|, {\it340}, $\underline{352}$.
+
+\bugonpage A480, right column (3/13/90)
+
+\eightpoint
+|\vglue|, $\underline{352}$, {\it408}.
+
+\bugonpage A483, the Providence lines (10/8/89)
+
+\noindent[Change the first one to
+\begintt
+Providence RI 02940\kern.05em-9506, USA.
+\endtt
+Then the second one will be
+\begindisplay
+Providence RI 02940\kern.05em-9506, USA.
+\enddisplay
+The second line will also appear on page C361.]
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C11, replacement for second quotation at bottom of page (9/27/90)
+
+\begingroup
+ \eightpoint \let\tt=\ninett
+ \baselineskip 10pt
+ \parfillskip \z@
+ \interlinepenalty 10000
+ \leftskip \z@ plus 40pc minus \parindent
+ \let\rm=\eightss \let\sl=\eightssi
+ \everypar{\sl}
+ \def\par{\ifhmode\/\endgraf\fi}\obeylines
+To anyone who has lived in a modern American city (except Boston)
+at least one of the underlying ideas of ^{Descartes}' analytic geometry
+will seem ridiculously evident. Yet, as remarked,
+it took mathematicians all of two thousand years
+to arrive at this simple thing.
+\author ERIC TEMPLE ^{BELL}, {\sl Mathematics: Queen and Servant of %
+ Science\/} (1951) % p123
+
+\endgroup
+
+\bugonpage C220, top line (3/13/90)
+
+\ninepoint\noindent
+modes you get into by hitting
+`|S|', `|R|', or `|Q|', respectively, in response to error messages\cutpar
+
+\bugonpage C252, line 16 (3/13/90)
+
+\ninepoint\indent
+| for i:=1 upto n_windows: display blankpicture inwindow i; endfor|
+
+\bugonpage C262, lines 19--21 (11/9/90)
+
+\ninepoint\noindent
+for commonly occurring idioms.
+For example, `{\bf stop} |"hello"|' displays `|hello|' on the terminal and waits
+until \<return> is typed.
+\beginlines
+|def |^|upto|| = step 1 until enddef; def |^|downto|| = step -1 until enddef;|
+\endgroup
+
+\bugonpage C264, lines 4--6 from the bottom (3/24/90)
+
+\ninepoint\noindent
+|vardef |^|counterclockwise|| primary c =|\par\noindent
+| if turningcheck>0:|\par\noindent
+| interim |^|autorounding||:=0;|\par\noindent
+| if |^|turningnumber|| c <= 0: reverse fi fi c enddef;|
+
+\bugonpage C306, line 6 (3/13/90)
+
+\ninepoint\noindent
+| ligtable "'": "'" =: oct"042", % close quotes|
+
+\bugonpage C309, second line from bottom (11/18/89)
+
+\ninepoint\noindent
+| define_whole_vertical_blacker_pixels(vair,slab,| $\cdots$ |);|
+
+\bugonpage C315, line 9 from the bottom (1/2/90)
+
+\ninepoint\noindent
+units of printer's points):
+
+\bugonpage C329, line 25 (12/29/90)
+
+\ninepoint\noindent
+which can be used to specify a nonstandard file area
+or directory name for the gray\cutpar
+
+\bugonpage C337, line 4 from the bottom (1/7/90)
+
+\ninepoint\noindent
+|\def\startfont{\font\testfont=\fontname \spaceskip=0pt|
+
+\bugonpage C347, left column (9/27/90)
+
+\eightpoint\noindent
+Bell, Eric Temple, 11.
+
+\bugonpage C349, left column (9/27/90)
+
+\eightpoint\noindent
+Descartes, Ren\'e, 6, 11, 19.
+
+\bugonpage C356, right column (9/27/90)
+
+\eightpoint\noindent
+[remove the entry for Rex Stout.]
+
+\bugonpage C358, right column (9/27/90)
+
+\eightpoint\noindent
+[remove the entry for Nero Wolfe.]
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, replacement for last four lines (4/30/90)
+
+\textindent{\bull}``AMS Euler---A new typeface for mathematics''
+ by Donald~E. Knuth
+and Hermann Zapf, {\sl Scholarly Publishing\/ \bf21} (1989), 131--157.
+\ {\it The story of a design project that helps bridge the gulf between
+mathematics and art.}
+
+\smallskip
+\textindent{\bull}``Meta-Marks:
+ Preliminary studies for a Pandora's Box of shapes''
+by Neenie Billawala, Stanford Computer Science report 1259 (Stanford,
+California, July 1989), 132~pp.
+\ {\it Lavishly illus\-trated studies in parameter variation,
+leading to the design of a new typeface called Pandora.}
+
+
+
+\bugonpage E325, line 13 (3/13/90)
+
+\ninepoint\noindent
+{\bf if} \\{serifs}: $x_{3r}=\max(x_{1r},{\rm hround}(x_1+.5\\{dot\_diam}
+ -.2\\{jut})-.5\\{tiny})$\par\noindent
+{\bf else}: $x_3=x_1-.5$ {\bf fi};
+
+\bugonpage E483, line 4 (3/13/90)
+
+\ninepoint
+\rightline{\% Character codes \oct{000}--\oct{100} and \oct{133}--\oct{177}
+ are generated.}
+
+\bugonpage E544, line 5 (3/13/90)
+
+\ninepoint\noindent
+\hskip 3em\vdots\hskip2em\raise2pt\hbox{(the rest of the
+ program for `$\gamma$' in |greekl| comes here)}
+
+\bugonpage E557, line 9 (3/13/90)
+
+\ninepoint
+\rightline{\sl`Nevermore---Ah nevermore.'\thinspace''}
+
+\bugonpage E558, line 21 (3/13/90)
+
+\eightpoint\noindent
+|Clasp a rare and radiant maiden whom the angels name Lenore."|
+
+\bugonpage E570, lines 27--28 look better with proper skewchars (3/13/90)
+
+\begingroup
+\tenpoint\bf
+\textfont0=\tenbf \scriptfont0=\sevenbf
+\font\boldi=cmmib10 \font\boldsy=cmbsy10
+\skewchar\boldi='177 \skewchar\boldsy='60
+\textfont1=\boldi
+\textfont2=\boldsy
+\noindent Here's some bold 10-point math:
+${\hat A}^\Gamma_0
++{\check B}^\Delta_1
+-{\tilde C}^\Theta_2
+\times{\acute D}^\Lambda_3
+/{\grave E}^\Xi_4
+\oplus{\dot F}^\Pi_5
+\ominus{\ddot G}^\Sigma_6
+\otimes{\breve H}^\Phi_7
+\oslash{\bar I}^\Psi_8
+\odot{\vec J}^{\,\Omega}_9$.
+\endgroup
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.ten b/Master/texmf-doc/doc/english/knuth/errata/errata.ten
new file mode 100644
index 00000000000..85cdca31e09
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.ten
@@ -0,0 +1,1289 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\def\curl{\mathop{\rm curl}}
+\def\cycle{{\rm cycle}}\indent
+\def\dashto{\mathrel{\hbox{-\thinspace-\kern-.05em}}}
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 2000}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all substantial corrections made to {\sl Computers
+\& Typesetting\/} from the mid-1990s until the Millennium edition was
+published at the end of the year 2000.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Changes to the mini-indexes
+and master indexes of Volumes B, D, and~E are not shown here unless they are
+not obviously derivable from what has been shown.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A3, line 14 {(in certain printings only)} (9/6/00)
+
+\tenpoint\noindent
+that
+looks like {\tt\char'15} or {\tt\char'23}.
+
+\bugonpage A8, lines 14 and 15 (9/6/00)
+
+\tenpoint\noindent
+that is not to be ignored. Notice that |\|\] is a control
+sequence of the second kind, namely a control symbol, since there is a
+single nonletter (\]) following\cutpar
+
+\bugonpage A43, line $-17$ (8/4/98)
+
+\tenpoint\noindent
+into your manuscript, if the |b|-key on your keyboard is broken. \
+(An optional\cutpar
+
+\bugonpage A88, lines 14, 16, 18, and 21 (8/12/00)
+
+\tenpoint\noindent
+[Insert two blank spaces between `{\tt blank space}' and `{\tt\char`\}}']
+
+\bugonpage A96, lines 9 and 10 (8/6/98)
+
+\ninepoint\indent
+Before 1998, some ^{German} words changed their spelling
+when split between lines. For example, `backen' became `bak-ken'
+and `Bettuch' sometimes became `Bett-\cutpar
+
+\bugonpage A107, line 2 (8/5/98)
+
+\ninepoint
+\line{\indent\spaceskip=.4em minus.35em
+ually, you might be tempted to set
+|\tolerance=10000|; this allows arbitrarily bad}
+
+\bugonpage A115, line $-19$ (8/5/98)
+
+\ninepoint\noindent
+If there's no room for such an insertion on this page, \TeX\
+will insert it at the top of\cutpar
+
+\bugonpage A119, line 15 (8/5/98)
+
+\ninepoint\noindent
+of\/ |\dimen3|, assuming that |\dimen3| is positive.
+
+\bugonpage A182, middle line of the displayed commutative diagram (12/3/99)
+
+\ninepoint
+\def\mapright#1{\smash{
+ \mathop{\longrightarrow}\limits^{#1}}}
+$$\matrix{
+ 0&\mapright{}&{\cal O}_C&\mapright\pi&
+ \pi_*{\cal O}_D&\mapright\delta&
+ R^1f_*{\cal O}_V(-D)&\mapright{}&0\cr}$$
+
+\bugonpage A233, line $-2$ (8/5/98)
+
+\ninepoint\noindent
+could avoid this by adding |\hskip| |0pt| |minus-1fil|; then
+an oversize text would\cutpar
+
+\bugonpage A277, line 1 (8/5/98)
+
+\ninepoint\indent
+\<code assignment>\is\<codename>\<8-bit number>\<equals>\<number>
+
+\bugonpage A277, line $-11$ (8/5/98)
+
+\ninepoint\noindent
+[Move this line, which defines \<at clause>, up to the top of the page.]
+
+\bugonpage A289, line 24 (2/3/97)
+
+\ninepoint\indent
+\<math field>\is\<filler>\<math symbol>\alt\<filler>|{|\<math mode material>|}|
+
+\bugonpage A309, line 3 (8/12/97)
+
+\ninepoint
+\ansno8.4:
+|$|$_{3}$ |x|$_{11}$ |^|$_7$ |2|$_{12}$ |$|$_{3}$ |~|$_{13}$ \]$_{10}$
+\cstok{TeX} |b|$_{11}$ |v|$_{11}$ \]$_{10}$. The final space comes from
+the\cutpar
+
+\bugonpage A313, line 24 (9/19/00)
+
+\ninepoint\noindent
+stands for `|\par\vfill...|', so the next three commands are
+
+\bugonpage A313, line 27 (9/19/00)
+
+\ninepoint\indent
+|{vertical mode: \par}|
+
+\bugonpage A318, lines 12 and 13 (8/5/98)
+
+\ninepoint\noindent\hbox to\parindent{\hfil\bf15.8.\enspace}%
+|\advance\dimen2 by\ifnum\dimen2<0 -\fi.5\dimen3|\parbreak
+|\divide\dimen2 by\dimen3 \multiply\dimen2 by\dimen3|
+
+\bugonpage A325, line 22 (12/3/99)
+
+\ninepoint
+| 0&\mapright{}&{\cal O}_C&\mapright\pi&|
+
+\bugonpage A337, line 3 from the bottom (9/6/00)
+
+\rightline{\eightss DONALD E. KNUTH, {\eightssi The \TeX book\/} (1984)}
+
+\bugonpage A348, lines 14--16 (8/6/98)
+
+\ninepoint\noindent
+| \def\@if#1{true}{\let#1=\iftrue}%|\par\noindent
+| \expandafter\expandafter\expandafter|\par\noindent
+| \def\@if#1{false}{\let#1=\iffalse}%|\par\noindent
+
+\bugonpage A356, line 21 (8/6/98)
+
+\ninepoint\noindent
+|\def\AA{\leavevmode\setbox0=\hbox{!}\dimen@=\ht0 \advance\dimen@ by-1ex|
+
+\bugonpage A356, lines 9--21 from the bottom (8/6/98)
+
+\ninepoint
+{\parindent=0pt
+|\def\S{\mathhexbox278} \def\P{\mathhexbox27B} \def\Orb{\mathhexbox20D}|\par
+\smallskip
+|\def\oalign#1{\leavevmode\vtop{\baselineskip0pt \lineskip.25ex|\par
+| \ialign{##\crcr#1\crcr}}} \def\o@lign{\lineskiplimit=0pt \oalign}|\par
+|\def\ooalign{\lineskiplimit=-\maxdimen \oalign} % chars over each other|\par
+|{\catcode`p=12 \catcode`t=12 \gdef\\#1pt{#1}} \let\getf@ctor=\\|\par
+|\def\sh@ft#1{\dimen@=#1 \kern\expandafter\getf@ctor\the\fontdimen1\font|\par
+| \dimen@} % kern by #1 times the current slant|\par
+|\def\d#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{-1ex}.\hidewidth}}}|\par
+|\def\b#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{-3ex}%|\par
+| \vbox to.2ex{\hbox{\char'26}\vss}\hidewidth}}}|\par
+|\def\c#1{{\setbox0=\hbox{#1}\ifdim\ht0=1ex \accent'30 #1%|\par
+| \else\ooalign{\unhbox0\crcr\hidewidth\char'30\hidewidth}\fi}}|\par
+|\def\copyright{{\ooalign{\hfil\raise.07ex\hbox{c}\hfil\crcr\Orb}}}|\par
+}
+
+\bugonpage A364, line 9 (8/9/98)
+
+\ninepoint\noindent
+|\def\makefootline{\baselineskip=24pt \lineskiplimit=0pt|\par\noindent
+| \line{\the\footline}}|
+
+
+\bugonpage A364, line 4 from the bottom (8/6/98)
+
+\ninepoint\noindent
+|\def\fmtversion{3.1415926} % identifies the current format|
+
+\bugonpage A447, bottom line (6/3/98)
+
+\rightline{\eightss--- JOHN SMITH, {\eightssi The Printer's Grammar\/}\enspace
+ (1755)}
+
+\bugonpage A450, lines 11--13 (4/12/98)
+
+\def\\#1{$_{\kern\scriptspace#1}$}%
+\tenpoint\noindent
+between `|e|' and `|n|' there are five relevant values
+in this case (2~from {\tt\\0h\\0e\\2n\\0},
+0~from {\tt\\0h\\0e\\0n\\0a\\4},
+0~from {\tt\\0h\\0e\\0n\\5a\\0t\\0},
+1~from {\tt\\1n\\0a\\0},
+and 0~from {\tt\\0n\\2a\\0t\\0}); the maximum of these is~2.
+The result of all the maximizations is
+
+\bugonpage A453, line 6 (8/5/98)
+
+\ninepoint\noindent
+tion dictionary, except that plain \TeX\ blocks hyphens after the
+very first letter or be-\cutpar
+
+\bugonpage A458, left column (9/6/00)
+
+\eightpoint
+\leavevmode{\tt\rlap<\char`\_}, 45, 135, 368--369; {\sl see also\/} |\le|.\par
+\leavevmode{\tt\rlap/=}, 45, 135, 368--369; {\sl see also\/} |\ne|.\par
+\leavevmode{\tt\rlap>\char`\_}, 45, 135, 368--369; {\sl see also\/} |\ge|.
+
+\bugonpage A458, right column (7/5/99)
+
+\eightpoint
+{\tt\char'13} and {\tt\char'14}, 135, 343, 368--369, 429;\par
+al-Khw\^arizm\^\i, abu `Abd All\^ah Mu\d{h}ammad ibn M\^us\^a, 53.
+
+\bugonpage A464, right column (8/6/98)
+
+\eightpoint
+\newbox\astbox \setbox\astbox=\hbox to0pt{\hss\lower1pt\hbox{*}}
+\def\prim#1{\par\indent\copy\astbox{\tt\char`\\#1}}
+\prim{edef}, {\it215--216}, 275, {\it328}, {\it373--374}.
+
+\bugonpage A466, right column (8/8/98)
+
+\eightpoint
+|\getfactor|, {\it356}, $\underline{375}$, {\it398}.
+
+\bugonpage A467, right column (8/5/98)
+
+\eightpoint
+\prim{hfilneg}, 72, 100, 283, 285, 290, 397.
+
+\bugonpage A469, left column (8/5/98)
+
+\eightpoint
+italic type, 13--14, 100, 127, 165, 409, 428, 430.
+
+\bugonpage A469--A477, passim (5/13/98)
+
+\eightpoint\noindent
+Add page 272 to the index entries for |\lastskip|, |\pagedepth|,
+|\pagefilllstretch|,\hfil\break |\pagefillstretch|, |\pagefilstretch|,
+|\pagegoal|, |\pageshrink|, |\pagestretch|, |\pagetotal|,\hfil\break
+|\parshape|, |\prevdepth|, and |\spacefactor|.\par
+\smallskip\noindent Also change `369' to `370' in the index entries for
+|\lbrack|, |\lq|, |\rbrack|, |\rq|, |\sb|, and |\sp|.\par
+\smallskip\noindent Also change `Luckombe, Philip' to `Smith, John'.\par
+
+\bugonpage A472, right column (8/6/98)
+
+\eightpoint
+\prim{noexpand}, $\underline{209}$, $\underline{213}$, 215, 216,
+ {\it377}, {\it424}.
+
+\bugonpage A473, left column (8/6/98)
+
+\eightpoint
+|\Orb| ( \Orb\ ), $\underline{356}$.
+
+ % volume B
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Bix, line 16 (1/16/00)
+
+\tenpoint\textindent{\bull}``Word hy-phen-a-tion by com-put-er''
+by Franklin Mark Liang, Stan-\cutpar
+
+\bugonpage Bxiv, line 13 (4/19/96)
+
+\tenpoint\noindent preprocessor converts these into numeric constants that are
+256 or more. This\cutpar
+
+\bugonpage Bxiv, line $-1$ (4/19/96)
+
+\ninepoint\noindent This file contains one line per string, starting with
+string number 256, then number 257,\cutpar
+
+\bugonpage Bxv, lines 10 and 11 (4/19/96)
+
+\ninepoint\noindent
+In this case, occurrences of |""| in the |WEB| program will be replaced by
+256; occurrences of |"This longer string"| will be replaced by 257.
+The symbol |@$| stands for the numeric\cutpar
+
+\hsize=35pc
+\bugonpage B2, line $-10$ (3/8/95)
+
+\def\RQ/{{\char'23}} % right quote in a string
+\ninepoint\noindent\quad
+{\bf define} $\\{banner}\equiv\hbox{\tt\RQ/This\]is\]TeX,\]%
+ Version\]3.14159\RQ/}$\quad$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B169, line 13 (9/22/95)
+
+\tenpoint\noindent
+something in a ``muskip'' register, or to one of the
+three parameters \hbox{\tt\char`\\thinmuskip},
+\hbox{\tt\char`\\medmuskip},\cutpar
+
+\bugonpage B221, line 9 (3/4/95)
+
+\ninepoint\noindent
+\quad{\bf define} $\\{non\_address}=0$\quad
+$\{\,$a spurious \\{bchar\_label}$\,\}$
+
+\bugonpage B221, line 17 (3/4/95)
+
+\ninepoint\noindent
+\\{font\_params}: {\bf array}[\\{internal\_font\_number}] {\bf of}
+ \\{font\_index};\quad$\{\,$how many font parameters are present$\,\}$
+
+\bugonpage B256, insert new line 12 before the bottom (3/7/95)
+
+\ninepoint\noindent\qquad
+\\{glue\_temp}: \\{real};\quad $\{\,$glue value before rounding$\,\}$
+
+\bugonpage B258, line 11 before the bottom becomes four lines (3/7/95)
+
+\ninepoint\noindent
+{\tenbf 625.}\quad{\bf define} $\\{billion}\equiv
+ \\{float\_constant}(1000000000)$\par\noindent
+{\bf define} $\\{vet\_glue}(\hbox{\tt\char`\#})\equiv
+ \\{glue\_temp}\gets\hbox{\tt\char`\#}$;\par\noindent
+\qquad{\bf if\/} $\\{glue\_temp}>\\{billion}$
+ {\bf then} $\\{glue\_temp}\gets\\{billion}$\par\noindent
+\qquad{\bf else if\/} $\\{glue\_temp}<-\\{billion}$
+ {\bf then} $\\{glue\_temp}\gets-\\{billion}$\smallskip\noindent
+$\langle\,$Move right or output leaders{\sevenrm\kern.5em625}$\,\rangle\equiv$
+
+\bugonpage B258, lines 3--6 from the bottom (3/7/95)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{vet\_glue}(\\{float}(\\{glue\_set}
+ (\\{this\_box}))*\\{stretch}(g))$;\par\noindent
+\qquad\qquad$\\{rule\_wd}\gets\\{rule\_wd}+
+ \\{round}(\\{glue\_temp})$;\par\noindent
+\qquad\qquad{\bf end};\par\noindent
+\qquad\quad{\bf end}\par\noindent
+\qquad{\bf else if\/} $\\{shrink\_order}(g)=\\{g\_order}$
+ {\bf then}\par\noindent
+\qquad\quad{\bf begin} $\\{vet\_glue}(\\{float}(\\{glue\_set}
+ (\\{this\_box}))*\\{shrink}(g))$;\par\noindent
+\qquad\quad$\\{rule\_wd}\gets\\{rule\_wd}-\\{round}(\\{glue\_temp})$;
+
+\bugonpage B260, line 13 from the bottom (6/26/93)
+
+\ninepoint
+\noindent\hskip10pt
+$\\{doing\_leaders}\gets\\{outer\_doing\_leaders}$; \
+$\\{dvi\_v}\gets\\{save\_v}$; \
+$\\{dvi\_h}\gets\\{save\_h}$; \
+$\\{cur\_v}\gets\\{base\_line}$;
+
+\bugonpage B261, insert new line after line 7 (3/7/95)
+
+\ninepoint\noindent\qquad
+\\{glue\_temp}: \\{real};\quad $\{\,$glue value before rounding$\,\}$
+
+\bugonpage B262, lines 3--6 from the bottom (3/7/95)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{vet\_glue}(\\{float}(\\{glue\_set}
+ (\\{this\_box}))*\\{stretch}(g))$;\par\noindent
+\qquad\qquad$\\{rule\_ht}\gets\\{rule\_ht}+
+ \\{round}(\\{glue\_temp})$;\par\noindent
+\qquad\qquad{\bf end};\par\noindent
+\qquad\quad{\bf end}\par\noindent
+\qquad{\bf else if\/} $\\{shrink\_order}(g)=\\{g\_order}$
+ {\bf then}\par\noindent
+\qquad\quad{\bf begin} $\\{vet\_glue}(\\{float}(\\{glue\_set}
+ (\\{this\_box}))*\\{shrink}(g))$;\par\noindent
+\qquad\quad$\\{rule\_ht}\gets\\{rule\_ht}-\\{round}(\\{glue\_temp})$;
+
+\bugonpage B264, line 22 (6/26/93)
+
+\ninepoint
+\noindent\hskip10pt
+$\\{doing\_leaders}\gets\\{outer\_doing\_leaders}$; \
+$\\{dvi\_v}\gets\\{save\_v}$; \
+$\\{dvi\_h}\gets\\{save\_h}$; \
+$\\{cur\_h}\gets\\{left\_edge}$;
+
+\bugonpage B297, line 11 (3/7/95)
+
+\ninepoint\noindent
+\qquad $\\{width}(p)\gets\\{mu\_mult}(\\{width}(p))$; \
+ $\\{subtype}(p)\gets\\{explicit}$;
+
+\bugonpage B309, line 7 (9/22/95)
+
+\ninepoint\noindent
+\qquad {\bf if} $\\{cur\_style}<\\{text\_style}$ {\bf then}
+ \quad$\{\,$display style$\,\}$
+
+\bugonpage B356, line $-5$ (3/4/95)
+
+\tenpoint\noindent
+$\\{hang\_after}=1$, and $\\{hang\_indent}=0$.
+Note that if $\\{hang\_indent}=0$, the value of $\\{hang\_after}$ is\cutpar
+
+\bugonpage B388, bottom line (3/4/95)
+
+\ninepoint\noindent
+\quad {\bf if\/} $\\{bchar\_label}[\\{hf}]\ne\\{non\_address}$ {\bf then}\quad
+ $\{\,$put left boundary at beginning of new line$\,\}$
+
+\bugonpage B406, line 10 (5/1/98)
+
+\ninepoint\noindent
+\qquad$q\gets p$;\quad$\{\,$now node $q$ represents $p_1\ldots p_{l-1}\,\}$
+
+\bugonpage B503, line 12 (3/4/95)
+
+\tenpoint\noindent
+of the following procedure. (Exception: The tabskip
+glue isn't trapped while preambles are being scanned.)
+
+\bugonpage B529, line 12 (3/4/95)
+
+\ninepoint\noindent\quad
+\\{undump}(0)($\\{fmem\_ptr}-1$)(\\{bchar\_label}[$k$]);\par\noindent\quad
+\\{undump}(\\{min\_quarterword})(\\{non\_char})(\\{font\_bchar}[$k$]);
+
+\bugonpage B531, line 2 (11/23/98)
+
+\tenpoint\noindent
+from appearing again.
+
+\bugonpage B531, line 14 (11/23/98)
+
+\ninepoint\noindent
+\quad \\{print\_int}(\\{year}); \ \\{print\_char}(|"."|); \
+ \\{print\_int}(\\{month}); \ \\{print\_char}(|"."|); \
+ \\{print\_int}(\\{day});
+
+\bugonpage B534, insert new material between lines $-16$ and $-15$ (3/20/95)
+
+\ninepoint\noindent
+\quad {\bf while} $\\{input\_ptr}>0$ {\bf do}\par\noindent
+\qquad {\bf if\/} $\\{state}=\\{token\_list}$ {\bf then} \\{end\_token\_list}
+ {\bf else} \\{end\_file\_reading};
+
+\bugonpage B534, line $-2$ (3/20/95)
+
+\ninepoint\noindent
+\qquad $\\{temp\_ptr}\gets\\{cond\_ptr}$; \
+ $\\{cond\_ptr}\gets\\{link}(\\{cond\_ptr})$; \
+ $\\{free\_node}(\\{temp\_ptr},\\{if\_node\_size})$;
+
+\bugonpage B535, line 9 (3/20/95)
+
+\ninepoint\noindent
+\qquad {\bf begin init for} $c\gets\\{top\_mark\_code}$ {\bf to}
+ \\{split\_bot\_mark\_code} {\bf do}\par\noindent
+\qquad\qquad {\bf if\/} $\\{cur\_mark}[c]\ne\\{null}$ {\bf then}
+ $\\{delete\_token\_ref}(\\{cur\_mark}[c])$;\par\noindent
+\qquad\quad \\{store\_fmt\_file}; \ {\bf return}; \ {\bf tini}
+
+\bugonpage B581, Zabala entry (8/19/00)
+
+\eightpoint\noindent
+Zabala Salelles, Ignacio Andr\'es:\quad 2.
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C17, lines 12 and 13 (9/6/00)
+
+\tenpoint
+{\bf draw} $z_4\{\curl0\}\to z_2\{z_3-z_4\}\to\{\curl0\}\,z_3$;\par
+{\bf draw} $z_4\{\curl2\}\to z_2\{z_3-z_4\}\to\{\curl2\}\,z_3$
+
+\bugonpage C23, line $-7$ (8/5/98)
+
+\ninepoint\indent
+$x_1=ss=w-x_5$;\quad$y_3-y_1=\\{ygap}$
+
+\bugonpage C69, line 17 (9/6/00)
+
+\ninepoint\noindent
+|"abra"|, while
+$p_1$ is `$(0,0)\to(3,3)$' and $p_2$ is `$(0,0)\to(3,3)\to\cycle$'.
+
+\bugonpage C94, line $-11$ (3/4/95)
+
+\ninepoint\noindent
+put
+are assumed to have square pixels. But if, for
+example, the {\bf mode\_def} sets\cutpar
+
+\bugonpage C107, line 15 (3/4/95)
+
+\ninepoint
+{\bf labels}$(1a,1b,2a,2b,3a,3b,4a,4b,\,${\bf range} 1 {\bf thru} 36);
+ \ {\bf endchar\/};
+
+\bugonpage C123, lines 21 and 22 (12/19/95)
+
+\chardef\circc=34 % rotated quartercircle
+\def\chapno{ 14} \exno=2 % for exercise 14.3!
+\dangerexercise
+Use a {\sl rotated\/} quarter-circle to produce `{\manual\circc}\kern1pt'
+in font position `{\tt c}'.
+
+\bugonpage C129, lines 6--17 (8/5/98)
+
+\ninepoint
+\beginsyntax
+<path primary>\is<pair primary>\alt<path variable>
+ \alt[(]<path expression>[)]
+ \alt[reverse]<path primary>
+ \alt[subpath]<pair expression>[of]<path primary>
+<path secondary>\is<pair secondary>\alt<path primary>
+ \alt<path secondary><transformer>
+<path tertiary>\is<pair tertiary>\alt<path secondary>
+<path expression>\is<pair expression>\alt<path tertiary>
+ \alt<path subexpression><direction specifier>
+ \alt<path subexpression><path join>[cycle]
+<path subexpression>\is<path expression>
+ \alt<path subexpression><path join><path tertiary>
+\endsyntax
+
+\bugonpage C134, line 8 (3/4/95)
+
+\ninepoint\noindent
+of~$p$; if $t\le 0$, precontrol~$t$ of~$p$ is~$z_0$.
+In particular, if $t$ is an integer, postcontrol~$t$ of~$p$\cutpar
+
+\bugonpage C139, illustration (8/5/98)
+
+\eightpoint\noindent
+[Remove the labels {\tt 2r}, {\tt 2}, and {\tt 2l} below their dots.]
+
+\bugonpage C143, top two lines (3/4/95)
+
+\danger In order to have some transform variables to work with, it's necessary
+to `^{hide}' some declarations and commands before giving the next |expr|s:
+
+\bugonpage C147, lines 14, 16, and 19 (9/6/00)
+
+\noindent
+[Change `{\bf savepen}' to `{\it savepen}'.]
+
+\bugonpage C147, line 2 from the bottom (9/6/00)
+
+\ninepoint\noindent
+{\manual lmnj}'s {\bf penrazor} stands for
+`{\bf makepen} $\bigl((-.5,0)\dashto(.5,0)\dashto \cycle\bigr)$',
+and {\bf pensquare}\cutpar
+
+\bugonpage C171, line 19 (8/5/98)
+
+\ninepoint\noindent
+(\<path tertiary>) and
+(\<pair tertiary>). A pair expression is not considered to\cutpar
+
+\bugonpage C172, line 14 (8/5/98)
+
+\tenpoint\noindent
+been evaluated and changed to numeric tokens before being
+substituted for~$s$.\cutpar
+
+\bugonpage C175, line 23 (1/11/88)
+
+\ninepoint\noindent
+expand into a sequence of tokens. \
+(The language {\eightrm{SIMULA67}} demonstrated that it is\cutpar
+
+\bugonpage C206, minor changes to lines $-19$ to $-5$ (3/4/95)
+
+\vbox to70mm{\ninepoint
+\beginlines \advance\hsize.71pt
+|Path at line 15, before subdivision into octants:|
+|(1.53745,9.05345)..controls (1.53745,4.00511) and (5.75409,-0.00049)|
+| ..(10.85147,-0.00049)..controls (16.2217,-0.00049) and (20.46255,4.51297)|%
+ \kern.5em\null
+| ..(20.46255,9.94655)..controls (20.46255,14.99713) and (16.23842,19.00049)|
+ \kern-.71pt
+| ..(11.13652,19.00049)..controls (5.77066,19.00049) and (1.53745,14.48491)|%
+ \kern.5em\null
+| ..cycle|
+\smallskip
+|Cycle spec at line 15, after subdivision:|
+|(1.53745,9.05345) % beginning in octant `SSE'|
+| ..controls (1.53745,6.58786) and (2.54324,4.371)|
+| ..(4.16621,2.74803) % segment 0|
+|% entering octant `ESE'|
+| ..controls (5.8663,1.04794) and (8.24362,-0.00049)|
+| ..(10.85147,-0.00049) % segment 0|
+|% entering octant `ENE'|
+\endlines
+$\ldots$ and so on; there are lots more numbers! What does this all mean?
+Well, the first segment of the curve, from $(1.53745,9.05345)$ to
+$(10.85147,-0.00049)$,
+has been\cutpar}
+
+\bugonpage C207, minor changes to lines 1--23 (3/4/95)
+
+\ninepoint
+\begingroup\let\HRULE=\hrule \def\hrule{\HRULE width\hsize}
+\beginlines
+|Cycle spec at line 15, after subdivision and autorounding:|
+|(2,9.05348) % beginning in octant `SSE'|
+| ..controls (2,6.50526) and (3.02194,4.22272)|
+| ..(4.6577,2.58696) % segment 0|
+|% entering octant `ESE'|
+| ..controls (6.2624,0.98225) and (8.45786,0)|
+| ..(10.85873,0) % segment 0|
+|% entering octant `ENE'|
+\endlines
+Point $(1.53745,9.05345)$, where there was a vertical tangent, has been
+rounded to $(2,9.05348)$; point $(10.85147,-.00049)$, where there was
+\vadjust{\goodbreak}%
+a horizontal tangent, has been rounded to $(10.85873,0)$; the intermediate
+control points have been adjusted accordingly. \ (Rounding of $x$~coordinates
+has been done separately from $y$~coordinates.) \ Finally, with
+$\\{autorounding}=2$, additional adjustments are made so that the
+$45^\circ$ transition point will occur at what \MF\ thinks is a good spot:
+\beginlines
+|Cycle spec at line 15, after subdivision and double autorounding:|
+|(2,9.05348) % beginning in octant `SSE'|
+| ..controls (2,6.6761) and (3.07103,4.42897)|
+| ..(4.78537,2.71463) % segment 0|
+|% entering octant `ESE'|
+| ..controls (6.46927,1.03073) and (8.62749,0)|
+| ..(10.85873,0) % segment 0|
+|% entering octant `ENE'|
+\endlines
+(Notice that $4.78537+2.71463=7.50000$; when the slope
+is~$-1$ at a transition point\cutpar
+\endgroup
+
+\bugonpage C210, line $-7$ (8/5/98)
+
+\ninepoint\indent\qquad\alt\<numeric token primary>
+
+\bugonpage C210, line $-2$ (8/5/98)
+
+\ninepoint\indent\<numeric token primary>\is\<numeric token>\thinspace
+{\tt/}\thinspace\<numeric token>
+
+\bugonpage C211, line 16 (8/5/98)
+
+\ninepoint\indent\qquad\alt\<numeric token primary not followed by
+{\tt+} or {\tt-} or a numeric token>
+
+\bugonpage C213, lines 17--27 (8/5/98)
+
+\ninepoint
+\beginsyntax
+<path primary>\is<pair primary>\alt<path variable>\alt<path argument>
+ \alt[(]<path expression>[)]
+ \alt[begingroup]<statement list><path expression>[endgroup]
+ \alt[makepath]<pen primary>\alt[makepath]<future pen primary>
+ \alt[reverse]<path primary>
+ \alt[subpath]<pair expression>[of]<path primary>
+<path secondary>\is<pair secondary>\alt<path primary>
+ \alt<path secondary><transformer>
+<path tertiary>\is<pair tertiary>\alt<path secondary>
+<path subexpression>\is<path expression>
+ \alt<path subexpression><path join><path tertiary>
+\endsyntax
+
+\bugonpage C213, line $-4$ (8/5/98)
+
+\ninepoint\indent
+\<path expression>\is\<pair expression>\alt\<path tertiary>
+\endsyntax
+
+\bugonpage C234, line 6 (9/6/00)
+
+\ninepoint\noindent
+line~$z_1\to z_5$ that bisects $z_4\to z_2$, so it starts out in a
+south-by-southwesterly direction;\cutpar
+
+\bugonpage C246, line 5 of answer 14.15 (8/5/98)
+
+\ninepoint\indent
+\qquad/ length(postcontrol $t$ of $p$ $-$ point $t$ of $p$) {\bf enddef\/};
+
+\bugonpage C246, line 10 of answer 14.15 (8/5/98)
+
+\ninepoint\indent
+\qquad/ length(precontrol $t$ of $p$ $-$ point $t$ of $p$) {\bf enddef\/};
+
+\bugonpage C252, line $-6$ (8/5/98)
+
+\ninepoint\noindent
+$h+o$ and $\\{bot}\,y_4=-o$, so nothing needs to be done there.
+We should, however, say
+
+\bugonpage C257, large display on line 5 (3/4/95)
+
+\def\bb{$\,\left\{\vcenter\bgroup\halign\bgroup\hfil##\hfil\cr}
+\def\ee{\crcr\egroup\egroup\right\}\,$}
+\tenpoint\noindent
+\bb|boolean|\cr|numeric|\cr|pair|\cr|path|\cr
+|pen|\cr|picture|\cr|string|\cr|transform|\ee\<expression>; \
+\bb\<boolean>\cr\<numeric>\cr\<pair>\cr\<string>\cr\<transform>\ee
+ \bb|<|\cr|<=|\cr|=|\cr|<>|\cr|>=|\cr|>|\ee
+ \bb\<boolean>\cr\<numeric>\cr\<pair>\cr\<string>\cr\<transform>\ee;
+
+\bugonpage C261, line $-15$ (8/5/98)
+
+\tenpoint\textindent\bull {\it Hacks:\/} \ |gobble|, |gobbled|, |killtext|; \
+|capsule_def|; \ |numtok|.
+
+\bugonpage C286, line 15 (8/5/98)
+
+\ninepoint\noindent
+isn't entirely expanded by {\bf expandafter\/}; only \MF's first
+step in loop expansion\cutpar
+
+\bugonpage C299, line 2 (12/6/99)
+
+\ninepoint\noindent
+\begindisplay
+$\displaystyle t[u_1,\ldots,u_n]\;=\;\sum_{k=1}^n{n-1\choose k-1}
+ (1-t)^{n-k}t^{k-1}u_k,$
+\enddisplay
+
+\bugonpage C299, swap lines 11 and 12 (8/5/98)
+
+\ninepoint\begintt
+def lbrack = hide(delimiters []) lookahead [ enddef;
+let [[[ = [; let ]]] = ]; let [ = lbrack;
+\endtt
+
+\bugonpage C306, line 1 (11/4/98)
+
+\ninepoint\noindent
+| ligtable oct"013": "i" =: oct"016", "l" =: oct"017", % ffi and ffl|
+
+\bugonpage C311, line 2 (8/5/98)
+
+\ninepoint\noindent
+$\\{fine}:=4-\\{eps}$, and $\\{breadth\_}[1]:=4-\\{eps}$.
+\ (A small amount~\\{eps} has been subtracted\cutpar
+
+\bugonpage C323, line $-3$ (8/5/98)
+
+\ninepoint\noindent
+statement occurs,
+the special string `|"title "|\thinspace\&\thinspace\<title>'
+is output. \ (This is how the\cutpar
+
+\bugonpage C332, lines 22--24 (8/5/98)
+
+\ninepoint
+\item{}be replicated so that the final
+proofs will be \\{rep} times bigger than usual, and the pattern will be clipped
+slightly at the edges so that discrete pixels can be seen plainly.
+
+
+\bugonpage C341, line 23 (10/10/96)
+
+\ninepoint
+\noindent|\def\:{\setbox0=\hbox{\noboundary\char\n\noboundary}%|
+
+\bugonpage C346, left column (9/6/00)
+
+\eightpoint
+|...| (bounded join), 18--19, 127, 248, $\underline{262}$.\par
+|...| (truncation of displayed context), 44.
+
+\bugonpage C346, and throughout the index (3/7/95)
+
+\eightpoint\noindent
+(Many index entries for rules of syntax in chapters 25--26
+should have been underlined)
+
+\bugonpage C350, left column (4/24/00)
+
+\eightpoint\noindent
+Evetts, Leonard Charles, 153.
+
+\bugonpage C351, right column (9/22/97)
+
+\eightpoint\noindent
+\llap{\lower1pt\hbox{*}}%
+|intersectiontimes|, $\underline{136}$, {\it178}, 213, {\it265}, {\it294},
+{\it298}.
+
+\bugonpage C353, right column (8/5/98)
+
+\eightpoint\noindent
+\<numeric token atom>, {\it delete this entry}.\par\noindent
+\<numeric token primary>, 72, $\underline{210}$.
+
+\bugonpage C354, left column (7/26/98)
+
+\eightpoint\noindent
+Orwell, George (= Blair, Eric Arthur), 85.
+
+\bugonpage C355, right column (3/7/95)
+
+\eightpoint\noindent
+|rt|, {\it23}, {\it77}, 80, {\it103}, 147, 151, $\underline{273}$.
+
+\bugonpage C361, lines 14--15 (4/29/97)
+
+\tenpoint
+\begintt
+email: {\tt TUG@tug.org}
+internet: {\tt http://www.tug.org/}
+}
+\endtt
+
+\bugonpage C361, bottom five lines (4/29/97)
+
+\begingroup \def\TeX{T\kern-.2em\lower.5ex\hbox{E}\kern-.000em X}
+\baselineskip10pt
+\rightline{\eightssi Don't delay, subscribe today! That address again is}
+\rightline{\eightssi \TeX\ Users Group}
+\rightline{\eightssi email: \eighttt TUG\char`\@ tug.org}
+\rightline{\eightssi internet: \eighttt http://www.tug.org/}
+\smallskip
+\rightline{\eightss DONALD E. KNUTH, {\eightssi The \TeX book\/} (1996)}
+\endgroup
+
+ % Volume D
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Dix, line ix (8/19/00)
+
+\tenpoint
+\textindent{\bull}``Interfacing with graphic objects'' by
+Ignacio Andr\'es Zabala Salelles,\cutpar
+
+\hsize=35pc
+
+\bugonpage D71, line 11 of section 178 (9/13/00)
+
+\ninepoint
+\noindent\quad\qquad\qquad$\{$ previous \\{mem\_end}, \\{lo\_mem\_max},
+ and \\{hi\_mem\_min} $\}$
+
+\bugonpage D132, line 6 of section 291 (9/13/00)
+
+\tenpoint\noindent
+$$=v_n+w_n\theta_0-u_n\bigl(v_1+w_1\theta_0-u_1(v_2+\cdots
+-u_{n-2}(v_{n-1}+w_{n-1}\theta_0-u_{n-1}\theta_0)\ldots{})\bigr),$$
+
+\bugonpage D213, line 7 (9/14/00)
+
+\tenpoint\noindent
+$(-y+\epsilon,
+x+y+\epsilon\delta)$. We should therefore round as if our skewed coordinates
+were $(x+\epsilon+\epsilon\delta,y-\epsilon)$\cutpar
+
+\bugonpage D349, line 4 of section 784 (9/14/00)
+
+\ninepoint\noindent
+{\bf procedure} \\{pack\_job\_name}($s\;$: \\{str\_number});\quad
+ $\{$ $s={}$|".log"|, |".gf"|, |".tfm"|, or \\{base\_extension} $\}$
+
+\bugonpage D451, line 11 (9/14/00)
+
+\tenpoint\noindent
+{\bf 1040}.\qquad The value of \\{cur\_mod} controls the \\{verbosity} in
+the \\{print\_exp} routine: If it's \\{show\_code},\cutpar
+
+\bugonpage D464, bottom line (9/14/00)
+
+\ninepoint\noindent
+\\{long\_help\_seen}: \\{boolean};\quad$\{$ has the long {\bf errmessage}
+ help been used? $\}$
+
+\bugonpage D551, Zabala entry (8/19/00)
+
+\eightpoint\noindent
+Zabala Salelles, Ignacio Andr\'es:\quad 812.
+
+ % volume E
+\hsize=29pc
+\bugonpage Exiii, lines 3 and 4 from the bottom (7/17/98)
+
+\textindent{\bull}``Metamarks:
+Preliminary studies for a Pandora's Box of shapes''
+by Neenie Billawala, Stanford Computer Science report 1256 (Stanford,
+California,\cutpar
+
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+\def\ddashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu
+ \hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage E87, bottom line (6/4/98)
+
+\rightline{\eightss--- JOHN SMITH, {\eightssi The Printer's Grammar\/}\enspace
+ (1755)} % p129
+
+\bugonpage E95, line 16 (8/8/98)
+
+\ninepoint\noindent
+\quad$\dashto z_{1r}\dashto z_{1l}\dashto{}$%
+ {\bf subpath} $(t,0)$ {\bf of\/} $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E95, line 11 from the bottom (8/8/98)
+
+\ninepoint\noindent
+\quad$\dashto z_{1r}\dashto z_{1l}\dashto{}$%
+ {\bf subpath} $(t,0)$ {\bf of\/} $(z_{3r}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E95, line 8 from the bottom (3/6/95)
+
+\ninepoint\noindent
+{\bf cmchar} |"Extensible vertical arrow--extension module"|;
+
+\bugonpage E97, line 8 from the bottom (3/6/95)
+
+\ninepoint\noindent
+{\bf cmchar} |"Extensible double vertical arrow--extension module"|;
+
+\bugonpage E113, line 9 (3/6/95)
+
+\ninepoint\noindent
+$x_5=.5[x_4,x_6]$; \ $x_4-x_6=1.2u$; \ $\\{lft}\,x_{5r}=\hbox{hround}
+ (.5w-.5\\{curve})$;
+
+\bugonpage E113, line 10 from the bottom (3/6/95)
+
+\ninepoint\noindent
+$x_5=.5[x_4,x_6]$; \ $x_4-x_6=4.8u$; \ $\\{lft}\,x_{5r}=\hbox{hround}
+ (.5w-.5\\{max\_size})$;
+
+\bugonpage E115, line 9 (3/6/95)
+
+\ninepoint\noindent
+$x_5=.5[x_4,x_6]$; \ $x_4-x_6=1.2u$; \ $\\{lft}\,x_{5r}=\hbox{hround}
+ (.5w-.5\\{curve})$;
+
+\bugonpage E115, line 12 from the bottom (3/6/95)
+
+\ninepoint\noindent
+$x_5=.5[x_4,x_6]$; \ $x_4-x_6=4.8u$; \ $\\{lft}\,x_{5r}=\hbox{hround}
+ (.5w-.5\\{max\_size})$;
+
+\bugonpage E147, lines 11--14 from the bottom (7/7/97)
+
+\ninepoint\noindent
+$\\{pos}_3(.8[\\{hair},\\{stem}],0)$; \ $\\{pos}_4(\\{vair},-90)$; \
+ $\\{pos}_5(\\{hair},-180)$;\par\noindent
+$\\{pos}_6(\\{vair},-270)$; \ ${pos}_7(\\{stem},-360)$; \
+ $\\{pos}_8(\\{vair},-450)$; \ ${pos}_9(\\{hair},-540)$;\par\noindent
+$x_0=x_1=x_9$; \ $\\{lft}\,x_{0l}=\hbox{hround}(1.5u-.5\\{hair})$; \
+ $x_2=x_4=x_6=x_8=.5w-.25u$;\par\noindent
+$\\{rt}\,x_{3r}=\hbox{hround}(w-1.75u)$; \ $\\{rt}\,x_{7r}=\hbox{hround}(w-u)$;
+
+\bugonpage E147, line 8 from the bottom (7/7/97)
+
+\ninepoint\noindent
+$y_5=.5[y_4,y_6]$; \ $\\{top}\,y_{6r}-\\{bot}\,y_{4r}=\\{vstem}+\\{eps}$; \
+$\\{bot}\,y_8=-\\{oo}$; \ $y_7=y_9=.55[y_6,y_8]$;
+
+\bugonpage E165, line 6 (2/8/97)
+
+\ninepoint\noindent
+$y_1+.5\\{hair}=h$; \ $x_1=x_2+.75u$; \
+ $\\{pos}_1(\\{hair}+\\{dw},\hbox{angle}(2(x_1-x_2),y_1-y_2)+90)$;
+
+\bugonpage E165, line 10 (2/8/97)
+
+\ninepoint\noindent
+$x_3=.5[x_2,x_4]$; \ $x_7-.25u=.5[x_6,x_8]$; \
+ $\\{rt}\,x_{8r}=\hbox{hround}(w-.5u)$;
+
+\bugonpage E187, line 9 (3/6/95)
+
+\ninepoint\noindent
+$\\{lft}\, x_{1l}=\\{lft}\, x_{2l}=\hbox{hround}(.5w-.5\\{shaved\_stem})$; \
+ $\\{top}\, y_1=h$; \ $\\{bot}\, y_2=0$;
+
+\bugonpage E189, line 8 (3/6/95)
+
+\ninepoint\noindent
+$\\{lft}\, x_{1l}=\\{lft}\, x_{2l}=\hbox{hround}(.5w-.5\\{shaved\_stem})$; \
+ $\\{top}\, y_1=h$; \ $\\{bot}\, y_2=0$;
+
+\bugonpage E233, line 21 (3/6/95)
+
+\ninepoint\noindent
+{\bf path} $p$; \
+$\{\{${\bf interim} $\\{superness}:=\\{more\_super}$; \
+ $p=\\{pulled\_super\_arc}_l(3,4)(\\{pull})\}\}$;
+
+\bugonpage E237, line 5 (8/6/98)
+
+\ninepoint\noindent
+$\\{lft}\,x_1={\rm hround}\,.5u$; \ $x_2=w-x_1$; \
+ $y_1=y_2=\\{good}.y\,.7[\\{x\_height},\\{asc\_height}]$;
+
+\bugonpage E239, line 7 from the bottom (3/6/95)
+
+\ninepoint\noindent
+$\\{lft}\,x_{6r}=\hbox{hround}\, u$; \
+$x_7=3u$; \ $x_8=w-3.5u$; \ $\\{rt}\,x_{9l}=\hbox{hround}(w-u)$;
+
+\bugonpage E253, line 2 from the bottom (8/9/98)
+
+\ninepoint
+\line{\quad$.\,.\,z_{3e}\{\\{down}\}\,.\,.\,\{z_{5l}-z_{4l}\}z_{4e}
+ \dashto z_{5e}\dashto z_{6e}$;\hfil \% stroke}
+
+\bugonpage E263, line 21 (5/10/98)
+
+\ninepoint\noindent
+{\bf path} $p$; \
+$\{\{${\bf interim} $\\{superness}:=\\{more\_super}$; \
+ $p=\\{pulled\_super\_arc}_l(3,4)(\\{pull})\}\}$;
+
+\bugonpage E289, line 2 from the bottom (8/9/98)
+
+\ninepoint
+\line{\quad$.\,.\,z_{3e}\{\\{down}\}\,.\,.\,\{z_{5l}-z_{4l}\}z_{4e}
+ \dashto z_{5e}\dashto z_{6e}$;\hfil \% stroke}
+
+\bugonpage E291, line 18 (3/6/95)
+
+\def\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
+\ninepoint\noindent
+$x_4=\frac1/3[x_5,x_{3l}]$; \ $z_4=z_5+\\{whatever}*(15u,.1h)$;
+
+\bugonpage E297, line 17 (5/10/98)
+
+\ninepoint\noindent
+{\bf path} $p$; \
+$\{\{${\bf interim} $\\{superness}:=\\{more\_super}$; \
+ $p=\\{pulled\_super\_arc}_l(3,4)(\\{pull})\}\}$;
+
+\bugonpage E303, line 17 (5/10/98)
+
+\ninepoint\noindent
+{\bf path} $p$; \
+$\{\{${\bf interim} $\\{superness}:=\\{more\_super}$; \
+ $p=\\{pulled\_super\_arc}_l(3,4)(\\{pull})\}\}$;
+
+\bugonpage E309, line 7 from the bottom (5/8/98)
+
+\ninepoint\noindent
+\quad$y_{@0}=y_{@2l}-\\{bracket}-\\{eps}$;
+
+\bugonpage E313, line 7 from the bottom (5/8/98)
+
+\ninepoint\noindent
+\quad$y_{@0}=y_{@2l}+\\{bracket}+\\{eps}$;
+
+\bugonpage E319, line 8 (5/11/98)
+
+\ninepoint\noindent
+$\\{loop\_top}=$ {\bf if\/} \\{serifs}:
+ Vround .77$[\\{vair},\\{fudged.stem}]$ {\bf else}: \\{vair} {\bf fi};
+
+\bugonpage E373, lines 5 and 6 from the bottom (7/13/97)
+
+\ninepoint\noindent
+\quad$\\{top}\,y_{1r}=\hbox{vround}\, .95h+\\{oo}$; \
+$\\{top}\,y_{2r}=h+\\{oo}$; \ $y_3=.5h$;\par\noindent
+\quad$\\{bot}\,y_{4r}=-\\{oo}$; \
+$\\{bot}\,y_{5r}=\hbox{vround}\,.08h-\\{oo}$; \
+$y_{5l}:=\\{good}.y\, y_{5l}$; \ $x_{5l}:=\\{good}.x\,x_{5l}$;
+
+\bugonpage E381, lines 11 and 12 from the bottom (7/13/97)
+
+\ninepoint\noindent
+\quad$\\{top}\,y_{1r}=\hbox{vround}\, .93h+\\{oo}$; \
+$\\{top}\,y_{2r}=h+\\{oo}$; \ $y_3=.5h$;\par\noindent
+\quad$\\{bot}\,y_{4r}=-\\{oo}$; \
+$\\{bot}\,y_{5r}=\hbox{vround}\,.07h-\\{oo}$;
+
+\bugonpage E389, bottom two lines (8/7/98)
+
+\ninepoint\noindent
+\quad {\bf numeric} $\\{aa\_},\\{bb\_},\\{cc\_}$;
+ \ $\\{bb\_}=b/y$; \ $\\{cc\_}=c/y$;
+ \ $\\{aa\_}=a*a-\\{bb\_}*\\{bb\_}$;\par\noindent
+\quad $(a*(\\{cc\_}\mathbin{++}\hbox{sqrt}\,\\{aa\_})-\\{bb\_}*\\{cc\_})/\\{aa\_}$
+ {\bf enddef\/};
+
+\bugonpage E423, line 17 (8/8/98)
+
+\ninepoint\noindent\quad
+$x_{13}=x_{11}-.5$; \ $\\{top}\,y_{14r}=\min(\frac10/7\\{x\_height}+
+ .5\\{bulb\_diam},h)+1$; \ $\\{top}\,y_{11}=\\{x\_height}$;
+
+\bugonpage E427, line 21 (8/8/98)
+
+\ninepoint\noindent\quad
+$x_{23}=x_{21}-.5$; \ $\\{top}\,y_{24r}=\min(\frac10/7\\{x\_height}+
+ .5\\{bulb\_diam},h)+1$; \ $\\{top}\,y_{21}=\\{x\_height}$;
+
+\bugonpage E431, lines 18 and 19 (8/8/98)
+
+\ninepoint\noindent
+{\bf filldraw} $z_0\dashto(x_0,y_{2l})\dashto z_{1l}\{\\{right}\}\,.\,.\,
+ \{\\{left}\}z_{1r}$\par
+\noindent\quad$\dashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3r}\,.\,.\,\{2(x_0-x_3),y_0-y_3\}z_{5r})$
+
+\bugonpage E431, line 2 from the bottom (8/8/98)
+
+\ninepoint\line{\quad
+$\dashto z_{1l}\{\\{right}\}\,.\,.\,\{\\{left}\}z_{1r}\dashto
+ (x_0,y_{2r})\dashto{}$cycle;\hfill\% arrowhead and stem}
+
+\bugonpage E433, lines 13 and 14 (8/8/98)
+
+\ninepoint\noindent
+{\bf filldraw} $z_0\dashto(x_0,y_{2l})\dashto z_{1l}\{\\{left}\}\,.\,.\,
+ \{\\{right}\}z_{1r}$\par
+\noindent\quad$\dashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\,.\,.\,\{2(x_0-x_3),y_0-y_3\}z_{5r})$
+
+\bugonpage E433, line 2 from the bottom (8/8/98)
+
+\ninepoint\line{\quad
+$\dashto z_{1l}\{\\{left}\}\,.\,.\,\{\\{right}\}z_{1r}\dashto
+ (x_0,y_{2r})\dashto{}$cycle;\hfill\% arrowhead and stem}
+
+\bugonpage E463, line 15 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1r}\,.\,.\,z_{1l}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3r}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E463, line 3 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1r}\,.\,.\,z_{1l}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E465, line 16 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3r}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E465, line 3 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E467, line 18 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3r}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E467, line 3 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{11l}\,.\,.\,z_{12r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{13l}\{z_{19}-z_{13}\}\,.\,.\,z_{15r})$
+
+\bugonpage E483, lines 12--14 from the bottom (3/6/95)
+
+\ninepoint\noindent
+{\bf beginarithchar}(oct$\,$|"004"|); \
+{\bf pickup} \\{fine}.\\{nib}; \
+{\bf pickup} \\{rule}.\\{nib};\par
+\line{{\bf numeric} \\{del};
+ \ $\\{del}=\\{dot\_size}-\\{currentbreadth}$;\hfill
+ \% $\\{currentbreadth}=\\{fine}$}
+\noindent
+$x_3-.5\\{del}=\\{good}.x(.5w-.5\\{del})$;
+ \ $\\{center\_on}(x_3)$;\par\noindent
+$y_3+.5del=\\{good}.y(\\{math\_axis}+\\{math\_spread}[.5\\{x\_height}
+ ,.6\\{x\_height}]+.5\\{del})$;
+
+\bugonpage E485, bottom line (6/4/98)
+
+\rightline{\eightss--- JOHN SMITH, {\eightssi The Printer's Grammar\/}\enspace
+ (1755)} % p80
+
+\bugonpage E489, line 4 (8/8/98)
+
+\ninepoint\noindent
+$\\{lft}\,x_6={\rm hround}\,u$; \ $x_2=w-x_6$; \ $\\{top}\,y_8=h$; \
+ $y_8-y_4=x_2-x_6$;
+
+\bugonpage E489, line 10 (8/8/98)
+
+\ninepoint\noindent
+$\\{lft}\,x_6={\rm hround}\,u$; \ $x_2=w-x_6$; \ $\\{top}\,y_8=h$; \
+ $y_8-y_4=x_2-x_6$; \ \\{circle\_points};
+
+\bugonpage E491, line 3 from the bottom (3/6/95)
+
+\def\SH{\raise.7ex\hbox{$\scriptstyle\#$}} % sharp sign for sharped units
+\ninepoint\noindent
+\quad $\\{spread}:=2\hbox{ceiling}(\\{spread}\SH*\\{hppp}/2)+\\{eps}$;
+ \ {\bf enddef\/};
+
+\bugonpage E507, line 15 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1r}\,.\,.\,z_{1l}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3r}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E507, line 3 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{11r}\,.\,.\,z_{11l}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{13l}\{z_{19}-z_{13}\}\,.\,.\,z_{15r})$
+
+\bugonpage E509, line 17 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E509, lines 3 and 4 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E511, line 17 (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E511, lines 3 and 4 from the bottom (8/8/98)
+
+\ninepoint\noindent\quad
+$\ddashto z_{1l}\,.\,.\,z_{1r}\ddashto{}${\bf subpath} $(t,0)$ {\bf of\/}
+ $(z_{3l}\{z_9-z_3\}\,.\,.\,z_{5r})$
+
+\bugonpage E541, bottom line (2/27/97)
+
+{\bf labels}\kern.05em$(1,2,3,5,6,7,8,9,10,11,12,13,14,15)$; \ {\bf endchar};
+
+\bugonpage E568, the example of {\tt cmtex8} (4/18/96)
+
+\eightpoint\indent
+(The word `{\tt logician}' should not be hyphenated.)
+
+\bugonpage E574, left column (3/6/95)
+
+\eightpoint\indent
+\\{currentbreadth}, 483, $\underline{545}$, 546.
+
+\bugonpage E575, right column (9/10/98)
+
+Holmes, Kris Ann, vi, vii.
+
+\bugonpage E576, right column (6/4/98)
+
+\eightpoint\noindent Delete the entry for Luckombe
+
+\bugonpage E579, left column (6/4/98)
+
+\eightpoint Smith, John, 87, 485.
+
+ \bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.tex b/Master/texmf-doc/doc/english/knuth/errata/errata.tex
new file mode 100644
index 00000000000..c9ea56063c0
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.tex
@@ -0,0 +1,736 @@
+% Bugs (sigh) in Computers \& Typesetting --- the most recent errata
+
+\input manmac
+\def\.#1{\hbox{\tt#1}}
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting as of \today}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all substantial corrections made to {\sl Computers
+\& Typesetting\/} since the publication of the Millennium Edition at the close
+of the year 2000. (More precisely, it lists errors corrected
+since the 16th printing of Volume~A, the 7th printing
+of Volume~B, the 6th printing of Volume~C, the 4th printing of Volume~D,
+and the 5th printing of Volume~E.)
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Changes to the mini-indexes
+and master indexes of Volumes B, D, and~E are not shown here unless they are
+not obviously derivable from what has been shown. Some (or all) of these
+errors have been corrected in the most recent printings.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A16, line 7 from the bottom (6/30/01)
+
+\font\magnifiedfiverm=cmr5 at 10pt
+\tenpoint\indent
+Ten-point type is different from%
+ \magnifiedfiverm\ magnif{}ied f{}ive-point type.
+
+\bugonpage A17, line 7 (6/30/01)
+
+\ninepoint\indent
+fications that grow in geometric ratios---something like equal-tempered
+tuning\cutpar
+
+\bugonpage A51, lines 18--20 (6/30/01)
+
+\tenpoint\kern-6pt\noindent
+$$\openup1pt\halign{\indent#\hfil\cr
+|ff| yields ff\thinspace;$\!$\quad |fi| yields fi\thinspace;$\!$\quad
+|fl| yields fl\thinspace;$\!$\quad
+|ffi| yields ffi\thinspace;$\!$\quad |ffl| yields ffl\thinspace;\cr
+|``| yields``\thinspace;\qquad |''| yields ''\thinspace;\qquad
+|!||`| yields !`\thinspace;\qquad |?||`| yields ?`\thinspace;\cr
+|--| yields --\thinspace;\qquad |---| yields ---\thinspace.\cr}$$
+
+\bugonpage A52, line 7 from the bottom (6/30/01)
+
+\tenpoint\kern-6pt\noindent
+$$\halign{\indent\hbox to 50pt{#\hfil}&\hbox to 35pt{#\hfil}&#\hfil\cr
+|\ae,\AE|&\ae,\thinspace\AE&(Latin ligature and Scandinavian letter AE)\cr}$$
+
+\bugonpage A71, line 15 (6/30/01)
+
+\tenpoint\indent
+One of the interesting things that can happen when glue stretches and\cutpar
+
+\bugonpage A180, line 20 (6/30/01)
+
+\ninepoint\indent
+Challenge number 5:\enspace
+$\qquad\tenmath k=1.38065\times10^{-16}\rm\,erg\,K^{-1}$.
+
+\bugonpage A254, line 12 from the bottom becomes two lines (4/09/01)
+
+\ninepoint\noindent
+\begintt
+\output={\unvbox255
+ \ifnum\outputpenalty<10000 \penalty\outputpenalty\fi}
+\endtt
+
+\bugonpage A292, lines 13--16 (6/30/01)
+
+\def\s{\hskip0pt plus1pt}
+\ninepoint\textindent{$\bull$}|\mathchoice|\s
+$\langle$filler$\rangle$\s|{|\s$\langle$math mode material$\rangle$\s|}|\s
+$\langle$filler$\rangle$\s|{|\s$\langle$math mode material$\rangle$\s|}|\break
+$\langle$filler$\rangle$|{|$\langle$math mode material$\rangle$|}|
+$\langle$filler$\rangle$|{|$\langle$math mode material$\rangle$|}|.
+Four math lists, which are defined as in the
+second alternative of a \<math field>, are
+recorded in a ``choice item'' that is appended to the current list.
+
+\bugonpage A306, line 7 (6/30/01)
+
+\ninepoint\noindent
+instead of a shelf{\kern0pt}ful.
+In fact, the latter idea---to
+insert an ^{italic correction}---is prefer-\cutpar
+
+\bugonpage A308, lines 25 and 26 (6/17/02)
+
+\ninepoint
+\begintt
+\def\appendroman#1#2#3{\expandafter\def\expandafter#1\expandafter
+ {\csname\expandafter\gobble\string#2\romannumeral#3\endcsname}}
+\endtt
+
+\bugonpage A311, line 14 (12/2/02)
+
+\ninepoint\indent
+|\def\\{\if\space\next\ % assume that \next is unexpandable|
+
+\bugonpage A323, line 12 from the bottom (6/30/01)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss18.31.\enspace}%
+|$k=1.38065\times10^{-16}\rm\,erg\,K^{-1}$|.
+
+\bugonpage A364, lines 12--15 from the bottom (01/21/03)
+
+\ninepoint\noindent
+|\def\loggingall{\tracingcommands=2 \tracingstats=2|\par\noindent
+| \tracingpages=1 \tracingoutput=1 \tracinglostchars=1 |\par\noindent
+| \tracingmacros=2 \tracingparagraphs=1 \tracingrestores=1 |\par\noindent
+| \showboxbreadth=\maxdimen \showboxdepth=\maxdimen \errorstopmode}|\par
+\noindent
+|\def\tracingall{\tracingonline=1 \loggingall}|
+
+\bugonpage A364, line 5 from the bottom (01/21/03)
+
+\ninepoint\noindent
+|\def\fmtversion{3.14159265} % identifies the current format|
+
+\bugonpage A450, lines 14--16 from the bottom (12/19/02)
+
+\begingroup\def\\#1{$_{\kern\scriptspace#1}$}
+\indent\qquad{\tt s\\1tic
+ \\1exp x\\3p pi\\3a \\2i\\1a i\\2al \\2id \\1do \\1ci \\2io ou\\2 \\2us}
+\medskip\noindent
+(where subscripts that aren't shown are zero), and this yields
+$$\centerline{%
+\tt.\\0s\\0u\\1p\\0e\\0r\\1c\\0a\\0l\\1i\\0f\\0r\\0a\\0g\\1i\\0l\\4i%
+\\0s\\1t\\2i\\0c\\1e\\0x\\3p\\2i\\3a\\0l\\2i\\1d\\0o\\1c\\2i\\0o\\2u\\2s\\0.}$$
+\endgroup
+
+\bugonpage A451, line 15 (1/30/01)
+
+\tenpoint\noindent
+{\sl Connecticut Yankee\/} come out with only nine or
+ten bad hyphens:
+
+\bugonpage A451, line 23 (1/30/01)
+
+\tenpoint\noindent\begintt
+ mo-er-der-mohren-mut-ter-mar-mor-mon-u-menten-macher.
+\endtt
+
+\bugonpage A454, lines 23--30 (6/30/01)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger If a suitable starting letter is found, let it be in font~$f$.
+Hyphenation is abandoned unless the ^|\hyphenchar| of~$f$ is a number
+between 0 and~255, inclusive.
+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$.
+\par\endgroup
+
+\bugonpage A461, right column (7/08/01)
+
+\eightpoint\noindent
+\llap{*}|\char|, {\it 43--45}, 76, 86, 155, 283, $\underline{286}$,
+
+\bugonpage A466, left column (7/09/01)
+
+\eightpoint\noindent
+\llap{*}|\floatingpenalty|, $\underline{123}$--$\underline{124}$,
+ 272, 281, {\it 363}.
+
+\bugonpage A470, left column (1/21/03)
+
+\eightpoint\noindent
+|\loggingall|, $\underline{364}$.
+
+\bugonpage A473, left column (6/30/01)
+
+\eightpoint\noindent
+orphans, {\sl see\/} widow words.
+
+ % volume B
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Bvii, bottom two lines (12/20/02)
+
+\eightpoint\noindent
+all of those changes.
+I~now believe that the final bug was discovered and removed on
+20~December 2002.
+The finder's fee has converged to \$327.68.
+
+\hsize=35pc
+
+\bugonpage B2, line 10 from the bottom (12/20/02)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]3.141592\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B3, new paragraph to follow line 9 (12/20/02)
+
+\tenpoint\noindent\quad
+Incidentally, Pascal's standard \\{round} function can be problematical,
+because it disagrees with the IEEE floating-point standard.
+Many implementors have
+therefore chosen to substitute their own home-grown rounding procedure.
+
+\bugonpage B8, line 2 (5/04/01)
+
+\tenpoint\noindent
+statements will be meaningful. We insert the label
+`\\{exit}' just before the `{\bf end}' of a procedure in\cutpar
+
+\bugonpage B30, line $-4$ (5/04/01)
+
+\ninepoint\noindent
+\quad{\bf begin} \\{update\_terminal};\quad$\{\,$now the user sees
+ the prompt for sure$\,\}$
+
+\bugonpage B84, lines 22 and 27 (5/04/01)
+
+\ninepoint\noindent
+\quad$\\{ignore}=9$\quad$\{\,$characters to ignore ( |^^@| )$\,\}$\par
+\noindent
+\quad$\\{active\_char}=13$\quad$\{\,$characters that invoke
+ macros ( |~| )$\,\}$
+
+\bugonpage B139, line 20 (12/19/02)
+
+\ninepoint\noindent
+\quad{\bf begin while} $(\\{state}=\\{token\_list}) \land
+ (\\{loc}=\\{null}) \land (\\{token\_type}\ne\\{v\_template})$ {\bf do}\par
+\noindent\qquad\\{end\_token\_list};\quad$\{\,$conserve stack space$\,\}$
+
+\bugonpage B206, line 14 (10/30/02)
+
+\tenpoint\noindent
+used input files like \.{webmac.tex}.
+
+\bugonpage B206, new paragraph to follow line 22 (12/20/02)
+
+\tenpoint\noindent\quad
+The following procedures don't allow spaces to be part of
+file names; but some users seem to like names that are spaced-out.
+System-dependent changes to allow such things should probably
+be made with reluctance, and only when an entire file name that
+includes spaces is ``quoted'' somehow.
+
+\bugonpage B256, line 25 (12/20/02)
+
+\ninepoint\noindent
+\qquad\\{cur\_glue}: \\{real};\quad$\{\,$glue seen so far$\,\}$\par\noindent
+\qquad\\{cur\_g}: \\{scaled};\quad$\{\,$rounded
+ equivalent of \\{cur\_glue} times the glue ratio$\,\}$\par\noindent
+\quad{\bf begin} $\\{cur\_g}\gets0$;
+ $\\{cur\_glue}\gets\\{float\_constant}(0)$;\par\noindent
+\quad$\\{this\_box}\gets\\{temp\_ptr}$;
+ $\\{g\_order}\gets\\{glue\_order}(\\{this\_box})$;
+ $\\{g\_sign}\gets\\{glue\_sign}(\\{this\_box})$;
+
+\bugonpage B258, line 5 from the bottom (12/20/02)
+
+\ninepoint\noindent
+\quad{\bf begin} $g\gets\\{glue\_ptr}(p)$;
+ $\\{rule\_wd}\gets\\{width}(g)-\\{cur\_g}$;
+
+\bugonpage B258, bottom line (12/20/02)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{cur\_glue}\gets\\{cur\_glue}+\\{stretch}(g)$;
+ $\\{vet\_glue}(\\{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue})$;\par
+\noindent\qquad\qquad$\\{cur\_g}\gets\\{round}(\\{glue\_temp})$;
+
+\bugonpage B259, line 4 (12/20/02)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{cur\_glue}\gets\\{cur\_glue}-\\{shrink}(g)$;
+ $\\{vet\_glue}(\\{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue})$;\par
+\noindent\qquad\qquad$\\{cur\_g}\gets\\{round}(\\{glue\_temp})$;
+
+\bugonpage B259, new line to precede old line 7 (12/20/02)
+
+\ninepoint\noindent
+\quad$\\{rule\_wd}\gets\\{rule\_wd}+\\{cur\_g}$;
+
+\bugonpage B260, line 21 (12/19/02)
+
+\ninepoint\noindent
+\qquad{\bf else begin} $\\{lx}\gets\\{lr}$ {\bf div} $(\\{lq}+1)$;
+
+\bugonpage B261, line 9 (12/20/02)
+
+\ninepoint\noindent
+\qquad\\{cur\_glue}: \\{real};\quad$\{\,$glue seen so far$\,\}$\par\noindent
+\qquad\\{cur\_g}: \\{scaled};\quad$\{\,$rounded
+ equivalent of \\{cur\_glue} times the glue ratio$\,\}$\par\noindent
+\quad{\bf begin} $\\{cur\_g}\gets0$;
+ $\\{cur\_glue}\gets\\{float\_constant}(0)$;\par\noindent
+\quad$\\{this\_box}\gets\\{temp\_ptr}$;
+ $\\{g\_order}\gets\\{glue\_order}(\\{this\_box})$;
+ $\\{g\_sign}\gets\\{glue\_sign}(\\{this\_box})$;
+
+\bugonpage B262, line 10 from the bottom (12/20/02)
+
+\ninepoint\noindent
+\quad{\bf begin} $g\gets\\{glue\_ptr}(p)$;
+ $\\{rule\_ht}\gets\\{width}(g)-\\{cur\_g}$;
+
+\bugonpage B262, line 6 from the bottom (12/20/02)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{cur\_glue}\gets\\{cur\_glue}+\\{stretch}(g)$;
+ $\\{vet\_glue}(\\{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue})$;\par
+\noindent\qquad\qquad$\\{cur\_g}\gets\\{round}(\\{glue\_temp})$;
+
+\bugonpage B262, line 2 from the bottom (12/20/02)
+
+\ninepoint\noindent
+\qquad\qquad{\bf begin} $\\{cur\_glue}\gets\\{cur\_glue}-\\{shrink}(g)$;
+ $\\{vet\_glue}(\\{float}(\\{glue\_set}(\\{this\_box}))*\\{cur\_glue})$;\par
+\noindent\qquad\qquad$\\{cur\_g}\gets\\{round}(\\{glue\_temp})$;
+
+\bugonpage B263, new line to precede old line 2 (12/20/02)
+
+\ninepoint\noindent
+\quad$\\{rule\_ht}\gets\\{rule\_ht}+\\{cur\_g}$;
+
+\bugonpage B264, line 10 (12/19/02)
+
+\ninepoint\noindent
+\qquad{\bf else begin} $\\{lx}\gets\\{lr}$ {\bf div} $(\\{lq}+1)$;
+
+\bugonpage B280, lines 23 and 24 (4/08/01)
+
+\tenpoint\noindent
+or unset nodes; in particular, each mlist item appears in the
+variable-size part of \\{mem}, so the \\{type} field is always present.
+
+\bugonpage B299, line 9 (12/20/02)
+
+\ninepoint\noindent
+\qquad\qquad\quad{\bf if\/} $\\{type}(r)=\\{kern\_node}$ {\bf then}
+ \quad$\{\,$unneeded italic correction$\,\}$
+
+\bugonpage B332, line 6 (12/19/02)
+
+\tenpoint\noindent
+is being scanned, or when no alignment preamble is active.
+
+\bugonpage B332, line 8 (12/19/02)
+
+\ninepoint\noindent
+\quad{\bf begin if\/} $(\\{scanner\_status}=\\{aligning}) \lor
+ (\\{cur\_align}=\\{null})$ {\bf then}
+
+\bugonpage B382, line 6 (1/01/01)
+
+\tenpoint\noindent
+between `fl' and `y', then $m=2$, $t=2$, and $y_1$ will
+be a ligature node for `fl' followed by an\cutpar
+
+\bugonpage B386, line 11 (4/08/01)
+
+\ninepoint\noindent
+\quad$\\{qi}(2),\\{qi}(6)$: {\bf begin} $\\{cur\_r}\gets\\{rem\_byte}(q)$;%
+ \quad$\{\,$\||=:|, \||=:>|$\,\}$
+
+\bugonpage B472, new paragraph to follow line 10 (12/20/02)
+
+\tenpoint\noindent\quad
+A devious user might force an \\{endv} command to occur just about anywhere;
+we must defeat such hacks.
+
+\bugonpage B472, replacement for what used to be line 13 (12/20/02)
+
+\ninepoint\noindent
+\quad{\bf begin} $\\{base\_ptr}\gets\\{input\_ptr}$;
+ $\\{input\_stack}[\\{base\_ptr}]\gets\\{cur\_input}$;\par\noindent
+\quad{\bf while} $(\\{input\_stack}[\\{base\_ptr}].\\{index\_field}\ne
+ \\{v\_template}) \land{}$\par\noindent
+\quad\qquad $(\\{input\_stack}[\\{base\_ptr}].\\{loc\_field}=
+ \\{null}) \land {}$\par\noindent
+\quad\qquad $(\\{input\_stack}[\\{base\_ptr}].\\{state\_field}=
+ \\{token\_list})$ {\bf do} \\{decr}(\\{base\_ptr});\par\noindent
+\quad{\bf if\/} $(\\{input\_stack}[\\{base\_ptr}].\\{index\_field}\ne
+ \\{v\_template}) \lor {}$\par\noindent
+\quad\qquad $(\\{input\_stack}[\\{base\_ptr}].\\{loc\_field}\ne
+ \\{null}) \lor {}$\par\noindent
+\quad\qquad $(\\{input\_stack}[\\{base\_ptr}].\\{state\_field}\ne
+ \\{token\_list})$ {\bf then}\par\noindent
+\qquad\\{fatal\_error}(\hbox{\tt\char'23(interwoven\]alignment\]preambles\]%
+ are\]not\]allowed)\char'23});\par\noindent
+\quad{\bf if\/} $\\{cur\_group}=\\{align\_group}$ {\bf then}
+
+\bugonpage B475, line 12 (7/01/01)
+
+\ninepoint\noindent
+\qquad{\bf end};\quad$\{\,$now we are in vertical mode,
+ working on the list that will contain the display$\,\}$
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C11, line 11 (10/11/01)
+
+\noindent
+the area below the bar to the area above it equal to
+$(\sqrt5+1)/2\approx1.61803$, the\cutpar
+
+\bugonpage C29, illustration for exercise 4.11 (9/09/01)
+
+\noindent
+[points 2 and 5 should not be labeled twice]
+
+\bugonpage C156, line 15 from the bottom (9/09/01)
+
+\ninepoint\noindent
+be the values they had upon entry to the group.)
+
+\bugonpage C171, line 16 from the bottom (6/18/02)
+
+\tenpoint
+\<loop>\is\<loop header>|:|\<loop text> {\tt endfor}
+
+\bugonpage C179, line 7 from the bottom (9/09/01)
+
+\ninepoint\noindent
+next time \MF\ gets to the end of an input line, it will stop reading
+from the\cutpar
+
+\bugonpage C204, line 3 from the bottom (7/08/01)
+
+\ninepoint\noindent
+slightly. If $\\{autorounding}>1$,
+you get even more changes: Paths are perturbed slightly\cutpar
+
+\bugonpage C238, lines 9 and 8 from the bottom (7/08/01)
+
+\ninepoint\noindent
+tance is ${\rm length}(z_4-z_1)$. But there's a slicker solution:
+Just calculate
+$$\hbox{abs ypart$((z_1-z_2)\mathbin{\rm rotated}-{\rm angle}(z_3-z_2))$.}$$
+
+\bugonpage C286, line 25 (9/09/01)
+
+\ninepoint\noindent
+problem; it would simply have put |ENDFOR| into the
+replacement text of |asts|, because\cutpar
+
+\bugonpage C289, line 7 (9/09/01)
+
+\vskip-6pt\ninepoint\begintt
+if if pair x: x>(0,0) else: false fi: A else: B fi.
+\endtt
+
+\bugonpage C292, line 10 from the bottom (9/09/01)
+
+\ninepoint\noindent
+be known by saying `{\bf if\/} known $p-q$: $p=q$ {\bf else}:~{\bf false}
+{\bf fi}'; transforms could be handled\cutpar
+
+\bugonpage C313, bottom line (6/30/01)
+
+\rightline{\eightss--- LA ROCHEFOUCAULD, {\eightssi Maximes\/}\enspace(1665)}
+
+\bugonpage C346, left column (6/18/02)
+
+\eightpoint\noindent
+\llap{*}|:|, 169, 171, 317--319.
+
+\bugonpage C346, right column (7/09/01)
+
+\eightpoint\noindent
+\llap{*}|angle|, {\it29}, {\it67}, $\underline{72}$, {\it107},
+{\it135}, 211, {\it238}.
+
+\bugonpage C352, left column (6/30/01)
+
+\eightpoint\noindent
+La Rochefoucauld, Fran\c cois VI, 313.
+
+\bugonpage C357, right column (7/08/01)
+
+\eightpoint\noindent
+\llap{*}|true|, 55, {\it64\/}--{\it65}, 170, 210.
+
+ % Volume D
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Dvii, bottom two lines (12/21/02)
+
+\eightpoint\noindent
+corporates all of those changes.
+I~now believe that the final bug was discovered on 22~January 2001,
+and removed in version 2.71828.
+The finder's fee has converged to \$327.68.
+
+\hsize=35pc
+
+\bugonpage D2, line $-17$ (12/21/02)
+
+\ninepoint\noindent
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]2.71828\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D2, lines 4 and 5 from the bottom (12/23/02)
+
+\tenpoint\noindent
+types; there are no `{\bf var}' parameters, except in the case of files
+or in the system-dependent \\{paint\_row} procedure;
+there are no tag fields on variant records; there are no \\{real} variables;
+no procedures are declared local to other procedures.)
+
+\bugonpage D8, line 2 (5/04/01)
+
+\tenpoint\noindent
+statements will be meaningful. We insert the label
+`\\{exit}' just before the `{\bf end}' of a procedure in\cutpar
+
+\bugonpage D28, line $-8$ (5/04/01)
+
+\ninepoint\noindent
+\quad{\bf begin} \\{update\_terminal};\quad$\{\,$now the user sees
+ the prompt for sure$\,\}$
+
+\bugonpage D42, replacement for lines 8--13 (12/23/02)
+
+\tenpoint\noindent\quad
+Notice that if 64-bit integer arithmetic were available,
+we could simply compute $(2^{29}*p+\nobreak q)\allowbreak\,
+\hbox{\bf div}\,(2*q)$.
+But when we are restricted to Pascal's 32-bit arithmetic we
+must either resort to multiple-precision maneuvering
+or use a simple but slow iteration. The multiple-precision technique
+would be about three times faster than the code adopted here, but it
+would be comparatively long and tricky, involving about sixteen
+additional multiplications and divisions.
+
+\bugonpage D43, line 20 (12/23/02)
+
+\tenpoint\noindent
+language or 64-bit substitute is advisable.
+
+\bugonpage D44, lines 24--26 (12/23/02)
+
+\tenpoint\noindent\quad
+Once again it is a good idea to use 64-bit arithmetic if
+possible; otherwise |take_scaled| will use more than 2\% of the running time
+when the Computer Modern fonts are being generated.
+
+\bugonpage D101, line 21 (7/08/01)
+
+\ninepoint\noindent
+\quad{\bf define} $\\{subscr\_head\_loc}(\hbox{\tt\#})\equiv\hbox{\tt\#}+1$
+\quad$\{\,$where \\{value}, \\{subscr\_head}, and \\{attr\_head} are$\,\}$
+
+\bugonpage D180, lines 22 and 23 (1/26/01)
+
+\tenpoint\noindent
+$(y,-x)$ will appear in node~$p$. Similarly, a fourth-octant
+transformation will have been applied after the transition, so
+we will have $\\{x\_coord}(q)=\hbox{$-x$}$ and $\\{y\_coord}(q)=y$.
+
+\bugonpage D184, line 18 (12/21/02)
+
+\ninepoint\noindent
+\qquad\\{chopped}: \\{integer};\quad
+$\{\,$positive if data truncated, negative if data dangerously large$\,\}$
+
+\bugonpage D184, line 25 (12/21/02)
+
+\ninepoint\noindent
+\quad{\bf if\/} $(\\{internal}[\\{autorounding}]>0)\land(\\{chopped}=0)$
+ {\bf then} \\{xy\_round};
+
+\bugonpage D184, line 27 (12/21/02)
+
+\ninepoint\noindent
+\quad{\bf if\/} $(\\{internal}[\\{autorounding}]>\\{unity})\land
+ (\\{chopped}=0)$ {\bf then} \\{diag\_round};
+
+\bugonpage D184, line 32 (12/21/02)
+
+\ninepoint\noindent
+\qquad{\bf if\/} $(\\{internal}[\\{autorounding}]\le0)\lor(\\{chopped}\ne0)$
+ {\bf then} \\{print\_spec}({\tt\char`",\]after\]subdivision\char`"})
+
+\bugonpage D185, lines 15--19 (12/21/02)
+
+\ninepoint\noindent
+\quad{\bf define} \\{procrustes}({\tt\char`#})${}\equiv{}${\bf if\/}
+ $\\{abs}(\.\#)\ge\\{dmax}$ {\bf then}\par\noindent
+\qquad\qquad\quad{\bf if\/} $\\{abs}(\.\#)>\\{max\_allowed}$ {\bf then}\par
+\noindent\qquad\qquad\qquad{\bf begin} $\\{chopped}\gets1$;\par\noindent
+\qquad\qquad\qquad{\bf if\/} $\.\#>0$ {\bf then} $\.\#\gets\\{max\_allowed}$
+ {\bf else} $\.\#\gets-\\{max\_allowed}$;\par\noindent
+\qquad\qquad\qquad{\bf end}\par\noindent
+\qquad\qquad\quad{\bf else if\/} $\\{chopped}=0$ {\bf then}
+ $\\{chopped}\gets-1$
+
+\bugonpage D185, old line 22 (12/21/02)
+
+\ninepoint\noindent
+\quad$p\gets\\{cur\_spec}$; $k\gets1$; $\\{chopped}\gets0$;
+ $\\{dmax}\gets\\{half}(\\{max\_allowed})$;
+
+\bugonpage D185, old line 28 (12/21/02)
+
+\ninepoint\noindent
+\quad{\bf if\/} $\\{chopped}>0$ {\bf then}
+
+\bugonpage D196, lines 7 and 8 (1/26/01)
+
+\tenpoint\noindent
+where $x'(t)\ge0$ we have $\\{right\_type}=%
+\\{first\_octant}$ or $\\{right\_type}=\\{eighth\_octant}$; in regions where
+$x'(t)\le0$,
+we have $\\{right\_type}=\\{fifth\_octant}$ or $\\{right\_type}=\\{fourth%
+\_octant}$.
+
+\bugonpage D511, line 17 (7/03/01)
+
+\tenpoint\noindent
+from appearing again.
+
+ % volume E
+\hsize=29pc
+
+\bugonpage E7, line 11 (12/21/02)
+
+\ninepoint\indent
+\\{hair}, \\{vair}, \\{stem}, \\{curve}, \\{ess}, \\{flare}, \\{dot\_size},
+ \\{bar}, \\{slab},
+
+\bugonpage E7, line 11 (12/21/02)
+
+\ninepoint\indent
+\\{crisp}, \\{tiny}, \\{fine};
+\medskip\noindent
+and \\{thin\_join} should not be less than \\{fine}.
+
+\bugonpage E9, line 9 (7/03/01)
+
+\tenpoint\indent
+|[92] [123] [124]) ) )|
+
+\bugonpage E19, line 19 (11/7/01)
+
+\tenpoint
+\line{\\{cap\_notch\_cut}\hskip 0pt plus1.5fil46/36\hfil31/36\hfil25/36\hfil
+24/36\hfil22/36\hskip0pt plus3fil25/36}
+
+\bugonpage E41, line 8 (12/21/02)
+
+\ninepoint\noindent\mathchardef\AM="2026 % ampersand
+\quad$\\{extra\_endchar}\gets\\{extra\_endchar}\AM
+ \.{\char`"charcode:=charcode+code\_offset;"}$;
+
+\bugonpage E53, line 7 (12/21/02)
+
+\def\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
+\ninepoint\noindent
+{\bf numeric} \\{mid\_thickness};
+ $\\{mid\_thickness}={\rm Vround}$ \frac1/3[$\\{vair},\\{stem}$];
+
+\bugonpage E377, lines 3 and 4 from the bottom (12/22/02)
+
+\newbox\shorthyf \setbox\shorthyf=\hbox{-\kern-.05em}
+\mathchardef\period=`\.
+{\catcode`\-=\active \global\def-{\copy\shorthyf\mkern3.9mu}
+ \catcode`\.=\active \global\def.{\period\mkern3mu}}
+\def\8#1{\mathrel{\mathcode`\.="8000 \mathcode`\-="8000
+ #1\unkern}} % `..' and `--'
+\ninepoint\noindent
+\qquad {\bf path} \\{p\_}; $\\{p\_}=z_{\$\$l}\{z_{@1}-z_{\$\$l}\}\8{...}
+ \\{darkness}[z_{@1},.5[z_{@2},z_{\$\$l}]]\8{...}z_{@2}$\par\noindent
+\qquad\quad$\8{---}z_{\$l}\8{--}z_{\$r}\8{--}z_{@0}\8{--}z_{\$\$r}\8{--}%
+ {\rm cycle}$;\par\noindent
+\qquad{\bf if\/} $(y_{\$\$}>y_\$) \ne ({\rm ypart}\,\hbox{\bf precontrol}\,1
+ \,\hbox{\bf of\/}\,\\{p\_} > {\rm ypart}\,\hbox{\bf postcontrol}\,1\,
+ \,\hbox{\bf of\/}\,\\{p\_})$:\par\noindent
+\qquad\quad$\\{p\_}=z_{\$\$l}\{z_{@1}-z_{\$\$l}\}\8{...}
+ \\{darkness}[z_{@1},.5[z_{@2},z_{\$\$l}]]$\par\noindent
+\qquad\qquad$\8{---}z_{\$l}\8{--}z_{\$r}\8{--}z_{@0}\8{--}z_{\$\$r}\8{--}%
+ {\rm cycle}$;\ {\bf fi}\par\noindent
+\line{\qquad {\bf filldraw} \\{p\_};\hfil \% arm and beak}
+
+\bugonpage E577, right column (12/23/02)
+
+\eightpoint\noindent
+{\bf padded}, 103--111, 117--121, $\underline{549}$.
+
+ \bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.three b/Master/texmf-doc/doc/english/knuth/errata/errata.three
new file mode 100644
index 00000000000..5f00f73b22e
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.three
@@ -0,0 +1,1898 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A--E\null, between the date of publication
+(May, 1986) and 15~June 1987.
+It also includes corrections made to
+the softcover version of {\sl The \TeX book}, beginning with the
+sixth printing (January 1986); these are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+ % volume A
+\bugonpage A7, fourth line from the bottom (6/28/86)
+
+\tenpoint\line{%
+since control sequences of the second kind always have exactly one
+symbol after}
+
+\bugonpage A35, second-last line (1/31/87)
+
+\rightline{\eightssi He may run who reads.}
+\smallskip
+\rightline{\eightss--- HABAKKUK 2\thinspace:\thinspace2 (c.~600 B.C.)}
+\smallskip
+\rightline{\eightssi He that runs may read.}
+
+\bugonpage A43, lines 8--9 (8/23/86)
+
+\tenpoint\noindent
+of Appendix B\null, which defines |%| to be a special kind of symbol so that you
+can use it for comments, defines the control sequence |\%| to mean
+a percent sign.
+
+\bugonpage A45, lines 10--13 (8/23/86)
+
+\ninepoint\noindent
+\TeX\ adds~64. Hence
+code 127 can be typed |^^?|, and
+the dangerous bend sign can be obtained by saying
+|{\manual^^?}|. However, you must change the category code of character
+127 before using it, since this character ordinarily has category~15
+(^{invalid}); say, e.g., |\catcode`\^^?=12|.
+The |^^| notation is different from |\char|, because |^^|\cutpar
+
+\bugonpage A76, line 7 (8/23/86)
+
+\ninepoint
+\noindent
+and extra space; for example, these quantities are
+$3.33333\pt$, $1.66666\pt$, $1.11111\pt$,\cutpar
+
+\bugonpage A83, bottom line (5/19/87)
+
+\tenpoint\noindent[This line should be flush right.]
+
+\bugonpage A111, 7th-last line, right-hand column (2/15/87)
+
+\ninepoint
+if $b=10000$ and $-10000<p<10000$ and $q<10000$;
+
+\bugonpage A117, second-last line (6/10/87)
+
+\eightpoint
+marks; sometimes also |$\|\||$| ($\Vert$).
+You can say, e.g., `|\footnote\dag{...}|'.
+
+\bugonpage A124, lines 6--11 (2/26/87)
+
+\begingroup \def\n{\thinspace$n$}
+\ninepoint\noindent
+of insertion; an additional `|\penalty-10000|' item is assumed
+to be present at the end of the vertical list, to ensure that a legal
+breakpoint exists.) \ Let $u$ be the natural height plus depth of that
+least-cost box, and let $r$ be the penalty associated with the optimum
+breakpoint. Decrease $g$ by~$uf$, and increase $q$ by~$r$. \ (If
+|\tracingpages||=1|, the log file should now get a cryptic message that says
+`|% split|\n\ |to| $v$|,|$u$ |p=|$r$'. For~example,
+\begintt
+% split254 to 180.2,175.3 p=100
+\endtt
+\endgroup
+
+\bugonpage A158, lines 6--8 (2/20/87)
+
+\ninepoint\noindent the
+second atom, which has subscript~$i$; the superscripts are empty except for the
+last atom, whose superscript is~$\overline{n+1}$. This superscript is
+itself a math list consisting of one atom, whose nucleus is~$n+1$; and that
+nucleus is a math list consisting of three atoms.
+
+\bugonpage A171, line 20 (1/26/86)
+
+\ninepoint\line{%
+will be surrounded by more space than there would be
+if that subformula were enclosed}
+
+\bugonpage A176, line 1 (8/23/86)
+
+\ninepoint
+You can insert `|\noalign||{|$\langle$vertical mode
+material$\rangle$|}|' just after any \kern-1pt|\cr| within\cutpar
+
+\bugonpage A248, line 17 (6/17/86)
+
+\ninepoint
+`|&|' or `|\span|' or `|\cr|', it needs some way to decide which
+alignment is involved.\cutpar
+
+\bugonpage A249, line 20 (6/17/86)
+
+\ninepoint\noindent
+line (see Chapter~8).
+If you don't want a~|\cr| at the end of a certain line,
+just type\cutpar
+
+\bugonpage A276, line 19 (1/27/86)
+
+\ninepoint\vskip-3pt
+\beginsyntax
+ \alt^|\font|<control sequence><equals><file name><at clause>
+ \alt<global assignment>
+\endsyntax
+[The bottom line of p.~276 will now move to the top of p.~277.]
+
+\bugonpage A277, lines 31--32 (1/27/86)
+
+\ninepoint
+\beginsyntax
+<font assignment>\is^|\fontdimen|<number><font><equals><dimen>
+\endsyntax
+
+\bugonpage A286, sixth-last line (4/28/87)
+
+\ninepoint\noindent
+|\sfcode| table as described in Chapter~12; characters numbered 128
+to~255 set the\cutpar
+
+\bugonpage A287, line 19 (2/15/87)
+
+\ninepoint
+\textindent{$\bull$}|\-|.\enskip
+This ``discretionary hyphen'' command is defined in Appendix H.
+
+\bugonpage A292, lines 9--10 (2/15/87)
+
+\ninepoint
+\textindent{$\bull$}|\-|.\enskip
+This command is usually equivalent to `|\discretionary{-}{}{}|'; the `|-|' is
+therefore interpreted as a ^{hyphen}, not as a minus sign.
+\ (See Appendix~H.)
+
+\bugonpage A308, lines 25--26 (6/1/87)
+
+\ninepoint\indent
+|\def\appendroman#1#2#3{\edef#1{\csname|\parbreak
+| \expandafter\gobble\string#2\romannumeral#3\endcsname}}|
+
+\bugonpage A312, lines 10--14 (8/23/86)
+
+\ninepoint
+\ansno12.11: The interline glue will be zero, and the natural height is
+$1+1-3+2=1\pt$ (because the depth of\/ |\box2| isn't included in the natural
+height); so the glue will ultimately become |\vskip-1pt| when it's set.
+Thus, |\box3| is $3\pt$ high, $2\pt$ deep, $4\pt$ wide. Its reference
+point coincides with that of\/ |\box2|; to get to the reference point
+of\/ |\box1| you go up $2\pt$ and right $3\pt$.
+
+\bugonpage A312, line 21 (8/23/86)
+
+\ninepoint\noindent
+up $4\pt$ to get to the upper left corner of
+|\box4|; then down $-1.6\pt$, i.e., up $1.6\pt$, to\cutpar
+
+\bugonpage A319, line 20 (31/3/87)
+
+\ninepoint\noindent
+make ordinary periods act like |\cdot| symbols: Just define
+|\mathcode`.| to be |"0201|,\cutpar
+
+\bugonpage A328, lines 18--19 (5/14/87)
+
+\ninepoint\noindent
+not performed
+while the expansion is taking place, and the control sequences following
+|\def| are expanded; so the result is an infinite string
+\begintt
+A\def A\def A\def A\def A\def A\def A\def A\def A...
+\endtt
+
+\bugonpage A329, lines 14--15 (8/23/86)
+
+\ninepoint
+\ansno20.5: The |##| feature is indispensable when the replacement text of
+a definition contains other definitions. For example, consider
+
+\bugonpage A356, lines 6--7 (1/30/87)
+
+\ninepoint\noindent
+| \spaceskip=.3333em \xspaceskip=.5em\relax}|\hfil\break
+|\def\ttraggedright{\tt\rightskip=0pt plus2em\relax}|
+
+\bugonpage A356, line 33 (6/1/87)
+
+\ninepoint\noindent
+| \vbox to.2ex{\hbox{\char'26}\vss}\hidewidth}}|
+
+\bugonpage A357, tenth-last line (10/13/86)
+
+\ninepoint\noindent
+|\let\sp=^ \let\sb=_ {\catcode`\_=\active \global\let_=\_}|
+
+\bugonpage A357, third-last and second-last lines (2/17/87)
+
+\ninepoint\noindent
+|\def\pr@m@s{\ifx'\next\let\nxt\pr@@@s \else\ifx^\next\let\nxt\pr@@@t|%
+\hfil\break\strut
+| \else\let\nxt\egroup\fi\fi \nxt}|
+
+\bugonpage A364, fifth-last line (1/30/87)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.3} % identifies the current format|
+
+\bugonpage A368, bottom line (2/26/86)
+
+\ninepoint
+\line{that includes the symbols
+{\tentex\char'30},~{\tentex\char1}, {\tentex\char'32}, {\tentex\char'34},
+and~{\tentex\char'35}, and he finds that this makes it much more}
+
+\bugonpage A396, line 13 (8/23/86)
+
+\ninepoint
+| \hyphenpenalty=10000 \exhyphenpenalty=10000|
+
+\bugonpage A414, line 10 (3/4/86)
+
+\ninepoint\noindent
+|\font\titlefont=cmssdc10 at 40pt % titles in chapter openings|
+
+\bugonpage A427, line 7 (2/23/86)
+
+\ninepoint\noindent
+the author's book
+{\sl Computer Modern Typefaces}.)
+
+\bugonpage A428, lines 18--20 (6/15/87)
+
+\tenpoint\noindent
+The first eight of these all have essentially the same layout;
+but |cmr5| needs no ligatures, and many of the symbols of |cmti10|
+have different shapes.
+For example, the ^{ampersand} becomes an `^{E.T.}', and the
+^{dollar} changes to ^{pound} ^{sterling}:
+
+\bugonpage A434, lines 25--28 (8/17/86)
+
+\tenpoint\noindent
+from |\nu|~($\nu$). Similarly,
+|\varsigma|~($\varsigma$) should not be confused with |\zeta|~($\zeta$).
+It turns out that |\varsigma| and |\upsilon| are almost never used in
+math formulas; they are included in plain \TeX\ primarily because they are
+sometimes needed in short Greek citations (cf.~Appendix~J).
+
+\bugonpage A447, line 32 (6/1/87)
+
+\ninepoint\noindent
+ters
+also affect mathematical typesetting:
+dimension parameters
+ \hbox{|\delimitershortfall|}\cutpar
+
+\bugonpage A455, new paragraph to follow line 9 (2/15/87)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger The control sequence ^|\-| is equivalent to
+|\discretionary{\char|$\,h$|}{}{}|, where $h$ is the
+^|\hyphenchar| of the current font, provided that $h$ lies
+between 0 and~255. Otherwise |\-| is equivalent to |\discretionary{}{}{}|.
+
+\endgroup % end the special hyphenation conventions
+
+\bugonpage A457, left column, fifth-last line (2/17/87)
+
+\eightpoint\indent\qquad 155, 201, {\it 305}, 324, $\underline{357}$, 394--395;
+
+\bugonpage A458, left column, line 6 (2/15/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\-} (discretionary hyphen), 95, 283, 287,\par
+\indent\qquad 292, $\underline{455}$.
+
+\bugonpage A458, left column, near the bottom (5/19/87)
+
+\eightpoint {\tt!} (exclamation point), 51,
+{\it 72}, 73, 75, {\it 169}.
+\nobreak\medskip\noindent[This saves a line that otherwise would make
+the index too long on page 481!]
+
+\bugonpage A458, right column, line 10 (11/27/86)
+
+\eightpoint {\tt\char`\~}
+(tilde), 38, 51, 343, $\underline{353}$; {\sl see also\/} ties.
+
+\bugonpage A458, right column (6/14/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\accent} (general accent), 9, 54, 86, 283, $\underline{286}$.
+
+\bugonpage A461, entry for boxes (3/16/87)
+
+\eightpoint boxes, 63--67, 77--83, 221--229.
+
+\bugonpage A461, entry for {\tt\char`\\centering} (1/28/86)
+
+\eightpoint {\tt\char`\\centering}, $\underline{347}$, 348, 362.
+
+\bugonpage A462, entry for \<code assignment> (1/27/86)
+
+\eightpoint \<code assignment>, $\underline{277}$.
+
+\bugonpage A464, left column, line 3 (2/15/87)
+
+\eightpoint
+discretionary hyphens, 28, 95--96, 453, $\underline{455}$.
+
+\bugonpage A465, right column, line 8 (5/3/87)
+
+\eightpoint
+expansion of expandable tokens, 212--216, 238,
+
+\bugonpage A466, entry for {\tt\char`\\font}, second line (1/27/86)
+
+\eightpoint \indent\qquad 271, $\underline{276}$.
+
+\bugonpage A466, new entry (2/3/87)
+
+\eightpoint \indent\<fontdef token>, $\underline{271}$.
+
+\bugonpage A467, entry for {\tt\char`\\hideskip} (1/28/86)
+
+\eightpoint {\tt\char`\\hideskip}, $\underline{347}$, 348, 354.
+
+\bugonpage A468, left column line 2 (2/15/87)
+
+\eightpoint\indent\qquad 351, 395, {\it 414}, 454, 455.
+
+\bugonpage A470, entry for {\tt manfnt} (1/15/86)
+
+\eightpoint {\tt manfnt}, 44, 408, 414.
+
+\bugonpage A471, entry for {\tt\char`\\medbreak} (10/13/86)
+
+\eightpoint {\tt\char`\\medbreak}, 111, 113, $\underline{353}$,
+ {\it355}, {\it419}, {\it422}.
+
+\bugonpage A471, entry for {\tt\char`\\moveright} (2/27/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\moveright}, 80--81, {\it 221}, $\underline{282}$.
+
+\bugonpage A471, entry for Mozart, second line (3/19/86)
+
+\eightpoint \indent\qquad Gottlieb (= Theophilus = Amadeus), 409.
+
+\bugonpage A472, the entry for {\tt\char`\\not} (2/12/87)
+
+\eightpoint\noindent
+[The overprinting here is intentional, since {\tt\char`\\not} is a
+character of width zero. More than a dozen people have reported this
+as an error, but it is not!]
+
+\bugonpage A477, entry for {\tt\char`\\span} (5/3/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\span}, 215, 238, $\underline{243}$, {\it244}, $\underline{245}$,
+248, 249,\par
+\indent\qquad 282, {\it330}, 385.
+
+\bugonpage A479, entry for ties, second line (11/27/86)
+
+\eightpoint \indent\qquad {\it173}, 353, {\it404}.
+
+\bugonpage A480, changes to various entries (6/14/87)
+
+\eightpoint
+\newbox\astbox \setbox\astbox=\hbox to0pt{\hss\lower1pt\hbox{*}}
+\def\prim#1{\par\indent\copy\astbox{\tt\char`\\#1}}
+\prim{underline}, {\it130--131}, 141, 291, $\underline{443}$.
+\prim{unhbox}, 120, 283, $\underline{285}$, {\it354}, {\it356}, {\it361},
+ {\it399}.
+\prim{unhcopy}, 120, 283, $\underline{285}$, {\it353}.
+\prim{unkern}, $\underline{280}$.
+\prim{unpenalty}, $\underline{280}$.
+\prim{unskip}, 222--223, $\underline{280}$, 286, {\it313}, {\it392},
+ {\it418--419}.
+\prim{unvbox}, 120, 254, $\underline{282}$, 286, {\it354}, {\it361},
+ {\it363}, {\it364}, {\it392}, {\it399}, {\it417}.
+\prim{unvcopy}, 120, $\underline{282}$, 286, {\it361}.
+\prim{vadjust}, 95, 105, 109, 110, 117, 259, $\underline{281}$, 393, 454.
+\prim{valign}, 249, 283, $\underline{285}$--$\underline{286}$, 302,
+ {\it335}, {\it397}.
+\prim{vcenter}, 150--151, 159, 170, 193, 222, 242,
+\prim{vfil}, 71, $\underline{72}$, 111, 256, 281, 286, 417.
+\prim{vfill}, 24, 25, 71, $\underline{72}$, 256--257, 281, 286.
+\prim{vfilneg}, $\underline{72}$, 111, 281, 286.\par
+|\voidb@x|, $\underline{347}$, 348.
+
+\bugonpage A481, left column (6/14/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\vss}, 71, $\underline{72}$, {\it 255}, 281, 286.
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\buginvol B, in general (7/28/86)
+
+\tenpoint\noindent
+[A number of entries were mistakenly omitted from the mini-indexes
+on the right-hand pages. Here is a combined list of all the missing
+items; you can mount it inside the back cover, say, as a secondary mini-index
+when the first one fails\dots\ ]
+
+\nobreak\medskip
+\setbox0=\vbox{\eightpoint \hsize=11pc \catcode`\_=\active \let_=\_
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+ \obeylines
+ \def\makeref #1 #2 #3#4
+ {\nn=#2 \hangindent=1em \noindent\\{#1}%
+ \if#3:: \else\unhcopy\eqbox \fi#4, \S\number\nn.\par}
+ \makeref active_base 222 =$1$
+ \makeref aux 213 =macro
+ \makeref begin_name 515 :\&{procedure}
+ \makeref big_switch 1030 =$60$
+ \makeref choice_node 689 =$15$
+ \makeref cur_boundary 271 :$0\to \\{save\_size}$
+ \makeref cur_c 724 :\\{quarterword}
+ \makeref cur_group 271 :\\{group\_code}
+ \makeref cur_i 724 :\\{four\_quarters}
+ \makeref cur_level 271 :\\{quarterword}
+ \makeref do_extension 1348 :\&{procedure}
+ \makeref dvi_buf 595 :\&{array}
+ \makeref dvi_gone 595 :\\{integer}
+ \makeref dvi_limit 595 :\\{dvi\_index}
+ \makeref dvi_offset 595 :\\{integer}
+ \makeref dvi_ptr 595 :\\{dvi\_index}
+ \makeref end_graf 1096 :\&{procedure}
+ \makeref error 82 :\&{procedure}
+ \makeref error_stop_mode 73 =$3$
+ \makeref font_base 12 =$0$
+ \makeref font_info 549 :\&{array}
+ \makeref get_token 365 :\&{procedure}
+ \makeref glue_base 222 =$2626$
+ \makeref half_buf 595 :\\{dvi\_index}
+ \makeref handle_right_brace 1068 :\&{procedure}
+ \makeref hash_base 222 =$258$
+ \makeref head 213 =macro
+ \makeref hyf_distance 921 :\&{array}
+ \makeref hyf_next 921 :\&{array}
+ \makeref hyf_num 921 :\&{array}
+ \makeref index 302 =macro
+ \makeref inf 448 :\\{boolean}
+ \makeref init_col 788 :\&{procedure}
+ \makeref init_span 787 :\&{procedure}
+ \makeref input_ln 31 :\&{function}
+ \makeref interaction 73 :$0\to 3$
+ \makeref limit 302 =macro
+ \makeref line_width 830 :\\{scaled}
+ \makeref macro_call 389 :\&{procedure}
+ \makeref main_control 1030 :\&{procedure}
+ \makeref mem 116 :\&{array}
+ \makeref mem_bot 12 =$0$
+ \makeref mem_end 118 :\\{pointer}
+ \makeref mem_top 12 =macro
+ \makeref mlist_to_hlist 726 :\&{procedure}
+ \makeref mode 213 =macro
+ \makeref mode_line 213 =macro
+ \makeref more_name 516 :\&{function}
+ \makeref mu 448 :\\{boolean}
+ \makeref name 302 =macro
+ \makeref nest 213 :\&{array}
+ \makeref off_save 1064 :\&{procedure}
+ \makeref open_log_file 534 :\&{procedure}
+ \makeref output_active 989 :\\{boolean}
+ \makeref p 498 :\\{pointer}
+ \makeref param_stack 308 :\&{array}
+ \makeref pool_file 50 :\\{alpha\_file}
+ \makeref pool_ptr 39 :\\{pool\_pointer}
+ \makeref prefixed_command 1211 :\&{procedure}
+ \makeref prev_depth 213 =macro
+ \makeref prev_graf 213 =macro
+ \makeref prev_prev_r 830 :\\{pointer}
+ \makeref print_err 73 =macro
+ \makeref r 960 :\\{trie\_pointer}
+ \makeref reconstitute 906 :\&{function}
+ \makeref resume_after_display 1200 :\&{procedure}
+ \makeref save_ptr 271 :$0\to \\{save\_size}$
+ \makeref save_stack 271 :\&{array}
+ \makeref scan_dimen 448 :\&{procedure}
+ \makeref scan_math 1151 :\&{procedure}
+ \makeref short_display 174 :\&{procedure}
+ \makeref show_node_list 182 :\&{procedure}
+ \makeref start 302 =macro
+ \makeref state 302 =macro
+ \makeref str_pool 39 :\&{packed}\ \&{array}
+ \makeref str_ptr 39 :\\{str\_number}
+ \makeref str_start 39 :\&{array}
+ \makeref tail 213 =macro
+ \makeref trap_zero_glue 1229 :\&{procedure}
+ \makeref trie 921 :\&{array}
+ \makeref trie_char 921 =macro
+ \makeref trie_link 921 =macro
+ \makeref trie_op 921 =macro
+ \makeref vlist_out 629 :\&{procedure}
+ \makeref write_loc 1345 :\\{pointer}
+ }
+\hbox{\nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}}
+
+\buginvol B, in general (4/6/87)
+
+\tenpoint\noindent[The percent signs in all the comments (for example,
+on pages 7 and 50) are in the wrong font! Change `{\tt\%}' to `\%'.]
+
+\bugonpage Bvi, bottom line, and top line of next page (10/12/86)
+
+{\hsize=29pc
+\tenpoint\noindent
+puter Science Report 1097 (Stanford, California, April 1986), 146~pp.
+\ {\it The {\sltt WEB} programs for four utility programs that are
+often used with \TeX: {\sltt POOLtype}, {\sltt TFtoPL},
+{\sltt PLtoTF}, and {\sltt DVItype}.}
+\par}
+
+\bugonpage B2, line 32 (4/22/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.2\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B7, new line after line 25 (1/28/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $\\{max\_in\_open}\ge128$ {\bf then} $\\{bad}\gets6$;
+
+\bugonpage B13, first three lines (4/7/87)
+
+\tenpoint\noindent
+The `\\{name}' parameter, which is of type `{\bf packed array
+$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
+the external file that is being opened for input or output.
+Blank spaces that might appear in \\{name} are ignored.
+
+\bugonpage B14, line 30 (4/7/87)
+
+\tenpoint\noindent
+{\bf 31.\quad}%
+The \\{input\_ln} function brings the next line of input from the specified
+file into available\cutpar
+
+\bugonpage B18, line 30 (5/22/86)
+
+\ninepoint\noindent
+\\{str\_ptr}: \\{str\_number};\quad
+$\{\,$number of the current string being created$\,\}$
+
+\bugonpage B21, first line of mini-index, right column (6/14/87)
+
+\eightpoint
+\indent\\{pool\_name}\unhcopy\eqbox|"string"|, \S11.
+
+\bugonpage B34, lines 5--6 (6/14/87)
+
+\tenpoint\noindent
+to delete a token, and/or if some fatal error
+occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\bugonpage B55, lines 12--13 (4/21/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $r=p$ {\bf then if} $\\{rlink}(p)\ne p$ {\bf then}
+ $\langle\,$Allocate entire node $p$ and {\bf goto} \\{found}%
+ {\sevenrm\kern.5em129}$\,\rangle$;
+
+\bugonpage B57, lines 25--28 (6/14/87)
+
+\tenpoint\noindent
+The first of these has $\\{font}=\\{font\_base}$, and its \\{link}
+points to the second;
+the second identifies the font and the character dimensions.
+The saving feature about oriental characters is that most of them have
+the same box dimensions. The \\{character} field of the first \\{char\_node}
+is a ``\\{charext}'' that distinguishes between graphic symbols whose
+dimensions are identical for typesetting purposes. (See the \MF\ manual.)
+Such an extension of \TeX\ would not be difficult; further details are
+left to the reader.
+
+\bugonpage B58, second line of section 136 (7/23/86)
+
+\tenpoint\noindent
+the values corresponding to `|\hbox{}|'. The \\{subtype} field is set to
+\\{min\_quarterword}, since that's\cutpar
+
+\bugonpage B66, lines 2--8 (4/21/87)
+
+\tenpoint\noindent
+location is
+more efficient than dynamic allocation when we can get away with it. For
+example, locations \\{mem\_bot} to $\\{mem\_bot}+3$ are always used to store the
+specification for glue that is `\hbox{\tt 0pt plus 0pt minus 0pt}'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Static variable-size nodes appear
+in locations \\{mem\_bot} through \\{lo\_mem\_stat\_max}, and static
+single-word nodes appear in locations \\{hi\_mem\_stat\_min} through
+\\{mem\_top}, inclusive. It is harmless to let \\{lig\_trick} and
+\\{garbage} share the same location of \\{mem}.
+
+\bugonpage B67, line 23 (4/13/87)
+
+\ninepoint\noindent\hskip30pt
+$\{\,$previous \\{mem\_end}, \\{lo\_mem\_max}, and \\{hi\_mem\_min}$\,\}$
+
+\bugonpage B71, line 17 (4/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin while} $p>\\{mem\_min}$ {\bf do}
+
+\smallskip\eightpoint\noindent[Now \\{null} can be removed from the mini-index.]
+
+\bugonpage B74, line 24 (4/15/87)
+
+\ninepoint\noindent
+{\bf procedure} \\{show\_node\_list}($p\;{:}\;\\{integer}$);\quad
+$\{\,$prints a node list symbolically$\,\}$
+
+\bugonpage B74, line 33 (4/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf while} $p>\\{mem\_min}$ {\bf do}
+
+\bugonpage B84, line 12 (2/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{relax}=0$\quad$\{\,$do nothing ( {\tt\char`\\relax} )$\,\}$
+
+\bugonpage B86, third line of section 210 (8/23/86)
+
+\tenpoint\noindent
+that their special nature is easily discernible.
+The ``expandable'' commands come first.
+
+\bugonpage B88, line 23 (5/22/86)
+
+\ninepoint\noindent
+{\bf procedure\/}\ $\\{print\_mode}(m:\\{integer})$;\quad
+$\{\,$prints the mode represented by $m\,\}$
+
+\bugonpage B93, lines 3--4 (8/17/86)
+
+{\tenpoint\parindent=1em
+In the first region we have 128 equivalents for ``active characters'' that
+act as control sequences, followed by 128 equivalents for single-character
+control sequences.
+\par}
+
+\bugonpage B130, ninth-last line (5/7/87)
+
+\tenpoint\noindent
+This variable has six possible values:
+
+\bugonpage B151, line 9 (4/22/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin if} $(\\{end\_line\_char}<0)\lor(\\{end\_line\_char}>127)$
+ {\bf then} \\{incr}(\\{limit});\par\noindent\hskip20pt
+{\bf if} $\\{limit}=\\{start}$ {\bf then}\quad
+ $\{\,$previous line was empty$\,\}$
+
+\bugonpage B160, lines 17--20 (7/28/86)
+
+\tenpoint\noindent
+{\bf 389.\quad}%
+After parameter scanning is complete, the parameters are moved to the
+\\{param\_stack}. Then the macro body is fed to the scanner; in other words,
+\\{macro\_call} places the defined text of the control sequence at the
+top of\/ \TeX's input stack, so that \\{get\_next} will proceed to read it
+next.
+
+\bugonpage B200, top line (5/5/87)
+
+\tenpoint\noindent{\bf 495.\quad}%
+ When we begin to process a new {\tt\char`\\if}, we set
+$\\{if\_limit}\gets\\{if\_code}$; then
+if\/ {\tt\char`\\or} or {\tt\char`\\else} or {\tt\char`\\fi}\cutpar
+
+\bugonpage B217, lines 15--16 (6/14/87)
+
+\tenpoint\noindent
+|DVI| format.
+
+\bugonpage B224, lines 4--7 of section 560 (10/22/86)
+
+\tenpoint\noindent
+name and area strings \\{nom} and \\{aire}, and the
+``at'' size~$s$. If $s$~is negative, it's the negative of a scale factor
+to be applied to the design size; $s=-1000$ is the normal case.
+Otherwise $s$ will be substituted for the design size; in this
+case, $s$ must be positive and less than $2048\rm\,pt$
+(i.e., it must be less than $2^{27}$ when considered as an integer).
+
+\bugonpage B224, second-last line (4/28/87)
+
+\ninepoint\noindent
+\\{done}: {\bf if} \\{file\_opened} {\bf then} \\{b\_close}(\\{tfm\_file});\par
+\noindent\hskip10pt $\\{read\_font\_info}\gets g$;
+
+\bugonpage B255, mini-index at the bottom (4/15/87)
+
+\eightpoint
+$\\{mag}=\rm macro$, \S236.
+
+\bugonpage B257, lines 11--13 (6/14/87)
+
+\ninepoint
+\noindent\hskip20pt{\bf if} $c\ge\\{qi}(128)$ {\bf then}
+ \\{dvi\_out}(\\{set1});\par
+\noindent\hskip20pt\\{dvi\_out}(\\{qo}($c$));
+
+\bugonpage B260, lines 7--8 (4/15/87)
+
+\tenpoint\noindent\hskip10pt
+In the case of \\{c\_leaders} (centered leaders), we want to increase \\{cur\_h}
+by half of the excess space not occupied by the leaders; and in the
+case of \\{x\_leaders} (expanded leaders) we increase\cutpar
+
+\bugonpage B267, mini-index at the bottom (4/15/87)
+
+\eightpoint
+\\{cur\_s}: \\{integer}, \S616.
+$\\{mag}=\rm macro$, \S236.
+$\\{pop}=142$, \S586.
+
+\bugonpage B271, line 10 (8/23/86)
+
+\tenpoint\noindent
+which will be ignored in the calculations
+because it is a highly negative number.
+
+\bugonpage B285, lines 23 and 24 (5/4/87)
+
+\tenpoint\noindent
+the current string would be `{\tt.\char`\^.\char`\_/}'
+if $p$ points to the \\{ord\_noad} for $x$ in the (ridiculous) formula
+`{\tt\char`\\sqrt\char`\{a\char`\^\char`\{\char`\\mathinner\char`\{%
+b\char`\_\char`\{c\char`\\over x+y\char`\}\char`\}\char`\}\char`\}\char`\$}'.
+
+\bugonpage B296, lines 3--5 (5/8/87)
+
+\tenpoint\noindent
+box~$b$ and
+changes it so that the new box is centered in a box of width~$w$.
+The centering is done by putting {\tt\char`\\hss} glue at the left and right
+of the list inside $b$, then packaging the new box; thus, the
+actual box might not really be centered, if it already contains
+infinite glue.
+
+\bugonpage B346, line 19 (5/19/87)
+
+\ninepoint\noindent
+\\{pass\_number}: \\{halfword};\quad
+$\{\,$the number of passive nodes allocated on this pass$\,\}$
+
+\bugonpage B350, lines 36 and 37 (1/28/87)
+
+\ninepoint\noindent
+$v$: \\{pointer};\quad
+$\{\,$points to a glue specification or a node ahead of \\{cur\_p}$\,\}$
+\par\noindent
+$t$: \\{integer};\quad
+$\{\,$node count, if \\{cur\_p} is a discretionary node$\,\}$
+
+\bugonpage B353, lines 8--22 (1/28/87)
+
+\ninepoint
+\noindent\hskip10pt$s\gets\\{cur\_p}$;\par
+\noindent\hskip10pt{\bf if} $\\{break\_type}>\\{unhyphenated}$ {\bf then}
+ {\bf if} $\\{cur\_p}\ne\\{null}$ {\bf then}\par
+\noindent\hskip30pt$\langle\,$Compute the discretionary
+ \\{break\_width} values{\sevenrm\kern.5em840}$\,\rangle$;\par
+\noindent\hskip10pt{\bf while} $s\ne\\{null}$ {\bf do}\par
+\noindent\hskip30pt\vdots\hskip30pt [as before, but indented one less notch]\par
+\noindent\hskip10pt{\bf end};
+
+\bugonpage B354, line 6 (1/28/87)
+
+\tenpoint\noindent
+will be the background plus $l_1$, so the length from \\{cur\_p} to \\{cur\_p}
+should be $\gamma+l_0+l_1-l$,
+minus the length of nodes that will be discarded after the discretionary break.
+
+\bugonpage B354, lines 12--18 (1/28/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf begin} $t\gets\\{replace\_count}(\\{cur\_p})$;\kern5pt
+ $v\gets\\{cur\_p}$;\kern5pt $s\gets\\{post\_break}(\\{cur\_p})$;\par
+\noindent\hskip10pt{\bf while} $t>0$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $\\{decr}(t)$;\kern5pt
+ $v\gets\\{link}(v)$;\kern5pt
+ $\langle\,$Subtract the width of node $v$ from \\{break\_width}%
+ {\sevenrm\kern.5em841}$\,\rangle$;\par
+\noindent\hskip20pt{\bf end};\par
+\noindent\hskip10pt{\bf while} $s\ne\\{null}$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle$;\par
+
+\bugonpage B354, new line after line 21 (1/28/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $t=0$ {\bf then} $s\gets\\{link}(v)$;\quad
+ $\{\,$more nodes may also be discardable after the break$\,\}$
+
+\bugonpage B354, lines 26--34 (1/28/87)
+
+\ninepoint\noindent
+[Change `$s$' to `$v$' throughout this section (8 times).]
+
+\bugonpage B354, line 9 from the bottom (1/28/87)
+
+\tenpoint\noindent{\bf 842.\quad}%
+\ninepoint$\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle\equiv$
+
+\bugonpage B355, lines 1--3 (1/28/87)
+
+\ninepoint
+\noindent\hskip20pt$\\{hlist\_node},\\{vlist\_node},\\{rule\_node}$:
+ $\\{break\_width}[1]\gets\\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt\\{kern\_node}: {\bf if} $(t=0)\land
+ (\\{subtype}(s)\ne\\{acc\_kern})$ {\bf then}
+ $t\gets-1$\quad$\{\,$discardable$\,\}$\par
+\noindent\hskip30pt{\bf else} $\\{break\_width}[1]\gets
+ \\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt{\bf othercases}
+ \\{confusion}({\tt\char'42 disc2\char'42})\par
+\noindent\hskip20pt{\bf endcases};\par
+\noindent\hskip10pt$\\{incr}(t)$
+
+\bugonpage B355, patches to mini-index at bottom (1/28/87)
+
+\eightpoint
+$\\{acc\_kern}=2$, \S155.\par
+$\\{incr}=\rm macro$, \S16.\par
+$t$: \\{integer}, \S830.\par
+$v$: \\{pointer}, \S830.
+
+\bugonpage B372, lines 12--14 (1/28/87)
+
+\ninepoint
+\noindent\hskip40pt$\langle\,$Change discretionary to compulsory
+ and set $\\{disc\_break}\gets\\{true}${\sevenrm\kern.5em882}$\,\rangle$\par
+\noindent\hskip30pt{\bf else if\/} $(\\{type}(q)=\\{math\_node})\lor
+ (\\{type}(q)=\\{kern\_node})$ {\bf then} $\\{width}(q)\gets0$;
+
+\bugonpage B380, fifth-last line (5/7/87)
+
+\begingroup\tenpoint\noindent\def\!{\kern-1pt}\def\.#1{\hbox{\tt#1}}
+\.b and \.c, the two patterns with and without hyphenation are
+$\.a\,\.b\,\.-\,\.{c\!d}\,\.{e\!f}$ and $\.a\,\.{b\!c}\,\.{d\!e}\,\.f$.
+Thus the\cutpar\endgroup
+
+\bugonpage B386, lines 2--4 (5/21/87)
+
+\tenpoint\noindent
+hyphenation,
+\TeX\ first looks to see if it is in the user's exception dictionary. If not,
+hyphens are inserted based on patterns that appear within the given word,
+using an algorithm due to Frank~M. Liang.
+
+\bugonpage B397, line 28 (5/21/87)
+
+\tenpoint\noindent
+$h=z-c$. It follows that location \\{trie\_max} will
+never be occupied in \\{trie}, and we will have\cutpar
+
+\bugonpage B415, the mini-index (4/6/87)
+
+\eightpoint\noindent[Delete the spurious entry for `$c$'.]
+
+\bugonpage B419, mini-index entry for \\{c} (4/6/87)
+
+\eightpoint $c$: \\{integer}, \S994.
+
+\bugonpage B422, line 24 (8/23/86)
+
+\ninepoint\noindent
+\hskip20pt\\{prev\_p}: \\{pointer};\quad
+$\{\,$predecessor of $p\,\}$
+
+\bugonpage B435, line 16 (10/12/86)
+
+\ninepoint\noindent
+\hskip20pt$\\{width}(p)\gets\\{font\_info}[k].\\{sc}$;\quad
+$\{\,$that's \\{space}$(f)\,\}$\par\noindent
+\hskip20pt$\\{stretch}(p)\gets\\{font\_info}[k+1].\\{sc}$;\quad
+$\{\,$and \\{space\_stretch}$(f)\,\}$\par\noindent
+\hskip20pt$\\{shrink}(p)\gets\\{font\_info}[k+2].\\{sc}$;\quad
+$\{\,$and \\{space\_shrink}$(f)\,\}$\par
+\smallskip\eightpoint\noindent
+[And the mini-index gets three new entries:
+$\\{space}=macro$, \S558.
+$\\{space\_shrink}=macro$, \S558.
+$\\{space\_stretch}=macro$, \S558.]
+
+\bugonpage B495, lines 18 and 19 (2/15/87)
+
+\ninepoint\noindent
+[delete these lines, since the cases cannot occur]
+
+\bugonpage B510, line 8 (12/15/86)
+
+\ninepoint\noindent\hskip30pt
+({\tt"Pretend\]that\]you're\]Hercule\]Poirot:\]Examine\]all\]clues,"})
+
+\bugonpage B527, new line to follow line 13 (6/17/86)
+
+{\tenpoint\parindent=1em
+This program doesn't bother to close the input files that may still be open.
+\par}
+
+\bugonpage B534, fourth-last line (5/4/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{write\_stream}(\hbox{\tt\char`\#})\equiv\\{info}(
+ \hbox{\tt\char`\#}+1)$\quad $\{\,$stream number (0 to 17)$\,\}$
+
+\bugonpage B544, left column (1/28/87)
+
+\eightpoint
+\leftline{\\{acc\_kern}:\quad$\underline{155}$, 191, 837, 842, 879, 1125.}
+
+\bugonpage B546, entry for \\{c} (4/6/87)
+
+\eightpoint\noindent[Add a reference to section $\underline{994}$.]
+
+\bugonpage B547, left column (4/7/87)
+
+\eightpoint
+\leftline{\\{char}:\quad 19, 26--27, 520, 534.}
+
+\bugonpage B547, left column (6/14/87)
+
+\eightpoint
+\leftline{Chinese characters:\quad 134, 585.}
+
+\bugonpage B553, entry for \\{font\_base} (6/14/87)
+
+\eightpoint\noindent[Insert a reference to section 134.]
+
+\bugonpage B555, right column, new entry (10/25/86)
+
+\eightpoint
+\leftline{{\tt Huge page...},\quad 641.}
+
+\bugonpage B556, entry for \\{incr} (1/28/87)
+
+\eightpoint\noindent[Add a reference to section 842.]
+
+\bugonpage B557, entry for \\{is\_char\_node} (1/28/87)
+
+\eightpoint\noindent[Delete the reference to section 881.]
+
+\bugonpage B557, right column (6/14/87)
+
+\eightpoint
+\leftline{Japanese characters:\quad 134, 585.}
+
+\bugonpage B560, right column (1/28/87)
+
+\eightpoint
+\leftline{\\{max\_in\_open}:\quad$\underline{11}$, 14, 304, 328.}
+
+\bugonpage B561, left column, line 10 (4/15/87)
+
+\eightpoint
+\leftline{\qquad 169--172, 174, 178, 182, 1249, 1312, 1334.}
+
+\bugonpage B561, left column (5/1/87)
+
+\eightpoint
+\leftline{{\tt Missing font identifier}:\quad 577.}
+
+\bugonpage B563, left column, line 2 (4/15/87)
+
+\eightpoint
+\leftline{\qquad 136, 145, 149--154, 164, 168--169, 175--176, 182,}
+
+\bugonpage B563, right column (6/14/87)
+
+\eightpoint
+\leftline{oriental characters:\quad 134, 585.}
+
+\bugonpage B569, right column, in appropriate places (10/12/86)
+
+\eightpoint
+\leftline{\\{space}:\quad 547, $\underline{558}$, 752, 755, 1042.}
+\leftline{\\{space\_shrink}:\quad 547, $\underline{558}$, 1042.}
+\leftline{\\{space\_stretch}:\quad 547, $\underline{558}$, 1042.}
+
+\bugonpage B570, third-last line (1/28/87)
+
+\eightpoint\noindent\qquad
+ 786, 795, 809, 819--820, 822, 837, 842--844, 866,
+
+\bugonpage B571, right column (10/25/86)
+
+\eightpoint
+\leftline{{\tt The following...deleted},\quad 641, 992, 1121.}
+
+\bugonpage B571, right column (4/7/87)
+
+\eightpoint
+\leftline{\\{text\_char}:\quad $\underline{19}$, 20, 25, 47.}
+
+\bugonpage B573, right column (5/1/87)
+
+\eightpoint\noindent
+[Delete the entry for `{\tt Undefined font code}'.]
+
+\bugonpage B576, line 2 (1/28/87)
+
+\ninepoint\noindent
+$\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle$\par
+\noindent\qquad {\eightpoint Used in section 840.}
+
+\bugonpage B591, line 6 from the bottom (1/28/87)
+
+\ninepoint\noindent
+ $\langle\,$Subtract the width of node $v$ from \\{break\_width}%
+ {\sevenrm\kern.5em841}$\,\rangle$\quad
+ {\eightpoint Used in section 840.}
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C14, top two lines (3/16/87)
+
+\danger The recursive midpoint rule for curve-drawing was discovered in 1959
+by Paul de Casteljau, who showed that the curve could be described
+algebraically by the remarkably simple formula
+
+\bugonpage C54, sixth-last to fourth-last lines (10/13/86)
+
+\ninepoint Jonathan H. Quick (a student) used `|a.plus1|' as the name
+of a variable at the beginning of his program; later he said `|let|
+|plus=+|'. How could he refer to the variable `|a.plus1|' after that?
+
+\bugonpage C76, line 14 (10/13/86)
+
+\tenpoint
+\newdimen\longesteq
+\setbox0=\hbox{\indent$z_{12}-z_{11}=z_{14}-z_{13}$\quad}
+\longesteq=\wd0
+\noindent\hbox to \longesteq{\indent
+ $x_4=w-.01\\{in}$\hfil}%
+Point 4 should be one-hundredth of an inch inside\cutpar
+
+\bugonpage C103, line 12 (10/12/86)
+
+\tenpoint
+$\\{ht}\0=\\{body\_height}\0$; \ $.5[\\{ht}\0,-\\{dp}\0]=\\{axis}\0$;
+
+\bugonpage C105, line 13 (10/13/86)
+
+\ninepoint
+The vertical line just to the right of the italic left parenthesis
+shows the italic\cutpar
+
+\bugonpage C113, lines 20--27 (8/23/86)
+
+{\catcode`\@=\active
+\def@#1@{\begingroup\def\_{\kern.04em
+ \vbox{\hrule width.3em height .6pt}\kern.08em}%
+ \ifmmode\mathop{\bf#1}\else\hbox{\bf#1\/}\fi\endgroup}
+\danger The command `@erase@ @fill@ $c$' is an abbreviation for
+`@cullit@; @unfill@~$c$; @cullit@'; this zeros out the pixel values inside
+the cyclic path~$c$, and sets other pixel values to~1 if they were positive
+before erasing took place. \ (It works because the initial @cullit@ makes
+all the values 0 or~1, then the @unfill@ changes the values inside~$c$
+to 0 or negative. The final @cullit@ gets rid of the negative values,
+so that they won't detract from future filling and drawing.) \ You can
+also use `@draw@', `@filldraw@', or `@drawdot@' with `@erase@'; for example,
+`@erase@ @draw@~$p$' is an abbreviation for `@cullit@; @undraw@~$p$;
+@cullit@', which uses the currently-picked-up pen as if it were an
+eraser applied to path~$p$.
+
+}
+
+\bugonpage C124, line 9 (6/17/86)
+
+\eightpoint
+\noindent\hskip1.8in
+$\\{branch}_2=\\{flex}((30,570),(10,590),(-1,616))$
+
+\bugonpage C130, 3rd-last line (9/25/86)
+
+\ninepoint\noindent
+{\sl Geometry\/ \bf 1} (1986), 123--140]: Given a sequence
+
+\bugonpage C144, sixth line of the program (8/23/86)
+
+\ninepoint\noindent\hbox to\parindent{\hfil\sevenrm6\ \ \ }%
+$y_2=.1h$; \ $\\{top}\,y_3=.4h$;
+
+\bugonpage C148, the line before the illustration (11/27/86)
+
+\ninepoint\noindent
+are polygons with 32 and 40 sides, respectively:
+
+\smallskip\noindent
+[New illustrations are needed here, since \MF\ version 1.3 improves
+the accuracy of pen polygons.]
+
+\bugonpage C149, 7th line after the illustration (10/24/86)
+
+\ninepoint
+\line{$(200,y+100\pm\alpha)$, where
+$\alpha=\sqrt5/4\approx0.559$. If we digitize these outlines and fill the}
+
+\bugonpage C178, second-last line (8/23/86)
+
+\ninepoint\noindent
+(If $t_3=t_1$~transum~$t_2$, then
+$z$~transformed~$t_3=z$~transformed~$t_1+z$~transformed~$t_2$,\cutpar
+
+\bugonpage C198, fifth-last and fourth-last lines (10/13/86)
+
+\ninepoint\vskip-3pt
+\begindisplay
+$\\{top}\,y_2={\rm round}(\\{top}\,\beta)$.
+\enddisplay
+Such operations occur frequently in practice, so plain \MF\ provides
+convenient\cutpar
+
+\bugonpage C212, lines 9--11 from the bottom (8/23/86)
+
+\ninepoint
+\qquad
+ \alt\[point]\<numeric expression>\[of]\<path primary>\continuerule
+ \alt\[precontrol]\<numeric expression>\[of]\<path primary>\continuerule
+ \alt\[postcontrol]\<numeric expression>\[of]\<path primary>
+
+\bugonpage C233, lines 13--14 (2/15/87)
+
+\ninepoint\noindent
+one column of white
+pixels, if the character is $2a$ pixels wide, because the right edge of
+black pixels is specified here to have the $x$~coordinate $2a-1$.
+
+\bugonpage C247, lines 23--25 (11/27/86)
+
+\ninepoint
+\ansno 16.2:
+ `{\bf pencircle} scaled 1.06060' is the diamond but
+`{\bf pencircle} scaled 1.06061' is~the square. \ (This assumes that
+$\\{fillin}=0$. If, for example, $\\{fillin}=.1$, the change doesn't
+occur until the diameter is 1.20204.) \ The next change is at diameter
+1.5, which\cutpar
+
+\bugonpage C262, lines 1--4 (7/28/86)
+
+\ninepoint
+When we come to macros whose use has not yet been explained---for
+example, somehow |softjoin| and |stop| never made it
+into Chapters 1 through~27---we shall consider them from a user's
+viewpoint. But most of the comments that follow are addressed to a
+potential base-file designer.
+
+\bugonpage C266, line 16 (8/17/86)
+
+\ninepoint\noindent
+variables; they have the side effect of changing the variable's value.
+
+\bugonpage C276, line 26 (6/23/86)
+
+\ninepoint
+\noindent
+| if charic<>0: r((w+charic*hppp,h.o_),(w+charic*hppp,.5h.o_)); fi|
+
+\bugonpage C286, lines 24--26 (10/13/86)
+
+\ninepoint\noindent
+but \MF\ won't let you. And even if this had worked, it wouldn't have
+solved the problem; it would simply have put |ENDFOR| into the
+replacement text of |ast|, because expansion is inhibited when the
+replacement text is being read.
+
+\bugonpage C290, line 1 (8/23/86)
+
+\ninepoint \noindent{\it 2.\enspace Fortuitous loops.\enspace}%
+The `^{max}' and `^{min}' macros in Appendix~B make use of the fact\cutpar
+
+\bugonpage C298, third-last line (8/23/86)
+
+\ninepoint
+$t[\,u_1,\ldots,u_n]\;=\;t\bigl[t[u_1,\ldots,u_{n-1}],t[u_2,\ldots,u_n]\,\bigr]$
+
+\bugonpage C304, 14th-last line (2/15/87)
+
+\ninepoint\noindent
+[replace this `|\smallskip|' by a |\smallskip| between lines!]
+
+\bugonpage C307, fifth-last line (12/7/86)
+
+\ninepoint
+{\def\_{\kern.04em
+ \vbox{\hrule width.3em height .6pt}\kern.08em}%
+\bf adjust\_fit}(\<left sidebearing adjustment>,\thinspace
+ \<right sidebearing adjustment>);
+
+\bugonpage C312, line 34 (10/12/86)
+
+\ninepoint\noindent
+|params[2] = "sans_params"; fontname[2] = "cmssbx10";|
+
+\bugonpage C316, lines 19--21 (8/17/86)
+
+\ninepoint\noindent
+example,
+`|(some| |charht| |values| |had| |to| |be| |adjusted| |by| |as| |much|
+|as| |0.12pt)|' means that~you had too many different nonzero heights, but
+\MF\ found a way to reduce the number to at most~15 by changing some of
+them; none of them had to be\cutpar
+
+\bugonpage C319, line 3 (8/23/86)
+
+\ninepoint\noindent
+specified by saying, e.g.,
+
+\bugonpage C321, line 6 (7/28/86)
+
+\ninepoint\noindent
+| special "identifier " & font_identifier_;|
+
+\bugonpage C334, line 2 (6/23/86)
+
+\ninepoint\noindent
+| currentpicture := currentpicture shifted-(1,1); pix := currentpicture;|
+
+\bugonpage C339, tenth-last line (2/4/87)
+
+\ninepoint\noindent
+| Jackie K\=aren {\L}au\.ra Mar{\'\i}a N\H{a}ta{\l}{\u\i}e {\O}ctave|
+
+\bugonpage C343, second-last line (8/23/86)
+
+\rightline{\eightssi
+the precise needs of a precise but limited intellectual goal.}
+
+\bugonpage C346, 2nd line of entry for `{\tt;}' (1/12/87)
+
+\eightpoint
+\qquad 217, 223--224, 263, 312.
+
+\bugonpage C348, line 6 (6/17/86)
+
+\eightpoint
+concatenation, of paths, {\eightit 70--71}, {\eightit 123}, 127,
+
+\bugonpage C348, just before `debugging' (3/16/87)
+
+\eightpoint
+de Casteljau, Paul de Faget, 14.
+
+\bugonpage C348, right column (3/16/87)
+
+\eightpoint\noindent
+[The entry for `|define_whole_vertical_blacker_pixels|' should be moved up
+before the entry for `|define_whole_vertical_pixels|'.]
+
+\bugonpage C352, left column (6/1/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt kern}, {\it 97}, {\it 316}, $\underline{317}$.
+
+\bugonpage C352, right column (3/8/87)
+
+\eightpoint\noindent
+[The entry for `|lowres|' belongs before the entry for `|lowres_fix|'.]
+
+\bugonpage C353, left column (3/8/87)
+
+\eightpoint\noindent
+[The entries for `|mode|' and `\<mode command>' belong before the entry
+for `|mode_def|'.]
+
+\bugonpage C353, entry for {\tt mode\char`\_def} (8/17/86)
+
+\eightpoint
+{\tt mode\char`\_def}, 94, 189, $\underline{\smash{\hbox{\it 270}}}$,
+{\it 278--279}.
+
+\bugonpage C355, right column (4/15/86)
+
+\eightpoint\noindent
+[The entry for `{\tt rulepen}' belongs before the entry for `rules'.]
+
+\bugonpage C355, right column (8/5/86)
+
+\eightpoint
+{\tt screenstrokes}, 191, $\underline{277}$.
+
+\bugonpage C355, 2nd line of entry for `semicolons' (1/12/87)
+
+\eightpoint
+\qquad 217, 223--224, 263, 312.
+
+\bugonpage C356, full names for the Stanfords (4/10/86)
+
+\eightpoint
+Stanford, Amasa Leland, 340.
+
+Stanford, Jane Elizabeth Lathrop, 340.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\buginvol D, in general (7/28/86)
+
+\tenpoint\noindent
+[A number of entries were mistakenly omitted from the mini-indexes
+on the right-hand pages. Here is a combined list of all the missing
+items; you can mount it inside the back cover, say, as a secondary mini-index
+when the first one fails\dots\ ]
+
+\nobreak\medskip
+\setbox0=\vbox{\eightpoint \hsize=11pc \catcode`\_=\active \let_=\_
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+ \obeylines
+ \def\makeref #1 #2 #3#4
+ {\nn=#2 \hangindent=1em \noindent\\{#1}%
+ \if#3:: \else\unhcopy\eqbox \fi#4, \S\number\nn.\par}
+ \makeref add_or_subtract 930 :\&{procedure}
+ \makeref after 427 :\&{array}
+ \makeref arg_list 720 :\\{pointer}
+ \makeref b 580 :\\{pixel\_color}
+ \makeref bad_exp 824 :\&{procedure}
+ \makeref before 427 :\&{array}
+ \makeref begin_name 770 :\&{procedure}
+ \makeref bilin1 968 :\&{procedure}
+ \makeref binary_mac 863 :\&{procedure}
+ \makeref blank_rectangle 567 :\&{procedure}
+ \makeref boc_c 1162 :\\{integer}
+ \makeref boc_p 1162 :\\{integer}
+ \makeref cf 298 :\\{fraction}
+ \makeref clockwise 453 :\\{boolean}
+ \makeref ct 298 :\\{fraction}
+ \makeref cubic_intersection 556 :\&{procedure}
+ \makeref cur_pen 403 :\\{pointer}
+ \makeref cur_rounding_ptr 427 :$0\to \\{max\_wiggle}$
+ \makeref cur_spec 403 :\\{pointer}
+ \makeref cur_x 389 :\\{scaled}
+ \makeref cur_y 389 :\\{scaled}
+ \makeref dely 557 :\\{integer}
+ \makeref dep_finish 935 :\&{procedure}
+ \makeref dep_list 587 =macro
+ \makeref dimen_head 1125 :\&{array}
+ \makeref dx 495 :\\{integer}
+ \makeref dy 495 :\\{integer}
+ \makeref d1 464 :$0\to 1$
+ \makeref end_name 772 :\&{procedure}
+ \makeref eqtb 201 :\&{array}
+ \makeref error_stop_mode 68 =$3$
+ \makeref firm_up_the_line 682 :\&{procedure}
+ \makeref get_next 667 :\&{procedure}
+ \makeref gf_buf 1152 :\&{array}
+ \makeref gf_offset 1152 :\\{integer}
+ \makeref gf_ptr 1152 :\\{gf\_index}
+ \makeref halfword 156 =$\\{min\_halfword}\to \\{max\_halfword}$
+ \makeref hash 201 :\&{array}
+ \makeref index 629 =macro
+ \makeref input_ln 30 :\&{function}
+ \makeref interaction 68 :$0\to 3$
+ \makeref j 357 :$0\to \\{move\_size}$
+ \makeref known_pair 872 :\&{procedure}
+ \makeref limit 629 =macro
+ \makeref m_spread 357 :\\{integer}
+ \makeref materialize_pen 865 :\&{procedure}
+ \makeref max_allowed 403 :\\{scaled}
+ \makeref max_c 813 :\&{array}
+ \makeref max_link 813 :\&{array}
+ \makeref max_tfm_dimen 1130 :\\{scaled}
+ \makeref mem_top 12 =macro
+ \makeref mem 159 :\&{array}
+ \makeref memory_word 156 =\&{record}
+ \makeref more_name 771 :\&{function}
+ \makeref m1 464 :\\{integer}
+ \makeref n 580 :\\{screen\_col}
+ \makeref n_sin_cos 145 :\&{procedure}
+ \makeref name 629 =macro
+ \makeref negate_dep_list 904 :\&{procedure}
+ \makeref new_knot 871 :\&{function}
+ \makeref node_to_round 427 :\&{array}
+ \makeref n1 464 :\\{integer}
+ \makeref octant_dir 395 :\&{array}
+ \makeref o1 453 :\\{small\_number}
+ \makeref o2 453 :\\{small\_number}
+ \makeref paint_row 568 :\&{procedure}
+ \makeref param 1096 :\&{array}
+ \makeref param_stack 633 :\&{array}
+ \makeref path_length 916 :\&{function}
+ \makeref perturbation 1119 :\\{scaled}
+ \makeref phi 542 :\\{angle}
+ \makeref pool_ptr 38 :\\{pool\_pointer}
+ \makeref post_head 843 :\\{pointer}
+ \makeref pre_head 843 :\\{pointer}
+ \makeref print_err 68 =macro
+ \makeref print_macro_name 722 :\&{procedure}
+ \makeref quarterword 156 =$0\to 255$
+ \makeref recycle_value 809 :\&{procedure}
+ \makeref row_transition 579 :\\{trans\_spec}
+ \makeref scan_text_arg 730 :\&{procedure}
+ \makeref scroll_mode 68 =$2$
+ \makeref set_controls 299 :\&{procedure}
+ \makeref sf 298 :\\{fraction}
+ \makeref show_context 635 :\&{procedure}
+ \makeref sorted 325 =macro
+ \makeref st 298 :\\{fraction}
+ \makeref start 629 =macro
+ \makeref start_sym 1077 :\\{halfword}
+ \makeref str_pool 38 :\&{packed}\ \&{array}
+ \makeref str_ptr 38 :\\{str\_number}
+ \makeref str_start 38 :\&{array}
+ \makeref take_part 910 :\&{procedure}
+ \makeref tfm_changed 1130 :\\{integer}
+ \makeref tol 557 :\\{integer}
+ \makeref tt 843 :\\{small\_number}
+ \makeref tx 954 :\\{scaled}
+ \makeref txx 954 :\\{scaled}
+ \makeref txy 954 :\\{scaled}
+ \makeref ty 954 :\\{scaled}
+ \makeref tyx 954 :\\{scaled}
+ \makeref tyy 954 :\\{scaled}
+ \makeref unsorted 325 =macro
+ \makeref uv 557 :$0\to \\{bistack\_size}$
+ \makeref xy 557 :$0\to \\{bistack\_size}$
+ \makeref x1 542 :\\{scaled}
+ \makeref x2 542 :\\{scaled}
+ \makeref x3 542 :\\{scaled}
+ \makeref y1 542 :\\{scaled}
+ \makeref y2 542 :\\{scaled}
+ \makeref y3 542 :\\{scaled}
+ }
+\hbox{\nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}}
+
+\buginvol D, in general (4/6/87)
+
+\tenpoint\noindent[The percent signs in all the comments (for example,
+on pages 7 and 42) are in the wrong font! Change `{\tt\%}' to `\%'.]
+
+\bugonpage Dvii, line 9 (9/25/86)
+
+{\tenpoint\noindent\hsize=29pc
+{\sl Discrete and Computational Geometry\/ \bf1} (1986), 123--140.
+\ \it Develops the theory\cutpar}
+
+\bugonpage D2, line 27 (6/17/86)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]1.3\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D18, line 30 (5/22/86)
+
+\ninepoint\noindent
+\\{str\_ptr}: \\{str\_number};\quad
+$\{\,$number of the current string being created$\,\}$
+
+\bugonpage D23, second line of mini-index, right column (6/14/87)
+
+\eightpoint
+\indent\\{pool\_name}\unhcopy\eqbox|"string"|, \S11.
+
+\bugonpage D30, lines 33--34 (6/14/87)
+
+\tenpoint\noindent
+to delete a token, and/or if some fatal error
+occurs while \MF\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\bugonpage D63, lines 13--14 (5/5/87)
+
+\ninepoint\noindent
+[These two lines can be eliminated, since the variable \\{temp\_ptr}
+is no longer used! If you delete them, also remove \S158 from the
+list of sections where global variables are declared (pages D7 and D552),
+and remove \\{temp\_ptr} from the index on page D540.]
+
+\bugonpage D66, line 6 (5/22/86)
+
+\ninepoint\noindent
+{\bf function\/}\ $\\{get\_node}(s:\\{integer})$: \\{pointer};\quad
+$\{\,$variable-size node allocation$\,\}$
+
+\bugonpage D66, lines 31--32 (3/16/86)
+
+\tenpoint\noindent
+controlled
+growth helps to keep the \\{mem} usage consecutive when \MF\ is
+implemented on ``virtual memory'' systems.
+
+\bugonpage D67, lines 7--8 (4/21/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $r=p$ {\bf then if} $\\{rlink}(p)\ne p$ {\bf then}
+ $\langle\,$Allocate entire node $p$ and {\bf goto} \\{found}%
+ {\sevenrm\kern.5em171}$\,\rangle$;
+
+\bugonpage D86, second line of section 198 (2/27/87)
+
+\noindent
+Individual class numbers have no semantic
+or syntactic significance, except in a few instances\cutpar
+
+\bugonpage D101, line 2 (3/16/86)
+
+\tenpoint\line{%
+like `{\tt x}', or they can
+combine the structural properties of arrays and records, like `{\tt x20a.b}'.
+A}
+
+\bugonpage D102, line 24 (3/16/86)
+
+\tenpoint\line{\kern10pt
+In other words, variables have a hierarchical structure that includes
+enough threads running}
+
+\bugonpage D127, line 10 (5/5/87)
+
+\ninepoint\noindent
+[Variable $r$ can be eliminated, since it is not
+used in this procedure! If you delete it, also remove $\underline{280}$
+from the corresponding index entry on page D536.]
+
+\bugonpage D129, line 15 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since \\{sine} and \\{cosine} are not
+used in this procedure! If you delete them, also remove $\underline{284}$
+from the corresponding index entries on pages D538 and D521.]
+
+\bugonpage D142, line 23 (4/24/87)
+
+\tenpoint\noindent
+$(7-\sqrt{28}\,)/12$; the worst case
+occurs for polynomials like $B(0,28-4\sqrt{28},14-5\sqrt{28},42;t)$.)
+
+\bugonpage D178, third-last line (7/30/86)
+
+\tenpoint\line{\quad
+The following code maintains the invariant relations
+$0\le \\{x0}<\max(\\{x1},\\{x1}+\\{x2})$, $\vert\\{x1}\vert<2^{30}$,}
+
+\bugonpage D228, line 13 (7/30/86)
+
+\ninepoint\noindent\kern10pt
+{\bf while} $\\{max\_coef}<\\{fraction\_half}$ {\bf do}
+
+\smallskip\eightpoint\noindent
+The mini-index at the bottom of the next page should also receive the following
+new entry:
+\smallskip\indent
+$\\{fraction\_half}={\rm macro}$, \S105.
+
+\bugonpage D228, 10th-last line (5/5/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} $\\{right\_type}(p)\gets k$;
+\smallskip
+\noindent[Also eliminate `$q,$' seven lines above this, and delete
+$\underline{497}$ from the index entry for \\{q} on page D536.]
+
+\bugonpage D248, lines 16--21 (11/27/86)
+
+\ninepoint\noindent\kern10pt
+$\\{alpha}\gets\\{abs}(u)$;\kern5pt
+ $\\{beta}\gets\\{abs}(v)$;\par\noindent\kern10pt
+{\bf if} $\\{alpha}<\\{beta}$ {\bf then}\par\noindent\kern20pt
+{\bf begin} $\\{alpha}\gets\\{abs}(v)$;\kern5pt
+ $\\{beta}\gets\\{abs}(u)$;\kern5pt
+{\bf end};\quad$\{\,$now $\alpha=\max(\vert u\vert,\vert v\vert)$,
+ $\beta=\min(\vert u\vert,\vert v\vert)\,\}$\par\noindent\kern10pt
+{\bf if} $\\{internal}[\\{fillin}]\ne0$ {\bf then}\par\noindent\kern20pt
+$d\gets d-\\{take\_fraction}(\\{internal}[\\{fillin}],
+ \\{make\_fraction}(\\{beta}+\\{beta},\\{delta}))$;\par\noindent\kern10pt
+$d\gets\\{take\_fraction}((d+4)\;{\bf div}\;8,\\{delta})$;\kern5pt
+$\\{alpha}\gets\\{alpha}\;{\bf div}\;\\{half\_unit}$;
+
+\bugonpage D263, line 20 (3/16/86)
+
+\tenpoint\noindent
+instead of \\{false}, the other routines will simply log the fact
+that they have been called; they won't\cutpar
+
+\bugonpage D268, line 2 (4/28/87)
+
+\tenpoint\noindent
+Given the number~$k$ of an open window, the pixels of positive
+weight in \\{cur\_edges} will be shown\cutpar
+
+\bugonpage D301, line 6 of section 652 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since variable $s$ is not
+used in this procedure! If you delete it, also remove $\underline{652}$
+from the corresponding index entry on page D537; remove 652 from
+the index entries for \\{param\_size} and \\{param\_start} on page D534;
+and remove \\{param\_size} from the mini-index on page D301.]
+
+\bugonpage D376, lines 17 and 18 (11/14/86)
+
+\tenpoint\noindent
+[these two mysterious lines should be deleted]
+
+\bugonpage D380, line 11 (5/5/87)
+
+\ninepoint\noindent
+[Variables $q$ and $r$ can be eliminated, since they are not
+used in this procedure! If you delete them, also remove $\underline{862}$
+from the corresponding index entries on page D536.]
+
+\bugonpage D429, line 14 (5/5/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $p\gets\\{cur\_exp}$;
+\smallskip
+\noindent[Also eliminate line 12, and delete $\underline{985}$ from the
+index entry for \\{vv} on page D543.]
+
+\bugonpage D455, line 5 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since variable $t$ is not
+used in this procedure! If you delete it, also remove $\underline{1059}$
+from the corresponding index entry on page D540; remove 1059 from
+the index entries for \\{small\_number} and \\{with\_option} on pages D539
+and D544; and remove \\{with\_option} from the mini-index on page D455.]
+
+\bugonpage D463, line 10 (12/15/86)
+
+\ninepoint\noindent\hskip30pt
+({\tt"Pretend\]that\]you're\]Miss\]Marple:\]Examine\]all\]clues,"})
+
+\bugonpage D465, lines 17--18 (6/14/87)
+
+\tenpoint\noindent
+[Delete these two lines.]
+
+\bugonpage D474, 5th-last line (3/16/86)
+
+\tenpoint\noindent
+depths, or italic corrections) are sorted;
+then the list of sorted values is perturbed, if necessary.
+
+\bugonpage D481, line 12 (6/17/86)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"Font\]metrics\]written\]on\]\char`\"});\kern5pt
+\\{print}(\\{metric\_file\_name});\kern5pt
+\\{print\_char}({\tt\char`\".\char`\"});
+
+\noindent\hskip10pt\\{b\_close}(\\{tfm\_file})
+
+\smallskip\eightpoint\noindent
+The mini-index at the bottom of this page should also receive the following
+new entry:
+\smallskip\indent
+\\{print\_char}: {\bf procedure}, \S58.
+
+\bugonpage D510, new line to follow line 5 (6/17/86)
+
+{\tenpoint\parindent=1em
+This program doesn't bother to close the input files that may still be open.
+\par}
+
+\bugonpage D510, just before the fifth-last line (8/5/86)
+
+\ninepoint\noindent\hskip30pt$\\{internal}[\\{fontmaking}]\gets0$;\quad
+$\{\,$avoid loop in case of fatal error$\,\}$
+
+\bugonpage D520, right column (6/14/87)
+
+\eightpoint
+\leftline{Chinese characters:\quad 1147.}
+
+\bugonpage D526, left column, lines 1--2 (7/30/86)
+
+\eightpoint
+\leftline{\indent\\{fraction\_half}:\quad
+ $\underline{105}$, 111, 152, 288, 408, 496, 543,}
+\leftline{\indent\qquad 1098, 1128, 1141.}
+
+\bugonpage D526, left column, lines 6--7 (7/30/86)
+
+\eightpoint
+\leftline{\indent\qquad 478, 497, 499, 503, 530, 540, 547, 549, 599, 603,}
+\leftline{\indent\qquad 612, 615, 815--816, 917, 1169--1170.}
+
+\bugonpage D528, right column (6/14/87)
+
+\eightpoint
+\leftline{Japanese characters:\quad 1147.}
+
+\bugonpage D530, right column, line 45 (7/30/86)
+
+\eightpoint
+\leftline{\indent\\{max}:\quad$\underline{539}$, 543.}
+
+\bugonpage D533, right column (6/14/87)
+
+\eightpoint
+\leftline{oriental characters:\quad 1147.}
+
+\bugonpage D535, right column, line 27 (6/17/86)
+
+\eightpoint
+\leftline{\indent\qquad 1134, 1163--1165, 1182, 1194, 1200, 1205, 1213.}
+
+\bugonpage D547, bottom two lines (11/27/86)
+
+\ninepoint\noindent
+[These lines, and the top two on the next page, should move down
+so that they appear in alphabetical order just before `Compute
+test coefficients'.]
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, lines 1--2 (7/28/86)
+
+\tenpoint\noindent
+February 11--13, 1984), 49.
+\ {\it An example meta-character of the Devanagari alphabet, worked out
+``online'' with the help of Matthew Carter.}
+
+\bugonpage Exiii, line 6 (7/28/86)
+
+\tenpoint\noindent
+{\it and western alphabets work also for Devanagari and Tamil.}
+
+\bugonpage E12, lines 15 and 19 (7/23/86)
+
+\tenpoint\noindent[change `17.32' to `17.28' in both places]
+
+\bugonpage E12, third-last line (12/18/86)
+
+\tenpoint\noindent[change `41' to `40']
+
+\bugonpage E13, lines 3, 4, and 20 (12/18/86)
+
+\tenpoint\noindent[change `40' to `41', `48' to `47', `17' to `7']
+
+\bugonpage E18, line 20 (7/23/86)
+
+\tenpoint\noindent[change `17.32' to `17.28']
+
+\bugonpage E18, line 29 (12/9/86)
+
+\tenpoint\noindent[change `236' to `212' in the {\tt cmss9} column]
+
+\bugonpage E170, top illustration (11/2/86)
+
+\tenpoint\noindent[There should be no ``dish'' or depression in the
+vicinity of point {\tt 3r}; the top edge of the character should be
+straight. This error appears also in the other uses of `\\{no\_dish\_serif}'
+throughout the book, since the illustrations were made before
+`\\{no\_dish\_serif}' was added to the program. See page
+E180~(twice at the top), E370~(twice), E374~(twice), E376~(twice), E378~(top),
+E390~(bottom), E398~(top), E402~(top), E406~(top), E453~(twice).]
+
+\bugonpage E179, new line to be inserted after line 6 (10/13/86)
+
+\ninepoint\noindent
+{\bf if} $\\{shaved\_stem}<\\{crisp}.\\{breadth}$:
+ $\\{shaved\_stem}:=\\{crisp}.\\{breadth}$; {\bf fi}
+
+\bugonpage E219, line 29 (6/2/87)
+
+\ninepoint\line{\\{top} $y_1=h$; \ $x_1=x_2$; \
+ {\bf filldraw stroke} $z_{1e}\dashto z_{2'e}$;\hfil\% stem}
+
+\bugonpage E279, seventh line from the bottom (7/20/86)
+
+\rightline{\eightssi that delicious but restrained humor which
+ her readers found so irresistible.}
+
+\bugonpage E301, new line to be inserted after line 28 (5/15/87)
+
+\ninepoint\noindent
+\quad{\bf if} $\\{lower\_side}>1.2\\{upper\_side}$:
+ $\\{upper\_side}:=\\{lower\_side}$; {\bf fi}
+
+\bugonpage E554, bottom half of page (12/18/86)
+
+\ninepoint\noindent[The letters will change slightly because of the
+corrections to {\tt cmr17} noted on pages 12 and 13.]
+
+\bugonpage E561, line 3 (12/9/86)
+
+\ninepoint\noindent[The numerals should be `\thinspace
+{\niness 0123456789}\thinspace' (i.e., 2/3 point less tall)
+because of the correction made to page 18.]
+
+\bugonpage E562, line 9 (12/9/86)
+
+\ninepoint\noindent[The numerals should be `\thinspace
+{\ninessi 0123456789\/}\thinspace' (i.e., 2/3 point less tall)
+because of the correction made to page 18.]
+
+\bugonpage E572, entry for {\it breadth} (10/13/86)
+
+\eightpoint
+{\it breadth}, 59, 75, 79, 91, 93, 179, 225, 233,
+
+\bugonpage E573, entry for {\tt cmcsc10} (8/17/86)
+
+\eightpoint
+{\tt cmcsc10}, $\underline{30}$--$\underline{31}$, 567.
+
+\bugonpage E576, tenth-last line (5/15/87)
+
+\eightpoint
+{\bf lowres\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em
+ fix}, 550.
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata.two b/Master/texmf-doc/doc/english/knuth/errata/errata.two
new file mode 100644
index 00000000000..74dde877267
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata.two
@@ -0,0 +1,491 @@
+% More bugs (sigh) in The TeXbook
+
+\input manmac
+\proofmodefalse
+\raggedbottom
+\output{\onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\rhead{Bugs in {\tensl The \TeX book}, second printing}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule\line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule\nobreak\medskip}
+
+\noindent This is a list of all corrections made to {\sl The \TeX book\/}
+since the second printing. If your copy doesn't say `{\sl\kern-1pt Second
+printing (October 1984)\/}' on the copyright page, you should also look at
+the previous bug list. In fact, the most important corrections to the
+first printing were discovered first, so they've already been~made.
+
+\bugonpage 23, line 16 (10/13/84)
+
+\tenpoint\indent
+|This is TeX, Version 1.0 (preloaded format=plain 83.7.15)|
+
+\bugonpage 33, line 32 (10/21/84)
+
+The bottom line shows how far \TeX\ has gotten until now in the
+|story|{\parfillskip=0pt\par}
+
+\bugonpage 41, lines 7 and 8 (10/8/85)
+
+\ddanger The twin operations ^|\uppercase||{|\<token list>|}| and
+^|\lowercase||{|\<token list>|}| go through a given token list and convert
+all of the character tokens to their\parfillskip=0pt\enddanger
+
+\bugonpage 57, line 17 (1/6/86)
+
+|dd|\quad didot point ($\rm1157\,dd=1238\,pt$)
+
+\bugonpage 61, lines 17--19 (12/18/85)
+
+\ninepoint\noindent
+|depth|, |em|, |ex|,
+|fil|, |height|, |in|, |l|, |minus|, |mm|, |mu|, |pc|, |plus|,
+|pt|, |scaled|, |sp|, |spread|, |to|, |true|, |width|. ^^{reserved words}
+\ (See Appendix~I for references to the contexts in which each of these is
+recognized as a keyword.)
+
+\bugonpage 67, append a new exercise (1/19/85)
+
+\exno=5 \def\chapno{11}
+\gdef\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
+
+\ddangerexercise Construct a |\frac| macro such that `|\frac1/2|' yields
+`\frac1/2'.
+
+\bugonpage 130, line 15 (4/17/85)
+
+\beginmathdemo
+|$y'''_3+g'^2$|&y'''_3+g'{}^2\cr
+\endmathdemo
+
+\bugonpage 170, line 5 (5/28/85)
+
+\ninepoint
+\line{tall, unslanted
+letter; and so on. But two of the examples involve corrections that were}
+
+\bugonpage 194, lines 13--15 should be centered better (10/22/84)
+
+\ninepoint
+$$\displaylines{\hfill x\equiv x;\hfill\llap{(1)}\cr
+ \hfill\hbox{if}\quad x\equiv y\quad\hbox{then}\quad
+ y\equiv x;\hfill\llap{(2)}\cr
+ \hfill\hbox{if}\quad x\equiv y\quad\hbox{and}\quad
+ y\equiv z\quad\hbox{then}\quad
+ x\equiv z.\hfill\llap{(3)}\cr}$$
+
+\bugonpage 215, lines 9 and 10 from the bottom (12/23/84)
+
+\ninepoint\noindent
+general format
+is the same as for |\def| and |\gdef|, but \TeX\ blindly expands the tokens
+of the replacement text according to the expansion rules above. For
+example, consider
+
+\bugonpage 233, lines 15--19 (1/19/85)
+
+\medskip
+\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
+\+&\negthinspace\it Weight&\it Servings&
+ {\it Approximate Cooking Time\/}*\cr
+\smallskip
+\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
+\+&9 lbs.&7 to 8&About 2 hours\cr
+\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
+\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
+
+\bugonpage 236, lines 18--21 (1/19/85)
+
+\ninepoint
+$$\vbox{\openup2pt
+\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&
+ \quad\hfil#\hfil&\quad#\hfil\cr
+Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
+Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
+Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
+Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr}}$$
+[This change should also be made at the bottom of page 237.]
+
+\bugonpage 236, fifth-last line (1/19/85)
+
+\ninepoint
+| Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr|
+
+\bugonpage 237, line 25 (10/10/84)
+
+\ninepoint\noindent
+saying `^|\tabskip||=|\<glue>'. For example,
+let's do the poultry table again, but with the{\parfillskip=0pt\par}
+
+\bugonpage 265, bottom line (11/6/85)
+
+[insert a comma after `{\eightss LEONTIEF}'.]
+
+\bugonpage 271, line 8 (11/12/85)
+
+\ninepoint
+\beginsyntax
+<fil unit>\is[fil]\alt<fil unit>[l]
+\endsyntax
+
+\bugonpage 280, lines 7 and 8 (1/8/85)
+
+\ninepoint\noindent
+\<4-bit number>.\enskip
+The specified output stream is opened or closed, for use in |\write|
+commands, as explained in Chapter~21.
+
+\bugonpage 300, lines 5--10 [changed for version 1.3] (11/25/84)
+
+\ninepoint\noindent
+what part of \TeX's memory has become overloaded;
+one of the following fourteen things will be mentioned:
+\begindisplay
+|number of strings|\qquad(names of control sequences and files)\cr
+|pool size|\qquad(the characters in such names)\cr
+|main memory size|\qquad(boxes, glue, breakpoints, token lists,
+ characters, etc.)\cr
+\enddisplay
+
+\bugonpage 300, lines 23--29 [changed for version 1.3] (11/25/84)
+
+\danger If you have a job that doesn't overflow \TeX's capacity, yet
+you want to see just how closely you have approached the limits,
+just set ^|\tracingstats| to a positive value before the end of your
+job. The log file will then conclude with a report on your actual
+usage of the first eleven things named above (i.e., the number of strings,
+\dots, the save size), in that order. ^^{stack positions}
+Furthermore, if you set |\tracingstats| equal to 2~or~more, \TeX\
+will show its current memory usage whenever it
+does a ^|\shipout| command. Such statistics are broken into two
+parts; `|490&5950|' means, for example, that 490 words are being used
+for ``large'' things like boxes, glue, and
+breakpoints, while 5950 words are being used for ``small'' things like
+tokens and characters.
+
+\bugonpage 302, line 14 (10/8/85)
+
+\begintt
+.\tenrm || (ligature ---)
+\endtt
+
+\bugonpage 305, line 26 (12/24/84)
+
+\ninepoint\noindent
+sentable as |^^M|. Asking \TeX\ to |\show\^^M|
+\looseness-1
+produces the response `|>| |\^^M=macro:->\|\]|.|'.
+
+\bugonpage 306, line 10 (7/1/85)
+
+\ninepoint\noindent
+no ``^{explicit kerns},'' and an italic correction is an
+explicit kern.) \ But the italic correction may be too much (especially in an
+italic font); |shelf{|^|\kern||0pt}ful| is often best.
+
+\bugonpage 308, line 25 (3/25/85)
+
+\ninepoint\indent
+|\def\appendroman#1#2#3{\edef#1{\def\noexpand#1{\csname|
+
+\bugonpage 311, insert a new answer (1/19/85)
+
+\ninepoint
+\ansno11.6:
+ |\def\frac#1/#2{\leavevmode\kern.1em|\parbreak
+|\raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em|\parbreak
+|/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}|
+
+\smallskip\noindent[This causes answer 12.8 to move to page 312;
+answer 12.16 also moves to page 313.]
+
+\bugonpage 320, lines 17--20 (8/10/85)
+
+\ninepoint
+\ansno17.16:
+ |\def\sqr#1#2{{\vcenter{\vbox{\hrule height.#2pt|\parbreak
+ | \hbox{\vrule width.#2pt height#1pt \kern#1pt|\parbreak
+ | \vrule width.#2pt}|\parbreak
+ | \hrule height.#2pt}}}}|
+
+\bugonpage 327, lines 26--33 (10/22/84)
+
+\ninepoint
+\ansno19.16:
+ |$$\displaylines{\hfill x\equiv x;\hfill\llap{(1)}\cr|\parbreak
+ | \hfill\hbox{if}\quad x\equiv y\quad\hbox{then}\quad|\parbreak
+ | y\equiv x;\hfill\llap{(2)}\cr|\parbreak
+ | \hfill\hbox{if}\quad x\equiv y\quad\hbox{and}\quad|\parbreak
+ | y\equiv z\quad\hbox{then}\quad|\parbreak
+ | x\equiv z.\hfill\llap{(3)}\cr}$$|\par\medskip\noindent
+There's also a trickier solution, which begins with
+\begintt
+$$\displaylines{x\equiv x;\hfil\llap{(1)}\hfilneg\cr
+\endtt
+
+\bugonpage 330, line 29 (11/15/85)
+
+\ninepoint\indent
+|\edef\next#1#2{\def#1{\b#2\d}} \next\a\c|
+
+\bugonpage 332, lines 17--24 (1/19/85)
+
+\ninepoint
+\begintt
+\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
+\+&\negthinspace\it Weight&\it Servings&
+ {\it Approximate Cooking Time\/}*\cr
+\smallskip
+\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
+\+&9 lbs.&7 to 8&About 2 hours\cr
+\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
+\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
+\endtt
+
+\bugonpage 332, lines 33--35 (1/19/85)
+
+\ninepoint\noindent
+proofs. \ (You weren't supposed to think of this,
+but it has to be mentioned.) \ See exercise 11.\fracexno\ for the `|\frac|'
+macro; it's better to say `\frac1/2' than `$1\over2$', in a cookbook.\par
+Another way to treat this table would be to display it in a vbox, instead
+of including a first column whose sole purpose is to specify indentation.
+
+\bugonpage 337, line 28 (11/12/85)
+
+\ninepoint\noindent |\nextnumber|. Quick should put `|\relax|'
+at the end of his macro. \ (The {keywords} |l|,{\parfillskip=0pt\par}
+
+\bugonpage 357, lines 35 and 36 (1/8/85)
+
+\ninepoint\noindent
+|\def\*{\discretionary{\thinspace\the\textfont2\char2}{}{}}|
+
+\bugonpage 357, last two lines (4/17/85)
+
+\ninepoint\noindent
+|\def\pr@m@s{\ifx'\next\let\next\pr@@@s|%
+ | \else\ifx^\next\let\next\pr@@@t|\par\noindent
+| \else\let\next\egroup\fi\fi \next}|\par\noindent
+|\def\pr@@@s#1{\prim@s} \def\pr@@@t#1#2{#2\egroup}|
+
+\bugonpage 358, lines 8--12 (1/23/85)
+
+\ninepoint\noindent
+|\def\hbar{{\mathchar'26\mkern-9muh}}|\hfil\break\null
+|\def\surd{{\mathchar"1270}}|\hfil\break\null
+|\def\angle{{\vbox{\ialign{$\m@th\scriptstyle##$\crcr|\hfil\break\null
+| \not\mathrel{\mkern14mu}\crcr \noalign{\nointerlineskip}|\hfil\break\null
+| \mkern2.5mu\leaders\hrule height.34pt\hfill\mkern2.5mu\crcr}}}}|
+
+\bugonpage 359, lines 7--8 (1/22/85)
+
+\ninepoint\noindent
+|\def\ddots{\mathinner{\mkern1mu\raise7pt\vbox{\kern7pt\hbox{.}}\mkern2mu|%
+\hfil\break\null
+| \raise4pt\hbox{.}\mkern2mu\raise1pt\hbox{.}\mkern1mu}}|
+
+\bugonpage 360, line 22 (1/22/85)
+
+\ninepoint\noindent
+| \mkern5mu \raise.6\dimen@\copy\rootbox \mkern-10mu \box0}|
+
+\bugonpage 361, line 3 (3/27/85)
+
+\ninepoint\noindent
+|\def\buildrel#1\over#2{\mathrel{\mathop{\kern0pt #2}\limits^{#1}}}|
+
+\bugonpage 361, lines 19--20 (1/22/85)
+
+\ninepoint\noindent
+|\def\bmod{\mskip-\medmuskip \mkern5mu|\hfil\break\null
+| \mathbin{\rm mod} \penalty900 \mkern5mu \mskip-\medmuskip}|
+
+\bugonpage 361, line 27 (5/1/85)
+
+\ninepoint\noindent
+|\def\matrix#1{\null\,\vcenter{\normalbaselines\m@th|
+
+\bugonpage 361, bottom line (5/1/85)
+
+\ninepoint\noindent
+| \null\;\vbox{\kern\ht1\box2}\endgroup}|
+
+\bugonpage 362, line 9 (5/1/85)
+
+\ninepoint\noindent
+|\def\eqalign#1{\null\,\vcenter{\openup1\jot \m@th|
+
+\bugonpage 362, lines 17--29 (8/10/85)
+
+{\parindent=0pt\ninepoint
+|\def\@lign{\tabskip=0pt\everycr={}} % restore inside \displ@y|\par
+|\def|^|\displaylines||#1{\displ@y|\parbreak%
+| \halign{\hbox to\displaywidth{|%
+ |$\hfil\@lign\displaystyle##\hfil$}\crcr|\parbreak%
+| #1\crcr}}|
+\smallbreak
+|\def|^|\eqalignno||#1{\displ@y \tabskip=|^|\centering|\parbreak%
+| \halign to\displaywidth{\hfil$\@lign\displaystyle{##}$\tabskip=0pt|\parbreak%
+| &$\@lign\displaystyle{{}##}$\hfil\tabskip=\centering|\parbreak%
+| &\llap{$\@lign##$}\tabskip=0pt\crcr|\parbreak%
+| #1\crcr}}|\par
+|\def|^|\leqalignno||#1{\displ@y \tabskip=\centering|\parbreak%
+| \halign to\displaywidth{\hfil$\@lign\displaystyle{##}$\tabskip=0pt|\parbreak%
+| &$\@lign\displaystyle{{}##}$\hfil\tabskip=\centering|\parbreak%
+| &\kern-\displaywidth\rlap{$\@lign##$}\tabskip=\displaywidth\crcr|\parbreak%
+| #1\crcr}}|
+\par}
+
+\bugonpage 363, line 9 (5/12/85)
+
+\ninepoint\noindent
+|\def\footnote#1{\let\@sf=\empty % parameter #2 (the text) is read later|
+
+\bugonpage 364, line 3 (3/23/85)
+
+\ninepoint\noindent
+|\def\plainoutput{\shipout\vbox{\makeheadline\pagebody\makefootline}%|
+
+\bugonpage 364, fifth-last line (9/15/85)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.0} % identifies the current format|
+
+\bugonpage 399, eighth-last line (2/11/85)
+
+\ninepoint\noindent
+| \baselineskip=\footnotebaselineskip\noindent\unhbox0\par}|
+
+\bugonpage 401, line 5 (1/29/85)
+
+\ninepoint\noindent
+{|\fontdimen| parameters to qualify as a math symbol font).
+(2)~Set all the font identifiers\parfillskip=0pt\par}
+
+\bugonpage 414, line 10 (12/17/84)
+
+\ninepoint\noindent
+|\font\titlefont=cmssdc40 % titles in chapter openings|
+
+%\bugonpage 420, line 9 (10/3/85)
+%
+%\ninepoint\noindent
+%|\def\AmSTeX{$\cal A\kern-.1667em\lower.5ex\hbox{$\cal M$}\kern-.075em|
+% that change comes under `font data', explained away below
+
+\bugonpage 444, bottom line (1/10/85)
+
+\ninepoint\noindent
+depth $d(z)+v$, consisting
+of box~$x$ followed by an appropriate kern followed by box~$z$.
+
+\bugonpage 461, entry for character codes (11/6/85)
+
+\eightpoint
+Add `{\sl see also\/} category codes'.
+
+\bugonpage 463, entries for {\tt dd}, Didot, and didot (1/6/86)
+
+\eightpoint
+Remove the circumflex accents.
+
+\bugonpage 466, left column (1/19/85)
+
+\eightpoint
+fractions, 67, 139--143, 152, 170, 179,\par
+\qquad 186, 444--445.\par
+\quad huge, 196.\par
+\quad slashed form, 67, 139--140, 233, 236.
+
+\bugonpage 467, index entry for {\tt\char`\\hsize} (6/14/85)
+
+\eightpoint
+Add a reference to page {\it 60}.
+
+\bugonpage 469, index entry for {\tt\char`\\kern} (7/1/85)
+
+\eightpoint
+Add a reference to page {\it 306}.
+
+\bugonpage 469, index entry for kerns (7/1/85)
+
+\eightpoint
+Add a reference to page 306.
+
+\bugonpage 469, new entry (11/12/85)
+
+\eightpoint
+|l| after |fil|, $\underline{271}$, 337.
+
+\bugonpage 469, second line on the right (9/13/85)
+
+\eightpoint
+%\def\LaTeX{L\kern-.25em\raise.7ex\hbox{a}\kern-.05em\TeX} % old style
+{L\kern -.36em\raise.6ex\hbox{\sixrm A}\kern-.15em\TeX}, 137.
+
+\bugonpage 470, index entries for {\tt\char`\\longleftarrow}
+ thru {\tt\char`\\Longrightarrow} (10/5/84)
+
+\eightpoint
+The references to page 358 should be underlined (seven times).
+
+\bugonpage 475, index entry for punctuation in formulas (4/29/85)
+
+\eightpoint
+Add a reference to page 161.
+
+\bugonpage 476, index entry for {\tt\char`\\scriptspace} (8/10/85)
+
+\eightpoint
+Change `445' to `445--446'.
+
+\bugonpage 478, first and last lines (10/11/84)
+
+\noindent Delete the last line in the right-hand column
+(since it appears on page 479), and add the following line
+at the top of the left-hand column (since it was dropped by mistake
+from the second printing):
+
+\smallskip
+\eightpoint styles of math formatting, 140--141, 441--447.
+
+\bugonpage 478, new entry after tabbing (5/28/85)
+
+\eightpoint
+tables, {\sl see\/} alignments, tabbing.
+
+\bugonpage 478, tabskip entries (3/25/85)
+
+\eightpoint\noindent Instead of `237--239' and `237--238' it should say
+`$\underline{237}$--$\underline{239}$' twice.
+
+\bugonpage 481, the entry for {\tt\char`\\widetilde} (9/23/85)
+
+\eightpoint
+Page 359 should be underlined.
+
+\bugonpage 483, lines 16--17 (1/19/85)
+
+|P.O. Box 9506|\parbreak
+|Providence RI 02940-9506, USA.|
+
+\bugonpage 483, lines 22--23 (1/19/85)
+
+P.O. Box 9506\par
+Providence RI 02940-9506, USA.
+
+\bigskip
+\hrule
+\bigskip\noindent\tenrm
+Note: The next printing will use the ``real'' Computer Modern fonts
+instead of the ``almost'' Computer Modern fonts. Therefore many of
+the line breaks will be slightly different. Also, the font-related
+numerical data on pages 27, 29, 66, 75, 76, 79, 88, 98, 99, 112, 113, 310,
+314, 396, 399, 409, 420, and 459 will be different. However, these
+differences need not be listed here, because the old book was correct with
+respect to the old fonts.
+
+\bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata1.tex b/Master/texmf-doc/doc/english/knuth/errata/errata1.tex
new file mode 100644
index 00000000000..471971958c3
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata1.tex
@@ -0,0 +1,751 @@
+% Bugs (sigh) in The TeXbook
+
+\input manmac
+\proofmodefalse
+\raggedbottom
+\output{\onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\rhead{Bugs in {\sl The \TeX book}, first printing}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule\line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule\nobreak\medskip}
+
+\noindent This is a list of all corrections made to {\sl The \TeX book\/}
+between the first and second printings. If your copy says `{\sl\kern-1pt Second
+printing (October 1984)\/}' on the copyright page, you've already got
+all of these things corrected. Otherwise, you're a lucky owner of the
+rare first edition; read on.
+
+\bugonpage 29, lines 31--32 (8/25/84)
+
+The underfull box that \TeX\ produces in the 1.5-inch case is really bad;
+with such narrow limits, an occasional wide space is unavoidable. But try
+
+\bugonpage 54, lines 5--6 (4/20/84)
+
+{\parfillskip=0pt
+\ddanger Appendix B shows that plain \TeX\ handles most of the accents
+by using \TeX's ^|\accent| primitive. For example, |\'#1| is equivalent
+to |{\accent19 #1}|, where\par}
+
+\bugonpage 63, seven lines below the first illustration (2/27/84)
+
+\line{points, a width of 5.5555 points, and a depth of zero;
+the letter `g' has a height}
+
+\bugonpage 72, line 35 (2/28/84)
+
+\ninepoint\noindent
+from |0pt|, but |0.00001filll| is infinitely greater than |16383.99999fill|.
+
+\bugonpage 79, line 12 (2/28/84)
+
+\ninepoint\indent
+|\hbox(6.25+1.94444)x312.0, glue set 0.5783, shifted 36.0 []|
+
+\bugonpage 98, line 24 (4/13/84)
+
+\ninepoint
+\line{and |\finalhyphendemerits=5000|. Demerits are in units of
+ ``badness squared,'' so the}
+
+\bugonpage 101, lines 29--30 (3/13/84)
+
+{\parfillskip=0pt
+\danger It's possible to control the length of lines in a much more general
+way, if simple changes to |\leftskip| and |\rightskip| aren't
+flexible enough for your\par}
+
+\bugonpage 113, bottom two lines (3/13/84)
+
+{\parfillskip=0pt
+\ddanger Notice that the first ``|%| line'' of our example says |t=10.0|;
+this is a consequence of another parameter, called ^|\topskip|. Glue
+disappears at a page break, but\par}
+
+\bugonpage 124, eighth-last line (8/25/84)
+
+\ninepoint
+{\parfillskip=0pt\noindent
+discarded, |\box100| will
+be void after the |\vsplit|. And if\/ |\box100| was void before the\par}
+
+\bugonpage 131, display in exercise 16.8 (3/16/84)
+
+\indent
+|If$ x = y$, then $x$ is equal to $y.$|
+
+\bugonpage 170, table in middle of the page (2/12/84)
+
+\ninepoint
+$$\baselineskip0pt\lineskip0pt
+\halign to\hsize
+ {\strut\hbox to\parindent{\it#\hfil}& % for the legend "Left atom"
+ #\hfil\quad& % for the row labels
+ #\hfil\tabskip 0pt plus 10pt& % for the rule at the left
+ \hbox to 25pt{\tt\hss#\hss}& % for column 1
+ \hbox to 25pt{\tt\hss#\hss}& % for column 2
+ \hbox to 25pt{\tt\hss#\hss}& % for column 3
+ \hbox to 25pt{\tt\hss#\hss}& % for column 4
+ \hbox to 25pt{\tt\hss#\hss}& % for column 5
+ \hbox to 25pt{\tt\hss#\hss}& % for column 6
+ \hbox to 25pt{\tt\hss#\hss}& % for column 7
+ \hbox to 25pt{\tt\hss#\hss}& % for column 8
+ #\hfil\tabskip0pt\cr % for the rule at the right
+\noalign{\vskip-6pt} % it just happens that there's extra white space
+&&&&\multispan7\hss\it Right atom\hss\cr
+\noalign{\vskip3pt}
+&&&\rm Ord&\rm Op&\rm Bin&\rm Rel&\rm Open&\rm Close&\rm Punct&\rm Inner\cr
+\noalign{\vskip2pt}
+\omit&&\multispan{10}\leaders\hrule\hfil\cr
+\omit\vbox to 2pt{}&&\vrule&&&&&&&&&\vrule\cr
+&Ord&\vrule&0&1&(2)&(3)&0&0&0&(1)&\vrule\cr
+&Op&\vrule&1&1&*&(3)&0&0&0&(1)&\vrule\cr
+&Bin&\vrule&(2)&(2)&*&*&(2)&*&*&(2)&\vrule\cr
+Left&Rel&\vrule&(3)&(3)&*&0&(3)&0&0&(3)&\vrule\cr
+atom&Open&\vrule&0&0&*&0&0&0&0&0&\vrule\cr
+&Close&\vrule&0&1&(2)&(3)&0&0&0&(1)&\vrule\cr
+&Punct&\vrule&(1)&(1)&*&(1)&(1)&(1)&(1)&(1)&\vrule\cr
+&Inner&\vrule&(1)&1&(2)&(3)&(1)&0&(1)&(1)&\vrule\cr
+\omit\vbox to 2pt{}&&\vrule&&&&&&&&&\vrule\cr
+\omit&&\multispan{10}\leaders\hrule\hfil\cr}$$
+
+\bugonpage 173, line 11 (1/2/84)
+
+\indent|Clearly $a_i<b_i$ for~$i=1, 2, \ldots, n$.|
+
+\bugonpage 176, bottom two lines (7/20/84)
+
+\def\chapno{ 18} \exno=23 % for exercise 18.24!
+\dangerexercise Typeset the display \ \lower12pt\null
+$\tenpoint\smash{\displaystyle
+\left\lgroup\matrix{a&b&c\cr d&e&f\cr}\right\rgroup
+ \left\lgroup\matrix{u&x\cr v&y\cr w&z\cr}\right\rgroup
+}$, \
+using ^|\lgroup| and ^|\rgroup|.
+
+\bugonpage 189, line 18 (2/13/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+when there is an overlap.] \ If $e=0$ and if there is an |\leqno|,
+the equation number is\par}
+
+\bugonpage 204, line 31 (2/13/84)
+
+\ninepoint\noindent
+of\/ |\a| is delimited by a left brace.
+
+\bugonpage 212, line 23 (7/8/84)
+
+\ninepoint\noindent
+it equals~2.) \
+Similarly, ^|\tracingmacros||=2| will trace |\output|, |\everypar|, etc.
+
+\bugonpage 216, first five lines (8/25/84)
+
+\ddanger Expanded definitions that are made with |\edef| or |\xdef| continue
+to expand tokens until only unexpandable tokens remain, except that
+token lists produced by `^|\the|' are not expanded further. Furthermore
+a token following `^|\noexpand|' will not be expanded, since its ability
+to expand has been nullified. These two operations can be used to control
+^^{expansion, avoiding} what gets expanded and what doesn't.
+
+\bugonpage 219, simplification of line 18 (2/15/84)
+
+\ninepoint\indent
+| \advance\count0 by\count2 \hexdigit}}|
+
+\bugonpage 223, lines 3--4 (3/13/84)
+
+{\parfillskip=0pt
+\ddanger Chapters 24 to 26 present summaries of all \TeX's operations
+in all modes, and when those summaries mention a `\<box>' they mean one
+of the seven\par}
+
+\bugonpage 242, line 29 (1/2/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+a relation, the solution is to insert `|{}|' ^^{lbrace rbrace}
+at the beginning of the right-hand formula; \TeX
+\par}
+
+\bugonpage 245, line 24 (2/15/84)
+
+\ninepoint\noindent
+of a box that spans columns $i$ through~$j$,
+hence the glue in such a box might shrink.
+
+\bugonpage 248, the fourth dangerous bend (2/15/84)
+
+{\parfillskip=0pt
+\ddanger You have to be careful with the use of |&| and ^|\span| and ^|\cr|,
+because these tokens are intercepted by \TeX's scanner even when it is
+not expanding macros.\par}
+
+\bugonpage 249, lines 20--26 (2/15/84)
+
+\ninepoint\noindent
+line (see Chapter~9).
+If you don't want a~|\cr| at the end of a certain line,
+just type `|%|' and the corresponding |\cr|
+will be ``commented out.'' ^^{percent} \ (This special mode doesn't
+work with ^|\+| lines, since |\+| is a macro whose argument is delimited
+by the token `|\cr|', not simply by a token that has the same meaning
+as~|\cr|. ^^{delimited arguments} But you can redefine |\+| to overcome
+this hurdle, if you want to. For example, define a macro |\alternateplus|
+that is just like |\+| except that its argument is delimited by the active
+character |^^M|; then include the command `|\let\+=\alternateplus|' as
+part of\/ |\obeylines|.)
+
+\bugonpage 253, lines 28--32 (4/25/84)
+
+\ninepoint\noindent
+vertical list at what it thinks is the best place, and at such times
+it enters internal vertical mode and begins to read the commands in the
+current |\output| routine. When the output routine begins, ^|\box255|
+contains the page that \TeX\ has completed; the output routine is supposed to
+do something with this vbox. When the output routine ends, the list of
+items that it has constructed in internal vertical mode is placed just%
+{\parfillskip=0pt\par}
+
+\bugonpage 254, lines 1--13 (3/13/84)
+
+\ddanger \TeX's primitive command |\shipout|\<box> is what actually
+causes output. It sends the contents of the box to the |dvi| file,
+which is \TeX's main output file; after \TeX\ has finished,
+the ^|dvi| file will contain a compact device-independent encoding of
+instructions that specify exactly what should be printed. When a
+box is shipped out, \TeX\ displays the values of\/ |\count0| through
+|\count9| on your terminal, ^^|\count0| as explained in Chapter~15; these
+ten counters are also recorded in the |dvi| file, where they can be used
+to identify the page. All of the ^|\openout|, ^|\closeout|, and ^|\write|
+commands that appear inside of the \<box> are performed in their natural
+order as that box is being shipped out. Since a |\write| command
+expands macros, as explained in Chapter~21, \TeX's scanning mechanism
+might detect syntax errors while a |\shipout| is in progress. If
+^|\tracingoutput| is nonzero at the time of a |\shipout|, the contents
+of the \<box> being shipped are written into your log file in symbolic
+form. You can say |\shipout| anywhere, not only in an output routine.
+
+\bugonpage 255, line 33 (4/25/84)
+
+\ninepoint\indent
+|\nointerlineskip|
+
+
+\bugonpage 256, starting with line $-17$ (11/1/83)
+
+\ninepoint
+\textindent{6)} Finally, the ^|\dosupereject| macro is designed to clear
+out any insertions that have been held over, whether they are illustrations
+or footnotes or both: ^^|\insertpenalties| ^^|\supereject|
+\begintt
+\ifnum\insertpenalties>0
+ \line{} \kern-\topskip \nobreak
+ \vfill\supereject\fi
+\endtt
+The mysterious negative ^|\kern| here cancels out the natural space of the
+^|\topskip| glue that goes above the empty |\line|; that empty line box
+prevents the ^|\vfill| from disappearing into a page break. The vertical
+list that results from |\dosupereject| is placed on \TeX's list of things
+to put out next, just after the straggling insertions have been
+reconsidered as explained in Chapter~15. Hence another super-eject will
+occur, and the process will continue until no insertions remain.
+
+\bugonpage 262, line 14 (2/12/84)
+
+\ninepoint\indent
+|\def\endindex{\mark{}\break\endgroup}|
+
+\bugonpage 262, lines 34 and 35 (2/12/84)
+
+\ninepoint\noindent
+if\/ |\next| is `|\endindex|',
+the next commands executed will be `|\vfill|\allowbreak
+|\mark{}|\allowbreak|\break|\allowbreak|\endgroup|';
+otherwise the line will be treated as a main entry.
+
+\bugonpage 269, line 23 becomes two lines (8/25/84)
+
+\ninepoint\noindent
+tokens like |+|$_{12}$;
+(3)~keywords like \[pt]; (4)~control sequence names like |\dimen|;
+or (5)~the special symbols |{|, |}|, |$|.
+
+\bugonpage 274, line 24 (2/15/84)
+
+\ninepoint\indent
+|\lineskip|\quad(interline glue if\/ |\baselineskip| isn't feasible)
+
+\bugonpage 289, slight clarification on lines 39--41 (3/10/84)
+
+\ninepoint
+A \<math character> defines a 15-bit number either by specifying it
+directly with ^|\mathchar| or in a previous ^|\mathchardef|, or by
+specifying a 27-bit |\delimiter| value; in the latter case, the least
+significant 12~bits are discarded.
+
+
+\bugonpage 307, a slightly more explicit answer (11/3/83)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss6.3.\enspace}%
+It represents the heavy bar that shows up in
+your output. \ (This bar wouldn't be present if\/ ^|\overfullrule| had been
+set to |0pt|, nor is it present in an underfull box.)
+
+\bugonpage 313, first four lines (3/13/84)
+
+{\ninepoint\parfillskip=0pt
+\ansno12.17:
+ You get `A' at the extreme left and `puzzle.\null' at the extreme right,
+because the space between words has the only stretchability that is finite;
+the infinite stretchability cancels out. \ (In this case, \TeX's rule
+about ^{infinite glue} differs from what you would get in the limit if the
+value of $1\,{\rm fil}$ were finite but getting larger and larger.
+The true\par}
+
+\bugonpage 315, first three lines (3/13/84)
+
+\ninepoint
+\ansno14.14:
+ Just say |\parfillskip|\stretch|=|\stretch|\parindent|. Of course,
+\TeX\ will not be able to find appropriate line breaks unless each
+paragraph is sufficiently long or sufficiently lucky; but with an
+appropriate text, your output will be immaculately
+symmetrical.{\parfillskip=\parindent\par}
+
+\bugonpage 324, line 16 (2/15/84)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss18.41.\enspace}%
+|$$\{\underbrace{\overbrace{\mathstrut a,\ldots,a}|
+
+\bugonpage 324, first line of answer 18.44 (4/11/84)
+
+\ninepoint
+\ansno18.44:
+ |$$\mathop{{\sum}'}_{x\in A}f(x)\mathrel{\mathop=^{\rm def}}|
+
+\bugonpage 333, beginning of the final paragraph (12/19/83)
+
+\ninepoint
+{\sl Note:\/} The stated preamble solves the problem and demonstrates
+that \TeX's line-breaking capability can be used within tables. But this
+particular table is not really a good example of the use of\/ |\halign|,
+because \TeX\ could typeset it directly, using ^|\everypar| in an
+appropriate manner to set up the hanging indentation, and using |\par|
+instead of\/ |\cr|. For example, one could say
+
+\bugonpage 341, the bottom line was left out! (2/9/84)
+
+\line{Footline\quad\dotfill\quad Page 1009}
+
+\bugonpage 345, top three lines (1/26/84)
+
+\ninepoint{\noindent\parfillskip=0pt
+A mathcode is relevant only when the corresponding category code is
+11 or~12; therefore many of these codes will rarely be looked at. For
+example, the math code for |^^M| specifies the character |\oplus|,
+but it's hard to imagine a user who would want |^^M|\par}
+
+\bugonpage 345, line 31 (2/29/84)
+
+\ninepoint\noindent
+|\delcode`\<="26830A \delcode`\\="26E30F \delcode`\>="26930B|
+
+\bugonpage 347, lines 1 and 2 (3/16/84)
+
+\ninepoint\noindent
+|\count18=3 % this counter allocates math families 4, 5, 6, ...|\hfil\break
+|\count19=255 % this counter allocates insertions 254, 253, 252, ...|
+
+\bugonpage 350, line 9 from the bottom (3/16/84)
+
+\ninepoint\noindent
+font, whose information does not have to be loaded again.
+
+\bugonpage 354, line 5 (6/7/84)
+
+\ninepoint\noindent
+|\def\ialign{\everycr={}\tabskip=0pt \halign} % initialized \halign|
+
+\bugonpage 355, lines 19--21 (7/3/84)
+
+\ninepoint\noindent
+subdivision in a document; to use it, you say
+`|\beginsection|\<section title>' followed by a blank line (or~|\par|).
+The macro first emits glue and penalties, designed to start a new page
+if the present page is nearly full; then it makes a ^|\bigskip| and
+puts the section{\parfillskip=0pt\par}
+
+\bugonpage 355, lines 27--29 (7/3/84)
+
+\ninepoint\noindent
+|\outer\def\beginsection#1\par{\vskip0pt plus.3\vsize\penalty-250|
+\par\noindent
+| \vskip0pt plus-.3\vsize\bigskip\vskip\parskip|
+\par\noindent
+| \message{#1}\leftline{\bf#1}\nobreak\smallskip\noindent}|
+
+\bugonpage 355, line 37 (4/24/84)
+
+\ninepoint\noindent
+|\outer\def\proclaim #1. #2\par{\medbreak|
+
+\bugonpage 356, seven lines from the bottom (4/11/84)
+
+\ninepoint\noindent
+|\def|^|\TeX||{T\kern-.1667em \lower.5ex\hbox{E}\kern-.125em X}|
+
+\bugonpage 359, starting with line 2 (11/16/83)
+
+\ninepoint
+\beginlines
+|\mathchardef\ldotp="602E\mathchardef\cdotp="6201\mathchardef\colon="603A|
+|\def\ldots{\mathinner{\ldotp\ldotp\ldotp}}|
+|\def\cdots{\mathinner{\cdotp\cdotp\cdotp}}|
+|\def\vdots{\vbox{\baselineskip=4pt \lineskiplimit=0pt|
+| \kern6pt \hbox{.}\hbox{.}\hbox{.}}}|
+|\def\ddots{\mathinner{\mskip1mu\raise7pt\vbox{\kern7pt\hbox{.}}\mskip2mu|
+| \raise4pt\hbox{.}\mskip2mu\raise1pt\hbox{.}\mskip1mu}}|
+\endlines
+
+\bugonpage 359, starting with line 19 (11/3/83)
+
+{\ninepoint\parindent=0pt
+|\def|^|\overbrace|%
+ |#1{\mathop{\vbox{\ialign{##\crcr\noalign{\kern3pt}|\parbreak%
+| \downbracefill\crcr\noalign{\kern3pt\nointerlineskip}|\parbreak%
+| $\hfil\displaystyle{#1}\hfil$\crcr}}}|^|\limits||}|
+
+|\def|^|\underbrace||#1{\mathop{\vtop{\ialign{##\crcr|\parbreak%
+| $\hfil\displaystyle{#1}\hfil$\crcr|%
+ |\noalign{\kern3pt\nointerlineskip}|\parbreak%
+| \upbracefill\crcr\noalign{\kern3pt}}}}\limits}|
+}
+
+\bugonpage 359, seventh line from the bottom (2/29/84)
+
+\ninepoint\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"000033E }|
+
+\bugonpage 361, line 3 (8/17/84)
+
+\ninepoint\noindent
+
+|\def\buildrel#1\over#2{\mathrel{\mathop{\null#2}\limits^{#1}}}|
+
+\bugonpage 363, line 10 (4/26/84)
+
+\ninepoint\noindent
+| \ifhmode\edef\@sf{\spacefactor=\the\spacefactor}\/\fi|
+
+\bugonpage 364, starting with line 10 (11/1/83)
+
+{\ninepoint\parindent=0pt
+|\def\dosupereject{\ifnum\insertpenalties>0 % something is being held over|%
+\parbreak
+| \line{}\kern-\topskip\nobreak\vfill\supereject\fi}|
+}
+
+\bugonpage 364, line 28 (7/8/84)
+
+\ninepoint\noindent
+| \tracingmacros=2 \tracingparagraphs=1 \tracingrestores=1 |
+
+\bugonpage 370, line 7 (3/16/84)
+
+\ninepoint\noindent
+information about the \TeX\ Users Group.)
+
+\bugonpage 374, line 23 (7/8/84)
+
+\ninepoint
+\line{log file when |\tracingmacros=2| and
+ |\tracingcommands=2|. One of the important ways}
+
+\bugonpage 379, line 1 (1/12/84)
+
+\ninepoint\noindent
+A particular item can be selected by its position number from the left:
+
+\bugonpage 381, line 6 (2/12/84)
+
+\ninepoint\indent
+|\newcount\lineno % the number of file lines listed|
+
+\bugonpage 381, lines 24 and 25 (12/15/83)
+
+\ninepoint
+{\parfillskip=0pt
+Instead of listing a file verbatim, you might want to define a |\verbatim|
+macro such that `|\verbatim{$this$|{\tt\ is }|{\it!}}|' yields
+`|$this$|{\tt\ is }|{\it!}|'. It's somewhat\par}
+
+\bugonpage 385, lines 22 and 23 (1/12/84)
+
+\ninepoint\noindent
+macro, a parameter, or a token list
+variable; (b)~when \TeX\ must determine whether the token
+|&|~or ^|\span| ^^{ampersand}
+or ^|\cr| or~^|\crcr| is the end of an entry within an ^{alignment}.
+
+\bugonpage 387, two paragraphs in right column (1/18/84)
+
+\setbox0=\vbox{
+\eightpoint
+\tolerance=9999
+\hbadness=2300
+\finalhyphendemerits=3000000
+\doublehyphendemerits=1000000
+\parskip=1pt
+\parindent=1.5em
+\frenchspacing
+\hsize=166.8125pt
+\def\\#1{\raise.5pt\hbox{$\scriptscriptstyle
+ \ifx#1`\langle\!\langle\else\rangle\!\rangle\fi$}% Spanish quote marks
+ \ifx#1`\nobreak\hskip0pt \fi} % allow hyphenation
+\item{A.} Exactamente. Pero los profesores son tan conservadores
+que temer\'\i an espantar al tipo de estudiante \\`apisonadora\\'
+que hace lo que le proponen para casa, obe\-dien\-te\-mente y de forma
+mec\'anica. Adem\'as, no creo que les gustase el trabajo adicional
+de calificar respuestas a preguntas abiertas.
+
+\item{}La forma tradicional es dejar la parte creativa para los cursos
+altos. Durante diecisiete a\~nos o m\'as se ense\~na al es\-tu\-diante a
+aprobar, luego de golpe, cerca de la graduaci\'on, se le pide que haga
+algo original.
+
+}\rightline{\box0}
+
+\bugonpage 395, lines 21 and 22 (1/12/84)
+
+\ninepoint\noindent
+{\parfillskip=0pt
+Notice that the macros need to do their own checking for ligatures, and
+they also take appropriate actions when a paragraph begins with an opening
+quote. Since |\kern|\par}
+
+\bugonpage 399, line 1 (1/10/84)
+
+\ninepoint
+{\parfillskip=0pt
+Inside the output routine, |\box\footins| will now be a vbox of hboxes, and
+\par}
+
+\bugonpage 399, line 9 (2/28/84)
+
+\ninepoint\indent
+|.\hbox(7.6359+0.0)x269.62617 []|
+
+\bugonpage 407, line 4 (6/10/84)
+
+\ninepoint\noindent
+|\beginlinemode| and |\beginparmode| are defined to initiate these
+modes; and another%
+{\parfillskip=0pt\par}
+
+\bugonpage 408, line 15 (12/14/83)
+
+\noindent
+| P. O. Box 1009, Haga Alto, CA 94321 USA}|
+
+\smallskip\noindent\ninepoint
+[Also change the ZIP code in the return address on the envelope
+illustrated at the bottom of page 405.]
+
+\bugonpage 409, line 5 (2/18/84)
+
+\ninepoint\noindent
+|\font\twelveit=cmti10 at 12pt % (a cheap substitute for cmti12)|
+
+\bugonpage 417, last six lines (8/25/84)
+
+\ninepoint\noindent
+^|\parskip|
+of |0pt| |plus|~|.8pt| between adjacent entries, and since there is room for
+more than 50 lines per column; therefore the |manmac| balancing routine tries
+to make both the top and bottom baselines agree at the end of the index.
+In applications where the glue is not so flexible it would be more
+appropriate to let the right-hand column be a little short; the best
+way to do this is probably to replace the command `|\unvbox3|' by
+`|\dimen2=|^|\dp||3| |\unvbox3| |\kern-\dimen2| ^|\vfil|'.
+
+\bugonpage 422, lines 24--26 (2/9/84)
+
+\ninepoint\noindent
+(The last two lines use |\d@nger| and |\dd@nger|, which are non-|\outer|
+equivalents of\/ |\danger| and |\ddanger|; such duplication is necessary
+because control sequences of type ^|\outer| cannot appear within a |\def|.)
+
+\bugonpage 428, in the table of sixteen basic fonts (12/19/83)
+
+\ninepoint\noindent
+[The special fonts called |cmi10| and |cmi7| and |cmi5| should really be
+called |cmmi10| and |cmmi7| and |cmmi5|.]
+
+\bugonpage 433, last eight lines (8/17/84)
+
+\noindent
+explained in Appendix~G\null. If you want to increase
+the number of parameters past the number that actually appear in a font's
+metric information file, you can assign new values immediately after that font
+has been loaded. For example, if some font |\ff| with seven parameters
+has just entered \TeX's memory, the command |\fontdimen13\ff=5pt| will set
+parameter number~13 to $5\pt$; the intervening parameters, numbers 8--12,
+will be set to zero. You can even give more than seven parameters to
+^|\nullfont|, provided that you assign the values before any actual fonts
+have been loaded.
+
+\bugonpage 445, line 6 (11/11/83)
+
+\ninepoint
+\line{if $(a-{1\over2}\theta)-
+\bigl(h(z)-v\bigr)<\varphi$, increase~$v$ by the difference. Finally
+construct a vbox of}
+
+\bugonpage 449, line 12 (1/18/84)
+
+\line{immediately clear why the `n' should
+be attached to the `e' in one case but not}
+
+\bugonpage 459, left column, line 2 (1/18/84)
+
+\eightpoint
+al-Khw\^arizm\^\i, abu Ja`far Mu\d{h}ammad
+
+\bugonpage 460, index entry for Beethoven (8/16/84)
+
+\eightpoint
+Change `von' to `van'.
+
+\bugonpage 461, third line in left column (8/25/84)
+
+\eightpoint The entry for |\box255| should not be indented.
+
+\bugonpage 461, index entry for boxed material (8/2/84)
+
+\eightpoint Add `{\it 420}'.
+
+\bugonpage 462, index entry for {\tt\char`\\colon} (11/16/83)
+
+\eightpoint Add page \underbar{359} to this list.
+
+\bugonpage 462, right column, third-last line (5/21/84)
+
+\eightpoint\indent
+[Change `crochets' to `crotchets'; then move this entry down two lines.]
+
+\bugonpage 463, right column, line 16 (5/20/84)
+
+\eightpoint\indent
+design size, 16--17, 213.
+
+\bugonpage 464, index entry for {\tt\char`\\dump} (1/10/84)
+
+\eightpoint Add page {\it 344\/} to this list.
+
+\bugonpage 464, right column, line 5 (1/5/84)
+
+\eightpoint
+Dvo\v r\'ak, Anton\'\i n Leopold, 409.
+
+\bugonpage 464, index entry for {\tt\char`\\end} (8/25/84)
+
+\eightpoint Page number 264 should be underlined.
+
+\bugonpage 465, index entry for {\tt\char`\\everydisplay} (8/25/84)
+
+\eightpoint Add page {\it 326\/} to this list.
+
+\bugonpage 465, index entry for {\tt\char`\\filbreak} (7/3/84)
+
+\eightpoint Delete the reference to page number 355.
+
+\bugonpage 466, index entry for {\tt\char`\\footnote} (4/26/84)
+
+\eightpoint Page number 363 should be underlined.
+
+\bugonpage 467, index entry for {\tt\char`\\hidewidth} (7/3/84)
+
+\eightpoint Page number 354 should be underlined.
+
+\bugonpage 468, index entry for insertions (8/25/84)
+
+\eightpoint Add pages 115--117, 122--125 to this list.
+
+\bugonpage 469, index entry for {\tt\char`\\kern} (11/1/83)
+
+\eightpoint Add page {\it 256\/} to this list.
+
+\bugonpage 470, index entry for {\tt\char`\\limits} (11/3/83)
+
+\eightpoint Add page {\it 359\/} to this list.
+
+\bugonpage 472, right column, lines 10--11 (7/9/84)
+
+{\eightpoint
+\indent
+|\normalbaselines|\kern1pt,
+ {\it 325}, 349, $\underline{351}$, {\it 414--415}.\par
+\baselineskip=9.9pt
+\indent
+|\normalbaselineskip|\kern1pt,
+ $\underline{349}$, {\it 414--415}.\par
+}
+
+\bugonpage 472, index entry for {\tt\char`\\null} (7/3/84)
+
+\eightpoint Page number 351 should be underlined.
+
+\bugonpage 472, right column, line 28 (1/3/84)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\nullfont|, 14, 153, 271, 433.
+
+\bugonpage 476, a new index entry (8/25/84)
+
+\eightpoint\indent
+shifted output, {\sl see\/} |\hoffset|, |\voffset|.
+
+\bugonpage 476, index entry for shriek (8/25/84)
+
+\eightpoint It should not be capitalized.
+
+\bugonpage 478, index entry for \'Swierczkowski (9/15/84)
+
+\eightpoint
+The middle name should be `S\l awomir'.
+
+\bugonpage 479, last seven lines in the left column (8/23/84)
+
+\eightpoint
+{\baselineskip=9.9pt
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingmacros|, $\underline{205}$, $\underline{212}$, 273, {\it329}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingonline|, 121, 212, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingoutput|, $\underline{254}$, 273, {\it301--302}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingpages|, {\it112--114}, 124, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingparagraphs|, {\it98--99}, 273, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingrestores|, 273, $\underline{301}$, $\underline{303}$.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tracingstats|, 273, $\underline{300}$, $\underline{303}$, {\it383}.
+}
+
+\bugonpage 479, index entry for underlined text (8/2/84)
+
+\eightpoint Add `{\sl see also\/} |\underbar|'.
+
+\bugonpage 480, index entry for {\tt\char`\\vbox} (11/1/83)
+
+\eightpoint Delete page 256 from this list.
+
+\bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata2.tex b/Master/texmf-doc/doc/english/knuth/errata/errata2.tex
new file mode 100644
index 00000000000..74dde877267
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata2.tex
@@ -0,0 +1,491 @@
+% More bugs (sigh) in The TeXbook
+
+\input manmac
+\proofmodefalse
+\raggedbottom
+\output{\onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\rhead{Bugs in {\tensl The \TeX book}, second printing}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule\line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule\nobreak\medskip}
+
+\noindent This is a list of all corrections made to {\sl The \TeX book\/}
+since the second printing. If your copy doesn't say `{\sl\kern-1pt Second
+printing (October 1984)\/}' on the copyright page, you should also look at
+the previous bug list. In fact, the most important corrections to the
+first printing were discovered first, so they've already been~made.
+
+\bugonpage 23, line 16 (10/13/84)
+
+\tenpoint\indent
+|This is TeX, Version 1.0 (preloaded format=plain 83.7.15)|
+
+\bugonpage 33, line 32 (10/21/84)
+
+The bottom line shows how far \TeX\ has gotten until now in the
+|story|{\parfillskip=0pt\par}
+
+\bugonpage 41, lines 7 and 8 (10/8/85)
+
+\ddanger The twin operations ^|\uppercase||{|\<token list>|}| and
+^|\lowercase||{|\<token list>|}| go through a given token list and convert
+all of the character tokens to their\parfillskip=0pt\enddanger
+
+\bugonpage 57, line 17 (1/6/86)
+
+|dd|\quad didot point ($\rm1157\,dd=1238\,pt$)
+
+\bugonpage 61, lines 17--19 (12/18/85)
+
+\ninepoint\noindent
+|depth|, |em|, |ex|,
+|fil|, |height|, |in|, |l|, |minus|, |mm|, |mu|, |pc|, |plus|,
+|pt|, |scaled|, |sp|, |spread|, |to|, |true|, |width|. ^^{reserved words}
+\ (See Appendix~I for references to the contexts in which each of these is
+recognized as a keyword.)
+
+\bugonpage 67, append a new exercise (1/19/85)
+
+\exno=5 \def\chapno{11}
+\gdef\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}
+
+\ddangerexercise Construct a |\frac| macro such that `|\frac1/2|' yields
+`\frac1/2'.
+
+\bugonpage 130, line 15 (4/17/85)
+
+\beginmathdemo
+|$y'''_3+g'^2$|&y'''_3+g'{}^2\cr
+\endmathdemo
+
+\bugonpage 170, line 5 (5/28/85)
+
+\ninepoint
+\line{tall, unslanted
+letter; and so on. But two of the examples involve corrections that were}
+
+\bugonpage 194, lines 13--15 should be centered better (10/22/84)
+
+\ninepoint
+$$\displaylines{\hfill x\equiv x;\hfill\llap{(1)}\cr
+ \hfill\hbox{if}\quad x\equiv y\quad\hbox{then}\quad
+ y\equiv x;\hfill\llap{(2)}\cr
+ \hfill\hbox{if}\quad x\equiv y\quad\hbox{and}\quad
+ y\equiv z\quad\hbox{then}\quad
+ x\equiv z.\hfill\llap{(3)}\cr}$$
+
+\bugonpage 215, lines 9 and 10 from the bottom (12/23/84)
+
+\ninepoint\noindent
+general format
+is the same as for |\def| and |\gdef|, but \TeX\ blindly expands the tokens
+of the replacement text according to the expansion rules above. For
+example, consider
+
+\bugonpage 233, lines 15--19 (1/19/85)
+
+\medskip
+\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
+\+&\negthinspace\it Weight&\it Servings&
+ {\it Approximate Cooking Time\/}*\cr
+\smallskip
+\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
+\+&9 lbs.&7 to 8&About 2 hours\cr
+\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
+\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
+
+\bugonpage 236, lines 18--21 (1/19/85)
+
+\ninepoint
+$$\vbox{\openup2pt
+\halign{\hfil\bf#&\quad\hfil\it#\hfil&\quad\hfil#\hfil&
+ \quad\hfil#\hfil&\quad#\hfil\cr
+Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr
+Broiler&Poulet Nouveau&2 to 3&1\frac1/2 to 2\frac1/2&Broil, Grill, Roast\cr
+Fryer&Poulet Reine&3 to 5&2 to 3&Fry, Saut\'e, Roast\cr
+Roaster&Poularde&5\frac1/2 to 9&Over 3&Roast, Poach, Fricassee\cr}}$$
+[This change should also be made at the bottom of page 237.]
+
+\bugonpage 236, fifth-last line (1/19/85)
+
+\ninepoint
+| Squab&Poussin&2&\frac3/4 to 1&Broil, Grill, Roast\cr|
+
+\bugonpage 237, line 25 (10/10/84)
+
+\ninepoint\noindent
+saying `^|\tabskip||=|\<glue>'. For example,
+let's do the poultry table again, but with the{\parfillskip=0pt\par}
+
+\bugonpage 265, bottom line (11/6/85)
+
+[insert a comma after `{\eightss LEONTIEF}'.]
+
+\bugonpage 271, line 8 (11/12/85)
+
+\ninepoint
+\beginsyntax
+<fil unit>\is[fil]\alt<fil unit>[l]
+\endsyntax
+
+\bugonpage 280, lines 7 and 8 (1/8/85)
+
+\ninepoint\noindent
+\<4-bit number>.\enskip
+The specified output stream is opened or closed, for use in |\write|
+commands, as explained in Chapter~21.
+
+\bugonpage 300, lines 5--10 [changed for version 1.3] (11/25/84)
+
+\ninepoint\noindent
+what part of \TeX's memory has become overloaded;
+one of the following fourteen things will be mentioned:
+\begindisplay
+|number of strings|\qquad(names of control sequences and files)\cr
+|pool size|\qquad(the characters in such names)\cr
+|main memory size|\qquad(boxes, glue, breakpoints, token lists,
+ characters, etc.)\cr
+\enddisplay
+
+\bugonpage 300, lines 23--29 [changed for version 1.3] (11/25/84)
+
+\danger If you have a job that doesn't overflow \TeX's capacity, yet
+you want to see just how closely you have approached the limits,
+just set ^|\tracingstats| to a positive value before the end of your
+job. The log file will then conclude with a report on your actual
+usage of the first eleven things named above (i.e., the number of strings,
+\dots, the save size), in that order. ^^{stack positions}
+Furthermore, if you set |\tracingstats| equal to 2~or~more, \TeX\
+will show its current memory usage whenever it
+does a ^|\shipout| command. Such statistics are broken into two
+parts; `|490&5950|' means, for example, that 490 words are being used
+for ``large'' things like boxes, glue, and
+breakpoints, while 5950 words are being used for ``small'' things like
+tokens and characters.
+
+\bugonpage 302, line 14 (10/8/85)
+
+\begintt
+.\tenrm || (ligature ---)
+\endtt
+
+\bugonpage 305, line 26 (12/24/84)
+
+\ninepoint\noindent
+sentable as |^^M|. Asking \TeX\ to |\show\^^M|
+\looseness-1
+produces the response `|>| |\^^M=macro:->\|\]|.|'.
+
+\bugonpage 306, line 10 (7/1/85)
+
+\ninepoint\noindent
+no ``^{explicit kerns},'' and an italic correction is an
+explicit kern.) \ But the italic correction may be too much (especially in an
+italic font); |shelf{|^|\kern||0pt}ful| is often best.
+
+\bugonpage 308, line 25 (3/25/85)
+
+\ninepoint\indent
+|\def\appendroman#1#2#3{\edef#1{\def\noexpand#1{\csname|
+
+\bugonpage 311, insert a new answer (1/19/85)
+
+\ninepoint
+\ansno11.6:
+ |\def\frac#1/#2{\leavevmode\kern.1em|\parbreak
+|\raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em|\parbreak
+|/\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}|
+
+\smallskip\noindent[This causes answer 12.8 to move to page 312;
+answer 12.16 also moves to page 313.]
+
+\bugonpage 320, lines 17--20 (8/10/85)
+
+\ninepoint
+\ansno17.16:
+ |\def\sqr#1#2{{\vcenter{\vbox{\hrule height.#2pt|\parbreak
+ | \hbox{\vrule width.#2pt height#1pt \kern#1pt|\parbreak
+ | \vrule width.#2pt}|\parbreak
+ | \hrule height.#2pt}}}}|
+
+\bugonpage 327, lines 26--33 (10/22/84)
+
+\ninepoint
+\ansno19.16:
+ |$$\displaylines{\hfill x\equiv x;\hfill\llap{(1)}\cr|\parbreak
+ | \hfill\hbox{if}\quad x\equiv y\quad\hbox{then}\quad|\parbreak
+ | y\equiv x;\hfill\llap{(2)}\cr|\parbreak
+ | \hfill\hbox{if}\quad x\equiv y\quad\hbox{and}\quad|\parbreak
+ | y\equiv z\quad\hbox{then}\quad|\parbreak
+ | x\equiv z.\hfill\llap{(3)}\cr}$$|\par\medskip\noindent
+There's also a trickier solution, which begins with
+\begintt
+$$\displaylines{x\equiv x;\hfil\llap{(1)}\hfilneg\cr
+\endtt
+
+\bugonpage 330, line 29 (11/15/85)
+
+\ninepoint\indent
+|\edef\next#1#2{\def#1{\b#2\d}} \next\a\c|
+
+\bugonpage 332, lines 17--24 (1/19/85)
+
+\ninepoint
+\begintt
+\settabs\+\indent&10\frac1/2 lbs.\qquad&\it Servings\qquad&\cr
+\+&\negthinspace\it Weight&\it Servings&
+ {\it Approximate Cooking Time\/}*\cr
+\smallskip
+\+&8 lbs.&6&1 hour and 50 to 55 minutes\cr
+\+&9 lbs.&7 to 8&About 2 hours\cr
+\+&9\frac1/2 lbs.&8 to 9&2 hours and 10 to 15 minutes\cr
+\+&10\frac1/2 lbs.&9 to 10&2 hours and 15 to 20 minutes\cr
+\endtt
+
+\bugonpage 332, lines 33--35 (1/19/85)
+
+\ninepoint\noindent
+proofs. \ (You weren't supposed to think of this,
+but it has to be mentioned.) \ See exercise 11.\fracexno\ for the `|\frac|'
+macro; it's better to say `\frac1/2' than `$1\over2$', in a cookbook.\par
+Another way to treat this table would be to display it in a vbox, instead
+of including a first column whose sole purpose is to specify indentation.
+
+\bugonpage 337, line 28 (11/12/85)
+
+\ninepoint\noindent |\nextnumber|. Quick should put `|\relax|'
+at the end of his macro. \ (The {keywords} |l|,{\parfillskip=0pt\par}
+
+\bugonpage 357, lines 35 and 36 (1/8/85)
+
+\ninepoint\noindent
+|\def\*{\discretionary{\thinspace\the\textfont2\char2}{}{}}|
+
+\bugonpage 357, last two lines (4/17/85)
+
+\ninepoint\noindent
+|\def\pr@m@s{\ifx'\next\let\next\pr@@@s|%
+ | \else\ifx^\next\let\next\pr@@@t|\par\noindent
+| \else\let\next\egroup\fi\fi \next}|\par\noindent
+|\def\pr@@@s#1{\prim@s} \def\pr@@@t#1#2{#2\egroup}|
+
+\bugonpage 358, lines 8--12 (1/23/85)
+
+\ninepoint\noindent
+|\def\hbar{{\mathchar'26\mkern-9muh}}|\hfil\break\null
+|\def\surd{{\mathchar"1270}}|\hfil\break\null
+|\def\angle{{\vbox{\ialign{$\m@th\scriptstyle##$\crcr|\hfil\break\null
+| \not\mathrel{\mkern14mu}\crcr \noalign{\nointerlineskip}|\hfil\break\null
+| \mkern2.5mu\leaders\hrule height.34pt\hfill\mkern2.5mu\crcr}}}}|
+
+\bugonpage 359, lines 7--8 (1/22/85)
+
+\ninepoint\noindent
+|\def\ddots{\mathinner{\mkern1mu\raise7pt\vbox{\kern7pt\hbox{.}}\mkern2mu|%
+\hfil\break\null
+| \raise4pt\hbox{.}\mkern2mu\raise1pt\hbox{.}\mkern1mu}}|
+
+\bugonpage 360, line 22 (1/22/85)
+
+\ninepoint\noindent
+| \mkern5mu \raise.6\dimen@\copy\rootbox \mkern-10mu \box0}|
+
+\bugonpage 361, line 3 (3/27/85)
+
+\ninepoint\noindent
+|\def\buildrel#1\over#2{\mathrel{\mathop{\kern0pt #2}\limits^{#1}}}|
+
+\bugonpage 361, lines 19--20 (1/22/85)
+
+\ninepoint\noindent
+|\def\bmod{\mskip-\medmuskip \mkern5mu|\hfil\break\null
+| \mathbin{\rm mod} \penalty900 \mkern5mu \mskip-\medmuskip}|
+
+\bugonpage 361, line 27 (5/1/85)
+
+\ninepoint\noindent
+|\def\matrix#1{\null\,\vcenter{\normalbaselines\m@th|
+
+\bugonpage 361, bottom line (5/1/85)
+
+\ninepoint\noindent
+| \null\;\vbox{\kern\ht1\box2}\endgroup}|
+
+\bugonpage 362, line 9 (5/1/85)
+
+\ninepoint\noindent
+|\def\eqalign#1{\null\,\vcenter{\openup1\jot \m@th|
+
+\bugonpage 362, lines 17--29 (8/10/85)
+
+{\parindent=0pt\ninepoint
+|\def\@lign{\tabskip=0pt\everycr={}} % restore inside \displ@y|\par
+|\def|^|\displaylines||#1{\displ@y|\parbreak%
+| \halign{\hbox to\displaywidth{|%
+ |$\hfil\@lign\displaystyle##\hfil$}\crcr|\parbreak%
+| #1\crcr}}|
+\smallbreak
+|\def|^|\eqalignno||#1{\displ@y \tabskip=|^|\centering|\parbreak%
+| \halign to\displaywidth{\hfil$\@lign\displaystyle{##}$\tabskip=0pt|\parbreak%
+| &$\@lign\displaystyle{{}##}$\hfil\tabskip=\centering|\parbreak%
+| &\llap{$\@lign##$}\tabskip=0pt\crcr|\parbreak%
+| #1\crcr}}|\par
+|\def|^|\leqalignno||#1{\displ@y \tabskip=\centering|\parbreak%
+| \halign to\displaywidth{\hfil$\@lign\displaystyle{##}$\tabskip=0pt|\parbreak%
+| &$\@lign\displaystyle{{}##}$\hfil\tabskip=\centering|\parbreak%
+| &\kern-\displaywidth\rlap{$\@lign##$}\tabskip=\displaywidth\crcr|\parbreak%
+| #1\crcr}}|
+\par}
+
+\bugonpage 363, line 9 (5/12/85)
+
+\ninepoint\noindent
+|\def\footnote#1{\let\@sf=\empty % parameter #2 (the text) is read later|
+
+\bugonpage 364, line 3 (3/23/85)
+
+\ninepoint\noindent
+|\def\plainoutput{\shipout\vbox{\makeheadline\pagebody\makefootline}%|
+
+\bugonpage 364, fifth-last line (9/15/85)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.0} % identifies the current format|
+
+\bugonpage 399, eighth-last line (2/11/85)
+
+\ninepoint\noindent
+| \baselineskip=\footnotebaselineskip\noindent\unhbox0\par}|
+
+\bugonpage 401, line 5 (1/29/85)
+
+\ninepoint\noindent
+{|\fontdimen| parameters to qualify as a math symbol font).
+(2)~Set all the font identifiers\parfillskip=0pt\par}
+
+\bugonpage 414, line 10 (12/17/84)
+
+\ninepoint\noindent
+|\font\titlefont=cmssdc40 % titles in chapter openings|
+
+%\bugonpage 420, line 9 (10/3/85)
+%
+%\ninepoint\noindent
+%|\def\AmSTeX{$\cal A\kern-.1667em\lower.5ex\hbox{$\cal M$}\kern-.075em|
+% that change comes under `font data', explained away below
+
+\bugonpage 444, bottom line (1/10/85)
+
+\ninepoint\noindent
+depth $d(z)+v$, consisting
+of box~$x$ followed by an appropriate kern followed by box~$z$.
+
+\bugonpage 461, entry for character codes (11/6/85)
+
+\eightpoint
+Add `{\sl see also\/} category codes'.
+
+\bugonpage 463, entries for {\tt dd}, Didot, and didot (1/6/86)
+
+\eightpoint
+Remove the circumflex accents.
+
+\bugonpage 466, left column (1/19/85)
+
+\eightpoint
+fractions, 67, 139--143, 152, 170, 179,\par
+\qquad 186, 444--445.\par
+\quad huge, 196.\par
+\quad slashed form, 67, 139--140, 233, 236.
+
+\bugonpage 467, index entry for {\tt\char`\\hsize} (6/14/85)
+
+\eightpoint
+Add a reference to page {\it 60}.
+
+\bugonpage 469, index entry for {\tt\char`\\kern} (7/1/85)
+
+\eightpoint
+Add a reference to page {\it 306}.
+
+\bugonpage 469, index entry for kerns (7/1/85)
+
+\eightpoint
+Add a reference to page 306.
+
+\bugonpage 469, new entry (11/12/85)
+
+\eightpoint
+|l| after |fil|, $\underline{271}$, 337.
+
+\bugonpage 469, second line on the right (9/13/85)
+
+\eightpoint
+%\def\LaTeX{L\kern-.25em\raise.7ex\hbox{a}\kern-.05em\TeX} % old style
+{L\kern -.36em\raise.6ex\hbox{\sixrm A}\kern-.15em\TeX}, 137.
+
+\bugonpage 470, index entries for {\tt\char`\\longleftarrow}
+ thru {\tt\char`\\Longrightarrow} (10/5/84)
+
+\eightpoint
+The references to page 358 should be underlined (seven times).
+
+\bugonpage 475, index entry for punctuation in formulas (4/29/85)
+
+\eightpoint
+Add a reference to page 161.
+
+\bugonpage 476, index entry for {\tt\char`\\scriptspace} (8/10/85)
+
+\eightpoint
+Change `445' to `445--446'.
+
+\bugonpage 478, first and last lines (10/11/84)
+
+\noindent Delete the last line in the right-hand column
+(since it appears on page 479), and add the following line
+at the top of the left-hand column (since it was dropped by mistake
+from the second printing):
+
+\smallskip
+\eightpoint styles of math formatting, 140--141, 441--447.
+
+\bugonpage 478, new entry after tabbing (5/28/85)
+
+\eightpoint
+tables, {\sl see\/} alignments, tabbing.
+
+\bugonpage 478, tabskip entries (3/25/85)
+
+\eightpoint\noindent Instead of `237--239' and `237--238' it should say
+`$\underline{237}$--$\underline{239}$' twice.
+
+\bugonpage 481, the entry for {\tt\char`\\widetilde} (9/23/85)
+
+\eightpoint
+Page 359 should be underlined.
+
+\bugonpage 483, lines 16--17 (1/19/85)
+
+|P.O. Box 9506|\parbreak
+|Providence RI 02940-9506, USA.|
+
+\bugonpage 483, lines 22--23 (1/19/85)
+
+P.O. Box 9506\par
+Providence RI 02940-9506, USA.
+
+\bigskip
+\hrule
+\bigskip\noindent\tenrm
+Note: The next printing will use the ``real'' Computer Modern fonts
+instead of the ``almost'' Computer Modern fonts. Therefore many of
+the line breaks will be slightly different. Also, the font-related
+numerical data on pages 27, 29, 66, 75, 76, 79, 88, 98, 99, 112, 113, 310,
+314, 396, 399, 409, 420, and 459 will be different. However, these
+differences need not be listed here, because the old book was correct with
+respect to the old fonts.
+
+\bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata3.tex b/Master/texmf-doc/doc/english/knuth/errata/errata3.tex
new file mode 100644
index 00000000000..5f00f73b22e
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata3.tex
@@ -0,0 +1,1898 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A--E\null, between the date of publication
+(May, 1986) and 15~June 1987.
+It also includes corrections made to
+the softcover version of {\sl The \TeX book}, beginning with the
+sixth printing (January 1986); these are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+ % volume A
+\bugonpage A7, fourth line from the bottom (6/28/86)
+
+\tenpoint\line{%
+since control sequences of the second kind always have exactly one
+symbol after}
+
+\bugonpage A35, second-last line (1/31/87)
+
+\rightline{\eightssi He may run who reads.}
+\smallskip
+\rightline{\eightss--- HABAKKUK 2\thinspace:\thinspace2 (c.~600 B.C.)}
+\smallskip
+\rightline{\eightssi He that runs may read.}
+
+\bugonpage A43, lines 8--9 (8/23/86)
+
+\tenpoint\noindent
+of Appendix B\null, which defines |%| to be a special kind of symbol so that you
+can use it for comments, defines the control sequence |\%| to mean
+a percent sign.
+
+\bugonpage A45, lines 10--13 (8/23/86)
+
+\ninepoint\noindent
+\TeX\ adds~64. Hence
+code 127 can be typed |^^?|, and
+the dangerous bend sign can be obtained by saying
+|{\manual^^?}|. However, you must change the category code of character
+127 before using it, since this character ordinarily has category~15
+(^{invalid}); say, e.g., |\catcode`\^^?=12|.
+The |^^| notation is different from |\char|, because |^^|\cutpar
+
+\bugonpage A76, line 7 (8/23/86)
+
+\ninepoint
+\noindent
+and extra space; for example, these quantities are
+$3.33333\pt$, $1.66666\pt$, $1.11111\pt$,\cutpar
+
+\bugonpage A83, bottom line (5/19/87)
+
+\tenpoint\noindent[This line should be flush right.]
+
+\bugonpage A111, 7th-last line, right-hand column (2/15/87)
+
+\ninepoint
+if $b=10000$ and $-10000<p<10000$ and $q<10000$;
+
+\bugonpage A117, second-last line (6/10/87)
+
+\eightpoint
+marks; sometimes also |$\|\||$| ($\Vert$).
+You can say, e.g., `|\footnote\dag{...}|'.
+
+\bugonpage A124, lines 6--11 (2/26/87)
+
+\begingroup \def\n{\thinspace$n$}
+\ninepoint\noindent
+of insertion; an additional `|\penalty-10000|' item is assumed
+to be present at the end of the vertical list, to ensure that a legal
+breakpoint exists.) \ Let $u$ be the natural height plus depth of that
+least-cost box, and let $r$ be the penalty associated with the optimum
+breakpoint. Decrease $g$ by~$uf$, and increase $q$ by~$r$. \ (If
+|\tracingpages||=1|, the log file should now get a cryptic message that says
+`|% split|\n\ |to| $v$|,|$u$ |p=|$r$'. For~example,
+\begintt
+% split254 to 180.2,175.3 p=100
+\endtt
+\endgroup
+
+\bugonpage A158, lines 6--8 (2/20/87)
+
+\ninepoint\noindent the
+second atom, which has subscript~$i$; the superscripts are empty except for the
+last atom, whose superscript is~$\overline{n+1}$. This superscript is
+itself a math list consisting of one atom, whose nucleus is~$n+1$; and that
+nucleus is a math list consisting of three atoms.
+
+\bugonpage A171, line 20 (1/26/86)
+
+\ninepoint\line{%
+will be surrounded by more space than there would be
+if that subformula were enclosed}
+
+\bugonpage A176, line 1 (8/23/86)
+
+\ninepoint
+You can insert `|\noalign||{|$\langle$vertical mode
+material$\rangle$|}|' just after any \kern-1pt|\cr| within\cutpar
+
+\bugonpage A248, line 17 (6/17/86)
+
+\ninepoint
+`|&|' or `|\span|' or `|\cr|', it needs some way to decide which
+alignment is involved.\cutpar
+
+\bugonpage A249, line 20 (6/17/86)
+
+\ninepoint\noindent
+line (see Chapter~8).
+If you don't want a~|\cr| at the end of a certain line,
+just type\cutpar
+
+\bugonpage A276, line 19 (1/27/86)
+
+\ninepoint\vskip-3pt
+\beginsyntax
+ \alt^|\font|<control sequence><equals><file name><at clause>
+ \alt<global assignment>
+\endsyntax
+[The bottom line of p.~276 will now move to the top of p.~277.]
+
+\bugonpage A277, lines 31--32 (1/27/86)
+
+\ninepoint
+\beginsyntax
+<font assignment>\is^|\fontdimen|<number><font><equals><dimen>
+\endsyntax
+
+\bugonpage A286, sixth-last line (4/28/87)
+
+\ninepoint\noindent
+|\sfcode| table as described in Chapter~12; characters numbered 128
+to~255 set the\cutpar
+
+\bugonpage A287, line 19 (2/15/87)
+
+\ninepoint
+\textindent{$\bull$}|\-|.\enskip
+This ``discretionary hyphen'' command is defined in Appendix H.
+
+\bugonpage A292, lines 9--10 (2/15/87)
+
+\ninepoint
+\textindent{$\bull$}|\-|.\enskip
+This command is usually equivalent to `|\discretionary{-}{}{}|'; the `|-|' is
+therefore interpreted as a ^{hyphen}, not as a minus sign.
+\ (See Appendix~H.)
+
+\bugonpage A308, lines 25--26 (6/1/87)
+
+\ninepoint\indent
+|\def\appendroman#1#2#3{\edef#1{\csname|\parbreak
+| \expandafter\gobble\string#2\romannumeral#3\endcsname}}|
+
+\bugonpage A312, lines 10--14 (8/23/86)
+
+\ninepoint
+\ansno12.11: The interline glue will be zero, and the natural height is
+$1+1-3+2=1\pt$ (because the depth of\/ |\box2| isn't included in the natural
+height); so the glue will ultimately become |\vskip-1pt| when it's set.
+Thus, |\box3| is $3\pt$ high, $2\pt$ deep, $4\pt$ wide. Its reference
+point coincides with that of\/ |\box2|; to get to the reference point
+of\/ |\box1| you go up $2\pt$ and right $3\pt$.
+
+\bugonpage A312, line 21 (8/23/86)
+
+\ninepoint\noindent
+up $4\pt$ to get to the upper left corner of
+|\box4|; then down $-1.6\pt$, i.e., up $1.6\pt$, to\cutpar
+
+\bugonpage A319, line 20 (31/3/87)
+
+\ninepoint\noindent
+make ordinary periods act like |\cdot| symbols: Just define
+|\mathcode`.| to be |"0201|,\cutpar
+
+\bugonpage A328, lines 18--19 (5/14/87)
+
+\ninepoint\noindent
+not performed
+while the expansion is taking place, and the control sequences following
+|\def| are expanded; so the result is an infinite string
+\begintt
+A\def A\def A\def A\def A\def A\def A\def A\def A...
+\endtt
+
+\bugonpage A329, lines 14--15 (8/23/86)
+
+\ninepoint
+\ansno20.5: The |##| feature is indispensable when the replacement text of
+a definition contains other definitions. For example, consider
+
+\bugonpage A356, lines 6--7 (1/30/87)
+
+\ninepoint\noindent
+| \spaceskip=.3333em \xspaceskip=.5em\relax}|\hfil\break
+|\def\ttraggedright{\tt\rightskip=0pt plus2em\relax}|
+
+\bugonpage A356, line 33 (6/1/87)
+
+\ninepoint\noindent
+| \vbox to.2ex{\hbox{\char'26}\vss}\hidewidth}}|
+
+\bugonpage A357, tenth-last line (10/13/86)
+
+\ninepoint\noindent
+|\let\sp=^ \let\sb=_ {\catcode`\_=\active \global\let_=\_}|
+
+\bugonpage A357, third-last and second-last lines (2/17/87)
+
+\ninepoint\noindent
+|\def\pr@m@s{\ifx'\next\let\nxt\pr@@@s \else\ifx^\next\let\nxt\pr@@@t|%
+\hfil\break\strut
+| \else\let\nxt\egroup\fi\fi \nxt}|
+
+\bugonpage A364, fifth-last line (1/30/87)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.3} % identifies the current format|
+
+\bugonpage A368, bottom line (2/26/86)
+
+\ninepoint
+\line{that includes the symbols
+{\tentex\char'30},~{\tentex\char1}, {\tentex\char'32}, {\tentex\char'34},
+and~{\tentex\char'35}, and he finds that this makes it much more}
+
+\bugonpage A396, line 13 (8/23/86)
+
+\ninepoint
+| \hyphenpenalty=10000 \exhyphenpenalty=10000|
+
+\bugonpage A414, line 10 (3/4/86)
+
+\ninepoint\noindent
+|\font\titlefont=cmssdc10 at 40pt % titles in chapter openings|
+
+\bugonpage A427, line 7 (2/23/86)
+
+\ninepoint\noindent
+the author's book
+{\sl Computer Modern Typefaces}.)
+
+\bugonpage A428, lines 18--20 (6/15/87)
+
+\tenpoint\noindent
+The first eight of these all have essentially the same layout;
+but |cmr5| needs no ligatures, and many of the symbols of |cmti10|
+have different shapes.
+For example, the ^{ampersand} becomes an `^{E.T.}', and the
+^{dollar} changes to ^{pound} ^{sterling}:
+
+\bugonpage A434, lines 25--28 (8/17/86)
+
+\tenpoint\noindent
+from |\nu|~($\nu$). Similarly,
+|\varsigma|~($\varsigma$) should not be confused with |\zeta|~($\zeta$).
+It turns out that |\varsigma| and |\upsilon| are almost never used in
+math formulas; they are included in plain \TeX\ primarily because they are
+sometimes needed in short Greek citations (cf.~Appendix~J).
+
+\bugonpage A447, line 32 (6/1/87)
+
+\ninepoint\noindent
+ters
+also affect mathematical typesetting:
+dimension parameters
+ \hbox{|\delimitershortfall|}\cutpar
+
+\bugonpage A455, new paragraph to follow line 9 (2/15/87)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger The control sequence ^|\-| is equivalent to
+|\discretionary{\char|$\,h$|}{}{}|, where $h$ is the
+^|\hyphenchar| of the current font, provided that $h$ lies
+between 0 and~255. Otherwise |\-| is equivalent to |\discretionary{}{}{}|.
+
+\endgroup % end the special hyphenation conventions
+
+\bugonpage A457, left column, fifth-last line (2/17/87)
+
+\eightpoint\indent\qquad 155, 201, {\it 305}, 324, $\underline{357}$, 394--395;
+
+\bugonpage A458, left column, line 6 (2/15/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\-} (discretionary hyphen), 95, 283, 287,\par
+\indent\qquad 292, $\underline{455}$.
+
+\bugonpage A458, left column, near the bottom (5/19/87)
+
+\eightpoint {\tt!} (exclamation point), 51,
+{\it 72}, 73, 75, {\it 169}.
+\nobreak\medskip\noindent[This saves a line that otherwise would make
+the index too long on page 481!]
+
+\bugonpage A458, right column, line 10 (11/27/86)
+
+\eightpoint {\tt\char`\~}
+(tilde), 38, 51, 343, $\underline{353}$; {\sl see also\/} ties.
+
+\bugonpage A458, right column (6/14/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\accent} (general accent), 9, 54, 86, 283, $\underline{286}$.
+
+\bugonpage A461, entry for boxes (3/16/87)
+
+\eightpoint boxes, 63--67, 77--83, 221--229.
+
+\bugonpage A461, entry for {\tt\char`\\centering} (1/28/86)
+
+\eightpoint {\tt\char`\\centering}, $\underline{347}$, 348, 362.
+
+\bugonpage A462, entry for \<code assignment> (1/27/86)
+
+\eightpoint \<code assignment>, $\underline{277}$.
+
+\bugonpage A464, left column, line 3 (2/15/87)
+
+\eightpoint
+discretionary hyphens, 28, 95--96, 453, $\underline{455}$.
+
+\bugonpage A465, right column, line 8 (5/3/87)
+
+\eightpoint
+expansion of expandable tokens, 212--216, 238,
+
+\bugonpage A466, entry for {\tt\char`\\font}, second line (1/27/86)
+
+\eightpoint \indent\qquad 271, $\underline{276}$.
+
+\bugonpage A466, new entry (2/3/87)
+
+\eightpoint \indent\<fontdef token>, $\underline{271}$.
+
+\bugonpage A467, entry for {\tt\char`\\hideskip} (1/28/86)
+
+\eightpoint {\tt\char`\\hideskip}, $\underline{347}$, 348, 354.
+
+\bugonpage A468, left column line 2 (2/15/87)
+
+\eightpoint\indent\qquad 351, 395, {\it 414}, 454, 455.
+
+\bugonpage A470, entry for {\tt manfnt} (1/15/86)
+
+\eightpoint {\tt manfnt}, 44, 408, 414.
+
+\bugonpage A471, entry for {\tt\char`\\medbreak} (10/13/86)
+
+\eightpoint {\tt\char`\\medbreak}, 111, 113, $\underline{353}$,
+ {\it355}, {\it419}, {\it422}.
+
+\bugonpage A471, entry for {\tt\char`\\moveright} (2/27/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\moveright}, 80--81, {\it 221}, $\underline{282}$.
+
+\bugonpage A471, entry for Mozart, second line (3/19/86)
+
+\eightpoint \indent\qquad Gottlieb (= Theophilus = Amadeus), 409.
+
+\bugonpage A472, the entry for {\tt\char`\\not} (2/12/87)
+
+\eightpoint\noindent
+[The overprinting here is intentional, since {\tt\char`\\not} is a
+character of width zero. More than a dozen people have reported this
+as an error, but it is not!]
+
+\bugonpage A477, entry for {\tt\char`\\span} (5/3/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\span}, 215, 238, $\underline{243}$, {\it244}, $\underline{245}$,
+248, 249,\par
+\indent\qquad 282, {\it330}, 385.
+
+\bugonpage A479, entry for ties, second line (11/27/86)
+
+\eightpoint \indent\qquad {\it173}, 353, {\it404}.
+
+\bugonpage A480, changes to various entries (6/14/87)
+
+\eightpoint
+\newbox\astbox \setbox\astbox=\hbox to0pt{\hss\lower1pt\hbox{*}}
+\def\prim#1{\par\indent\copy\astbox{\tt\char`\\#1}}
+\prim{underline}, {\it130--131}, 141, 291, $\underline{443}$.
+\prim{unhbox}, 120, 283, $\underline{285}$, {\it354}, {\it356}, {\it361},
+ {\it399}.
+\prim{unhcopy}, 120, 283, $\underline{285}$, {\it353}.
+\prim{unkern}, $\underline{280}$.
+\prim{unpenalty}, $\underline{280}$.
+\prim{unskip}, 222--223, $\underline{280}$, 286, {\it313}, {\it392},
+ {\it418--419}.
+\prim{unvbox}, 120, 254, $\underline{282}$, 286, {\it354}, {\it361},
+ {\it363}, {\it364}, {\it392}, {\it399}, {\it417}.
+\prim{unvcopy}, 120, $\underline{282}$, 286, {\it361}.
+\prim{vadjust}, 95, 105, 109, 110, 117, 259, $\underline{281}$, 393, 454.
+\prim{valign}, 249, 283, $\underline{285}$--$\underline{286}$, 302,
+ {\it335}, {\it397}.
+\prim{vcenter}, 150--151, 159, 170, 193, 222, 242,
+\prim{vfil}, 71, $\underline{72}$, 111, 256, 281, 286, 417.
+\prim{vfill}, 24, 25, 71, $\underline{72}$, 256--257, 281, 286.
+\prim{vfilneg}, $\underline{72}$, 111, 281, 286.\par
+|\voidb@x|, $\underline{347}$, 348.
+
+\bugonpage A481, left column (6/14/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\vss}, 71, $\underline{72}$, {\it 255}, 281, 286.
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\buginvol B, in general (7/28/86)
+
+\tenpoint\noindent
+[A number of entries were mistakenly omitted from the mini-indexes
+on the right-hand pages. Here is a combined list of all the missing
+items; you can mount it inside the back cover, say, as a secondary mini-index
+when the first one fails\dots\ ]
+
+\nobreak\medskip
+\setbox0=\vbox{\eightpoint \hsize=11pc \catcode`\_=\active \let_=\_
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+ \obeylines
+ \def\makeref #1 #2 #3#4
+ {\nn=#2 \hangindent=1em \noindent\\{#1}%
+ \if#3:: \else\unhcopy\eqbox \fi#4, \S\number\nn.\par}
+ \makeref active_base 222 =$1$
+ \makeref aux 213 =macro
+ \makeref begin_name 515 :\&{procedure}
+ \makeref big_switch 1030 =$60$
+ \makeref choice_node 689 =$15$
+ \makeref cur_boundary 271 :$0\to \\{save\_size}$
+ \makeref cur_c 724 :\\{quarterword}
+ \makeref cur_group 271 :\\{group\_code}
+ \makeref cur_i 724 :\\{four\_quarters}
+ \makeref cur_level 271 :\\{quarterword}
+ \makeref do_extension 1348 :\&{procedure}
+ \makeref dvi_buf 595 :\&{array}
+ \makeref dvi_gone 595 :\\{integer}
+ \makeref dvi_limit 595 :\\{dvi\_index}
+ \makeref dvi_offset 595 :\\{integer}
+ \makeref dvi_ptr 595 :\\{dvi\_index}
+ \makeref end_graf 1096 :\&{procedure}
+ \makeref error 82 :\&{procedure}
+ \makeref error_stop_mode 73 =$3$
+ \makeref font_base 12 =$0$
+ \makeref font_info 549 :\&{array}
+ \makeref get_token 365 :\&{procedure}
+ \makeref glue_base 222 =$2626$
+ \makeref half_buf 595 :\\{dvi\_index}
+ \makeref handle_right_brace 1068 :\&{procedure}
+ \makeref hash_base 222 =$258$
+ \makeref head 213 =macro
+ \makeref hyf_distance 921 :\&{array}
+ \makeref hyf_next 921 :\&{array}
+ \makeref hyf_num 921 :\&{array}
+ \makeref index 302 =macro
+ \makeref inf 448 :\\{boolean}
+ \makeref init_col 788 :\&{procedure}
+ \makeref init_span 787 :\&{procedure}
+ \makeref input_ln 31 :\&{function}
+ \makeref interaction 73 :$0\to 3$
+ \makeref limit 302 =macro
+ \makeref line_width 830 :\\{scaled}
+ \makeref macro_call 389 :\&{procedure}
+ \makeref main_control 1030 :\&{procedure}
+ \makeref mem 116 :\&{array}
+ \makeref mem_bot 12 =$0$
+ \makeref mem_end 118 :\\{pointer}
+ \makeref mem_top 12 =macro
+ \makeref mlist_to_hlist 726 :\&{procedure}
+ \makeref mode 213 =macro
+ \makeref mode_line 213 =macro
+ \makeref more_name 516 :\&{function}
+ \makeref mu 448 :\\{boolean}
+ \makeref name 302 =macro
+ \makeref nest 213 :\&{array}
+ \makeref off_save 1064 :\&{procedure}
+ \makeref open_log_file 534 :\&{procedure}
+ \makeref output_active 989 :\\{boolean}
+ \makeref p 498 :\\{pointer}
+ \makeref param_stack 308 :\&{array}
+ \makeref pool_file 50 :\\{alpha\_file}
+ \makeref pool_ptr 39 :\\{pool\_pointer}
+ \makeref prefixed_command 1211 :\&{procedure}
+ \makeref prev_depth 213 =macro
+ \makeref prev_graf 213 =macro
+ \makeref prev_prev_r 830 :\\{pointer}
+ \makeref print_err 73 =macro
+ \makeref r 960 :\\{trie\_pointer}
+ \makeref reconstitute 906 :\&{function}
+ \makeref resume_after_display 1200 :\&{procedure}
+ \makeref save_ptr 271 :$0\to \\{save\_size}$
+ \makeref save_stack 271 :\&{array}
+ \makeref scan_dimen 448 :\&{procedure}
+ \makeref scan_math 1151 :\&{procedure}
+ \makeref short_display 174 :\&{procedure}
+ \makeref show_node_list 182 :\&{procedure}
+ \makeref start 302 =macro
+ \makeref state 302 =macro
+ \makeref str_pool 39 :\&{packed}\ \&{array}
+ \makeref str_ptr 39 :\\{str\_number}
+ \makeref str_start 39 :\&{array}
+ \makeref tail 213 =macro
+ \makeref trap_zero_glue 1229 :\&{procedure}
+ \makeref trie 921 :\&{array}
+ \makeref trie_char 921 =macro
+ \makeref trie_link 921 =macro
+ \makeref trie_op 921 =macro
+ \makeref vlist_out 629 :\&{procedure}
+ \makeref write_loc 1345 :\\{pointer}
+ }
+\hbox{\nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}}
+
+\buginvol B, in general (4/6/87)
+
+\tenpoint\noindent[The percent signs in all the comments (for example,
+on pages 7 and 50) are in the wrong font! Change `{\tt\%}' to `\%'.]
+
+\bugonpage Bvi, bottom line, and top line of next page (10/12/86)
+
+{\hsize=29pc
+\tenpoint\noindent
+puter Science Report 1097 (Stanford, California, April 1986), 146~pp.
+\ {\it The {\sltt WEB} programs for four utility programs that are
+often used with \TeX: {\sltt POOLtype}, {\sltt TFtoPL},
+{\sltt PLtoTF}, and {\sltt DVItype}.}
+\par}
+
+\bugonpage B2, line 32 (4/22/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.2\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B7, new line after line 25 (1/28/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $\\{max\_in\_open}\ge128$ {\bf then} $\\{bad}\gets6$;
+
+\bugonpage B13, first three lines (4/7/87)
+
+\tenpoint\noindent
+The `\\{name}' parameter, which is of type `{\bf packed array
+$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of
+the external file that is being opened for input or output.
+Blank spaces that might appear in \\{name} are ignored.
+
+\bugonpage B14, line 30 (4/7/87)
+
+\tenpoint\noindent
+{\bf 31.\quad}%
+The \\{input\_ln} function brings the next line of input from the specified
+file into available\cutpar
+
+\bugonpage B18, line 30 (5/22/86)
+
+\ninepoint\noindent
+\\{str\_ptr}: \\{str\_number};\quad
+$\{\,$number of the current string being created$\,\}$
+
+\bugonpage B21, first line of mini-index, right column (6/14/87)
+
+\eightpoint
+\indent\\{pool\_name}\unhcopy\eqbox|"string"|, \S11.
+
+\bugonpage B34, lines 5--6 (6/14/87)
+
+\tenpoint\noindent
+to delete a token, and/or if some fatal error
+occurs while \TeX\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\bugonpage B55, lines 12--13 (4/21/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $r=p$ {\bf then if} $\\{rlink}(p)\ne p$ {\bf then}
+ $\langle\,$Allocate entire node $p$ and {\bf goto} \\{found}%
+ {\sevenrm\kern.5em129}$\,\rangle$;
+
+\bugonpage B57, lines 25--28 (6/14/87)
+
+\tenpoint\noindent
+The first of these has $\\{font}=\\{font\_base}$, and its \\{link}
+points to the second;
+the second identifies the font and the character dimensions.
+The saving feature about oriental characters is that most of them have
+the same box dimensions. The \\{character} field of the first \\{char\_node}
+is a ``\\{charext}'' that distinguishes between graphic symbols whose
+dimensions are identical for typesetting purposes. (See the \MF\ manual.)
+Such an extension of \TeX\ would not be difficult; further details are
+left to the reader.
+
+\bugonpage B58, second line of section 136 (7/23/86)
+
+\tenpoint\noindent
+the values corresponding to `|\hbox{}|'. The \\{subtype} field is set to
+\\{min\_quarterword}, since that's\cutpar
+
+\bugonpage B66, lines 2--8 (4/21/87)
+
+\tenpoint\noindent
+location is
+more efficient than dynamic allocation when we can get away with it. For
+example, locations \\{mem\_bot} to $\\{mem\_bot}+3$ are always used to store the
+specification for glue that is `\hbox{\tt 0pt plus 0pt minus 0pt}'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Static variable-size nodes appear
+in locations \\{mem\_bot} through \\{lo\_mem\_stat\_max}, and static
+single-word nodes appear in locations \\{hi\_mem\_stat\_min} through
+\\{mem\_top}, inclusive. It is harmless to let \\{lig\_trick} and
+\\{garbage} share the same location of \\{mem}.
+
+\bugonpage B67, line 23 (4/13/87)
+
+\ninepoint\noindent\hskip30pt
+$\{\,$previous \\{mem\_end}, \\{lo\_mem\_max}, and \\{hi\_mem\_min}$\,\}$
+
+\bugonpage B71, line 17 (4/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin while} $p>\\{mem\_min}$ {\bf do}
+
+\smallskip\eightpoint\noindent[Now \\{null} can be removed from the mini-index.]
+
+\bugonpage B74, line 24 (4/15/87)
+
+\ninepoint\noindent
+{\bf procedure} \\{show\_node\_list}($p\;{:}\;\\{integer}$);\quad
+$\{\,$prints a node list symbolically$\,\}$
+
+\bugonpage B74, line 33 (4/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf while} $p>\\{mem\_min}$ {\bf do}
+
+\bugonpage B84, line 12 (2/15/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{relax}=0$\quad$\{\,$do nothing ( {\tt\char`\\relax} )$\,\}$
+
+\bugonpage B86, third line of section 210 (8/23/86)
+
+\tenpoint\noindent
+that their special nature is easily discernible.
+The ``expandable'' commands come first.
+
+\bugonpage B88, line 23 (5/22/86)
+
+\ninepoint\noindent
+{\bf procedure\/}\ $\\{print\_mode}(m:\\{integer})$;\quad
+$\{\,$prints the mode represented by $m\,\}$
+
+\bugonpage B93, lines 3--4 (8/17/86)
+
+{\tenpoint\parindent=1em
+In the first region we have 128 equivalents for ``active characters'' that
+act as control sequences, followed by 128 equivalents for single-character
+control sequences.
+\par}
+
+\bugonpage B130, ninth-last line (5/7/87)
+
+\tenpoint\noindent
+This variable has six possible values:
+
+\bugonpage B151, line 9 (4/22/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin if} $(\\{end\_line\_char}<0)\lor(\\{end\_line\_char}>127)$
+ {\bf then} \\{incr}(\\{limit});\par\noindent\hskip20pt
+{\bf if} $\\{limit}=\\{start}$ {\bf then}\quad
+ $\{\,$previous line was empty$\,\}$
+
+\bugonpage B160, lines 17--20 (7/28/86)
+
+\tenpoint\noindent
+{\bf 389.\quad}%
+After parameter scanning is complete, the parameters are moved to the
+\\{param\_stack}. Then the macro body is fed to the scanner; in other words,
+\\{macro\_call} places the defined text of the control sequence at the
+top of\/ \TeX's input stack, so that \\{get\_next} will proceed to read it
+next.
+
+\bugonpage B200, top line (5/5/87)
+
+\tenpoint\noindent{\bf 495.\quad}%
+ When we begin to process a new {\tt\char`\\if}, we set
+$\\{if\_limit}\gets\\{if\_code}$; then
+if\/ {\tt\char`\\or} or {\tt\char`\\else} or {\tt\char`\\fi}\cutpar
+
+\bugonpage B217, lines 15--16 (6/14/87)
+
+\tenpoint\noindent
+|DVI| format.
+
+\bugonpage B224, lines 4--7 of section 560 (10/22/86)
+
+\tenpoint\noindent
+name and area strings \\{nom} and \\{aire}, and the
+``at'' size~$s$. If $s$~is negative, it's the negative of a scale factor
+to be applied to the design size; $s=-1000$ is the normal case.
+Otherwise $s$ will be substituted for the design size; in this
+case, $s$ must be positive and less than $2048\rm\,pt$
+(i.e., it must be less than $2^{27}$ when considered as an integer).
+
+\bugonpage B224, second-last line (4/28/87)
+
+\ninepoint\noindent
+\\{done}: {\bf if} \\{file\_opened} {\bf then} \\{b\_close}(\\{tfm\_file});\par
+\noindent\hskip10pt $\\{read\_font\_info}\gets g$;
+
+\bugonpage B255, mini-index at the bottom (4/15/87)
+
+\eightpoint
+$\\{mag}=\rm macro$, \S236.
+
+\bugonpage B257, lines 11--13 (6/14/87)
+
+\ninepoint
+\noindent\hskip20pt{\bf if} $c\ge\\{qi}(128)$ {\bf then}
+ \\{dvi\_out}(\\{set1});\par
+\noindent\hskip20pt\\{dvi\_out}(\\{qo}($c$));
+
+\bugonpage B260, lines 7--8 (4/15/87)
+
+\tenpoint\noindent\hskip10pt
+In the case of \\{c\_leaders} (centered leaders), we want to increase \\{cur\_h}
+by half of the excess space not occupied by the leaders; and in the
+case of \\{x\_leaders} (expanded leaders) we increase\cutpar
+
+\bugonpage B267, mini-index at the bottom (4/15/87)
+
+\eightpoint
+\\{cur\_s}: \\{integer}, \S616.
+$\\{mag}=\rm macro$, \S236.
+$\\{pop}=142$, \S586.
+
+\bugonpage B271, line 10 (8/23/86)
+
+\tenpoint\noindent
+which will be ignored in the calculations
+because it is a highly negative number.
+
+\bugonpage B285, lines 23 and 24 (5/4/87)
+
+\tenpoint\noindent
+the current string would be `{\tt.\char`\^.\char`\_/}'
+if $p$ points to the \\{ord\_noad} for $x$ in the (ridiculous) formula
+`{\tt\char`\\sqrt\char`\{a\char`\^\char`\{\char`\\mathinner\char`\{%
+b\char`\_\char`\{c\char`\\over x+y\char`\}\char`\}\char`\}\char`\}\char`\$}'.
+
+\bugonpage B296, lines 3--5 (5/8/87)
+
+\tenpoint\noindent
+box~$b$ and
+changes it so that the new box is centered in a box of width~$w$.
+The centering is done by putting {\tt\char`\\hss} glue at the left and right
+of the list inside $b$, then packaging the new box; thus, the
+actual box might not really be centered, if it already contains
+infinite glue.
+
+\bugonpage B346, line 19 (5/19/87)
+
+\ninepoint\noindent
+\\{pass\_number}: \\{halfword};\quad
+$\{\,$the number of passive nodes allocated on this pass$\,\}$
+
+\bugonpage B350, lines 36 and 37 (1/28/87)
+
+\ninepoint\noindent
+$v$: \\{pointer};\quad
+$\{\,$points to a glue specification or a node ahead of \\{cur\_p}$\,\}$
+\par\noindent
+$t$: \\{integer};\quad
+$\{\,$node count, if \\{cur\_p} is a discretionary node$\,\}$
+
+\bugonpage B353, lines 8--22 (1/28/87)
+
+\ninepoint
+\noindent\hskip10pt$s\gets\\{cur\_p}$;\par
+\noindent\hskip10pt{\bf if} $\\{break\_type}>\\{unhyphenated}$ {\bf then}
+ {\bf if} $\\{cur\_p}\ne\\{null}$ {\bf then}\par
+\noindent\hskip30pt$\langle\,$Compute the discretionary
+ \\{break\_width} values{\sevenrm\kern.5em840}$\,\rangle$;\par
+\noindent\hskip10pt{\bf while} $s\ne\\{null}$ {\bf do}\par
+\noindent\hskip30pt\vdots\hskip30pt [as before, but indented one less notch]\par
+\noindent\hskip10pt{\bf end};
+
+\bugonpage B354, line 6 (1/28/87)
+
+\tenpoint\noindent
+will be the background plus $l_1$, so the length from \\{cur\_p} to \\{cur\_p}
+should be $\gamma+l_0+l_1-l$,
+minus the length of nodes that will be discarded after the discretionary break.
+
+\bugonpage B354, lines 12--18 (1/28/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf begin} $t\gets\\{replace\_count}(\\{cur\_p})$;\kern5pt
+ $v\gets\\{cur\_p}$;\kern5pt $s\gets\\{post\_break}(\\{cur\_p})$;\par
+\noindent\hskip10pt{\bf while} $t>0$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $\\{decr}(t)$;\kern5pt
+ $v\gets\\{link}(v)$;\kern5pt
+ $\langle\,$Subtract the width of node $v$ from \\{break\_width}%
+ {\sevenrm\kern.5em841}$\,\rangle$;\par
+\noindent\hskip20pt{\bf end};\par
+\noindent\hskip10pt{\bf while} $s\ne\\{null}$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle$;\par
+
+\bugonpage B354, new line after line 21 (1/28/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $t=0$ {\bf then} $s\gets\\{link}(v)$;\quad
+ $\{\,$more nodes may also be discardable after the break$\,\}$
+
+\bugonpage B354, lines 26--34 (1/28/87)
+
+\ninepoint\noindent
+[Change `$s$' to `$v$' throughout this section (8 times).]
+
+\bugonpage B354, line 9 from the bottom (1/28/87)
+
+\tenpoint\noindent{\bf 842.\quad}%
+\ninepoint$\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle\equiv$
+
+\bugonpage B355, lines 1--3 (1/28/87)
+
+\ninepoint
+\noindent\hskip20pt$\\{hlist\_node},\\{vlist\_node},\\{rule\_node}$:
+ $\\{break\_width}[1]\gets\\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt\\{kern\_node}: {\bf if} $(t=0)\land
+ (\\{subtype}(s)\ne\\{acc\_kern})$ {\bf then}
+ $t\gets-1$\quad$\{\,$discardable$\,\}$\par
+\noindent\hskip30pt{\bf else} $\\{break\_width}[1]\gets
+ \\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt{\bf othercases}
+ \\{confusion}({\tt\char'42 disc2\char'42})\par
+\noindent\hskip20pt{\bf endcases};\par
+\noindent\hskip10pt$\\{incr}(t)$
+
+\bugonpage B355, patches to mini-index at bottom (1/28/87)
+
+\eightpoint
+$\\{acc\_kern}=2$, \S155.\par
+$\\{incr}=\rm macro$, \S16.\par
+$t$: \\{integer}, \S830.\par
+$v$: \\{pointer}, \S830.
+
+\bugonpage B372, lines 12--14 (1/28/87)
+
+\ninepoint
+\noindent\hskip40pt$\langle\,$Change discretionary to compulsory
+ and set $\\{disc\_break}\gets\\{true}${\sevenrm\kern.5em882}$\,\rangle$\par
+\noindent\hskip30pt{\bf else if\/} $(\\{type}(q)=\\{math\_node})\lor
+ (\\{type}(q)=\\{kern\_node})$ {\bf then} $\\{width}(q)\gets0$;
+
+\bugonpage B380, fifth-last line (5/7/87)
+
+\begingroup\tenpoint\noindent\def\!{\kern-1pt}\def\.#1{\hbox{\tt#1}}
+\.b and \.c, the two patterns with and without hyphenation are
+$\.a\,\.b\,\.-\,\.{c\!d}\,\.{e\!f}$ and $\.a\,\.{b\!c}\,\.{d\!e}\,\.f$.
+Thus the\cutpar\endgroup
+
+\bugonpage B386, lines 2--4 (5/21/87)
+
+\tenpoint\noindent
+hyphenation,
+\TeX\ first looks to see if it is in the user's exception dictionary. If not,
+hyphens are inserted based on patterns that appear within the given word,
+using an algorithm due to Frank~M. Liang.
+
+\bugonpage B397, line 28 (5/21/87)
+
+\tenpoint\noindent
+$h=z-c$. It follows that location \\{trie\_max} will
+never be occupied in \\{trie}, and we will have\cutpar
+
+\bugonpage B415, the mini-index (4/6/87)
+
+\eightpoint\noindent[Delete the spurious entry for `$c$'.]
+
+\bugonpage B419, mini-index entry for \\{c} (4/6/87)
+
+\eightpoint $c$: \\{integer}, \S994.
+
+\bugonpage B422, line 24 (8/23/86)
+
+\ninepoint\noindent
+\hskip20pt\\{prev\_p}: \\{pointer};\quad
+$\{\,$predecessor of $p\,\}$
+
+\bugonpage B435, line 16 (10/12/86)
+
+\ninepoint\noindent
+\hskip20pt$\\{width}(p)\gets\\{font\_info}[k].\\{sc}$;\quad
+$\{\,$that's \\{space}$(f)\,\}$\par\noindent
+\hskip20pt$\\{stretch}(p)\gets\\{font\_info}[k+1].\\{sc}$;\quad
+$\{\,$and \\{space\_stretch}$(f)\,\}$\par\noindent
+\hskip20pt$\\{shrink}(p)\gets\\{font\_info}[k+2].\\{sc}$;\quad
+$\{\,$and \\{space\_shrink}$(f)\,\}$\par
+\smallskip\eightpoint\noindent
+[And the mini-index gets three new entries:
+$\\{space}=macro$, \S558.
+$\\{space\_shrink}=macro$, \S558.
+$\\{space\_stretch}=macro$, \S558.]
+
+\bugonpage B495, lines 18 and 19 (2/15/87)
+
+\ninepoint\noindent
+[delete these lines, since the cases cannot occur]
+
+\bugonpage B510, line 8 (12/15/86)
+
+\ninepoint\noindent\hskip30pt
+({\tt"Pretend\]that\]you're\]Hercule\]Poirot:\]Examine\]all\]clues,"})
+
+\bugonpage B527, new line to follow line 13 (6/17/86)
+
+{\tenpoint\parindent=1em
+This program doesn't bother to close the input files that may still be open.
+\par}
+
+\bugonpage B534, fourth-last line (5/4/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{write\_stream}(\hbox{\tt\char`\#})\equiv\\{info}(
+ \hbox{\tt\char`\#}+1)$\quad $\{\,$stream number (0 to 17)$\,\}$
+
+\bugonpage B544, left column (1/28/87)
+
+\eightpoint
+\leftline{\\{acc\_kern}:\quad$\underline{155}$, 191, 837, 842, 879, 1125.}
+
+\bugonpage B546, entry for \\{c} (4/6/87)
+
+\eightpoint\noindent[Add a reference to section $\underline{994}$.]
+
+\bugonpage B547, left column (4/7/87)
+
+\eightpoint
+\leftline{\\{char}:\quad 19, 26--27, 520, 534.}
+
+\bugonpage B547, left column (6/14/87)
+
+\eightpoint
+\leftline{Chinese characters:\quad 134, 585.}
+
+\bugonpage B553, entry for \\{font\_base} (6/14/87)
+
+\eightpoint\noindent[Insert a reference to section 134.]
+
+\bugonpage B555, right column, new entry (10/25/86)
+
+\eightpoint
+\leftline{{\tt Huge page...},\quad 641.}
+
+\bugonpage B556, entry for \\{incr} (1/28/87)
+
+\eightpoint\noindent[Add a reference to section 842.]
+
+\bugonpage B557, entry for \\{is\_char\_node} (1/28/87)
+
+\eightpoint\noindent[Delete the reference to section 881.]
+
+\bugonpage B557, right column (6/14/87)
+
+\eightpoint
+\leftline{Japanese characters:\quad 134, 585.}
+
+\bugonpage B560, right column (1/28/87)
+
+\eightpoint
+\leftline{\\{max\_in\_open}:\quad$\underline{11}$, 14, 304, 328.}
+
+\bugonpage B561, left column, line 10 (4/15/87)
+
+\eightpoint
+\leftline{\qquad 169--172, 174, 178, 182, 1249, 1312, 1334.}
+
+\bugonpage B561, left column (5/1/87)
+
+\eightpoint
+\leftline{{\tt Missing font identifier}:\quad 577.}
+
+\bugonpage B563, left column, line 2 (4/15/87)
+
+\eightpoint
+\leftline{\qquad 136, 145, 149--154, 164, 168--169, 175--176, 182,}
+
+\bugonpage B563, right column (6/14/87)
+
+\eightpoint
+\leftline{oriental characters:\quad 134, 585.}
+
+\bugonpage B569, right column, in appropriate places (10/12/86)
+
+\eightpoint
+\leftline{\\{space}:\quad 547, $\underline{558}$, 752, 755, 1042.}
+\leftline{\\{space\_shrink}:\quad 547, $\underline{558}$, 1042.}
+\leftline{\\{space\_stretch}:\quad 547, $\underline{558}$, 1042.}
+
+\bugonpage B570, third-last line (1/28/87)
+
+\eightpoint\noindent\qquad
+ 786, 795, 809, 819--820, 822, 837, 842--844, 866,
+
+\bugonpage B571, right column (10/25/86)
+
+\eightpoint
+\leftline{{\tt The following...deleted},\quad 641, 992, 1121.}
+
+\bugonpage B571, right column (4/7/87)
+
+\eightpoint
+\leftline{\\{text\_char}:\quad $\underline{19}$, 20, 25, 47.}
+
+\bugonpage B573, right column (5/1/87)
+
+\eightpoint\noindent
+[Delete the entry for `{\tt Undefined font code}'.]
+
+\bugonpage B576, line 2 (1/28/87)
+
+\ninepoint\noindent
+$\langle\,$Add the width of
+ node $s$ to \\{break\_width} and increase $t$, unless it's
+ discardable{\sevenrm\kern.5em842}$\,\rangle$\par
+\noindent\qquad {\eightpoint Used in section 840.}
+
+\bugonpage B591, line 6 from the bottom (1/28/87)
+
+\ninepoint\noindent
+ $\langle\,$Subtract the width of node $v$ from \\{break\_width}%
+ {\sevenrm\kern.5em841}$\,\rangle$\quad
+ {\eightpoint Used in section 840.}
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C14, top two lines (3/16/87)
+
+\danger The recursive midpoint rule for curve-drawing was discovered in 1959
+by Paul de Casteljau, who showed that the curve could be described
+algebraically by the remarkably simple formula
+
+\bugonpage C54, sixth-last to fourth-last lines (10/13/86)
+
+\ninepoint Jonathan H. Quick (a student) used `|a.plus1|' as the name
+of a variable at the beginning of his program; later he said `|let|
+|plus=+|'. How could he refer to the variable `|a.plus1|' after that?
+
+\bugonpage C76, line 14 (10/13/86)
+
+\tenpoint
+\newdimen\longesteq
+\setbox0=\hbox{\indent$z_{12}-z_{11}=z_{14}-z_{13}$\quad}
+\longesteq=\wd0
+\noindent\hbox to \longesteq{\indent
+ $x_4=w-.01\\{in}$\hfil}%
+Point 4 should be one-hundredth of an inch inside\cutpar
+
+\bugonpage C103, line 12 (10/12/86)
+
+\tenpoint
+$\\{ht}\0=\\{body\_height}\0$; \ $.5[\\{ht}\0,-\\{dp}\0]=\\{axis}\0$;
+
+\bugonpage C105, line 13 (10/13/86)
+
+\ninepoint
+The vertical line just to the right of the italic left parenthesis
+shows the italic\cutpar
+
+\bugonpage C113, lines 20--27 (8/23/86)
+
+{\catcode`\@=\active
+\def@#1@{\begingroup\def\_{\kern.04em
+ \vbox{\hrule width.3em height .6pt}\kern.08em}%
+ \ifmmode\mathop{\bf#1}\else\hbox{\bf#1\/}\fi\endgroup}
+\danger The command `@erase@ @fill@ $c$' is an abbreviation for
+`@cullit@; @unfill@~$c$; @cullit@'; this zeros out the pixel values inside
+the cyclic path~$c$, and sets other pixel values to~1 if they were positive
+before erasing took place. \ (It works because the initial @cullit@ makes
+all the values 0 or~1, then the @unfill@ changes the values inside~$c$
+to 0 or negative. The final @cullit@ gets rid of the negative values,
+so that they won't detract from future filling and drawing.) \ You can
+also use `@draw@', `@filldraw@', or `@drawdot@' with `@erase@'; for example,
+`@erase@ @draw@~$p$' is an abbreviation for `@cullit@; @undraw@~$p$;
+@cullit@', which uses the currently-picked-up pen as if it were an
+eraser applied to path~$p$.
+
+}
+
+\bugonpage C124, line 9 (6/17/86)
+
+\eightpoint
+\noindent\hskip1.8in
+$\\{branch}_2=\\{flex}((30,570),(10,590),(-1,616))$
+
+\bugonpage C130, 3rd-last line (9/25/86)
+
+\ninepoint\noindent
+{\sl Geometry\/ \bf 1} (1986), 123--140]: Given a sequence
+
+\bugonpage C144, sixth line of the program (8/23/86)
+
+\ninepoint\noindent\hbox to\parindent{\hfil\sevenrm6\ \ \ }%
+$y_2=.1h$; \ $\\{top}\,y_3=.4h$;
+
+\bugonpage C148, the line before the illustration (11/27/86)
+
+\ninepoint\noindent
+are polygons with 32 and 40 sides, respectively:
+
+\smallskip\noindent
+[New illustrations are needed here, since \MF\ version 1.3 improves
+the accuracy of pen polygons.]
+
+\bugonpage C149, 7th line after the illustration (10/24/86)
+
+\ninepoint
+\line{$(200,y+100\pm\alpha)$, where
+$\alpha=\sqrt5/4\approx0.559$. If we digitize these outlines and fill the}
+
+\bugonpage C178, second-last line (8/23/86)
+
+\ninepoint\noindent
+(If $t_3=t_1$~transum~$t_2$, then
+$z$~transformed~$t_3=z$~transformed~$t_1+z$~transformed~$t_2$,\cutpar
+
+\bugonpage C198, fifth-last and fourth-last lines (10/13/86)
+
+\ninepoint\vskip-3pt
+\begindisplay
+$\\{top}\,y_2={\rm round}(\\{top}\,\beta)$.
+\enddisplay
+Such operations occur frequently in practice, so plain \MF\ provides
+convenient\cutpar
+
+\bugonpage C212, lines 9--11 from the bottom (8/23/86)
+
+\ninepoint
+\qquad
+ \alt\[point]\<numeric expression>\[of]\<path primary>\continuerule
+ \alt\[precontrol]\<numeric expression>\[of]\<path primary>\continuerule
+ \alt\[postcontrol]\<numeric expression>\[of]\<path primary>
+
+\bugonpage C233, lines 13--14 (2/15/87)
+
+\ninepoint\noindent
+one column of white
+pixels, if the character is $2a$ pixels wide, because the right edge of
+black pixels is specified here to have the $x$~coordinate $2a-1$.
+
+\bugonpage C247, lines 23--25 (11/27/86)
+
+\ninepoint
+\ansno 16.2:
+ `{\bf pencircle} scaled 1.06060' is the diamond but
+`{\bf pencircle} scaled 1.06061' is~the square. \ (This assumes that
+$\\{fillin}=0$. If, for example, $\\{fillin}=.1$, the change doesn't
+occur until the diameter is 1.20204.) \ The next change is at diameter
+1.5, which\cutpar
+
+\bugonpage C262, lines 1--4 (7/28/86)
+
+\ninepoint
+When we come to macros whose use has not yet been explained---for
+example, somehow |softjoin| and |stop| never made it
+into Chapters 1 through~27---we shall consider them from a user's
+viewpoint. But most of the comments that follow are addressed to a
+potential base-file designer.
+
+\bugonpage C266, line 16 (8/17/86)
+
+\ninepoint\noindent
+variables; they have the side effect of changing the variable's value.
+
+\bugonpage C276, line 26 (6/23/86)
+
+\ninepoint
+\noindent
+| if charic<>0: r((w+charic*hppp,h.o_),(w+charic*hppp,.5h.o_)); fi|
+
+\bugonpage C286, lines 24--26 (10/13/86)
+
+\ninepoint\noindent
+but \MF\ won't let you. And even if this had worked, it wouldn't have
+solved the problem; it would simply have put |ENDFOR| into the
+replacement text of |ast|, because expansion is inhibited when the
+replacement text is being read.
+
+\bugonpage C290, line 1 (8/23/86)
+
+\ninepoint \noindent{\it 2.\enspace Fortuitous loops.\enspace}%
+The `^{max}' and `^{min}' macros in Appendix~B make use of the fact\cutpar
+
+\bugonpage C298, third-last line (8/23/86)
+
+\ninepoint
+$t[\,u_1,\ldots,u_n]\;=\;t\bigl[t[u_1,\ldots,u_{n-1}],t[u_2,\ldots,u_n]\,\bigr]$
+
+\bugonpage C304, 14th-last line (2/15/87)
+
+\ninepoint\noindent
+[replace this `|\smallskip|' by a |\smallskip| between lines!]
+
+\bugonpage C307, fifth-last line (12/7/86)
+
+\ninepoint
+{\def\_{\kern.04em
+ \vbox{\hrule width.3em height .6pt}\kern.08em}%
+\bf adjust\_fit}(\<left sidebearing adjustment>,\thinspace
+ \<right sidebearing adjustment>);
+
+\bugonpage C312, line 34 (10/12/86)
+
+\ninepoint\noindent
+|params[2] = "sans_params"; fontname[2] = "cmssbx10";|
+
+\bugonpage C316, lines 19--21 (8/17/86)
+
+\ninepoint\noindent
+example,
+`|(some| |charht| |values| |had| |to| |be| |adjusted| |by| |as| |much|
+|as| |0.12pt)|' means that~you had too many different nonzero heights, but
+\MF\ found a way to reduce the number to at most~15 by changing some of
+them; none of them had to be\cutpar
+
+\bugonpage C319, line 3 (8/23/86)
+
+\ninepoint\noindent
+specified by saying, e.g.,
+
+\bugonpage C321, line 6 (7/28/86)
+
+\ninepoint\noindent
+| special "identifier " & font_identifier_;|
+
+\bugonpage C334, line 2 (6/23/86)
+
+\ninepoint\noindent
+| currentpicture := currentpicture shifted-(1,1); pix := currentpicture;|
+
+\bugonpage C339, tenth-last line (2/4/87)
+
+\ninepoint\noindent
+| Jackie K\=aren {\L}au\.ra Mar{\'\i}a N\H{a}ta{\l}{\u\i}e {\O}ctave|
+
+\bugonpage C343, second-last line (8/23/86)
+
+\rightline{\eightssi
+the precise needs of a precise but limited intellectual goal.}
+
+\bugonpage C346, 2nd line of entry for `{\tt;}' (1/12/87)
+
+\eightpoint
+\qquad 217, 223--224, 263, 312.
+
+\bugonpage C348, line 6 (6/17/86)
+
+\eightpoint
+concatenation, of paths, {\eightit 70--71}, {\eightit 123}, 127,
+
+\bugonpage C348, just before `debugging' (3/16/87)
+
+\eightpoint
+de Casteljau, Paul de Faget, 14.
+
+\bugonpage C348, right column (3/16/87)
+
+\eightpoint\noindent
+[The entry for `|define_whole_vertical_blacker_pixels|' should be moved up
+before the entry for `|define_whole_vertical_pixels|'.]
+
+\bugonpage C352, left column (6/1/87)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt kern}, {\it 97}, {\it 316}, $\underline{317}$.
+
+\bugonpage C352, right column (3/8/87)
+
+\eightpoint\noindent
+[The entry for `|lowres|' belongs before the entry for `|lowres_fix|'.]
+
+\bugonpage C353, left column (3/8/87)
+
+\eightpoint\noindent
+[The entries for `|mode|' and `\<mode command>' belong before the entry
+for `|mode_def|'.]
+
+\bugonpage C353, entry for {\tt mode\char`\_def} (8/17/86)
+
+\eightpoint
+{\tt mode\char`\_def}, 94, 189, $\underline{\smash{\hbox{\it 270}}}$,
+{\it 278--279}.
+
+\bugonpage C355, right column (4/15/86)
+
+\eightpoint\noindent
+[The entry for `{\tt rulepen}' belongs before the entry for `rules'.]
+
+\bugonpage C355, right column (8/5/86)
+
+\eightpoint
+{\tt screenstrokes}, 191, $\underline{277}$.
+
+\bugonpage C355, 2nd line of entry for `semicolons' (1/12/87)
+
+\eightpoint
+\qquad 217, 223--224, 263, 312.
+
+\bugonpage C356, full names for the Stanfords (4/10/86)
+
+\eightpoint
+Stanford, Amasa Leland, 340.
+
+Stanford, Jane Elizabeth Lathrop, 340.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\buginvol D, in general (7/28/86)
+
+\tenpoint\noindent
+[A number of entries were mistakenly omitted from the mini-indexes
+on the right-hand pages. Here is a combined list of all the missing
+items; you can mount it inside the back cover, say, as a secondary mini-index
+when the first one fails\dots\ ]
+
+\nobreak\medskip
+\setbox0=\vbox{\eightpoint \hsize=11pc \catcode`\_=\active \let_=\_
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+ \obeylines
+ \def\makeref #1 #2 #3#4
+ {\nn=#2 \hangindent=1em \noindent\\{#1}%
+ \if#3:: \else\unhcopy\eqbox \fi#4, \S\number\nn.\par}
+ \makeref add_or_subtract 930 :\&{procedure}
+ \makeref after 427 :\&{array}
+ \makeref arg_list 720 :\\{pointer}
+ \makeref b 580 :\\{pixel\_color}
+ \makeref bad_exp 824 :\&{procedure}
+ \makeref before 427 :\&{array}
+ \makeref begin_name 770 :\&{procedure}
+ \makeref bilin1 968 :\&{procedure}
+ \makeref binary_mac 863 :\&{procedure}
+ \makeref blank_rectangle 567 :\&{procedure}
+ \makeref boc_c 1162 :\\{integer}
+ \makeref boc_p 1162 :\\{integer}
+ \makeref cf 298 :\\{fraction}
+ \makeref clockwise 453 :\\{boolean}
+ \makeref ct 298 :\\{fraction}
+ \makeref cubic_intersection 556 :\&{procedure}
+ \makeref cur_pen 403 :\\{pointer}
+ \makeref cur_rounding_ptr 427 :$0\to \\{max\_wiggle}$
+ \makeref cur_spec 403 :\\{pointer}
+ \makeref cur_x 389 :\\{scaled}
+ \makeref cur_y 389 :\\{scaled}
+ \makeref dely 557 :\\{integer}
+ \makeref dep_finish 935 :\&{procedure}
+ \makeref dep_list 587 =macro
+ \makeref dimen_head 1125 :\&{array}
+ \makeref dx 495 :\\{integer}
+ \makeref dy 495 :\\{integer}
+ \makeref d1 464 :$0\to 1$
+ \makeref end_name 772 :\&{procedure}
+ \makeref eqtb 201 :\&{array}
+ \makeref error_stop_mode 68 =$3$
+ \makeref firm_up_the_line 682 :\&{procedure}
+ \makeref get_next 667 :\&{procedure}
+ \makeref gf_buf 1152 :\&{array}
+ \makeref gf_offset 1152 :\\{integer}
+ \makeref gf_ptr 1152 :\\{gf\_index}
+ \makeref halfword 156 =$\\{min\_halfword}\to \\{max\_halfword}$
+ \makeref hash 201 :\&{array}
+ \makeref index 629 =macro
+ \makeref input_ln 30 :\&{function}
+ \makeref interaction 68 :$0\to 3$
+ \makeref j 357 :$0\to \\{move\_size}$
+ \makeref known_pair 872 :\&{procedure}
+ \makeref limit 629 =macro
+ \makeref m_spread 357 :\\{integer}
+ \makeref materialize_pen 865 :\&{procedure}
+ \makeref max_allowed 403 :\\{scaled}
+ \makeref max_c 813 :\&{array}
+ \makeref max_link 813 :\&{array}
+ \makeref max_tfm_dimen 1130 :\\{scaled}
+ \makeref mem_top 12 =macro
+ \makeref mem 159 :\&{array}
+ \makeref memory_word 156 =\&{record}
+ \makeref more_name 771 :\&{function}
+ \makeref m1 464 :\\{integer}
+ \makeref n 580 :\\{screen\_col}
+ \makeref n_sin_cos 145 :\&{procedure}
+ \makeref name 629 =macro
+ \makeref negate_dep_list 904 :\&{procedure}
+ \makeref new_knot 871 :\&{function}
+ \makeref node_to_round 427 :\&{array}
+ \makeref n1 464 :\\{integer}
+ \makeref octant_dir 395 :\&{array}
+ \makeref o1 453 :\\{small\_number}
+ \makeref o2 453 :\\{small\_number}
+ \makeref paint_row 568 :\&{procedure}
+ \makeref param 1096 :\&{array}
+ \makeref param_stack 633 :\&{array}
+ \makeref path_length 916 :\&{function}
+ \makeref perturbation 1119 :\\{scaled}
+ \makeref phi 542 :\\{angle}
+ \makeref pool_ptr 38 :\\{pool\_pointer}
+ \makeref post_head 843 :\\{pointer}
+ \makeref pre_head 843 :\\{pointer}
+ \makeref print_err 68 =macro
+ \makeref print_macro_name 722 :\&{procedure}
+ \makeref quarterword 156 =$0\to 255$
+ \makeref recycle_value 809 :\&{procedure}
+ \makeref row_transition 579 :\\{trans\_spec}
+ \makeref scan_text_arg 730 :\&{procedure}
+ \makeref scroll_mode 68 =$2$
+ \makeref set_controls 299 :\&{procedure}
+ \makeref sf 298 :\\{fraction}
+ \makeref show_context 635 :\&{procedure}
+ \makeref sorted 325 =macro
+ \makeref st 298 :\\{fraction}
+ \makeref start 629 =macro
+ \makeref start_sym 1077 :\\{halfword}
+ \makeref str_pool 38 :\&{packed}\ \&{array}
+ \makeref str_ptr 38 :\\{str\_number}
+ \makeref str_start 38 :\&{array}
+ \makeref take_part 910 :\&{procedure}
+ \makeref tfm_changed 1130 :\\{integer}
+ \makeref tol 557 :\\{integer}
+ \makeref tt 843 :\\{small\_number}
+ \makeref tx 954 :\\{scaled}
+ \makeref txx 954 :\\{scaled}
+ \makeref txy 954 :\\{scaled}
+ \makeref ty 954 :\\{scaled}
+ \makeref tyx 954 :\\{scaled}
+ \makeref tyy 954 :\\{scaled}
+ \makeref unsorted 325 =macro
+ \makeref uv 557 :$0\to \\{bistack\_size}$
+ \makeref xy 557 :$0\to \\{bistack\_size}$
+ \makeref x1 542 :\\{scaled}
+ \makeref x2 542 :\\{scaled}
+ \makeref x3 542 :\\{scaled}
+ \makeref y1 542 :\\{scaled}
+ \makeref y2 542 :\\{scaled}
+ \makeref y3 542 :\\{scaled}
+ }
+\hbox{\nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}}
+
+\buginvol D, in general (4/6/87)
+
+\tenpoint\noindent[The percent signs in all the comments (for example,
+on pages 7 and 42) are in the wrong font! Change `{\tt\%}' to `\%'.]
+
+\bugonpage Dvii, line 9 (9/25/86)
+
+{\tenpoint\noindent\hsize=29pc
+{\sl Discrete and Computational Geometry\/ \bf1} (1986), 123--140.
+\ \it Develops the theory\cutpar}
+
+\bugonpage D2, line 27 (6/17/86)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]1.3\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D18, line 30 (5/22/86)
+
+\ninepoint\noindent
+\\{str\_ptr}: \\{str\_number};\quad
+$\{\,$number of the current string being created$\,\}$
+
+\bugonpage D23, second line of mini-index, right column (6/14/87)
+
+\eightpoint
+\indent\\{pool\_name}\unhcopy\eqbox|"string"|, \S11.
+
+\bugonpage D30, lines 33--34 (6/14/87)
+
+\tenpoint\noindent
+to delete a token, and/or if some fatal error
+occurs while \MF\ is trying to fix a non-fatal one. But such recursion
+is never more than two levels deep.
+
+\bugonpage D63, lines 13--14 (5/5/87)
+
+\ninepoint\noindent
+[These two lines can be eliminated, since the variable \\{temp\_ptr}
+is no longer used! If you delete them, also remove \S158 from the
+list of sections where global variables are declared (pages D7 and D552),
+and remove \\{temp\_ptr} from the index on page D540.]
+
+\bugonpage D66, line 6 (5/22/86)
+
+\ninepoint\noindent
+{\bf function\/}\ $\\{get\_node}(s:\\{integer})$: \\{pointer};\quad
+$\{\,$variable-size node allocation$\,\}$
+
+\bugonpage D66, lines 31--32 (3/16/86)
+
+\tenpoint\noindent
+controlled
+growth helps to keep the \\{mem} usage consecutive when \MF\ is
+implemented on ``virtual memory'' systems.
+
+\bugonpage D67, lines 7--8 (4/21/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf if} $r=p$ {\bf then if} $\\{rlink}(p)\ne p$ {\bf then}
+ $\langle\,$Allocate entire node $p$ and {\bf goto} \\{found}%
+ {\sevenrm\kern.5em171}$\,\rangle$;
+
+\bugonpage D86, second line of section 198 (2/27/87)
+
+\noindent
+Individual class numbers have no semantic
+or syntactic significance, except in a few instances\cutpar
+
+\bugonpage D101, line 2 (3/16/86)
+
+\tenpoint\line{%
+like `{\tt x}', or they can
+combine the structural properties of arrays and records, like `{\tt x20a.b}'.
+A}
+
+\bugonpage D102, line 24 (3/16/86)
+
+\tenpoint\line{\kern10pt
+In other words, variables have a hierarchical structure that includes
+enough threads running}
+
+\bugonpage D127, line 10 (5/5/87)
+
+\ninepoint\noindent
+[Variable $r$ can be eliminated, since it is not
+used in this procedure! If you delete it, also remove $\underline{280}$
+from the corresponding index entry on page D536.]
+
+\bugonpage D129, line 15 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since \\{sine} and \\{cosine} are not
+used in this procedure! If you delete them, also remove $\underline{284}$
+from the corresponding index entries on pages D538 and D521.]
+
+\bugonpage D142, line 23 (4/24/87)
+
+\tenpoint\noindent
+$(7-\sqrt{28}\,)/12$; the worst case
+occurs for polynomials like $B(0,28-4\sqrt{28},14-5\sqrt{28},42;t)$.)
+
+\bugonpage D178, third-last line (7/30/86)
+
+\tenpoint\line{\quad
+The following code maintains the invariant relations
+$0\le \\{x0}<\max(\\{x1},\\{x1}+\\{x2})$, $\vert\\{x1}\vert<2^{30}$,}
+
+\bugonpage D228, line 13 (7/30/86)
+
+\ninepoint\noindent\kern10pt
+{\bf while} $\\{max\_coef}<\\{fraction\_half}$ {\bf do}
+
+\smallskip\eightpoint\noindent
+The mini-index at the bottom of the next page should also receive the following
+new entry:
+\smallskip\indent
+$\\{fraction\_half}={\rm macro}$, \S105.
+
+\bugonpage D228, 10th-last line (5/5/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} $\\{right\_type}(p)\gets k$;
+\smallskip
+\noindent[Also eliminate `$q,$' seven lines above this, and delete
+$\underline{497}$ from the index entry for \\{q} on page D536.]
+
+\bugonpage D248, lines 16--21 (11/27/86)
+
+\ninepoint\noindent\kern10pt
+$\\{alpha}\gets\\{abs}(u)$;\kern5pt
+ $\\{beta}\gets\\{abs}(v)$;\par\noindent\kern10pt
+{\bf if} $\\{alpha}<\\{beta}$ {\bf then}\par\noindent\kern20pt
+{\bf begin} $\\{alpha}\gets\\{abs}(v)$;\kern5pt
+ $\\{beta}\gets\\{abs}(u)$;\kern5pt
+{\bf end};\quad$\{\,$now $\alpha=\max(\vert u\vert,\vert v\vert)$,
+ $\beta=\min(\vert u\vert,\vert v\vert)\,\}$\par\noindent\kern10pt
+{\bf if} $\\{internal}[\\{fillin}]\ne0$ {\bf then}\par\noindent\kern20pt
+$d\gets d-\\{take\_fraction}(\\{internal}[\\{fillin}],
+ \\{make\_fraction}(\\{beta}+\\{beta},\\{delta}))$;\par\noindent\kern10pt
+$d\gets\\{take\_fraction}((d+4)\;{\bf div}\;8,\\{delta})$;\kern5pt
+$\\{alpha}\gets\\{alpha}\;{\bf div}\;\\{half\_unit}$;
+
+\bugonpage D263, line 20 (3/16/86)
+
+\tenpoint\noindent
+instead of \\{false}, the other routines will simply log the fact
+that they have been called; they won't\cutpar
+
+\bugonpage D268, line 2 (4/28/87)
+
+\tenpoint\noindent
+Given the number~$k$ of an open window, the pixels of positive
+weight in \\{cur\_edges} will be shown\cutpar
+
+\bugonpage D301, line 6 of section 652 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since variable $s$ is not
+used in this procedure! If you delete it, also remove $\underline{652}$
+from the corresponding index entry on page D537; remove 652 from
+the index entries for \\{param\_size} and \\{param\_start} on page D534;
+and remove \\{param\_size} from the mini-index on page D301.]
+
+\bugonpage D376, lines 17 and 18 (11/14/86)
+
+\tenpoint\noindent
+[these two mysterious lines should be deleted]
+
+\bugonpage D380, line 11 (5/5/87)
+
+\ninepoint\noindent
+[Variables $q$ and $r$ can be eliminated, since they are not
+used in this procedure! If you delete them, also remove $\underline{862}$
+from the corresponding index entries on page D536.]
+
+\bugonpage D429, line 14 (5/5/87)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $p\gets\\{cur\_exp}$;
+\smallskip
+\noindent[Also eliminate line 12, and delete $\underline{985}$ from the
+index entry for \\{vv} on page D543.]
+
+\bugonpage D455, line 5 (5/5/87)
+
+\ninepoint\noindent
+[This line can be eliminated, since variable $t$ is not
+used in this procedure! If you delete it, also remove $\underline{1059}$
+from the corresponding index entry on page D540; remove 1059 from
+the index entries for \\{small\_number} and \\{with\_option} on pages D539
+and D544; and remove \\{with\_option} from the mini-index on page D455.]
+
+\bugonpage D463, line 10 (12/15/86)
+
+\ninepoint\noindent\hskip30pt
+({\tt"Pretend\]that\]you're\]Miss\]Marple:\]Examine\]all\]clues,"})
+
+\bugonpage D465, lines 17--18 (6/14/87)
+
+\tenpoint\noindent
+[Delete these two lines.]
+
+\bugonpage D474, 5th-last line (3/16/86)
+
+\tenpoint\noindent
+depths, or italic corrections) are sorted;
+then the list of sorted values is perturbed, if necessary.
+
+\bugonpage D481, line 12 (6/17/86)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"Font\]metrics\]written\]on\]\char`\"});\kern5pt
+\\{print}(\\{metric\_file\_name});\kern5pt
+\\{print\_char}({\tt\char`\".\char`\"});
+
+\noindent\hskip10pt\\{b\_close}(\\{tfm\_file})
+
+\smallskip\eightpoint\noindent
+The mini-index at the bottom of this page should also receive the following
+new entry:
+\smallskip\indent
+\\{print\_char}: {\bf procedure}, \S58.
+
+\bugonpage D510, new line to follow line 5 (6/17/86)
+
+{\tenpoint\parindent=1em
+This program doesn't bother to close the input files that may still be open.
+\par}
+
+\bugonpage D510, just before the fifth-last line (8/5/86)
+
+\ninepoint\noindent\hskip30pt$\\{internal}[\\{fontmaking}]\gets0$;\quad
+$\{\,$avoid loop in case of fatal error$\,\}$
+
+\bugonpage D520, right column (6/14/87)
+
+\eightpoint
+\leftline{Chinese characters:\quad 1147.}
+
+\bugonpage D526, left column, lines 1--2 (7/30/86)
+
+\eightpoint
+\leftline{\indent\\{fraction\_half}:\quad
+ $\underline{105}$, 111, 152, 288, 408, 496, 543,}
+\leftline{\indent\qquad 1098, 1128, 1141.}
+
+\bugonpage D526, left column, lines 6--7 (7/30/86)
+
+\eightpoint
+\leftline{\indent\qquad 478, 497, 499, 503, 530, 540, 547, 549, 599, 603,}
+\leftline{\indent\qquad 612, 615, 815--816, 917, 1169--1170.}
+
+\bugonpage D528, right column (6/14/87)
+
+\eightpoint
+\leftline{Japanese characters:\quad 1147.}
+
+\bugonpage D530, right column, line 45 (7/30/86)
+
+\eightpoint
+\leftline{\indent\\{max}:\quad$\underline{539}$, 543.}
+
+\bugonpage D533, right column (6/14/87)
+
+\eightpoint
+\leftline{oriental characters:\quad 1147.}
+
+\bugonpage D535, right column, line 27 (6/17/86)
+
+\eightpoint
+\leftline{\indent\qquad 1134, 1163--1165, 1182, 1194, 1200, 1205, 1213.}
+
+\bugonpage D547, bottom two lines (11/27/86)
+
+\ninepoint\noindent
+[These lines, and the top two on the next page, should move down
+so that they appear in alphabetical order just before `Compute
+test coefficients'.]
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, lines 1--2 (7/28/86)
+
+\tenpoint\noindent
+February 11--13, 1984), 49.
+\ {\it An example meta-character of the Devanagari alphabet, worked out
+``online'' with the help of Matthew Carter.}
+
+\bugonpage Exiii, line 6 (7/28/86)
+
+\tenpoint\noindent
+{\it and western alphabets work also for Devanagari and Tamil.}
+
+\bugonpage E12, lines 15 and 19 (7/23/86)
+
+\tenpoint\noindent[change `17.32' to `17.28' in both places]
+
+\bugonpage E12, third-last line (12/18/86)
+
+\tenpoint\noindent[change `41' to `40']
+
+\bugonpage E13, lines 3, 4, and 20 (12/18/86)
+
+\tenpoint\noindent[change `40' to `41', `48' to `47', `17' to `7']
+
+\bugonpage E18, line 20 (7/23/86)
+
+\tenpoint\noindent[change `17.32' to `17.28']
+
+\bugonpage E18, line 29 (12/9/86)
+
+\tenpoint\noindent[change `236' to `212' in the {\tt cmss9} column]
+
+\bugonpage E170, top illustration (11/2/86)
+
+\tenpoint\noindent[There should be no ``dish'' or depression in the
+vicinity of point {\tt 3r}; the top edge of the character should be
+straight. This error appears also in the other uses of `\\{no\_dish\_serif}'
+throughout the book, since the illustrations were made before
+`\\{no\_dish\_serif}' was added to the program. See page
+E180~(twice at the top), E370~(twice), E374~(twice), E376~(twice), E378~(top),
+E390~(bottom), E398~(top), E402~(top), E406~(top), E453~(twice).]
+
+\bugonpage E179, new line to be inserted after line 6 (10/13/86)
+
+\ninepoint\noindent
+{\bf if} $\\{shaved\_stem}<\\{crisp}.\\{breadth}$:
+ $\\{shaved\_stem}:=\\{crisp}.\\{breadth}$; {\bf fi}
+
+\bugonpage E219, line 29 (6/2/87)
+
+\ninepoint\line{\\{top} $y_1=h$; \ $x_1=x_2$; \
+ {\bf filldraw stroke} $z_{1e}\dashto z_{2'e}$;\hfil\% stem}
+
+\bugonpage E279, seventh line from the bottom (7/20/86)
+
+\rightline{\eightssi that delicious but restrained humor which
+ her readers found so irresistible.}
+
+\bugonpage E301, new line to be inserted after line 28 (5/15/87)
+
+\ninepoint\noindent
+\quad{\bf if} $\\{lower\_side}>1.2\\{upper\_side}$:
+ $\\{upper\_side}:=\\{lower\_side}$; {\bf fi}
+
+\bugonpage E554, bottom half of page (12/18/86)
+
+\ninepoint\noindent[The letters will change slightly because of the
+corrections to {\tt cmr17} noted on pages 12 and 13.]
+
+\bugonpage E561, line 3 (12/9/86)
+
+\ninepoint\noindent[The numerals should be `\thinspace
+{\niness 0123456789}\thinspace' (i.e., 2/3 point less tall)
+because of the correction made to page 18.]
+
+\bugonpage E562, line 9 (12/9/86)
+
+\ninepoint\noindent[The numerals should be `\thinspace
+{\ninessi 0123456789\/}\thinspace' (i.e., 2/3 point less tall)
+because of the correction made to page 18.]
+
+\bugonpage E572, entry for {\it breadth} (10/13/86)
+
+\eightpoint
+{\it breadth}, 59, 75, 79, 91, 93, 179, 225, 233,
+
+\bugonpage E573, entry for {\tt cmcsc10} (8/17/86)
+
+\eightpoint
+{\tt cmcsc10}, $\underline{30}$--$\underline{31}$, 567.
+
+\bugonpage E576, tenth-last line (5/15/87)
+
+\eightpoint
+{\bf lowres\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em
+ fix}, 550.
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata4.tex b/Master/texmf-doc/doc/english/knuth/errata/errata4.tex
new file mode 100644
index 00000000000..11d0435e749
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata4.tex
@@ -0,0 +1,1052 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1987--1988}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A--E\null, between
+16 June 1987 and 20 February 1989. Corrections made to
+the softcover version of {\sl The \TeX book} are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+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.
+ % volume A
+
+\bugonpage A159, line 22 (2/15/88)
+
+\ninepoint\noindent
+`|\nolimits|' if the normal |\displaylimits|
+convention has been overridden; a Rad\cutpar
+
+\bugonpage A213, lines 34--35 (12/23/87)
+
+\ninepoint\noindent
+text will be a single control sequence token, defined to be like |\relax| if
+its meaning is currently undefined.
+
+\bugonpage A299, line 30 (7/6/88)
+
+\ninepoint\indent\tt
+Fatal format file error; I'm stymied.
+
+\bugonpage A326, line 12 (12/12/87)
+
+\ninepoint\noindent
+its natural width. The |\hbox| version also invokes |\everymath|.
+
+\bugonpage A359, line 2 (11/6/88)
+
+\ninepoint\noindent
+|\mathchardef\ldotp="613A\mathchardef\cdotp="6201\mathchardef\colon="603A|
+
+\bugonpage A359, lines 35--38 (5/24/88)
+
+\ninepoint\noindent
+|\def\updownarrow{\delimiter"326C33F } \def\arrowvert{\delimiter"033C000 }|%
+ \par\noindent
+|\def\Updownarrow{\delimiter"326D377 } \def\Arrowvert{\delimiter"033D000 } |%
+ \par\noindent
+|\def\vert{\delimiter"026A30C } \def\Vert{\delimiter"026B30D } |%
+ \par\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"033E000 }|
+
+\bugonpage A364, line 35 (11/6/88)
+
+\ninepoint\noindent
+|\def\fmtname{plain}\def\fmtversion{2.94} % identifies the current format|
+
+\bugonpage A379, line 15 (10/12/87)
+
+\ninepoint
+|\def\deleterightmost#1{\edef#1{\expandafter\xyzzy#1\xyzzy}}|
+
+\bugonpage A383, lines 7--15 from the bottom (1/4/89)
+
+\begintt
+ 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
+\endtt
+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.
+
+\bugonpage A454, lines 23--29 (8/13/87)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger If a suitable starting letter is found, let it be in font~$f$.
+Hyphenation is abandoned 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$.
+
+\endgroup % end the special hyphenation conventions
+
+\bugonpage A458, left column, line 19 (2/15/88)
+
+\eightpoint\indent
+|\|\| ( $\Vert$ ), {\it146--147}, {\it171}, $\underline{361}$, 435, 438.
+
+\bugonpage A462, left column, line 7 (10/9/87)
+
+\eightpoint\indent\qquad 152, 178, $\underline{360}$.
+
+\bugonpage A463, left column (4/17/88)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\day|, 273, 349, {\it406}.
+
+\bugonpage A464, left column, under Displays (12/8/88)
+
+\eightpoint\indent\quad
+non-centered, 186, 326, 375--376, 420--421.
+
+\bugonpage A465, entry for {\tt\char`\\everymath} (12/12/87)
+
+\eightpoint\indent[Include also a reference to page 326.]
+
+\bugonpage A465, right column (7/6/88)
+
+\eightpoint\indent{\tt Fatal format file error}, 299.
+
+\bugonpage A473, entry for `page builder' (8/13/87)
+
+\eightpoint\indent\quad when exercised, 122, 280--283, 286--287.
+
+\bugonpage A474, left column (12/27/88)
+
+\eightpoint\indent
+\hbox to0pt{\hss\lower1pt\hbox{*}}|\parshape|, 101--102, 214, 271, 277, 283,
+
+\bugonpage A480, right column (2/15/88)
+
+\eightpoint\indent|\vdots| ( $\vdots$ ), {\it177}, $\underline{359}$.
+
+\bugonpage A481, right column (7/3/87)
+
+\eightpoint|\z@|, $\underline{347}$, 348.\par
+|\z@skip|, $\underline{347}$, 348.
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 32 (2/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.97\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B38, lines 7--9 from the bottom (11/6/88)
+
+\tenpoint\noindent[Delete this paragraph; it is being moved to page B214.]
+
+\bugonpage B38, line 5 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{term\_and\_log}$
+
+\bugonpage B39, line 5 (12/14/88)
+
+\ninepoint\noindent\kern50pt
+{\bf if\/} \\{log\_opened} {\bf then} \\{error};
+
+\bugonpage B52, line 5 (8/13/87)
+
+\tenpoint\noindent
+cannot be done, i.e., if $\\{hi\_mem\_min}=\\{lo\_mem\_max}+1$,
+we have to quit.
+
+\bugonpage B54, lines 34--35 (7/9/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} $\\{hi\_mem\_min}-\\{lo\_mem\_max}\ge1998$
+ {\bf then} $t\gets\\{lo\_mem\_max}+1000$\par\noindent\kern10pt
+{\bf else} $t\gets\\{lo\_mem\_max}+1+(\\{hi\_mem\_min}-\\{lo\_mem\_max})
+\,\mathbin{\bf div}\,2$;\quad\kern-4pt
+$\{\,\\{lo\_mem\_max}+2\le t<\\{hi\_mem\_min}\,\}$
+
+\bugonpage B108, new line after line 8 (5/24/88)
+
+\ninepoint\noindent\kern20pt
+$d$: \\{integer};\quad
+$\{\,$number of characters in incomplete current string$\,\}$
+
+\bugonpage B108, lines 31--33 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{str\_room}(l)$; $d\gets\\{cur\_length}$;\par\noindent\kern10pt
+{\bf while} $\\{pool\_ptr}>\\{str\_start}[\\{str\_ptr}]$ {\bf do}
+ \par\noindent\kern20pt
+{\bf begin} \\{decr}(\\{pool\_ptr});
+ $\\{str\_pool}[\\{pool\_ptr}+l]\gets\\{str\_pool}[\\{pool\_ptr}]$;
+ \par\noindent\kern20pt
+{\bf end};\quad$\{\,$move current string up to make room for another$\,\}$
+\par\noindent\kern10pt
+{\bf for} $k\gets j$ {\bf to} $j+l-1$ {\bf do} $\\{append\_char}(\\{buffer}[k])$;
+\par\noindent\kern10pt
+$\\{text}(p)\gets\\{make\_string}$; $\\{pool\_ptr}\gets\\{pool\_ptr}+d$;
+
+\bugonpage B115, line 12 (4/28/88)
+
+\ninepoint\noindent\hskip10pt
+$\\{group\_code}=0\to\\{max\_group\_code}$;\quad
+ $\{\,$\\{save\_level} for a level boundary$\,\}$
+
+\bugonpage B141, line 19 (4/28/88)
+
+\ninepoint\noindent
+\\{par\_token}: \\{halfword};\quad
+ $\{\,$token representing `|\par|'$\,\}$
+
+\bugonpage B150, line 24 (4/28/88)
+
+\tenpoint\noindent{\bf 358.\quad}%
+The present point in the program is reached only when the \\{expand}
+routine has inserted\cutpar
+
+\bugonpage B151, mini-index (4/28/88)
+
+\eightpoint\noindent
+Delete the entry for `\\{no\_expand}'; replace it by:
+
+\indent\\{expand}: {\bf procedure}, \S366.
+
+\bugonpage B154, lines 25, 29, 34 respectively (9/20/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cvl\_backup},\\{radix\_backup},\\{co\_backup}$: \\{small\_number};\quad
+ $\{\,$to save \\{cur\_val\_level}, etc.$\,\}$\par\noindent\hskip10pt
+$\\{co\_backup}\gets\\{cur\_order}$;
+ $\\{backup\_backup}\gets\\{link}(\\{backup\_head})$;\par\noindent\hskip10pt
+$\\{cur\_order}\gets\\{co\_backup}$;
+ $\\{link}(\\{backup\_head})\gets\\{backup\_backup}$;
+
+\bugonpage B155, new entry for mini-index (9/20/87)
+
+\eightpoint\indent
+\\{cur\_order}: \\{glue\_ord}, \S447.
+
+\bugonpage B156, line 28 (12/23/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{eq\_define}(\\{cur\_cs},\\{relax},256)$;
+
+\bugonpage B157, mini-index (12/23/87)
+
+\eightpoint\noindent
+Delete the entries for `\\{eqtb}' and `\\{frozen\_relax}'; replace them
+by the following:
+
+\indent\\{eq\_define}: {\bf procedure}, \S227.\par
+$\\{relax}=0$, \S207.\par
+
+\bugonpage B162, lines 12--14 (4/30/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf repeat} $\\{link}(\\{temp\_head})\gets\\{null}$;\par\noindent\hskip20pt
+{\bf if\/} $(\\{info}(r)>\\{match\_token}+127)\lor
+ (\\{info}(r)<\\{match\_token})$ {\bf then}
+ $s\gets\\{null}$\par\noindent\hskip20pt
+{\bf else begin} $\\{match\_chr}\gets\\{info}(r)-\\{match\_token}$; \
+ $s\gets\\{link}(r)$; \ $r\gets s$; \ $p\gets\\{temp\_head}$; \
+ $m\gets 0$;
+
+\bugonpage B177, bottom line before mini-index (7/13/88)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_val}\gets0$; \
+ $\\{cur\_val\_level}\gets\\{int\_val}$; \
+ $\\{radix}\gets0$; \
+ $\\{cur\_order}\gets0$;
+
+\bugonpage B181, line 31 (4/28/88)
+
+\ninepoint\noindent
+[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.]
+
+\bugonpage B188, line 8 (5/25/88)
+
+\ninepoint\noindent
+{\bf function} $\\{str\_toks}(b:\\{pool\_pointer})$: \\{pointer};\quad
+ $\{\,$changes the string \\{str\_pool}$[b\to\\{pool\_ptr}]$ to a token list$\,\}$
+
+\bugonpage B188, line 13 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin} \\{str\_room}(1); $p\gets\\{temp\_head}$;
+ $\\{link}(p)\gets\\{null}$; $k\gets b$;
+
+\bugonpage B188, line 20 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+$\\{pool\_ptr}\gets b$; $\\{str\_toks}\gets p$;
+
+\bugonpage B188, new line after line 28 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$b$: \\{pool\_pointer};\quad$\{\,$base of temporary string$\,\}$
+
+\bugonpage B188, line 31 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf else begin} $\\{old\_setting}\gets\\{selector}$;
+ $\\{selector}\gets\\{new\_string}$; $b\gets\\{pool\_ptr}$;
+
+\bugonpage B188, line 41 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$\\{selector}\gets\\{old\_setting}$; $\\{the\_toks}\gets\\{str\_toks}(b)$;
+
+\bugonpage B190, lines 16--18 (5/25/88)
+
+\ninepoint\noindent\kern20pt
+$b$: \\{pool\_pointer};\quad$\{\,$base of temporary string$\,\}$\par
+\noindent\kern10pt
+{\bf begin} $c\gets\\{cur\_chr}$;
+ $\langle\,$Scan the argument for command $c${\eightrm\kern.5em471}$\,\rangle$;
+\par\noindent\kern10pt
+$\\{old\_setting}\gets\\{selector}$;
+$\\{selector}\gets\\{new\_string}$; $b\gets\\{pool\_ptr}$;
+$\langle\,$Print the result of command~$c${\eightrm\kern.5em472}$\,\rangle$;
+\par\noindent\kern10pt
+$\\{selector}\gets\\{old\_setting}$;
+$\\{link}(\\{garbage})\gets\\{str\_toks}(b)$;
+$\\{ins\_list}(\\{link}(\\{temp\_head}))$;
+
+\bugonpage B210, line 36 (5/25/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if} $(\\{pool\_ptr}+\\{name\_length}>\\{pool\_size})
+ \lor(\\{str\_ptr}=\\{max\_strings})\lor(\\{cur\_length}>0)$ {\bf then}
+
+\bugonpage B211, new line of code before the mini-index (12/14/88)
+
+\ninepoint\noindent
+\\{log\_opened}: \\{boolean};\quad$\{\,$has the transcript file been opened?$\,\}$
+
+\bugonpage B212, line 5 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{job\_name}\gets0$; \ $\\{name\_in\_progress}\gets\\{false}$; \
+$\\{log\_opened}\gets\\{false}$;
+
+\bugonpage B213, line 24 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{log\_name}\gets\\{a\_make\_name\_string}(\\{log\_file})$; \
+$\\{selector}\gets\\{log\_only}$; \
+$\\{log\_opened}\gets\\{true}$;
+
+\bugonpage B214, lines 2 and 3 (12/14/88)
+
+\tenpoint\noindent
+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.
+\par\noindent\hskip10pt
+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.
+
+\bugonpage B214, lines 7--11 reduce to a single line (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $\\{selector}\gets\\{term\_only}$;
+
+\bugonpage B224, second-last line (4/28/87)
+
+\ninepoint\noindent
+\\{done}: {\bf if} \\{file\_opened} {\bf then} \\{b\_close}(\\{tfm\_file});\par
+\noindent\hskip10pt $\\{read\_font\_info}\gets g$;
+
+\bugonpage B229, lines 6--8 (11/17/87)
+
+\tenpoint\noindent
+than $2^{27}$.
+If $z<2^{23}$, the individual multiplications $b\cdot z$,
+$c\cdot z$, $d\cdot 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^\prime=z/2^e$, let $\beta=2^{4-e}$; we shall compute
+
+\bugonpage B229, lines 11--12 (11/17/87)
+
+\tenpoint\noindent
+if $a=0$, or the same quantity minus $\alpha=2^{4+e}z^\prime$ if $a=255$.
+This calculation must be done exactly, in order to guarantee portability
+of \TeX\ between computers.
+
+\bugonpage B230, lines 2--5 (11/17/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf begin} $\\{alpha}\gets16$;\par
+\noindent\hskip10pt{\bf while} $z\ge\oct{40000000}$ {\bf do}\par
+\noindent\hskip20pt{\bf begin} $z\gets z\ {\bf div}\ 2$; \
+ $\\{alpha}\gets\\{alpha}+\\{alpha}$; \ {\bf end};\par
+\noindent\hskip10pt$\\{beta}\gets256\ {\bf div}\ \\{alpha}$; \
+ $\\{alpha}\gets\\{alpha}\ast z$;\par
+
+\bugonpage B245, new entry for mini-index (8/7/87)
+
+\eightpoint\indent
+\\{cur\_s}: \\{integer}, \S616.
+
+\bugonpage B254, line 29 (8/7/87)
+
+\ninepoint\noindent
+\\{cur\_s}: \\{integer};\quad
+$\{\,$current depth of output box nesting, initially $-1\,\}$
+
+\bugonpage B254, line 31 (8/7/87)
+
+\ninepoint\noindent
+[Remove the statement `$\\{cur\_s}\gets-1$;' and put it on page B244 at the
+end of line 31.]
+
+\bugonpage B259, line 13 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{rule\_wd}\gets\\{rule\_wd}+10$;\quad
+$\{\,$compensate for floating-point rounding$\,\}$\par\noindent\hskip20pt
+$\\{edge}\gets\\{cur\_h}+\\{rule\_wd}$; $\\{lx}\gets0$;
+$\langle\,$Let \\{cur\_h} be the position of the first box, and set
+
+\bugonpage B259, line 17 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cur\_h}\gets\\{edge}-10$; {\bf goto} \\{next\_p};
+
+\bugonpage B263, line 21 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin }$\\{rule\_ht}\gets\\{rule\_ht}+10$;\quad
+$\{\,$compensate for floating-point rounding$\,\}$\par\noindent\hskip20pt
+$\\{edge}\gets\\{cur\_v}+\\{rule\_ht}$; $\\{lx}\gets0$;
+$\langle\,$Let \\{cur\_v} be the position of the first box, and set
+
+\bugonpage B263, line 25 (11/9/87)
+
+\ninepoint\noindent\hskip20pt
+$\\{cur\_v}\gets\\{edge}-10$; {\bf goto} \\{next\_p};
+
+\bugonpage B266, line 8 (8/7/87)
+
+\ninepoint\noindent\hskip10pt
+\\{dvi\_out}(\\{eop}); \\{incr}(\\{total\_pages}); $\\{cur\_s}\gets-1$;
+
+\bugonpage B266, new code between lines 31 and 32 (8/7/87)
+
+\ninepoint
+\noindent\hskip10pt{\bf while} $\\{cur\_s}>-1$ {\bf do}\par
+\noindent\hskip20pt{\bf begin if} $\\{cur\_s}>0$ {\bf then}
+ \\{dvi\_out}(\\{pop})\par
+\noindent\hskip20pt{\bf else begin} \\{dvi\_out}(\\{eop});
+ \\{incr}(\\{total\_pages})\par
+\noindent\hskip30pt{\bf end};\par
+\noindent\hskip20pt\\{decr}(\\{cur\_s});\par
+\noindent\hskip20pt{\bf end};\par
+
+\bugonpage B285, line 21 (4/28/88)
+
+\noindent\tenpoint
+is subsidiary to the \\{nucleus} field of some noad; the dot is replaced by
+`|_|' or `|^|' or `|/|' or `|\|' if $p$ is\cutpar
+
+\bugonpage B338, second-last line (8/19/87)
+
+\ninepoint\noindent\kern10pt
+$q\gets\\{link}(\\{head})$; $s\gets\\{head}$;
+
+\bugonpage B339, line 4 (8/19/87)
+
+\ninepoint\noindent\kern20pt
+$s\gets q$; $q\gets\\{link}(q)$;
+
+\bugonpage B339, new code to insert after line 10 (8/19/87)
+
+\ninepoint
+\noindent\kern10pt{\bf if} $o\ne0$ {\bf then}\par
+\noindent\kern20pt{\bf begin} $r\gets\\{link}(q)$; $\\{link}(q)\gets\\{null}$;
+ $q\gets\\{hpack}(q,\\{natural})$;\par
+\noindent\kern20pt$\\{shift\_amount}(q)\gets o$; $\\{link}(q)\gets r$;
+ $\\{link}(s)\gets q$;\par
+\noindent\kern20pt{\bf end};\par
+\noindent[These new lines also imply changes to the index that aren't
+ shown in this errata list.]
+
+\bugonpage B387, line 2 (5/24/88)
+
+\tenpoint\noindent
+is quite short. In the following code we set \\{hc}$[\\{hn}+2]$ to the
+impossible value 128, in order to\cutpar
+
+\bugonpage B387, line 8 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{hc}[0]\gets127$; $\\{hc}[\\{hn}+1]\gets127$;
+ $\\{hc}[\\{hn}+2]\gets128$;\quad$\{\,$insert delimiters$\,\}$
+
+\bugonpage B390, lines 17--18 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\langle\,$Enter as many hyphenation exceptions as are listed, until coming
+ to a right brace; then {\bf return\eightrm\kern.5em961}$\,\rangle$;
+
+\smallskip[The same change applies to lines 20--21, and
+to page~582.]
+
+\bugonpage B396, new line after line 34 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$\\{trie\_link}(\\{trie\_size})\gets0$;
+$\\{trie\_back}(0)\gets\\{trie\_size}$;\quad
+$\{\,$wrap around$\,\}$
+
+\bugonpage B396, bottom line (12/12/87)
+
+\ninepoint\noindent\hskip10pt
+$\\{trie\_link}(0)\gets0$; $\\{trie\_char}(0)\gets0$;
+ $\\{trie\_op}(0)\gets\\{min\_quarterword}$;
+
+\bugonpage B397, lines 15--17 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin} $c\gets\\{trie\_c}[p]$;\par\noindent\kern10pt
+{\bf if} $c<\\{trie\_min}$ {\bf then} $\\{trie\_min}\gets c$;\par\noindent\kern10pt
+{\bf if} $\\{trie\_min}=0$ {\bf then} $z\gets\\{trie\_link}(\\{trie\_size})$\par
+\noindent\kern10pt
+{\bf else} $z\gets\\{trie\_link}(\\{trie\_min}-1)$;\quad
+$\{\,$get the first conceivably good hole$\,\}$
+
+\bugonpage B400, lines 3--4 (5/24/88)
+
+\ninepoint\noindent
+$\langle\,$Enter all of the patterns into a linked trie, until coming
+ to a right brace{\eightrm\kern.5em961}$\,\rangle\equiv$
+
+\smallskip[The same change applies to page B399, lines 29--30, and
+to page~582.]
+
+\bugonpage B402, line 10 (5/24/88)
+
+\ninepoint\noindent\kern10pt
+$r\gets\\{trie\_size}$;\quad
+$\{\,$finally, we will zero out the holes$\,\}$
+
+\bugonpage B406, line 9 from the bottom (1/23/89)
+
+\ninepoint\noindent\kern30pt
+$\\{shrink\_order}(r)\gets\\{normal}$; \ $\\{delete\_glue\_ref}(q)$; \
+$\\{glue\_ptr}(p)\gets r$; \ $q\gets r$;
+
+\bugonpage B417, line 10 (1/23/89)
+
+\ninepoint\noindent\kern10pt
+$q\gets\\{new\_skip\_param}(\\{top\_skip\_code})$; \quad
+$\{\,$now $\\{temp\_ptr}=\\{glue\_ptr}(q)\,\}$
+
+\bugonpage B418, line 14 (1/23/89)
+
+\ninepoint\noindent\kern30pt
+$\\{shrink\_order}(r)\gets\\{normal}$; \ $\\{delete\_glue\_ref}(q)$; \
+$\\{glue\_ptr}(p)\gets r$; \ $q\gets r$;
+
+\bugonpage B507, line 13 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{selector}+2$;
+
+\bugonpage B527, line 21 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage B528, line 5 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage B547, right column (9/20/87)
+
+\eightpoint
+\leftline{\\{co\_backup}:\quad $\underline{366}$.}
+
+\bugonpage B548, right column (9/20/87)
+
+\eightpoint
+\leftline{\\{cur\_order}:\quad 366, $\underline{447}$, 448, 454, 462.}
+
+\bugonpage B548, right column (8/7/87)
+
+\eightpoint
+\leftline{\\{cur\_s}:\quad 593, $\underline{616}$, 619, 629, 640, 642.}
+
+\bugonpage B551, both columns (12/23/87)
+
+\eightpoint[Remove `372' from \\{eqtb} and put it into \\{eq\_define}.]
+
+\bugonpage B552, left column (4/28/88)
+
+\eightpoint[Insert `358' into \\{expand}.]
+
+\bugonpage B554, left column (12/23/87)
+
+\eightpoint[Remove `372' from \\{frozen\_relax}.]
+
+\bugonpage B559, new entry (12/14/88)
+
+\eightpoint\noindent
+\\{log\_opened}, 92--93, $\underline{527}$, 528, 534--535, 1265, 1333--1334.
+
+\bugonpage B559, right column (8/13/87)
+
+\eightpoint[Delete the entry for \\{low\_mem\_max}.]
+
+\bugonpage B562, left column (4/28/88)
+
+\eightpoint[Remove `358' from \\{no\_expand}.]
+
+\bugonpage B565, left column (8/7/87)
+
+\eightpoint
+\leftline{\\{pop}:\quad 584--585, $\underline{586}$, 590, 601, 608, 642.}
+
+\bugonpage B567, left column (12/23/87)
+
+\eightpoint[Insert `372' into \\{relax}.]
+
+\bugonpage B568, left column (4/28/88)
+
+\eightpoint[Move `269' from \\{save\_index} to \\{save\_level}.]
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C26, bottom line (7/18/87)
+
+\tenpoint\noindent
+What angle corresponds to the direction North-Northwest?
+
+\bugonpage C107, line 13 (10/7/87)
+
+{\bf pickup penrazor} xscaled \\{heavyline}
+ rotated (angle$(z_{32}-z_{31})+90$);
+
+\bugonpage C164, line 10 (4/27/88)
+
+\ninepoint\indent
+\quad $y_{\$c}=\\{top}\,y_{\$l}$; \ $y_{\$d}=y_{\$r}$; \
+ $x_{\$c}=x_{\$l}-\\{left\_jut}$; \ $x_{\$d}=x_{\$r}+\\{right\_jut}$;
+
+\bugonpage C175, line 23 (1/11/88)
+
+\ninepoint\noindent
+expand into a sequence of tokens. \
+(The language {\eightrm{SIMULA67}} demonstrated that it is\cutpar
+
+\bugonpage C241, line 11 (5/25/88)
+
+\ninepoint\indent
+{\bf numeric} $\\{ht}\0,\\{dp}\0$; \
+ $\\{ht}\0=\\{body\_height}\0$; \
+ $.5[\\{ht}\0,-\\{dp}\0]=\\{axis}\0$;
+
+\bugonpage C248, line 21 becomes two lines (1/24/89)
+
+\ninepoint\noindent
+which might not
+be numerically stable in the presence of rounding errors.)
+Another case, not really desirable, is $\\{left\_jut}=\\{right\_jut}=0$.
+
+\bugonpage C262, line 15 (12/23/88)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="1.7";|
+
+\bugonpage C271, line 12 (1/4/89)
+
+\ninepoint\noindent
+the user and \MF's primitive picture commands.
+First, some important program\cutpar
+
+\bugonpage C271, line 4 from the bottom (12/23/88)
+
+\ninepoint\noindent
+|def |^|cutdraw|| expr p = % caution: you may need autorounding=0|
+
+\bugonpage C272, lines 5 and 6 (12/23/88)
+
+\ninepoint\noindent
+| (cut_ scaled (1+max(pen_lft,pen_rt,pen_top,pen_bot))|\par\noindent
+| rotated theta shifted z)t_;|
+
+\bugonpage C273, lines 20 and 22 (9/26/88)
+
+\ninepoint\noindent
+| (z_+(0,pen_top))t_=round((z+(0,pen_top))t_); z_ enddef;|\par\noindent
+| (z_+(0,pen_bot))t_=round((z+(0,pen_bot))t_); z_ enddef;|
+
+\bugonpage C290, line 6 from the bottom (12/23/88)
+
+\ninepoint\noindent
+(2)~A throwaway variable,
+`\\{whatever}', nullifies an unwanted equation at the beginning\cutpar
+
+\bugonpage C331, just below the illustration (7/18/87)
+
+\ninepoint\noindent
+Such a pattern is, of course, rather unlikely to occur in a |gf| file,
+but |GFtoDVI| would\cutpar
+
+\bugonpage C337, line 11 (4/28/88)
+
+\ninepoint
+An online ``menu'' of the available test routines will be typed at your
+terminal\cutpar
+
+\bugonpage C346, entry for {\tt autorounding} (12/23/88)
+
+\eightpoint\indent\hskip20pt
+212, {\it262}, {\it264}, 271--272.
+
+\bugonpage C350, left column (7/6/88)
+
+\eightpoint\indent
+|Fatal| |base| |file| |error|, 226.
+
+\bugonpage C356, left column (1/11/88)
+
+\eightpoint
+SIMULA67 language, 175.
+
+\bugonpage C358, right column (2/15/88)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|yoffset|, 212, $\underline{220}$, 315, 324.
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage D2, line 27 (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]1.7\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D36, lines 3--5 (11/6/88)
+
+\tenpoint\noindent[Delete this paragraph; it is being moved to page D349.]
+
+\bugonpage D36, line 7 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{term\_and\_log}$
+
+\bugonpage D36, line 16 (12/14/88)
+
+\ninepoint\noindent\kern50pt
+{\bf if\/} \\{log\_opened} {\bf then} \\{error};
+
+\bugonpage D66, lines 34--35 (7/9/88)
+
+\ninepoint\noindent\kern10pt
+{\bf begin if\/} $\\{hi\_mem\_min}-\\{lo\_mem\_max}\ge1998$
+ {\bf then} $t\gets\\{lo\_mem\_max}+1000$\par\noindent\kern10pt
+{\bf else} $t\gets\\{lo\_mem\_max}+1+(\\{hi\_mem\_min}-\\{lo\_mem\_max})
+\,\mathbin{\bf div}\,2$;\quad\kern-4pt
+$\{\,\\{lo\_mem\_max}+2\le t<\\{hi\_mem\_min}\,\}$
+
+\bugonpage D347, new line of code after line 5 (12/14/88)
+
+\ninepoint\noindent
+\\{log\_opened}: \\{boolean};\quad$\{\,$has the transcript file been opened?$\,\}$
+
+\bugonpage D347, line 11 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{job\_name}\gets0$; \
+$\\{log\_opened}\gets\\{false}$;
+
+\bugonpage D348, line 4 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+$\\{log\_name}\gets\\{a\_make\_name\_string}(\\{log\_file})$; \
+$\\{selector}\gets\\{log\_only}$; \
+$\\{log\_opened}\gets\\{true}$;
+
+\bugonpage D349, lines 6 and 7 (12/14/88)
+
+\tenpoint\noindent
+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.
+\par\noindent\hskip10pt
+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.
+
+\bugonpage D349, lines 11--15 reduce to a single line (12/14/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $\\{selector}\gets\\{term\_only}$;
+
+\bugonpage D420, bottom line (5/25/88)
+
+\ninepoint\noindent\kern30pt
+{\bf if\/} \\{txx} {\bf mod} $\\{unity}=0$ {\bf then}
+
+\bugonpage D441, delete line 2 and change line 12 as follows (5/25/88)
+
+\ninepoint\noindent
+\\{done}: {\bf if} $\\{eq\_type}(x)\ne\\{tag\_token}$ {\bf then}
+ $\\{clear\_symbol}(x,\\{false})$;\par\noindent\kern10pt
+{\bf if} $\\{equiv}(x)=\\{null}$ {\bf then} $\\{new\_root}(x)$;
+\par\noindent\kern10pt
+$\\{scan\_declared\_variable}\gets h$;
+
+\bugonpage D444, line 8 from the bottom (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then} $\\{selector}\gets\\{selector}+2$;
+
+\bugonpage D510, line 14 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage D511, line 11 (12/14/88)
+
+\ninepoint\noindent\kern10pt
+{\bf if\/} \\{log\_opened} {\bf then}
+
+\bugonpage D530, new entry (12/14/88)
+
+\eightpoint\noindent
+\\{log\_opened}, 87--88, $\underline{782}$, 783, 788--789, 1023, 1205, 1208.
+
+\bugonpage D545, left column (10/31/87)
+
+\eightpoint
+\leftline{{\bf zscaled} primitive:\quad $\underline{893}$.}
+\leftline{Zabala Salelles, Ignacio Andres:\quad 812.}
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage E32, second-last line (9/20/87)
+
+\tenpoint\noindent
+after which comes `\\{math\_axis}\0; {\bf generate} |mathsy|' (which we
+won't bother to\cutpar
+
+\bugonpage E111, line 29 (10/16/88)
+
+\ninepoint\noindent
+$\\{lft}\,x_{11}={\rm hround}\,u$; \
+ $x_{1l}-x_{11}=x_{2l}-x_{12}=x_{22}-x_{2r}={\rm hround}\,1.6\\{cap\_jut}$;
+
+\bugonpage E285, bottom line (12/1/87)
+
+\rightline{\eightssi Due to Technical Developments\/\enspace\eightss(1968)}
+
+\bugonpage E333, lines 9--11 (1/9/89)
+
+\ninepoint\noindent
+$\\{lft}\,x_{1l}={\rm hround}(2.5u-.5\\{mfudged.stem})$; \
+ $x_{1l}=x_{1'l}=x_{2l}=x_{2'l}$;\par\noindent
+$\\{lft}\,x_{3l}={\rm hround}(.5w-.5\\{mfudged.stem})$; \
+ $x_5-x_3=x_3-x_1$;\par
+\line{{\bf if\/} not \\{monospace}:
+ $r:={\rm hround}(x_5+x_1)+r-w$; {\bf fi}\hfill
+ \% change width for better fit}
+
+\bugonpage E353, lines 38--39 (8/12/87)
+
+\ninepoint
+\leftline{\kern10pt{\bf else}: {\bf fill} \\{diag\_end}$(6r,5r,1,1,5l,6l)
+ \dashto.9[z_{5l},z_{6l}]$}
+\line{\kern30pt$.\,.\,\{z_5-z_6\}\,.1[z_{5r},z_{6r}]\dashto\rm cycle$;\hfil
+ \% middle stem}
+
+\bugonpage E387, line 13 (8/12/87)
+
+\ninepoint
+\line{\kern10pt{\bf pickup} \\{tiny}.\\{nib}; \ \\{bulb}$(3,4,5)$;\hfil\% bulb}
+
+\bugonpage E413, lines 37--38 (8/12/87)
+
+\ninepoint
+\leftline{\kern10pt{\bf else}: {\bf fill} \\{diag\_end}$(6r,5r,1,1,5l,6l)
+ \dashto.9[z_{5l},z_{6l}]$}
+\line{\kern30pt$.\,.\,\{z_5-z_6\}\,.1[z_{5r},z_{6r}]\dashto\rm cycle$;\hfil
+ \% middle stem}
+
+\bugonpage E459, line 24 (8/7/87)
+
+\ninepoint\noindent[Delete the `$=$' sign between `\\{lft}' and `$x_5$'.]
+
+\bugonpage E471, line 5 (12/11/88)
+
+\ninepoint\noindent
+$x_2=\\{good}.x\,.5w$; \ $\\{center\_on}(x_2)$;
+
+\bugonpage E471, insert two lines below the rule at bottom of page (12/11/88)
+
+\ninepoint
+\line{{\bf def\/}
+\\{center\_on}({\bf expr} $x) =\null$
+{\bf if\/} not \\{monospace}:\hfill \% change width for symmetric fit}
+\leftline{\kern10pt
+ $r:=r+2x-w$; \ $w:=2x$; \ {\bf fi} {\bf enddef};}
+
+\bugonpage E477, line 20 (12/11/87)
+
+\ninepoint\noindent
+$x_4=x_8=\\{good}.x\,.5w$; \ $\\{center\_on}(x_4)$; \
+$x_2=w-x_6=\\{good}.x(x_4+a)$;
+
+\bugonpage E483, third line of elementary division operator (12/11/88)
+
+\ninepoint\noindent
+$x_3-.5\\{dot\_size}={\rm hround}(.5w-.5\\{dot\_size})$; \
+$\\{center\_on}(x_3)$;
+
+\bugonpage E485, line 4 (8/7/87)
+
+\ninepoint\noindent[Delete the `$=$' sign between `\\{lft}' and `$x_5$'.]
+
+\bugonpage E487, line 17 (8/4/88)
+
+\ninepoint\line{%
+{\bf fill} \\{fullcircle} scaled$\,(\\{bold}+3.8\\{dw}+\\{eps})\,$%
+ shifted$\,(.5[z_4,z_8])$;\hfill\% dot}
+\smallskip\noindent[Also remove page 487 from the index entry for
+\\{dot\_size}, and add it to the entries for \\{bold} and \\{dw}.]
+
+\bugonpage E515, lines 5 and 12 (12/11/88)
+
+\ninepoint\noindent
+$.5[x_1,x_2]=x_3=\\{good}.x\,.5w$; \
+$\\{center\_on}(x_3)$; \ $\\{lft}\,x_1={\rm hround}(.5w-u*{\rm sqrt}48)$;
+
+\bugonpage E515, line 21 (1/23/89)
+
+\ninepoint\noindent
+{\bf labels}$(5,6)$; \ \\{zero\_width}; \ {\bf endchar\/};
+\smallskip\noindent[Also put labels `{\tt5}' and `{\tt6}' on the
+upper right figure, page E514.]
+
+\bugonpage E521, lines 4 and 14 (12/12/88)
+
+\ninepoint\noindent
+$x_1=x_2=\\{good}.x\,.5w$; \
+$\\{center\_on}(x_1)$; \ $\\{lft}\,x_3={\rm hround}\,u$; \ $x_4=w-x_3$;
+
+\bugonpage E537, line 6 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_2=x_3=x_4$; \
+$x_1-.5\\{stem}={\rm hround}(.5w-.5\\{stem})$; \
+$\\{center\_on}(x_1)$;
+
+\bugonpage E537, line 19 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_2=x_3$; \
+$x_1-.5\\{stem}={\rm hround}(.5w-.5\\{stem})$; \
+$\\{center\_on}(x_1)$;
+
+\bugonpage E539, line 4 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_4=x_{30}=x_{33}=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E539, line 21 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_4=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E541, line 4 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_5=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E541, line 17 (12/11/88)
+
+\ninepoint\noindent
+$x_1=x_{10}=\\{good}.x\,.5w$; \ $\\{center\_on}(x_1)$;
+
+\bugonpage E550, new line after line 23 (8/15/87)
+
+\ninepoint\noindent\kern10pt
+{\bf forsuffixes} $\hbox{\$}=\\{notch\_cut},\\{cap\_notch\_cut}$:
+ {\bf if\/} $\hbox{\$}<3$: $\hbox{\$}:=3$; {\bf fi endfor}
+\smallskip\noindent
+[To make room for this, combine lines 38 and 39 into a single line.]
+
+\bugonpage E550, line 29 (7/9/88)
+
+\ninepoint\noindent\hskip10pt
+{\bf \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+define\_whole\_vertical\_blacker\_pixels}$(\\{vair},\\{bar},\\{slab},
+ \\{cap\_bar},\\{cap\_band})$;
+
+\bugonpage E572, new entry at bottom (12/11/88)
+
+\eightpoint\noindent
+\\{center\_on}, $\underline{471}$, 477, 483, 515, 521, 537--541.
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata5.tex b/Master/texmf-doc/doc/english/knuth/errata/errata5.tex
new file mode 100644
index 00000000000..4e2982f109a
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata5.tex
@@ -0,0 +1,1108 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1989}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes \hbox{A--E}, between 20 February 1989 and
+30 September 1989 (when \TeX\ Version 3.0 and \MF\ Version 2.0 were
+fully defined). Corrections made to
+the softcover version of {\sl The \TeX book\/} are the same as corrections to
+Volume~A\null. Corrections to the softcover version of {\sl The
+\slMF\kern1ptbook\/} are the same as corrections to Volume~C\null.
+Some of these corrections have already been made in reprintings
+of the books. Several minor changes
+to Volumes A~and~C are not shown here because they simply
+make room for the more substantive changes needed to describe the new
+features of \TeX\ Version 3.0 and \MF\ Version 2.0. Hundreds of
+changes will soon be made to Volumes B~and~D because of the upgrades
+to \TeX\ and \MF\/; it will unfortunately be impossible to document all of those
+changes. Therefore, readers who need up-to-date information on the \TeX\ and
+\MF\ programs should refer to the |WEB| source files until new
+printings of Volumes B~and~D are issued.
+
+ % volume A
+
+\buginvol A, in general (9/23/89)
+
+\ninepoint\noindent
+[Change `127' to `255' and `128' to `256' in contexts referring to character
+codes. This happens on pages 37(twice), 39, 41, 43, 44(twice), 48, 93, 154,
+277, 305(twice), 308(twice), 313, and 343. Also change `7-bit' to `8-bit' on
+pages 214 and 277.]
+
+\bugonpage A23, line 16 (9/23/89)
+
+|This is TeX, Version 3.0 (preloaded format=plain 89.7.15)|
+
+\bugonpage A34, new copy for bottom of page (9/23/89)
+
+\ddanger If you use \TeX\ format packages designed by others, your
+error messages may involve many inscrutable two-line levels of macro
+context. By setting ^|\errorcontextlines||=0| at the beginning of your file,
+you can reduce the amount of information that is reported;
+\TeX\ will show only the top and bottom pairs of context lines
+together with up to |\errorcontextlines| additional two-line items. \ (If
+anything has thereby been omitted, you'll also see `|...|'.) \ Chances
+are good that you can spot the source of an error even when most of a
+large context has been suppressed; if not, you can say
+`|I\errorcontextlines=100\oops|' and try again. \ (That will usually
+give you an undefined control sequence error and plenty of context.) \
+Plain \TeX\ sets |\errorcontextlines=5|.
+
+\bugonpage A45, lines 9--15 (9/23/89)
+
+\ninepoint\noindent
+|^^| has an internal code between 64 and 127, \TeX\
+subtracts 64 from the code; if the code is between 0 and 63, \TeX\
+adds~64. Hence code 127 can be typed |^^?|, and
+the dangerous bend sign can be obtained by saying
+|{\manual^^?}|. However, you must change the category code of character
+127 before using it, since this character ordinarily has category~15
+(^{invalid}); say, e.g., |\catcode`\^^?=12|.
+^^{double hat} ^^{hat hat}
+The |^^| notation is different from |\char|, because |^^| combinations are
+like single characters; for example, it would not be permissible to say
+|\catcode`\char127|, but |^^| symbols can even be used as letters within
+control words.
+
+\bugonpage A45, new copy before line 20 (9/23/89)
+
+\danger There's also a special convention in which |^^| is
+followed by {\sl two\/} ``lowercase hexadecimal digits,'' |0|--|9| or |a|--|f|.
+With this convention, all 256 characters are obtainable in a uniform
+way, from |^^00| to |^^ff|. Character 127 is |^^7f|.
+
+\noindent
+[Also remove one of the two dangerous bend signs on line 20.]
+
+\bugonpage A45, bottom paragraph and footnote (9/23/89)
+
+\ddanger People who install \TeX\ systems for use with non-American alphabets
+can make \TeX\ conform to any desired standard. For example, suppose
+you have a ^{Norwegian keyboard} containing the letter {\tt\ae}, which
+^^{Scandinavian letters} ^^{foreign languages}
+comes in as code~241 (say). Your local format package should define
+|\catcode`|{\tt\ae}|=11|; then you could have control sequences like
+|\s|{\tt\ae}|rtrykk|. Your \TeX\ input files could be made readable by
+American installations of \TeX\ that don't have your keyboard, by
+substituting |^^f1| for character~241. \ (For example, the stated control
+sequence would appear as |\s^^f1rtrykk| in the file; your American
+friends should also be provided with the format that you used, with its
+|\catcode`^^f1=11|.) \ Of course you should also arrange your fonts
+so that \TeX's character 241 will print as {\ae}; and you should
+change \TeX's hyphenation algorithm so that it will do correct
+Norwegian hyphenation. The main point is that such changes are not
+extremely difficult; nothing in the design of \TeX\ limits it to the
+American alphabet. Fine printing is obtained by fine tuning to the
+language or languages being used.
+^^{keyboards, non-ASCII}
+
+\ddanger European languages can also be accommodated effectively with
+only a limited character set.
+For example, let's consider Norwegian again, but suppose that\parfillskip=0pt
+
+\noindent [Now continue with the text on line 11 of page 46.]
+
+\bugonpage A47, lines 9--21 (9/23/89)
+
+\ddanger If \TeX\ sees a superscript character (category 7) in any state,
+and if that character is followed by another identical character, and if
+those two equal characters are followed by a character of code
+$c<128$, then they
+are deleted and 64 is added~to or subtracted from the code~$c$.
+\ (Thus, |^^A| is
+replaced by a single character whose code is~1, etc., as explained earlier.) \
+However, if the two superscript characters are immediately followed by two
+of the lowercase hexadecimal digits |0123456789abcdef|, the
+four-character sequence is replaced by a single character having the
+specified hexadecimal code.
+The replacement is carried out also if such a trio or quartet of
+characters is encountered during steps (b) or~(c) of the control-sequence-name
+scanning procedure described above. After the replacement is made, \TeX\
+begins again as if the new character had been present all the time.
+If a superscript character is not the first of such a trio or quartet, it is
+handled by the following rule.
+
+\ddanger If \TeX\ sees a character of categories 1, 2, 3, 4, 6, 8, 11, 12,
+or~13,
+or a character of category~7 that is not the first of a special
+sequence as just
+described, it converts the character to a token by attaching the category
+code, and goes into state~$M$. This is the normal case; almost every
+nonblank character is handled by this rule.
+
+\bugonpage A48, line 15 (9/23/89)
+
+\ninepoint\noindent
+the input line
+`| $x^2$~ \TeX ^^62^^6|'\thinspace?
+
+\bugonpage A54, third line from the bottom (9/23/89)
+
+\ninepoint\noindent
+For example, a well-designed \TeX\ font for ^{French}
+might well treat accents as lig-\cutpar
+
+\bugonpage A76, lines 3--5 from the bottom (9/23/89)
+
+\ninepoint\noindent
+\TeX\ does not assign any value to
+|\sfcode'042|.
+
+\bugonpage A107, new copy for top of page (9/23/89)
+
+\ddanger If you want to avoid overfull boxes at all costs without
+trying to fix them manually, you might be tempted to set
+|tolerance=10000|; this allows arbitrarily bad lines to be acceptable
+in tough situations. But infinite tolerance is a bad idea, because
+\TeX\ doesn't distinguish between terribly bad and preposterously
+horrible lines. Indeed, a tolerance of 10000 encourages \TeX\ to
+concentrate all the badness in one place, making one truly unsightly
+line instead of two moderately bad ones, because a single
+``write-off'' produces fewest total demerits according to the rules.
+There's a much better way to get the desired effect: \TeX\ has a
+parameter called ^|\emergencystretch| that is added to the assumed
+stretchability of every line when badness and demerits are computed,
+in cases where overfull boxes are otherwise unavoidable. If
+|\emergencystretch| is positive, \TeX\ will make a third pass over a
+paragraph before choosing the line breaks, when the first passes did
+not find a way to satisfy the ^|\pretolerance| and ^|\tolerance|.
+The effect of\/ |\emergencystretch| is to scale down the badnesses so
+that large infinities are distinguishable from smaller ones. By
+setting |\emergencystretch| high enough (based on |\hsize|) you can be
+sure that the |\tolerance| is never exceeded; hence overfull boxes
+will never occur unless the line-breaking task is truly impossible.
+
+\bugonpage A116, lines 11--15 (6/7/89)
+
+\danger If you have two or more |\topinsert| or |\pageinsert| commands in
+quick succession, \TeX\ may need to carry them over to several subsequent
+pages; but they will retain their relative order when they are
+carried over. For example, suppose you have pages that are nine inches
+tall, and suppose you have already specified 4~inches of text for some
+page, say page~25. Then suppose you make seven topinserts in a row, of%
+{\parfillskip=0pt\endgraf}\endgroup
+
+\bugonpage A125, lines 13--29 (9/23/89)
+
+\ddanger \looseness=-1
+When the best page break is finally chosen, \TeX\ removes everything after
+the chosen breakpoint from the bottom of the ``current page,'' and puts it
+all back at the top of the ``recent contributions.'' The
+chosen breakpoint itself is placed at the very top of the recent contributions.
+If it is a penalty item, the value of the penalty is recorded in
+^|\outputpenalty| and the penalty in the contribution list is changed
+to $10000$; otherwise |\outputpenalty| is set to 10000.
+The insertions that remain on the current page are of three kinds: For
+each class~$n$ there are unsplit insertions, followed possibly by
+a single split insertion, followed possibly by others. If
+^|\holdinginserts|$\null>0$, all insertions remain in place (so that
+they might be contributed again); otherwise they are all removed from
+the current page list as follows: The unsplit insertions
+are appended to |\box|$\,n$, with no interline glue between them. \
+(^{Struts} should be used, as in the |\vfootnote| macro of
+Appendix~B\null.) \
+If a split insertion is present, it is effectively |\vsplit| to the size
+that was computed previously in Step~4; the top part is treated as an
+unsplit insertion, and the remainder (if any) is converted to an insertion
+as if it had not been split. This remainder, followed by any other floating
+insertions of the same class, is held
+over in a separate place. \ (They will show up on the ``current page'' if
+^|\showlists| is used while an ^|\output| routine is active; the total
+number of such insertions appears in ^|\insertpenalties| during an
+|\output| routine.) %\
+Finally, the remaining items before the best break on the current page are put
+together in a |\vbox|\parfillskip=0pt
+
+\bugonpage A131, line 12 (9/22/89)
+
+\ninepoint\noindent
+work fine; but sometimes you want to have uniformity
+between different members of a\cutpar
+
+\bugonpage A155, lines 3--5 (9/23/89)
+
+\ninepoint\noindent
+when it encounters a character that
+is given explicitly as ^|\char|\<number>.
+
+\bugonpage A214, lines 19--24 (9/23/89)
+
+\ninepoint
+\textindent\bull |\the|\<special register>, where \<special register> is
+one of the integer quantities ^|\prevgraf|, ^|\deadcycles|, ^|\insertpenalties|,
+^|\inputlineno|, ^|\badness|,
+or ^|\parshape| (denoting only the number of lines of\/ |\parshape|); or
+one of the dimensions ^|\pagetotal|, ^|\pagegoal|, ^|\pagestretch|,
+^|\pagefilstretch|, ^|\pagefillstretch|, ^|\pagefilllstretch|, ^|\pageshrink|,
+^|\pagedepth|. In horizontal modes you can also refer to a special integer,
+|\the\spacefactor|; in vertical modes there's a special dimension,
+|\the\prevdepth|.
+
+\bugonpage A229, new copy after line 11 (9/23/89)
+
+\ddanger \TeX\ will report the badness of glue setting in a box if
+you ask for the numeric quantity
+^|\badness| after making a box. For example, you might say
+\begintt
+\setbox0=\line{\trialtexta}
+\ifnum\badness>250 \setbox0=\line{\trialtextb}\fi
+\endtt
+The badness is between 0 and 10000
+unless the box is overfull, when |\badness=1000000|.
+
+\bugonpage A271, lines 17--20 (9/23/89)
+
+\ninepoint
+\beginsyntax
+ \alt<countdef token>\alt^|\count|<8-bit number>\alt<codename><8-bit number>
+ \alt<chardef token>\alt<mathchardef token>\alt^|\parshape|\alt^|\inputlineno|
+ \alt^|\hyphenchar|<font>\alt^|\skewchar|<font>\alt^|\badness|
+\endsyntax
+
+\bugonpage A272, lines 3--4 (9/23/89)
+
+\ninepoint\noindent
+value is between 0~and $2^8-1=255$; a ^\<4-bit number> is similar.
+
+\bugonpage A273, insert after lines 11, 20, 21, 21, 38 (9/23/89)
+
+\ninepoint
+\begindisplay
+|\holdinginserts|\quad(positive if insertions remain dormant in output box)\cr
+|\language|\quad(the current set of hyphenation rules)\cr
+|\lefthyphenmin|\quad(smallest fragment at beginning of hyphenated word)\cr
+|\righthyphenmin|\quad(smallest fragment at end of hyphenated word)\cr
+|\errorcontextlines|\quad(maximum extra context shown when errors occur)\cr
+\enddisplay
+
+\bugonpage A274, insert after line 4 (9/23/89)
+
+\ninepoint\indent
+|\emergencystretch|\quad(reduces badnesses on final pass of line-breaking)
+
+\bugonpage A275, line 13 (9/23/89)
+
+\ninepoint\noindent
+That makes a total of 103 parameters of all five kinds.
+
+\bugonpage A283, line 14 (9/23/89)
+
+\ninepoint
+\beginsyntax
+ \alt^|\noboundary|\alt^|\unhbox|\alt^|\unhcopy|\alt^|\valign|\alt^|\vrule|
+\endsyntax
+
+\bugonpage A286, lines 3--12 from the bottom (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+\<letter>, \<otherchar>, \kern-1pt^|\char|\<8-bit number>, \<chardef token>,
+\kern-1pt^|\noboundary|.\enskip
+The most common commands of all are the character commands that tell
+\TeX\ to append a character to the current horizontal
+list, using the current font.
+If two or more commands of this type occur in succession, \TeX\ processes
+them all as a unit, converting to ligatures and/or
+inserting kerns as directed by the font information. \ (Ligatures and
+kerns may be influenced by invisible ``boundary'' characters at the left
+and right, unless |\noboundary| appears.) \ Each character
+command adjusts ^|\spacefactor|, using
+the ^|\sfcode| table as described in Chapter~12.
+In unrestricted horizontal mode, a
+`|\discretionary{}{}{}|' item is appended after a character whose code is
+the ^|\hyphenchar| of its font, or after a ligature formed from a sequence
+that ends with such a character.
+
+\bugonpage A287, insert after line 19 (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+|\setlanguage|\<number>.\enskip See the conclusion of Appendix H.
+
+\bugonpage A289, lines 9--14 from the bottom (9/23/89)
+
+\ninepoint\noindent
+$2^{15}-1$. This is done by replacing the character number by its
+^|\mathcode| value. If the
+|\mathcode| value turns out to be $32768=\null$\hex{8000}, however,
+ the \<character>
+is replaced by an ^{active character} token having the original character
+code (0 to~255); \TeX\ forgets the original \<character> and expands this
+active character according to the rules of Chapter~20.
+
+\bugonpage A290, insert before 13th line from bottom (9/23/89)
+
+\ninepoint
+\textindent{$\bull$}%
+|\noboundary|. This command is redundant and therefore has no
+effect; boundary ligatures are automatically disabled in math modes.
+
+\bugonpage A296, line 16 from the bottom (9/22/89)
+
+\noindent[There should be a `|^|' just above the `|3|' in the line below.
+This was mistakenly dropped by the printer some time during 1985; it was
+correct in the first two printings and it has always been correct inside the
+computer!]
+
+\bugonpage A309, lines 3--5 (9/23/89)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss8.4.\enspace}\ignorespaces
+|$|$_{3}$ |x|$_{11}$ |^|$_7$ |2|$_{12}$ |$|$_{3}$ |~|$_{13}$ \]$_{10}$
+\cstok{TeX} |b|$_{12}$ |v|$_{12}$ \]$_{10}$. The final space comes from the
+\<return> placed at the end of the line. Code |^^6| yields |v| only
+when not followed by |0|--|9| or |a|--|f|.
+The initial space is ignored, because state~$N$
+governs the beginning of the line.
+
+\bugonpage A314, line 27 (9/23/89)
+
+\ninepoint\noindent
+The English word `eighteen' might deserve similar treatment.
+\TeX's hyphenation algorithm will not make such spelling changes automatically.
+
+\bugonpage A318, line 19 (3/3/89)
+
+\ninepoint
+|\def\clearnotenumber{\notenumber=0\relax}|
+
+\bugonpage A330, line 3 (8/25/89)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss20.10.\enspace}\ignorespaces
+|\def\overpaid{{\count0=\balance|
+
+\bugonpage A336, lines 4--8 from the bottom (9/23/89)
+
+\ninepoint\noindent
+badness rating of a
+box is at most 10000, except that the |\badness| of
+an overfull box is 1000000. |INITEX| initializes |\tolerance| to
+10000, thereby making all line breaks feasible. Penalties of 10000 or more
+prohibit breaks; penalties of $-10000$ or less make breaks mandatory. The
+cost of a page break is 100000, if the badness is 10000 and if the
+associated penalties are less than 10000 in magnitude (see Chapter~15).
+
+\bugonpage A337, lines 2--16 (9/23/89)
+
+\ninepoint\noindent
+ifies characters whose codes differ by~64
+from the codes of |?|, |@|, |A|; this convention applies only to
+characters with ASCII codes less than~128. There are 256 possible characters,
+hence 256 entries in each of the |\catcode|, |\mathcode|,
+|\lccode|, |\uccode|, |\sfcode|, and |\delcode| tables. All
+|\lccode|, |\uccode|, and |\char| values
+must be less than~256. A font has at most 256 characters. There are
+256~|\box| registers, 256~|\count| registers, 256~|\dimen| registers,
+256~|\skip| registers, 256~|\muskip| registers, 256~|\toks| registers,
+256~hyphenation tables.
+The ``at size'' of a font must be less than~$2048\pt$, i.e.,~$2^{11}\pt$.
+Math delimiters are encoded by multiplying the math~code of the ``small
+character'' by~$2^{12}$. The magnitude of
+a~\<dimen> value must be less than~$16384\pt$, i.e.,~$2^{14}\pt$;
+similarly, the \<factor> in a~\<fil dimen> must be less than~$2^{14}$.
+A~|\mathchar| or |\spacefactor| or |\sfcode| value must be less than~$2^{15}$;
+a~|\mathcode| or |\mag| value must be less than or equal to~$2^{15}$,
+and $2^{15}$ denotes an ``active'' math character. There
+are $2^{16}\rm\,sp$ per~pt. A~|\delcode| value
+must be less than~$2^{24}$; a~|\delimiter|, less than $2^{27}$.
+The |\end| command sometimes contributes
+a penalty of $-2^{30}$ to the current page. A~\<dimen> must be less than
+$2^{30}\rm\,sp$ in absolute value; a~\<number> must be
+less than $2^{31}$ in absolute value.
+
+\bugonpage A348, line 12 from the bottom (9/23/89)
+
+\ninepoint\noindent
+^|\showboxbreadth||=5 |^|\showboxdepth||=3 |^|\errorcontextlines||=5|
+
+\bugonpage A364, insert before line 18 from the bottom (9/23/89)
+
+\ninepoint\noindent
+^|\lefthyphenmin||=2 |^|\righthyphenmin||=3 % disallow x- or -xx breaks|
+
+\bugonpage A364, line 5 from the bottom (9/23/89)
+
+\ninepoint\noindent
+|\def|^|\fmtname||{plain}\def\fmtversion{3.0} % identifies the current format|
+
+\bugonpage A369, insert before line 5 from the bottom (9/23/89)
+
+\ninepoint
+Modern keyboards allow 256 codes to be input, not just 128; so \TeX\
+represents characters internally as numbers in the range 0--255 (i.e.,
+\oct{000}--\oct{377}, or \hex{00}--\hex{FF}). Implementations of \TeX\
+differ in which characters they will accept in input files and which
+they will transmit to output files; these subsets can be specified
+independently. A completely permissive version of \TeX\ allows full
+256-character input and output; other versions might ignore all
+but the visible characters of ASCII; still other versions might
+distinguish the tab character (code \oct{011}) from a space on input,
+but might output each tab as a sequence of three characters |^^I|.
+
+\bugonpage A370, lines 3--7 (9/23/89)
+
+\ninepoint\noindent
+close as possible to the ASCII conventions.
+\ (b)~Make sure that codes \oct{041}--\oct{046}, \oct{060}--\oct{071},
+\oct{141}--\oct{146}, and \oct{160}--\oct{171} are present and that
+each unrepresentable
+internal code $<\null$\oct{200} leads to a representable code when \oct{100} is
+added or subtracted; then all 256 codes can be input and output.
+\ (c)~Cooperate with everyone else who shares
+the same constraints, so that you all adopt the same policy.
+\ (See Appendix~J for information about the \TeX\ Users Group.)
+
+\bugonpage A370, bottom line (9/23/89)
+
+\ninepoint\noindent
+doesn't matter if these symbols have their plain
+\TeX\ meanings or not. \ (6)~There is a special convention for
+representing characters 0--255 in the hexadecimal forms
+|^^00|--|^^ff|, explained in Chapter~8. This convention is always
+acceptable as input, when |^| is any character of catcode~7. Text
+output is produced with this convention only when representing
+characters of code $\ge128$ that a \TeX\ installer has chosen not to
+output directly.
+
+\bugonpage A385, line 8 (5/14/89)
+
+\ninepoint
+|\def\beginbox{\setbox0=\hbox\bgroup}|
+
+\bugonpage A400, line 18 from the bottom (9/23/89)
+
+\ninepoint\noindent
+page prematurely if you want to pass a signal. \ (Set
+^|\holdinginserts| positive to pass a signal when the contents of\/
+|\box255| will be sent back through the page builder again, if any
+insertions are present.)
+
+\bugonpage A419, lines 4--6 (9/23/89)
+
+\ninepoint\noindent
+shortened or lengthened anyway;
+book preparation with \TeX, as with type, encourages interaction between
+humans and machines.) \
+The lines of the quotations are set ^{flush right} by using
+^|\obeylines| together with a stretchable ^|\leftskip|:
+
+\bugonpage A444, lines 21--26 (9/23/89)
+
+\ninepoint\noindent
+following one, using the specified family and the current size, then
+insert the ligature character and continue as specified by the font;
+two characters may collapse into one, or a new character may appear.
+Otherwise if the font information
+shows a kern between the current symbol and the next, insert a kern item
+after the current Ord atom and move to the next item after that.
+Otherwise (i.e., if no ligature or kern is specified between the present
+text symbol and the following character), go to Rule~17.
+
+\bugonpage A453, lines 12--14 from the bottom (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ninepoint\noindent
+Exception: The character
+`|.|'~is treated as if it were a \<letter> of code~0
+when it appears in a pattern. Code~0 (which obviously cannot match a nonzero
+|\lccode|) is used by \TeX\ to represent the
+left or right edge of a word when it is being hyphenated.
+
+\endgroup
+
+\bugonpage A454, lines 7--15 from the bottom (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger If a trial word $l_1\ldots l_n$ has been found by this process,
+hyphenation will still be abandoned unless $n\ge\lambda+\rho$, where
+$\lambda=\max(1,\hbox{|\lefthyphenmin|})$ and
+$\rho=\max(1,\hbox{|\righthyphenmin|})$.
+\ (Plain \TeX\ takes $\lambda=2$ and $\rho=3$.) \ Furthermore, the items
+immediately following the trial word must consist of zero or more
+characters, ligatures, and implicit kerns, followed immediately by
+either glue or an explicit kern or a penalty item or a whatsit or an
+item of vertical mode material from ^|\mark|, ^|\insert|, or ^|\vadjust|.
+Thus, a box or rule or math formula or discretionary following too closely
+upon the trial word will inhibit hyphenation. (Since \TeX\ inserts
+empty discretionaries after ^{explicit hyphens}, these rules imply that
+already-hyphenated compound words will not be further hyphenated by
+the algorithm.)
+
+\endgroup
+
+\bugonpage A455, new copy after line 13 (9/23/89)
+
+\begingroup
+\hyphenpenalty=-1000 \pretolerance=-1 \tolerance=1000
+\doublehyphendemerits=-100000 \finalhyphendemerits=-100000
+\ddanger \looseness=-1
+So far we have assumed that \TeX\ knows only one style of
+hyphenation at a time; but in fact \TeX\ can remember up to 256
+distinct sets of rules, if you have enough memory in your computer. An
+integer parameter called ^|\language| selects the rules actually used;
+every ^|\hyphenation| and ^|\patterns| specification appends new rules
+to those previously given for the current value of\/ |\language|.
+\ (If\/ |\language| is negative or greater than 255, \TeX\ acts as if
+|\language|$\null=0$.) \ All |\patterns| for all languages must be
+given before a paragraph is typeset, if |INITEX| is used for
+typesetting.
+
+\ddanger \TeX\ is able to work with several languages in the same
+paragraph, because it operates as follows. At the beginning of a
+paragraph the ``current language'' is defined to be~0. Whenever a
+character is added to the current paragraph (i.e., in unrestricted
+horizontal mode), the current language is compared to |\language|; if
+they differ, the current language is reset and a whatsit node
+specifying the new current language is inserted before the character.
+Thus, if you say `|\def\french{\language1...}|' and `|mix| |{\french
+franc/ais}| |with| |English|', \TeX\ will put whatsits before the |f|
+and the~|w|; hence it will use language~1 rules when hyphenating
+|franc/ais|, after which it will revert to language~0. You can insert
+the whatsit yourself (even in restricted horizontal mode) by saying
+^|\setlanguage|\<number>; this changes the current language but it
+does not change |\language|.
+
+\endgroup
+
+\bugonpage A459, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\badness|, 214, {\it229}, 271.
+
+\bugonpage A461, right column (9/23/89)
+
+\eightpoint
+caron, {\sl see\/} h\'a\v cek.
+
+\bugonpage A464, line 10 (5/15/89)
+
+\eightpoint
+displays, 87, 103, {\it139--145}, {\it166--167},
+
+\bugonpage A464, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\emergencystretch|, $\underline{107}$, 274.
+
+\bugonpage A465, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\errorcontextlines|, $\underline{34}$, 273, {\it348}.
+
+\bugonpage A466, entry for `fractions' (9/23/89)
+
+\eightpoint[Add page 332 to this entry.]
+
+\bugonpage A466, entry for `French'' (9/23/89)
+
+\eightpoint[Add page 455 to this entry.]
+
+\bugonpage A467, entry for `hexadecimal' (9/23/89)
+
+\eightpoint[Add pages 45, 47--48 to this entry.]
+
+\bugonpage A467, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\holdinginserts|, $\underline{125}$, 273, 400.
+
+\bugonpage A467, bottom line (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\hyphenation|, 277, {\it419}, $\underline{452}$--$\underline{453}$, 455.
+
+\bugonpage A468, right column (9/23/89)
+
+\eightpoint
+infinite badness, 97, 107, 111, 229, 317.
+
+\bugonpage A468, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\inputlineno|, 214, 271.
+
+\bugonpage A469, entry for kerns (9/23/89)
+
+\eightpoint[Add pages 286 and 444 to this entry.]
+
+\bugonpage A469, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\language| (hyphenation method), 273, $\underline{455}$.
+
+\bugonpage A469, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\lefthyphenmin|, 273, {\it364}, $\underline{454}$.
+
+\bugonpage A470, entry for ligatures (9/23/89)
+
+\eightpoint[Add pages 286 and 444 to this entry.]
+
+\bugonpage A472, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\noboundary|, 283, $\underline{286}$, 290.
+
+\bugonpage A473, right column (9/23/89)
+
+\eightpoint
+overfull boxes, 27--30, 94, 229, 238,\par
+\indent\qquad 302--303, 307, 400.\par
+\indent\quad avoiding, 107.
+
+\bugonpage A474, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\patterns|, 277, $\underline{453}$, 455.
+
+\bugonpage A476, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\righthyphenmin|, 273, {\it364}, $\underline{454}$.
+
+\bugonpage A476, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\setlanguage|, 287, $\underline{455}$.
+
+\bugonpage A476, right column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\showboxbreadth|, 273, $\underline{302}$, 303, {\it348}.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\showboxdepth|, 79, 273, $\underline{302}$, 303, {\it348}.
+
+\bugonpage A479, left column (9/23/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\tolerance|, {\it29--30}, 91, 94, $\underline{96}$, 107, 272,\par
+\indent\qquad{\it317}, {\it333}, {\it342}, {\it348}, {\it364}, {\it451}.
+
+\bugonpage A481, right column, last six entries (9/23/89)
+
+\def\frac#1/#2{\leavevmode\kern.1em
+ \raise.5ex\hbox{\the\scriptfont0 #1}\kern-.1em
+ /\kern-.15em\lower.25ex\hbox{\the\scriptfont0 #2}}%
+\eightpoint
+\frac1/2, 67, 332.\par
+1/2, in unslashed form, 141, 186.\par
+\<4-bit number>, $\underline{271}$.\par
+\<8-bit number>, $\underline{271}$, 276--278.\par
+\<15-bit number>, $\underline{271}$, 277, 289, 291.\par
+\<27-bit number>, $\underline{271}$, 289, 291.\par
+
+\bugonpage A483, lines 15 and 21 (9/23/89)
+
+\noindent[Delete these two lines, as TUG's address is no longer c/o AMS.]
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Bvii, top two lines (4/21/89)
+
+{\hsize=29pc
+\tenpoint\noindent
+{\it {\sltt WEB} documentation for four utility programs that are
+often used in conjunction with \TeX: {\sltt POOLtype}, {\sltt TFtoPL},
+{\sltt PLtoTF}, and {\sltt DVItype}.}
+\par}
+
+\bugonpage B2, line 32 (6/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]2.991\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B118, lines 2--4 (3/2/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin if\/} $\\{cur\_level}>\\{level\_one}$ {\bf then}\par
+\noindent\hskip20pt{\bf begin} \\{check\_full\_save\_stack}; \
+ $\\{save\_type}(\\{save\_ptr})\gets\\{insert\_token}$;\par
+\noindent\hskip20pt$\\{save\_level}(\\{save\_ptr})\gets\\{level\_zero}$; \
+ $\\{save\_index}(\\{save\_ptr})\gets t$; \ \\{incr}(\\{save\_ptr});\par
+\noindent\hskip20pt{\bf end};
+
+\bugonpage B182, line 13 becomes two lines (6/20/89)
+
+\ninepoint\noindent
+$k,\\{kk}$: \\{small\_number};\quad
+ $\{\,$number of digits in a decimal fraction$\,\}$\par\noindent
+$p,q$: \\{pointer};\quad
+ $\{\,$top of decimal digit stack$\,\}$
+
+\bugonpage B182, line 15 from the bottom (6/20/89)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} $k\gets0$; $p\gets\\{null}$; \\{get\_token};\quad
+ $\{\,$\\{point\_token} is being re-scanned$\,\}$
+
+\bugonpage B182, line 11 from the bottom (6/20/89)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} $q\gets\\{get\_avail}$; $\\{link}(q)\gets p$;
+ $\\{info}(q)\gets\\{cur\_tok}-\\{zero\_token}$;
+ $p\gets q$; $\\{incr}(k)$;
+
+\bugonpage B182, line 8 from the bottom (6/20/89)
+
+\ninepoint\noindent
+\\{done1}: {\bf for} $\\{kk}\gets k$ {\bf downto} 1 {\bf do}\par
+\noindent\hskip20pt
+{\bf begin} $\\{dig}[kk-1]\gets\\{info}(p)$; $q\gets p$; $p\gets\\{link}(p)$;
+ $\\{free\_avail}(q)$;\par
+\noindent\hskip20pt{\bf end};\par
+\noindent\hskip10pt$f\gets\\{round\_decimals}(k)$;
+
+\bugonpage B332, lines 11 and 12 from the bottom (4/8/89)
+
+\ninepoint
+\noindent\hskip10pt
+{\bf begin if\/} $\\{cur\_align}=\\{null}$ {\bf then}
+ \\{confusion}({\tt\char'23endv\char'23});\par\noindent\hskip10pt
+$q\gets\\{link}(\\{cur\_align})$; \ {\bf if\/} $q=\\{null}$ {\bf then}
+ \\{confusion}({\tt\char'23endv\char'23});
+
+\bugonpage B466, line 5 becomes three lines (6/7/89)
+
+\ninepoint
+\noindent
+$\\{mmode}+\\{halign}$: {\bf if\/} \\{privileged} {\bf then}\par\noindent
+\hskip20pt{\bf if\/} $\\{cur\_group}=\\{math\_shift\_group}$
+ {\bf then} \\{init\_align}\par\noindent\hskip20pt
+{\bf else} \\{off\_save};
+
+\bugonpage B518, line 25 (8/31/89)
+
+\ninepoint\noindent\hskip10pt
+$\\{undump}(\\{lo\_mem\_stat\_max}+1)(\\{lo\_mem\_max})(\\{rover})$; \
+$p\gets\\{mem\_bot}$; \ $q\gets\\{rover}$;
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\buginvol C, in general (9/23/89)
+
+\ninepoint\noindent
+[Change `127' to `255' and `128' to `256' in contexts referring to character
+codes. This happens on pages 188(thrice) and 251.]
+
+\bugonpage C91, lines 12 and 13 (8/31/89)
+
+\begintt
+\mode=cheapo; input newface
+\endtt
+and the same file should also produce a high-resolution font if we start with
+
+\bugonpage C204, line 4 (8/18/89)
+
+\ninepoint\noindent
+so that
+\\{currenttransform} multiplies all $y$~coordinates by
+\\{aspect\_ratio}, when paths are\cutpar
+
+\bugonpage C212, lines 24--27 (9/30/89)
+
+\ninepoint
+\begindisplay
+{\it boundarychar}\quad&the right boundary character for ligatures and kerns\cr
+\enddisplay
+All of these quantities are numeric. They are initially zero at the
+start of a job, except for {\it year\/}, {\it month\/},
+ {\it day\/}, and {\it time\/}, which
+are initialized to the time the run began; furthermore, {\it boundarychar\/} is
+initially~$-1$. A {\it granularity\/} of zero is equivalent to
+ $\hbox{\it granularity\/}=1$.
+A preloaded base file like plain \MF\ will usually give nonzero values to
+several other internal quantities on this list.
+
+\bugonpage C259, lines 16 and 17 from the bottom (5/14/89)
+
+\tenpoint
+\noindent
+|screenchars|; \ |screenstrokes|; \ |imagerules|; \ |gfcorners|; \
+|nodisplays|;\hfil\break
+|notransforms|; \ |input| \<filename>.
+
+\bugonpage C282, the three lines following the chart (9/30/89)
+
+\tenpoint\noindent
+\MF\ can also be configured to accept any or all of the character codes
+128--255.
+However, \MF\ programs that make use of anything in addition to the 95
+standard ASCII characters cannot be expected to run on other systems, so
+the use of extended character sets is discouraged.
+
+\bugonpage C316, bottom 14 lines and top 30 of page C317 (9/30/89)
+
+\ninepoint
+Ligature information and kerning information is specified in short
+``^{ligtable programs}'' of a particularly simple form. Here's an example
+that illustrates most of the features (although it is not a serious
+example of typographic practice):
+\beginlines
+^|ligtable|| "f": "f" =: oct"013", "i" |\||=: oct"020", skipto 1;|
+|ligtable "o": "b": "p": "e" kern .5u#, "o" kern .5u#, "x" kern-.5u#,|
+| 1:: "!" kern u#;|
+\endlines
+This sequence of instructions can be paraphrased as follows:
+\smallskip
+\hangindent 3pc
+Dear \TeX, when you're typesetting an~`f' with this font, and when the
+following character also belongs to this font, look at it closely because
+you might need to do something special: If that following character is
+another~`f', replace the two f's by character code |oct"013"|
+[namely `\char'13'\kern.5pt];
+if it's an `i', retain the `f' but replace the `i' by character code
+|oct"020"| [a dotless `\char'20'\kern.5pt];
+otherwise skip down to label `|1::|' for further instructions.
+When you're typesetting an `o' or~`b' or~`p', if the next input to \TeX\ is
+`e' or~`o', add a half unit
+of space between the letters; if it's an `x', subtract a half unit; if it's an
+exclamation point, add a full unit. The last instruction applies also
+to exclamation points following~`f' (because of the label `|1::|').
+\smallskip\noindent
+When a character code appears in front of a colon, the colon ``labels''
+the starting place for that character's ligature and kerning program,
+which continues to the end of the ligtable statement. A double colon denotes
+a ``local label''; a |skipto| instruction advances to the next matching local
+label, which must appear before 128 ligtable steps intervene. The special
+label \|\||:| can be used to initiate ligtable instructions for an invisible
+``left boundary character'' that is implicitly present just before every
+word; an invisible ``right boundary character'' equal to {\it boundarychar\/} is
+also implicitly present just after every word, if {\it boundarychar\/}
+ lies between
+0 and~255.
+
+The general syntax for ligtable programs is pretty easy to guess from
+these examples, but we ought to exhibit it for completeness:
+\beginsyntax \chardef\\=`\|
+<ligtable command>\is[ligtable]<ligtable program><optional skip>
+<ligtable program>\is<ligtable step>\alt<ligtable program>[,]<ligtable step>
+<optional skip>\is[,] [skipto]<code>\alt<empty>
+<ligtable step>\is<code><ligature op><code>
+ \alt<code>[kern]<numeric expression>
+ \alt<label><ligtable step>
+<ligature op>\is[=:]\alt[\\=:]\alt[\\=:>]\alt[=:\\]\alt[=:\\>]%
+ \alt[\\=:\\]\alt[\\=:\\>]\alt[\\=:\\>>]
+<label>\is<code>[:]\alt<code>[::]\alt[\\\\:]
+<code>\is<numeric expression>\alt<string expression>
+\endsyntax
+A \<code> should have a numeric value between 0 and 255, inclusive,
+after having been rounded to the nearest integer; or it should be a
+string of length~1, in which case it denotes the corresponding
+^{ASCII} code (Appendix~C\null). For example, |"A"| and |64.61| both
+specify the code value 65. Vertical bars to the left or right of `|=:|'
+tell \TeX\ to retain the original left and/or right character that invoked a
+ligature. Additional `|>|' signs tell \TeX\ to advance its focus of attention
+instead of doing any further ligtable operations at the current
+character position.
+
+\bugonpage C338, lines 21 and 22 (9/30/89)
+
+\ninepoint\noindent
+and 127--255 have to be specified with the `|#|' option,
+on non-fancy installations of \TeX,
+and so does code 35 (which is the ASCII code of `|#|' itself).
+
+\bugonpage C346, left column, after line 14 (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|, {\it316}, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|=:|\|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|=:|\||>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\||>|, $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\||=:|\||>>|, $\underline{317}$.\par
+
+\bugonpage C346, left column, after line 31 (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|::| (local label), $\underline{317}$.\par
+\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+\|\||:| (left boundary label), $\underline{317}$.\par
+
+\bugonpage C347, left column (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|boundarychar|, 212, 317.
+
+\bugonpage C352, left column (9/30/89)
+
+\eightpoint[Change `\<ligature replacement>' to `\<ligature op>'.]
+
+\bugonpage C354, left column (9/30/89)
+
+\eightpoint
+\<optional skip>, 217.
+
+\bugonpage C356, left column (9/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|skipto|, {\it316}, $\underline{317}$.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage Dvi, bottom two lines, and top lines of page vii (4/21/89)
+
+{\hsize=29pc \tenpoint
+\textindent\bull ``\MF\/ware'' by Donald~E. Knuth, Tomas~G. Rokicki, and
+Ar\-thur~L. Samuel, Stanford Computer Science Report 1255 (Stanford,
+California, April 1989), 207~pp. \ {\it The {\sltt WEB} programs for
+four utility programs that are often used in conjunction with
+\slMF\kern1pt: {\sltt GFtype}, {\sltt GFtoPK}, {\sltt GFtoDVI},
+and {\sltt MFT}.}
+\par}
+
+\bugonpage D63, line 9 (8/31/89)
+
+\tenpoint\noindent
+\\{mem}, so we
+allow pointers to assume any \\{halfword} value. The minimum memory
+index represents\cutpar
+
+\bugonpage D63, line 28 (8/31/89)
+
+\tenpoint\centerline{$\\{null}=\\{mem\_min}<\\{lo\_mem\_max}<
+\\{hi\_mem\_min}<\\{mem\_top}\le\\{mem\_end}\le\\{mem\_max}$.}
+
+\bugonpage D67, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete line 7, which has a redundant `{\bf if\/} $r=p$ {\bf then}';
+ move line 8 to the left 10 points for alignment; and restore the following
+ line (which was deleted by mistake after line 8):
+
+ \noindent\hskip10pt
+ $\\{node\_size}(p)\gets q-p$\quad$\{\,$reset the size in case it grew$\,\}$
+
+ \noindent
+ These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D228, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete lines 14--15, which were inserted erroneously from a previous errata
+list; and restore the following lines (which were deleted by mistake):
+
+\noindent\hskip20pt
+{\bf begin} \\{double}(\\{max\_coef}); \
+\\{double}(\\{x0}); \
+\\{double}(\\{x1}); \
+\\{double}(\\{x2});\par\noindent\hskip20pt
+\\{double}(\\{y0}); \
+\\{double}(\\{y1}); \
+\\{double}(\\{y2});\par\noindent\hskip20pt
+{\bf end}
+
+\noindent
+These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D248, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Delete line 16, which begins with `$d\gets\\{take\_fraction}$';
+and restore the following line (which was deleted by mistake after line 22):
+
+\noindent\hskip10pt
+{\bf if\/} $d<\\{alpha}$ {\bf then} $d\gets\\{alpha}$
+
+\noindent
+These corrections are needed only in the reprinting made July, 1987.]
+
+\bugonpage D389, line 10 (6/20/89)
+
+\ninepoint\noindent\hskip20pt
+\\{help1}({\tt\char'23
+The\]expression\]above\]should\]have\]been\]a\]number\]>=3/4.\char'23});
+
+\bugonpage D504, line 25 (8/31/89)
+
+\ninepoint\noindent\hskip10pt
+$\\{undump}(\\{lo\_mem\_stat\_max}+1)(\\{lo\_mem\_max})(\\{rover})$; \
+$p\gets\\{mem\_min}$; \ $q\gets\\{rover}$;
+
+\bugonpage D510, in the July 1987 printing (4/7/89)
+
+\ninepoint\noindent
+[Move the 7th-to-last line, which begins with `\\{internal}[\\{fontmaking}]',
+one line down, and indent it to the right by 10 more points.
+This correction is needed only in the reprinting made July, 1987.]
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, bottom four lines (5/5/89)
+
+{\hsize=29pc \tenpoint
+\textindent\bull ``Metamarks: Preliminary studies for a Pandora's Box of
+shapes'' by Neenie Billawala,
+Stanford Computer Science Report 1256 (Stanford,
+California, May 1989), 132~pp. \ {\it Lavishly illustrated studies in
+parameter variation, leading to the design of a new family of
+typefaces called Pandora.}
+\par}
+
+\bugonpage E401, bottom line (5/16/89)
+
+\ninepoint\noindent
+{\bf \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+math\_fit}$(-.3\\{cap\_height}\0*\\{slant}-.5u\0,\\{ic}\0)$;\par\noindent
+{\bf penlabels}$(1,2,3,4,5,6,7,8)$; {\bf endchar\/};
+\smallskip\noindent
+[some points and labels are missing at the tip of the tail on page 400]
+ \bye
+ Now here are some that I will make soon!
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata6.tex b/Master/texmf-doc/doc/english/knuth/errata/errata6.tex
new file mode 100644
index 00000000000..ad7444d8600
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata6.tex
@@ -0,0 +1,528 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1990}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A,~C, and E\null, between 30 September 1989 (when
+the revisions for \TeX\ Version 3.0 and \MF\ Version 2.0 were made) and
+December 31, 1990.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Some of the corrections below have already been made in
+reprintings of the books. Hundreds of changes, too many to list here,
+have been made to Volumes B~and~D because of the upgrades to \TeX\ and
+\MF\null. Readers who need up-to-date information on the \TeX\ and
+\MF\ programs should refer to the |WEB| source files until new
+printings of Volumes B~and~D are issued. \looseness=-1
+
+ % volume A
+
+\bugonpage A99, line 4 from the bottom (2/22/90)
+
+\ninepoint\indent
+to be chosen because there was no feasible
+way to keep total demerits small.
+
+\bugonpage A124, lines 18--21 (9/5/90)
+
+\ninepoint\noindent
+Floating insertions can be accommodated
+as a special case of split insertions, by making each floating topinsert
+start with a small penalty, and by having
+zero as the associated |\floatingpenalty|; non-floating insertions
+like footnotes are accommodated by associating larger penalties with
+split insertions (see Appendix~B).
+
+\bugonpage A137, lines 2 and 3 from the bottom (11/9/90)
+
+{\eightssi
+\rightline{and you shouldn't even be reading this manual,}
+\rightline{which is undoubtedly all English to you.}
+}
+
+\bugonpage A141, line 15 from the bottom (10/18/90)
+
+\tenpoint\noindent
+Thus if you type `|$1\over2$|' (in a text) you get $1\over2$, namely style
+$S$ over style~$S'$;\cutpar
+
+\bugonpage A156, line 2 (11/18/89)
+
+\ninepoint
+Commands like |\mathchardef\alpha="010B| are used in
+Appendix~B to define\cutpar
+
+\bugonpage A165, lines 2--3 (8/13/90)
+
+\ninepoint
+ Type the formula $\bf\bar x^{\rm T}Mx={\rm0}\iff x=0$,
+using as few keystrokes as possible.
+\ (The first `0' is roman, the second is bold. The superscript `T' is roman.)
+
+\bugonpage A171, lines 24--26 (3/13/90)
+
+\ninepoint\noindent
+formula produces a result exactly equivalent to
+`|\left(|\<subformula>|\right)|', when the \<subformula> doesn't end
+with Punct, except that the {delimiters} are forced to
+be of the |\big| size regardless of the height and depth of the subformula.
+
+\bugonpage A193, lines 16--18 (12/2/89)
+
+\ninepoint\noindent
+line if you insert
+`^|\noalign||{|^|\break||}|'
+after the |\cr| for that line. You can prohibit {\sl all\/} breaks
+in an |\eqalignno| if you set ^|\interdisplaylinepenalty||=10000|; or you
+can enclose the whole works in a ^|\vbox|:
+
+\bugonpage A233, bottom 9 lines, and top three on next page (12/2/89)
+
+\danger The |\+| macro in Appendix~B works
+by putting the \<text> for each column that's followed by~|&|
+into an hbox as follows:
+\begindisplay
+|\hbox to |\<column width>|{|\<text>|\hss}|
+\enddisplay
+The ^|\hss| means that the text is normally flush left, and that it can
+extend to the right of its box. Since |\hfill| is ``more infinite'' than
+|\hss| in its ability to stretch, it has the effect of right-justifying or
+centering as stated above. Note that |\hfill| doesn't shrink, but |\hss|
+does; if the text doesn't fit in its column, it will stick out at the right.
+You could cancel the shrinkability of |\hss| by adding ^|\hfilneg|; then
+an oversize text would produce an overfull box.
+You could also center some text by putting `|\hss|' before it and just
+`|&|' after it; in that case the text would be allowed to extend to the
+left and right of its column.
+ The last column of a |\+|~line (i.e., the column entry that is
+followed by |\cr|) is treated differently: The
+\<text> is simply put into an hbox with its natural~width.\looseness=-1
+
+\bugonpage A254, line 5 from the bottom (10/5/89)
+
+\ninepoint\noindent
+|\vsize| hasn't changed, and if all insertions have been
+held in place, the same page break\cutpar
+
+\bugonpage A286, lines 30--32 (3/13/90)
+
+\ninepoint\noindent
+reading and expanding this \cstok{par}
+token, \TeX\ will see the \<vertical command> token again. \ (The current
+meaning of the control sequence ^|\par| will be used; \cstok{par} might no
+longer stand for \TeX's |\par| primitive.)
+
+\bugonpage A290, lines 12--13 (3/24/90)
+
+\ninepoint\noindent
+simply a single Ord atom without subscripts or superscripts,
+or an Acc whose nucleus is an Ord, the
+enclosing braces are effectively removed.
+
+\bugonpage A317, line 17 (5/17/90)
+
+\ninepoint
+|\pretolerance=9999 \tolerance=9999 \parindent=0pt|
+
+\bugonpage A321, lines 16--17 (8/13/90)
+
+\ninepoint\noindent
+\hbox to\parindent{\bf\hss18.6.\enspace}\ignorespaces
+|$\bf\bar x^{\rm T}Mx={\rm0}\iff x=0$|. \ (If you typed a space between
+|\rm| and~|0|, you wasted a keystroke; but don't feel guilty about it.)
+
+\bugonpage A340, nonblank line 11 (3/13/90)
+
+\tenpoint\noindent
+|\topglue 1in % This makes an inch of blank space (1in=2.54cm).|
+
+\bugonpage A342, line 6 (3/13/90)
+
+\tenpoint\noindent
+|\topglue| but not |\hglue|. It does not
+illustrate |\raggedright| setting of para-\cutpar
+
+\bugonpage A346, lines 20--21 (12/3/89)
+
+\ninepoint\noindent
+streams used by ^|\read| and ^|\write|, to math
+^{families} used by ^|\fam|, to sets of hyphenation rules used by
+^|\language|, and to insertions (which require
+^|\box|, ^|\count|, ^|\dimen|, and ^|\skip| registers all having the
+same number).
+
+\bugonpage A346, line 20 from the bottom (12/3/89)
+
+\ninepoint\noindent
+manent value. These macros use registers
+|\count10| through |\count20| to hold the\cutpar
+
+\bugonpage A346, lines 8--13 from the bottom (12/3/89)
+
+\ninepoint\noindent
+number was allocated. The inside story of how allocation is actually performed
+should be irrelevant when the allocation macros are used at a higher level;
+you mustn't assume that |plain.tex| really does allocation in any
+particular way.
+\beginlines
+|\count10=22 % this counter allocates \count registers 23, 24, 25, ...|
+\endgroup
+
+\bugonpage A347, lines 2--5 (12/3/89)
+
+\ninepoint{\parindent=0pt
+|\count19=0 % this counter allocates language codes 1, 2, 3, ...|\parbreak
+|\count20=255 % this counter allocates insertions 254, 253, 252, ...|\parbreak
+|\countdef\insc@unt=20 % nickname for the insertion counter|\parbreak
+|\countdef\allocationnumber=21 % the most recent allocation|\parbreak
+|\countdef|^|\m@ne||=22 \m@ne=-1 % a handy constant|\par}
+
+\bugonpage A347, new line after former line 17 (12/3/89)
+
+\ninepoint\noindent
+|\outer\def|^|\newlanguage||{\alloc@9\language\chardef\@cclvi}|
+
+\bugonpage A352, new line before line 6 from the bottom (3/13/90)
+
+\ninepoint\noindent
+|\def\topglue{\nointerlineskip \vglue-\topskip \vglue} % for top of page|
+
+\bugonpage A355, line 8 from the bottom (12/3/89)
+
+\ninepoint\noindent
+| \noindent{\bf#1.\enspace}{\sl#2\par}%|
+
+\bugonpage A363, lines 8--9 from the bottom (12/8/89)
+
+{\ninepoint\parindent=0pt
+| \if@mid \dimen@=\ht0 \advance\dimen@ by\dp\z@ |%
+ |\advance\dimen@ by12\p@|\parbreak%
+| \advance\dimen@ by\pagetotal \advance\dimen@ by-\pageshrink|
+\par}
+
+\bugonpage A375, line 27 (10/30/89)
+
+\ninepoint\noindent
+depending on whether or not |\t|~contains
+an asterisk. \ (Do you see why?) \ And here's\cutpar
+
+\bugonpage A393, lines 3--5 from the bottom (12/3/89)
+
+\ninepoint
+|\hskip-.17em plus-3em minus.11em|\par
+|\vadjust{}\penalty10000|\par
+|\leaders\copy\dbox\hskip3.3\wd\dbox plus1fil minus.3\wd\dbox|
+
+\bugonpage A444, line 4 (3/13/90)
+
+\ninepoint\noindent
+Shift box~$x$ down by ${1\over2}\bigl(h(x)-d(x)\bigr)
+-a$, where $a=\sigma_{22}$, so that the operator character\cutpar
+
+\bugonpage A450, line 8 (12/3/89)
+
+\def\\#1{$_{\kern\scriptspace#1}$}
+\ninepoint\indent
+{\qquad\tt\\0h\\0e\\0n\\5a\\0t\\0 \\1n\\0a\\0 \\0n\\2a\\0t\\0
+ \\1t\\0i\\0o\\0 \\2i\\0o\\0 \\0o\\2n\\0}
+
+\bugonpage A450, line 14 (12/3/89)
+
+\ninepoint
+{\tt.\\0h\\0y$_3$p\\0h\\0e\\2n\\5a\\4t\\2i\\0o\\2n\\0.}
+
+\bugonpage A450, lines 19 and 20 (12/3/89)
+
+\ninepoint\vskip-10pt
+\begindisplay
+\tt\\0o\\2n\\0
+\\0o\\0n\\1c\\0
+\\1c\\0a\\0
+\\1n\\0a\\0
+\\0n\\2a\\0t\\0
+\\1t\\0i\\0o\\0
+\\2i\\0o\\0
+\\0o\\2n\\0
+\enddisplay
+and this yields `{\tt\\0c\\0o\\2n\\1c\\0a\\0t\\0e\\1n\\2a\\1t\\2i\\0o\\2n\\0}',
+i.e., `|con-cate-na-tion|'.
+
+\bugonpage A455, last lines before the quotes (11/30/89)
+
+\ninepoint\noindent
+sit yourself (even in restricted horizontal mode) by saying
+^|\setlanguage|\<number>;\break
+ this changes the current language but it
+does not change |\language|. Each what-\break
+sit records the current
+|\lefthyphenmin| and |\righthyphenmin|.
+
+\bugonpage A467, right column (12/3/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\hfilneg|, 72, 100, 233, 283, 285, 290, 397.
+
+\bugonpage A468, right column (12/2/89)
+
+\eightpoint
+|\interdisplaylinepenalty|, {\it193}, 349, 362.
+
+\bugonpage A469, left column (12/3/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\language| (hyphenation method), 273, 346, $\underline{455}$.
+
+\bugonpage A469, right column (10/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\lefthyphenmin|, 273, {\it364}, $\underline{454}$, 455.
+
+\bugonpage A472, left column (12/3/89)
+
+\eightpoint
+|\newlanguage|, 346, $\underline{347}$.
+
+\bugonpage A476, left column (10/30/89)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+|\righthyphenmin|, 273, {\it364}, $\underline{454}$, 455.
+
+\bugonpage A479, new entry (3/13/90)
+
+\eightpoint
+|\topglue|, {\it340}, $\underline{352}$.
+
+\bugonpage A480, right column (3/13/90)
+
+\eightpoint
+|\vglue|, $\underline{352}$, {\it408}.
+
+\bugonpage A483, the Providence lines (10/8/89)
+
+\noindent[Change the first one to
+\begintt
+Providence RI 02940\kern.05em-9506, USA.
+\endtt
+Then the second one will be
+\begindisplay
+Providence RI 02940\kern.05em-9506, USA.
+\enddisplay
+The second line will also appear on page C361.]
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C11, replacement for second quotation at bottom of page (9/27/90)
+
+\begingroup
+ \eightpoint \let\tt=\ninett
+ \baselineskip 10pt
+ \parfillskip \z@
+ \interlinepenalty 10000
+ \leftskip \z@ plus 40pc minus \parindent
+ \let\rm=\eightss \let\sl=\eightssi
+ \everypar{\sl}
+ \def\par{\ifhmode\/\endgraf\fi}\obeylines
+To anyone who has lived in a modern American city (except Boston)
+at least one of the underlying ideas of ^{Descartes}' analytic geometry
+will seem ridiculously evident. Yet, as remarked,
+it took mathematicians all of two thousand years
+to arrive at this simple thing.
+\author ERIC TEMPLE ^{BELL}, {\sl Mathematics: Queen and Servant of %
+ Science\/} (1951) % p123
+
+\endgroup
+
+\bugonpage C220, top line (3/13/90)
+
+\ninepoint\noindent
+modes you get into by hitting
+`|S|', `|R|', or `|Q|', respectively, in response to error messages\cutpar
+
+\bugonpage C252, line 16 (3/13/90)
+
+\ninepoint\indent
+| for i:=1 upto n_windows: display blankpicture inwindow i; endfor|
+
+\bugonpage C262, lines 19--21 (11/9/90)
+
+\ninepoint\noindent
+for commonly occurring idioms.
+For example, `{\bf stop} |"hello"|' displays `|hello|' on the terminal and waits
+until \<return> is typed.
+\beginlines
+|def |^|upto|| = step 1 until enddef; def |^|downto|| = step -1 until enddef;|
+\endgroup
+
+\bugonpage C264, lines 4--6 from the bottom (3/24/90)
+
+\ninepoint\noindent
+|vardef |^|counterclockwise|| primary c =|\par\noindent
+| if turningcheck>0:|\par\noindent
+| interim |^|autorounding||:=0;|\par\noindent
+| if |^|turningnumber|| c <= 0: reverse fi fi c enddef;|
+
+\bugonpage C306, line 6 (3/13/90)
+
+\ninepoint\noindent
+| ligtable "'": "'" =: oct"042", % close quotes|
+
+\bugonpage C309, second line from bottom (11/18/89)
+
+\ninepoint\noindent
+| define_whole_vertical_blacker_pixels(vair,slab,| $\cdots$ |);|
+
+\bugonpage C315, line 9 from the bottom (1/2/90)
+
+\ninepoint\noindent
+units of printer's points):
+
+\bugonpage C329, line 25 (12/29/90)
+
+\ninepoint\noindent
+which can be used to specify a nonstandard file area
+or directory name for the gray\cutpar
+
+\bugonpage C337, line 4 from the bottom (1/7/90)
+
+\ninepoint\noindent
+|\def\startfont{\font\testfont=\fontname \spaceskip=0pt|
+
+\bugonpage C347, left column (9/27/90)
+
+\eightpoint\noindent
+Bell, Eric Temple, 11.
+
+\bugonpage C349, left column (9/27/90)
+
+\eightpoint\noindent
+Descartes, Ren\'e, 6, 11, 19.
+
+\bugonpage C356, right column (9/27/90)
+
+\eightpoint\noindent
+[remove the entry for Rex Stout.]
+
+\bugonpage C358, right column (9/27/90)
+
+\eightpoint\noindent
+[remove the entry for Nero Wolfe.]
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+\bugonpage Exiii, replacement for last four lines (4/30/90)
+
+\textindent{\bull}``AMS Euler---A new typeface for mathematics''
+ by Donald~E. Knuth
+and Hermann Zapf, {\sl Scholarly Publishing\/ \bf21} (1989), 131--157.
+\ {\it The story of a design project that helps bridge the gulf between
+mathematics and art.}
+
+\smallskip
+\textindent{\bull}``Meta-Marks:
+ Preliminary studies for a Pandora's Box of shapes''
+by Neenie Billawala, Stanford Computer Science report 1259 (Stanford,
+California, July 1989), 132~pp.
+\ {\it Lavishly illus\-trated studies in parameter variation,
+leading to the design of a new typeface called Pandora.}
+
+
+
+\bugonpage E325, line 13 (3/13/90)
+
+\ninepoint\noindent
+{\bf if} \\{serifs}: $x_{3r}=\max(x_{1r},{\rm hround}(x_1+.5\\{dot\_diam}
+ -.2\\{jut})-.5\\{tiny})$\par\noindent
+{\bf else}: $x_3=x_1-.5$ {\bf fi};
+
+\bugonpage E483, line 4 (3/13/90)
+
+\ninepoint
+\rightline{\% Character codes \oct{000}--\oct{100} and \oct{133}--\oct{177}
+ are generated.}
+
+\bugonpage E544, line 5 (3/13/90)
+
+\ninepoint\noindent
+\hskip 3em\vdots\hskip2em\raise2pt\hbox{(the rest of the
+ program for `$\gamma$' in |greekl| comes here)}
+
+\bugonpage E557, line 9 (3/13/90)
+
+\ninepoint
+\rightline{\sl`Nevermore---Ah nevermore.'\thinspace''}
+
+\bugonpage E558, line 21 (3/13/90)
+
+\eightpoint\noindent
+|Clasp a rare and radiant maiden whom the angels name Lenore."|
+
+\bugonpage E570, lines 27--28 look better with proper skewchars (3/13/90)
+
+\begingroup
+\tenpoint\bf
+\textfont0=\tenbf \scriptfont0=\sevenbf
+\font\boldi=cmmib10 \font\boldsy=cmbsy10
+\skewchar\boldi='177 \skewchar\boldsy='60
+\textfont1=\boldi
+\textfont2=\boldsy
+\noindent Here's some bold 10-point math:
+${\hat A}^\Gamma_0
++{\check B}^\Delta_1
+-{\tilde C}^\Theta_2
+\times{\acute D}^\Lambda_3
+/{\grave E}^\Xi_4
+\oplus{\dot F}^\Pi_5
+\ominus{\ddot G}^\Sigma_6
+\otimes{\breve H}^\Phi_7
+\oslash{\bar I}^\Psi_8
+\odot{\vec J}^{\,\Omega}_9$.
+\endgroup
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata7.tex b/Master/texmf-doc/doc/english/knuth/errata/errata7.tex
new file mode 100644
index 00000000000..0866189da51
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata7.tex
@@ -0,0 +1,821 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1991}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volumes A,~B, C, and D\null, between 1 January 1991 and
+15 March 1992.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Some of the corrections below have already been made in
+reprintings of the books. Changes to Volume~B refer to the fourth printing
+(1991), which differs markedly from earlier printings because it includes
+all the revisions for \TeX3.0. Changes to Volume~D refer to the third
+printing (1991), which differs markedly from earlier printings because
+it includes all the revisions for \MF\kern1pt2.0. Changes to the mini-indexes
+and master indexes of Volumes B and~D are not shown here unless they are
+not obviously derivable from what has been shown.
+Dozens of changes, too many to list
+here, have been made to Volume~E because of recent upgrades to the
+Computer Modern font source files.
+Those changes, which affect only the digitization at
+low resolution and the appearance of lowercase delta and
+some characters in the math symbols
+fonts (but not the {\tt TFM} files), are documented at
+the end of file {\tt cm85.bug}.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A96, lines 9--11 (9/18/91)
+
+\ninepoint
+Some ^{German} words traditionally change their spelling
+when they are split between lines. For example, `backen' becomes `bak-ken'
+and `Bettuch' becomes `Bett-tuch'. How can you instruct \TeX\ to produce
+such effects?
+
+\bugonpage A178, line 17 (11/19/91)
+
+\ninepoint
+If you say `|\phantom{|\<subformula>|}|' in any formula, plain
+\TeX\ will do its\cutpar
+
+\bugonpage A286, bottom two lines and continuing into A287 (11/21/91)
+
+\ninepoint\noindent
+stands for zero or more \<assignment>
+commands other than |\setbox|.
+If the assignments are not followed by a \<character>, where
+\<character> stands for any of the commands just discussed in the previous
+paragraph, \TeX\ treats |\accent| as if it were |\char|, except that
+the space factor is set to 1000. Otherwise the character that follows
+the assignment is accented by the character that corresponds to the
+\<8-bit number>. \ (The purpose of the intervening assignments is to
+allow the accenter and accentee to be in different fonts.) \ If the
+accent must be moved up or down, it is put into an hbox that is
+raised or lowered. Then the accent is effectively superposed on the
+character by means of kerns, in such a way that the width of the accent
+does not influence the width of the resulting horizontal list.
+Finally, \TeX\ sets |\spacefactor=1000|.
+
+\bugonpage A291, lines 6--8 (11/21/91)
+
+\ninepoint\noindent
+`|}|' may be followed by
+optional \<assignment> commands other than |\setbox|,
+after which `|$$|'~must conclude
+the display. \TeX\ will insert the |\abovedisplayskip| and
+|\belowdisplayskip| glue before and after the result of the alignment.
+
+\bugonpage A293, line 14 (9/18/91)
+
+\ninepoint\noindent
+explained in Appendix~G\null. \TeX\
+scans \<one optional space> after completing a displayed formula; this is
+usually the implicit space at the end of a line in the input file.
+
+\bugonpage A311, bottom four lines (9/18/91)
+
+\ninepoint
+\ansno12.7: 1000, except: 999 after |O|, |B|, |S|, |D|, and |J|; 1250 after the
+comma; 3000 after the exclamation point, the right-quote marks, and the
+periods. If a period had come just after the |B| (i.e., if the text had
+said `|B. Sally|'), the space factor after that period would have
+been~1000, not~3000.
+
+\bugonpage A314, lines 16--18 from the bottom (1/10/92)
+
+\ninepoint
+\ansno14.8: |ba\ck/en| and |Be\ttt/uch|, where the macros |\ck/| and |\ttt/|
+are defined by
+\begintt
+\def\ck/{\discretionary{k-}{k}{ck}}
+\def\ttt/{tt\discretionary{-}{t}{}}
+\endtt
+
+\bugonpage A354, line 8 (9/18/91)
+
+\ninepoint\noindent
+|\def\multispan#1{\omit\mscount=#1\relax\loop\ifnum\mscount>1 \sp@n\repeat}|%
+\kern-10pt\null
+
+\bugonpage A356, line 11 from the bottom (9/23/91)
+
+\ninepoint\noindent
+| \else{\ooalign{\unhbox0\crcr\hidewidth\char'30\hidewidth}}\fi}|
+
+\bugonpage A358, line 8 from the bottom (9/18/91)
+
+\ninepoint\noindent
+|\mathchardef\mapstochar="3237 \def\mapsto{\mapstochar\rightarrow}|
+
+\bugonpage A359, line 13 (11/4/91)
+
+\ninepoint\noindent
+|\def\overrightarrow#1{\vbox{\m@th\ialign{##\crcr|
+
+\bugonpage A359, line 16 (11/4/91)
+
+\ninepoint\noindent
+|\def\overleftarrow#1{\vbox{\m@th\ialign{##\crcr|
+
+\bugonpage A359, line 19 (11/4/91)
+
+\ninepoint\noindent
+|\def\overbrace#1{\mathop{\vbox{\m@th\ialign{##\crcr\noalign{\kern3pt}|
+
+\bugonpage A359, line 22 (11/4/91)
+
+\ninepoint\noindent
+|\def\underbrace#1{\mathop{\vtop{\m@th\ialign{##\crcr|
+
+\bugonpage A359, lines 7--14 from the bottom (1/11/92)
+
+\ninepoint\noindent
+|\def\lgroup{\delimiter"462833A } \def\rgroup{\delimiter"562933B }|%
+\par\noindent
+|\def\lmoustache{\delimiter"437A340 } \def\rmoustache{\delimiter"537B341 }|%
+ \kern-2pt\null\par\noindent
+|\def\uparrow{\delimiter"3222378 } \def\Uparrow{\delimiter"322A37E }|%
+\par\noindent
+|\def\downarrow{\delimiter"3223379 } \def\Downarrow{\delimiter"322B37F }|%
+\par\noindent
+|\def\updownarrow{\delimiter"326C33F } \def\arrowvert{\delimiter"026A33C }|%
+\par\noindent
+|\def\Updownarrow{\delimiter"326D377 } \def\Arrowvert{\delimiter"026B33D } |%
+\par\noindent
+|\def\vert{\delimiter"026A30C } \def\Vert{\delimiter"026B30D } |%
+\par\noindent
+|\def\backslash{\delimiter"026E30F } \def\bracevert{\delimiter"077C33E }|
+
+\bugonpage A360, line 13 (11/19/91)
+
+\ninepoint\noindent
+|\phantom|, |\smash|, |\root|, and other
+operations. (Actually |\phantom| and |\smash| are not perfect: They
+assume that the current style is uncramped.)
+
+\bugonpage A360, line 2 from the bottom (11/4/91)
+
+\ninepoint\noindent
+|\def\c@ncel#1#2{\m@th\ooalign{$\hfil#1\mkern1mu/\hfil$\crcr$#1#2$}}|
+
+\bugonpage A361, top line (11/4/91)
+
+\ninepoint\noindent
+|\def\rlh@#1{\vcenter{\m@th\hbox{\ooalign{\raise2pt|
+
+\bugonpage A364, line 5 from the bottom (11/4/91)
+
+\ninepoint\noindent
+|\def|^|\fmtname||{plain}\def\fmtversion{3.141}|
+
+\bugonpage A377, the bottom 17 lines (9/18/91)
+
+\eightpoint\noindent\hangindent\parindent\hangafter-3
+story: Macro |\stest| decides whether or not
+a given token list register begins with
+a \<space token> as defined in Chapter~24. If so, the macro
+decides whether the token is explicit and/or funny and/or active.
+\begintt
+\newif\ifspace \newif\iffunny \newif\ifexplicit \newif\ifactive
+\def\stest#1{\funnyfalse \expandafter\s\the#1! \stest}
+\def\s{\global\explicitfalse \global\activefalse \futurelet\next\ss}
+\def\ss{\ifcat\noexpand\next\stoken\let\nxt\sx\else\let\nxt\ns\fi\nxt}
+\def\sx{\spacetrue\ifx\next\stoken\let\nxt\sss\else\let\nxt=\ssss\fi\nxt}
+\long\def\sss#1 #2\stest{\def\next{#1}%
+ \ifx\next\empty \global\explicittrue \else\testactive#1\s\fi}
+\long\def\ssss#1#2\stest{\funnytrue{\escapechar=\if*#1`?\else`*\fi\relax
+ \if#1\string#1\uccode`#1=`~ % we assume that ~ is an active character
+ \uppercase{\ifcat\noexpand#1}\noexpand~\global\activetrue
+ \else\global\explicittrue\fi
+ \else\testactive#1\s\fi}}
+\long\def\ns#1\stest{\spacefalse}
+\long\def\testactive#1#2\s{\expandafter\tact\string#1\s\tact}
+\long\def\tact#1#2\tact{\def\next{#2}\ifx\next\xs\global\activetrue
+ \else\ifx\next\empty \global\activetrue\fi\fi} \def\xs{\s}
+\endtt
+
+\bugonpage A444, lines 15--26 (3/26/91)
+
+\ninepoint
+\textindent{\bf14.}If the current item is an Ord atom,
+go directly to Rule~17 unless
+all of the following are true: The nucleus is a symbol; the subscript
+and superscript are both empty; the very next item in the math list is an
+atom of type Ord, Op, Bin, Rel, Open, Close, or Punct; and the nucleus of the
+next item is a symbol whose family is the same as the family in the present
+Ord atom. In such cases the present symbol is marked as a text symbol.
+If the font information shows a ligature between this symbol and the
+following one, using the specified family and the current size, then
+insert the ligature character and continue as specified by the font;
+in this process, two characters may collapse into a single Ord
+text symbol, and/or new Ord text characters may appear. If the font information
+shows a kern between the current symbol and the next, insert a kern item
+following the current atom.
+As soon as an Ord atom has been fully processed for ligatures and kerns,
+go to Rule~17.
+
+\bugonpage A446, lines 5 and 6 from the bottom (1/13/92)
+
+\ninepoint\noindent
+are used to change the current style just as
+in the first pass, so that both passes have the same value of~$C$ when
+they work on any particular atom.
+
+\bugonpage A447, in the parameter usage table (1/13/92)
+
+\ninepoint\noindent[Delete the entry for `$\sigma_2$'; the entry for
+`$\sigma_{17}$' moves down to the bottom of the left column.]
+
+\bugonpage A447, line 2 after the parameter usage table (1/13/92)
+
+\ninepoint\noindent
+to parameters in arbitrary families:
+Rule~17 uses |\fontdimen| parameter~2 (space) to de-\cutpar
+
+\bugonpage A467, entry for {\tt\char`\\hss} (9/18/91)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\hss}, 71--72, {\it82--83}, 233, 283, 285, 290, 442.
+
+\bugonpage A467, new subentry under hyphenation (9/18/91)
+
+\eightpoint\indent\quad
+suppressing, 93, 414, 424, 454.
+
+\bugonpage A476, right column (11/21/91)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt\char`\\setbox}, 66--67, 77, 81, $\underline{120}$, 276, 279, 286,\par
+\indent\qquad 291, {\it386--392}.
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 10 from the bottom (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]3.141\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B18, lines 21 and 22 (10/12/91)
+
+\tenpoint\noindent
+must have an \\{xchr} equivalent in the local
+character set. (This restriction applies only to preloaded strings,
+not to those generated dynamically by the user.)
+
+\bugonpage B26, new line before fourth line from bottom (1/24/92)
+
+\ninepoint\noindent\hskip20pt
+\\{nl}: \\{integer};\quad$\{\,$new-line character to restore$\,\}$
+
+\bugonpage B26, bottom line and top 3 lines of B27 (1/24/92)
+
+\ninepoint\noindent\hskip30pt
+{\bf else begin if\/} $\\{selector}>\\{pseudo}$ {\bf then}\par
+\noindent\hskip50pt
+{\bf begin} \\{print\_char}($s$); \ {\bf return};\quad
+ $\{\,$internal strings are not expanded$\,\}$\par\noindent\hskip50pt
+{\bf end};\par\noindent\hskip40pt
+{\bf if\/} ($\langle\,$Character $s$ is the current new-line
+ character{\sevenrm\kern.5em244}$\,\rangle$) {\bf then}\par\noindent\hskip50pt
+{\bf if\/} $\\{selector}<\\{pseudo}$ {\bf then}\par\noindent\hskip60pt
+{\bf begin} \\{print\_ln}; \ {\bf return}; \
+{\bf end};\par\noindent\hskip40pt
+$\\{nl}\gets\\{new\_line\_char}$; \ $\\{new\_line\_char}\gets-1$;\quad
+ $\{\,$temporarily disable new-line character$\,\}$\par\noindent\hskip40pt
+$j\gets\\{str\_start}[s]$;\par\noindent\hskip40pt
+{\bf while} $j<\\{str\_start}[s+1]$ {\bf do}\par\noindent\hskip50pt
+{\bf begin} $\\{print\_char}(\\{so}(\\{str\_pool}[j]))$; \ $\\{incr}(j)$; \
+{\bf end};\par\noindent\hskip40pt
+$\\{new\_line\_char}\gets\\{nl}$; \ {\bf return};\par\noindent\hskip40pt
+{\bf end};
+
+\bugonpage B27, lines 9 and 10 (9/19/91)
+
+\tenpoint\noindent
+{\bf 60.\quad}%
+Control sequence names, file names, and strings constructed with
+{\tt\char`\\string} might contain \\{ASCII\_code} values that can't
+be printed using \\{print\_char}. Therefore we use
+\\{slow\_print} for them:
+
+\bugonpage B27, lines 13--26 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $j$: \\{pool\_pointer};\quad$\{\,$current character code
+ position$\,\}$\par\noindent\hskip10pt
+{\bf begin if\/} $(s\ge\\{str\_ptr})\lor(s<256)$ {\bf then} \\{print}(s)
+\par\noindent\hskip10pt {\bf else begin} $j\gets\\{str\_start}[s]$;\par
+\noindent\hskip20pt{\bf while} $j<\\{str\_start}[s+1]$ {\bf do}\par
+\noindent\hskip30pt{\bf begin} $\\{print}(\\{so}(\\{str\_pool}[j]))$; \
+ $\\{incr}(j)$;\par\noindent\hskip30pt
+{\bf end};\par\noindent\hskip20pt
+{\bf end};\par\noindent\hskip10pt
+{\bf end};
+
+\bugonpage B28, line 8 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf else begin} \\{slow\_print}(\\{format\_ident}); \ \\{print\_ln};
+
+\bugonpage B33, line 3 (1/11/92)
+
+\tenpoint\noindent
+recursively. A similar interlock is provided by \\{set\_box\_allowed}.
+
+\bugonpage B33, new line to come after line 14 (1/11/92)
+
+\ninepoint\noindent
+\\{set\_box\_allowed}: \\{boolean};\quad
+ $\{\,$is it safe to do a |\setbox| assignment?$\,\}$
+
+\bugonpage B33, new line to come after line 20 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{set\_box\_allowed}\gets\\{true}$;
+
+\bugonpage B36, line 12 (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} \\{print\_nl}({\tt\char`\"You\]want\]to\]edit\]file\]\char`\"});
+ \ \\{slow\_print}(\\{input\_stack}[\\{base\_ptr}].\\{name\_field});
+
+\bugonpage B46, lines 9 and 10 (5/24/91)
+
+\tenpoint\noindent
+arithmetic; see {\sl TUGboat \bf3},1 (March 1982), 10--27. (But the
+routines cited there must be modified to allow negative glue ratios.)
+
+\bugonpage B47, lines 2 and 3 (5/24/91)
+
+\tenpoint\noindent
+structures on a \\{memory\_word}, which contains either a (signed) integer,
+possibly scaled, or a (signed) \\{glue\_ratio}, or a small number of
+fields that are one half or one quarter of the size used\cutpar
+
+\bugonpage B177, lines 10 and 11 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} \\{print\_err}({\tt\char`\"Bad\]mathchar\char`\"});\par
+\noindent\hskip20pt
+\\{help2}({\tt\char`\"A\]mathchar\]number\]must\]be\]between\]0\]%
+ and\]32767.\char`\"})
+
+\bugonpage B196, new lines after line 11 (1/13/92)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $\\{align\_state}<1000000$ {\bf then}\quad
+ $\{\,$unmatched `|}|' aborts the line$\,\}$\par\noindent\hskip30pt
+{\bf begin repeat} \\{get\_token}; \ {\bf until} $\\{cur\_tok}=0$;\par
+\noindent\hskip30pt$\\{align\_state}\gets1000000$; \ {\bf goto} \\{done};\par
+\noindent\hskip30pt{\bf end};
+
+\bugonpage B208, line 21 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{slow\_print}($a$); \ \\{slow\_print}($n$); \
+ \\{slow\_print}($e$);
+
+\bugonpage B214, line 14 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{wlog}(\\{banner}); \\{slow\_print}(\\{format\_ident}); \
+ \\{print}({\tt\char`\"\]\]\char`\"}); \
+ \\{print\_int}(\\{day}); \
+ \\{print\_char}({\tt\char`\"\]\char`\"});
+
+\bugonpage B214, line 2 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_char}({\tt\char`\"(\char`\"}); \
+\\{incr}(\\{open\_parens}); \
+\\{slow\_print}(\\{name}); \
+\\{update\_terminal}; \
+$\\{state}\gets\\{new\_line}$;
+
+\bugonpage B234, line 22 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+\\{print}({\tt\char`\"\]in\]font\]\char`\"}); \
+\\{slow\_print}(\\{font\_name}[$f$]); \
+\\{print\_char}({\tt\char`\"!\char`\"}); \
+\\{end\_diagnostic}(\\{false});
+
+\bugonpage B267, lines 7 and 8 (9/19/91)
+
+\ninepoint\noindent\hskip20pt
+\\{print\_nl}({\tt\char`\"Output\]written\]on\]\char`\"}); \
+\\{slow\_print}(\\{output\_file\_name});\par\noindent\hskip20pt
+\\{print}({\tt\char`\"\](\char`\"}); \
+\\{print\_int}(\\{total\_pages}); \
+\\{print}({\tt\char`\"\]page\char`\"});
+
+\bugonpage B296, new lines after line 8 of section 716 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $f<0$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} \\{decr}($n$); \ $f\gets f+\oct{200000}$;\par\noindent\hskip20pt
+{\bf end};
+
+\bugonpage B297, new lines after line 7 of section 717 (1/11/92)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $f<0$ {\bf then}\par\noindent\hskip30pt
+{\bf begin} \\{decr}($n$); \ $f\gets f+\oct{200000}$;\par\noindent\hskip30pt
+{\bf end};
+
+\bugonpage B348, bottom two lines (1/3/92)
+
+\tenpoint\noindent\hskip10pt
+Up to three passes might be made through the paragraph in an attempt to find at
+least one set of feasible breakpoints. On the first pass, we have
+$\\{threshold}=\\{pretolerance}$ and $\\{second\_pass}=$\cutpar
+
+\bugonpage B364, line 20 (1/3/92)
+
+\tenpoint\noindent
+{\bf 863.\quad}
+The `{\bf loop}' in the following code is performed at most
+thrice per call of \\{line\_break}, since\cutpar
+
+\bugonpage B377, insert new line after line 12 (9/19/91)
+
+\ninepoint\noindent
+\\{hyf\_bchar}:\enspace\\{halfword};\quad
+ $\{\,$boundary character after $c_n\,\}$
+
+\bugonpage B378, line 12 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+$\\{hyf\_bchar}\gets\\{character}(s)$; \
+$c\gets\\{qo}(\\{hyf\_bchar})$;
+
+\bugonpage B378, line 9 from the bottom (1/10/92)
+
+\ninepoint\noindent\hskip30pt
+$\\{hb}\gets s$; \ \\{incr}(\\{hn}); \ $\\{hu}[\\{hn}]\gets c$; \
+$\\{hc}[\\{hn}]\gets\\{lc\_code}(c)$; \
+$\\{hyf\_bchar}\gets\\{non\_char}$;
+
+\bugonpage B378, line 5 from the bottom (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf else if} $(\\{type}(s)=\\{kern\_node})\land(\\{subtype}(s)=\\{normal})$
+ {\bf then} $\\{hb}\gets s$\par\noindent\hskip40pt
+ {\bf else goto} \\{done3};
+
+\bugonpage B379, line 6 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+$j\gets\\{hn}$; \ $q\gets\\{lig\_ptr}(s)$; \
+{\bf if\/} $q>\\{null}$ {\bf then} $\\{hyf\_bchar}\gets\\{character}(q)$;
+
+\bugonpage B379, new line between lines 14 and 15 (1/10/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{odd}(\\{subtype}(s))$ {\bf then}
+$\\{hyf\_bchar}\gets\\{font\_bchar}[\\{hf}]$ {\bf else}
+$\\{hyf\_bchar}\gets\\{non\_char}$;
+
+\bugonpage B379, line 19 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{hn}<\\{l\_hyf}+\\{r\_hyf}$ {\bf then goto} \\{done1}; \
+\quad$\{\,$\\{l\_hyf} and \\{r\_hyf} are always $\ge1\,\}$
+
+\bugonpage B380, lines 9--11 from the bottom reduce to a single line (1/10/92)
+
+\ninepoint\noindent\hskip10pt
+$q\gets\\{link}(\\{hb})$; \ $\\{link}(\\{hb})\gets\\{null}$; \
+$r\gets\\{link}(\\{ha})$; \ $\\{link}(\\{ha})\gets\\{null}$; \
+$\\{bchar}\gets\\{hyf\_bchar}$;
+
+\bugonpage B436, lines 9 and 10 (3/15/92)
+
+\tenpoint
+$$\\{cur\_r}=\cases{\\{character}(\\{lig\_stack}),&if $\\{lig\_stack}>
+ \\{null}$;\cr
+ \\{font\_bchar}[\\{cur\_font}],&otherwise;\cr}$$
+except when $\\{character}(\\{lig\_stack})=\\{font\_false\_bchar}
+ [\\{cur\_font}]$. Several additional global variables are needed.
+
+\bugonpage B438, line 13 from the bottom (3/15/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_q}\gets\\{tail}$; \ $\\{cur\_l}\gets\\{character}(\\{lig\_stack})$;
+
+\bugonpage B507, line 6 of section 1241 (1/11/92)
+
+\ninepoint\noindent\hskip10pt
+\\{scan\_optional\_equals};\par\noindent\hskip10pt
+{\bf if\/} \\{set\_box\_allowed} {\bf then}
+$\\{scan\_box}(\\{box\_flag}+n)$\par\noindent\hskip10pt
+{\bf else begin} \\{print\_err}({\tt\char`\"Improper\]\char`\"});
+\ \\{print\_esc}({\tt\char`\"setbox\char`\"});\par\noindent\hskip20pt
+\\{help2}({\tt\char`\"Sorry,\]\char`\\setbox\]is\]not\]allowed\]after\]%
+\char`\\halign\]in\]a\]display,\char`\"})\par\noindent\hskip20pt
+({\tt\char`\"or\]between\]\char`\\accent\]%
+and\]an\]accented\]character.\char`\"});
+\ \\{error};\par\noindent\hskip20pt
+{\bf end};
+
+\bugonpage B511, new line inserted after line 3 (1/24/92)
+
+\ninepoint\noindent\hskip20pt
+\\{flushable\_string}: \\{str\_number};\quad
+ $\{\,$string not yet referenced$\,\}$
+
+\bugonpage B512, new line inserted after line 3 of section 1260 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+$\\{flushable\_string}\gets\\{str\_ptr}-1$;
+
+\bugonpage B512, the former line 6 of section 1260 (1/24/92)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin if\/} $\\{cur\_name}=\\{flushable\_string}$ {\bf then}
+\par\noindent\hskip40pt{\bf begin} \\{flush\_string}; \
+ $\\{cur\_name}\gets\\{font\_name}[f]$; \ {\bf end};
+\par\noindent\hskip30pt{\bf if\/} $s>0$ {\bf then}
+
+\bugonpage B512, line 10 from the bottom (9/19/91)
+
+\ninepoint\noindent
+\\{set\_font}:\enspace{\bf begin}
+\\{print}({\tt\char`\"select\]font\]\char`\"}); \
+\\{slow\_print}(\\{font\_name}[\\{chr\_code}]);
+
+\bugonpage B514, line 9 (1/11/92)
+
+\ninepoint\noindent\hskip20pt
+$\\{set\_box\_allowed}\gets\\{false}$; \
+\\{prefixed\_command}; \
+$\\{set\_box\_allowed}\gets\\{true}$;
+
+\bugonpage B515, line 19 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{slow\_print}($s$); \ \\{update\_terminal};
+
+\bugonpage B516, line 2 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+{\bf begin} \\{print\_err}({\tt\char`\"\char`\"}); \
+ \\{slow\_print}($s$);
+
+\bugonpage B531, lines 19 and 20 (9/19/91)
+
+\ninepoint\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"Beginning\]to\]dump\]on\]file\]\char`\"}; \
+\\{slow\_print}(\\{w\_make\_name\_string}(\\{fmt\_file})); \
+\\{flush\_string};\par\noindent\hskip10pt
+\\{print\_nl}({\tt\char`\"\char`\"}); \
+\\{slow\_print}(\\{format\_ident})
+
+\bugonpage B533, line 29 (9/19/91)
+
+\ninepoint\noindent\hskip30pt
+{\bf begin} \\{print\_nl}({\tt\char`\"Transcript\]written\]on\]\char`\"}); \
+\\{slow\_print}(\\{log\_name}); \
+\\{print\_char}({\tt\char`\".\char`\"});
+
+\bugonpage B538, line 13 (9/19/91)
+
+\ninepoint\noindent
+10:\enspace\\{slow\_print}($n$);
+
+\bugonpage B577, left column (12/23/91)
+
+\eightpoint\noindent[Add 798 to the index entries for `system dependencies'.]
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C262, line 15 (3/26/91)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="2.7";|
+
+\bugonpage C271, line 17 from the bottom (3/26/91)
+
+\ninepoint\noindent
+| currentpen_path shifted (z.t_) withpen penspeck enddef;|
+
+\bugonpage C347, Bront''e entry (1/29/91)
+
+\eightpoint\noindent
+[The accent was clobbered; her name should, of course, be Bront\"e.
+Fix the entries for D\"urer, M\"obius, and Stravinsky in the same way.]
+
+\bugonpage C348, left column (1/11/92)
+
+\eightpoint\indent
+compound statement, $\underline{155}$, 217.
+
+\bugonpage C353, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt numeric}, 55, $\underline{56}$, {\it65}, 88.
+
+\bugonpage C354, miscellaneous entries in both columns (1/11/92)
+
+\eightpoint
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt openwindow}, $\underline{191}$--$\underline{193}$, 220, {\it277},
+ {\it312--313}.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt or}, {\it65}, $\underline{170}$, 210, 237, 288--289.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt pair}, 55, $\underline{56}$, 65.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt path}, 55, $\underline{56}$, 171.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt pen}, 55, $\underline{56}$, {\it65}, 170.
+\par\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt picture}, 55, $\underline{56}$, {\it114}.
+
+\bugonpage C356, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt string}, 55, $\underline{56}$, 69.
+
+\bugonpage C357, right column (1/11/92)
+
+\eightpoint\indent\hbox to0pt{\hss\lower1pt\hbox{*}}%
+{\tt transform}, 55, $\underline{56}$, 57, 141--143, {\it160}, 266.
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage D2, last line of section 2 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]METAFONT,\]Version\]2.71\char'23}\quad
+$\{\,$printed when \MF\ starts$\,\}$
+
+\bugonpage D102, line 15 from the bottom (11/1/91)
+
+\tenpoint\noindent
+Then
+$\\{eq\_type}(h(x))=\\{tag\_token}$ and $\\{equiv}(h(x))=p$,
+where $p$~is a two-word value
+node with\cutpar
+
+\bugonpage D188, lines 16 and 17 (1/24/92)
+
+\tenpoint\noindent
+errors. Our subroutines also obey the identity $t[a,b]+t[b,a]=a+b$.
+
+\bugonpage D190, new copy before bottom four lines (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(r)<\\{x\_coord}(\\{pp})$ {\bf then}
+ $\\{x\_coord}(r)\gets\\{x\_coord}(\\{pp})$\par\noindent\hskip10pt
+{\bf else if\/} $\\{x\_coord}(r)>\\{dest\_x}$ {\bf then}
+ $\\{x\_coord}(r)\gets\\{dest\_x}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{left\_x}(r)>\\{x\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_x}(r)\gets\\{x\_coord}(r)$; \
+{\bf if\/} $\\{right\_x}(\\{pp})>\\{x\_coord}(r)$ {\bf then}
+$\\{right\_x}(\\{pp})\gets\\{x\_coord}(r)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_x}(r)<\\{x\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_x}(r)\gets\\{x\_coord}(r)$; \
+{\bf if\/} $\\{left\_x}(\\{qq})<\\{x\_coord}(r)$ {\bf then}
+$\\{left\_x}(\\{qq})\gets\\{x\_coord}(r)$; \ {\bf end};
+
+\bugonpage D191, new copy before bottom two lines of section 416 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(s)<\\{x\_coord}(r)$ {\bf then}
+ $\\{x\_coord}(s)\gets\\{x\_coord}(r)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{x\_coord}(s)>\\{dest\_x}$ {\bf then}
+ $\\{x\_coord}(s)\gets\\{dest\_x}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{left\_x}(s)>\\{x\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_x}(s)\gets\\{x\_coord}(s)$; \
+{\bf if\/} $\\{right\_x}(r)>\\{x\_coord}(s)$ {\bf then}
+$\\{right\_x}(r)\gets\\{x\_coord}(s)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_x}(s)<\\{x\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_x}(s)\gets\\{x\_coord}(s)$; \
+{\bf if\/} $\\{left\_x}(\\{qq})<\\{x\_coord}(s)$ {\bf then}
+$\\{left\_x}(\\{qq})\gets\\{x\_coord}(s)$; \ {\bf end};
+
+\bugonpage D194, lines 4 and 5 (1/24/92)
+
+\tenpoint\noindent[Delete those two lines; I no longer believe that the
+assertion has been proved (although it might be true).]
+
+\bugonpage D194, lines 7--13 of section 424 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{y\_coord}(r)<\\{y\_coord}(p)$ {\bf then}
+ $\\{y\_coord}(r)\gets\\{y\_coord}(p)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{y\_coord}(r)>\\{dest\_y}$ {\bf then}
+ $\\{y\_coord}(r)\gets\\{dest\_y}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(p)+\\{y\_coord}(r)>\\{dest\_x}+\\{dest\_y}$
+{\bf then} $\\{y\_coord}(r)\gets\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(p)$;\par
+\noindent\hskip10pt
+{\bf if\/} $\\{left\_y}(r)>\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{right\_y}(p)>\\{y\_coord}(r)$ {\bf then}
+$\\{right\_y}(p)\gets\\{y\_coord}(r)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(r)<\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(r)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(r)$; \ {\bf end};
+
+\bugonpage D194, lines 8--11 from the bottom (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(r)<\\{y\_coord}(r)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(r)\gets\\{y\_coord}(r)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(r)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(r)$; \ {\bf end};
+
+\bugonpage D195, lines 3--9 of section 425 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{y\_coord}(s)<\\{y\_coord}(r)$ {\bf then}
+ $\\{y\_coord}(s)\gets\\{y\_coord}(r)$\par\noindent\hskip10pt
+{\bf else if\/} $\\{y\_coord}(s)>\\{dest\_y}$ {\bf then}
+ $\\{y\_coord}(s)\gets\\{dest\_y}$;\par\noindent\hskip10pt
+{\bf if\/} $\\{x\_coord}(r)+\\{y\_coord}(s)>\\{dest\_x}+\\{dest\_y}$
+{\bf then} $\\{y\_coord}(s)\gets\\{dest\_x}+\\{dest\_y}-\\{x\_coord}(r)$;\par
+\noindent\hskip10pt
+{\bf if\/} $\\{left\_y}(s)>\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{left\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{right\_y}(r)>\\{y\_coord}(s)$ {\bf then}
+$\\{right\_y}(r)\gets\\{y\_coord}(s)$; \ {\bf end};\par\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(s)<\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(s)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(s)$; \ {\bf end};
+
+\bugonpage D195, lines 3--7 from the bottom if section 425 (1/24/92)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{right\_y}(s)<\\{y\_coord}(s)$ {\bf then}\par\noindent\hskip20pt
+{\bf begin} $\\{right\_y}(s)\gets\\{y\_coord}(s)$; \
+{\bf if\/} $\\{left\_y}(q)<\\{y\_coord}(s)$ {\bf then}
+$\\{left\_y}(q)\gets\\{y\_coord}(s)$; \ {\bf end};
+
+\bugonpage D289, lines 9 and 10 (11/1/91)
+
+\ninepoint\noindent\hskip20pt
+$p\gets\\{dep\_list}(p)$; \ $r\gets\\{inf\_val}$;\par\noindent\hskip20pt
+{\bf repeat if\/} $\\{value}(\\{info}(p))\ge\\{value}(r)$ {\bf then}\par
+
+\bugonpage D486, line 18 (11/1/91)
+
+\tenpoint\noindent
+The \\{label\_loc}
+and \\{label\_char} arrays have been set up to record all the
+starting addresses; we have\cutpar
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata8.tex b/Master/texmf-doc/doc/english/knuth/errata/errata8.tex
new file mode 100644
index 00000000000..30e73fccd49
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata8.tex
@@ -0,0 +1,525 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting, 1992}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting\/} between 15 March 1992 and the publication of the final
+printed versions of those books.
+Corrections made to the softcover version of {\sl The \TeX book\/} are
+the same as corrections to Volume~A\null. Corrections to the softcover
+version of {\sl The \slMF\kern1ptbook\/} are the same as corrections
+to Volume~C\null. Changes to Volume~B refer to the fourth printing
+(1991), which differs markedly from earlier printings because it includes
+all the revisions for \TeX3.0. Changes to Volume~D refer to the third
+printing (1991), which differs markedly from earlier printings because
+it includes all the revisions for \MF\kern1pt2.0. Changes to the mini-indexes
+and master indexes of Volumes B and~D are not shown here unless they are
+not obviously derivable from what has been shown.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A23, line 14 (9/1/92)
+
+\tenpoint\noindent
+a command and you type `|tex|' or `|run| |tex|' or something like that.)
+
+\bugonpage A53, line 23 (7/7/92)
+
+\tenpoint\noindent
+{\sl scientiarum imperialis petropolitan\ae\/}
+became {\sl Akademi\t\i a Nauk SSSR, Doklady}.
+
+\bugonpage A146, line 2 from the bottom (2/25/93)
+
+|$\bigl|\|| |\||x|\||-|\||y|\|| \bigr|\||$|\hskip1.25in
+ $\bigl\vert\vert x\vert-\vert y\vert\bigr\vert$
+
+\bugonpage A149, lines 3--5 (2/25/93)
+
+\noindent
+example, we used |\bigl| and |\bigr| to produce $\bigl\vert\vert x\vert-
+\vert y\vert\bigr\vert$ in one of the previous illustrations; |\left| and
+|\right| don't make things any bigger than necessary, so
+`|$\left|\||\left|\||x\right|\||-\left|\||y\right|\||\right|\||$|'
+yields only `$\left\vert
+ \left\vert x\right\vert -\left\vert y\right\vert \right\vert$'.\cutpar
+
+\bugonpage A158, line 18 from the bottom (2/25/93)
+
+\ninepoint
+are four possibilities for each of these fields.
+A field can be
+
+\bugonpage A282, line 9 from the bottom (7/8/92)
+
+\ninepoint\noindent
+category~4) are intercepted by the alignment
+process, en route to \TeX's stomach, so\cutpar
+
+\bugonpage A293, new paragraph after line 15 (4/9/92)
+
+\ninepoint
+\textindent{$\bull$}|\unhbox|\<8-bit number>, |\unhcopy|\<8-bit number>.\enskip
+The specified box register must be void. Nothing happens.
+
+\bugonpage A309, line 23 (7/7/92)
+
+\ninepoint\noindent
+|petropolitan\ae\/} became {\sl Akademi\t\i a Nauk SSSR, Doklady}.|
+
+\bugonpage A320, line 11 (1/26/93)
+
+\ninepoint
+\ansno17.12:
+|$\bigl(x+f(x)\bigr) \big/ \bigl(x-f(x)\bigr)$|. \ Notice especially the\cutpar
+
+\bugonpage A349, second line from the bottom (7/8/92)
+
+\ninepoint\noindent
+expand to a ^\<number> en route to \TeX's
+``stomach''; |\multiply| wouldn't work, because\cutpar
+
+\bugonpage A358, bottom line (2/3/93)
+
+\ninepoint\noindent
+it is easy to define ^|\ldots| and ^|\cdots| macros that
+give the proper spacing in most\cutpar
+
+\bugonpage A370, lines 28 and 29 (9/1/92)
+
+\def\Russiantt#1{{\tt\hbox to.5em{\hss\eighttt\char#1\hss}}}
+\ninepoint\noindent
+example, if \TeX\ is implemented for
+a purely ^{Cyrillic} ^^{Russian} keyboard, the letter `\Russiantt5' should be
+assigned to code \oct{160} and `\Russiantt{`T}' to code \oct{164}, so that
+`\Russiantt5\Russiantt{`T}' still means `|pt|'; or else control\cutpar
+
+\bugonpage A377, lines 17--24 (5/4/92)
+
+\ninepoint
+\begintt
+\def\sanswitch{\let\n@xt\endsanity \ifx\next\endsanity
+ \else\ifcat\noexpand\next\stoken\aftergroup\space\let\n@xt=\eat
+ \else\ifcat\noexpand\next\bgroup\aftergroup{\let\n@xt=\eat
+ \else\ifcat\noexpand\next\egroup\aftergroup}\let\n@xt=\eat
+ \else\let\n@xt=\copytok\fi\fi\fi\fi \n@xt}
+\def\eat{\afterassignment\sanitize \let\next= }
+\long\def\copytok#1{\ifcat\noexpand#1\relax\aftergroup\noexpand\fi
+ \ifcat\noexpand#1\noexpand~\aftergroup\noexpand\fi
+\endtt
+
+\bugonpage A455, line 25 (2/26/93)
+
+\ninepoint\noindent
+rent language'' is set equal to |\language|. Whenever a
+character is added to the cur-\cutpar
+
+\bugonpage A459, second line of entry for ampersand (3/22/92)
+
+\eightpoint\indent\qquad
+{\it231--248}, $\underline{282}$, {\it339}, 344, 385--386, 428.
+
+\bugonpage A461, right column (2/19/93)
+
+\eightpoint
+\newbox\astbox \setbox\astbox=\hbox to0pt{\hss\lower1pt\hbox{*}}
+\def\prim#1{\par\indent\copy\astbox{\tt\char`\\#1}}
+\prim{chardef}, 44, 121, 155, 210, 214, 215, 271,\par
+\indent\qquad $\underline{277}$, 336, {\it343}, {\it345}, {\it356}, 452.\par
+\indent\<chardef token>, $\underline{271}$, 283, 286, 289.
+
+\bugonpage A467, left column (2/25/93)
+
+\eightpoint
+Greek, 127--128, 137, 156, 164, 319,\par
+\indent\qquad 358, 430, 434.
+
+\bugonpage A470, left column (2/25/93)
+
+\eightpoint
+margins, {\sl see\/} |\hoffset|, |\hsize|, |\narrower|.
+
+\bugonpage A471, left column (2/19/93)
+
+\eightpoint
+\prim{mathchardef}, 155, 199, 214, 215, 271,\par
+\indent\qquad 277, 289, 336, {\it358}, {\it394}.\par
+\indent\<mathchardef token>, $\underline{271}$, 289.
+
+\bugonpage A474, right column (3/22/92)
+
+\eightpoint
+pound sterling, 54, {\it339}, 428.
+
+\bugonpage A477, right column (3/22/92)
+
+\eightpoint
+sterling, 54, {\it339}, 428.
+
+\bugonpage A480, left column (4/9/92)
+
+\eightpoint
+\prim{unhbox}, 120, 283, $\underline{285}$, 293, {\it354}, {\it356},
+ {\it399}.\par
+\prim{unhcopy}, 120, 283, $\underline{285}$, 293, {\it353}.
+
+\bugonpage A481, left column (2/25/93)
+
+\eightpoint
+whatsits, 95, 110, 157, 226--229, 455.
+
+\bugonpage A483, lines 15--21 (2/25/93)
+
+{\tt P.O. Box 869\par
+Santa Barbara, CA 93102-0869 USA.\par
+|}|}
+\smallskip\noindent
+Don't delay, write today! That number again is
+
+\smallskip
+{\obeylines
+\TeX\ Users Group
+P.O. Box 869
+Santa Barbara, CA 93102-0869 USA.
+}
+
+ % volume B
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage B2, line 10 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$%
+{\tt This\]is\]TeX,\]Version\]3.1415\char'23}\quad
+$\{\,$printed when \TeX\ starts$\,\}$
+
+\bugonpage B89, line 12 (2/27/93)
+
+\tenpoint
+\noindent\hskip10pt
+In horizontal mode, the \\{prev\_graf} field is used for initial language data.
+
+\bugonpage B89, line 20 (2/27/93)
+
+\ninepoint
+\noindent\hskip20pt
+\\{pg\_field}, \\{ml\_field}: \\{integer}; \ \\{aux\_field}: \\{memory\_word};
+\par
+\noindent [Also delete the definitions of \\{lhmin} and \\{rhmin}, lines
+32 and 33.]
+
+\bugonpage B90, line 13 (2/27/93)
+
+\ninepoint
+\noindent\hskip10pt
+$\\{prev\_depth}\gets\\{ignore\_depth}$; \ $\\{mode\_line}\gets0$; \
+$\\{prev\_graf}\gets0$;
+
+\bugonpage B91, top three lines (2/27/93)
+
+\ninepoint
+\noindent\hskip20pt
+{\bf if\/} $m=\\{hmode}$ {\bf then if\/} $\\{nest}[p].\\{pg\_field}\ne
+ \oct{40600000}$ {\bf then}\par\noindent\hskip40pt
+{\bf begin} \\{print}({\tt\char`\"\](language\char`\"}); \
+ \\{print\_int}(\\{nest}[$p$].\\{pg\_field} {\bf mod} \oct{200000});\par
+\noindent\hskip40pt
+ \\{print}({\tt\char`\":hyphenmin\char`\"}); \
+ \\{print\_int}(\\{nest}[$p$].\\{pg\_field} {\bf div} \oct{20000000}); \
+ \\{print\_char}({\tt\char`\",\char`\"});\par\noindent\hskip40pt
+\\{print\_int}((\\{nest}[$p$].\\{pg\_field} {\bf div} \oct{200000})
+ {\bf mod} \oct{100}); \ \\{print\_char}({\tt\char`\")\char`\"});
+
+\bugonpage B344, lines 21 and 22 (2/27/93)
+
+\tenpoint\noindent\hskip10pt
+This code assumes that a \\{glue\_node} and a \\{penalty\_node} occupy the
+same number of \\{mem}~words.
+
+\bugonpage B344, line 30 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+$\\{link}(\\{tail})\gets\\{new\_param\_glue}(\\{par\_fill\_skip\_code})$; \
+ $\\{init\_cur\_lang}\gets\\{prev\_graf}$ {\bf mod} \oct{200000};\par
+\noindent\hskip10pt
+$\\{init\_l\_hyf}\gets\\{prev\_graf}$ {\bf div} \oct{20000000}; \
+$\\{init\_r\_hyf}\gets(\\{prev\_graf}$ {\bf div} \oct{200000}) {\bf mod}
+ \oct{100}; \
+\\{pop\_nest};
+
+\bugonpage B353, line 4 (2/27/93)
+
+\tenpoint\noindent\hskip10pt
+Kern nodes do not disappear at a line break unless they are \\{explicit}.
+
+\bugonpage B353, lines 15 and 16 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+\\{math\_node}: $\\{break\_width}[1]\gets\\{break\_width}[1]-\\{width}(s)$;\par
+\noindent\hskip20pt
+\\{kern\_node}: {\bf if\/} $\\{subtype}(s)\ne\\{explicit}$
+ {\bf then goto} \\{done}\par\noindent\hskip30pt
+{\bf else} $\\{break\_width}[1]\gets\\{break\_width}[1]-\\{width}(s)$;
+
+\bugonpage B354, lines 6 and 7 (2/27/93)
+
+\tenpoint\noindent
+will be the background
+plus $l_1$, so the length from \\{cur\_p} to \\{cur\_p} should be
+$\gamma+l_0+l_1-l$.
+If the post-break text of the discretionary is empty, a break may also
+discard~$q$; in that unusual case we subtract the length of~$q$ and any
+other nodes that will be discarded after the discretionary break.
+
+\bugonpage B354, line 18 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf begin} $\langle\,$Add the width of node $s$ to \\{break\_width}{\sevenrm
+ \kern.5em842}$\,\rangle$;
+
+\bugonpage B354, line 22 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf if\/} $\\{post\_break}(\\{cur\_p})=\\{null}$ {\bf then}
+ $s\gets\\{link}(v)$;\quad$\{\,$nodes may be discardable after the break$\,\}$
+
+\bugonpage B355, top line (2/27/93)
+
+\ninepoint\noindent
+{\tenbf842.\quad}$\langle\,$Add the width of node $s$ to
+ \\{break\_width}{\sevenrm\kern.5em842}$\,\rangle\equiv$
+
+\bugonpage B355, lines 9--14 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+$\\{hlist\_node},\\{vlist\_node},\\{rule\_node},\\{kern\_node}$:
+ $\\{break\_width}[1]\gets\\{break\_width}[1]+\\{width}(s)$;\par
+\noindent\hskip20pt
+{\bf othercases} \\{confusion}({\tt\char`\"disc2\char`\"})\par
+\noindent\hskip20pt
+{\bf endcases}
+
+\bugonpage B364, line 10 (2/27/93)
+
+\tenpoint\noindent
+a glue node, penalty node, explicit kern node, or math node.
+
+\bugonpage B366, line 11 from the bottom (2/27/93)
+
+\ninepoint\noindent
+\\{kern\_node}: {\bf if\/} $\\{subtype}(\\{cur\_p})=\\{explicit}$
+ {\bf then} \\{kern\_break}\par\noindent\hskip10pt
+{\bf else} $\\{act\_width}\gets\\{act\_width}+\\{width}(\\{cur\_p})$;
+
+\bugonpage B367, line 21 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf else if\/} \\{precedes\_break}(\\{prev\_p}) {\bf then}
+ $\\{try\_break}(0,\\{unhyphenated})$\par\noindent\hskip20pt
+{\bf else if\/} $(\\{type}(\\{prev\_p})=\\{kern\_node})\land
+ (\\{subtype}(\\{prev\_p})\ne\\{explicit})$ {\bf then}
+ $\\{try\_break}(0,\\{unhyphenated})$;
+
+\bugonpage B372, lines 12 and 13 (2/27/93)
+
+\ninepoint\noindent\hskip20pt
+{\bf if\/} $\\{type}(q)=\\{kern\_node}$ {\bf then}\par\noindent\hskip30pt
+{\bf if\/} $\\{subtype}(q)\ne\\{explicit}$ {\bf then goto} \\{done1};
+
+\bugonpage B376, line 3 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+$\\{cur\_lang}\gets\\{init\_cur\_lang}$; \
+$\\{l\_hyf}\gets\\{init\_l\_hyf}$; \
+$\\{r\_hyf}\gets\\{init\_r\_hyf}$;
+
+\bugonpage B377, lines 11 and 12 (2/27/93)
+
+\ninepoint\noindent
+$\\{cur\_lang},\\{init\_cur\_lang}$: \\{ASCII\_code};\quad
+ $\{\,$current hyphenation table of interest$\,\}$\par\noindent
+$\\{l\_hyf},\\{r\_hyf},\\{init\_l\_hyf},\\{init\_r\_hyf}$: \\{integer};\quad
+ $\{\,$limits on fragment sizes$\,\}$
+
+\bugonpage B378, line 5 from the bottom, overriding earlier change (2/27/93)
+
+\ninepoint\noindent\hskip30pt
+{\bf else if} $(\\{type}(s)=\\{kern\_node})\land(\\{subtype}(s)=\\{normal})$
+ {\bf then}\par\noindent\hskip50pt
+{\bf begin} $\\{hb}\gets s$; \ $\\{hyf\_bchar}\gets\\{font\_bchar}[\\{hf}]$; \
+ {\bf end}\par\noindent\hskip40pt
+{\bf else goto} \\{done3};
+
+
+\bugonpage B394, lines 12 and 13 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $n$: $0\to64$;\quad$\{\,$length of current word; not always
+ a \\{small\_number}$\,\}$\par\noindent\hskip20pt
+$j$: $0\to64$;\quad$\{\,$an index into \\{hc}$\,\}$
+
+\bugonpage B404, line 21 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+{\bf var} $k,l$: $0\to64$;\quad$\{\,$indices into \\{hc} and \\{hyf};
+ not always in \\{small\_number} range$\,\}$
+
+\bugonpage B460, lines 21 and 22 (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+\\{push\_nest}; \ $\\{mode}\gets\\{hmode}$; \ $\\{space\_factor}\gets1000$; \
+ \\{set\_cur\_lang}; \ $\\{clang}\gets\\{cur\_lang}$;\par\noindent\hskip10pt
+$\\{prev\_graf}\gets(\\{norm\_min}(\\{left\_hyphen\_min})\ast\oct{100}+
+ \\{norm\_min}(\\{right\_hyphen\_min}))\ast\oct{200000}+\\{cur\_lang}$;
+
+\bugonpage B492, line 6 from the bottom (2/27/93)
+
+\ninepoint\noindent\hskip10pt
+\\{unsave}; \ $\\{prev\_graf}\gets\\{prev\_graf}+3$;\par\noindent\hskip10pt
+\\{push\_nest}; \ $\\{mode}\gets\\{hmode}$; \ $\\{space\_factor}\gets1000$; \
+ \\{set\_cur\_lang}; \ $\\{clang}\gets\\{cur\_lang}$;\par\noindent\hskip10pt
+$\\{prev\_graf}\gets(\\{norm\_min}(\\{left\_hyphen\_min})\ast\oct{100}+
+ \\{norm\_min}(\\{right\_hyphen\_min}))\ast\oct{200000}+\\{cur\_lang}$;
+
+ % volume C
+\hsize=29pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+
+\bugonpage C151, line 11 from the bottom (6/26/93)
+
+\ninepoint\indent
+\qquad scaled $1.42(1+\max(-\\{pen\_lft},\\{pen\_rt},\\{pen\_top},
+ -\\{pen\_bot}))$
+
+\bugonpage C262, line 15 (6/26/93)
+
+\ninepoint\noindent
+|string base_name, base_version; base_name="plain"; base_version="2.71";|
+
+\bugonpage C262, line 29 (6/26/93)
+
+\ninepoint\noindent
+|def |^|gobble|| primary g = enddef; def |^|killtext|| text t = enddef;|
+
+\bugonpage C271, bottom line (6/26/93)
+
+\ninepoint\noindent
+| culldraw p enddef;|
+
+\bugonpage C272, three new lines for top of page (6/26/93)
+
+{\ninepoint\parindent=0pt
+|def |^|culldraw|| expr p = addto pic_ doublepath p.t_ withpen currentpen;|\par
+| cull pic_ dropping(-infinity,0) withweight default_wt_;|\par
+| addto_currentpicture also pic_; pic_:=nullpicture; killtext enddef;|\par
+}
+
+\bugonpage C272, replacement for former line 5 (6/26/93)
+
+\ninepoint\noindent
+| (cut_ scaled (1+max(-pen_lft,pen_rt,pen_top,-pen_bot))|
+
+\bugonpage C296, line 24 (2/3/93)
+
+\ninepoint\noindent
+the definition of |rp| is changed to `|]..tension 4..|',
+and if `|scaled|~|5pt|' is inserted\cutpar
+
+\bugonpage C299, line 3 (5/15/92)
+
+\ninepoint\noindent
+a Bernshte{\u\i}n polynomial of order $n-1$.)
+
+\bugonpage C347, left column (5/15/92)
+
+\eightpoint
+Bernshte{\u\i}n, Serge{\u\i} \thinspace Natanovich, 14.
+
+\bugonpage C348, left column (6/26/93)
+
+\eightpoint
+|culldraw|, {\it271}, $\underline{272}$.
+
+\bugonpage C350, left column (6/26/93)
+
+\eightpoint
+exponential, {\sl see\/} |mexp|.
+
+\bugonpage C352, left column (6/26/93)
+
+\eightpoint
+|killtext|, $\underline{262}$, {\it 272}.
+
+\bugonpage C352, right column (6/26/93)
+
+\eightpoint
+logarithm, {\sl see\/} |mlog|.
+
+\bugonpage C361, lines 14 and 15 (2/25/93)
+
+P.O. Box 869\par
+Santa Barbara, CA 93102-0869 USA.
+
+
+ % Volume D
+\hsize=35pc
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+
+\bugonpage D190, and subsequent pages (6/26/93)
+
+\noindent[Several changes to the code in sections 415, 416, 424, and 425
+were made to \MF\ version 2.71 in July~1991, too numerous to mention here.]
+
+\bugonpage D216, line 10 from the bottom (7/15/92)
+
+\tenpoint\noindent
+will be offset by $w_1$ or $w_2$, unless its slope drops to zero
+en route to the eighth octant; in the latter\cutpar
+
+\bugonpage D289, lines 9 and 10 (6/26/93)
+
+\ninepoint\noindent\hskip20pt
+$p\gets\\{dep\_list}(p)$; \ $r\gets\\{inf\_val}$;\par\noindent\hskip20pt
+{\bf repeat if\/} $\\{value}(\\{info}(p))\ge\\{value}(r)$ {\bf then}
+
+ % volume E
+\hsize=29pc
+\def\dashto{\mathrel{\hbox{-\kern-.05em}\mkern3.9mu\hbox{-\kern-.05em}}}
+
+
+ \bye
+
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errata9.tex b/Master/texmf-doc/doc/english/knuth/errata/errata9.tex
new file mode 100644
index 00000000000..3715cd813fc
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errata9.tex
@@ -0,0 +1,226 @@
+% Bugs (sigh) in Computers \& Typesetting
+
+\input manmac
+\font\sltt=cmsltt10
+\font\niness=cmss9
+\font\ninessi=cmssi9
+\proofmodefalse
+\raggedbottom
+\output{\hsize=29pc \onepageout{\unvbox255\kern-\dimen@ \vfil}}
+
+\def\today{\number\day\
+ \ifcase\month\or
+ Jan\or Feb\or Mar\or Apr\or May\or Jun\or
+ Jul\or Aug\or Sep\or Oct\or Nov\or Dec\fi
+ \ \number\year}
+
+\def\cutpar{{\parfillskip=0pt\par}}
+
+\def\rhead{Bugs in {\tensl Computers \& Typesetting A, 1996}}
+\def\bugonpage#1(#2) \par{\bigbreak\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Page #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\buginvol#1(#2) \par{\bigbreak\penalty-1000\tenpoint
+ \hrule width\hsize
+ \line{\lower3.5pt\vbox to13pt{}Volume #1\hfil(#2)}\hrule width\hsize
+ \nobreak\medskip}
+\def\slMF{{\manual 89:;}\-{\manual <=>:}} % slant the logo
+\def\0{\raise.7ex\hbox{$\scriptstyle\#$}}
+\newcount\nn
+\newdimen\nsize \newdimen\msize \newdimen\ninept \ninept=9pt
+\newbox\eqbox \setbox\eqbox=\hbox{\kern2pt\eightrm=\kern2pt}
+
+\tenpoint
+\noindent This is a list of all corrections made to {\sl Computers \&
+Typesetting}, Volume~A (also known as {\sl The \TeX book}),
+between 1992 and the publication of the final printed
+version of that book in September 1996.
+\looseness=-1
+
+ % volume A
+
+\bugonpage A31, line 8 (3/6/95)
+
+\tenpoint\noindent
+\TeX\ begins its error messages with `|!|', and it shows what it was
+reading at the\cutpar
+
+\bugonpage A46, line 8 (1/22/95)
+
+\ninepoint\noindent
+out for
+the occasional times when the adjacent characters |aa|, |ae|, and |o/|
+should not be\cutpar
+
+\bugonpage A282, lines 11 and 12 (4/18/96)
+
+\ninepoint\noindent
+unadorned \<box> command, except that the new box
+being appended to the vertical list is also shifted left or right by the
+specified amount.
+
+\bugonpage A285, lines 15--17 from the bottom (4/18/96)
+
+\ninepoint
+\textindent{$\bull$}|\raise|\<dimen>\<box>, |\lower|\<dimen>\<box>.\enskip
+This acts just like an unadorned \<box> command, except that the new box
+being appended to the horizontal list is also shifted up or down by the
+specified amount.
+
+\bugonpage A290, lines 4--6 from the bottom (4/18/96)
+
+\ninepoint
+\textindent{$\bull$}|\raise|\<dimen>\<box>, |\lower|\<dimen>\<box>.\enskip
+This acts just like an unadorned \<box> command, except that the new box
+being put into the nucleus is also shifted up or down by the specified amount.
+
+\bugonpage A331, bottom two lines (6/25/93)
+
+\ninepoint\noindent
+if you know that the
+enclosing box is sufficiently small; and |\leaders\vrule\vfill| works fine in
+vertical mode.
+
+\bugonpage A354, lines 19--22 (3/5/95)
+
+\ninepoint\noindent
+|\def\sett@b{\ifx\next\+\def\nxt{\afterassignment\s@tt@b\let\nxt}%|\par
+\noindent
+| \else\let\nxt=\s@tcols\fi|\par\noindent
+| \let\next=\relax \nxt} % turn off \outerness|\par\noindent
+|\def\s@tt@b{\let\nxt=\relax \us@false\m@ketabbox}|
+
+\bugonpage A356, lines 13--20 from the bottom (3/5/95)
+
+\ninepoint
+{\parindent=0pt
+|\def\oalign#1{\leavevmode\vtop{\baselineskip0pt \lineskip.25ex|\par
+| \ialign{##\crcr#1\crcr}}} \def\o@lign{\lineskiplimit=0pt \oalign}|\par
+|\def\ooalign{\lineskiplimit=-\maxdimen \oalign} % chars over each other|\par
+|\def\sh@ft#1{\dimen0=.00#1ex \multiply\dimen0 by\fontdimen1\font|\par
+| \kern-.0156\dimen0} % compensate for slant in lowered accents|\par
+|\def|^|\d||#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{10}.\hidewidth}}}|\par
+|\def|^|\b||#1{{\o@lign{\relax#1\crcr\hidewidth\sh@ft{29}%|\par
+| \vbox to.2ex{\hbox{\char'26}\vss}\hidewidth}}}|\par
+}
+
+\bugonpage A357, lines 7--12 (8/1/95)
+
+\ninepoint\noindent
+|\def|^|\rightarrowfill||{$\m@th \smash- \mkern-7mu|\par\noindent
+| \cleaders\hbox{$\mkern-2mu \smash- \mkern-2mu$}\hfill|\par\noindent
+| \mkern-7mu \mathord\rightarrow$}|\par\noindent
+|\def|^|\leftarrowfill|%
+ |{$\m@th \mathord\leftarrow \mkern-7mu|\par\noindent
+| \cleaders\hbox{$\mkern-2mu \smash- \mkern-2mu$}\hfill|\par\noindent
+| \mkern-7mu \smash-$}|
+
+\bugonpage A357, lines 16--20 (6/25/93)
+
+\ninepoint
+{\parindent=0pt
+| \setbox0=\hbox{$\braceld$}%|\par
+| \bracelu\leaders\vrule height\ht0 depth0pt\hfill\bracerd|\par
+| \braceld\leaders\vrule height\ht0 depth0pt\hfill\braceru$}|\par
+|\def|^|\downbracefill||{$\m@th|\par
+| \setbox0=\hbox{$\braceld$}%|\par
+| \braceld\leaders\vrule height\ht0 depth0pt\hfill\braceru|\par
+| \bracelu\leaders\vrule height\ht0 depth0pt\hfill\bracerd$}|\par
+\smallskip[Also delete lines 21 and 22, as the usage is no longer restricted.]
+}
+
+\bugonpage A359, line 25 (3/5/95)
+
+\ninepoint\noindent
+|\def|^|\skew||#1#2#3{{\muskip0=#1mu \mkern.5\muskip0|\par\noindent
+| #2{\mkern-.5\muskip0{#3}\mkern.5\muskip0}\mkern-.5\muskip0}{}}|
+
+\bugonpage A360, line 5 from the bottom (3/5/95)
+
+\ninepoint\noindent
+|\def\@vereq#1#2{\lower.5pt\vbox{\lineskiplimit\maxdimen \lineskip-.5pt|
+
+\bugonpage A361, lines 19 and 20 (3/5/95)
+
+\ninepoint\noindent
+|\def|^|\bmod||{\nonscript\mskip-\medmuskip \mkern5mu|\par\noindent
+| |^|\mathbin||{\rm mod} \penalty900 \mkern5mu \nonscript\mskip-\medmuskip}|
+
+\bugonpage A362, lines 14--18 (3/5/95)
+
+\ninepoint\noindent
+| |^|\everycr||{\noalign{\ifdt@p \global\dt@pfalse|%
+ | \ifdim\prevdepth>-1000pt|\par\noindent
+| \vskip-\lineskiplimit \vskip\normallineskiplimit \fi|\par\noindent
+| \else \penalty|^|\interdisplaylinepenalty|| \fi}}}|\par\noindent
+|\def\@lign{\tabskip=0pt\everycr={}} % restore inside \displ@y|\par\noindent
+|\def|^|\displaylines||#1{\displ@y \tabskip=0pt|
+
+\bugonpage A363, lines 8--9 from the bottom (12/8/89)
+
+{\ninepoint\parindent=0pt
+| \if@mid \dimen@=\ht0 \advance\dimen@ by\dp\z@ |%
+ |\advance\dimen@ by12\p@|\parbreak%
+| \advance\dimen@ by\pagetotal \advance\dimen@ by-\pageshrink|
+\par}
+
+\bugonpage A364, line 5 from the bottom (4/11/96)
+
+\ninepoint\noindent
+|\def\fmtname{plain}|\par\noindent
+|\def\fmtversion{3.141592} % identifies the current format|
+
+\bugonpage A374, line 3 (3/7/95)
+
+\ninepoint\indent
+|\begingroup\aftergroup\def\aftergroup\asts\aftergroup{|
+
+\bugonpage A410, line 23 (4/18/96)
+
+\ninepoint\noindent
+| Tema con variazione \(su un tema differente)|
+\smallskip\eightpoint\noindent
+(This implies a corresponding correction to page 411.)
+
+\bugonpage A451, line $16$ (8/8/93)
+
+\ninepoint\noindent
+But when plain \TeX\ is tried on the name of a famous ^{Welsh} village,
+
+\bugonpage A462, right column (3/5/95)
+
+\def\cong{\mathrel{\mathpalette\OvOreq\sim}} % congruence sign, index version
+\def\OvOreq#1#2{\lower.5pt\vbox{\baselineskip0pt\lineskip-.0pt
+ \ialign{$#1\hfil##\hfil$\crcr#2\crcr=\crcr}}}
+\eightpoint
+|\cong| ( $\cong$ ), 151, $\underline{360}$, 436.
+
+\bugonpage A463, right column (6/25/93)
+
+\eightpoint
+direct sum, {\sl see\/} |\oplus|.
+
+\bugonpage A464, left column (6/25/93)
+
+\eightpoint
+|\downbracefill| (\hbox to 4em{\downbracefill}), 225--226, $\underline{357}$.
+
+\bugonpage A483, lines 15--21 (4/29/97)
+
+\tenpoint
+\begintt
+email: {\tt TUG@tug.org}
+internet: {\tt http://www.tug.org/}
+}
+\endtt
+Don't delay, subscribe today! That address again is
+
+\smallskip
+{\obeylines
+\TeX\ Users Group
+email: {\tt TUG\char`\@ tug.org}
+internet: {\tt http://www.tug.org/}
+}
+
+\bye
diff --git a/Master/texmf-doc/doc/english/knuth/errata/errorlog.tex b/Master/texmf-doc/doc/english/knuth/errata/errorlog.tex
new file mode 100644
index 00000000000..dc4845c1c19
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/errorlog.tex
@@ -0,0 +1,2924 @@
+% Appendix to the Errors of TeX paper (updated)
+% Section numbers now adjusted to TeX 3.0 equivalents
+% NB: tab marks are significant in this file, they signal continuation lines
+%\magnification=\magstephalf
+%\pageno=35
+\input logmac
+* 10 Mar 1978
+L1. Rename a few external variables to make their first six letters unique.
+D2. Initialize \\{escape_char} to $-1$, not 0 [it will be set to the
+ first character input]. @240
+L3. Fix bug: The test `$\\{id}<\O{200}$' was supposed to distinguish one-letter
+ identifiers from longer (packed) ones, but negative values of
+ \\{id} also pass this test. @356
+B4. Fix bug: I wrote `{\bf while} $\alpha\land(\beta\lor\gamma)$' when I meant
+ `{\bf while} $(\alpha\land\beta)\lor\gamma$'. @259
+R5. Initialize the input routines in |INITEX| [at this time a short,
+ separate program not under user control], in case errors occur. @1337
+E6. Don't initialize \\{mem} in |INITEX|, it wastes time. @164
+B7. Change `\\{new_line}' [which denotes a lexical scanning state] to
+ `\\{next_line}' [which denotes
+ \\{carriage_return} and \\{line_feed}] in print commands.
+F8. Include additional test `$\\{mem}[p] \ne 0\; \land$' in \\{check_mem}. @168
+M9. Fix inconsistency between the \\{eq_level} conventions of \\{macro_def} and
+ \\{eq_define}. @277
+# About six hours of debugging time today.
+# |INITEX| appears to work,
+ and the test routine got through \\{start_input},
+ \\{chcode} [the \TeX78 command for assigning a \\{cat_code}],
+ \\{get_next}, and \\{back_input} the first time.
+* 11 Mar 1978
+I10. Insert space before `|(|' on terminal when opening a new file. @537
+F11. Put `$p\gets \\{link}(p)$' into the loop of \\{show_token_list},
+ so that it doesn't loop forever. @292
+L12. Shift the last item found by \\{scan_toks} into the \\{info} field.
+ [With |SAIL| all packing of fields was done by arithmetic operations,
+ not by the compiler.] @474
+B13\>12. Fix the previous bugfix: I shifted by the wrong amount. @474
+I14. Add a feature that prints a warning when the end of a file page occurs within
+ a macro definition or call. [System dependent.] @336
+# Unintended bugs in my test routine [a format intended eventually to typeset
+ {\sl The Art of Computer Programming\/}] helped check out the
+ error recovery mechanisms.
+ For example, I had `|\lft{#}|' instead of `|\lft{##}|' inside a macro,
+ and three cases of improper |{|~and~|}| nesting.
+F15. Add the forgotten case `\\{set_font}:' to \\{eq_destroy}. @275
+C16. Change |\require| to |\input|. @376
+F17. Add code for the case $\\{cur_cmd}=0$ [later known as the case
+ `$\,t\ge\\{cs_token_flag}$'] when scanning a tokenlist. @357
+# That's the first ``big'' error I've spotted so far.
+I18. Introduce a `|d|' option in the error routine, to facilitate debugging. @84
+L19. Assign a floating-point constant \\{ignore_depth} to \\{prev_depth},
+ instead of assigning the integer constant \\{flag}
+ [since \\{prev_depth} is type \\{real} in \TeX78]. @215
+I20. Improve the readability and spacing of \\{show_node_list} output. @182,187
+F21. Set the variable $v$ before using the {\bf case} construction in
+ \\{show_node_list}, because there's one case where $v$
+ didn't receive a value [as part of the field unpacking]. @182
+# About seven hours today.
+* 12 Mar 1978
+# One hour to enter yesterday's corrections and recompile.
+# At this point \TeX\ correctly located further unintended syntax errors
+ in |acphdr| [the test file].
+I22. Insert \\{debug_help} into \\{succumb}, giving a chance to look at memory
+ before the system dies. @93
+D23. Use \\{eq_destroy} wherever necessary in \\{unsave}. @283
+L24. Change `$t \gets (t-1)$ mod 8' to `$t \gets (t-1)$ land~7' in \\{id_name},
+ since |SAIL| has $-1$~mod~$8 = -1$. [At this time, \\{id_name} is a
+ routine that unpacks control sequence names, according to a scheme
+ that will become obsolete after change \#422.]
+S25. Remove the space that appears at end of paragraph.
+ (I hadn't anticipated that.) @816
+L26. Throw away unwanted \\{line_feed} after getting a \\{carriage_return}
+ in response to \\{in_chr_w} [a system routine for
+ input from the terminal]. @83
+B27. Delete spurious call to \\{flush_list} in \\{end_token_list}. @324
+# Why did I make such a silly mistake?
+F28. Fix bug in \\{get_x_token}: I forgot to say `\\{macro_call}' (which is the
+ main point of that routine)! @380
+# While tracking that bug down, I found out incidentally that kerning is okay.
+# Also \TeX\ correctly caught an error |0p| for |0pt|.
+L29. Fix bug in \\{scan_spec} ({\bf while} instead of {\bf repeat}). @404
+M30. Make the table entries for |\hfill| and |\hskip| consistent with the
+ program conventions. @1058
+L31. Disable unforeseen coercion: When \\{scan_spec} put \\{hsize} on
+ \\{save_stack}, the value changed from \\{real} to \\{integer}. @645
+I32. Use `|*|' instead of `|-1.0|' for running dimensions
+ of rules in \\{show_node_list}. @176
+D33. Clear \\{mem}[\\{head}] to null in \\{push_nest} [in \TeX82, this
+ will be done by \\{get_avail}]. @216
+# A vrule link got clobbered because I forgot to do this.
+I34. Translate ASCII control codes to special form when displaying them. @48,68
+# Ligatures work, but \\{show_node_list} showed them funny.
+F35. Remember to clear parameters off \\{save_stack} in \\{package} routine. @1086
+# About eight hours today.
+* 13 Mar 1978
+D36. Introduce a new variable \\{hang_first} [later the sign of \\{hang_after}]. @849
+E37\>36. Simplify the new code, realizing that if $\\{hang_indent}=0$ then
+ \\{hang_first} is irrelevant. @848
+# Time sharing is very slow today, so I'm mostly reading technical reports while
+ waiting\/ {\bf three hours} for compiler, editor, and loading routine.
+# I'm not counting this as debugging time!
+# (Came back in the evening.)
+P38. Spruce up the comments in the \\{line_break} routine, which appears to be
+ almost working. @813
+D39. Rethink the setting of \\{best_line}; it's 1 too high in many cases.
+ [The final line of a paragraph was handled in a treacherous way.] @874
+D40. Compute proper initialization for
+ \\{prev_depth} when beginning an |\hbox|
+ with a paragraph inside. [This refers to a special `paragraph box'
+ construction, used when an hbox of specified size becomes overfull;
+ \TeX78 doesn't have the concept of internal vertical mode.] @1083
+D41. Also initialize \\{tail} in that case. @1083
+M42. Also put the result of line-breaking into the correct list.
+T43. Fix a typo in the \\{free_node} routine (`\\{link}' not `\\{llink}');
+ by strange chance it had been harmless until today. @130
+F44. Fix bug: \\{post_line_break} forgot to set \\{adjust_tail}. @889
+D45. Update \\{act_width} properly when looking for end of word while
+ line breaking. @866
+B46. Repair the ``tricky'' part of \\{get_node}: I used the \\{info} field
+ when I meant to say \\{llink}. @127
+# Now the |\corners| macro of |acphdr| works! [See |\setcornerrules|
+ in {\sl The \TeX book}, page 417.]
+D47. Reset \\{contrib_tail} properly in \\{build_page}. @995
+T48. Fix typo (|-| for |+|) in computation of \\{page_total}. @1004
+S49. Change the page-breaking logic: \TeX\ reached \\{fire_up} with
+ $\\{best_page_break}=\\{null}$ in one case,
+ since the badness was too bad. @1005
+M50. Perform the operation \\{delete_token_ref}(\\{top_mark}) only when
+ $\\{top_mark}\ne0$. @1012
+F51. Make \\{scan_toks} omit the initial |{| of an |\output| routine. @473
+I52. Insert a comma to make memory usage statistics look better. @639
+# About seven good hours of debugging today.
+# Tomorrow will be first-output day (I hope).
+* 14 Mar 1978
+# (Came in evening after sleeping most of day, to get computer at better time.)
+# (Some day we will have personal computers and will live more normally.)
+# 8:30pm, began to enter corrections to yesterday's problems.
+I53. Issue an error message for non-character in filename or in font name. @771
+I54. Display `|...|' for omitted stuff in \\{show_context} routine. @643
+L55. Watch out for the |SAIL| syntax `$\alpha+\beta\mathbin{\rm lsh}\gamma$';
+ it doesn't shift $\alpha+\beta$ left (only $\beta$). @464
+# That error was very hard to track down; it created a spurious link field
+ and sent $\\{hash}[0]=\null$|\beta| to the scanner!
+# I could have found this bug an hour sooner if I had looked at the correct
+ stack entries for \\{name} and \\{token_type}.
+D56. Show the correct page number when tracing pages before output is shipped. @638
+F57. Remember to nullify a box after using it. @1079
+I58. Issue an error message if\/ |\box255| isn't consumed by the output routine. @1015
+# I'm having trouble with the |BAIL| debugger;
+ it makes an illegal memory reference and dies,
+ when single-stepping past the entry to recursive procedures
+ \\{hlist_out} and \\{vlist_out}. So I have to reload and be careful
+ to go thru these procedures at high speed.
+P59. Fix bug in comment (memory parameter description said $\ge$ not $\le$). @11
+B60. Fix typo in definition of rule output (said $x,y$ not $\\{x0},\\{y0}$).
+ [This part of the code went away when |DVI| files were introduced.]
+B61. Correct the embarrassing bug in shellsort, where I said `$\le\\{str}[k]$'
+ not `$\le t$'.
+ [The first \TeX\ had to sort all output by vertical position on page.]
+M62. Make \\{start_input} set up \\{job_name} in the form needed by \\{shipout};
+ it uses obsolete conventions. @532,537
+L63. Insert |(| and |)| into the |SAIL| macro definition of \\{new_string}.
+ [This macro was for pre-|DVI| output.]
+M64. Unscramble the parameters of \\{out_rule}:
+ The declaration was $(\\{x0},\\{y0},\\{x1},\\{y1})$
+ while the call was $(\\{x0},\\{x1},\\{y0},\\{y1})$.
+# 4:30am, \TeX's first page is successfully output!
+# (It was `|\titlepage\setcpage1\corners\eject\end|'.)
+* 15 Mar 1978
+# 10:30pm. Today I'm instrumenting the line-breaking routine and putting it
+ through a bunch of tests.
+# (The inserted instrumentation had bugs that won't be mentioned here.)
+C65. Don't abort the job when \\{eq_destroy} redefines a
+ \TeX\ control sequence. @275
+# The first word of a paragraph won't be hyphenated \dots\ so be it!
+T66. Fix the typo in \\{line_break} that spoils the test for
+ `letters in the same font'. @896
+# The effect of that typo was to suppress all hyphenation attempts.
+B67\>25. Replace the space at paragraph end by fillglue, not by zero. @816
+L68. Pack the hyphen character properly into its node. @582
+T69. Fix a typo (`{\tentex\char'30}' for `|+|')
+ in the computation of \\{break_width}. @838
+M70. Change the |\end| maneuver; the present code doesn't end the job,
+ since I forgot that \\{back_input} uses \\{cur_tok}. @1054
+A71. Add a parameter to \\{try_break}, since the width is different at
+ a discretionary hyphen. [This problem will be solved differently in \TeX82,
+ when discretionaries become much more general.] @840
+F72. Bypass kern nodes in pre-hyphenation. @896
+F73. Supply code for the forgotten case `$<$ |"a"|' in pre-hyphenation.
+ [This case was later generalized to a test of \\{lc_code}.] @897
+B74. Change $\\{mem}[q]$ to $\\{prev_break}(q)$ in the
+ reverse-linking loop. @878
+# (Such blunders. Am I getting feeble-minded?)
+A75. Introduce special logic for \\{eject_penalty}; I was wrong
+ to think that forced ejection was exactly like an
+ infinitely negative penalty. @851
+A76. Use $(1+b)^2-p^2$ when computing demerits with $p<0$. @859
+# 6:30am. The line-breaking algorithm appears to be working fine
+ and efficiently.
+ On small measures (about 20 characters per line), it gives overfull boxes
+ instead of spaced out ones. Surprising but satisfactory.
+* 16 Mar 1978
+# 9pm. The plan for tonight is to test page breaking and more paragraphing.
+G77. Insert `|\topskip|' glue at beginning of page. @1001
+I78. Add `|\pausing|' feature. @363
+M79. Fix discrepancy: In \\{make_accent} I called \\{vpackage}
+ with a pointer to the first list item, but \\{vpackage} itself assumes
+ that the parameter is a pointer to that pointer. [The
+ \\{vpackage} of \TeX82 will be different.] @668
+# I checked for other lapses like that. Result: 14 calls OK, 12 NG.
+M80. Create a new temporary list head location, \\{hold_head}, since there's
+ a case where \\{vpackage} is improperly called with
+ parameter \\{temp_head}. [At this time \\{vpackage} uses \\{temp_head}
+ to make a list of all insertions found.] @1014
+# 11:30pm. The machine is tied up again.
+F81. Write code to handle charnodes in vlists; I forgot that I'd decided
+ to allow them. [Later I prohibited them again!] @669
+F82. Combine the page lists before pruning off glue
+ in \\{fire_up}; otherwise the pruning doesn't go far enough. @1017
+B83\>25. Fix typo where line-breaking starts: `\\{fill_glue}' should be
+ `\\{new_glue}(\\{fill_glue})'. @816
+I84. Add |/q| to |xspool| command (cosmetic change). [This changes a system
+ command that causes \TeX\ output to be printed on the Xerox Graphics
+ Printer (XGP), the progenitor of future laser printers;
+ the |/q| option says that the queue of printing requests should be
+ displayed on the user's terminal.] @642
+E85. Don't write a form feed after the last page of output. @642
+# To fix this, I reorganized \\{ship_out}, and it became simpler.
+T86. Correct a typo (`{\tentex\char'30}' for `|+|') in the \\{vlist_node} case
+ within \\{hlist_out}. [The output routines were quite different
+ at this time, because output went directly to the XGP.] @622
+I87. Change the message `|completed page|' to `|Completed for page|'. @638
+B88\>48. Fix yet another typo in the computation of \\{page_total}: My original
+ code said $\\{stretch}(p)$ instead of $\\{stretch}(q)$ (terrible). @1004
+P89. Document the dirty trick about \\{bot_mark}'s reference count.
+ [That trick is, fortunately, no longer useful.] @1016
+A90. Rethink the algorithm for contributing an insertion: The original code
+ tests for a page break after incrementing the totals but
+ before the \\{contrib_list} is updated. [\TeX78 handles insertions
+ in a hardwired manner that will be greatly generalized in \TeX82.]
+F91. Fix \\{get_node} again:
+ After the variable memory overflows, control falls through to \\{found}
+ instead of going to the \\{overflow} call. @125
+# I spent several hours tracking down that data structure bug!
+B92. Change \\{new_line} to \\{next_line} in yet another print command (see \#7).
+A93\>75. Amend the line-breaking algorithm:
+ |\break| in paragraph doesn't work with really bad breaks. @851
+# A problem to be diagnosed tomorrow: Each time I run the test program,
+ the amount of memory in use grows by 13 cells not returned.
+# Seven hours tonight.
+* 17 Mar 1978
+G94. Introduce \\{dead_cycles} to keep |\end| active until \\{ship_out}
+ occurs. @1054
+E95. Don't call \\{line_break} with an empty list. @1096
+S96. Take proper account of the (infinite) fillglue when computing
+ the width of a paragraph line preceding a display. @1146
+M97. Add a new parameter to \\{hpack} so that \\{line_break} won't be called
+ at the wrong time.
+ [This is for the soon-to-be-obsolete feature described in \#40.]
+L98. Give a warning message if there's an |\hfill| in the middle of a paragraph;
+ fillglue upsets the line breaker,
+ because floating-point calculations don't have sufficient accuracy. @868
+# I spent an hour looking for another bug in \TeX, but the following one was in \MF:
+ The \\{xgp_height} data in fonts had been supplied wrong.
+# It took two hours to recompile 32 fonts with proto-\MF.
+R99. Make \\{show_node_list} and \\{show_token_list}
+ more robust in the presence of software bugs. @182
+D100\>97. Do not remove nodes with \\{eject_penalty},
+ when the new parameter to \\{hpack} is \\{true}.
+E101\>97. Put a fast exit into \\{hpack}; e.g., at glue nodes, test `{\bf if}
+ \\{paragraphing} $\land$ $\langle$current width is large$\rangle$'.
+# 2am. I have to go to bed ``early'' tonight.
+* 18 Mar 1978
+# 3:30pm. (Saturday)
+I102. Add a parameter to \\{check_mem} (to suppress display unless needed). @167
+G103. Introduce a user-settable parameter |\maxdepth|, and
+ pass it as a parameter to \\{vpackage}. @668
+# I realized the need for |\maxdepth| while fixing insertions (see \#90).
+G104. Introduce a user-settable parameter for \\{line_break}: The constant
+ 2.0 in my original algorithm becomes |\jpar|
+ [later |\tolerance|], to be set like |\tracing|. @828
+D105. Reclaim the \\{eject_penalty} nodes removed during line-breaking. @879
+# (Those were the 13 extra nodes reported on Thursday.)
+# The \\{init_align} procedure worked right the first time!
+# Also \\{init_row}, \\{init_col}. But then\thinspace\dots
+S106. Rethink the command codes: \\{endv} in a token list has too high a
+ code for the assumptions of \\{get_next}. @207
+A107. Add a \\{prev_cmd} variable for processing delimited macro parameters;
+ the original algorithm loses track of braces.
+ [The rules will change slightly in \TeX82, and
+ \\{rbrace_ptr} will take on a similar function.] @400
+S108. Make the \\{get_next} routine intercept |&| and |\cr| tokens. @342
+# I'd thought I could just put |&| and |\cr| into
+ \\{big_switch} [i.e., in the stomach of \TeX, not the eyes];
+ that was a great big mistake.
+R109. Make more error checks on \\{endv}; e.g., it must not occur in
+ a macro definition or call. @780
+S110\>108. No, rethink alignments again; the new program still fails! @768
+# For the first time I can glimpse the
+ hairiness of alignment in general (e.g., `|\halign{\u#\v&...|'
+ when |\u| and |\v| are defined to include |&|'s and possible
+ alignments themselves).
+# I think there's a ``simple'' solution, by considering only whether
+ an alignment is currently active [in \S342].
+# 11:30pm. Went to bed.
+* 19 Mar 1978
+# Woke up with ``better'' idea on how to handle |&| and |\cr|.
+# (Namely, to consider a special kind of\/ |\def| whose parameters don't interrupt
+ on |&|'s and |\cr|'s.)
+# But replaced this by a much better idea (to introduce \\{align_state}).
+# 11pm. Began to use computer. Performed major surgery
+ (inserting \\{align_state} and updating the associated routines
+ and documentation).
+D111. Pop the alignment stacks in \\{fin_align}. @800
+T112\>110. Fix a (newly inserted) typo in \\{show_context}. @314
+D113\>110. Set \\{align_state} false when a live |&| or |\cr| is found.
+ [Originally \\{align_state} was of type \\{boolean}.] @789
+I114. Insert |\cr| when `|}|' occurs prematurely in an alignment. @1132
+M115. Remember to record \\{glue_stretch} when packaging an unset node. @796
+# I had a mistake in |acphdr| definition of\/ |\quoteformat|; also extra spaces.
+# My first test programs, used before today, were contrived to test macro
+ expansion, line-breaking, and page layout.
+# Next I'm using a test program based on Volume 2.
+C116. Make carriage-return, space, and tab equivalent for macro matching. @348
+F117. Omit the reference count node when displaying a mark. @176
+B118. Correct a silly slip: I wrote `\\{type_displacement}' instead of
+ `\\{value_displacement}' when packing data in a penalty node. @158
+M119. Don't go to \\{build_page} after seeing |\noindent|; \TeX\ isn't
+ ready for that.
+ [In the original program, this was an instance of a bad {\bf goto}.] @1091
+# I had undesired spaces coming thru the scanner in my macro definitions
+ of\/ |\tenpoint| [see {\sl The \TeX book}, page 414].
+# 4am. \TeX\ now knows enough to typeset page 1 of Volume 2!
+# Also it did its first ``math formula'' (namely `|$X$|') without crucial error.
+# (Except that the italic correction was missing for some reason.)
+D120. Remember to decrement \\{cur_level} in \\{fin_align}. [The routines will
+ eventually become more general and use \\{unsave} here.] @800
+D121. Remember to increment \\{cur_level} in error corrections by
+ \\{handle_right_brace}. [A better procedure will be adopted later.] @1069
+T122. Fix a typo: (`|{|' instead of `|}|') in error message for $\\{mmode}+
+ \\{math_shift}$. @1065
+R123\>99. Make \\{show_noad_list} more robust and more like the new
+ \\{show_node_list}. [The routines will be combined in \TeX82.] @690
+L124. Fix a typo in \\{char_box}: should say \\{font_info_real}.
+ [In \TeX78 a single array
+ is used for both \\{real} and \\{integer}; in \TeX82 things will be
+ \\{scaled}.] @554
+B125. Fix typos in the definitions of \\{default_rule_thickness} and
+ \\{big_op_spacing}; they shouldn't start at \\{mathex}(7). @701
+B126. Reverse the \\{before} and \\{after} conventions in math nodes. @1196
+# I had them backwards; this turned
+ hyphenation on just before math, and off just after it!
+# Seven and a half hours debugging today.
+ Got through the test program a little more.
+ But \TeX\ blew up on `|$Y+1$|'; tomorrow I hope to find out why.
+* 20 Mar 1978
+# 8pm. I decided to work next on a super-hairy formula.
+C127. Change `|\ascii|' to `|\cc|' (character code). [This name will change again
+ later, to `|\char|'.] @265
+E128. Don't bother to store a penalty node at the beginning of |$$| when
+ the paragraph-so-far fits on a single line, since such a penalty
+ has already been stored. [These conventions will change later, and
+ the |\predisplaypenalty| will always be stored.] @1203
+S129. Avoid reference to \\{tail} in \\{build_page},
+ if $\\{nest_ptr}>0$. @995
+B130. Correct a silly
+ slip in \\{math_comp} (the exact opposite of what I did in \#118). @1158
+B131. Rectify my mental lapse in \\{make_fraction}; I said \\{nucleus} instead of
+ \\{thickness}. @743
+F132. Mask off the math class when scanning delimiters. @1160
+C133. Allow an optional space after |\def{...}|. [This decision
+ will be retracted later.] @473
+# My test example is so complicated it causes the semantic stacks to overflow!
+L134. Don't test for no pages output by looking at the channel status. @642
+T135. Fix typo in definition of\/ |\mathop| (\\{open_noad} not \\{op_noad}). @1156
+A136. Rewrite \\{fin_mlist}, because `|\left(...\above...\right)|' doesn't
+ parse correctly; the |\left| goes into the numerator,
+ the |\right| into the denominator. @1184
+B137. Correct the use of \\{depth_threshold} in \\{print_subsidiary_data}:
+ Simple fields get shown while others look empty. @692
+I138\>78. Return the carriage before showing the first line of a new file
+ when pausing. @538
+M139. Fix bug: The call \\{show_noad_list}(\\{mem}[|..|]) should be
+ \\{show_noad_list}(|..|), in the \\{incompleat_noad} case
+ of \\{show_activities}. @219
+# 3am. The whole messy formula has been parsed correctly into a tree.
+# The easy part is done, now comes the harder part.
+F140. Don't shift single characters down in \\{make_op}. @749
+D141. Make \\{clean_box} return a box (as its name implies), not an hlist. @720
+# Font info still isn't quite right, it has the wrong value of \\{quad}.
+A142. Retain the italic correction when doing \\{rebox};
+ can make $\\{glue_set}\ne0$ a flag for this. [A better
+ solution will be adopted later.] @715
+B143. Fix the bug that makes \\{rebox} bomb out: $\\{value}(p)$ should be
+ $\\{value}(\\{mem}[p])$. @715
+# 6am; ten hours today. \TeX\ didn't do |$\pi\over2$| correctly, but was close.
+# I found that the \\{rebox} problem (\#142) went away when I fixed the
+ \\{clean_box} problem (\#141); but I
+ will leave the extra stuff about $\\{glue_set} \ne 0$
+ in the program anyway, just for weird cases.
+E144. Omit extra levels of boxing when possible in \\{clean_box}. @721
+# (To do this, I need to face the \\{rebox} problem anyway.)
+* 21 Mar 1978
+# 10pm. The computer is rather heavily loaded tonight.
+F145. Don't forget \\{thickness} when making a square-root sign (see \#131).
+ [The rule thickness will later be derived from the character height.] @737
+L146. Define $p$ local to the \\{make_fraction} routine. @743
+# Unwittingly using the global $p$ was a disaster.
+I147. Don't show the amount of \\{glue_set} when it's zero. @186
+D148\>142. Make \\{glue_set} nonzero in the result of \\{var_delimiter}. @706
+F149. Fix bug: The \\{math_glue} function didn't return any result. @716
+T150. Fix typo in \\{char_box} ($c$ not $w$); this caused a subscripted~$P$ to come
+ out the same width as an unsubscripted~$P$. [Later changes in the rules
+ will move this computation to \S755.] @709
+P151\>144. Revise \\{clean_box} to do operations that are needed
+ often because of the \\{rebox} change. @720
+D152. Use the new \\{clean_box} to avoid a bug in |\sqrt{\raise...}|. @737
+Q153. Change the definition of\/ |\not| so that it's a relation
+ (which will butt against the following relation). [All math
+ symbols and Greek letters are defined in |INITEX| at this
+ time, not in a changeable format definition.]
+I154. Give error message `{\tt Large delimiter must be
+ in mathex font}', instead of calling \\{confusion},
+ since the error can occur.
+ [This particular error is impossible in \TeX82.] @706
+F155. Change the use of $p$ in \\{var_delimiter}; it isn't always set when I say
+ {\bf goto} \\{found}. @706
+# Another font problem now surfaced: The mathex meta-font didn't compute \TeX\ info
+ in a machine-independent way.
+ (It took two hours to correct this.)
+D156. Don't forget to set $\\{type}(b)$ in all relevant cases of
+ \\{var_delimiter}. @708
+B157. Use the correct sign convention for \\{shift_amount} in \\{hpackage}. @653
+F158. Always kern by \\{delta} when there's no superscript. @755
+M159. Declare \\{space_table} to be $[0\,.\,.\,6,0\,.\,.\,6]$
+ not $[0\,.\,.\,7,0\,.\,.\,7]$; otherwise its entries are
+ pre\-loaded into the wrong positions. [The \\{space_table} in \TeX78 is
+ $7\times7$; it will become $8\times8$ in \TeX82,
+ represented as a string called \\{math_spacing}.] @764
+C160. Use a negative value, not zero, to represent a null delimiter.
+ [Actually zero will come back again later.] @685
+C161\>127. Change |\cc| to |\char|. @265
+L162. Don't use tricky subtraction on packed data when changing $q$ to
+ an \\{ord_noad} in \\{mlist_to_hlist}; subtraction isn't always safe. @729
+B163. Fix two typos in the \\{space_table} (|*| for |0|). @764
+F164. Initialize \\{cur_size} everywhere (I forgot it in two places). @703
+A165. Reset \\{op_noad} before resetting \\{bin_noad}. @728
+F166. Treat $\\{display_style}+\\{cramped}$ the same as \\{display_style}
+ inside \\{make_op}. @749
+B167. Shift the character correctly in the non-|\displaystyle| case of
+ \\{make_op}. @749
+# Still another font problem: The italic corrections are wrong because
+ the corresponding array was declared \\{real} in proto-\MF\ (and
+ italic corrections were used in nonstandard way in |mathex|).
+B168. Use \\{depth} instead of \\{height} in \\{var_delimiter}.
+ [Later, both were used.] @714
+Q169. Skew the accents according to the font \\{slant}. [Soon retracted.] @741
+# At this point I think nearly all the math routines have been exercised.
+# Tomorrow they should work!
+# Eight hours debugging today.
+* 22 Mar 1978
+# (Wednesday, but actually Thursday:
+ I began at midnight because I was proofreading a paper.)
+# I checked out the font access tables, slowly (i.e., all the |\mathcode|
+ and special-character name entries were catalogued).
+Q170\>169. Do {\bf not\/} consider slants after all in the math accent
+ routine, since slanted math letters are put differently into fonts. @741
+B171. Don't use $q$ for two different things simultaneously
+ in \\{make_math_accent}. @738
+F172. Fix bug in \\{compact_list} (I forgot to advance the loop variable).
+ [This procedure became unnecessary in \TeX82.]
+M173. Avoid conflict between \\{var_delimiter} and \\{mlist_to_hlist}, which
+ want to use \\{temp_head} simultaneously. @713
+T174. Fix bad typo in \\{overbar} routine ($b$ for $p$). @705
+# Finally \TeX\ got to \\{after_math} after dealing with that
+ hairy formula\thinspace\dots
+T175. Fix another bad typo: $p$ for $b$ this time. @1199
+L176. Insert more parentheses (twice) because of `|lsh|' precedence
+ in |SAIL|. @1199
+M177\>36. Use the new hanging-indentation conventions when formatting displayed
+ equations. @1199
+Q178. Recompute penalties so that break is allowed after \\{punct_noad}s. @761
+F179. Center the large delimiters vertically. @749
+Q180. Round all rule sizes (up) before drawing them. @589
+Q181. Provide more space over $x$ in $\sqrt x$, and more space atop vincula.
+ @705,737
+Q182. Make large delimiters large enough to cover formula height
+ (important for subscripts, superscripts). @762
+I183. Insert |/ntn=33| on XGP prompt message so that complex math
+ won't blow the device driver. [See \#84.]
+P184\>161. Update the comment about the meaning of\/ |\char|, since it
+ can be used in math mode. @208
+# Six hours today.
+* 23 Mar 1978
+# 11pm, Maundy Thursday.
+C185\>104. Make |\tracing| and |\jpar| follow block structure. @283
+# It took me two hours to enter yesterday's corrections,
+ because the changes were so numerous.
+M186. Fix bad call on \\{begin_token_list} when marks are to be scanned. @396
+# Now the formula looks like it should, modulo problems in fonts.
+Q187. Prevent an exponent from going below baseline + xheight/4. @758
+B188. Change \\{quad} to \\{math_quad} when finishing a display
+ (several places). @1199
+A189. Don't use \\{append_to_vlist} when putting an |\eqno| box on a separate
+ line, because the page shouldn't break at glue there.
+ [Later, the \\{append} will be used but preceded by an
+ infinite penalty.] @1205
+S190. Increase the input \\{stack_size}; \TeX\ may need to back up a lot. @11
+A191. Don't assume that $p$ always points to a glue node when
+ a page is broken. @1017
+A192. Use \\{epsilon} in \\{scan_spec} (I had used a different
+ small constant). [This was a kludge to avoid the extra
+ parameter later called \\{exactly} or \\{additional}.] @645
+R193. Introduce a new procedure \\{scan_positive_length}, to prevent
+ negative or zero lengths in \\{scan_rule_spec}.
+ [This restrictive rule will be ``overruled'' later.] @463
+B194. Fix ridiculous bug in the leaders routine of \\{vlist_out}:
+ I had the initialization {\sl inside\/} the loop! @635
+L195. Eliminate confusion between the two temp variables named $h$;
+ one is \\{real} and the other is \\{integer}. @629
+F196. Include forgotten case (\\{leader_node}) in \\{hlist_out}.
+ [Type \\{leader_node} will be absorbed
+ into \\{glue_node} in \TeX82.] @622
+F197. Don't forget to compute \\{x0} in variable horizontal rules. @624
+# Seven and a half hours today.
+# \TeX\ seems to be ready to tackle my test file based on Volume 2.
+S198. Calculate \\{y00} in horizontal rules as an integer number of pixels
+ from the baseline, so that the baseline doesn't jump. @589
+* 25 Mar 1978
+# 2am Saturday. (Might as well drop Friday.)
+D199\>185. Make \\{def_code} consistent with the new |\tracing| conventions.
+ [Many tracing options are packed into a single
+ parameter called |\tracing|.] @1233
+R200\>185. Don't allow users to change nonexistent things like |\catcode1000|. @1232
+F201\>110. Reset \\{align_state} at beginning of \\{init_align}. @774
+F202. Don't forget \\{scan_left_brace} after |\noalign|. @785
+F203\>110. Set $\\{cur_cs}\gets 0$ in \\{get_next}, after |\cr|
+ causes a switch to the $\langle v_j\rangle$ template. @342
+# Ouch, that was a big bad bug, which took me three hours to find
+ (since I thought \TeX's low-level scanning mechanism was working).
+# Note to myself: I\/ {\bf knew\/} it would be cleaner to define \\{get_next}
+ so that it sets \\{cur_cs} to zero every time it begins [i.e.,
+ in \S341, where this change will in fact be made in \TeX82].
+ But I had avoided this on grounds of efficiency in the inner loop.
+ Well, now I have earned this tiny bit of efficiency.
+D204. Prohibit the first word of an unavailable node from becoming negative.
+ [The storage allocator of \TeX78 uses
+ a negative value to signify a node that is available, just as
+ `$\\{link}=\\{max_halfword}$' will signal availability in \TeX82.] @124
+# That was another bad one, it's not my night.
+# At least I'm developing more subtle diagnostic techniques.
+M205. Remember to un-negate the top \\{save_stack} entry
+ when \\{handle_right_brace} finishes an \\{insert_group}.
+ [This routine was completely revised in \TeX82.] @1100
+F206\>185. Initialize |\jpar| [i.e., |\tolerance|]. @240
+B207. Correct the display of insertion nodes by \\{show_node_list}. @188
+R208. Prevent \\{show_token_list} from generating really long strings
+ when in a loop. @292
+D209. Increase the reference count of \\{bot_mark} when
+ \\{vpackage} finds it. [This was later the job of \\{fire_up}.] @1016
+M210. Remember that the tokenlist for a mark ends with a |}|. @1101
+D211. Don't let \\{vpackage} lose the top insert. (It fails when
+ the very first item is a |\topinsert|.) @1014
+A212. And when that stupid code is corrected, make it handle
+ insertions first-in-first-out. @1018
+# Seven hours today.
+* 26 Mar 1978
+# Easter Sunday, will work till sunrise.
+I213. Add an `|i|' feature to the \\{error} recovery routine. @87
+I214. Include a prompt. @87
+C215. Ignore space after |\noalign{...}|. @1133
+# Otherwise, things are going well tonight;
+ I'm finding more bugs in my test program than in \TeX.
+# The `|i|' feature is proving to be very helpful.
+# I increased the size of \\{mem}
+ (now $\\{lo_mem_max}=3500$, $\\{mem_max}=10000$).
+# In fact I just needed to increase it again
+ (now $\\{lo_mem_max}=4500$, $\\{mem_max}=11000$).
+R216. Make |INITEX| output \\{mem_top} for consistency checking. @1307
+A217. Calculate the size of delimiters by considering the enclosed formula's
+ distance from the axis, not from the baseline. @762
+# I'm having trouble with a |SAIL| compiler bug; I must rearrange the program,
+ more or less at random, until it
+ compiles correctly. I hope the bug isn't more severe than it appears.
+D218\>210. Don't put a new group on \\{save_stack} if a null mark is expanded.
+ [\TeX82 will remove the `|}|' from the mark text.] @386
+# I had to redo the typewriter-style font since its width tables were wrong.
+# And I increased low-memory size again to 5500, then 6500.
+# Finally the entire test program was \TeX ed. Happy Easter! Six hours today.
+* 27 Mar 1978
+# Beginning at 2:30am.
+A219. Move |\vcenter| processing to the first pass of \\{mlist_to_hlist};
+ otherwise the height, depth, subscripts, etc., are way off. @733
+C220. Omit space after closing |$$|. @1200
+# Spacing is wrong in the formula $Y_1+\cdots+Y_k$; I have to rethink the use
+ of three dots.
+G221. Make conditional thin space available to user as |\|{\tentex\char'34}.
+ [Later will retract this.] @226
+Q222. Introduce |\dispaskip| and |\dispbskip| [later called
+ |\abovedisplayshortskip| and |\belowdisplayshortskip|]. @226
+# Reminder: I need to test line-breaking with embedded math formulas.
+I223. Make sure that $\\{interaction}\ne\\{error_stop_mode}$
+ in the `|Whoa|' error [\\{fatal_error}]. @93
+B224. Fix a big mistake in the \\{style_node} routine (which points to a glue spec,
+ not to glue itself); somehow this didn't cause trouble yesterday.
+ [In \TeX78, style nodes double as placeholders for math glue
+ like thin spaces.] @732
+C225. Make |\fntfam| obey group structure. [\TeX78's |\fntfam| operation
+ is a combination of \TeX82's
+ |\textfont|, |\scriptfont|, and |\scriptscriptfont|.] @1234
+# At this point the test routine for Volume 2 works perfectly.
+# But I will change the page width in order to check harder cases.
+Q226\>178. Disable automatic line breaks after punctuation in math
+ (e.g., consider $f(x,y)$). @761
+S227. Represent italic corrections as boxes, not glue, so that they won't be broken.
+ [The |\kern| command doesn't exist yet.] @1113
+# Eight hours today.
+B228. Fix a bug that just clobbered the memory: Call \\{free_avail}, not
+ \\{free_node}, in the \\{ins_node} case of \\{vpackage}.
+ [This logic will change completely in \TeX82.] @1019
+* 29 Mar 1978
+# (Wednesday) Again beginning at 2:30am.
+Q229. Put still more space above and below fraction lines in displayed
+ formulas. @746
+G230\>189. Install an infinite penalty feature, which positively suppresses breaks;
+ use it in displayed formulas whose |\eqno| doesn't fit. @1205
+F231. Call \\{build_page} after finishing a display; and don't
+ go to the |\noindent| routine because of the next remark. @1200
+S232. Put |\parskip| glue just before a paragraph, not just after
+ (since it interferes with a penalty after). @1091
+# Although the test program gives correct output, it generates 46 locations
+ of variable-size memory and 280 of one-word memory that are not freed.
+F233. Recycle the ulists and vlists in \\{fin_align}. @801
+M234\>25. Fix bug when deleting space at end of paragraph:
+ \\{delete_glue_ref}(\\{cur_node}) not
+ \\{delete_glue_ref}(\\{value}(\\{cur_node})). @816
+# There's also a more mysterious type of uncollected garbage,
+ a \\{fraction_noad} corresponding to
+ |$p\choose$|, an \\{incompleat_noad} not completed.
+# Couldn't find that one, so I recompiled with \#233 and \#234 corrected.
+# Now it gains just 10 locations of variable-size memory and 7 of the other kind.
+I235. Extend \\{search_mem} to search \\{eqtb} also. @255
+D236\>143. Fix bug in \\{rebox} when $\\{list_ptr}(b)=0$. @715
+# The seven one-word nodes were generated by this bug;
+ \\{rebox}\kern-1pt\ put them onto a linked list starting with
+ $\\{mem}[0]$, growing at the far end!
+D237. Remember to complete each \\{incompleat_noad}. @1184
+# This solved the other mystery. I had never noticed that my test output
+ was actually wrong: |$p\choose k$| came out as `$k$'.
+# After these corrections, the test routine worked\thinspace\dots\ I feel
+ that \TeX\ is now pretty well debugged
+ (except perhaps for error recovery)---it's time to celebrate!
+* 1 Apr 1978
+I238. Don't quit after file lookup fails. @530
+* 2 Apr 1978
+P239. Add \\{\TeX_font_area}, so that it's easier to change the
+ default library area associated with a device. @514
+* 3 Apr 1978
+L240. Insert parentheses again, to cope with the precedence of\/ |lsh|
+ when packing data. (See \#55 and \#176.) @1114
+# I had never tried $\\{hmode}+\\{discretionary}$ before!
+M241. Remember that \\{back_error} requires \\{cur_tok} to be set.
+ (Problem can arise during error recovery on parameter |#|$n$
+ with $n$ out of range.) @476
+* 4 Apr 1978
+I242. Add a deletion feature to the \\{error} routine. @88
+* 5 Apr 1978
+Q243. Reset \\{space_factor} after |\/| [this was later rescinded]
+ and after math in text. @1196
+* 10 Apr 1978
+G244\>104. Replace |\jpar| and |\tracing| by a new primitive |\chpar| for parameters.
+ It allows a user to change those quantities as well as the penalties for
+ hyphens, relations, binary ops, widows. @209
+* 14 May 1978
+# Beginning to typeset a real book (Volume 2, second edition), not just a test.
+Q245. Make math in text end with spacing as if it were
+ followed by punctuation. [This rule will soon be rescinded.] @760
+F246. Insert |\times| into the hash table; I left it out by mistake.
+ [It will eventually move into |plain.tex|.]
+C247. Change the names of Scandinavian accents from |\o|, |\oslash|,
+ |\Oslash| to |\a|, |\o|, |\O|. [This will also move to |plain|.]
+* 17 May 1978
+B248. Fix a silly bug that hasn't been tweaked until today:
+ `|\halign to size|' [obsolete in \TeX82] used \\{vsize}
+ instead of \\{hsize}. @645
+* 19 May 1978
+G249. Add a |\topbaseline| feature [later called |\topskip|]. @1001
+Q250\>245. Subtract the math spacing change of May 14. @760
+A251. Skip past blanks in the \\{scan_math} procedure. [This blank-skipping
+ will eventually go into \\{scan_left_brace}.] @403
+I252. Introduce a \\{missing_brace} routine [later generalized] to improve
+ error recovery in $\\{mmode}+\\{math_shift}$, when the top
+ of \\{save_stack} isn't a \\{math_shift_group}. @1065
+Q253. Adjust the math spacing between closing parentheses and
+ Ord, Op, Open, Punct. @764
+Q254. Make the underline go further under. @735
+S255\>96. Compute the proper natural width when a displayed equation follows
+ a paragraph whose fillglue has been deleted by \\{line_break}. @1146
+* 20 May 1978
+A256. Fix the spurious value of \\{prev_depth} inside alignments. @775
+S257. Consider (and defeat) the following scenario:
+ The u and v lists are built in \\{init_align} using \\{temp_head};
+ then while scanning `|\tabskip 2pt\rt{...}|' the macro |\rt| is expanded,
+ clobbering \\{temp_head}. @779
+# That bug was more subtle than usual.
+Q258. Add the parameter \\{num3}, so that the positioning of\/ |\atop|
+ can be different from that for fractions. @700
+Q259. Add new parameters \\{delim1} and \\{delim2}, so that
+ |\comb| can use fixed size delimiters, not computed as with |\left|. @748
+* 22 May 1978
+C260\>221. Change |\|{\tentex\char'34} to |\|{\tentex\char'35} and introduce
+ |\|{\tentex\char'34} as the negative of\/ |\|{\tentex\char'35}.
+ [Later obsolete.] @226
+L261. Fix the display of negative penalty nodes; \\{show_node_list} is confused
+ when a negative value has been packed into the middle of a word. @194
+# Memory overflow just occurred with $\\{lo_mem_max}=7500$ and $\\{mem_max}=16384$.
+ So I have to go to 15-bit pointers. (A problem on 32-bit machines?)
+* 23 May 1978
+Q262. Add a new parameter \\{big_op_spacing5}, for
+ extra space above and below limits of big displayed operators. @751
+F263. Initialize \\{incompleat_noad} in |$$\halign{...}$$|. @775
+# That was another heretofore-untested operation. How much of the code
+ has not yet been exercised?
+F264\>238. Close the file when doing lookup-failure recovery. @27
+I265. Improve the error recovery for `|Extra &|'. @792
+R266. The top piece must be calculated mod 128 in \\{var_delimiter},
+ to guarantee a valid subscript range. [Obsolete in \TeX82.] @546
+B267\>252. Fix a blunder in new \\{missing_brace} code. @1065
+B268\>262. Fix a blunder in new code for limits on display operators. @751
+* 26 May 1978
+Q269. Don't insert a new penalty after an explicit penalty in math mode. @767
+# The hash table overflowed; I ought to make it much bigger.
+R270\>110. Avoid possible bad memory references in alignment
+ when there is erroneous input after |\cr|. [Instead of
+ \\{extra_info}, the value of \\{cur_align} in \TeX78 is negated,
+ because we need only distinguish |\cr| from |&|.] @789
+S271. Make the dimension parameters like |\hsize| all global, so that they can
+ be set in the |\output| routine. @279
+# This led to major simplifications, also to major surgery.
+# [But it was a kludgy decision, overruled in \TeX82.]
+D272\>94. Don't forget to set the type of the new null box in the |\end| routine. @1054
+* 27 May 1978
+# The data overflowed memory again, both low and high, doing Section 3.3.2.
+R273\>184. Mask off extra bits of\/ |\char| in math mode,
+ to avoid bad memory references. @1151
+B274. Zero out the negative |\medmuskip| in script styles. @732
+* 29 May 1978
+S275. Be prepared to handle an undefined control sequence during \\{get_x_token}.
+ (Can fix this by brute force, using \\{get_token} instead of \\{get_next}.)
+ @380
+D276. Correct the superscript shift when a single character is raised. @758
+R277\>184. Mask off all but 7 bits in |\char| routine,
+ to avoid space-factor index out of range. @435
+# More memory capacity overflows.
+E278\>22. Fix \TeX's overflow stop so that I don't have to wait for loading of the
+ |BAIL| debug routines. [System dependent.] @93
+F279. Remember to adjust the page number
+ when a file page ends in mid-macro. [System dependent.] @306
+* 5 Jun 1978
+R280. Make sure that the arguments of positioning commands don't overflow
+ their field size. @610
+I281. Report the excess amount when giving an overfull box warning. @666,677
+* 7 Jun 1978
+Q282. Use $\ge$ instead of $>$ as termination criterion in \\{var_delimiter}. @714
+R283. Disallow |\eject| in math mode. [In \TeX78, |\eject| is
+ distinct from |\break|; in horizontal mode it includes
+ \TeX82's `|\vadjust{\break}|'.] @1102
+Q284. Don't put too much clearance above |\sqrt| in text style. @737
+* 9 Jun 1978
+G285\>110. Make \\{align_state} an integer variable, not \\{boolean},
+ so that |\eqalign| can be within another |\eqalign|. @309
+C286. A |\mark| should expand its input. @1101
+* 10 Jun 1978
+E287. Provide for preloading of fonts. @1320
+L288. Close the output file before switching to edit the input file with
+ the `|e|' option. @84
+E289. Return adjustments found by \\{hpack} to free storage if
+ they're not used. [Later, \\{hpack} will detach them only
+ when they're used.] @655
+Q290. Strive for consistency between \\{make_under} and \\{make_over}.
+ @735
+* 18 Jun 1978
+B291\>236. Fix a serious error in \\{rebox}
+ (`$b$' instead of `$\\{list_ptr}(b)$'). @715
+# Strange that such a bug would now surface for the first time!
+C292. Remove |\deg| from |INITEX|, since macros suffice.
+Q293. Add an extra hyphenation penalty for two hyphenated lines in a row. @859
+* 19 Jun 1978
+S294. Introduce the `\\{no_new_control_sequence}' switch. Among other things,
+ this will prevent an undefined control sequence following \\{scan_math}
+ from clobbering the save stack. @259
+* 20 Jun 1978
+L295. Change the badness test
+ `$\\{glue}\le0.0$' to `$\\{glue}\le0.0001$'. [\TeX82 will avoid such
+ problems by calculating badness without floating point arithmetic.] @99
+R296. Force \\{badness} to be at most $10^{19}$. @108
+I297. Add \\{end_template} for better error recovery in alignments. @375
+E298\>287. Make |INITEX| more like the real \TeX; my simple scheme for
+ font preloading was no good because it left thousands of `dead'
+ words in memory. @8
+E299. Economize disk space by using internal arrays in load
+ modules that aren't being reinitialized. [System dependent.]
+E300. Move the declaration of \\{mem} to the semantics module, so that the
+ object code will be more efficient. [System dependent. The code of
+ \TeX78 was divided into separately compiled modules for syntax,
+ semantics, output, extensions, and general organization.]
+* 21 Jun 1978
+# Today I'm working on the user manual.
+C301. Disallow |\input| except in vertical mode. [I will change this in
+ \TeX82, treating |\input| as a case of expansion.] @378
+I302. Add error recovery for \\{endv} and \\{par_end} occurring in math mode.
+ @1047
+G303. Generalize |\ifT| to |\if T|. @506
+* 22 Jun 1978
+F304. Preload the |\bullet| [later done by |plain.tex|].
+D305\>256. Get the correct \\{prev_depth} at the beginning of an alignment. @775
+C306. Change |\eject| so that it ejects only once. @1000
+* 14 Jul 1978
+I307. Look in standard area if a file isn't found in the user's area. @537
+I308. Echo all online inputs in the transcript file. @71
+* 19 Jul 1978
+Q309. Equalize spacing when only one of numerator/denominator is big. @745
+Q310. Prevent subscript from getting too high above baseline. @757
+R311. Avoid infinite loop when stack overflows: \\{push_input} should say
+ `{\bf if} $\\{input_ptr}\ge\\{stack_size}\;\land\;\\{interaction}=
+ \\{error_stop_mode}$'. @321
+* 22 Jul 1978
+C312. Make |\quad| meaningful outside math mode. (All fonts must
+ be generated again!) @558
+I313. Show the nesting level at the end of \\{show_activities}.
+ [But I decided not to do this in \TeX82.] @218
+C314. Put in |\>| [namely, |\mskip\medmuskip|;
+ \TeX78 already has |\|{\tentex\char'35}, for conditional |\thinmuskip|,
+ as well as the negative amounts |\<|,~|\|{\tentex\char'34}].
+ Change the name of vector accent from |\>| to |\b|. [Math spacing
+ operators will become much more general in \TeX82.] @716
+* 25 Jul 1978
+Q315\>94. Give the correct |\hsize| and |\vsize| to the null boxes created
+ at |\end|. @1054
+A316\>94. And don't ``append'' them. [Later this was changed, so
+ that it would work better with generalized output routines.] @1054
+I317\>297. Remove the control sequence |\endv|,
+ since error recovery is now better. @375
+I318. Define another mode of tracing: It says `|OK|' and stops after
+ |\showlists|. @1298
+Q319\>244. Give better defaults to parameters. [Later done by |plain.tex|.] @209
+I320. Allow more bits in the packed representation of\/ |\showboxdepth|. @238
+I321. Scan past delimiters and/or dimensions when recovering from
+ ambiguous fractions. @1183
+R322. Reduce accent numbers modulo 128 or 512, depending on the
+ mode. @1165
+I323. Include a warning, `|(\end occurred on level ...)|'. @1335
+* 28 Jul 1978
+# (I'm writing Chapter 27 of the manual: `Recovery From Errors'.)
+I324. Improve the error message in \\{scan_digit}. [This procedure will change
+ its name to \\{scan_eight_bit_int}, when the number of registers
+ increases from 10 to~256.] @433
+I325. Don't report overfull boxes if they're less than .1~point
+ over. @666,677
+I326. Give the user extra chances to define the font, if \\{read_font_info}
+ is unsuccessful. @560
+I327. Change default recovery for bad parameter number from |#1| to |##|, since
+ |#1| won't always work and since |##| is probably intended. @479
+I328. Omit the |"Negative?"| message on things like \\{scan_char_num}. @435
+I329. Improve error recovery when a large delimiter isn't in family~3.
+ [Obsolete.]
+I330. Give a more appropriate error message when the input is `|$\right|'. @1192
+# Currently \TeX\ says `|Missing $|'!
+I331. Call \\{back_input} before the error message in \\{back_error},
+ not afterwards. @327
+* 1 Aug 1978
+I332. Give an appropriate warning when there's no input file and the user
+ types `|e|'. @84
+L333. Increase the system pushdownlist size so that the manual will compile.
+ [Procedures \\{hlist_out} and \\{vlist_out} can recurse deeply.]
+# Yesterday I distributed 45 preliminary copies of the manual; today I
+ took out the ``debugging hooks'' and put \TeX\ up as a system program.
+* 2 Aug 1978
+# I'm typing Volume 2 again (currently in Section 4.2.2). Culture shock!
+G334. Introduce a |\ragged| parameter, to indicate a degree of raggedness.
+ [Previously, ragged-right setting was performed when the
+ |\tolerance|/100 was odd! Eventually a better approach,
+ with |\rightskip| and such things, will be discovered.] @886
+Q335. Omit the `widow penalty' in one-line paragraphs. @890
+* 5 Aug 1978
+G336. Generalize |\pageno| to |\count|\<digit>. @236
+D337\>285. Update \\{align_state} when recovering from `|Missing {|' and
+ `|Extra }|' errors. @1069,1127
+I338. Show ``runaway'' tokens, making it easier to pinpoint an error. @306
+* 22 Aug 1978
+G339. Add |\predisplaypenalty|. @1203
+I340. Clarify error messages; they should indicate when something has been
+ inserted, etc. @1064
+* 23 Aug 1978
+I341\>114. Substitute `|Extra }|' for the losing `|Missing \cr|' error message. @1069
+I342\>213. Go past online insertions in \\{show_context}. @311
+Q343. Exact no penalty for breaking one line before a display. @1145
+I344\>338. Check for runaways at end of file. @362
+I345. Give error message when a macro argument begins with |}|. @395
+* 24 Aug 1978
+L346\>213. Remove extra line-feed in \\{show_context} after printing insertions.
+ [System dependent.] @318
+* 25 Aug 1978
+Q347. Leave no glue at top of page, even after |\eject|. @997
+* 27 Aug 1978
+P348. Adopt Guy Steele's new version of the \TeX\ source files. [He has
+ recently made a copy and modified it by introducing
+ compile-time switches for MIT conventions as an alternative to SUAI.
+ This is the first time that \TeX\ is being ported to another site;
+ additional switches for PARC, TENEX, TOPS10, and TOPS20 will be
+ added later, using the Steele style.]
+* 1 Sep 1978
+Q349. Don't pass over leader nodes in the \\{try_break} background
+ computation. [At this time, leaders have not yet been
+ unified with glue.] @837
+Q350\>82. Prune away all penalties at the top of a page. @997
+* 4 Sep 1978
+I351\>338. Include `|\|' in error message about a runaway argument. @306
+* 8 Sep 1978
+# I just remade all the fonts, with increased ligature field size.
+B352\>350. Insert a necessary {\bf goto} statement in the first branch of
+ the new penalty routine within \\{build_page}. @997
+* 30 Sep 1978
+M353\>338. Make the token list for runaway arguments meaningful outside
+ of \\{macro_call}. (I just had a runaway argument ending with
+ `|\lcm|', which turned out to be the
+ control sequence in hashtable location 0.) @371
+R354. Avoid infinite loop when recovering from |$$| in
+ restricted horizontal mode. @1138
+L355. Fix two hyphenation bugs related to |-ages|, |-ers|.
+ [A completely new algorithm for hyphenation will go into \TeX82.]
+Q356. Add |-est| to hyphenation routine;
+ also disable |puz-zled| and |rat-tled|, etc.
+* 4 Oct 1978
+G357. Add new primitive |\vtop|. @1087
+Q358. Treat implicit kerns properly after discretionary hyphens have been
+ inserted. @914
+* 4 Nov 1978
+Q359. Forget the half quad originally required at left and right when
+ centering displayed equations without equation numbers. @1202
+* 11 Nov 1978
+R360. Don't let the postamble come out empty. [This could occur if no fonts were
+ selected.] @642
+* 15 Nov 1978
+C361. Allow optional space after digit in \\{scan_int} routine. @444
+* 17 Nov 1978
+R362. Make the \\{check_mem} procedure slightly more robust. @167
+* 20 Nov 1978
+C363. Make the |\par| in a |\def| match the |\par| that comes automatically with
+ a blank line. (Suggested by Terry Winograd.) @351
+G364. Add new parameter |\mathsurround| for spacing before and after
+ math in text. @1196
+G365. Extend |\advance| to allow increase by other than unity. [At this
+ time it applies only to the ten |\count| registers, and it is
+ called |\advcount|.] @1238
+* 25 Nov 1978
+G366. Add a new primitive: |\unskip|. @1105
+G367. Add new primitives |\uppercase| and |\lowercase|. @1288
+* 28 Nov 1978
+M368\>338. Don't let |\mark| and \\{macro_call} interfere with each other's
+ \\{scanner_status}. @306
+M369. Omit extra |}| after \\{show_node_list} shows a |\mark|,
+ since the right brace is already there. (See \#210.) @176
+G370. Add a new primitive suggested by Terry Winograd: |\xdef|. @1218
+* 29 Nov 1978
+S371. Delete a space following |\else{...}| also in the
+ false case. [\TeX78 uses braces, not |\fi|, for conditionals.]
+D372\>320. Make |\tracing| set |\showboxbreadth| as advertised. @198
+F373. Account properly for kerns in width calculations of \\{line_break}.
+ @866
+Q374\>364. Delete a \\{math_node} at the beginning of a line. @148
+A375\>339. Guarantee that |\predisplaypenalty=10000| will suppress page breaking
+ before a display. @1005
+* 6 Dec 1978
+L376. Change the file opening statement to allow lines up to 150 characters long.
+ [System dependent.]
+* 16 Jan 1979
+F377\>365. Initialize \\{negative} properly in the |\advance| routine
+ with a |\count| as argument. @440
+* 20 Jan 1979
+R378. Try to keep complex, buggy preambles of alignments from
+ crashing the program. @789
+* 17 Feb 1979
+I379\>376. Give more detailed information when warning about a
+ long line being broken. [System dependent;
+ the buffer size in \TeX78 is very limited.]
+L380. Declare $p$ local to \\{try_break}, for the ``rare'' case code.
+ [My original program included the following comment:
+ ``This case can arise only in weird circumstances due to
+ changing line lengths, and the code may in fact never be executed.''
+ Later Michael Plass will discover that variable line lengths require an
+ entirely different algorithm, using \\{last_special_line}.]
+ @847
+F381\>334. Don't omit the raggedness correction when the
+ last line of paragraph has to shrink. [Obsolete in \TeX82.]
+* 22 Feb 1979
+F382\>363. Don't forget to return from \\{get_x_token} after finding |\par|. @351
+Q383. Add a new parameter: |\lineskiplimit|. @679
+C384. Change the syntactic sugar:
+ `|\hbox par|' replaces `|\hjust to ...{overfull}|'. [This vastly improves on
+ the old idea (see \#40), but there still is no internal vertical mode.]
+C385. Introduce new names |\hbox| and |\vbox| for |\hjust| and |\vjust|. @1071
+G386. Add a new condition: |\ifpos|. [It will later be
+ generalized to |\ifnum| and |\ifdim|.] @513
+G387. Add |vu| and |\varunit|. [\TeX82 will eventually allow arbitrary
+ internal dimensions as units of measure.] @453
+G388\>312. Add an |em| unit. @455
+C389. Legalize |\hbox spread |\<negative dimension> [since \\{scan_spec}
+ no longer uses the sign as a flag]. @645
+* 10 Mar 1979
+C390\>370. Make \\{scan_toks} expand |\count| during |\xdef|. [This will
+ change later when |\the| and |\number| are introduced.] @367
+* 23 Mar 1979
+Q391. Put only 100000\thinspace pt stretch at the end of a paragraph instead of
+ 10000000000\thinspace pt.
+ [In \TeX78, ``infinite'' glue is actually finite but large; in the
+ language of \TeX82 we would say that |\parfillskip|, which is
+ not yet user-settable, is being changed to be like |\hfil| instead of
+ like |\hfill|.] @816
+Q392. Treat the last line of a paragraph more consistently with
+ the other lines (e.g., when |\hfil| appears in mid-paragraph), by
+ effectively inserting \\{inf_penalty} at the end. @816
+* 31 Mar 1979
+S393. Ensure that penalty nodes aren't wiped out, in weird cases where
+ breaks occur at penalties that normally disappear. @879
+* 27 Apr 1979
+A394. Correct the page number count when files begin with an empty page.
+ [System dependent.]
+G395. Allow the \\{math_code} table to be changeable via |\chcode|.
+ [In \TeX82, |\chcode| will split into |\mathcode| and |\catcode|.] @1232
+I396\>332. Don't accept `|e|' after an error message if not
+ inputting from a file. @84
+* 29 May 1979
+F397. Don't call \\{end_file_reading} if you haven't already invoked
+ \\{begin_file_reading}; this could happen when trying to
+ recover from an error in \\{start_input}.@537
+* 7 Jun 1979
+A398\>306. Be sure to eject two pages,
+ when |\eject| comes just at the time another break is preferable
+ (e.g., when the page has just become too full). @1005
+* 27 Jun 1979
+I399\>354. Don't say `|You can't do that in math mode|' when the user
+ says `|$$|' in restricted horizontal mode! @1138
+* 30 Jun 1979
+G400. Add |wd|, |dp|, |ht| dimension units. @455
+I401\>307. Don't try the system area for file names whose area is explicitly
+ indicated. @537
+* 1 Jul 1979
+G402. Allow letters as (ASCII) numbers [without the |`| marker introduced
+ later]. @442
+* 2 Jul 1979
+F403. Fix a |\gdef| bug: If the control sequence was never defined before
+ [this later became the \\{restore_zero} option],
+ don't remove it at group end. @282
+* 16 Jul 1979
+I404\>320. Update \\{show_noad_list} to be like \\{show_node_list}.
+ [The two routines, originally separate, will be merged in \TeX82.] @238
+* 18 Jul 1979
+G405. Extend capacity from 32 fonts to 64 fonts if desired. @134
+Q406. Add new \\{extra_space} parameter to all text fonts (requested
+ by Frances Yao). @558
+F407. Make each \\{node_noad} print properly in \\{show_noad_list}. @183
+Q408. Make |\jpar| allow any break if it is 1000000 or more.
+ [In \TeX82, a |\tolerance| of 10000 or more allows any break.] @851
+* 23 Jul 1979
+E409. Introduce new primitives |\hfil|, |\vfil|, |\hfilneg|, |\vfilneg|. @1058
+G410. Add |\ifmmode|. @501
+G411. Add |\firstmark|. @1012,1016
+C412. Allow break at leaders (horizontal mode only). @149
+* 25 Jul 1979
+I413\>213. Revise \\{error} so that online insertions work properly
+ after end-of-file errors. @336
+B414\>411. Change `{\bf if} $\\{first_mark}\ne0$' to
+ `{\bf if} $\\{first_mark}\ge0$' [because $-1$
+ is used to indicate `not yet given a value']. @1012
+* 28 Jul 1979
+C415\>370. Stop |\xdef| from expanding control sequences after |\def|'s.
+ [This decision will be rescinded later, after several more years of
+ experience with macro expansion will suggest better ways to cure
+ the problem.] @366
+I416. Change symbolic printout for control symbols. [System dependent.] @49
+L417\>308. Avoid linefeeds in the transcript file. [System dependent.]
+C418\>370. Expand |\topmark|, etc., in |\xdef|. @366
+* 4 Aug 1979
+B419\>413. Fix an error introduced recently: |\par| was suddenly
+ omitted at end of page. [System dependent.]
+* 11 Aug 1979
+P420. Change error messages that use |SAIL| characters not in
+ standard ASCII. @360
+* 28 Aug 1979
+D421\>411. Move the command `$\\{first_mark}\gets-1$' from \\{vpackage}
+ to \\{fire_up}. @1012
+S422\>403. Correct a serious |\gdef| bug:
+ Control sequences don't obey a last-in-first-out
+ discipline, so \TeX\ loses things from the hash table when deleting a
+ control sequence. @259
+# To fix this, I either need to restrict \TeX\ (so that
+ |\gdef| can be used inside a group only for control sequences already
+ defined on the outer level) or need to change the hash table algorithm.
+ Although all applications of \TeX\ known to me will agree to the
+ former restriction, I've chosen the latter alternative, because it gives me
+ a chance to improve the language: Control sequences
+ of arbitrary length will now be recognized.
+D423. Make sure that \\{unsave} cannot call \\{eq_destroy}
+ with a value from the upper part of \\{eqtb}. @282
+# I noticed this long-standing bug while fixing \#422. It had very
+ low probability of causing damage (e.g., it required a certain field
+ of a floating-point number to have a certain value), but it would have
+ been devastating on the day it first showed up!
+* 29 Aug 1979
+F424. Call \\{eq_destroy} when a control sequence is |\gdef|'ed
+ after being |\def|'ed. @283
+F425\>418. Treat the first token consistently
+ when |\topmark| and its cousins are expanded in \\{scan_toks}. @477
+# Now I've checked things pretty carefully and I think \TeX\ is ``fully debugged.''
+* 25 Jan 1980
+I426\>338. Display runaway alignment preambles. @306
+G427. Introduce active characters (one-stroke control sequences).
+ [I don't yet go
+ all the way: The meanings of `|x|' and `|\x|' have to be identical.] @344
+* 7 Feb 1980
+F428\>314. Fix a glaring omission: Op space |\>| was
+ never implemented in math mode! @716
+* 25 Feb 1980
+G429. Add a new dimension `|ex|' (for units of xheight). @455
+* 3 Mar 1980
+C430\>427. Allow the control sequence |\:| to be redefined
+ [it was the `select font' operator];
+ this allows the character |:| to be active. [Obsolete.]
+* 23 Mar 1980
+# An extend-\TeX-for-the-eighties party:
+G431. Add a new |\copy| feature. @204
+G432. Add a new |\unbox| feature. @1110
+G433. Add a new |\open| feature [later |\openout|]. @1351
+G434. Add a new |\send| feature [later |\write|]. @1352
+G435. Add a new |\leqno| feature, requested by MDS. @1204
+G436. Add a new |\ifdimen| feature [later |\ifdim|]. @513
+C437. Make |\|\<space> in vertical mode begin a paragraph. @1090
+G438. Add a new |\font| feature [replacing the silly previous convention that
+ a font must be defined when it is first selected]. @1256
+G439. Add new |\parval| and |\codeval| features [later
+ |\the|\thinspace\<whatever>\thinspace]. @413
+C440\>427. Don't let active characters gobble the following space. @344
+G441\>208. Add a new parameter to govern amount of token list dumped. [Obsolete.] @295
+G442. Add a new |\linebreak| feature [later replaced by |\break|]. @831
+* 25 Mar 1980
+# (Still working on the above, also thought of more.)
+G443. Add a new |\mskip| feature. @716
+G444. Add a new |\newname| feature (soon changed to |\let|). @1221
+G445\>430. Allow any control sequence to be redefined. @275
+I446. Send the output to the user's current file area, even when
+ input comes from elsewhere. @532
+* 27 Mar 1980
+Q447. Compute the xheight for accents in math mode from
+ family~1, not family~3. [Obsolete.]
+* 28 Mar 1980
+Q448. Increase minimum clearance between subscript and superscript. @759
+* 29 Mar 1980
+Q449\>222. When a display follows a display, the second should have the
+ `shortskip' glue. @1146
+* 4 Apr 1980
+A450\>445. Look at current token meanings when trying to recognize
+ |\tabskip| in alignment preambles. @782
+* 23 Apr 1980
+I451. Estimate the length of printed output, for the new
+ priority feature on our XGP device driver. [System dependent.]
+C452\>434. Break long |\send| lines
+ into pieces so that the file can be read in again. [System dependent.]
+* 19 May 1980
+Q453\>182. Don't make |\left| and |\right| delimiters too large; they
+ need to be only 90\% of the enclosed size. [This eventually
+ became |\delimiterfactor|.] @762
+* 21 May 1980
+G454. Add a new |\pagebreak| feature [later |\vadjust{\break}|]. @655
+* 13 Jun 1980
+# Today I'm beginning to overhaul the line-breaking routine,
+ and I'll also install miscellaneous goodies.
+G455. Allow a radical sign to be in different font positions. @737
+E456. Clear empty tokenlists off input stacks to allow deeper recursions
+ (suggested by Jim Boyce's macros for chess positions). @325
+G457. Make |\spaceskip| and |\parfillskip| changeable. @1228
+G458. Add a new parameter |\rfudge| (per request of Zippel) [later |\mag|]. @288
+G459. Add a new parameter |\loose| [later |\looseness|];
+ now parameters are allowed to take negative values. @875
+E460. Remove the variable \\{just_par}. [Obsolete; it was the \\{real} equivalent
+ of an \\{integer}].
+* 14 Jun 1980
+Q461. Install new line-breaking routines, including |\parshape|.
+ (These major changes are introduced as Michael Plass
+ and I write our article.) @813
+G462. Add a new parameter |\exhyf| [later |\exhyphenpenalty|]. @869
+* 16 Jun 1980
+S463\>444. Change conventions in \\{eqtb} so that glue is distinguishable
+ from other equivalents. @275
+A464\>444. Don't expand |\b| in |\xdef{\d\b{...}}| after |\let\d=\def|.
+ [Obsolete.]
+D465\>444. Avoid creating dead storage when doing \\{unsave} in certain regions. @275
+* 17 Jun 1980
+C466. Allow negative dimensions in rules. @138
+* 19 Jun 1980
+B467\>463. Make the new test for glue at the outer level of \\{show_eqtb}. @252
+* 27 Jun 1980
+Q468\>453. Don't let |\left| and |\right| become too small for big matrices.
+ [This eventually became |\delimitershortfall|.] @762
+* 3 Aug 1980
+Q469. Don't move extra-wide, numbered equations flush left unless
+ they begin with glue. @1202
+* 15 Sep 1980
+M470\>461. Say `$\ge\\{fz}$' instead of `$>\\{fz}$' in the pre-hyphenation
+ routine; I'd forgotten my definition of \\{fz} [a variable used to test
+ for a sequence of lowercase letters in the same font]. @897
+R471\>395. Check the range of the index in |\chcode| before saving the old value.
+ @1232
+* 18 Sep 1980
+D472\>457. Don't forget to increase the reference count to |\parfillskip|,
+ or it will mysteriously vanish. @816
+* 19 Sep 1980
+C473\>412. Make leaders break like glue in both horizontal and vertical modes.
+ @149
+Q474\>364. Make |\mathsurround| break properly at left and right end of lines.
+ @879
+* 13 Oct 1980
+I475\>461. Remove spurious overfull boxes generated when the looseness criterion
+ fails. [Obsolete.]
+A476\>461. Redesign the iteration for looseness; breakpoints were not chosen
+ optimally. @875
+E477\>461. Avoid storing a lot of breakpoints when they are dominated by
+ others. @836
+B478\>366. Don't say `\\{cur_node}' when you mean `\\{mem}[\\{cur_node}]'. @1105
+Q479\>461. Prefer the oldest break to the youngest break
+ when two break nodes have the same total demerits. @836
+L480\>461. Don't make badness too big for floating-point calculations,
+ when forced to make an overfull box. [Obsolete.]
+* 10 Dec 1980
+R481. Make it impossible to get unmatched `|}|' in a delimited macro
+ argument. @392
+G482. Add new |\topsep| and |\botsep| features. [These are \TeX78's
+ way to put space at the edge of inserts,
+ replaced in \TeX82 by the |\skip| register corresponding
+ to an |\insert| class.] @1009
+* 6 Jan 1981
+P483. Install new routines for reading the font metrics, using Ramshaw's
+ |TFM| files instead of\/ |TFX| files. @539
+I484. Abort after reporting 100 errors, if not pausing on errors. @82
+G485. Add new |\spacefactor| and |\specskip| and |\skip| primitives.
+ [At this time we write `|\specskip3=10pt|' and `|\skip3|' for what
+ will become `|\skip3=10pt|' and `|\hskip\skip3|' in \TeX82.] @1060
+G486\>366. |\unskip| is now allowed in internal vertical mode. @1105
+* 26 Jan 1981
+B487\>482. Don't say `\\{mem}[$q$]' when you mean `$q$'. (See \#143 and \#478.) @1009
+* 27 Feb 1981
+I488\>417. Put some linefeeds back into the transcript file, in order
+ to prevent overprinting in listings. [System dependent.]
+G489. Add a new |\dpenalty| feature [later |\postdisplaypenalty|]. @1205
+G490. Add the dimension |cc| for European users. @458
+C491. Make \\{scan_keyword} match uppercase letters as alternatives
+ to lowercase ones (suggested by Barbara Beeton's experiments
+ with |\uppercase|). @407
+I492. Add nonstop mode so that overnight batch processing is possible. @73
+* 2 Mar 1981
+S493\>422. Fix a still more serious |\gdef| bug: The generality
+ of\/ |\gdef| almost makes it a crime to
+ forget {\sl any\/} control sequence names, ever! (The previous bug was
+ only the tip of an iceberg.) @259
+I494. Issue warning message at the end of a file page if nesting level isn't zero.
+ [System dependent.]
+* 5 Mar 1981
+I495. Keep track of maximum memory usage, for statistical
+ reporting. [Obsolete.] @125
+Q496\>350. Prune away glue and penalties at top of page after marks, sends,
+ inserts. @1000
+G497. Allow |\mark| in horizontal mode. [Later it will
+ be |\vadjust{\mark...}|.] @655
+C498. Allow optional space before a required left brace, e.g., |\if AA {...}|.
+ [See \#251.] @403
+I499. Issue an incomplete |\if| error, to help catch a bad |\if|. @336
+* 17 Mar 1981
+I500\>494. Omit the warning message at end of a file page unless
+ the nesting level has changed on that page. [System dependent.]
+Q501\>310. Fix the spacing when there is a very tall subscript with
+ a superscript. @759
+* 20 Mar 1981
+S502\>371. Make space-eating after |\else| fully consistent between the
+ true and false cases. [Obsolete.]
+* 24 Mar 1981
+B503\>496. Change \\{glue_spec_size} to \\{ins_spec_size}
+ in \\{vpackage} [where insertions are done]. [Obsolete.]
+* 5 Apr 1981
+B504\>501. Fix a typo (`|+|' instead of `|-|') in the new subscript code;
+ this shifted certain subscripts down instead of up. @759
+* 18 Apr 1981
+G505. Make leaders with rules of specified size act like variable rules.
+ @626,635
+* 29 Apr 1981
+A506\>461. Don't consider $\\{badness}>\\{threshold}$ at a line |\break|
+ except in an emergency. @854
+* 13 Jul 1981
+C507\>402. Allow other characters as numbers. @442
+R508\>294. Avoid dead storage if a \\{no_new_control_sequence} error occurs.
+ [Obsolete.] @259
+G509. Add a new |\ifx| feature. @507
+G510. Add new features |\xleaders| and |\cleaders|. @626,635
+* 14 Jul 1981
+S511\>507. Amend the new code for constants;
+ the `|.|' in `|.5|' is thought to mean \O{056}! @442
+L512\>507. And fix an egregious blunder in that code: New commands at the
+ end of a procedure are ignored when earlier statements
+ exit via {\bf return}. @442
+* 4 Aug 1981
+P513. Accept alphabetic codes for all online error recovery options,
+ instead of insisting on control codes like line feed or form feed.
+ [The original error-recovery codes were suggested by the
+ conventions of the |SAIL| compiler.] @84
+G514. Add a new |\thebox| feature [later |\lastbox|]. @1079
+* 7 Aug 1981
+G515. Add |fil|, |fill|, and |filll| as units for glue stretching
+ or shrinking. @454
+I516. Suppress the overfull box error when shrinkage amount is negative. @664
+* 9 Aug 1981
+Q517. Let unset boxes inherit the size of their parent in alignments. @810
+* 12 Apr 1982
+F518. Make |INITEX| dump out the \\{font_dsize} array needed by
+ the new |DVI| output module. @1322
+* 1 May 1982
+S519\>151. Fix \\{clean_box} so that \\{mlist_to_hlist} cannot make
+ $\\{link}(q)=0$ and $\\{type}(q)=\\{glue_node}$. @720
+# [That was the historic final change to \TeX78. All subsequent entries
+ in this log refer to \TeX82.]
+* 15 Jul 1982
+# Finished draft of test program and began debugging about 1430
+ [2:30\thinspace pm]. Taking my time.
+BX1. Change \\{eqtb}[\\{cur_font}] to \\{eqtb}[\\{cur_font_loc}]. @232
+# Not logging changes to the exposition.
+# Compile time is about 2 minutes CPU, times 5 for time-sharing;
+ add another half minute for linking and loading.
+# Hash table and \\{get_next} seem to be working, with no changes needed!
+# Time out 1630--1815 for Jill's birthday party.
+LX2. Insert {\bf begin} \dots~{\bf end} around \\{dump_int} macro. @1305
+IX3. Print two blank spaces before date in \\{open_log_file}. @536
+AX4. Update $x$ and \\{var_used} outside the {\bf for} loop. @1311
+BX5. Change {\bf if} $=$ to {\bf if} $\ne$ as loop exit condition. @1315,1316
+# The |TRIP| test should preload more fonts.
+LX6. Insert {\bf begin} \dots~{\bf end} around statistics output. @1334
+FX7. Must \\{get_x_token} when scanning a number. @445
+IX8. Interactive \\{debug_help} needs to print a newline. @1338
+FX9. Include \\{ignore_spaces} and \\{math_accent} in \\{print_cmd_char} cases. @266
+IX10. Don't call \\{confusion} when \\{print_cmd_char} sees unknown code. @298
+# Compiler bug causes stack overflow. Retiring for the night at 2145.
+* 16 Jul 1982
+# Starting at 0700; DRF has fixed the compiler.
+RX11. Allow arbitrary integer parameters in diagnostic print routines. @237,699
+TX12. Say \\{cur_tok}, not \\{cur_val}, when you mean \\{cur_tok}. @440
+FX13. Make |\pause| effective also on first line of a file. @538
+FX14. Show context after online deletion. @88
+IX15. Bypass reference count when \\{debug_help} shows a token list. @1339
+BX16. Change `{\bf case} $p$' to `{\bf case} \\{type}($p$)'. @1000
+FX17. Fix timing of \\{print_ln} when scrolling help messages. @90
+PX18. Make \\{other_char} the default category for ASCII control codes too. @232
+AX19. Use special scanning method for font number in \\{new_font}. @1257
+# Eating lunch, 1020--1035, while the machine slowly recompiles everything.
+FX20. Don't forget to increase $k$ in the {\bf while} loop. @355
+DX21. Adjust \\{limit} properly after line changed when pausing. @363
+FX22. Remember to return a value in \\{new_spec} and \\{new_penalty}. @151,158
+# Now stepping through \\{line_break} in simple case.
+AX23. Don't prune unwanted nodes if $\\{cur_p}=\\{null}$. @877
+FX24. Print a closing parenthesis when displaying glue nodes. @189
+SX25. Use \\{last}, not \\{limit}, in \\{term_input}; else error prompt causes
+ trouble when $\\{state}=\\{token_list}$. @71,87
+DX26. Set $\\{first}\gets\\{limit}+1$ after \\{init_terminal}. @331
+DX27. Make sure \\{set_trick_count} is always performed. @317
+* 17 Jul 1982
+IX28. Add new diagnostic feature |\tracingcommands|. @299,1031
+# Debugging of system-dependent code not shown in this log.
+# Tangling \TeX\ now takes 1.75 minutes; about 75K bytes, 108K tokens.
+# Redundant semicolon sends Pascal compiler into infinite loop!
+FX29. Initialize $\\{passive}\gets\\{null}$. @864
+AX30. Fix pseudoprinting when the line is empty. @318
+EX31. Merge adjacent free areas of dynamic memory before dumping. @131
+FX32. Print the word |mode| in \\{print_mode}. @211
+IX33. Improve message and help in case of weird error. @415
+GX34. Allow optional space after |\def| and similar constructions. @473
+MX35. Declare \\{alpha} to be integer in \\{read_font_info}. @560
+AX36. Fix timing of \\{back_input} in \\{scan_dimen}. @448
+IX37. Back up after missing number error. @446
+IX38. Show the `|at|' size that is considered improper. @1259
+IX39. Streamline the dialog in \\{debug_help}. @1338
+MX40. Take output of \\{the_toks} from the advertised place. @467,1297
+TX41. Say \\{trie_fix}($q$), not \\{trie_fix}($p$). @959
+SX42. Decrease low limit of \\{error_count} to $-1$. @76
+* 18 Jul 1982
+FX43. Clear initial reference count of macro definitions. @473
+AX44. Fix timing of \\{back_input} in \\{scan_glue}. @461
+BX45. Use \\{cur_val_level}, not \\{cur_val}, when checking levels. @461
+BX46. Multiply |fil| units by $2^{16}$ for correct scaling. @454
+BX47. Don't confuse \\{glue_base} with \\{skip_base}. @1237
+AX48. Fix \\{print_scaled} so that 0.01 doesn't come out |0.1|. @103
+IX49\>X28. Show mode changes when tracing commands. @299
+LX50. Don't say {\bf if} $(n=0)\lor(\,\ldots\;\hbox{\bf div}\;n)$ in Pascal. @105
+BX51. Don't confuse \\{box_flag} with \\{box_code}. @1075
+SX52. Reset \\{offset} on \\{print_ln} even in \\{no_print} mode. @57
+SX53. Fix restarting of interrupts after \\{big_switch}. @1031
+LX54. Don't loop {\bf for} $k\gets a$ {\bf to} $b-1$ when $b=0$ if $k$ is
+ declared nonnegative.
+IX55. Put `|=|' sign into the \\{format_ident}. @1328
+SX56. Allow $r$ to be any integer in \\{get_node}. @125
+IX57. Don't put the output of \\{print_file_name} in quotes. @518
+IX58. Say `|dumped|' after dumping. @1311
+EX59. Eliminate unnecessary initialization code. @1332
+LX60. Get the file reading started right when beginning to undump. @1308
+IX61. Give forlorn message if format file can't be loaded. @1303
+FX62. Assign value to \\{cur_val} after glue arithmetic. @1239,1240
+* 19 Jul 1982
+LX63. Don't say {\bf if} $p>\\{max}\lor\\{free}[p]$ in Pascal. @169
+AX64. Fix memory-undump logic; loops are out of phase with input. @1312
+BX65. Undump \\{hyph_word}[$j$], not \\{hyph_word}[$k$]. @1325
+# At last |trip.fmt| loads without bombing out.
+PX66. Remove assignment of array to array, not allowed by IBM Pascal
+ (Susan Plass). @167
+PX67. Simplify an expression that's too big for IBM Pascal (Susan Plass). @1009
+AX68. Go to \\{contribute}, not \\{done}, after insertions. @1000
+IX69. Decrease \\{depth_threshold} if there's not enough string space. @198
+IX70. Show rules as `{\tt\char`\|}' in short displays. @175
+IX71. Don't show null glue in short displays. @175
+SX72. Set $\\{job_name}\gets0$ as part of output initialization. @528
+SX73. Don't complain of infinite shrinkage on |0pt minus 0fil|. @825,976,1009
+IX74. Use different prompt at beginning when accepting a file name. @37
+FX75. Reset \\{last_glue} on nonglue nodes. @996
+BX76. Remember to call \\{error} after printing |OK|. @1293
+LX77. Insert {\bf begin} \dots{ \bf end} around program text of section. @1025
+FX78. Define the |\shipout| primitive. @1071,1073
+AX79. Introduce \\{write_loc} analogous to \\{par_loc}. @1344,1371
+FX80. Dump and undump \\{par_loc} and \\{write_loc}. @1313,1314
+FX81. Allow \\{the} in \\{scan_the} [later \\{scan_something_internal}]. @413
+EX82. Interchange command codes $\\{the}:=:\\{number}$ [later \\{convert}]. @210
+BX83. Don't confuse \\{breadth} with \\{depth}. @236
+IX84. Add string printing feature to \\{debug_help}. @1339
+FX85. Set $\\{state}\gets\\{mid_line}$ in \\{begin_file_reading}. @328
+# Time out 2105--2200 to pick up Jenny from driving lesson.
+LX86. Keep $c\le127$ when deleting 99 tokens. @88
+SX87. Don't check for \\{str_room} error when $\\{selector}=\\{new_string}$. @1328
+* 21 Jul 1982
+IX88. Gather more statistics: String usage, font info, hyphen exceptions, stacks. @1334
+DX89\>X79. Initialize \\{write_loc} from \\{cur_val}, not from \\{cs_ptr}. @1344
+FX90. Remember to pack file name for |\open|. @1374
+SX91\>X34. Defuse |\outer| test before scanning optional space after `|}|'. @473
+SX92. Don't allow \\{prepare_mag} to cause errors after \\{jump_out}. @84
+# The first page of |DVI| output is {\sl perfect\/}! Pause to play piano.
+BX93. Don't confuse \\{dimen_base} with \\{scaled_base}. @1237
+DX94. Initialize $\\{link}(\\{page_head})\gets\\{null}$ when beginning a page. @991
+SX95. Correct \\{cur_height} more often, since \\{max_depth} might be negative. @972,973
+AX96. Calculate page dimensions properly after vertical kerns. @973
+SX97. Install new \\{page_contents} logic to handle interaction between
+ insertions and |\topskip|. @987,1008
+SX98. Allow \\{top_skip} glue to be a valid breakpoint. @1001
+FX99. Don't forget to count \\{dyn_used} in inner loop [erroneous analysis
+ retracted later]. @1034
+FX100. Set $p\gets q$ after migration step. @655
+FX101. Clear \\{prev_graf} to zero at start of paragraph. @1091
+LX102. Put parens into negated \\{leader_flag} macro. @1078
+# Time out 1720--1920 for John's birthday dinner.
+DX103. Scale \\{best_height} when adjusting \\{page_goal}. @1010
+AX104. Simplify logic of split insertions; three states become two. @981,1019,1020
+MX105. Don't omit first character when showing a macro argument. @400
+RX106. Prevent clobberage if macros have too many parameters. @390
+* 22 Jul 1982
+IX107. Tell how many |DVI| bytes were output. @642
+IX108\>X88. Adjust for singular or plural statistics. @1320,1334
+SX109\>X98. Consider \\{page_head} a glue node, to inhibit unwanted break. @988
+DX110. Introduce \\{new_skip_param} to keep reference counts updated. @679,969,1001
+DX111. Record the correct size of new insertion after it's split. @1010
+DX112. Use \\{free_node}, not \\{flush_node_list}, when recycling insertion
+ nodes. @1022
+SX113. Make online insertions work after \\{get_next} is interrupted. @87,324,343
+BX114. Print newline on interruption stop. @98
+SX115\>X34. Put space before \\{end_write_token}. @1371
+BX116. Don't confuse \\{glue_order} with \\{stretch_order}. @838
+TX117. Set $\\{max_dimen}\gets\hbox{\it'7777777777\/}$, not {\it'777777777}. @421
+MX118. Make |\global\textfont| legal. @1211
+BX119. Fetch |\the\textfont| with \\{equiv}, not \\{fam_font}. @415
+BX120. Call $\\{new_ligature}(f,l,\ldots)$ not $(f,c,\ldots)$. @1035
+RX121. Make \\{show_box} work on random garbage. @174,177
+DX122. Count reference to \\{zero_glue} from \\{cond_math_glue}. @1171
+* 23 Jul 1982
+RX123. Allow $\\{avail}=\\{null}$ when undumping. @1312
+BX124\>X110. Set $\\{width}(\\{glue_ptr}(p))$, not $\\{width}(p)$. @679
+AX125. Put \\{begin_file_reading} inside the \\{start_input} loop. @537
+BX126\>X116. Don't confuse \\{glue_stretch} with \\{stretch_order} [the previous
+ fix went only half\-way]. @838
+BX127. Negate $x$ when calculating badness of shrinkage. @667,678
+LX128\>X121. Remove dangling {\bf else} that parses wrong. @174
+IX129\>X28. Print newline before |{|, not after |}|, when tracing commands. @299
+IX130. Remove colon from overfull box messages. @663,675
+DX131\>X97. Compute \\{page_goal} properly when the first box arrives after
+ inserts. @1001
+BX132. Don't confuse \\{page_size} [now \\{page_goal}] with \\{best_size}. @1017
+AX133. Put heldover insertions at front of contribution list. @1023
+SX134\>X88. Output stats before closing |DVI| file, since the latter
+ decreases \\{font_ptr}. @1333
+TX135. Don't call a |\vbox| an |\hbox|. @674
+TX136. Fix misplaced {\bf end} caused by editing error. @675
+* 24 Jul 1982
+DX137. Don't \\{eq_destroy} any paragraph shape when \\{par_shape} is null. @275
+IX138. Omit blank before |\message| at the beginning of a line. @1280
+AX139\>X104. Don't try to split an insertion when \\{best_node} isn't the
+ split one. @1021
+LX140. Correct another case of `{\bf if} $x\land y$' misunderstood by Pascal.
+ @1021
+IX141. Provide diagnostic info about insertions via |\showlists|. @986
+IX142. Add `|inside a group|' to clarify a warning message. @1335
+IX143. Report \\{prev_depth} on a separate line in |\showlists|. @219
+SX144. Back up input to avoid unexpected clobberage of \\{cur_tok}. @1090
+# Wow what a bug: \\{new_graf} calls \\{build_page}, which invokes the
+ output routine, after which `\/{\bf goto} \\{reswitch}' is a {\sl disaster}.
+DX145. Add insertion glue to \\{page_so_far} instead of subtracting it from
+ the goal. @1009
+IX146. Put extra blank line before overfull box warning. @660
+CX147. Define break at kern consistently between horizontal and vertical lists. @973,1000
+DX148. Renumber so that math nodes are nondiscardable. @147
+TX149. Correct the \\{char_kern} macro: |#|, not $f$. @557
+FX150. Decrease $l$ after reconstituting discretionary break. @916
+EX151. Simplify the hyphen routine, knowing that $\\{link}(s)=\\{null}$. @918
+FX152. Initialize $r\gets q$ in discretionary destruction routine. @883
+* 25 Jul 1982
+AX153. Don't add interline penalty after last line of paragraph. @890
+IX154. Adjust spacing in diagnostic messages. @245
+DX155. Avoid simultaneous use of \\{temp_head} by \\{prune_page_top} and the
+ page builder. @1017
+FX156. Clear the \\{post_break} field of simple discretionaries. @916
+AX157. Split \\{offset} into independent variables \\{term_offset},
+ \\{file_offset}. @54,57,58
+# Am freezing current program as version $-0.25$; a week of TUG lectures
+ begins tomorrow.
+* 5 Aug 1982
+IX158. The `|.err|' file should be `|.log|' instead. @534
+GX159. Allow |\special| strings to contain more than 256 bytes. @585,1368
+MX160\>X99. Undo ``correction'' to a non-bug. @1034
+IX161. Suggest |\&| in help message for unexpected |&|. @1128
+GX162. Make `|E|' a standard option for exiting. @84
+GX163. Restore the use of dead cycles \`a la \TeX78. @1024,1054
+# The previous six changes were suggested during discussions with \TeX82 class.
+SX164. Fix global variable conflict between \\{open_log_file} and \\{new_font}. @1257
+CX165. Allow optional `|=|' when assign to font parameter. @1253
+FX166. Set \\{cur_val} after increasing the number of font parameters. @580
+DX167. Set \\{hash_brace} when matching `|{|'. @476
+IX168\>X88. Clarify meaning of statistics printed. @1334
+GX169. Change |DVI| format to include design size. @602,1260
+DX170. Introduce \\{def_ref} for \\{runaway} messages. @306
+MX171. Restore \\{cur_cs} before calling \\{scan_toks}. @1226
+AX172\>X157. Update \\{print_nl} to dual offset conventions. @62
+AX173\>X163. Move endgame logic inside \\{main_control}, because the output
+ routine becomes active. @1054
+* 6 Aug 1982
+CX174. Allow |INITEX| to load format files. @1337
+EX175. Conserve input stack space by deleting finished token lists. @325
+IX176\>X74. Print the opening `|**|' in the transcript file. @534
+# Now ready to try breaking new ground in |TRIP|.
+SX177. Preserve \\{align_state} from tokens deleted online. @88
+DX178. Set $t$ in all branches of \\{scan_toks}. @473
+SX179. Change `$\\{cur_cmd}\le\\{right_brace}$' to `$\\{cur_tok}\le
+ \\{right_brace_limit}$'; otherwise |\relax| gets through. @477
+CX180. Allow optional |=| when setting |\spacefactor|; disallow zero. @1243
+BX181. Change \\{vpackage}(\\{head}) to \\{vpackage}(\\{link}(\\{head})). @796
+# Shades of 1978!
+LX182. Insert missing {\bf begin} \dots{ \bf end}. @798
+* 7 Aug 1982
+LX183. Keep \\{trie_max} declared in non-|INITEX| [later rescinded]. @950
+DX184. Watch out for empty token list when copying. @466
+DX185. Free unused reference count slot when defining |\everypar|. @1226
+GX186\>X163. Introduce |\maxdeadcycles|. @1012
+# I believe the \\{line_break} routine has passed its test perfectly.
+SX187. Don't put discretionary after |-| inside a discretionary. @1039
+CX188. Change `|\minus|' to `|\minusthe|' [this feature retracted later]. @413
+BX189. Change \\{cur_p} to $r$ (three places). @875
+AX190. Increase range of \\{hc} to \\{halfword}; otherwise end-of-word mark
+ might match a vacant entry in the trie. @892
+FX191. Initialize $b$ in \\{shift_case} routine. @1288
+EX192. Don't back up if a space follows a decimal fraction. @452
+BX193. Don't confuse \\{glue_base} with \\{dimen_base}. @1145
+LX194. Guard against anomalous floating-point values in glue display. @186
+* 8 Aug 1982
+SX195. Avoid infinite loop when |\outer| leads to runaways. @339
+# I worked on that problem about two hours before fixing it.
+IX196. Move final \\{debug_help} to \\{succumb}, except in batch mode. @93
+RX197. Insert kern after spanned box, to defeat access to floating point. @808
+* 9 Aug 1982
+CX198. Include |\leftskip| and |\rightskip| in displayed equations [rescinded
+ later]. @1199
+IX199. Trace line-break computations if $\\{tracing_stats}>2$. @846,856
+DX200. Keep \\{prev_p} up to date when passing a string. @867
+# Now stepping through math stuff; a lot is working.
+DX201. Set $\\{link}(p)\gets z$ when making a fraction. @747
+CX202. Don't reset space factor when beginning |\valign|. @775
+IX203. Don't show glue setting if $\\{glue_sign}=\\{normal}$. @186
+DX204. Clear \\{glue_stretch} and \\{glue_shrink} when creating an unset box. @801
+BX205. Do \\{vpack} in hmode and vice versa when aligning. @804
+AX206. Remove fallacious call to \\{confusion} after alignment in display. @1206
+AX207. Don't test $\\{mode}=\\{vmode}$ in display, test $\\{nest_ptr}=1$. @1145
+FX208. Show an \\{inner_noad} as well as the other types. @690,696
+DX209. Renumber \\{mu_glue} and \\{cond_math_glue} so that the glue display logic
+ works. @149
+BX210. Don't confuse \\{cur_size} with \\{cur_style}. @703
+FX211. Advance $p\gets q$ during second pass over mlist. @761
+IX212. Add helpful hint about |\tracingonline=1|. @1293
+TX213. Delete spurious statement left from sloppy editing. @710
+DX214. Change the subtype when \\{mskip} becomes \\{hskip}. @732
+FX215. Don't forget to use the remainder when computing math glue. @716
+IX216\>X199. Improve paragraph diagnostics using \\{short_display}. @857
+IX217\>X199. Introduce \\{artificial_badness} for better diagnostics. @854,856
+* 11 Aug 1982
+AX218. Introduce \\{char_box} subroutine so that \\{var_delimiter} adds italic
+ correction. @709
+SX219. Save font and char in local variables of \\{make_math_accent}, since
+ it can be recursive. @738
+FX220. Call \\{error} after decrying an invalid character. @346
+* 12 Aug 1982
+IX221\>X199. Install new format for showing break nodes. @846
+# I have been testing \\{line_break} and I think it's working fine.
+BX222. Change $q$ to $p$, in order to catch empty alignments. @812,1206
+SX223. Disallow third part of discretionary in math mode. @1120
+DX224. Don't change \\{tail} if discretionary third part is empty. @1120
+IX225. Say |nonscript|, not |non_script|. @189
+SX226. Inhibit math if |\scriptfont3| is improper. @1195
+IX227\>X199. Introduce {\tt\@}|firstpass| and {\tt\@}|secondpass| comments. @863
+TX228. Change $p$ to $r$ when you mean $r$. @1204
+IX229\>X108. Say |page|, not |pages|, if there's only |1|. @642
+IX230. Insert space before |[]| on truncated |\showlists|. @182
+* 28 Aug 1982
+# Back from vacation after having looked at hardcopy listing of |TRIP| test.
+GX231. Allow |dm| as a unit [later |.5dm1| will be |.5\dimen1|]. @455
+IX232\>X108. Singularize |prevgraf 1 lines|. @219
+IX233. Omit trailing zero count registers when showing completed page numbers. @638
+LX234. Avoid clobbering $a$ by introducing a new local variable $t$. @986
+DX235\>X216. Fix diagnostic printing of discretionaries. @858
+IX236. Don't show unset stretch/shrink that's zero. @185
+CX237\>X198. Make |\halign| in displays consistent with other displays. (Namely,
+ ignore |\leftskip| and |\rightskip| in nonaligned displays;
+ respect the paragraph shape in aligned displays.) @800,1199
+IX238. Parenthesize `|If you're confused ...|'. @403
+IX239. Say `|\fraction|', not `|\xabovex|'. @697
+FX240. Remember to {\bf return} when you should. @1153
+PX241. Use absolute value to make sure {\bf div} is unambiguous. @737
+BX242\>X218. Don't confuse depth with height. @709
+BX243. Use $\\{delta}-\\{height}$, not $\\{height}-\\{delta}$. @736
+BX244. Increase \\{shift_down} to increase the clearance. @745
+IX245. Don't back up after improper use of |\the|. @428
+IX246. Don't give |0pt| as the default result when looking for \\{tok_val}. @428
+FX247. Initialize \\{second_indent} in the easy case. @848
+FX248. Package the equation number. @1204
+QX249. Don't resort to $v\gets\\{max_dimen}$ when glue doesn't stretch or
+ shrink. @1148
+IX250. Insert newline before showing current |\botmark|.
+FX251. Call \\{error} after giving error message. @784
+AX252. Change implementation of |\number|; it should \\{scan_int}, not
+ something internal. @471
+PX253. Introduce symbolic constants like \\{format_area_length}. @524
+PX254. Change \\{quit} to \\{jump_out}, since some compilers treat \\{quit}
+ as a reserved word. @81
+LX255. Add more parentheses to get proper parsing. @1260
+IX256. Say |please| in order to be friendly (or at least polite). @360
+BX257. Don't confuse \\{cur_vcmd} with \\{cur_chr}. @508
+IX258. Use |&| instead of |!| to specify a preloaded format. @1337
+TX259\>X177. Correct |s3| to |s4|. @88
+GX260. Introduce new primitive |\mathchardef|, to save space and time. @1224
+CX261. Use the |[]| convention for noads as well as nodes. @692
+TX262. Correct spelling in call to \\{primitive}: |\xatopx| should be |\xoverx|
+ [later renamed, thank goodness]. @1178
+* 30 Aug 1982
+RX263. Don't fetch \\{link}(\\{null}) in malformed list. @175
+SX264. Initialize \\{align_state} at a better time so that \\{align_peek}
+ doesn't see |&| or |\span|. @785,791
+SX265. Outlaw preamble interfering with $\\{align_state}=0$. @789
+CX266. Add level of grouping to alignment to tabskip locality. @774
+FX267. Check \\{align_state} when scanning $\langle u_j\rangle$. @783
+AX268. Move `\\{unsave}; \\{new_save_level}' from \\{main_control} into
+ \\{fin_col}. @791,1131
+SX269\>X180. Remember \\{cur_chr} when you're looking for optional `|=|'. @1243
+TX270. Change $q$ to $r$ [in code now obsolete]. @804
+IX271. Disable interrupts during \\{back_error} so that help messages aren't
+ clobbered. @327
+SX272. Introduce \\{slow_print} for printing control sequences. @60
+IX273. Initialize \\{del_code}(|"."|$)\gets0$ for error recovery. @240
+SX274. Call \\{end_file_reading} before calling \\{check_outer_validity}. @362
+IX275. Don't delete an extra `|}|' when |\par| will help find a runaway. @395
+* 31 Aug 1982
+BX276. Don't confuse \\{thin_muskip} with \\{thin_muskip_code}. @413
+FX277\>X266. Recover from error if new \\{align_group} ends abnormally. @1132
+IX278. Recover from error if |\par| occurs when $\\{align_state}<0$. @1094
+CX279. Make |\hskip\the\thinmuskip| and |\mskip\the\baselineskip| erroneous. @413
+GX280. Add |\muskip| and |\setmuskip| analogs to |skip| and |\setskip|. @413,1228
+EX281. Don't output |pop| right after |push|. @601
+# The |TRIP| test looks right; now to test for wasted memory.
+# When memory should be empty I find $\\{dyn_used}=18$, $\\{var_used}=267$.
+* 1 Sep 1982
+# Made special |MEMTEX| program, designed to track all memory allocation.
+DX282. Delete reference to \\{last_glue} when a page is packaged. @1017
+IX283. Include \\{save_stack} in the \\{search_mem} debugging routine. @285
+CX284. Disallow |\vfill| in restricted horizontal mode. @1095
+# Most of the memory locations I thought were wasted were actually in good use.
+# Total 192 hours (approx) debugging time so far since July 15.
+* 2 Sep 1982
+# Now looking at all zero counts in profile and extending |TRIP|.
+EX285. Simplify the creation of |vtop| boxes. @1087
+CX286. Set $\\{space_factor}\gets1000$ after |\hbox|. @1076
+PX287. Introduce preamble into |DVI| format. @617
+SX288. Give special \\{chr_code} to |\relax|. @265
+IX289. Don't show `|(null)|' when token list is null, just show nothing. @295
+EX290. Delete the procedure \\{write_name_string}, which is never used.
+CX291. Rename |\xabovex| to |\abovewithdelims|; do the same for
+ |\xatopx| and |\xoverx|. @1178
+QX292. Improve \\{clean_box} so that it recognizes cleanliness better. @720
+IX293. Report a |Missing delimiter| more meaningfully. @1161
+RX294. Give \\{endv_token} a \\{chr} code of 128 so that it will end a file name. @289
+RX295. Test present of math fonts {\sl after\/} parsing an mlist, not
+ before. @1138,1195
+IX296. Omit `|recent contributions|' and/or `|current page|' when they are
+ empty. @218,986
+IX297. Display what \TeX\ has deleted after improper discretionary list
+ has arisen. @1121
+IX298. Show what math character was undefined. @723
+IX299. Improve the |Incompatible magnification| error; break it into two lines. @288
+DX300. Put new cases into \\{flush_node_list}, to recycle mlist noads. @698
+* 6 Sep 1982
+FX301\>X300. Insert a necessary `{\bf goto} \\{done}' in that new material. @698
+# It took two hours to diagnose that {\bf goto} problem.
+TX302\>X295. Change `|2|' to `|3|' in help message for extension fonts. @1195
+IX303. Add a special note if material is being held over for the next output. @986
+RX304. Divide before multiplying in \\{make_left_right}, to avoid overflow. @762
+IX305. Introduce the \\{box_error} routine. @992
+FX306. Clear \\{arith_error} after overflow has been reported. @460
+BX307\>X249. Don't confuse \\{stretch} with \\{glue_stretch}. @1148
+DX308. Set $\\{glue_sign}\gets\\{normal}$ when packaging with glue ratio
+ zero. @558,664
+AX309. Test for overflow before attaching the sign. @448
+# That all worked! Now trying |min_quarterword| negative.
+LX310. Take absolute value before applying {\bf mod} in \\{new_trie_op}. @944
+LX311. Say $\\{qi}(c)$, not $c$, when testing |TFM| flags [now obsolete]. @573
+LX312. Initialize \\{token_ref_count}(\\{def_ref}) to \\{null}, not zero. @473
+LX313. Change the type of \\{vsplit} parameter $n$ from \\{quarterword} to
+ \\{eight_bits}. @977
+LX314. Initialize \\{null-delimiter} different form \\{null_character}. @685
+LX315. Insert \\{qi} twice in \\{scan_delimiter}. @1160
+FX316. Insert \\{qi} in \\{scan_math}. @1151
+FX317. Insert \\{qo} in \\{fetch}. @722,723
+FX318. Insert \\{qi} in \\{set_math_char}. @1155
+FX319. Insert \\{qi} in \\{math_ac}. @1165
+FX320. Insert \\{qo} in \\{mlist_to_hlist}. @755
+IX321. Use brackets around 8-bit characters in \\{print_ASCII}. @68
+IX322. Include \\{hyph_list} in the \\{search_mem} debugging routine. @933
+# Now compiling non-|INITEX| to try an industrial-strength version.
+LX323. Add {\bf return} to \\{final_cleanup}, because some Pascal compilers
+ insist that each label be used. @1335
+DX324. Compute \\{par_token} when undumping. @1314
+* 11 Sep 1982
+IX325. Emit newline before file name, if near end of line. @537
+CX326. Define |\ifx| for arbitrary tokens. @507
+* 12 Sep 1982
+IX327. Don't ask users to type |x| twice before exiting. @84
+GX328. Install new features |\openin|, |\read|, |\ifeof|, |\closein|; rename
+ existing |\open|, |\send|, |\close| to be |\openout|, |\write|,
+ |\closeout|. @209,313,1275
+GX329. Install new feature |\expandafter|. @368
+PX330. Change the default file area from `|<TeX>|' to `|TeXinputs:|'. @574
+* 13 Sep 1982
+GX331. Install new feature |\string|. @472
+AX332. Remove spurious space printed by \\{sprint_cs}. @263
+# All tests passed now! But when I played with the system I found another bug
+ (undetected by |TRIP|):
+FX333. Set $r\gets s$ after matching macro parameter tokens. @397
+* 16 Sep 1982
+IX334\>X199. Introduce serial numbers in line-break records, improving
+ readability and independence. @846
+IX335. Don't abort when \\{file_name_size} is exceeded. @519
+* 17 Sep 1982
+IX336. Remove unwanted period from font capacity message. @567
+* 18 Sep 1982
+GX337\>X329. Make |\expandafter| more powerful by moving it from semantics
+ to syntax [i.e., from stomach to mouth]. @368
+* 19 Sep 1982
+IX338. Improve error recovery for `|Missing number|'. @415
+* 22 Sep 1982
+QX339. Suppress italic correction between letters in math mode except in math
+ fonts. @752
+* 24 Sep 1982
+PX340. Define $\\{null}=\\{mem_bot}$, not \\{min_halfword}, because there's
+ a reference to \\{link}(\\{null}) in \\{try_break}. @115
+DX341. Initialize $\\{str_start}[0]\gets0$. @47
+IX342. Avoid blank space at beginning of line. @638
+DX343. Set type of new box in math mode to \\{ord_noad}, not \\{inner_noad}. @1076
+* 28 Sep 1982
+# Here are the first changes made to the preliminary listing of \TeX82 that was
+ published by the \TeX\ project earlier this month.
+F520. Insert the missing cases \\{letter} and \\{other_char} after
+ \\{x_token} looks ahead. @1038
+C521. Change `|\pause|' to `|\pausing|'. @236
+D522. Reset \\{overfull_rule} when determining tabskip glue. @804
+A523. Fix the logic for scanning |\ifcase| [in obsolete syntax---everything
+ is still done with braces since `|\fi|' doesn't exist yet]. @509
+* 30 Sep 1982
+I524. Change |"0.0"| to |"?.?"| (suggested by DRF). @186
+* 2 Oct 1982
+Q525. Use conditional thin spacing next to `Inner' noads. @764
+Q526. Make thick spaces conditional. @766
+* 4 Oct 1982
+P527. Increase \\{trie_size} from 7000 to 8000, because of Frank Liang's improved
+ (but longer) hyphenation patterns. @11
+* 6 Oct 1982
+F528\>X330. Change the string lengths to match the new \\{\TeX_format_default}. @520
+# Version 0 of \TeX\ is being released today!
+* 8 Oct 1982
+B529. Fix a blunder: I decreased $h$ mod a quarterword when it should have
+ been decreased mod \\{trie_op_hash_size} (HWT). @944
+* 9 Oct 1982
+P530\>X258. Fix a typo (`|!|' not `|&|') in the |WEB| documentation. @524
+F531. Remember to call \\{initialize} if a different format was preloaded
+ (Max D{\'\i}az). @1337
+# Version 0.1 incorporates the above changes.
+* 12 Oct 1982
+G532. Add the `|\immediate|' feature, by popular request. @1375
+# Version 0.2 incorporates this (somewhat extensive) change.
+* 13 Oct 1982
+P533. Introduce new |WEB| macros so that \\{glue_ratio} is more easily changed. @109
+# I began writing {\sl The \TeX book\/} today: edited the old preface and
+ searched in the library for quotations.
+* 14 Oct 1982
+B534. Change the type of \\{hd} to \\{eight_bits}; it's
+ not a \\{quarterword} (HWT). @649
+S535\>X281. Revise the optimization of\/ |DVI| commands: It's not always safe to eliminate
+ \\{pop} when the preceding byte is \\{push}, since |DVI| commands
+ have variable length! (Embarrassing oversight caught by DRF.) @601
+* 15 Oct 1982
+C536. Test `$\\{prev_depth}>\\{ignore_depth}$', not `$\ne$'. @679
+# Version 0.3 incorporates the above changes.
+* 16 Oct 1982
+P537. Omit definition of \\{align_size}; it's never used (Bill Scherlis). @11
+I538. Inhibit error messages when packaging box 255. @1017
+* 21 Oct 1982
+A539\>X145. Subtract $\\{width}(q)$ from \\{page_goal}, don't add it to
+ $\\{page_so_far}[1]$. @1009
+# Version 0.4 incorporates the above changes.
+* 22 Oct 1982
+P540. Increase the amount of lower (variable-size) memory from 12000 to 13000,
+ since the \TeX\ program listing now needs about 11500. [At this time
+ there still is a fixed boundary between upper and lower memory.] @12
+G541. Add a new parameter |\boxmaxdepth|. @1086
+# Version 0.5 incorporates the above changes.
+* 26 Oct 1982
+B542. Fix an off-by-one error caught by Gabi Kuper and HWT.
+ (I forgot `${}+1$'). @1317
+B543. Fix the spacing of displayed control sequences: \\{print_cs} should base its
+ decision on $\\{cat_code}(p-\\{single_base})$, not $\\{cat_code}(p)$. @262
+# The |TRIP| test detected this bug, but I didn't notice.
+* 27 Oct 1982
+S544. Set \\{math_type} before saying $\\{fetch}(\\{nucleus}(q))$, since
+ fetching can have a side effect. @752
+* 28 Oct 1982
+G545. Install a major change: Fonts now have identifiers instead of code letters.
+ Eliminate the `|\:|' primitive, and give corresponding new
+ features to `|\the|'. @209
+# Actually I began making these changes on October 26, but I needed two days
+ to debug them and to put Humpty Dumpty together again.
+# At this time I'm also drafting macros for typesetting {\sl The \TeX book}.
+# The above changes have been incorporated into Version 0.6.
+* 30 Oct 1982
+# After years of searching, I've finally found a definitive definition of
+ the printer's point; and (unfortunately) my previous conjecture was
+ wrong. The truth is that $\rm83\,pc=35\,cm$, exactly;
+ so I am changing \TeX\ to conform.
+C546. Revise unit definitions for the `real' printer's point. @458,617
+# Version 0.7 incorporates the above.
+* 1 Nov 1982
+# Oops! Retract error \#546, and retract \TeX\ Version 0.7;
+ the source of my information about points was flaky after all.
+ My original suppositions were correct,
+ as confirmed by NBS Circular 570.
+* 4 Nov 1982
+C547. Revise the definition of |dd|, conforming to the definitive value
+ shown me by Chuck Bigelow. @458
+R548\>545. Introduce ``frozen'' copies of
+ font identifiers, to be returned by |\the\font|, so that font
+ manipulation is more robust. @1257
+* 5 Nov 1982
+D549. Reset \\{looseness} and paragraph shape when beginning a |\vbox|. @1083
+* 6 Nov 1982
+D550. De-update \\{align_state} when braces are in constants. @442
+I551\>X294. Improve error recovery for bad alignments. @1127
+# Today I wrapped up Chapters 4 and 5.
+* 8 Nov 1982
+G552. Give more power to |\let|: the right-hand side needn't be a control
+ sequence. @1221
+I553. Amend \\{show_context} to say
+ `$(\\{base_ptr}=\\{input_ptr})\lor{}$'; otherwise undefined control
+ sequences can be invisible in unusual cases (John Hobby). @312
+A554. Compute demerits more suitably by adding a penalty squared, instead of
+ adding penalties before squaring. @859
+# Previously a slightly loose hyphenated line followed by a decent line
+ was considered worse than a decent hyphenated line followed by
+ a quite loose line.
+* 10 Nov 1982
+E555. Save a bit of buffer space by declaring \\{pool_file} only in
+ |INITEX|. @50
+* 11 Nov 1982
+I556. Introduce a new context indicator to clarify \TeX's scanning state:
+ A special type
+ called \\{backed_up} is distinguished from other kinds of \\{inserted}
+ lists; it is called `recently read' or `to be read again', while
+ others are called `inserted'. @314
+I557. Append a comment, `|treated as zero|', to the missing-number message. @446
+I558. Ignore the settings of\/ |\hfuzz| or |\vfuzz| if\/ |\hbadness| or |\vbadness|
+ is less than 100. @666,677
+* 13 Nov 1982
+# Major surgery on the program is planned for today, because of new ideas
+ suggested by correspondence with MDS and other macro writers.
+G559. Introduce a new |\tokens| register; this will be useful and easy to add,
+ since \TeX\ already can handle |\everypar| and |\output|. @1227
+C560\>X34. Change \\{get_x_token} to \\{get_token} when scanning an optional
+ space; then a construction like
+ |\def\foo{...}\foo| won't complain that |\foo| is undefined. @443
+# This change was retracted when it was being debugged, because it could
+ cause \\{endv} to abort the job. Then it was re-established again
+ when I found that \\{endv} needed to be more robust anyway.
+ [But it was eventually rescinded again.]
+G561. Make |\span| mean `expand' in a preamble. @782
+E562. Use three separate {\bf if\/} tests instead of
+ `$\land$' in the inner loop of \\{get_next}, to gain efficiency. @342
+R563. Introduce \\{get_r_token} so that assignments have uniform error
+ messages and so that frozen equivalents cannot be changed. @1215
+# I gave a few variables more mnemonic names as I made these changes.
+C564. Move conditional statements from the semantics (`stomach') part of
+ \TeX\ to the syntax (`mouth') part, by introducing `|\fi|'.
+ Also introduce |\csname| and |\endcsname|. @372,489\hbox{--}500
+# This makes macros much more predictable and logical, but it is by far
+ the most drastic change ever made to \TeX. The program began to come
+ back to life only after three days of solid hacking.
+# Several other things were cleaned up as part of this change
+ because it is now more natural to handle them differently.
+ For example, a null control sequence has now become more logical.
+# The result of all this is called Version 0.8.
+* 18 Nov 1982
+# Today I resumed writing Chapter 8. Tomorrow I'm $\,2^{14}$ days old!
+* 21 Nov 1982
+F565. Declare $c$ as a local variable for hyphenation (DRF). @912
+E566. Omit the ``first pass'' and try hyphenations immediately,
+ if\/ |\pretolerance| is negative (suggested by DRF). @863
+R567. Don't ship out incredibly huge pages; they might foul up
+ |DVI| files. @641
+* 2 Dec 1982
+G568. Add new features |\everymath| and |\everydisplay|. @1139,1145
+G569. Add a new feature |\futurelet|. @1221
+# The changes above have been incorporated into Version 0.9 of TeX.
+* 7 Dec 1982
+G570. Add a new |\endinput| primitive (suggested by FY). @362,378
+* 8 Dec 1982
+I571. Try \\{off_save}, if\/ |\par| occurs in restricted horizontal mode.
+ (This avoids embarrassment if \TeX\ says `type a command or
+ say |\end|', then when you type |\end| it says you can't!)
+ [However, I soon retracted this change.] @1094
+* 21 Dec 1982
+A572. Redefine |\relax| so that its \\{chr} field exceeds 127. (This facilitates
+ the test for end in \\{scan_file_name}.) @265
+F573\>566. Call \\{begin_diagnostic} when omitting
+ the first pass of line breaking. @863
+A574. Fix the logic of glue scanning: In |\hskip-1pt plus2pt| the minus should
+ apply only to the |1pt|. @461
+* 23 Dec 1982
+I575. Renumber the decimal codes in paragraph statistics for loose and tight
+ lines; they were ordered backwards. @817
+C576. Treat a paragraph that ends with leaders like a paragraph that
+ ends with glue. @816
+C577. Allow commas as alternates to radix points, for Europeans. @438
+C578. Change |\hangindent| to a normal dimension parameter. [It had been
+ a combination of\/ |\hangindent| and |\hangafter|, with special
+ syntax.] @247
+G579. Make |\prevgraf| accessible to users. @422,1244
+G580. Split |\clubpenalty| off from |\widowpenalty|. @890
+# I'm typing Chapter 14 while making these changes.
+* 24 Dec 1982
+S581. Use \\{back_input} instead of {\bf goto} \\{reswitch} when
+ inserting |\par|, because |\par| may have changed. @1095
+* 25 Dec 1982
+# It's 10pm after a very Merry Christmas!
+I582\>X328. Don't prompt for a new file name if\/ |\openin| doesn't find a file. @1275
+G583. Add a new |\jobname| primitive. @472
+I584. Give the user a way to delete the dollar sign, when \TeX\ decides
+ to insert one. @1047
+C585. Allow optional equals after |\parshape|, and implement |\the\parshape|.
+ @423,1248
+* 26 Dec 1982
+I586. Add an \\{if_line_field} to the condition stack entries,
+ so that more informative error messages can be given. @489
+D587\>549. Introduce a \\{normal_paragraph} procedure, since initialization is needed
+ also within |\insert|, |\vadjust|, |\valign|, |\output|. @1070
+* 27 Dec 1982
+G588. Give users access to |\pagetotal| and |\pagegoal|. (Analogous to
+ \#679 and \#585, but simpler.) @1245
+I589\>X199. Introduce |\tracingpages|, allowing users to see
+ page-optimization calculations. Also split |\tracingparagraphs| off from
+ |\tracingstats|. @987,1005,1011
+# The changes above have been incorporated into Version 0.91 of \TeX.
+* 31 Dec 1982
+P590. Break the \\{build_page} procedure into two parts, by extracting
+ the section now called \\{fire_up}. [This is necessary because
+ some Pascal compilers, notably for IBM mainframes, cannot
+ deal with large procedures.] @1012
+S591\>564. Make |\ifodd1\else| legal by introducing \\{if_code}. @489
+Q592. Improve alignments when columns don't occur: Don't append null boxes
+ for columns missing before |\cr|, and zero out the tabskip
+ glue after nonpresent columns. @802
+I593. Make the error message about overfull alignment more intelligible.
+ @801,804
+# The changes above have been incorporated into Version 0.92 of \TeX82,
+ which was the last version of 1982,
+ completed at 11:59pm on December 31.
+* 3 Jan 1983
+# Today I'm beginning to write Chapter 15, and
+ planning the |\output| routine of |plain.tex|.
+C594\>X186. Change the logic of \\{its_all_over}; use \\{max_dead_cycles}
+ here too, instead of the fixed constant~100. @1054
+F595\>X34. Don't forget to \\{pop_nest} when an insert is empty. Also disallow
+ optional space after |\insert|$\,n\,$|{...}|. @1100
+* 4 Jan 1983
+C596\>541. Use the |\boxmaxdepth| that's declared inside a |\vbox| when packaging it.
+ @1086
+C597. Rename |\groupbegin| and |\groupend| as |\begingroup| and
+ |\endgroup|. @265
+G598\>594. Make |\deadcycles| accessible to users. @1246
+Q599. Base the split insertions on natural height plus depth, not
+ on \\{delta}. @1010
+# The changes above have been incorporated into Version 0.93.
+* 6 Jan 1983
+D600. Add \\{push_math} to handle a case where I forgot
+ to clear \\{incompleat_noad}. (This long-standing bug was
+ unearthed today by Phyllis Winkler.) @1136
+G601\>588. Add |\pageshrink|, etc., too. @1245
+G602. Introduce new parameters |\floatingpenalty|, |\insertpenalties|. Also
+ adopt a new internal representation of insertion nodes,
+ so that |\floatingpenalty|, |\splittopskip| and |\splitmaxdepth|
+ can be stored with each insertion. @140,1008
+* 7 Jan 1983
+Q603. Improve the rules for entering \\{new_line}, in particular
+ when the end-of-line character is active. @343
+* 9 Jan 1983
+Q604. Distinguish between implicit and explicit kerns. @155,896
+C605. Change the name |\ignorespace| to |\ignorespaces|. @265
+C606\>560. Don't omit a blank space after |\def|, |\message|, |\mark|, etc.;
+ the previous hodge-podge of rules is impossible to learn. @473
+# The above changes appear in Version 0.94.
+* 12 Jan 1983
+# Beginning to write the chapters on math today.
+G607. Add a new feature: active characters in math mode. @1151
+* 15 Jan 1983
+A608. Fix a surprise bug: `|$1-$|' treated the |-| as binary. @729
+D609. Initialize \\{space_factor} inside discretionaries. @1117
+* 16 Jan 1983
+F610. Fix an incredibly embarrassing bug: I forgot to update \\{spotless} in the
+ \\{error} routine!
+# While fixing this, I decided to change
+ \\{spotless} to a more general \\{history} variable, as suggested
+ by IBMers who want a return code. @76,82,1335
+I611. Replace two calls of \\{confusion} by attempts at error recovery, in places
+ where `|This can't happen|' could actually happen. @1027,1372
+* 18 Jan 1983
+R612. Introduce the \\{normalize_selector} routine
+ to protect against startup anomalies
+ when the transcript file isn't open. Also make \\{open_log_file}
+ terminate in some cases. @92,535
+R613\>591. Insert |\relax|, not a blank space, to cure infinite
+ loop like |\ifeof\fi| (LL). @510
+G614. Change the old |\limitswitch| to |\limits|, |\nolimits|, and
+ |\displaylimits|. Incidentally, this fixes a bug in the former
+ positioning of integral signs. @682,749
+C615. Give a |\char| in math mode its inherited |\mathcode|. @1151
+Q616\>525. Make underline, overline, radical, vcenter, accent noads and |{...}|
+ all revert to type Ord instead of type Inner. Introduce a new primitive
+ |\mathinner|. (This fixes the spacing, which
+ got worse in some ways after change \#525.) @761
+# I'm working on Appendix G today.
+* 19 Jan 1983
+G617. Introduce a |\mathchoice| primitive. @1174
+C618. Move |\input| from the stomach to the mouth. @378
+C619\>X260. Introduce |\chardef|, analogous to |\mathchardef|. @1038,1224
+G620. Change |\unbox| to |\unhbox| and |\unvbox|; also add |\unhcopy|. @1110
+C621. Consider |\spacefactor|, |\pagetotal|, etc., as part of
+ \\{prefixed_command}, even though they are always global. @1211
+* 20 Jan 1983
+C622. Switch modes when |\hrule| occurs in horizontal mode or |\vrule|
+ in vertical. @1090,1094
+G623. Add a new |\globaldefs| feature. @1211
+* 21 Jan 1983
+E624. Optimize the code, in places where it's important (based on
+ frequency counts of \TeX\ usage
+ accumulated during the past week): Introduce \\{fast_get_avail}
+ and \\{fast_store_new_token}; reduce procedure-call overhead
+ in \\{begin_token_list}, \\{end_token_list}, \\{back_input},
+ \\{flush_node_list}; change some tests from `{\bf if} $a\land b$' to
+ `{\bf if}~$a$ {\bf then if}~$b$'. @122,371
+* 22 Jan 1983
+E625. Save space in math lists: Don't insert penalties within restricted
+ horizontal mode; simplify trivial boxes. @721,1196
+S626. Fix a surprising oversight in the \\{rebox} routine:
+ Ensure that $b$ isn't a vbox. @715
+C627\>545. Make |\nullfont| a primitive, so that \\{cur_font} always
+ has a value. (This is a dramatic improvement over \TeX78, where a
+ missing font was a fatal error called `|Whoa|'!) @552
+* 24 Jan 1983
+I628\>586. List all incomplete |\if|'s when the job ends. @1335
+* 29 Jan 1983
+C629\>552. Change initialization of \\{align_state} so that |\halign\bgroup|
+ works. @777
+* 30 Jan 1983
+D630\>625. Be sure to test `\\{is_char_node}($q$)' when checking for a trivial
+ box. @721
+# By extraordinary coincidence, this bug was caught when somebody
+ used font number~11 ($=\\{kern_node}$) in the second character
+ of a list of length~2!
+I631\>X168. Improve format for stats at end of run, as suggested by DRF. @1334
+# The changes above have been incorporated into Version 0.95.
+C632. Don't ignore the space after a control symbol (except `|\ |'). @354
+P633. Remove all trailing spaces at the right of input lines,
+ so that there's perfect compatibility with IBM systems that
+ extend short lines with spaces. @31
+* 3 Feb 1983
+I634. Assume that a \\{math_accent} was intended, after giving an error
+ message in the case $\\{mmode}+\\{accent}$. @1165
+G635. Add new primitives |\iftrue| and |\iffalse|. @488
+* 6 Feb 1983
+A636\>X304. Improve the accuracy of fixed-point arithmetic when
+ calculating sizes for |\left| and |\right|. (I had started by
+ dividing \\{delimiter_factor}, not \\{delta1}, by 500.) @762
+* 12 Feb 1983
+C637. Change the name |\delimiterlimit| to |\delimitershortfall|. @248
+C638. Make |\abovewithdelims..| equivalent to |\above|; change the
+ order of operands so that delimiters precede the dimension. @1182
+C639\>607. Remove the kludgy math codes introduced earlier;
+ make |\fam| a normal integer parameter and allow |\mathcode|
+ to equal $2^{15}$. @1233
+R640. Don't let |\spacefactor| become more than $2^{15}$. @1233,1243
+# I finished drafting Chapter 17 today.
+* 14 Feb 1983
+I641\>639. Replace octal output (\\{print_octal}) by hexadecimal (\\{print_hex})
+ so that math codes are clearer. @67
+F642\>619. Don't forget \\{char_given} in the \\{math_accent} routine. @1124
+* 17 Feb 1983
+C643\>622. Switch modes when |\halign| occurs in horizontal mode, or |\valign|
+ in vertical mode. @1090,1094
+* 18 Feb 1983
+I644. Add a new feature |\tracingrestores|. This requires a new procedure called
+ \\{show_eqtb}, whose code can be
+ interspersed with the \\{eqtb} definitions. @252
+* 25 Feb 1983
+I645\>622. Suggest using |\leaders| when the user tries a horizontal rule
+ in restricted horizontal mode. @1095
+* 27 Feb 1983
+I646. Specify the range of source lines, when giving warning messages
+ for underfull or overfull boxes in alignments. @662,675
+# Why did it take me all day to type the middle part of Chapter 18?
+* 4 Mar 1983
+G647. Introduce a new feature |\xcr| (suggested by LL). [Changed later to
+ `|\crcr|'.] @785
+I648\>631. Subtract out \TeX's own string requirements from the stats. @1334
+* 6 Mar 1983
+G649. Add new features |\everyhbox| and |\everyvbox|. @1083,1167
+* 9 Mar 1983
+R650\>X295. Avoid accessing \\{math_quad} when the symbol fonts aren't known
+ to be present. @1199
+P651\>533. Introduce \\{float} and \\{unfloat} macros to aid portability (HWT). @109
+C652. Introduce new names |\abovedisplayskip| and |\belowdisplayskip| for
+ the old |\dispskip|; also |\abovedisplayshortskip| and
+ |\belowdisplayshortskip| for the old |\dispaskip| and |\dispbskip|. @226
+* 10 Mar 1983
+C653. Unbundle |\romannumeral| from |\number| (suggested by FY). @468
+* 12 Mar 1983
+C654. Ignore leading spaces in \\{scan_keyword}. @407
+* 14 Mar 1983
+E655\>631. Use \\{write} and \\{write_ln} directly when printing stats. @1334
+* 16 Mar 1983
+Q656\>602. Refine the page-break cost function (introducing `\\{deplorable}',
+ which is not quite `\\{awful_bad}'), after suggestion by LL. @974,1005
+# The changes above have been incorporated into Version 0.96.
+* 18 Mar 1983
+G657. Add a new feature |\everyjob| suggested by FY. @1030
+* 19 Mar 1983
+I658. Don't treat left braces specially when showing macros. @294
+C659. Ignore blanks that would otherwise become undelimited arguments. @393
+* 21 Mar 1983
+F660\>X280. Make |\lastskip| handle \\{mu_glue} as well as ordinary glue. @424
+C661\>561. Expand only one level in a preamble |\span|. @782
+* 22 Mar 1983
+C662. Let a single |#| suffice in |\tokens|, |\message|, etc. (The previous rule,
+ in which |##| was always required as in macros, was a loser especially
+ in |\write| where you had to say |####|!) @477
+C663\>X328. Require the keyword `|to|' in |\read|. (This will avoid the common error
+ of an incomplete constant when no space appears
+ before the |\cs|.) Also allow terminal
+ I/O as a default when a stream number is out of range. @482,1225,1370
+* 26 Mar 1983
+C664. Replace |\ifeven|\<countnumber> by |\ifodd|\<number>, for better
+ consistency of language. @504
+S665\>564. Introduce the \\{change_if_limit}, to overcome a big surprise
+ bug relating to |\if\if aabc\fi|. @497
+# Such examples show that \\{cur_if} might not be current,
+ in my original implementation.
+* 28 Mar 1983
+G666\>X326. Tolerate non-characters as arguments to |\if| and |\ifcat|. @506
+C667. Change `|absent|' to `|void|', a better word. @487
+C668. Clear the \\{shift_amount} in |\lastbox|, since I don't
+ want to figure out what it means in all cases. @1081
+* 29 Mar 1983
+I669. Wake up the terminal before giving an error message. (This
+ means a special \\{print_err} procedure is introduced.)
+ (Suggested by DRF.) @34,73
+* 1 Apr 1983
+# Today I finished Chapter 21 (boxes) and began to draft Chapter 22 (alignments).
+G670. Allow periodic preambles in alignments. @793
+C671. Make |\leaders| line up according to the smallest
+ enclosing box. @627,636
+Q672. Allow hyphenation after whatsits (e.g., after items for an index). @896
+* 2 Apr 1983
+Q673. Call \\{build_page} when |\par| occurs in vertical mode. @1094
+C674. Clear \\{aux} in \\{init_row}, for tidyness. @786
+* 4 Apr 1983
+C675. Let digits switch families in math mode. @232
+* 7 Apr 1983
+Q676\>602. Refine the test for not splitting an insertion. @1008
+* 8 Apr 1983
+C677\>647. Rename |\xcr| as |\crcr|, at LL's request. @780
+* 9 Apr 1983
+# Took a day off and had a chance to help print a sample page on
+ a 150-year-old letterpress in Murphys, California.
+* 11 Apr 1983
+I678. Recover more sensibly after a runaway preamble. @339
+* 12 Apr 1983
+C679\>X328. Make |\read| span several input lines, if necessary to get
+ balanced braces. @482
+* 14 Apr 1983
+S680. Fix a subtle bug found by JS: \S882 can make $q$ a \\{char_node},
+ so we need to test `{\bf if} $\lnot\\{is_char_node}(q)$'.
+ [Actually I discovered much later that the real bug was
+ to omit `{\bf else}' at this point.] @881
+* 15 Apr 1983
+C681. Make |\uppercase| and |\lowercase| apply to all characters, regardless
+ of category. @1289
+# 7:30am. After working all night, I completed a draft of the manual thru
+ Chapter 22, for distribution to volunteer readers.
+# 5pm. The changes above have been incorporated into Version 0.97.
+* 17 Apr 1983
+R682. Change `\\{small_number}' to `$0\,.\,.\,65$' in the
+ hyphenation routine (DRF). @901
+I683. Flush patterns in the input when the user tries |\patterns|
+ outside of\/ |INITEX| (suggested by DRF). @1252
+# Tomorrow I fly to England, where I'll lecture and write a paper about
+ `Literate Programming' [{\sl Comp.~J. \bf27} (1984), 97--111].
+* 14 May 1983
+I684\>663. Improve the behavior of\/ |\read| from terminal
+ (suggested by Todd Allen at Yale).
+ [I'd forgotten to implement the extended stream numbers in \#663.
+ Also, the prompt is now omitted if $n<0$.] @484
+* 18 May 1983
+I685. Restrict |\write| $n$ to the transcript file only, if $n<0$. @1350
+C686\>X188. Unify the syntax for registers and internal quantities. (Remove
+ primitives called `|\insthe|' and `|\minusthe|'; rename
+ \\{scan_the} to \\{scan_something_internal}, and change its
+ interface accordingly; clean up command codes generally.) @209,413
+G687. Introduce new parameters |\hoffset|, |\voffset|. @617
+* 24 May 1983
+G688. Introduce a new parameter |\everycr| (suggested by MDS). @774,799
+# Many macro writers and preliminary-manual readers have been requesting
+ new features; I'll try to keep the language as concise and consistent
+ as possible.
+* 25 May 1983
+G689. Introduce |\countdef|, |\dimendef|, etc.\ (suggested by DRF long ago,
+ easy now in view of \#686). @1224
+G690. Introduce |\advance|, |\multiply|, |\divide| (suggested by FY). @1240
+G691. Introduce |\hyphenchar|; this requires a new command
+ \\{assign_font_int}, plus minor changes to about 15 modules. @915
+G692. Introduce |\skewchar| (easy because of \#691). @741
+G693. Introduce |\noexpand|. (I had difficulty thinking of how to
+ implement this one!) @358,369
+G694. Introduce |\meaning|. @296
+G695\>X231. Remove `|dm|' and `|vu|'; allow the more general `|.5\hsize|'. @455
+C696. Change `|\texinfo| $f$ $n$' to `|\fontdimen| $n$ $f$'. @578
+* 27 May 1983
+G697. Add a new feature |\afterassignment| (suggested by ARK). @1269
+C698\>619. Adjust the timing so that commands like `|\chardef\xx=5\xx|'
+ behave sensibly. @1224
+* 28 May 1983
+C699. Ignore `|\relax|' as if it were a space, in math mode and in a few other
+ places where |\relax| would otherwise be erroneous. @404
+Q700. Improve |\mathaccent| spacing with respect to subscripts
+ and superscripts (suggested by HWT). @742
+* 30 May 1983
+C701\>598. Terminate a job only when $\\{dead_cycles}=0$. @1054
+# The changes above constitute Version 0.98.
+* 3 Jun 1983
+# I finished the draft of Chapter 23 (output routines) today.
+G702. Allow |\mark| and |\insert| and |\vadjust| in restricted
+ horizontal mode, and also in math mode. (This is a comparatively
+ big change, triggered by the fact that |\mark| in a display
+ presently causes \TeX\ to crash with `|This can't happen|'!)
+ The global variable \\{adjust_tail} is introduced. @796,888,1085
+* 6 Jun 1983
+G703\>695. Replace (and generalize) the previous uses of\/ |ht|, |wd|, and |dp|
+ in dimensions by introducing the new control sequences
+ |\ht|, |\wd|, and |\dp|. @1247
+I704. Display sub-parts of noads with the symbols |^| and |_| instead of
+ |(| and~|[|. @696
+C705\>694. Allow |A..F| in hex constants to be \\{other_char} as well as
+ \\{letter}. @445
+* 7 Jun 1983
+E706\>654. Remove an instance of \<Scan optional space>, since it's now
+ redundant. @457
+C707. Legalize |\mkern\thinmuskip| and |\mkern5\thinmuskip|. @456
+C708. Clean up the treatment of optional spaces in numerical specifications. @455
+# A construction like |2.5\space\space\dimen0| was previously
+ valid after `|plus|' or `|minus|' only!
+# I'm obviously working on Chapter~24 today.
+C709\>545. Allow `|\font|' as a \<font identifier> for the current font. @577
+C710\>623. Don't make |\gdef| global when $\\{global_defs}<0$. @1218
+E711. Produce \\{zero_glue} as the outcome of
+ |\advance\spaceskip by-\spaceskip|. @1229
+I712. Make |\show| do something appropriate for every possible token. @1294
+G713\>559. Replace the (single) |\tokens| parameter by an array of
+ 256 token registers. @230
+C714. Allow |\indent| in math mode; also make |\valign| in math mode produce the
+ `|Missing|~|$|' error. @1046,1093
+E715. Remove redundant code: There's no need to check \\{cur_group}
+ or call \\{off_save} when starting alignments or equation numbers
+ in displays. @1130,1142
+* 8 Jun 1983
+C716. Disallow |\openout-1| and |\closeout-1|. @1350
+C717. Disallow |\lastbox| in math mode. @1080
+* 9 Jun 1983
+I718. Call \\{back_error}, not \\{error}, when |\leaders| aren't followed by
+ proper glue. @1078
+D719. Initialize for a possible paragraph, after |\noalign|
+ in a |\valign|. @785
+* 10 Jun 1983
+C720\>708. Expand the optional space after an ASCII constant. @442
+* 12 Jun 1983
+C721. Set $\\{space_factor}\gets1000$ after a rule or a
+ constructed accent. @1056,1123
+* 14 Jun 1983
+D722. Correct a serious blunder: Set $\\{disc_width}\gets0$ before testing
+ if $s$ is null (caught by JS). @869
+# This is a real bug that existed since the beginning!
+ It showed up on page~37 of the
+ Version~0 |TRIP| manual, but I didn't notice the problem.
+C723\>708. Make optional spaces after \<dimen> like those after \<number>. @448
+C724\>568. Insert \\{every_display} before calling \\{build_page}. @1145
+I725\>648. Report \TeX's capacity on overflow errors in a way that's
+ fully consistent with other statistical reports. @42
+* 17 Jun 1983
+C726. Make all |\tracing| decisions on the basis of $\ge$ versus $<$,
+ not $\ne$ versus~$=$. @581
+# Today I finished the draft of Chapter 27 (the last chapter)!
+# The changes above were released as Version 0.99 on June 19, 1983.
+* 20 Jun 1983
+C727. Set |\catcode`\%=14| in |INITEX|. @232
+C728\>587. Call \\{normal_paragraph} when |\par| occurs in vertical mode. @1094
+# Once again I'm retiring about 8am and awaking about 4pm.
+* 21 Jun 1983
+C729\>558. Don't append an overfull rule solely because of\/ |\hbadness|. @666
+R730. Don't allow the glue-ratio of shrinking to be less than~$-1$. @810,811
+* 22 Jun 1983
+B731\>653. Declare the parameter to \\{print_roman_int} to be of type \\{integer},
+ instead of \\{nonnegative_integer} (found by Debby Clark). @69
+C732\>690. Make the keyword `|by|' optional (suggested by LL). @1236
+* 24 Jun 1983
+I733. Say `|preloaded|' when announcing \\{format_ident}. @1328
+* 25 Jun 1983
+R734. Add extra boxes and
+ glue to the output of alignment. [This thwarts possible attempts
+ at trickery by which system-dependent glue set values
+ computed by |\span| could have gotten into \TeX's registers by
+ things like |\valign| and |\vsplit|. It also has the advantage
+ of perfect accuracy in alignment of vertical rules.] @809
+C735. Make leaders affect the height or width of the enclosing boxes. @656,671
+# Today I'm mainly installing a much-improved format for change files
+ in |WEB| programs (suggested by DRF).
+* 28 Jun 1983
+C736. Permit |\unskip| in vertical mode when we know that it does nothing. @1106
+* 1 Jul 1983
+E737\>700. Avoid redundant boxes when things like `|{\bf A}|' occur in math. @1186
+G738. Add a `|scaled|' feature to |\font| input. @1258
+D739\>700. Remember to correct \\{delta} when an accented box changes. @742
+* 2 Jul 1983
+R740.Introduce \\{bypass_eoln}, to remove anomalous behavior on input files
+ of length~1. (Suggested by DRF after the problem was discovered by LL). @31
+* 4 Jul 1983
+G741. Allow codes like |^^b| as well as |^^B|. @352,355
+G742. Introduce new parameters |\escapechar|, |\endlinechar|, |\defaulthyphenchar|,
+ and |\defaultskewchar|, to make \TeX\ less dependent on the
+ character set. (This affects many modules, since a lot of
+ error messages must be broken up so that they use \\{print_esc}.)
+* 7 Jul 1983
+P743. Use a system-dependent function \\{erstat} when opening or closing
+ files (suggested by DRF). @27
+* 11 Jul 1983
+# The computer is back up after more than 50 hours down time
+ (due to air conditioning failure).
+I744. Show total glue in the output of\/ |\tracingpages|. @985
+R745. Guard against insertion into an hbox. @993
+C746. Legalize the assignment \<tokenvar>=\<tokenvar>. @1227
+I747. Introduce a new parameter |\errhelp|. @1283
+F748\>623. Don't forget to check \\{global_defs} when |\tabskip| is changed. @782
+* 12 Jul 1983
+C749. Allow an |\outer| macro to appear after |\string|, |\noexpand|,
+ and |\meaning| (Todd Allen). @369,471
+C750. Make `|\the|' an expandable control sequence (i.e., move it
+ from the stomach to the throat); this cleans up
+ several annoying glitches. @367
+C751\>620. Allow |\unhbox| and |\unhcopy| in math mode if the box is void. @1110
+* 13 Jul 1983
+# I lectured for four hours at the TUG meeting today after very little sleep!
+* 16 Jul 1983
+# The following were suggested by TUG meeting discussions.
+L752. Round the value of \\{default_rule} more properly: It should be 26215. @463
+Q753\>700. Fix |\mathaccent| again; it's still not right!
+ The final height should be the maximum of
+ the height of accented letter without superscript and
+ the height of unaccented letter with superscript. @742
+G754. Add a new feature |\newlinechar|. @59
+G755. Allow boxes and rules in discretionaries (suggested by somebody
+ from Hewlett-Packard). @1121
+I756\>X28. Show all token expansions, not just macros,
+ when |\tracingcommands|. @367
+C757. Allow |\char| in a |\hyphenation| list. @935
+G758. Introduce a new feature |\aftergroup|; it can be implemented with
+ \\{save_stack}. @326
+C759. Run the running dimensions to alignment boundaries (suggested
+ by ARK). @806
+* 17 Jul 1983
+R760. Zero out \\{hyf} values at the edges, so that
+ weird pattern data cannot lead to Pascal range checks. @965
+R761\>X190. Decrease the |hc| codes for hyphenation, so that code~127 cannot
+ possibly be matched. @937,962
+C762\>672. Allow whatsits after hyphenatable words. @899
+C763\>604. Represent an italic correction as an explicit kern. @1113
+* 18 Jul 1983
+C764. Allow lowercase letters in file names. @519
+I765. Change the message `|No output file|' to: `|No pages of output|'. @642
+I766. Confirm that a quiet mode is being entered, when error
+ interaction ends with |Q|, |R|, or |S| (suggested by ARK). @86
+# Version 0.999 was finally installed today; a new program listing has
+ been printed.
+# From now on, I plan to keep all section numbers unchanged.
+# I'm done writing Appendix~H; beginning to revise Chapter~20.
+* 25 Jul 1983
+C767\>663. Allow space after `|to|' in the |\read| command (FY). @1215
+# To bed at 1pm today.
+* 27 Jul 1983
+S768\>665. Stack the current type of\/ |\if|; this precaution is necessary
+ in general (FY). @498
+# To bed at 2pm today.
+* 29 Jul 1983
+E769. Avoid putting a control sequence in the hash table
+ when it occurs after |\ifx|. (Requested by Math Reviews people.) @507
+# Finished a version of {\sl The \TeX book\/} lacking only Appendices
+ D, E, and~I, for distribution to interested readers.
+# To bed at 10:30pm, planning to arise regularly at 6am for a change.
+* 31 Jul 1983
+I770\>766. Call \\{update_terminal} when going quiet (HWT). @86
+* 1 Aug 1983
+C771. Don't put an empty line at the end of an |\input| file! (This simplifies
+ the rules and the program, and also gets around a bug that occurred
+ at the end of files with $\\{end_line_char}<0$.) @362
+# The changes above went into Version 0.9999, which was widely distributed.
+* 16 Aug 1983
+B772\>665. Rectify a ridiculous gaffe: I initialized $q$ every time the loop
+ of \\{change_if_limit} was performed! (Found by FY.) @497
+I773\>648. Distinguish `|string|' from `|strings|' when reporting statistics. @1334
+A774. Introduce \\{lx}, to correct a bug in |\xleader| computations
+ (found by FY). @627
+* 20 Aug 1983
+F775. Don't forget to apply |\/| to ligatures. @1113
+# Today I began to read all previous issues of {\sl TUGboat}, in preparation for
+ Appendix~D.
+* 27 Aug 1983
+I776. Add debugging hack number~16, to help catch subtle data structure bugs. @1339
+E777. Remove redundant setting and resetting of \\{name_in_progress}. @531
+S778\>618. Suppress |\input| during a font size spec; otherwise
+ \\{cur_name} is clobbered (found by MDS). @1258
+G779. Introduce new conditionals |\ifhbox| and |\ifvbox|. @505
+* 29 Aug 1983
+D780\>750. Test for an empty list, if emptiness will mess up the data structure.
+ (Found by Todd Allen.) @478
+E781\>624. Use \\{fast_store_new_token} in another place for efficiency. @466
+I782. Say `|has only|' instead of `|has|'. @579
+# These changes yield Version 0.99999, used only at Stanford.
+* 30 Aug 1983
+C783. Make funny blank spaces showable. @298
+* 31 Aug 1983
+C784\>754. Make |\newlinechar| affect \\{print_char}, not just \\{print}. @58
+* 4 Sep 1983
+G785. Add new features |\lastkern|, |\lastpenalty|, |\unkern|, |\unpenalty|.
+ @424,996,1105
+# OK, Appendix D is finished!!
+# The above changes have been installed in Version 0.999999.
+* 17 Sep 1983
+P786\>548. Don't bother making duplicate font identifiers; that
+ was overkill, not really needed. @1258
+# Will this be the historic last change to \TeX?
+* 18 Sep 1983
+I787. Correct a minor inconsistency, `|display|' not `|displayed|'. @211
+* 20 Sep 1983
+C788\>604. Treat the kerns inserted for accents as explicit kerns. @1125
+* 26 Sep 1983
+I789. Change `|log|' to `|transcript|' in several messages. @535,1335
+# The index was finished today; I mailed the entire {\sl \TeX book\/} to
+ Massachusetts for final proofreading before publication.
+* 1 Oct 1983
+D790. Prevent uninitialized trie positions in case of overflow
+ (found by Bernd Schulze). @944
+* 7 Oct 1983
+# Henceforth our weekly `\TeX\ lunch' meetings will be called `\MF\ lunch'.
+# DRF begins to produce {\sl The \TeX book\/} on our APS phototypesetter.
+* 14 Oct 1983
+P791\>633. Ignore spaces at the ends of lines also in |TEX.POOL| (found
+ by DRF). @52
+D792\>610. Initialize the \\{history} variable at \\{start_here} (DRF). @1332
+* 18 Oct 1983
+I793. Extend \\{runaway} to catch runaway text (suggested by FY). @306
+D794. Reset \\{cur_cs} after \\{back_input}, not after scanning the
+ `|=|' (found by FY). @1226
+* 24 Oct 1983
+I795\>638. Change the error recovery for bad delimiters, in accordance with
+ the changed syntax. (Found by Barry Smith.) @1183
+* 9 Nov 1983
+E796. Optimize the code a bit more, based on empirical frequency data gathered
+ during September and October: In \S45, use the fact that the
+ result is almost always true. In \S380, delete `{\bf while}
+ \\{true} {\bf do}' since many compilers implement that badly.
+ Rewrite \S852 to avoid calling \\{badness} in the most common case.
+ @45,380,852
+* 3 Dec 1983
+F797. Don't forget to call |error| after the message has been
+ given (noticed by Gabi Kuper). @500
+# Version 1.0 released today incorporates all of the above.
+* 9 Dec 1983
+# Dinner party with 36 guests to celebrate \TeX's coming of age.
+* 2 Feb 1984
+S798\>786. Reinstall |\font| precautions that I thought were unnecessary.
+ I overlooked many problematic possibilities, like
+ `|{\font\a=x| |\global\a}| |\the\font|'
+ and `|\font\a=x| |\font\b=x| |\let\b=\undefined| |\the\a|', etc.
+ (Found by Mike Urban.) The new remedy involves removal of the
+ \\{font_ident} array and putting the identifiers into a frozen
+ part of the hash table; so there's a sprinkling of corrections
+ in lots of modules. But basically the change is quite conservative,
+ so it shouldn't spawn any new bugs (it says here). @222,267,1257
+* 9 Feb 1984
+S799. Remove the possibility of double interrupt, in a scenario
+ found by Clint Cuzzo. @1031
+* 12 Feb 1984
+Q800. Improve spacing in a formula like |$(A,<)$|. @764
+* 13 Feb 1984
+A801. Avoid a bad {\bf goto}, as diagnosed by Clint Cuzzo and George O'Connor.
+ (Must not go directly to \\{switch}.) @346
+E802. Conserve string pool space by not storing file name in two
+ guises (suggested by DRF). @537
+* 26 Feb 1984
+I803. Make scaled output look cleaner by printing fewer decimals whenever
+ this involves no loss of accuracy. (Suggested by \MF\ development.) @103
+* 2 Mar 1984
+R804. Maintain 17-digit accuracy, not 16; now
+ constants like `|.00000762939453126pt|' will round correctly. @452
+* 16 Mar 1984
+R805. Plug a loophole that permitted recursion in \\{get_next}, by disallowing
+ deletions in \\{check_outer_validity}. @336
+* 24 Mar 1984
+I806. Open the terminal before trying to wake it up, when the program starts bad.
+ @1332
+* 27 Mar 1984
+R807. Check that $k<63$, to avoid the
+ |\patterns{xxx...xxxdxxxdxxx}| anomaly found by Jacques D\'esarm\'enien. @962
+* 11 Apr 1984
+F808. Supply code for the missing case \\{adjust_node} in \\{copy_node_list}. @206
+# Yoicks, how could serious bugs like that have escaped detection?
+* 11 Jun 1984
+D809\>627. Initialize \\{char_base}, etc., for \\{null_font}.
+ (Found by Nick Briggs.) @552
+R810. Clear the \\{buffer} array initially (Briggs). @331
+* 21 Jun 1984
+C811. Look ahead for ligature or kern after a |\chardef|'d item
+ (D\'esarm\'enien). @1038
+* 4 Jul 1984
+R812. Make the quarterword constraint explicit with a
+ new `\\{bad}' case (19). @111
+* 7 Jul 1984
+E813. Optimize \\{firm_up_the_line} slightly,
+ to be consistent with the \MF\ program. @363
+* 8 Jul 1984
+I814. Give additional diagnostics when |\tracingmacros>1|. @323
+# The changes above were incorporated in Version 1.1, released July 9, 1984.
+* 27 Jul 1984
+I815. Say `|see| |the| |transcript| |file|' after handling offline |\show|
+ commands. (Suggested by \MF.) @1298
+* 20 Oct 1984
+I816. Allow `|0|' in response to error prompts. @84
+# Those two changes led to Version 1.2.
+* 25 Nov 1984
+R817. Don't forget to check for \\{null} before looking at subfields
+ of a node. (This was ``dirty Pascal,'' with two quarterword 0's
+ read as a halfword.) @846
+R818. Ditto in another place! @939
+E819. Remove the fixed-at-compile-time
+ partition between lower and upper memory. @116,125,162
+# This major change in memory management
+ completes Version 1.3, which was published in preliminary
+ looseleaf form as `\TeX: The Program'.
+* 20 Dec 1984
+R820. Keep the \\{node_size} field from overflowing if the lower part of memory
+ is too large. @125
+# That was another bug in existence from the beginning!
+* 5 Jan 1985
+I821. Improve the missing-format-file error (DRF). @524
+* 7 Jan 1985
+I822. Update the terminal right away so that the welcoming message will
+ appear as soon as possible (DRF). @61
+* 23 Jan 1985
+I823. Convey more uncertainty in the
+ help message at times of \\{confusion}. @95
+I824\>610. Improve the \\{history} logic in the \\{warning_issued} case. @245
+* 18 Feb 1985
+P825\>810. Stick to standard Pascal: Don't
+ use \\{first} in a {\bf for} loop. [Some procedures ``threaten'' it
+ globally, according to British Standard 6192, section 6.8.3.9.]
+ (Pointed out by CET.) @331
+* 11 Apr 1985
+S826. Prevent nonexistent characters from being output by
+ unusual combinations of ligatures and hyphenation. @915
+* 15 Apr 1985
+L827\>819. Compute memory usage correctly in |INITEX|; the previous number
+ was wrong because of a |WEB| text macro without parentheses (DRF). @164
+* 16 Apr 1985
+E828. Speed up \\{flush_list} by not calling \\{free_avail} (DRF). @123
+* 17 Apr 1985
+A829\>788. Introduce a special kind of kern for accent positioning;
+ it must not disappear after a line break. @837,879,1125
+* 18 Apr 1985
+R830\>755. Prevent |\lastbox| and |\unkern| from removing discretionary replacements.
+ @1081,1105
+# That completes Version 1.4.
+* 26 Apr 1985
+C831. Don't try \\{\TeX_area} if a nonstandard file area has been specified
+ (DRF). @537
+# That was \#401 in \TeX78; I never learn!
+* 30 Apr 1985
+C832\>754. Eliminate the limitation on |\write| length; the reason for it
+ has disappeared (Nancy Tuma). @1370
+* 8 May 1985
+D833\>819. Allocate two words for the head of the \\{active} list (CET). @162
+* 11 May 1985
+I834. Change \\{wterm} to \\{wterm_ln} after a bad beginning (Bill Gropp). @1332
+E835\>806. Don't open the terminal twice (CET). @1332
+* 22 May 1985
+R836. Test for \\{batch_mode} after trying to open the transcript file,
+ not before (DRF). @92
+R837. Be prepared for string pool overflow while reading the command line!
+ (This bug was first found in \MF, when it could occur more easily.) @525
+* 7 Aug 1985
+A838. Fix a bug in |\edef\foo{\iffalse\fi\the\toks0}|: \TeX\ should stay in the
+ loop when expanding non-|\the|. (Found by Dan Brotsky.) @478
+# The above changes were incorporated in Version 1.5.
+* 27 Nov 1985
+C839\>764. Make `|plain|' a lowercase name, for consistency with the manual. @521
+I840\>669. Wake up the terminal for |\show| commands. @1294,1297
+# The above changes were incorporated in Version 2.0, which was published
+ as Volume~B of the {\sl Computers \& Typesetting\/} series.
+* 15 Dec 1986
+I841. Punctuate the Poirot help message more carefully. @1283
+* 28 Jan 1987
+R842. Make sure that \\{max_in_open} doesn't exceed 127 (DRF). @14
+D843\>680. Don't allow a |\kern| to be clobbered at the end of a pre-break list
+ when a discretionary break is taken. (A missing `{\bf else}' was the
+ source of the error, diagnosed incorrectly before.) @881
+D844. Take account of discarded nodes when computing the background width
+ after a discretionary. @840
+# That was the first really serious bug detected for more than 17 months! I found it
+ while experimenting with right-to-left extensions.
+# Version 2.1 was released on January 26, 1987.
+* 5 Feb 1987
+E845. Remove cases in \\{shorthand_def} that cannot occur (found by Pat Monardo). @1224
+* 14 Apr 1987
+R846. Improve robustness of data structure display
+ when debugging (Ronaldo Am\'a). @174,182
+* 21 Apr 1987
+E847. Make the storage allocation algorithm more elegant and efficient. @127
+* 22 Apr 1987
+A848\>742. Calculate the empty-line condition properly when \\{end_line_char} is
+ absent. @360
+# The previous three changes were found while I was teaching a class based
+ on Volume~B; they led to Version 2.2.
+* 28 Apr 1987
+E849. Avoid closing a file when \TeX\ knows that it isn't open (JS). @560
+* 3 Aug 1987
+S850. Clean up unfinished output if it's necessary to
+ \\{jump_out} (Klaus Gunterman). @642
+# That makes Version 2.3; subsequent version numbers won't be logged here.
+* 19 Aug 1987
+A851. Indent rules properly in cases like\hfil\break
+ |\hangindent=1pt$$\halign{...\cr\noalign{\hrule}}$$|. @806
+* 20 Aug 1987
+S852. Introduce \\{co_backup} because of cases like
+ |\hskip 0pt plus 1fil\ifdim| (Alan Guth). @366
+* 9 Nov 1987
+S853. Change the calculation for number of leader boxes, so that
+ it won't be too sensitive to roundoff error near exact multiples
+ (M. F. Bridgland). @626
+* 17 Nov 1987
+A854. Replace my stupid algorithm
+ for fixed-point multiplication of negatives (WGS). @572
+* 12 Dec 1987
+B855. Fix a typo in the initialization of hyphenation tables (PB). @952
+# That error was almost completely harmless, thus undetectable,
+ except if some |\lccode| is~1 and no |\patterns| are given.
+* 23 Dec 1987
+S856\>564. Be more cautious when ``relaxing'' a previously undefined |\csname|;
+ you might be inside a group (CET). @372
+* 20 Apr 1988
+S857. Make sure \\{temp_head} is well-formed whenever it can be
+ printed in a ``runaway'' message: Consider constructions like
+ |\outer\def\a0{}\a\a| (Silvio Levy). @391
+* 24 Apr 1988
+S858\>618. Avoid conflicting use of the string pool in constructions like
+ |\def\\#1{}\input a\\\z| (Robert Messer). @260
+* 10 May 1988
+R859. Amend the |\patterns| data structure when $\\{trie_min}=0$
+ (PB). @951,953
+* 25 May 1988
+R860. Guarantee that \\{trie_pointer} cannot be out of range. @923
+S861\>618. Avoid additional bugs like \#858 in constructions
+ like |\input a\romannumeral1|, etc. @464,465,470
+R862\>618. Prevent similar string pool confusion that could occur
+ during the processing of |**\input\romannumeral6|. @525
+* 19 Jun 1988
+S863\>819. Prevent a negative dividend from rounding upward,
+ causing a loop (CET). @126
+E864\>819. Adopt a smoother allocation strategy when
+ memory is nearly gone (CET). @126
+* 20 Jun 1988
+D865\>852. Initialize \\{cur_order}, now that it's being backed up
+ (Tsunetoshi Hayashi). @439
+* 6 Nov 1988
+S866\>612. Disable \\{fatal_error} in \\{prompt_input}, so that
+ \\{open_log_file} can use it safely (Tim Morgan). @71
+S867\>836. Force terminal output whenever \\{open_log_file} fails. @535
+* 14 Dec 1988
+P868\>866. Restore \\{fatal_error} in \\{prompt_input}, but don't
+ let it be unsafe for \\{open_log_file}. @92,534
+* 23 Jan 1989
+D869. Give $q$ a legal value when recovering from ``infinite shrinkage''
+ error. @976,1004
+* 17 Feb 1989
+D870\>758. Avoid spurious error message for |\aftergroup\relax\dump| by avoiding
+ inaccessible |\aftergroup| tokens (FM and Rainer Sch\"opf). @280
+* 20 Mar 1989
+R871. Don't refer to \\{link}(\\{null}) even when it ``can't happen''
+ (PB). @791
+* 7 Jun 1989
+S872. Avoid confusion from |$$\begingroup\halign{#\cr}$$| (FM). @1130
+* 20 Jun 1989
+S873. Put fraction digits into dynamic memory, not the global \\{dig} array,
+ because of constructions like |.5\ifdim.6| (FM). @452
+* 17 Jul 1989
+S874. Prevent embarrassing attempts to report errors before the string
+ mechanism has been fully initialized, for example when the
+ command line exceeds the buffer size (WGS). @31
+* 16 Aug 1989
+M875. Allow integer products to be 31 bits long (FM). @105
+* 31 Aug 1989
+C876\>441. Increase the number of tokens shown by \\{token_show}
+ (J. Lavagnino). @295
+S877. Avoid confusion from |$$\begingroup\eqno$$| (FM). @1140
+# The recent TUG meeting turned out to be an extend-\TeX-for-the-nineties
+ party! I agreed that some extensions for non-English languages
+ ought to be made while I still knew how to do them. (In other words,
+ I broke my firm commitment to keeping \TeX\ completely stable;
+ but in this case nobody objected.) The following eleven changes
+ were coded during the month of September.
+* 30 Sep 1989
+G878. Install major change allowing general 8-bit code input. @38,352
+G879. Install major change allowing multiple hyphenation tables
+ (M. Ferguson). @923
+G880. Introduce new parameters |\lefthyphenmin| and |\righthyphenmin|. @923
+G881. Introduce major new ligature capabilities including implicit
+ boundary characters. @908,1037
+G882. Install new |\inputlineno| feature suggested by MDS. @424
+G883. Install new |\holdinginserts| feature suggested by FM. @1014
+G884. Install new |\badness| feature. @424,664
+G885. Install new |\emergencystretch| feature. @863
+G886. Install new |\errorcontextlines| feature suggested by FM. @311
+S887. Recover from anomaly when hyphenation |char_warning| clobbers
+ |old_setting|. @863
+P888. Make it easier to change the format extension (Don Hosek). @520,1328
+* 16 Oct 1989
+R889. Avoid range check in null font with |bc=256| (PB). @565
+* 22 Nov 1989
+S890\>856. Prevent \\{save_stack} conflicts in
+ |{\hbox\expandafter{\csname\endcsname}}| and\kern-3pt\break
+ similar constructions (WGS). @645,1117
+S891\>858. System-dependent parts of file names must be addressed relatively,
+ not absolutely (FM and Rainer Sch\"opf). @516,517
+* 3 Dec 1989
+G892\>880. Allow different hyphenmins in the same paragraph (M. Ferguson). @1376
+S893. Distinguish |\par| from characters on |\if| tests. (MVL). @334
+S894\>378. Alignments need to be more robust against malicious
+ attacks (MVL). @782
+C895. Don't let kerns in discretionaries disappear at breaks (MVL). @869
+Q896\>881. Make the new hyphenation reconstruction procedure less cautious,
+ so that it doesn't lose hyphens found by the old method. @914
+* 11 Dec 1989
+D897\>879. Make an undumped trie dumpable again (PB). @1325
+* 18 Dec 1989
+G898\>588. Allow access to page totals in |\output| routines
+ (FM and Chris Rowley). @421
+* 22 Jan 1990
+R899\>611. Recognize more cases of unbalanced |\output| (CET). @1026
+* 29 Jan 1990
+S900\>758. Make |\aftergroup| work properly after |\eqno| (Michael Downes).
+ @1194
+* 1 Feb 1990
+S901\>878. Fix one more case of \\{end_line_char_inactive} (WGS). @360
+* 22 Feb 1990
+R902. Don't lose the last active node when total demerits are very high (FM).
+ @836,854
+* 13 Mar 1990
+D903. Doublecheck math fonts after making equation number (MVL). @1194
+D904. Don't forget to rule out charnodes before testing \\{type} (MVL).
+ @805,1202
+* 23 Mar 1990
+F905\>881. Don't change the font of punctuation preceding a hyphenated word
+ (Scott C. Allendorf). @903
+I906. Balance the parentheses shown on the terminal during normal runs. @1335
+E907. Optimize |\ifx\p\q| after |\let\p=\q| (MVL). @508
+S908. Treat migration properly in displays (MVL). @1199,1205
+# We're now up to Version 3.0; I sincerely hope all bugs have been found.
+* 11 May 1990
+F909\>881. Initialize |\nullfont| ligature parameters (Lance Carnes). @552
+* 22 July 1990
+S910\>579. Treat |\prevgraf| as zero within |\write| (Bogus\l aw Jackowski).
+ @422
+* 26 July 1990
+S911. Report `|l.1|' when first line of file overflows buffer
+ (George Russell). @538
+* 5 December 1990
+S912\>878. Translate unprintable characters in font identifiers (WGS). @63
+* 28 December 1990
+R913. Avoid range check when there are 65536 or more pages (Eberhard Mattes).
+ @642
+* 20 September 1991
+I914\>878. Improve error message for |\mathchar| out of range. @436
+S915\>878. Retain unprintable internal strings in 8-bit form (FM). @59
+S916\>881. Retain right punctuation context for ligature reconstruction
+ (problem found by Brian Hamilton Kelly). @903
+* 10 January 1992
+S917\>881. Also avoid producing a double kern at boundary (CET). @897
+S918. Disallow |\setbox| where it doesn't work (Robert Hunt). @1241,1270
+S919. Robustify |\mskip| and |\mkern| in presence of negative quad (WGS).
+ @716,717
+S920\>679. Defend against `|}{|' in |\read| (Michael Downes). @483
+E921\>798. Save string memory if font occurs repeatedly (Bogus\l aw Jackowski).
+ @1260
+S922\>784. Don't let |\newlinechar| interrupt unprintable expansion (Bernd
+ Raichle). @59,60
+* 7 February 1992
+D923\>881. Restore |cur_l| properly when boundary character doesn't exist
+ (Mattes and Raichle). @1036
+* 17 July 1992
+C924\>892. Use current language at beginning of horizontal mode (Rainer
+ Sch\"opf and CET). @1091,1200
+* 17 December 1992
+R925\>879. Avoid (harmless) range errors (Philip Taylor and CET). @934,960
+* 25 February 1993
+C926\>881. Protect kerns inserted by boundary characters (William Baxter).
+ @837,866
+S927\>917. Don't let boundary kern disappear after hyphenation. @897
+* 26 June 1993
+R928\>668. Avoid potential future bug (Peter Breitenlohner). @628,637
+* 17 December 1993
+S929\>881. Boundary character representation shouldn't depend on the font
+ memory size (Berthold Horn). @549,1323
+* 10 March 1994
+R930. Huge font parameter number may exceed array bound (CET). @549
+* 4 September 1994
+F931\>926. Math kerns are explicit (Walter Carlip). @717
+R932. Avoid overflow on huge real-to-integer conversion. @625,634
+* 19 March 1995
+R933. Avoid spurious reference counts in format files (PB). @1335
+* 23 November 1998
+R934. Make sure that TeX is certifiably Y2K-safe. @1328
+* 12 July 1999
+A935\>255. |\xleaders| often drops the final box (Hiroshi Nakashima). @627,636
+* 30 August 2001
+R789. Don't allow a million unbalanced braces followed by |\cr|
+ outside of any alignment (Ralf Roth). @789
+R790. Don't allow end-template except at end of template (Roth). @325,1131
+* 30 September 2002
+Q791. Improve rounding of glue during output (M. F. Bridgland). @625,634
+\relax
+\bye
+
+Up to a point it is better to let the snags [bugs] be there
+than to spend such time in design that there are none
+(how many decades would this course take?).
+-- A M Turing
+ Proposals for Development in the Mathematics Division
+ of an Automatic Computing Engine (ACE)
+ Report E882, Executive Committee, National Physical Laboratory (NPL)
+ 1945; reprinted in April 1972 as NPL report Com Sci 57
+ page 18
+ quoted by Carpenter and Doran in The Computer Journal 20 (1977), 273.
+
+DRF David Fuchs
+HWT Howard Trickey
+FY Frank Yellin
+LL Leslie Lamport
+JS Jim Sterken
+ARK Arthur Keller
+CET Chris Thompson
+FM Frank Mittelbach (added subsequent to publication of paper)
+PB Peter Breitenlohner (ditto)
+WGS Wayne G. Sullivan (ditto)
+MVL Marc van Leeuwen (ditto)
+MDS Michael D. Spivak (ditto)
diff --git a/Master/texmf-doc/doc/english/knuth/errata/index.html b/Master/texmf-doc/doc/english/knuth/errata/index.html
new file mode 100644
index 00000000000..aaf02bf7b79
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/index.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<TITLE>Index of texmf/doc/general/errata/</TITLE>
+<!-- Created: UV, 1996/02/24 -->
+</HEAD>
+
+<BODY>
+<H1><IMG ALT="" SRC="../../html/icons/tex.xbm">
+ <IMG ALT="" SRC="../../html/icons/mf.xbm">
+ Index of <CODE>texmf/doc/general/errata/</CODE></H1>
+
+<HR>
+
+<H2>Errata in <CITE>Computers &amp; Typesetting</CITE></H2>
+<DL>
+ <!-- Note: files have been renamed to avoid name conflicts -->
+ <!-- since errata.{one,two,...,tex} all produce errata.dvi -->
+
+ <DT><A HREF="errata1.dvi">errata1.dvi</A><BR>
+ <DD>Errata in the first printing of <CITE>The TeXbook</CITE>
+ (October 1984)
+ <DT><A HREF="errata2.dvi">errata2.dvi</A><BR>
+ <DD>Errata in the second printing of <CITE>The TeXbook</CITE>
+ (January 1986)
+
+ <DT><A HREF="errata3.dvi">errata3.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ (15 June 1987)
+ <DT><A HREF="errata4.dvi">errata4.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ (20 Feb 1989)
+ <DT><A HREF="errata5.dvi">errata5.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ (30 Sep 1989)
+ <DT><A HREF="errata6.dvi">errata6.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ (31 Dec 1990)
+ <DT><A HREF="errata7.dvi">errata7.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ (15 March 1992)
+ <DT><A HREF="errata8.dvi">errata8.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ until the pubDTcation of the final printings.
+
+ <DT><A HREF="errata.dvi">errata.dvi</A><BR>
+ <DD>Errata in <CITE>Computers &amp; Typesetting</CITE>
+ since the pubDTcation of the final printings.
+</DL>
+<BR>
+
+
+<A HREF="../../index.html"><IMG SRC="../../html/icons/back.xbm"></A>
+<HR>
+<ADDRESS></ADDRESS>
+<!-- hhmts start -->
+Last modified: Sun Feb 25 16:02:20 MET 1996
+<!-- hhmts end -->
+</BODY>
+</HTML>
diff --git a/Master/texmf-doc/doc/english/knuth/errata/logmac.tex b/Master/texmf-doc/doc/english/knuth/errata/logmac.tex
new file mode 100644
index 00000000000..8719efc497d
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/logmac.tex
@@ -0,0 +1,107 @@
+% macros for the appendix to "Errors of TeX" paper
+\input manmac
+\voffset=-.3in
+\catcode`\^=7 % disable the indexing stuff
+\font\sltt=cmsltt9
+\font\logosl=logosl9
+\ninepoint
+\vsize=48pc \pageheight=\vsize
+\hsize=33.5pc
+
+\def\\{\bgroup\catcode`_=\active\identifier}
+{\catcode`_=\active \global\let_=\_}
+\def\identifier#1{\hbox{\it#1\/\kern.05em}\egroup} % italic type for identifiers
+
+\newdimen\codesize \setbox0=\hbox{\enspace M} \codesize=\wd0
+\setbox0=\hbox{\thinspace\S1111\kern\codesize} \rightskip=\wd0
+\newdimen\itemnosize \setbox0=\hbox{\bf999} \itemnosize=\wd0
+\setbox0=\hbox{$999\mapsto{}$\kern\itemnosize\enspace} \parindent=\wd0
+\newdimen\datemar \setbox0=\hbox{\bf 15 Mar 1977}
+\datemar=\hsize \advance\datemar-\wd0 \divide\datemar2
+\newdimen\hangamount \hangamount=\parindent \advance\hangamount 1em
+\everypar{\global\hangindent=\hangamount}
+\parfillskip=-\rightskip
+\finalhyphendemerits=0
+\interlinepenalty=100
+\smallskipamount=3pt plus 2pt
+\def\smallbreak{\fin\penalty-50\smallskip}
+
+\newbox\predec % for predecessor "mapsto" info
+\newbox\code % for the code letter
+\newbox\texsec % for TeX section numbers
+\newbox\cbox % the symbol used on commentlines
+\newbox\dbox % empty box used after datelines
+\setbox\dbox=\hbox to\datemar{}
+\setbox\cbox=\hbox to\itemnosize{\hfil$\bullet$}
+
+\newif\ifnothing \newif\ifnobreak
+\def\fin{\ifnothing\nothingfalse\else\endgroup
+ \unskip\nobreak\hfil\penalty500\enspace\null\nobreak\hfil\box\texsec
+ \box\code\endgraf\ifnobreak\nobreakfalse\nobreak\fi\fi}
+
+\catcode`\ =12 % tabs are ordinary characters
+\catcode`@=\active % @ signs denote a TeX section reference
+{\obeylines \gdef@#1
+ {\global\setbox\texsec=\hbox{\S$#1$}\lookahead}}
+\chardef\@=`\@
+{\catcode`X=\active \gdef X{\X}}
+\def\X{{\eightbf X}}
+\def\lightX{\hbox{\eightrm X}}
+\def\>#1\relax{\global\setbox\predec=\hbox{\let\X=\lightX
+ $#1\mapsto{}$}} % previous bug ref
+
+\def\checkvalid#1{\expandafter\ifx\csname#1!\endcsname\okay\else\invalidcode\fi}
+\def\okay{\okay}
+\def\makevalid#1{\expandafter\let\csname#1!\endcsname=\okay}
+\makevalid A % algorithm
+\makevalid B % blunder
+\makevalid C % cleanup
+\makevalid D % data structure
+\makevalid E % efficiency
+\makevalid F % forgotten case
+\makevalid G % generalization
+\makevalid I % interaction
+\makevalid L % language
+\makevalid M % mismatch
+\makevalid P % program organization
+\makevalid Q % quality
+\makevalid R % robustness
+\makevalid S % surprise
+\makevalid T % typo
+
+\def\lookahead{\futurelet\next\looky} % we'll do this at end of every line
+\def\looky{\if\next \let\cont\continuationline % tab mark
+ \else\if\next*\let\cont\dateline % asterisk
+ \else\if\next##\let\cont\commentline % sharp sign
+ \else\if\next\relax\let\cont\endit % \relax (gets us out)
+ \else\let\cont\dataline\fi\fi\fi\fi\cont} % otherwise should be a code letter
+\def\continuationline { } % insert space if a tab mark starts the next line
+\def\dateline* {\smallbreak\begingroup\bf\hfill\nobreaktrue
+ \global\setbox\code=\copy\dbox}
+\def\dataline#1{\fin\checkvalid#1%
+ \global\setbox\code=\hbox to\codesize{\enspace
+ \hskip0pt plus 3fil\rm#1\hskip0pt plus1fil}%
+ \begingroup\rm\catcode`X=\active\itemnumber}
+\def\itemnumber#1.{\catcode`X=11\setbox0=\hbox to\itemnosize{\bf\hss#1\relax}%
+ \setbox2=\hbox{\bf#1\relax}\ifdim\wd2>\wd0 \setbox0=\box2 \fi
+ \textindent{\hfil\box\predec\box0}}
+\def\commentline{\fin\afterassignment\begincomment\let\next}
+\def\begincomment{\begingroup\let\tt=\sltt
+ \let\MF=\slMF\sl\textindent{\hfil\copy\cbox}}
+
+\def\leftheadline{\hbox to \hsize{%
+ \vbox to 10pt{}% strut to position the baseline
+ {\tenrm\folio\kern1pc}% folio to left of text
+ \hfil\eightrm D. \ E. \ KNUTH\hfil% running head
+ }}
+\def\rightheadline{\hbox to \hsize{%
+ \vbox to 10pt{}% strut to position the baseline
+ \hfil\eightrm THE \ ERRORS \ OF \ \TeX\hfil% running head
+ {\kern1pc\tenrm\folio}% folio to right of text
+ }}
+
+\def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
+\def\slMF{{\logosl META}\-{\logosl FONT}}
+
+\def\endit{\fin\catcode`\^^M=5\let\par=\endgraf}
+\let\par=\lookahead \obeylines \nothingtrue
diff --git a/Master/texmf-doc/doc/english/knuth/errata/mf84.bug b/Master/texmf-doc/doc/english/knuth/errata/mf84.bug
new file mode 100644
index 00000000000..aaa36b33da8
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/mf84.bug
@@ -0,0 +1,2279 @@
+This file has been updated periodically ever since METAFONT84 was born.
+What you are about to read is "authentic source material" from the
+early days before the program converged. Module numbers on the first
+entries may bear little relation to those in Volume D.
+
+Entries are in chronological order; thus the most recent news appears
+at the bottom of the file.
+
+-------------------------------------------------------------------------------
+
+(rough list of all bugs found in MF after it passed syntax check)
+Starting with Version -100.0: [Mar 27, first run, about 00:30]
+1. fix_date_and_time was badly patched in INIMF.
+2. cur_tok function forgot "cur_tok:=p" at the end; PASCAL doesn't catch that.
+3. "multiletter control sequences" msgs should say "symbolic tokens".
+Version -99.0: [still Mar 27, done while waiting for WEAVE/TeX output]
+4. do_statement should initialize cur_type:=vacuous.
+5. find_variable has misplaced p:=equiv(p).
+6. one-character primitives shouldn't decrease str_ptr.
+7. clear_symbol had "q" at end where I meant to say "p".
+8. help message for extra token flushing improved.
+9. "buffer[k]" should be "buffer[j]" for 1-character id_lookup.
+10. def_delims forgot to get_next afterwards.
+11. type_command at beginning of statement wasn't diverted.
+12. menu always came out after help message.
+13. forgot to return after getting num/str token from token list.
+ Version -98.0: [March 28]
+14. scan_declared_variable flushes too much.
+15. ordered pairs: one level of indirection was forgotten.
+16. type declarations must add "unknown" bit.
+17. semicolon+ added to do_statement cases.
+18. base_ident should get max_str_ref.
+19. "internal[...]" missing in date for base_ident.
+20. do_binary(p,c) should be do_binary(p,d) after continue_path
+21. in scan_def after get_clear_symbol I need to get_next.
+22. get_next needed at end of scan_def.
+23. get_next needed at end of mode_command processing.
+24. randomseed missing error typo: `;' for `:='.
+25. print_nl("") at beginning of show.
+26. refcounts on macro calls were incremented twice.
+27. forgot to advance loc after getting num/str token from token list.
+28. "/" has the wrong command code.
+29. get_x_next needed after, e.g., "1/2" in scan_primary.
+30. take_fraction should be make_fraction in call of frac_mult.
+31. v:=dep_list(v) forgotten in dep+dep branch of add_or_subtract.
+32. q:=link(q) etc misplaced and omitted in p_plus_fq and p_plus_q.
+33. dep_finish recycled a dependency list twice.
+34. call of dep_finish should use null not cur_exp.
+35. decided that "3 3" shouldn't equal 9.
+[also put in new code for the addto command]
+ Version -97.0: [March 29]
+36. forget to set q:=qq in scan_expression.
+37. first line of print_path: forgot print_ln.
+38. typo in set_controls: right_y should be left_y.
+39. toss_knot_list forgot that it has a circular list to toss.
+40. print_exp shows big nodes backwards.
+41. angle brackets didn't look good in print_exp; took them out.
+42. left_brace must be between min_tertiary and max_tertiary.
+43. prev_dep should point back to tail, not head, of previous list.
+ (that error was in encapsulate and <Copy the big node>)
+44. nonlinear_eq should leave node p vacant, sometimes.
+45. conditional routine forgot that get_boolean starts with get_x_next.
+46. forgot get_x_next in processing of else.
+47. str_ref not initialized by make_string.
+48. param_start not initialized properly.
+49. "%EXPR" didn't look good in token list.
+50. "{loop}" not necessary in forever loops; there's already enough.
+51. macro name didn't come out right when tracing macros.
+52. macro parameters weren't shown when tracing macros.
+53. quote marks missing when displaying strings.
+54. parameter names on macro call trace should look nicer.
+55. statement beginning with bad token: error message needed.
+56. `->' desired in context lines of macro.
+57. forgot q:=loop_list_loc(s) in begin_iteration.
+[also put in new code for shipout]
+ Version -96.0: [March 30]
+58. forgot loop_type(s):=null in begin_iteration.
+59. forgot value(p):=null after type(p):=type(pp) in find_variable.
+60. forgot to delete_pen_ref after filling a contour.
+61. check that it's a cycle before calling make_spec.
+62. "if tracing_stats>0" should be "if internal[tracing_stats]>0"!
+63. forgot get_next after showdependencies.
+64. forgot link(r):=p at end of dependency list addition.
+65. extra `get_x_next' in <Scan a direction...>.
+66. typos in last half of <Remove open types...>: mind the p's and q's.
+67. take_fraction should be make_fraction in simple case of two givens.
+68. in print_exp of unknown type, stop if v=null.
+69. showtoken forgot to stop; also should be consistent with TeX.
+70. "continue" label needed in error routine, after all.
+71. id_lookup should treat length-one identifiers by simpler method.
+ (in particular, this allows it to find unprintable ones!)
+72. need psi[n+1]:=psi[1] in cyclic case of make_choices.
+73. tension/controls take primaries as arguments, not expressions.
+74. print_spec didn't initialize octant.
+75. print_spec: break lines into two, since they are quite long.
+76. smooth_moves not called in fill_spec.
+77. typo < for > in edge_prep.
+78. edge tracing misses half the corners, and forgot to set trace_y.
+79. edge_prep needs extra logic when rover=head.
+80. make_good should compute cur_d based on good values, not original values;
+ but we sometimes need the other alternative too.
+81. valid_sum: the test was backwards.
+82. print_weight blunder: ho(q) should be ho(info(q)).
+83. forgot init_gf in shipout.
+84. typo in <Finish the GF file>: if total_chars<>1 then print("s").
+85. initializations of ww, prev_w, and m were forgotten in ship_out.
+86. typos in initialization of prev_m and gf_min_x.
+87. forgot to update prev_n in ship_out.
+88. relax becomes "expandable".
+89. internal[x]>1 should be internal[x]>unity!
+90. forgot to restore normal scanner_status in pass_text.
+91. (end occurred when if...) was inevitable.
+[also put in new code for openwindow, display]
+ Version -95.0: [April 1]
+92. forgot to unscale the window numbers in that new code.
+93. had w<0 test instead of w<=0 in <Record a possible transition...>.
+94. prev_w:=w should be done in all cases of <Record a possible...>.
+95. forgot get_x_next after scanning `1/2'.
+96. in do_assignment, after recycle_value(p) I need to set type(p):=something.
+97. omit `.' after the equivalent in showtoken.
+98. in <Copy the big node p>, I said "until q=p"; I meant "until q=value(p)".
+99. print_macro_name said "info(link(a))"; meant "text(info(info(link(a))))".
+100. forgot get_x_next after macro_call in scan_primary.
+101. scan_primary installed dependent components badly (data structure error).
+102. new_structure failed in case of generic_subscript (data structure error).
+103. param_type case of print_cmd_mod had bad if/else nesting (language error).
+104. null_path forgot to return a value (language error).
+105. p_with_x_becoming_q had typos (q and f for x).
+106. <Copy the big node...> should end with cur_exp:=t, not r.
+107. subscripted definitions: out of sync; scan_primary loop needs revision.
+108. secondarydef went through scan_def instead of make_op_def.
+109. make_op_def forgot the final get_next.
+110. make_op_def also forgot to insert the general_macro preface.
+111. showvar shows too much of macro variables.
+ Version -94.0: [April 4]
+112. single_dependency needs to take account of the scale factor.
+113. add_or_subtract starts out with wrong v value. [bug 31 was fixed wrong]
+114. print_exp needs a case for t=independent.
+115. also numeric_type, and case v=null of pair_type, transform_type.
+116. end_token_list thought identity_macro and insertions had ref counts.
+117. disp_var should display also in case of generic subscripts.
+118. find_var should put value(pp):=null when it sets type(pp):=numeric_type.
+119. yet another problem in <Copy the big...>: copy_dep_list(dep_list(q)).
+120. scan_primary should flush_node_list(q) before make_exp_copy(p).
+121. make_scaled arguments reversed in p_over_v.
+[also added code for new internals: smoothing, autorounding]
+[also added code for showstats]
+ Version -90.0: [April 5]
+122. Should check range of variables when they become known.
+123. <Exclaim about...> should include begin...end (WEB language error).
+124. forever should be followed by a colon.
+125. dangling else problem in make_eq: "abc"="abc" considered false.
+126. showstats, showtoken should read the semicolon before stopping.
+127. print_variable_name balked at, e.g., xpart of a capsule.
+ Version -89.0: [April 6]
+128. after &foo, shouldn't assume there's an input file present.
+129. forever forgot get_next.
+130. pair=path and path=pair should coerce the pair to be a path.
+131. similarly in the operand to `addto'.
+[added new code for cull command]
+[minor revision of internal quantities; e.g., labeling is out, fontmaking is in]
+ Version -88.0: [April 7]
+132. "string" operator is renamed "str".
+133. min/max coordinates added to boc command.
+134. labeling_command removed; it will be implemented in macros.
+135. info(p) should be attr_loc(p) in flush_variable.
+136. make_spec didn't realize the need for xh and yh.
+137. gf_new_row parameters had sign reversed.
+138. the "numeric" case was left out of recycle_value.
+[added new code for special/numspecial]
+ Version -87.0: [April 13]
+139. q:=qq should apply also after <Splice...>, in scan_expr.
+140. param_size: better defined than a constant.
+141. surprise: back_input fails when cur_cmd=expr_arg, as it changes limit.
+142. <Subdivide...second time wrt x'-y'> forgot to change right_type(r).
+143. show <path> shows the whole path.
+144. expr like 0..1 leads to <Determine the path join...> with q undefined.
+145. typos in <Decide...clockwise>, clobbered dx2 and used right_type(p) twice.
+146. need to adjust expr_arg when macro is inside a macro!
+147. expr_arg forbidden to be in a text argument.
+148. frozen_relax added to prevent premature termination.
+[I took out the code used for debugging the screen interface]
+[added "cycle", a unary operator taking path to boolean]
+[added the code for concatenation and for str and for xpart..yypart]
+ Version -86.0: [April 25]
+149. not_scolded_yet was never set false after scolding.
+150. Missing "q:=s" at the end of <Make variable q known>.
+151. In @<Worry...@>, add get_next after back_error.
+152. New xpart routine didn't recycle other components of the big node.
+[added the "hard_times" case of multiplication]
+[added the complete set of boolean expressions]
+[added the eight transformations, applied to three kinds of expressions]
+[added the save command]
+[added the interim command]
+[added the let command]
+[added the pen operations]
+153. Incomplete help message on "Not a variable".
+154. forgot begin...end in the last section of materialize_pen.
+155. blunder <Insert a new line...>: length(p,s,q) should be length(s,q,r).
+156. <Construct the offset...>: forgot begin...end here too.
+157. "(newly created)" shd be " (newly created)".
+158. path_trans: forgot to unstash the capsule p.
+159. set_up_trans: transform_type should be transformed_by, in one place.
+160. <Install sines...>: had p instead of q, in several places.
+161. edges_trans: an edges variable isn't in a capsule.
+ Version -85.0: [May 2]
+162. begingroup ... endgroup should be allowed as compound statement.
+163. pausing shouldn't clobber "showit". (WAITS version only)
+164. Improved help message for isolated expressions.
+165. Bad error recovery after "Not a variable" in showvar.
+166. Typo in clear_symbol: name_type(p) instead of name_type(q).
+167. "%" and ";" to be left out of file names being input.
+168. dep_finish used v for two purposes; wrong declared type.
+169. autorounding 2 suppresses correction when the derivative isn't critical.
+170. tab characters should be changed to spaces on input. (WAITS version)
+171. harmful goto: Forgot to |return| after path_trans and edge_trans.
+[added ord, hex, oct, length, char, decimal, and jobname]
+ Version -80.0: [May 4]
+172. showvar still screwed up.
+173. don't clobber screen for prompt_input (WAITS only).
+174. length of non-cyclic path is one too high.
+175. <Evoke an error message...> evoked the wrong message.
+176. better error message needed on `Equation cannot be performed'.
+177. ">> " inserted before expression displays.
+178. <Finish linking...> should dup_offset also when n=0.
+179. pencircle was a factor of 2 too big.
+180. cosine of 180 should be -1 exactly.
+181. ord "" should be -1.
+182. shipout should allow expressions as well as variables.
+183. "mod outer_tag" needed in various tests on eq_type.
+184. merge_edges forgot to adjust for changes in m_offsets.
+185. typo, ww for w in print_pen.
+186. typo, "outer" for "errhelp" in print_cmd_mod (message case).
+[added "also"]
+[added "message", "errmessage", "errhelp"]
+[added "outer", "inner"]
+[added "readterminal", "readstring"]
+ Version -79.0: [May 6]
+187. read_toks forgot to include the general_macro token.
+188. offset_prep should treat n=0 like n=1.
+189. cusp transitions (from change 169) must be suppressed in envelope case.
+190. <Record a line segment...> shouldn't change xp or yp.
+191. <Find the initial slope...> was used too late.
+192. <Find the index...> had a redundant test (a relic of old code).
+193. <Compute test coeff...> wastefully made the same fraction three times.
+194. doublepath <cycle> should split the cycle.
+195. `if k=0' in fin_offset_prep should have been `if k=1'.
+196. `done:' misplaced in <Make the envelope moves...>.
+197. also move[move_ptr] should be initialized to 1 there, not 0.
+198. skew is used with p=q in fill_envelope.
+199. it's no use tracing subdivision for offsets, since everything is skewed.
+200. in <Record a line...>, round_unscaled should be floor_unscaled.
+201. unskewing: wrong formula (x was .5 too large).
+202. elliptical pens: better correction for the case gamma<=abs(alpha).
+203. dual env_move was updated badly, in both <Transfer...> and <Record...>.
+204. dual env_move to move: subscripts were off by 1.
+205. <Insert...dually...> should set ww:=knil(link(h)), not link(h).
+[added ++]
+ Version -70.0: [May 9]
+206. suppressed cusp rounding in envelope case too.
+207. `show' should use `>> ' when it shows an expression.
+208. streamlined the test for bad lambda and mu in |skew|.
+209. after linear_eq, must check if type(cur_exp)=known.
+210. print_spec surprise: contours might never travel toward the first octant!
+211. t0,t1,t2 sign was reversed in <Complete the offset splitting...>.
+ Version -69.0: [May 10]
+212. "showvar" changed to "showvariable".
+213. typo: r for r_delim in <Scan a text parameter...>.
+214. "newinternal" feature added.
+215. <Record a line...dually...> needs to update envmove at end of loop.
+216. smooth_moves shouldn't affect the extreme points.
+217. floor(unity*(n-1)/n) is unity when n is large; need to be more careful.
+218. major improvements to rounding, based on new theory of (x+eps,y+eps^2).
+219. pen offsets made symmetrical about the origin.
+220. p:=half(p+q) overflow problem in take_fraction, take_scaled.
+221. cull_edges now updates the max/min values too.
+222. make_spec needs to be more bullet-proof to rounding errors; added `dest's.
+223. xmult/ymult/zmult changed to xscaled/yscaled/zscaled.
+224. elliptical pens improved by temporarily allowing zero-length lines.
+[added edge transposition algorithm]
+ Version -67.0: [May 17]
+225. copy can encounter a vacuous expression, e.g. in a parameter.
+226. xy_swap_edges mustn't change w when inserting a large weight.
+227. in #222, had typo pp for r in <split ... second time ... x'-y'>.
+228. in #222, incorrectly assumed local max = global max of cubic.
+ Version -66.0: [May 19]
+229. bad_binary(c,p) should have been bad_binary(p,c).
+230. enabled comparison of unknown strings.
+231. fixed ring_delete to avoid unexpected scolding.
+232. should store character width info even when proofing<0.
+[added all the TFM commands and output routines]
+[added the `substring' operation]
+[added `point', `precontrol', `postcontrol'; deleted `direction']
+ Version -65.0: [May 24]
+233. Change error message `(t)point(u)' to `point(t)of(u)'.
+234. newinternal to allow a list of tokens.
+235. In <Feed...>, should check for overflow before begin_token_list.
+236. scan_def didn't allow for the case warning_info=null.
+ Version -60.0: [May 25]
+237. increased param_size.
+238. added <boolean><relation><boolean>.
+239. <Remove dead cubics> stopped too early if the first cubic was dead.
+240. bad_unary, bad_binary should distinguish pair from unknown pair.
+241. yet another "m<env_move[move_ptr]" test needs to be inserted.
+242. newinternal names need to go in the dump file.
+243. delete_mac_ref(v) should be delete_mac_ref(value(p)) in recycle_value.
+244. constant in <Decide...clockwise> was scaled instead of fraction.
+ Version -59.0: [May 27]
+245. break up initialize routine into two parts (cf init_prim in TeX)
+ Version -58.0: [May 28]
+246. do_ship_out should scan_expression, not scan_primary.
+247. offset_prep might clobber node q, so we need to search for q again.
+248. pair "1" = true! (blunder in type_test)
+249. allow strings x in `def f(expr x)=def g=x enddef enddef'.
+250. allow exprs in text parameters, in sufficiently easy cases.
+251. check right delimiters in macro_call.
+252. "Bad window number" message gave unscaled value.
+253. turnaround feature improves automatic rounding slightly.
+254. primaries changed to expressions in window and cull commands.
+255. scan_expression should make (0,0){0,0} a path, not a future path.
+256. showvariable and showtoken to allow lists; all shows made consistent.
+257. new internal quantity "windingcheck".
+258. delete warning message about edges never used.
+259. vardef: group the righthand side.
+260. show commands stop once each.
+261. cur_type should be vacuous after equation or assignment on outer level.
+ Version -57.0: [June 4]
+262. added xyzzy diagnostic about effect of autorounding.
+263. make_moves now puts xi_corr,eta_corr into halving.
+[otherwise "draw (0,0)..(9,-.00002)" and "draw (0,-.00002)..(9,0)" fail badly!]
+ Version -56.0: [June 6]
+264. smooth_moves changed completely; now is LR symmetric, cleaner.
+265. changed "unknown" to "known".
+266. pair to path conversion now done on length, makepen, reverse, etc.
+267. cycle now defined on arguments of any type.
+268. (re 218) sign was flipped in ceiling correction of <insert downward...>.
+[added union, subpath, penoffset, directiontime, intersectiontimes]
+
+Note: the first two draw statements in PENS.mf show an interesting effect.
+With autorounding, the curves are noticeably better, esp the small one.
+But there are two "holes", because of tiny discrepancies that I believe
+are unavoidable.
+Added later: Actually these are avoided by the new smooth_moves, but
+certain others will not be.
+ Version -50.0 [June 30]
+269. smoothing to be shut off at the retrograde transitions
+270. more care needed in the rootfinding part of find_direction_time.
+271. improved error recovery after "Isolated expression".
+ Version -40.0 [July 3] --- the first version to be "complete"!
+272. trivial change in <Exit...if the derivative $B(x_1,x_2,x_3;t)$...>.
+273. check that halfwords are large enough to hold edge/weight data.
+274. `path reverse (0,1)' should be true.
+275. xy_swap_edges might empty the structure; then x_reflect will fail!
+276. fix_offset was being done too often, due to improper range test.
+277. parameters come out even when tracingonline=0.
+278. step-until wasted r and didn't check syntax carefully.
+279. <Scan a group...> had typo: `line' for `group_line'.
+280. "You can't dump in a group" error was impossible.
+281. need better ETC cutoff in showmacro.
+282. print_exp needs to handle independents, because it's used by disp_var.
+283. suppress `#### xpart %CAPSULEnnnn' printouts.
+[added code for everyjob; this version wasn't complete after all!]
+ Version -30.0 [July 9]
+284. need better error/help after ` if s1=s2' when the strings are unknown.
+285. removed autorounding>2; it was leading to more glitches than it was worth.
+286. envelope filling of a cycle to be done by two calls of fill_envelope.
+287. "null" changed to "vacuous".
+288. cyclic path inserted in another path should retain its last arc.
+289. introduce several dozen "put_get" errors for improved recovery.
+290. suppress "with autorounding" when autorounding hasn't been set.
+291. {loop value} came out even when tracingonline=0.
+292. show commands should wake up the terminal before showing their output.
+293. forgot error message in `if true else'.
+ Version -20.0 [July 14]
+294. need to catch pens that are too large.
+295. make_eq dassn't change lhs (because this clobbers the memory links later).
+296. string usage is reported too high by showstats.
+297. bilin1 and add_mult_dep can call p_plus_fq with type(q)=proto_dependent.
+298. <Transform a known big node> forgot to recycle pp.
+299. in change number 286, the weight of the two paths should be the same.
+300. print_ln sometimes changed to print_nl("") in order to avoid blank lines.
+301. xyzzy to be combined with tracingedges.
+302. good3 entries should be 1 and 2 (not 1 and 0), to give desired symmetry.
+ Version -10.0 [July 17]
+303. had to add `new_if_limit' to `conditional'.
+304. `else' can be incomplete as well as `if' and `elseif'.
+305. new help "You can't redefine a parameter."
+306. print_edges should use cur_edges, because print_weight does.
+307. cull shouldn't round; it should use ordinary inequalities.
+308. obliterated variable left `0' token hanging in scan_primary.
+309. forgot recycle_value(p) in <Evoke...>.
+310. forgot to check improper culling amounts.
+311. `on' to be changed to `inwindow'.
+312. >=max_tfm_dimen should be simply >.
+ Version -9.0 [July 19]
+313. max_tfm_dimen needs to be decreased by design_size div 2^21.
+314. merge test data reporting into the screen display routines.
+315. use @# in printout at time of macro expansion tracing.
+316. bad recovery after "Incomplete string" error.
+317. @ should be usable as a parameter.
+318. spacing bad on `missing of' and `too many parameters' errors messages.
+319. keep track of largest str_ptr and pool_ptr values; showstats on two lines.
+ Version -8.0 [July 26] [introduced new test routines to study memory usage]
+320. make_pen doesn't recycle the knots
+321. flush_below often says free_node(2) on node of size 3.
+322. make_eq should recycle and free; do_equation shouldn't
+323. re #298 and #309: should also free the value nodes!
+324. the replacement text of a bad_var definition should be recycled.
+325. token lists left unrecycled in error recovery of addto, cull, display.
+ Version -7.0 [July 27]
+326. showall to put "(see the transcript file)" after >> if not tracingonline.
+327. remove redundant code: hex in print_the_digs; second l=1 in idlookup.
+328. procedures never called: b_open_in; round_scaled.
+329. need to zero cur_mod after back_expr in <Put the left bracket...>.
+330. <Print the coefficient...> now catches also numbers that round to 1.0.
+331. known_pair logic was obsolete; now it is massively simpler.
+332. fix_check_sum now zeroes the negative bytes; this simplifies other code.
+333. show_dependencies not to show parts of capsules.
+334. forgot to set fix_needed:=false!
+335. move fix_needed from add_or_subtract to dep_finish.
+336. test fix_needed in bilin1 and add_mult_dep.
+337. after back_expr in <Scan a mediation...>, forgot to unstash p.
+ Version 0.0 [July 28] [Hurray! The preliminary TRAP test is fully passed.]
+338. corrected blunder in definition of trans_spec type. (found by Karney)
+339. less extreme starting values of gf_min_x and its cousins.
+340. uninitialized left_curl was possible. (found by John Hobby)
+341. In <Reduce...straight line...>, need to test sign before the `div 3' ops.
+342. In pyth_add, remove `+2' when dividing by 4, to prevent overflow.
+343. "Not a variable" changed to "Not a suitable variable".
+344. known_pair forgot to reset cur_type.
+345. round and floor procedures need to work in the presence of huge arguments.
+346. major revision to allow independent variables to disappear silently:
+346a. delete null_path and <Declare the null value routines>.
+346b. delete the hard part of ring_delete, and delete <Scold...for using...>.
+346c. stash/unstash/flush_cur_exp routines to allow independent type.
+346d. print_exp to allow a ring that contains only capsules.
+346e. <Zero out...> becomes <Recycle an independent variable> (major new code).
+346f. stash_in needs code to handle the case cur_type=independent.
+346g. negation needs code to handle the case cur_type=independent.
+346h. take_part needs code to handle the case cur_type=independent.
+346i. do_binary needs code to handle either or both operands independent.
+346j. frac_mult needs code to handle the case cur_type=independent.
+346k. make_eq and try_eq too.
+346l. linear_eq needs to check if cur_exp=x and cur_type=independent.
+346m. linear_eq displays new dependency only when lhs is interesting.
+347. minor improvement for coding style/brevity: the "interesting" function.
+348. test `if t<independent' had been left out of print_exp (was dirty PASCAL).
+349. (begingroup save x;x+1000 endgroup,0) caused subtle bug during unsave.
+350. print_type(known) changed to "known numeric" for consistency.
+351. In <Change...to proto_dependent>, didn't watch for coefficients zeroed.
+352. check_mem now checks also the links in the dependency lists.
+353. null_pen initialization belongs in <Initialize tab...>, not <Set init...>.
+354. fix_dependencies has to worry about coefficients dropping to zero.
+355. add tracing to frac_mult.
+356. need cur_sym>0 at the time of end_read_terminal. (found by S Robinson)
+ Version 0.1 [August 30]
+357. Don't complain about winding_number<=0 when doing a doublepath.
+358. Need to test for max_coef=0 in offset_prep.
+359. Cusp detection should allow for more rounding error.
+360. Major change to path syntax, allowing {dir}..{dir} path joins.
+360a. `Fragments' disappear; new_fragment becomes new_knot.
+360b. print_path has simpler conventions.
+360c. future_path type disappears.
+360d. left_brace renumbered and removed from scan_tertiary.
+360e. some scan_tertiary code moves to new subroutine scan_direction.
+360f. scan_expression has a bunch of new code.
+361. scan_expression shouldn't have returned after cycle_hit.
+362. abort_path, scrap_knot logic removed from scan_expression.
+ Version 0.2 [September 12]
+363. new operator: makepath <pen primary>.
+364. define point/precontrol/postcontrol at endpoints and beyond. (JDH)
+365. union replaced by +; negation and subtraction allowed on edges.
+366. another new operator: totalweight <edges primary>. (JDH's idea)
+367. undelimited parameters may be preceded by an optional = or :=.
+368. base_area_length was wrong. (affects CH files)(found by Pavel)
+369. internal names to be allowable in suffixes.
+370. label not_found was misplaced in do_add_to. (found by PasMESA translator)
+371. progress report should be given at time of shipout.
+372. procedures make_choices, make_spec,fill_envelope split into shorter pieces.
+373. locals of cubic_intersection made global so that people could split it.
+ Version 0.3 [September 27]
+374. allow <future pen> ::= <pen> <transform>
+375. equation that's off by .0001 shouldn't be called inconsistent.
+376. bug in skew: must compute x_coord(q) and y_coord(q) exactly.
+377. right/left/up/down to be assigned to octants 1/5/2/6; was 1/4/2/7.
+378. boundedness to be allowed with any tension, and one-sidedly.
+379. eliminate coordinate nodes in path lists by passing angles instead (JDH).
+380. known_pair to free cur_exp after error msgs that might showdependencies.
+381. scan_primary sometimes accessed num before it had a value (found by Pavel).
+382. invalid characters should cause error message (suggested by PMB).
+ Version 0.4 [October 12]
+383. allow `0' in response to error prompts.
+384. put loop value on error context lines.
+385. change `ord' to `ASCII'.
+386. scantokens <string primary> to be permitted; readterminal goes away.
+387. expandafter <token> to be permitted.
+388. improved overflow conventions on make_fraction, make_scaled.
+389. variable=<value over 4096> should get its own error message.
+390. nice_pair first argument can be any integer.
+391. new feature, shortshow commands that don't pause.
+392. "harmless" bug in negate_edges, the sorted list can get out of sorts.
+393. ni too skimpy (15 instead of 63). (JDH)
+394. loop_ptr not initialized. (found by Paul Richards)
+395. bug in <Find the approximate type...>, q=null should goto done1. (Richards)
+396. empty_edges macro added for readability.
+397. x_reflect_edges might as well fix the offset as it goes.
+398. blunder: frozen_bad_vardef had the wrong eq_type.
+399. "name" changed to "tag".
+400. check_arith inserted after division of numeric tokens.
+401. stop_bit was not initialized in <Compile a ligature/kern...>.
+402. char 127 to be a string of length 1; slow_print added (therefore).
+403. pyth_sub added to the repertoire.
+404. minor change to calls on "confusion" in make_fraction, make_scaled. (JJW)
+ Version 0.5 [November 9]
+405. 4095.999999 should be erroneous.
+406. length <pair> to give the absolute value; argd changed to "angle".
+407. get_next changed to get_x_next wherever possible.
+408. z1..z2{curl 0} should be equivalent to z1..{curl 0}z2.
+409. scantokens "" should be fast.
+410. allow undelimited suffix and text parameters.
+411. warningcheck to allow large variable values passed over silently.
+412. "edges" changed to "picture".
+413. "winding" changed to "turning".
+414. <If consecutive knots...> had typo, "p" for "q".
+415. elliptical pens should have axis symmetry.
+416. slow_add introduced to catch arithmetic overflow on addition.
+417. add a turningnumber primitive.
+418. no carriage return between ">>" and "Edge structure...".
+419. install new memory management routines (from TeX version 1.3).
+420. generalized cull command. (suggested by Bruce Leban)
+421. bad goto: `x..' reports that x is vacuous, loses value of x.
+422. shortshows replaced by an internal variable "showstopping".
+423. major change, capsule tokens: lots of code and restrictions gone! (JDH)
+424. substring(a,b), subpath(a,b) to reverse the result when a>b.
+425. new GF format: z goes away. (suggested by ALS)
+426. another GF mod: chardw replaced by chardx/chardy, which are scaled. (PMB)
+427. make `&' have the same precedence always (not different for strings).
+428. wrong error message for 2"s" (bug introduced in change 369).
+429. variable l in show_context has to be declared type integer.
+430. bug in chop_path when both limits are large.
+ Version 0.6 [December 10]
+431. xoffset and yoffset to be added by shipout. [this affects GF comments]
+432. wake_up_terminal, not t_open_out, before "Ouch..." (Scott Robinson)
+433. undelimited suffix parameters to allow an optional delimiter, disallow =.
+434. showall... to be eliminated; tracingcapsules added.
+435. allow undelimited parameters after delimited ones.
+436. nullpen test in addto should test for any one-point pen.
+437. granularity parameter to affect autorounding (Bruce Leban)
+[this leads to major improvements suggested by JDH; lots of code changes!]
+[basically, make_spec is now responsible for autorounding; fill_spec just fills]
+438. node_size overflow problem must be prevented. (Paul Richards)
+439. allow unary + with a picture.
+440. nullpen should transform quickly to itself, if not shifted.
+441. print_edges should skip over null rows, if it doesn't already.
+442. open_base_file improved (following TeX's change number 302).
+443. output initialization improved (following TeX's change number 303).
+444. operators shouldn't fail because future pen isn't a pen. (JDH)
+445. intersection routine to quit in hard cases. (DRF)
+446. angle routine was off by epsilon on negative arguments. (Karney)
+447. octant assignment should look ahead further in ambiguous cases. (JDH)
+448. <Compute the incoming...> forgot that right_type(r)=endpoint could happen.
+449. turning_number calculated directly, not times 8.
+450. floor_scaled made more efficient by trading subtraction for multiplication.
+451. doublepath autorounding to compromise between east and west. (JDH)
+452. codes of picture_type and path_type interchanged, to simplify a "case".
+ Version 0.7 [January 17, 1985]
+453. def to allow both := and =. (NB)
+454. "keeping" and "dropping" instead of "including" and "excluding". (HWT)
+455. (see the transcript...): why, when tracingonline>0?
+456. dead cubics need to be removed also before xy_round. (NB)
+457. [re 433] I said get_x_next twice; a blunder.
+ Version 0.75 [January 23, 1985]
+458. Abbreviated boc command makes GF format more attractive for lowres. (GusF)
+ Version 0.76 [February 2]
+459. known and unknown might as well both be primitive.
+460. ab_vs_cd(a-d,b,c-b,d) simplifies to ab_vs_cd(a,b,c,d). (JDH)
+461. (from change 435) <Absorb undelimited...> must use k, not n.
+462. (from change 458) max_new_row added, since 165 wasn't updated to 164.
+ Version 0.77 [February 16]
+463. abbreviated version of tracingspecs is desired for turning number errors.
+464. improved octant number in pathological cases of quadrant_subdivide (JDH)
+465. xoffset,yoffset communicated to GF file when proofing>0.
+466. Poirot changed to Marple.
+467. reverse<cycle> starts the reversed path at the wrong time.
+468. Extra help given after `undefined coordinate' errors.
+469. Keep segment numbers from overflowing max_halfword. (JDH)
+470. Ditto for pen offset slope numbers.
+471. n_magic had min_halfword with wrong sign. (John Johnson)
+ Version 0.80 [April 1]
+472. In errhelp, % means <return>, %% means %. (BPL)
+473. tracing of envelopes should give symbolic octant names.
+474. (-x mod y) should be ((-x) mod y) in good_val.
+475. crossingpoint could overflow on 32-bit machines. (BPL)
+476. Improvements to abbreviated format of number 463.
+ Version 0.81 [April 4]
+477. `I hide(showdependencies)' in hint to become `I ???'.
+478. print_strange shouldn't wake up the terminal in scroll mode. (cf 463)
+479. flush_list procedure made a bit faster. (DRF)
+480. bounded velocities to be multiplied by .999 for safety.
+481. Detect error in declaration that tries to extend a vardef.
+482. print_strange puts turns in parentheses (cf 463).
+483. make_name_string shouldn't ever cause string space overflow.
+484. allow <picture primary> xscaled m yscaled n.
+485. checksum should consider values relative to designsize. (DRF)
+[I also increased max_strings to 2000.]
+
+[Note: Neenie found a case where missing pixels can occur, due to
+inconsistent rounding between left-to-right and right-to-left subdivision:
+pickup pencircle; draw
+(0,126)..controls (130.29451,126) and (288,126.00002)
+ ..(288,36)..controls (288,143.99998) and (132.97438,144)
+ ..(0,144)..controls (0,138) and (0,132)
+ ..cycle;
+The "right" way to fix this would be to develop a make_spec routine for
+non-cycles, and to copy a reversed spec, so that double paths would be
+guaranteed self-inverse. However, my later experiments showed that
+autorounding wasn't nearly as useful as I had expected it to be, hence I
+decided not to waste time beefing up this routine; no satisfactory
+automatic approach to rounding occurs to me.]
+ Version 0.90 [May 10]
+486. 180-degree turns to be clockwise for half of doublepath cycles.
+487. introduce fillin parameter.
+488. `numeric_type' moved before `known', so that print_exp works (Richards).
+489. numeric_type as unary op should include independent in its range (cf 346).
+ Version 0.91 [May 13]
+490. show_token_list gets null_tally parameter.
+491. if bad>0, change the code as in TeX changes 315, 316.
+492. batchmode change as in TeX 317.
+493. "and double autorounding" to be traced, if appropriate.
+494. introduce tracingrestores.
+ *`restoring a bad variable'?
+495. put decimal number into gf extension
+496. mediation put into scan_primary, so that round .5[a,b] works properly.
+497. cubic_intersection now has |tol| to compensate for rounding errors.
+498. find_direction_time needs to worry about degenerate case x3=y3=0.
+499. crossing_point(a,b,0) now yields fraction_one if a,b>0.
+500. diag_round shouldn't insist that b-a is even (see below).
+501. macro_call will show_macro with much larger limit.
+502. TFM file statistics are logged too.
+
+* Here's an example (found by Neenie) explaining bugfix 500:
+autorounding:=2; draw
+(7.03159,-9.31831)..controls (12.14732,-9.4386) and (17.4299,-6.82948)
+ ..(21.60132,0)..controls (27.47417,9.61507) and (37.87402,15.58647)
+ ..(43.74687,25.20154)..controls (51.16223,37.34201) and (57.31,50.171)
+ ..(63.45776,63.00002) withpen pencircle;
+The missing pixels are due to the following curious circumstances: (1) the
+middle cubic splits into three, when subdividing into octants; (2) the reverse
+curve splits too but with slightly different rounding, off by 1; (3) the old
+diag_round routine, when it ensures that b-a is even, computes aa=a+1 on
+one side of the curve, but aa=a-1 on the other side, thus making the
+rounding "safe" on only one side. (Namely, on one side we have consecutive
+values
+ b=1317666 a=1310720
+ b=1329617 a=1310721
+and on the other side,
+ b=-1329618 a=-1310720
+ b=-1317667 a=-1310721.)
+
+* Here's an example (by JDH) showing the necessary of bugfix 497:
+path p[];
+p1 = (1,0)..controls (1,0.10493) and (0.98347,0.20921)
+ ..(0.95105,0.30902)..controls (0.91862,0.40881) and (0.8707,0.50288)
+ ..(0.80902,0.58778);
+p2 = (0,0)..controls (0.63403,0.20601) and (1.26807,0.41203)
+ ..(1.9021,0.61804);
+show p1 intersectiontimes p2; % (-1,-1), without `tol'
+pickup pencircle;
+currenttransform := identity scaled 150;
+draw p1; draw p2;
+showit; % but they clearly intersect
+ Version 0.95 [Aug 12]
+503. `Se' changed to `SSE', etc. (suggested by RFS)
+504. Inconsisting diagonal rounding was introduced in bugfix 500.
+
+[the following lines from @<Determine the before...@> in diag_round:
+ if aa>bb then cc:=dd-half(aa-bb-1)@+else cc:=dd-half(aa-bb+1)
+ if a>b then c:=d-half(a-b-1)@+else c:=d-half(a-b+1)
+were replaced respectively by:
+ if right_type(p)>switch_x_and_y then cc:=dd-half(aa-bb+1)
+ else cc:=dd-half(aa-bb-1)
+ if right_type(p)>switch_x_and_y then c:=d-half(a-b-1)
+ else c:=d-half(a-b+1)
+in order to make the rounding consistent on adjacent octants;
+the following command caused `this can't happen':
+fill (33,7)..controls (32.63094,5.70827) and (32.06163,3.716)
+ ..(31.59488,3.36667)..controls (31.10509,3.00009) and (29.14824,3)
+ ..(27.85318,3)..controls (27.85286,3) and (23.84952,3)
+ ..(23.8492,3)..controls (23.73282,2) and (23.61646,1)
+ ..(23.50008,0)..controls (26.66672,0) and (29.83336,0)
+ ..(33,0)..controls (33.66667,2.33333) and (34.33333,4.66667)
+ ..(35,7)..controls (34.33333,7) and (33.66667,7)
+ ..cycle;]
+ Version 0.96 [Aug 17]
+505. allow comparison of transforms. [test by trying t=t when t is new...]
+506. {restoring...} shouldn't get through when tracingonline=0.
+507. better error message needed on `interim alpha:=0', `interim 0:=0'.
+508. make_op_def should put parameters in the other order.
+509. <Worry about...> should say get_x_next, not get_next.
+510. unif_rand to allow negative x, save on error messages.
+511. tidy up chop_string when b<0 and/or a>l.
+512. randomseed is automatically logged.
+513. change 495 messed up if gf file couldn't be opened. (found by DRF)
+[In INIMF.CH, 3-character extensions now have 0--9 or A--Z as leading digit.]
+ Version 0.97 [Sep 5]
+514. a[b,c] to be tried only if a is numeric type.
+515. simplified the code for length_op(string_type).
+516. citations of `Chapter xx' now replaced by correct references.
+517. <Log the subfile sizes...> to be in stat...tats version only.
+518. remove extra space after <insert> and <scantokens>.
+519. offsets should be included in the tracingoutput output.
+520. a vacuous expression should be considered known.
+521. charlist syntax changed from commas to colons.
+[also the WAITS version command-line reader was fixed to handle `^^W']
+ Version 0.99 [Sep 24]
+522. vardef's begingroup...endgroup should be accessible.
+523. allow an empty expression in for loops.
+ Version 0.999 [Oct 1]
+524. "charfam" changed to "charext".
+525. variable tt makes get_node slightly faster. (PROFILE suggests this)
+526. cur_cmd<=max should be tested before cur_cmd>=min. (PROFILE)
+527. fast_get_avail used in cur_tok and scan_primary. (PROFILE)
+ Version 0.9999 [Oct 27]
+528. Major change to representation of independent variables
+ ("serial number" added so that MF's equation solving doesn't depend
+ on vagaries of storage allocation)
+ [module number change: new module between old 585 and 586]
+ [in terms of new numbering, modules 232, 585--587, 589, 594, 597,
+ 601, 608, 610, 816--817, 855, 1198--1199 were affected]
+[I also reordered some of the cases in print_op, module 189,
+so that the program could be condensed in published version]
+ Version 0.99999 [Nov 13]
+529. forgot to decrease three_l in change 497!
+530. cubic_intersection to give approximation if max_patience exceeded.
+[the following example, found by NB, motivated this change:
+ show (
+ (36.00104,26.99951)..controls (36.00131,26.99979) and (36.00146,27.00017)
+ ..(36.00146,27.00055)
+ )intersectiontimes(
+ (36,27.00055)..controls (45.17148,21.12364) and (55.83588,18)
+ ..(66.72873,18)
+ );]
+ Version 0.999999 [Dec 2]
+531. hold_head needed (scan_toks calls cur_tok calls copy_edges). (D. Kosower)
+ Version 1.0 [January 4, 1986]
+532. Optimization in module 1174, suggested by LER (3 Feb 86)
+@x
+ if delta=0 then gf_out(skip0)
+ else begin gf_out(skip1); gf_out(delta);
+ end
+@y
+ begin gf_out(skip1); gf_out(delta);
+ end
+@z
+*** Late copies of version 1.0 include this correction;
+in particular, the program listing in Volume D was updated (with scissors)!
+ Changes subsequent to `Version 1.0' as published in C&T, Volume D:
+533. Inconsistent punctuation in user messages (found by Karl Berry, June 86)
+@x module 1134
+print_nl("Font metrics written on "); print(metric_file_name);
+@y
+print_nl("Font metrics written on "); print(metric_file_name); print_char(".");
+@z (that was installed in version 1.1)
+
+534. Possible arithmetic overflows (found by Klaus Guntermann, July 86)
+@x module 496
+while max_coef<fraction_one do
+@y
+while max_coef<fraction_half do
+@z (that was installed in version 1.2)
+
+535. Possible loop in nonstopmode (found by Chris Thompson, July 86)
+@x module 1206
+ @<Finish the \.{TFM} file@>;
+@y
+ internal[fontmaking]:=0; {avoid loop in case of fatal error}
+ @<Finish the \.{TFM} file@>;
+@z (that too was installed in version 1.2)
+
+536. Double rounding error should be avoided in make_ellipse (JDH, 22 Nov 86)
+@x module 533
+d:=take_fraction(d,delta);
+alpha:=abs(u); beta:=abs(v);
+if alpha<beta then
+ begin delta:=alpha; alpha:=beta; beta:=delta;
+ end; {now $\alpha=\max(\vert u\vert,\vert v\vert)$,
+ $\beta=\min(\vert u\vert,\vert v\vert)$}
+if internal[fillin]<>0 then d:=d-take_fraction(internal[fillin],beta+beta);
+d:=(d+4) div 8; alpha:=alpha div half_unit;
+@y
+alpha:=abs(u); beta:=abs(v);
+if alpha<beta then
+ begin alpha:=abs(v); beta:=abs(u);
+ end; {now $\alpha=\max(\vert u\vert,\vert v\vert)$,
+ $\beta=\min(\vert u\vert,\vert v\vert)$}
+if internal[fillin]<>0 then
+ d:=d-take_fraction(internal[fillin],make_fraction(beta+beta,delta));
+d:=take_fraction((d+4) div 8,delta); alpha:=alpha div half_unit;
+@z (That was the reason for version 1.3)
+
+537. Trivial change to a help message (version number is still 1.3).
+@x module 1086
+ ("Pretend that you're Miss Marple, examine all clues,")@/
+@y
+ ("Pretend that you're Miss Marple: Examine all clues,")@/
+@z
+
+538. Storage allocation can be more elegant and efficient (4/21/87)
+@x module 169
+if r=p then if ((rlink(p)<>rover) or (llink(p)<>rover)) then
+@y
+if r=p then if rlink(p)<>p then
+@z
+
+539. Unused variables can be eliminated. (Found by John Sauter, 5/5/87)
+@x module 158
+@<Glob...@>=
+@!temp_ptr:pointer; {a pointer variable for occasional emergency use}
+
+@y (I used it only in my change file!)
+@z
+@x module 280
+@!r,@!s,@!t:pointer; {registers for list traversal}
+@y
+@!s,@!t:pointer; {registers for list traversal}
+@z
+@x module 284
+@!sine,@!cosine:fraction; {trig functions of various angles}
+@y (the declarations in module 281 are correct, but in 284 they're superfluous)
+@z
+@x module 497
+var @!q,@!ww:pointer; {for list manipulation}
+@!du,@!dv:scaled; {for slope calculation}
+@!t0,@!t1,@!t2:integer; {test coefficients}
+@!t:fraction; {place where the derivative passes a critical slope}
+@!s:fraction; {slope or reciprocal slope}
+@!v:integer; {intermediate value for updating |x0..y2|}
+begin loop
+ begin q:=link(p); right_type(p):=k;
+@y
+var @!ww:pointer; {for list manipulation}
+@!du,@!dv:scaled; {for slope calculation}
+@!t0,@!t1,@!t2:integer; {test coefficients}
+@!t:fraction; {place where the derivative passes a critical slope}
+@!s:fraction; {slope or reciprocal slope}
+@!v:integer; {intermediate value for updating |x0..y2|}
+begin loop
+ begin right_type(p):=k;
+@z
+@x module 652
+@!s:0..param_size; {value of |param_start| on the current level}
+@y who knows why that line was there?
+@z
+@x module 862
+var @!p,@!q,@!r:pointer; {for list manipulation}
+@y
+var @!p:pointer; {for list manipulation}
+@z
+@x module 985
+@!vv:scaled; {initial value of |v|}
+@!q:pointer; {successor of |p|}
+begin vv:=v; p:=cur_exp;@/
+@y
+@!q:pointer; {successor of |p|}
+begin p:=cur_exp;@/
+@z
+@x module 1059
+@!t:small_number; {variant of |with_option|}
+@y
+@z
+
+540. Typo suppresses an error detection (Chris Thompson, 2May88)
+@x module 963
+ if txy mod unity=0 then if tyy mod unity=0 then
+@y
+ if txx mod unity=0 then if tyy mod unity=0 then
+@z
+
+541. get_x_token can lose a scanned declared variable (Chris Thompson, 4May88)
+@x module 1011
+if equiv(x)=null then new_root(x);
+@y
+@z
+@x module 1011
+done:scan_declared_variable:=h;
+@y
+done: if eq_type(x)<>tag_token then clear_symbol(x,false);
+if equiv(x)=null then new_root(x);
+scan_declared_variable:=h;
+@z
+
+542. Avoid negative divisor rounding upward (Chris Thompson, fixed 19Jun88)
+@x module 168
+else t:=(lo_mem_max+hi_mem_min+2) div 2; {|lo_mem_max+2<=t<hi_mem_min|}
+@y
+else t:=lo_mem_max+1+(hi_mem_min-lo_mem_max)div 2; {|lo_mem_max+2<=t<hi_mem_min|}
+@z
+
+543. Better strategy when near memory overflow (Chris Thompson)
+@x module 168
+begin if lo_mem_max+1000<hi_mem_min then t:=lo_mem_max+1000
+@y
+begin if hi_mem_min-lo_mem_max>=1998 then t:=lo_mem_max+1000
+@z
+
+544. Avoid fatal_error after terminal eof (Tim Morgan, reported 25Oct88)
+@x module 66 [serious problem occurred if this was called in open_log_file]
+if not input_ln(term_in,true) then fatal_error("End of file on the terminal!");
+@y
+if not input_ln(term_in,true) then t_open_in;
+@z
+
+545. Force terminal output when open_log_file aborts (6Nov88)
+@x module 789
+ begin print_err("I can't write on file `");
+@y
+ begin selector:=term_only; print_err("I can't write on file `");
+@z
+
+546. By popular request, undo #544 and fix the bug a more complex way.
+@x module 66 [this undoes change #544]
+if not input_ln(term_in,true) then t_open_in;
+@y
+if not input_ln(term_in,true) then fatal_error("End of file on the terminal!");
+@z
+@x module 87 [now we get to the new stuff]
+begin if job_name>0 then selector:=term_and_log
+@y
+begin if log_opened then selector:=term_and_log
+@z
+@x module 88
+ error;
+@y
+ if log_opened then error;
+@z
+@x module 782
+@!job_name:str_number; {principal file name}
+@y
+@!job_name:str_number; {principal file name}
+@!log_opened:boolean; {has the transcript file been opened?}
+@z
+@x module 783
+@<Initialize the output...@>=job_name:=0;
+@y
+@<Initialize the output...@>=job_name:=0; log_opened:=false;
+@z
+@x module 788
+selector:=log_only;
+@y
+selector:=log_only; log_opened:=true;
+@z
+@x module 789
+begin if interaction<scroll_mode then {bypass |fatal_error|}
+ begin selector:=term_only; print_err("I can't write on file `");
+@.I can't write on file x@>
+ print_file_name(cur_name,cur_area,cur_ext); print("'.");@/
+ job_name:=0; history:=fatal_error_stop; jump_out;
+ end; {abort the program without a log file}
+@y
+begin selector:=term_only;
+@z
+@x module 1023 [this change is optional, but it's a slight improvement]
+ if job_name<>0 then selector:=selector+2;
+@y
+ if log_opened then selector:=selector+2;
+@z
+@x module 1205
+if job_name>0 then
+@y
+if log_opened then
+@z
+@x module 1208
+if job_name>0 then {the log file is open}
+@y
+if log_opened then
+@z
+
+547. String startup problems corresponding to TeX change 355 (17 Jul 89)
+@x module 30 (Warning: This affects most change files!)
+ overflow("buffer size",buf_size);
+@:METAFONT capacity exceeded buffer size}{\quad buffer size@>
+@y
+ @<Report overflow of the input buffer, and abort@>;
+@z
+@x module 34
+consist of the remainder of the command line, after the part that invoked \MF.
+@y
+consist of the remainder of the command line, after the part that invoked \MF.
+
+The first line is special also because it may be read before \MF\ has
+input a base file. In such cases, normal error messages cannot yet
+be given. The following code uses concepts that will be explained later.
+
+@<Report overflow of the input buffer, and abort@>=
+if base_ident=0 then
+ begin write_ln(term_out,'Buffer size exceeded!'); goto final_end;
+@.Buffer size exceeded@>
+ end
+else begin cur_input.loc_field:=first; cur_input.limit_field:=last-1;
+ overflow("buffer size",buf_size);
+@:METAFONT capacity exceeded buffer size}{\quad buffer size@>
+ end
+@z
+@x module 1193
+k:=pool_ptr-4; undump_four_ASCII
+@y
+k:=pool_ptr-4; undump_four_ASCII;
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr;@/
+max_str_ptr:=str_ptr; max_pool_ptr:=pool_ptr
+@z
+@x module 1204
+tini@/
+@y
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr;@/
+max_str_ptr:=str_ptr; max_pool_ptr:=pool_ptr; fix_date_and_time;
+tini@/
+@z
+@x module 1204
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr;@/
+max_str_ptr:=str_ptr; max_pool_ptr:=pool_ptr;@/
+@y
+@z
+
+548. Major changes to allow 8-bit input, cf. TeX82 #359 (11 Sep 89).
+@x module 18
+@!ASCII_code=0..127; {seven-bit numbers}
+@y
+@!ASCII_code=0..255; {eight-bit numbers}
+@z
+@x module 19
+@d last_text_char=127 {ordinal number of the largest element of |text_char|}
+
+@<Local variables for init...@>=
+@!i:0..last_text_char;
+@y
+@d last_text_char=255 {ordinal number of the largest element of |text_char|}
+
+@<Local variables for init...@>=
+@!i:integer;
+@z
+@x module 21
+xchr[0]:=' '; xchr[@'177]:=' ';
+ {ASCII codes 0 and |@'177| do not appear in text}
+@y
+@z
+@x module 22
+for i:=1 to @'37 do xchr[i]:=' ';
+@y changing ' ' to chr(i) here will allow all 8-bit characters to get in
+for i:=0 to @'37 do xchr[i]:=' ';
+for i:=@'177 to @'377 do xchr[i]:=' ';
+@z
+@x module 23
+for i:=1 to @'176 do xord[xchr[i]]:=i;
+@y
+for i:=@'200 to @'377 do xord[xchr[i]]:=i;
+for i:=0 to @'176 do xord[xchr[i]]:=i;
+@z
+@x module 37
+@<Types...@>=
+@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|}
+@!str_number = 0..max_strings; {for variables that point into |str_start|}
+
+@ @<Glob...@>=
+@!str_pool:packed array[pool_pointer] of ASCII_code; {the characters}
+@y [OK to make si(#)==#-128 and so(#)==#+128 (without parens) in change files]
+Some \PASCAL\ compilers won't pack integers into a single byte unless the
+integers lie in the range |-128..127|. To accommodate such systems
+we access the string pool only via macros that can easily be redefined.
+
+@d si(#) == # {convert from |ASCII_code| to |packed_ASCII_code|}
+@d so(#) == # {convert from |packed_ASCII_code| to |ASCII_code|}
+
+@<Types...@>=
+@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|}
+@!str_number = 0..max_strings; {for variables that point into |str_start|}
+@!packed_ASCII_code = 0..255; {elements of |str_pool| array}
+
+@ @<Glob...@>=
+@!str_pool:packed array[pool_pointer] of packed_ASCII_code; {the characters}
+@z
+@x module 41
+begin str_pool[pool_ptr]:=#; incr(pool_ptr);
+@y
+begin str_pool[pool_ptr]:=si(#); incr(pool_ptr);
+@z
+@x module 45
+ begin if str_pool[j]<>buffer[k] then
+@y
+ begin if so(str_pool[j])<>buffer[k] then
+@z
+@x module 47
+var k,@!l:0..127; {small indices or counters}
+@y
+var k,@!l:0..255; {small indices or counters}
+@z
+@x module 47
+@<Make the first 128 strings@>;
+@y
+@<Make the first 256 strings@>;
+@z
+@x module 48
+@ @<Make the first 128...@>=
+for k:=0 to 127 do
+ begin if (@<Character |k| cannot be printed@>) then
+ begin append_char("^"); append_char("^");
+ if k<@'100 then append_char(k+@'100)
+ else append_char(k-@'100);
+@y
+@ @d app_lc_hex(#)==l:=#;
+ if l<10 then append_char(l+"0)@+else append_char(l-10+"a")
+
+@<Make the first 256...@>=
+for k:=0 to 255 do
+ begin if (@<Character |k| cannot be printed@>) then
+ begin append_char("^"); append_char("^");
+ if k<@'100 then append_char(k+@'100)
+ else if k<@'200 then append_char(k-@'100)
+ else begin app_lc_hex(k div 16); app_lc_hex(k mod 16);
+ end;
+@z
+@x module 59
+ begin print_char(str_pool[j]); incr(j);
+@y
+ begin print_char(so(str_pool[j])); incr(j);
+@z
+@x module 60
+ begin print(str_pool[j]); incr(j);
+@y
+ begin print(so(str_pool[j])); incr(j);
+@z
+@x module 85
+ begin if str_pool[j]<>"%" then print(str_pool[j])
+ else if j+1=str_start[err_help+1] then print_ln
+ else if str_pool[j+1]<>"%" then print_ln
+@y
+ begin if str_pool[j]<>si("%") then print(so(str_pool[j]))
+ else if j+1=str_start[err_help+1] then print_ln
+ else if str_pool[j+1]<>si("%") then print_ln
+@z
+@x module 199
+char_class[127]:=invalid_class;
+@y
+for k:=127 to 255 do char_class[k]:=invalid_class;
+@z
+@x module 200
+@d hash_is_full == (hash_used=1) {test if all positions are occupied}
+@d eq_type(#) == eqtb[#].lh {the current ``meaning'' of a symbolic token}
+@d equiv(#) == eqtb[#].rh {parametric part of a token's meaning}
+@d hash_base=129 {hashing actually starts here}
+@y [incidentally I fixed a bug re hash overflow here]
+@d eq_type(#) == eqtb[#].lh {the current ``meaning'' of a symbolic token}
+@d equiv(#) == eqtb[#].rh {parametric part of a token's meaning}
+@d hash_base=257 {hashing actually starts here}
+@d hash_is_full == (hash_used=hash_base) {are all positions occupied?}
+@z
+@x module 210
+for j:=0 to l-1 do buffer[j]:=str_pool[k+j];
+cur_sym:=id_lookup(0,l);@/
+if s>=128 then {we don't want to have the string twice}
+@y
+for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]);
+cur_sym:=id_lookup(0,l);@/
+if s>=256 then {we don't want to have the string twice}
+@z
+@x module 223
+begin c:=char_class[str_pool[str_start[r]]];
+@y
+begin c:=char_class[so(str_pool[str_start[r]])];
+@z
+@x module 717
+ begin buffer[first]:=str_pool[j]; incr(j); incr(first);
+@y
+ begin buffer[first]:=so(str_pool[j]); incr(j); incr(first);
+@z
+@x module 774
+for j:=str_start[a] to str_start[a+1]-1 do append_to_name(str_pool[j]);
+for j:=str_start[n] to str_start[n+1]-1 do append_to_name(str_pool[j]);
+for j:=str_start[e] to str_start[e+1]-1 do append_to_name(str_pool[j]);
+@y
+for j:=str_start[a] to str_start[a+1]-1 do append_to_name(so(str_pool[j]));
+for j:=str_start[n] to str_start[n+1]-1 do append_to_name(so(str_pool[j]));
+for j:=str_start[e] to str_start[e+1]-1 do append_to_name(so(str_pool[j]));
+@z
+@x module 912
+ else begin cur_exp:=round_unscaled(cur_exp) mod 128; cur_type:=string_type;
+ if cur_exp<0 then cur_exp:=cur_exp+128;
+@y
+ else begin cur_exp:=round_unscaled(cur_exp) mod 256; cur_type:=string_type;
+ if cur_exp<0 then cur_exp:=cur_exp+256;
+@z
+@x module 913
+ else n:=str_pool[str_start[cur_exp]]
+@y
+ else n:=so(str_pool[str_start[cur_exp]])
+@z
+@x ibid
+ begin m:=str_pool[k];
+@y
+ begin m:=so(str_pool[k]);
+@z
+@x module 976
+for k:=str_start[a] to str_start[a+1]-1 do append_char(str_pool[k]);
+for k:=str_start[b] to str_start[b+1]-1 do append_char(str_pool[k]);
+@y
+for k:=str_start[a] to str_start[a+1]-1 do append_char(so(str_pool[k]));
+for k:=str_start[b] to str_start[b+1]-1 do append_char(so(str_pool[k]));
+@z
+@x module 977
+ for k:=str_start[s]+b-1 downto str_start[s]+a do append_char(str_pool[k])
+else for k:=str_start[s]+a to str_start[s]+b-1 do append_char(str_pool[k]);
+@y
+ for k:=str_start[s]+b-1 downto str_start[s]+a do append_char(so(str_pool[k]))
+else for k:=str_start[s]+a to str_start[s]+b-1 do append_char(so(str_pool[k]));
+@z
+@x module 1103
+ begin c:=str_pool[str_start[cur_exp]]; goto found;
+@y
+ begin c:=so(str_pool[str_start[cur_exp]]); goto found;
+@z
+@x module 1160
+ for k:=str_start[s] to str_start[s+1]-1 do gf_out(str_pool[k]);
+ end;
+if t<>0 then for k:=str_start[t] to str_start[t+1]-1 do gf_out(str_pool[k]);
+@y
+ for k:=str_start[s] to str_start[s+1]-1 do gf_out(so(str_pool[k]));
+ end;
+if t<>0 then for k:=str_start[t] to str_start[t+1]-1 do gf_out(so(str_pool[k]));
+@z
+@x module 1192
+ w.b0:=str_pool[k]; w.b1:=str_pool[k+1];
+ w.b2:=str_pool[k+2]; w.b3:=str_pool[k+3];
+@y [often qi(so(x))=x, but not e.g. when "quarterwords" are two bytes]
+ w.b0:=qi(so(str_pool[k])); w.b1:=qi(so(str_pool[k+1]));
+ w.b2:=qi(so(str_pool[k+2])); w.b3:=qi(so(str_pool[k+3]));
+@z
+@x module 1193
+ str_pool[k]:=w.b0; str_pool[k+1]:=w.b1;
+ str_pool[k+2]:=w.b2; str_pool[k+3]:=w.b3
+@y
+ str_pool[k]:=si(qo(w.b0)); str_pool[k+1]:=si(qo(w.b1));
+ str_pool[k+2]:=si(qo(w.b2)); str_pool[k+3]:=si(qo(w.b3))
+@z
+
+549. Make ".base" more easily switchable (see TeX82 log #369).
+@x module 775 gets a new definition
+@y
+@d base_extension=".base" {the extension, as a \.{WEB} constant}
+@z now replace ".base" by base_extension in modules 784 and 1200.
+
+550. "This can't happen" happened because of nonmonotonic rounding
+ (bug found by Mark Eklof, fixed 7 Oct 89)
+@x module 411
+left_x(r):=x_coord(r);
+@y
+left_x(r):=x_coord(r);
+if right_x(p)>x_coord(r) then right_x(p):=x_coord(r);
+ {we always have |x_coord(p)<=right_x(p)|}
+@z
+@x ibid
+else if x_coord(r)>dest_x then x_coord(r):=dest_x;
+@y
+else begin if x_coord(r)>dest_x then
+ begin x_coord(r):=dest_x; left_x(r):=-x_coord(r); right_x(r):=x_coord(r);
+ end;
+ if left_x(q)>dest_x then left_x(q):=dest_x
+ else if left_x(q)<x_coord(r) then left_x(q):=x_coord(r);
+ end;
+@z
+@x module 412
+left_x(s):=x_coord(s);
+negate(x_coord(s)); right_x(s):=x_coord(s);
+negate(left_x(q));
+@y
+left_x(s):=x_coord(s); {now |x_coord(r)=right_x(r)<=left_x(s)|}
+if left_x(q)<dest_x then left_x(q):=-dest_x
+else if left_x(q)>x_coord(s) then left_x(q):=-x_coord(s)
+else negate(left_x(q));
+negate(x_coord(s)); right_x(s):=x_coord(s);
+@z
+@x module 415
+if x_coord(r)>dest_x then x_coord(r):=dest_x
+else if x_coord(r)<x_coord(pp) then x_coord(r):=x_coord(pp);
+if y_coord(r)<y_coord(pp) then y_coord(r):=y_coord(pp);
+left_y(r):=y_coord(r);
+@y
+if y_coord(r)<y_coord(pp) then y_coord(r):=y_coord(pp);
+left_y(r):=y_coord(r);
+if right_y(pp)>y_coord(r) then right_y(pp):=y_coord(r);
+ {we always have |y_coord(pp)<=right_y(pp)|}
+@z
+@x ibid
+else if y_coord(r)>dest_y then y_coord(r):=dest_y;
+@y
+else begin if y_coord(r)>dest_y then
+ begin y_coord(r):=dest_y; left_y(r):=-y_coord(r); right_y(r):=y_coord(r);
+ end;
+ if left_y(qq)>dest_y then left_y(qq):=dest_y
+ else if left_y(qq)<y_coord(r) then left_y(qq):=y_coord(r);
+ end;
+@z
+@x module 416
+if x_coord(s)>dest_x then x_coord(s):=dest_x
+else if x_coord(s)<x_coord(r) then x_coord(s):=x_coord(r);
+if y_coord(s)<dest_y then y_coord(s):=dest_y;
+if y_coord(s)<y_coord(r) then y_coord(s):=y_coord(r);
+right_type(s):=right_type(pp);
+left_y(s):=y_coord(s);
+negate(y_coord(s)); right_y(s):=y_coord(s);
+negate(left_y(qq));
+@y
+if y_coord(s)<dest_y then y_coord(s):=dest_y;
+if y_coord(s)<y_coord(r) then y_coord(s):=y_coord(r);
+right_type(s):=right_type(pp);
+left_y(s):=y_coord(s); {now |y_coord(r)=right_y(r)<=left_y(s)|}
+if left_y(qq)<dest_y then left_y(qq):=-dest_y
+else if left_y(qq)>y_coord(s) then left_y(qq):=-y_coord(s)
+else negate(left_y(qq));
+negate(y_coord(s)); right_y(s):=y_coord(s);
+@z
+@x module 424
+if y_coord(r)>dest_y then y_coord(r):=dest_y
+else if y_coord(r)<y_coord(p) then y_coord(r):=y_coord(p);
+if x_coord(r)<x_coord(p) then x_coord(r):=x_coord(p);
+left_x(r):=x_coord(r);@/
+y_coord(r):=y_coord(r)+x_coord(r); negate(x_coord(r));@/
+right_x(r):=x_coord(r); right_y(r):=right_y(r)-right_x(r);@/
+left_y(q):=left_y(q)+left_x(q); negate(left_x(q));@/
+dest_y:=dest_y+dest_x; negate(dest_x);
+@y
+if x_coord(p)+y_coord(r)>dest_x+dest_y then
+ begin y_coord(r):=dest_x+dest_y-x_coord(p);
+ if left_y(r)>y_coord(r) then
+ begin left_y(r):=y_coord(r);
+ if right_y(p)>y_coord(r) then right_y(p):=y_coord(r);
+ end;
+ end;
+if x_coord(r)<x_coord(p) then x_coord(r):=x_coord(p)
+else if x_coord(r)+y_coord(r)>dest_x+dest_y then
+ x_coord(r):=dest_x+dest_y-y_coord(r);
+left_x(r):=x_coord(r);
+if right_x(p)>x_coord(r) then right_x(p):=x_coord(r);
+ {we always have |x_coord(p)<=right_x(p)|}
+y_coord(r):=y_coord(r)+x_coord(r); right_y(r):=right_y(r)+x_coord(r);@/
+negate(x_coord(r)); right_x(r):=x_coord(r);@/
+left_y(q):=left_y(q)+left_x(q); negate(left_x(q));@/
+dest_y:=dest_y+dest_x; negate(dest_x);
+if right_y(r)>dest_y then right_y(r):=dest_y;
+if left_y(q)>dest_y then left_y(q):=dest_y
+else if left_y(q)<y_coord(r) then left_y(q):=y_coord(r);
+if right_y(r)>left_y(q) then right_y(r):=left_y(q);
+@z
+@x ibid
+else if x_coord(r)>dest_x then x_coord(r):=dest_x
+@y
+else begin if x_coord(r)>dest_x then
+ begin x_coord(r):=dest_x; left_x(r):=-x_coord(r); right_x(r):=x_coord(r);
+ end;
+ if left_x(q)>dest_x then left_x(q):=dest_x
+ else if left_x(q)<x_coord(r) then left_x(q):=x_coord(r);
+ end;
+@z
+@x module 425 is entirely replaced
+@y by the following code:
+@ @<Subdivide the cubic a second time with respect to $x'-y'$@>=
+begin split_cubic(r,t,dest_x,dest_y); s:=link(r);@/
+if x_coord(r)+y_coord(s)>dest_x+dest_y then
+ begin y_coord(s):=dest_x+dest_y-x_coord(r);
+ if left_y(s)>y_coord(s) then
+ begin left_y(s):=y_coord(s);
+ if right_y(r)>y_coord(s) then right_y(r):=y_coord(s);
+ end;
+ end;
+if x_coord(s)+y_coord(s)>dest_x+dest_y then x_coord(s):=dest_x+dest_y-y_coord(s)
+else begin if x_coord(s)<dest_x then x_coord(s):=dest_x;
+ if x_coord(s)<x_coord(r) then x_coord(s):=x_coord(r);
+ end;
+right_type(s):=right_type(p);
+left_x(s):=x_coord(s); {now |x_coord(r)=right_x(r)<=left_x(s)|}
+if left_x(q)<dest_x then
+ begin left_y(q):=left_y(q)+dest_x; left_x(q):=-dest_x;@+end
+else if left_x(q)>x_coord(s) then
+ begin left_y(q):=left_y(q)+x_coord(s); left_x(q):=-x_coord(s);@+end
+else begin left_y(q):=left_y(q)+left_x(q); negate(left_x(q));@+end;
+y_coord(s):=y_coord(s)+x_coord(s); right_y(s):=right_y(s)+x_coord(s);@/
+negate(x_coord(s)); right_x(s):=x_coord(s);@/
+dest_y:=dest_y+dest_x;
+if right_y(s)>dest_y then right_y(s):=dest_y;
+if left_y(q)>dest_y then left_y(q):=dest_y
+else if left_y(q)<y_coord(s) then left_y(q):=y_coord(s);
+if right_y(s)>left_y(q) then right_y(s):=left_y(q);
+end
+@z
+
+551. Major change for extended ligatures.
+@x module 11 (this may affect change files)
+@!lig_table_size=300; {maximum number of ligature/kern steps}
+@y
+@!lig_table_size=5000; {maximum number of ligature/kern steps, must be
+ at least 255 and at most 32510}
+@!max_kerns=500; {maximum number of distinct kern amounts}
+@z
+@x module 14 gets a new line of code
+@y
+if(lig_table_size<255)or(lig_table_size>32510)then bad:=7;
+@z
+@x module 186
+@d lig_kern_token=76 {the operators `\&{kern}' and `\.{=:}'}
+@d assignment=77 {the operator `\.{:=}'}
+@d colon=78 {the operator `\.:'}
+@#
+@d comma=79 {the operator `\.,'}
+@d end_of_statement==cur_cmd>comma
+@d semicolon=80 {the operator `\.;', must be |comma+1|}
+@d end_group=81 {end a group (\&{endgroup}), must be |semicolon+1|}
+@d stop=82 {end a job (\&{end}, \&{dump}), must be |end_group+1|}
+@y
+@d lig_kern_token=76
+ {the operators `\&{kern}' and `\.{=:}' and `\.{=:\char'174}, etc.}
+@d assignment=77 {the operator `\.{:=}'}
+@d skip_to=78 {the operation `\&{skipto}'}
+@d bchar_label=79 {the operator `\.{\char'174\char'174:}'}
+@d double_colon=80 {the operator `\.{::}'}
+@d colon=81 {the operator `\.:'}
+@#
+@d comma=82 {the operator `\.,', must be |colon+1|}
+@d end_of_statement==cur_cmd>comma
+@d semicolon=83 {the operator `\.;', must be |comma+1|}
+@d end_group=84 {end a group (\&{endgroup}), must be |semicolon+1|}
+@d stop=85 {end a job (\&{end}, \&{dump}), must be |end_group+1|}
+@z
+@x module 190
+@d max_given_internal=warning_check
+@y
+@d boundary_char=41 {the right boundary character for ligatures}
+@d max_given_internal=41
+@z
+@x module 192 gets two new lines of code
+@y
+primitive("boundarychar",internal_quantity,boundary_char);@/
+@!@:boundary_char_}{\&{boundarychar} primitive@>
+@z
+@x and module 193 gets one too
+@y
+int_name[boundary_char]:="boundarychar";
+@z
+@x and module 211 gets several
+@y (to be inserted in appropriate places)
+primitive("::",double_colon,0);
+@!@::: }{\.{::} primitive@>
+primitive("||:",bchar_label,0);
+@!@:::: }{\.{\char'174\char'174:} primitive@>
+primitive("skipto",skip_to,0);@/
+@!@:skip_to_}{\&{skipto} primitive@>
+@z
+@x as does module 212
+@y
+bchar_label:print("||:");
+double_colon:print("::");
+skip_to:print("skipto");
+@z
+@x module 1093 has new text (see TeX change 362 for module 545) and also this:
+@d stop_bit(#)==lig_kern[#].b0
+@d next_char(#)==lig_kern[#].b1
+@d op_bit(#)==lig_kern[#].b2
+@y
+@d skip_byte(#)==lig_kern[#].b0
+@d next_char(#)==lig_kern[#].b1
+@d op_byte(#)==lig_kern[#].b2
+@z
+@x module 1096 gets a new definition
+@y
+@d undefined_label==lig_table_size {an undefined local label}
+@z
+@x ...and some changed declarations
+@!char_remainder:array[eight_bits] of eight_bits; {the |remainder| byte}
+@!header_byte:array[1..header_size] of -1..255;
+ {bytes of the \.{TFM} header, or $-1$ if unset}
+@!lig_kern:array[0..lig_table_size] of four_quarters; {the ligature/kern table}
+@!nl:0..lig_table_size; {the number of ligature/kern steps so far}
+@!kern:array[eight_bits] of scaled; {distinct kerning amounts}
+@!nk:0..256; {the number of distinct kerns so far}
+@y
+@!char_remainder:array[eight_bits] of 0..lig_table_size; {the |remainder| byte}
+@!header_byte:array[1..header_size] of -1..255;
+ {bytes of the \.{TFM} header, or $-1$ if unset}
+@!lig_kern:array[0..lig_table_size] of four_quarters; {the ligature/kern table}
+@!nl:0..32767-256; {the number of ligature/kern steps so far}
+@!kern:array[0..max_kerns] of scaled; {distinct kerning amounts}
+@!nk:0..max_kerns; {the number of distinct kerns so far}
+@z
+@x ...and some new declarations
+@y
+@!skip_table:array[eight_bits] of 0..lig_table_size; {local label status}
+@!lk_started:boolean; {has there been a lig/kern step in this command yet?}
+@!bchar:integer; {right boundary character}
+@!bch_label:0..lig_table_size; {left boundary starting location}
+@!ll,@!lll:0..lig_table_size; {registers used for lig/kern processing}
+@!label_loc:array[0..256] of -1..lig_table_size; {lig/kern starting addresses}
+@!label_char:array[1..256] of eight_bits; {characters for |label_loc|}
+@!label_ptr:0..256; {highest position occupied in |label_loc|}
+@z
+@x module 1097
+ end;
+for k:=1 to header_size do header_byte[k]:=-1;
+bc:=255; ec:=0; nl:=0; nk:=0; ne:=0; np:=0;
+@y
+ skip_table[k]:=undefined_label;
+ end;
+for k:=1 to header_size do header_byte[k]:=-1;
+bc:=255; ec:=0; nl:=0; nk:=0; ne:=0; np:=0;@/
+internal[boundary_char]:=-unity;
+bch_label:=undefined_label;@/
+label_loc[0]:=-1; label_ptr:=0;
+@z
+@x module 1104
+procedure set_tag(@!c:eight_bits;@!t:small_number;@!r:eight_bits);
+begin if char_tag[c]=no_tag then
+ begin char_tag[c]:=t; char_remainder[c]:=r;
+@y
+procedure set_tag(@!c:halfword;@!t:small_number;@!r:halfword);
+begin if char_tag[c]=no_tag then
+ begin char_tag[c]:=t; char_remainder[c]:=r;
+ if t=lig_tag then
+ begin incr(label_ptr); label_loc[label_ptr]:=r; label_char[label_ptr]:=c;
+ end;
+@z
+@x module 1105
+if (c>" ")and(c<128) then print(c)
+@y
+if (c>" ")and(c<127) then print(c)
+else if c=256 then print("||")
+@z
+@x module 1106
+label continue;
+var @!c,@!cc:eight_bits; {character codes}
+@!k:0..256; {index into the |kern| array}
+@y
+label continue,done;
+var @!c,@!cc:0..256; {character codes}
+@!k:0..max_kerns; {index into the |kern| array}
+@z
+% also the previous code of module 1107 is inserted into 1106
+@x modules 1107--1111 are completely replaced
+@y by the following new code:
+@ @<Store a list of ligature/kern steps@>=
+begin lk_started:=false;
+continue: get_x_next;
+if(cur_cmd=skip_to)and lk_started then
+ @<Process a |skip_to| command and |goto done|@>;
+if cur_cmd=bchar_label then
+ begin c:=256; cur_cmd:=colon;@+end
+else begin back_input; c:=get_code;@+end;
+if(cur_cmd=colon)or(cur_cmd=double_colon)then
+ @<Record a label in a lig/kern subprogram and |goto continue|@>;
+if cur_cmd=lig_kern_token then @<Compile a ligature/kern command@>
+else begin print_err("Illegal ligtable step");
+@.Illegal ligtable step@>
+ help1("I was looking for `=:' or `kern' here.");
+ back_error; next_char(nl):=qi(0); op_byte(nl):=qi(0); rem_byte(nl):=qi(0);@/
+ skip_byte(nl):=stop_flag+1; {this specifies an unconditional stop}
+ end;
+if nl=lig_table_size then overflow("ligtable size",lig_table_size);
+@:METAFONT capacity exceeded ligtable size}{\quad ligtable size@>
+incr(nl);
+if cur_cmd=comma then goto continue;
+if skip_byte(nl-1)<stop_flag then skip_byte(nl-1):=stop_flag;
+done:end
+
+@ @<Put each...@>=
+primitive("=:",lig_kern_token,0);
+@!@:=:_}{\.{=:} primitive@>
+primitive("=:|",lig_kern_token,1);
+@!@:=:/_}{\.{=:\char'174} primitive@>
+primitive("=:|>",lig_kern_token,5);
+@!@:=:/>_}{\.{=:\char'174>} primitive@>
+primitive("|=:",lig_kern_token,2);
+@!@:=:/_}{\.{\char'174=:} primitive@>
+primitive("|=:>",lig_kern_token,6);
+@!@:=:/>_}{\.{\char'174=:>} primitive@>
+primitive("|=:|",lig_kern_token,3);
+@!@:=:/_}{\.{\char'174=:\char'174} primitive@>
+primitive("|=:|>",lig_kern_token,7);
+@!@:=:/>_}{\.{\char'174=:\char'174>} primitive@>
+primitive("|=:|>>",lig_kern_token,11);
+@!@:=:/>_}{\.{\char'174=:\char'174>>} primitive@>
+primitive("kern",lig_kern_token,128);
+@!@:kern_}{\&{kern} primitive@>
+
+@ @<Cases of |print_cmd...@>=
+lig_kern_token: case m of
+0:print("=:");
+1:print("=:|");
+2:print("|=:");
+3:print("|=:|");
+5:print("=:|>");
+6:print("|=:>");
+7:print("|=:|>");
+11:print("|=:|>>");
+othercases print("kern")
+endcases;
+
+@ Local labels are implemented by maintaining the |skip_table| array,
+where |skip_table[c]| is either |undefined_label| or the address of the
+most recent lig/kern instruction that skips to local label~|c|. In the
+latter case, the |skip_byte| in that instruction will (temporarily)
+be zero if there were no prior skips to this label, or it will be the
+distance to the prior skip.
+
+We may need to cancel skips that span more than 127 lig/kern steps.
+
+@d cancel_skips(#)==ll:=#;
+ repeat lll:=qo(skip_byte(ll)); skip_byte(ll):=stop_flag; ll:=ll-lll;
+ until lll=0
+@d skip_error(#)==begin print_err("Too far to skip");
+@.Too far to skip@>
+ help1("At most 127 lig/kern steps can separate skipto1 from 1::.");
+ error; cancel_skips(#);
+ end
+
+@<Process a |skip_to| command and |goto done|@>=
+begin c:=get_code;
+if nl-skip_table[c]>128 then {|skip_table[c]<<nl<=undefined_label|}
+ begin skip_error(skip_table[c]); skip_table[c]:=undefined_label;
+ end;
+if skip_table[c]=undefined_label then skip_byte(nl-1):=qi(0)
+else skip_byte(nl-1):=qi(nl-skip_table[c]-1);
+skip_table[c]:=nl-1; goto done;
+end
+
+@ @<Record a label in a lig/kern subprogram and |goto continue|@>=
+begin if cur_cmd=colon then
+ if c=256 then bch_label:=nl
+ else set_tag(c,lig_tag,nl)
+else if skip_table[c]<undefined_label then
+ begin ll:=skip_table[c]; skip_table[c]:=undefined_label;
+ repeat lll:=qo(skip_byte(ll));
+ if nl-ll>128 then
+ begin skip_error(ll); goto continue;
+ end;
+ skip_byte(ll):=qi(nl-ll-1); ll:=ll-lll;
+ until lll=0;
+ end;
+goto continue;
+end
+@x module 1112
+next_char(nl):=qi(c); op_bit(nl):=qi(cur_mod); stop_bit(nl):=qi(0);
+if cur_mod=0 then rem_byte(nl):=qi(get_code)
+@y
+begin next_char(nl):=qi(c); skip_byte(nl):=qi(0);
+if cur_mod<128 then {ligature op}
+ begin op_byte(nl):=qi(cur_mod); rem_byte(nl):=qi(get_code);
+ end
+@z
+@x ibid
+ begin if nk=256 then overflow("kern",256);
+@:METAFONT capacity exceeded kern}{\quad kern@>
+ incr(nk);
+ end;
+ rem_byte(nl):=qi(k);
+ end
+@y
+ begin if nk=max_kerns then overflow("kern",max_kerns);
+@:METAFONT capacity exceeded kern}{\quad kern@>
+ incr(nk);
+ end;
+ op_byte(nl):=kern_flag+(k div 256);
+ rem_byte(nl):=qi((k mod 256));
+ end;
+lk_started:=true;
+end
+@z
+@x module 1135
+tfm_two(6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np);
+ {this is the total number of file words that will be output}
+tfm_two(lh); tfm_two(bc); tfm_two(ec); tfm_two(nw); tfm_two(nh);
+tfm_two(nd); tfm_two(ni); tfm_two(nl); tfm_two(nk); tfm_two(ne); tfm_two(np);
+@y
+@<Compute the ligature/kern program offset and implant the
+ left boundary label@>;
+tfm_two(6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+lk_offset+nk+ne+np);
+ {this is the total number of file words that will be output}
+tfm_two(lh); tfm_two(bc); tfm_two(ec); tfm_two(nw); tfm_two(nh);
+tfm_two(nd); tfm_two(ni); tfm_two(nl+lk_offset); tfm_two(nk); tfm_two(ne);
+tfm_two(np);
+@z
+% modules 1137&1138 are combined into a single module
+% and so are modules 1140--1141, to make room for two new modules.
+@x module 1136 is moved to after old module 1141
+@y and changed to the following code:
+@ @<Log the subfile sizes of the \.{TFM} file@>=
+if bch_label<undefined_label then decr(nl);
+wlog_ln('(You used ',nw:1,'w,',@| nh:1,'h,',@| nd:1,'d,',@| ni:1,'i,',@|
+ nl:1,'l,',@| nk:1,'k,',@| ne:1,'e,',@|
+ np:1,'p metric file positions');
+wlog_ln(' out of ',@| '256w,16h,16d,64i,',@|
+ lig_table_size:1,'l,',max_kerns:1,'k,256e,',@|
+ max_font_dimen:1,'p)');
+end
+@z
+@x module 1139 is completely replaced
+@y by the following three modules:
+@ We need to output special instructions at the beginning of the
+|lig_kern| array in order to specify the right boundary character
+and/or to handle starting addresses that exceed 255. The |label_loc|
+and |label_char| arrays have been set up to record all the
+starting addesses; we have $-1=|label_loc|[0]<|label_loc|[1]\le\cdots
+\le|label_loc|[|label_ptr]|$.
+
+@<Compute the ligature/kern program offset...@>=
+bchar:=round_unscaled(internal[boundary_char]);
+if(bchar<0)or(bchar>255)then
+ begin bchar:=-1; lk_started:=false; lk_offset:=0;@+end
+else begin lk_started:=true; lk_offset:=1;@+end;
+@<Find the minimum |lk_offset| and adjust all remainders@>;
+if bch_label<undefined_label then
+ begin skip_byte(nl):=qi(255); next_char(nl):=qi(0);
+ op_byte(nl):=qi(((bch_label+lk_offset)div 256));
+ rem_byte(nl):=qi(((bch_label+lk_offset)mod 256));
+ incr(nl); {possibly |nl=lig_table_size+1|}
+ end
+
+@ @<Find the minimum |lk_offset|...@>=
+k:=label_ptr; {pointer to the largest unallocated label}
+if label_loc[k]+lk_offset>255 then
+ begin lk_offset:=0; lk_started:=false; {location 0 can do double duty}
+ repeat char_remainder[label_char[k]]:=lk_offset;
+ while label_loc[k-1]=label_loc[k] do
+ begin decr(k); char_remainder[label_char[k]]:=lk_offset;
+ end;
+ incr(lk_offset); decr(k);
+ until lk_offset+label_loc[k]<256;
+ {N.B.: |lk_offset=256| satisfies this when |k=0|}
+ end;
+if lk_offset>0 then
+ while k>0 do
+ begin char_remainder[label_char[k]]
+ :=char_remainder[label_char[k]]+lk_offset;
+ decr(k);
+ end
+
+@ @<Output the ligature/kern program@>=
+for k:=0 to 255 do if skip_table[k]<undefined_label then
+ begin print_nl("(local label "); print_int(k); print(":: was missing)");
+@.local label l:: was missing@>
+ cancel_skips(skip_table[k]);
+ end;
+if lk_started then {|lk_offset=1| for the special |bchar|}
+ begin tfm_out(255); tfm_out(bchar); tfm_two(0);
+ end
+else for k:=1 to lk_offset do {output the redirection specs}
+ begin ll:=label_loc[label_ptr];
+ if bchar<0 then
+ begin tfm_out(254); tfm_out(0);
+ end
+ else begin tfm_out(255); tfm_out(bchar);
+ end;
+ tfm_two(ll+lk_offset);
+ repeat decr(label_ptr);
+ until label_loc[label_ptr]<ll;
+ end;
+for k:=0 to nl-1 do tfm_qqqq(lig_kern[k]);
+for k:=0 to nk-1 do tfm_four(dimen_out(kern[k]))
+@z
+@x module 1205 gets a new declaration
+@y
+@!lk_offset:0..256; {extra words inserted at beginning of |lig_kern| array}
+@z
+
+552. Improved the covering/shortening routines. (18 Dec 89)
+@x module 1119 gets a new global variable
+@y
+@!excess:integer; {the list is this much too long}
+@z
+@x module 1120 gives it a value
+begin if min_cover(0)<=m then threshold:=0
+@y
+begin excess:=min_cover(0)-m;
+if excess<=0 then threshold:=0
+@z
+@x and module 1122 uses it
+begin repeat p:=link(p); info(p):=m;
+@y
+begin repeat p:=link(p); info(p):=m;
+decr(excess);@+if excess=0 then d:=0;
+@z
+@x and module 1122 also avoids overflow/ambiguous halving
+v:=half(l+value(p));
+@y
+v:=l+half(value(p)-l);
+@z
+
+553. Global variable used prematurely in do_add_to (Alan Jeffrey, 9 Feb 90)
+@x module 403
+@!cur_path_type:double_path_code..also_code; {likewise}
+@y
+@!cur_path_type:double_path_code..contour_code; {likewise}
+@z
+@x module 1059
+begin get_x_next; var_flag:=thing_to_add; scan_primary;
+if cur_type<>token_list then
+ @<Abandon edges command because there's no variable@>
+else begin lhs:=cur_exp; cur_path_type:=cur_mod;@/
+ cur_type:=vacuous; get_x_next; scan_expression;
+ if cur_path_type=also_code then @<Augment some edges by others@>
+@y
+@!add_to_type:double_path_code..also_code; {modifier of \&{addto}}
+begin get_x_next; var_flag:=thing_to_add; scan_primary;
+if cur_type<>token_list then
+ @<Abandon edges command because there's no variable@>
+else begin lhs:=cur_exp; add_to_type:=cur_mod;@/
+ cur_type:=vacuous; get_x_next; scan_expression;
+ if add_to_type=also_code then @<Augment some edges by others@>
+@z
+@x module 1064
+else begin lhs:=null;
+@y
+else begin lhs:=null; cur_path_type:=add_to_type;
+@z
+
+554. Balance the parens showing on the terminal (for Lispers).
+@x module 631
+@!in_open : 0..max_in_open; {the number of lines in the buffer, less one}
+@y
+@!in_open : 0..max_in_open; {the number of lines in the buffer, less one}
+@!open_parens : 0..max_in_open; {the number of open text files}
+@z
+@x module 657
+in_open:=0; max_buf_stack:=0;
+@y
+in_open:=0; open_parens:=0; max_buf_stack:=0;
+@z
+@x module 681
+ begin print_char(")"); force_eof:=false;
+ update_terminal; {show user that file has been read}
+@y
+ begin print_char(")"); decr(open_parens);
+ update_terminal; {show user that file has been read}
+ force_eof:=false;
+@z
+@x module 793
+print_char("("); print(name); update_terminal;
+@y
+print_char("("); incr(open_parens); print(name); update_terminal;
+@z
+@x module 1209
+if job_name=0 then open_log_file;
+@y
+if job_name=0 then open_log_file;
+while open_parens>0 do
+ begin print(" )"); decr(open_parens);
+ end;
+@z
+
+-----------Here I draw the line with respect to further changes
+
+555. Don't try system area if an area was given (see tex82.bug number 312;
+found by Jonathan Kew, May 1990)
+@x module 793
+ pack_file_name(cur_name,MF_area,cur_ext);
+ if a_open_in(cur_file) then goto done;
+@y
+ if cur_area="" then
+ begin pack_file_name(cur_name,MF_area,cur_ext);
+ if a_open_in(cur_file) then goto done;
+ end;
+@z
+
+556. Report correct line number when buffer overflows (CET, Jul 90).
+@x module 794
+begin if not input_ln(cur_file,false) then do_nothing;
+firm_up_the_line;
+buffer[limit]:="%"; first:=limit+1; loc:=start; line:=1;
+@y
+begin line:=1;
+if input_ln(cur_file,false) then do_nothing;
+firm_up_the_line;
+buffer[limit]:="%"; first:=limit+1; loc:=start;
+@z
+
+557. TeX82 bug 308, corrected in 1985, is also in MF! (Lutz Birkhahn, May91)
+@x module 176
+var_used:=lo_mem_stat_max+1-mem_min; dyn_used:=mem_top+1-hi_mem_stat_min;
+@y
+var_used:=lo_mem_stat_max+1-mem_min; dyn_used:=mem_top+1-hi_mem_min;
+@z
+
+558. Allow unprintable file names, as in TeX change 396 (19 Sep 91)
+(Much of this is redundant except for people who make nonportable
+versions that allow other 8-bit codes to be in variable names---and for
+those people only if they allow input of more codes than they can print!
+Still, it seems best to make the programs for TeX and MF as alike as possible.)
+@x module 59
+j:=str_start[s];
+while j<str_start[s+1] do
+ begin print_char(so(str_pool[j])); incr(j);
+ end;
+@y
+if (s<256)and(selector>pseudo) then print_char(s)
+else begin j:=str_start[s];
+ while j<str_start[s+1] do
+ begin print_char(so(str_pool[j])); incr(j);
+ end;
+ end;
+@z
+@x module 60
+j:=str_start[s];
+while j<str_start[s+1] do
+ begin print(so(str_pool[j])); incr(j);
+ end;
+@y
+if (s<256)and(selector>pseudo) then print_char(s)
+else begin j:=str_start[s];
+ while j<str_start[s+1] do
+ begin print(so(str_pool[j])); incr(j);
+ end;
+ end;
+@z
+@x module 61
+else begin print(base_ident); print_ln;
+@y
+else begin slow_print(base_ident); print_ln;
+@z
+@x module 79
+ print(input_stack[file_ptr].name_field);
+@y
+ slow_print(input_stack[file_ptr].name_field);
+@z
+@x module 223
+print(r);
+@y
+slow_print(r);
+@z
+@x module 254
+ print(int_name[q-(hash_end)]); print_char("=");
+@y
+ slow_print(int_name[q-(hash_end)]); print_char("=");
+@z
+@x module 254 again
+ print(text(q)); print_char("}");
+@y
+ slow_print(text(q)); print_char("}");
+@z
+@x module 638
+ if name<>null then print(text(name))
+@y
+ if name<>null then slow_print(text(name))
+@z
+@x module 664
+ if scanner_status=op_defining then print(text(warning_info))
+@y
+ if scanner_status=op_defining then slow_print(text(warning_info))
+@z
+@x module 664 again
+loop_defining: begin print("the text of a "); print(text(warning_info));
+@y
+loop_defining: begin print("the text of a "); slow_print(text(warning_info));
+@z
+@x module 722
+begin if n<>null then print(text(n))
+@y
+begin if n<>null then slow_print(text(n))
+@z
+@x module 722 again
+ if p=null then print(text(info(info(link(a)))))
+@y
+ if p=null then slow_print(text(info(info(link(a)))))
+@z
+@x module 725
+ print_nl(" Missing `"); print(text(r_delim));
+@y
+ print_nl(" Missing `"); slow_print(text(r_delim));
+@z
+@x module 773
+begin print(a); print(n); print(e);
+@y
+begin slow_print(a); slow_print(n); slow_print(e);
+@z
+@x module 790
+print(base_ident); print(" ");
+@y
+slow_print(base_ident); print(" ");
+@z
+@x module 793
+print_char("("); incr(open_parens); print(name); update_terminal;
+@y
+print_char("("); incr(open_parens); slow_print(name); update_terminal;
+@z
+@x module 998
+if info(lhs)>hash_end then print(int_name[info(lhs)-(hash_end)])
+@y
+if info(lhs)>hash_end then slow_print(int_name[info(lhs)-(hash_end)])
+@z
+@x module 999
+ print(int_name[info(lhs)-(hash_end)]);
+@y
+ slow_print(int_name[info(lhs)-(hash_end)]);
+@z
+@x module 1032
+else begin print_err("The token `"); print(text(r_delim));
+@y
+else begin print_err("The token `"); slow_print(text(r_delim));
+@z
+@x module 1034
+ else print(text(cur_sym));
+@y
+ else slow_print(text(cur_sym));
+@z
+@x module 1041
+else begin print(text(cur_sym)); print_char("=");
+@y
+else begin slow_print(text(cur_sym)); print_char("=");
+@z
+@x module 1042
+else begin print_char(""""); print(cur_mod); print_char("""");
+@y
+else begin print_char(""""); slow_print(cur_mod); print_char("""");
+@z
+@x module 1043
+ print("t delimiter that matches "); print(text(m));
+@y
+ print("t delimiter that matches "); slow_print(text(m));
+@z
+@x module 1043 again
+internal_quantity:print(int_name[m]);
+@y
+internal_quantity:slow_print(int_name[m]);
+@z
+@x module 1134
+print_nl("Font metrics written on "); print(metric_file_name); print_char(".");
+@y
+print_nl("Font metrics written on "); slow_print(metric_file_name);
+print_char(".");
+@z
+@x module 1182
+print_nl("Output written on "); print(output_file_name);
+@y
+print_nl("Output written on "); slow_print(output_file_name);
+@z
+@x module 1200
+print(w_make_name_string(base_file)); flush_string(str_ptr-1);
+print_nl(base_ident)
+@y
+slow_print(w_make_name_string(base_file)); flush_string(str_ptr-1);
+print_nl(""); slow_print(base_ident)
+@z
+@x module 1205
+ print(log_name); print_char(".");
+@y
+ slow_print(log_name); print_char(".");
+@z
+@x module 1213
+10: print(n);
+@y
+10: slow_print(n);
+@z
+
+------ The third printing of Volume D (October 1991) incorporated the above.
+
+559. Debugging routine never used since change 528; needed update then (JDH).
+@x module 617
+ p:=dep_list(p); r:=hi_mem_min;
+ repeat if info(p)>=r then
+@y
+ p:=dep_list(p); r:=inf_val;
+ repeat if value(info(p))>=value(r) then
+@z
+
+560. Corrections to blunders in change 550 (noted by B Jackowski, Jul 91).
+@x module 415 can use more paranoia even though no problems have occurred yet
+negate(left_y(qq)); negate(dest_y);@/
+@y
+negate(left_y(qq)); negate(dest_y);@/
+if x_coord(r)<x_coord(pp) then x_coord(r):=x_coord(pp)
+else if x_coord(r)>dest_x then x_coord(r):=dest_x;
+if left_x(r)>x_coord(r) then
+ begin left_x(r):=x_coord(r);
+ if right_x(pp)>x_coord(r) then right_x(pp):=x_coord(r);
+ end;
+if right_x(r)<x_coord(r) then
+ begin right_x(r):=x_coord(r);
+ if left_x(qq)<x_coord(r) then left_x(qq):=x_coord(r);
+ end;
+@z
+@x module 416 similarly
+negate(y_coord(s)); right_y(s):=y_coord(s);
+@y
+negate(y_coord(s)); right_y(s):=y_coord(s);
+if x_coord(s)<x_coord(r) then x_coord(s):=x_coord(r)
+else if x_coord(s)>dest_x then x_coord(s):=dest_x;
+if left_x(s)>x_coord(s) then
+ begin left_x(s):=x_coord(s);
+ if right_x(r)>x_coord(s) then right_x(r):=x_coord(s);
+ end;
+if right_x(s)<x_coord(s) then
+ begin right_x(s):=x_coord(s);
+ if left_x(qq)<x_coord(s) then left_x(qq):=x_coord(s);
+ end;
+@z
+@x module 424 similarly
+if x_coord(p)+y_coord(r)>dest_x+dest_y then
+ begin y_coord(r):=dest_x+dest_y-x_coord(p);
+ if left_y(r)>y_coord(r) then
+ begin left_y(r):=y_coord(r);
+ if right_y(p)>y_coord(r) then right_y(p):=y_coord(r);
+ end;
+ end;
+@y
+if y_coord(r)<y_coord(p) then y_coord(r):=y_coord(p)
+else if y_coord(r)>dest_y then y_coord(r):=dest_y;
+if x_coord(p)+y_coord(r)>dest_x+dest_y then
+ y_coord(r):=dest_x+dest_y-x_coord(p);
+if left_y(r)>y_coord(r) then
+ begin left_y(r):=y_coord(r);
+ if right_y(p)>y_coord(r) then right_y(p):=y_coord(r);
+ end;
+if right_y(r)<y_coord(r) then
+ begin right_y(r):=y_coord(r);
+ if left_y(q)<y_coord(r) then left_y(q):=y_coord(r);
+ end;
+@z
+@x in module 424, here's the serious bug introduced in change #550.
+if right_y(r)>dest_y then right_y(r):=dest_y;
+if left_y(q)>dest_y then left_y(q):=dest_y
+else if left_y(q)<y_coord(r) then left_y(q):=y_coord(r);
+if right_y(r)>left_y(q) then right_y(r):=left_y(q);
+@y
+if right_y(r)<y_coord(r) then
+ begin right_y(r):=y_coord(r);
+ if left_y(q)<y_coord(r) then left_y(q):=y_coord(r);
+ end;
+@z
+@x module 425 is analogous
+if x_coord(r)+y_coord(s)>dest_x+dest_y then
+ begin y_coord(s):=dest_x+dest_y-x_coord(r);
+ if left_y(s)>y_coord(s) then
+ begin left_y(s):=y_coord(s);
+ if right_y(r)>y_coord(s) then right_y(r):=y_coord(s);
+ end;
+ end;
+@y
+if y_coord(s)<y_coord(r) then y_coord(s):=y_coord(r)
+else if y_coord(s)>dest_y then y_coord(s):=dest_y;
+if x_coord(r)+y_coord(s)>dest_x+dest_y then
+ y_coord(s):=dest_x+dest_y-x_coord(r);
+if left_y(s)>y_coord(s) then
+ begin left_y(s):=y_coord(s);
+ if right_y(r)>y_coord(s) then right_y(r):=y_coord(s);
+ end;
+if right_y(s)<y_coord(s) then
+ begin right_y(s):=y_coord(s);
+ if left_y(q)<y_coord(s) then left_y(q):=y_coord(s);
+ end;
+@z
+@x module 425, the analogous bug
+dest_y:=dest_y+dest_x;
+if right_y(s)>dest_y then right_y(s):=dest_y;
+if left_y(q)>dest_y then left_y(q):=dest_y
+else if left_y(q)<y_coord(s) then left_y(q):=y_coord(s);
+if right_y(s)>left_y(q) then right_y(s):=left_y(q);
+@y
+if right_y(s)<y_coord(s) then
+ begin right_y(s):=y_coord(s);
+ if left_y(q)<y_coord(s) then left_y(q):=y_coord(s);
+ end;
+@z
+
+561. serious longstanding bug caused overflows and bad rounding (1 Mar 95)
+@x module 815
+begin if (max_c[dependent]>=fraction_one)or@|
+ (max_c[dependent] div @'10000 >= max_c[proto_dependent]) then
+@y
+begin if (max_c[dependent] div @'10000 >=
+ max_c[proto_dependent]) then
+@z
+
+562. final cleanup should not retain spurious reference counts (20 Mar 95)
+@x module 1209
+while open_parens>0 do
+@y
+while input_ptr>0 do
+ if token_state then end_token_list@+else end_file_reading;
+while loop_ptr<>null do stop_iteration;
+while open_parens>0 do
+@z
+@x module 1209
+ cur_if:=name_type(cond_ptr); cond_ptr:=link(cond_ptr);
+@y
+ cur_if:=name_type(cond_ptr); loop_ptr:=cond_ptr;
+ cond_ptr:=link(cond_ptr); free_node(loop_ptr,if_node_size);
+@z
+
+563. unprintable strings of length 1 need to be truly length 1 (27 Nov 95,
+pointed out by Ulrik Vieth)
+@x module 671
+ if loc=k+1 then cur_mod:=buffer[k]
+@y
+ if (loc=k+1) and (length(buffer[k])=1) then cur_mod:=buffer[k]
+@z
+
+564. minor improvement to pythagorean addition (22 Jan 97)
+@x module 124
+if a>0 then
+@y
+if b>0 then
+@z
+
+565. we need not raise hassles about two-digit years (23 Nov 98)
+@x module 1200
+print_int(round_unscaled(internal[year]) mod 100); print_char(".");
+@y
+print_int(round_unscaled(internal[year])); print_char(".");
+@z
+
+566. "this can't happen" can happen if coordinates are half vast
+ (Julian Gilbey, January 2001)
+@x module 402
+@!chopped:boolean; {have we truncated any of the data?}
+@y
+@!chopped:integer; {positive if data truncated,
+ negative if data dangerously large}
+@z
+@x module 402
+if internal[autorounding]>0 then xy_round;
+octant_subdivide; {complete the subdivision}
+if internal[autorounding]>unity then diag_round;
+@<Remove dead cubics@>;
+@<Insert octant boundaries and compute the turning number@>;
+while left_type(cur_spec)<>endpoint do cur_spec:=link(cur_spec);
+if tracing>0 then
+ if internal[autorounding]<=0 then print_spec(", after subdivision")
+@y
+if (internal[autorounding]>0)and(chopped=0) then xy_round;
+octant_subdivide; {complete the subdivision}
+if (internal[autorounding]>unity)and(chopped=0) then diag_round;
+@<Remove dead cubics@>;
+@<Insert octant boundaries and compute the turning number@>;
+while left_type(cur_spec)<>endpoint do cur_spec:=link(cur_spec);
+if tracing>0 then
+ if (internal[autorounding]<=0)or(chopped<>0) then
+ print_spec(", after subdivision")
+@z
+@x module 404
+@d procrustes(#)==if abs(#)>max_allowed then
+ begin chopped:=true;
+ if #>0 then #:=max_allowed@+else #:=-max_allowed;
+ end
+
+@<Truncate the values of all coordinates that exceed...@>=
+p:=cur_spec; k:=1; chopped:=false;
+@y
+@d procrustes(#)==if abs(#)>=dmax then
+ if abs(#)>max_allowed then
+ begin chopped:=1;
+ if #>0 then #:=max_allowed@+else #:=-max_allowed;
+ end
+ else if chopped=0 then chopped:=-1
+
+@<Truncate the values of all coordinates that exceed...@>=
+p:=cur_spec; k:=1; chopped:=0; dmax:=half(max_allowed);
+@z
+@x module 404
+if chopped then
+@y
+if chopped>0 then
+@z
+
+-------------
+567. The absolutely final change (to be made after my death)
+@x module 2
+@d banner=='This is METAFONT, Version 2.7182' {printed when \MF\ starts}
+@y
+@d banner=='This is METAFONT, Version $e$' {printed when \MF\ starts}
+@z
+When this change is made, the corresponding line should be changed in
+Volume D, and also on page 31 of The METAFONTbook.
+My last will and testament for METAFONT is that no further changes be made
+under any circumstances. Improved systems should not be called simply
+`METAFONT'; that name, unqualified, should refer only to the program for which
+I have taken personal responsibility. -- Don Knuth
diff --git a/Master/texmf-doc/doc/english/knuth/errata/tex82.bug b/Master/texmf-doc/doc/english/knuth/errata/tex82.bug
new file mode 100644
index 00000000000..2977f089156
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errata/tex82.bug
@@ -0,0 +1,9006 @@
+This file has been updated periodically ever since TeX82 was born;
+it has been summarized in "The errors of TeX," Software Practice &
+Experience, July 1989. Entries are in chronological order;
+thus the most recent news (including all bugfixes made since
+that article was published) appears at the bottom of the file.
+
+[Add 519 to these entry numbers to get the corresponding number in
+the published article. The article also translates all module
+numbers to their final form; what you are about to read is
+"authentic source material" from the early days before TeX converged.]
+
+-------------------------------------------------------------------------------
+
+First updates to the TeX82 listing published in September, 1982.
+(These changes were included in the original Version 0 of TeX, but they
+were discovered after the listing went to press.)
+
+1. Module 943, line 6 (bug discovered 9/28)
+change "if cur_cmd=char_num then" to
+ if (cur_cmd=letter) or (cur_cmd=other_char) then r:=qi(cur_chr)
+ else if cur_cmd=char_num then
+
+2. "pause" changed to "pausing" and "pause_code" to "pausing code", throughout.
+
+3. Module 719, lines 8 and 11 (bug discovered 9/28)
+insert "rule_save:=overfull_rule; overfull_rule:=0;" after "save_ptr-2;"
+insert "overfull_rule:=rule_save;" before "q:=p+list_offset;"
+and insert a declaration of "overfull_rule: scaled" in module 716.
+
+4. Module 1128, lines 6 and following (bug discovered 9/28)
+change "while n<>0 do" to "loop"
+change "goto done" to
+ begin scan_left_brace; new_save_level(false_group);
+ goto done;
+ end
+change "... return 1130>;" to
+ ... return 1130>
+ else if n=0 then
+ begin new_save_level(case_group); goto done;
+ end;
+and change "done: ... (false_group);" to "done:".
+
+5. Module 182, line 10 (suggestion by DRF on 9/30)
+change "0.0" to "?.?"
+
+6. Module 682, new definition of math_spacing (decision of 10/2)
+"0234000122*4000133**3**344*0400400*000000234000111*4111112341011"
+
+7. Module 684, new code for case "4" (decision of 10/2)
+"4": if cur_style<script_style then x:=thick_mu_skip_code else x:=0;
+[Also in module 682 line 7, say "...a conditional thick space (\nonscript..."]
+
+8. Module 11, trie_size changed from 7000 to 8000 because of new
+improved (but longer) hyphenation patterns (10/4)
+
+9. Module 453, forgot to change this when 454 changed (noted by DRF 10/6)
+format_default_length=20 (not 22)
+format_area_length=11 (not 13)
+
+ Changes to TEX.WEB made after Version 0 was released in October, 1982.
+
+Since copies of TEX.WEB are not supposed to be edited, there are
+two ways to make your version of TeX bug-free:
+ 1. Get a new copy of TEX.WEB.
+ 2. Put the corrections into your change file(s).
+Some people will find (1) easier than (2), except the main TeX sources at
+SCORE won't be updated quite as fast as the sources at SAIL (which have to
+be translated into ascii before they are sent to the outside world).
+Actually (2) will be quite easy, unless the list of changes becomes quite
+long, so it is the recommended procedure. In case (2) it would be useful
+to include a comment like "this is fix number xx" (using the numbering
+scheme in this file), so that the change could readily be deleted at some
+future time.
+
+10. Module 857 line -5 (bug discovered 10/8/82 by HWT)
+change it to: if h>0 then decr(h) else h:=trie_op_hash_size;
+
+11. Module 457 line 3 (typo discovered 10/9/82)
+change `\.!' to `\.\&'
+
+12. Module 1245 line 8 (bug fixed 10/9/82, discovered by MMD)
+insert the following between "begin" and "if":
+if format_ident<>0 then initialize; {erase preloaded format}
+
+** Version 0.1 incorporates the above changes.
+
+13. This is an extension to the language, put in to satisfy people who
+objected to the fact that \write (and \openout and \closeout) only
+caused action after being deferred to the next \shipout. Some applications
+call for immediate output, hence a new feature: \immediate followed by
+\openout or \write or \closeout causes the output action to take place
+without delay. For example, \immediate\write{x} is equivalent to
+\shipout\vbox{\write{x}} except that the latter also puts an empty
+page into the DVI file.
+
+The extension requires the following new code:
+13a. Insert `\immediate' after `\closeout' in module 1248.
+13b. Define immediate_code=4 and include the following in module 1252:
+ primitive("immediate",extension,immediate_code);
+13c. Include the following in module 1254:
+ immediate_code:print_esc("immediate");
+13d. And, in module 1256:
+ immediate_code:@<Implement \.{\\immediate}@>;
+13e. Finally, there's a new module inserted after old module 1280.
+Here is the WEB coding for this module:
+
+@ The presence of `\.{\\immediate}' causes the |do_extension| procedure
+to descend to one level of recursion. Nothing happens unless \.{\\immediate}
+is followed by `\.{\\openout}', `\.{\\write}', or `\.{\\closeout}'.
+@^recursion@>
+
+@<Implement \.{\\immediate}@>=
+begin get_nc_token;
+if (cur_cmd=extension)and(cur_chr<=close_node) then
+ begin p:=tail; do_extension; {append a whatsit node}
+ out_what(tail); {do the action immediately}
+ flush_node_list(tail); tail:=p; link(p):=null;
+ end
+else back_input;
+end;
+
+** Version 0.2 incorporates the above changes.
+
+14. Like change 11, this one doesn't affect the program, it just improves
+the documentation: Insert the following definitions in module 106:
+define set_glue_ratio_zero(#) == #:=0.0 {assign representation of zero ratio}
+define set_glue_ratio_one(#) == #:=1.0 {assign representation of unit ratio}
+
+These macros are now introduced in a dozen or so future modules, thereby
+eliminating most of the system-dependent changes needed elsewhere for ratios.
+(Note: I also changed 0 to 0.0 in two places of module 182, where a glue_ratio
+comparision was being made.)
+
+15. Change of module 576 (discovered by HWT, 10/14/82)
+"hd:quarterword" should be "hd:eight_bits".
+(The same error occurs in module 522, but in that module the remedy is
+simply to delete the declaration of hd, since this variable is no longer used.)
+
+16. A most embarrassing bug (discovered by DRF, 10/14/82)
+Replace module 531 by:
+
+@ A mild optimization of the output is performed by the |dvi_pop|
+routine, which issues a |pop| unless it is possible to cancel a
+`|push| |pop|' pair. The parameter to |dvi_pop| is the byte address
+following the old |push| that matches the new |pop|.
+
+@p procedure dvi_pop(@!l:integer);
+begin if (l=dvi_offset+dvi_ptr)and(dvi_ptr>0) then decr(dvi_ptr)
+else dvi_out(pop);
+end;
+
+Now we need to make a few changes to subsequent modules:
+16a. In 549, after "incr(cur_s)", insert
+ if cur_s>0 then dvi_out(push);
+and before "decr(cur_s)", insert
+ if cur_s>0 then dvi_pop(save_loc);
+
+16b. Delete "dvi_out(push);" and "dvi_pop;" from modules 553, 558, 562, 567.
+
+16c. Change module 559 just as in 16a.
+
+17. Module 605, line 6 (discovered 10/15/82)
+The test should be "prev_depth>ignore_depth"
+
+** Version 0.3 incorporates the above changes.
+
+18. Module 11 (noticed by WLS, 10/16/82)
+Delete the definition of align_size (it's harmless but never used)
+
+19. (This change and the next cause major changes to the TRIP output;
+file TRIP.LOG and its relatives are being kept up to date on area [tug,dek].)
+The change avoids error messages when vpackage is called during output.
+Such messages can occur when there was no error, because the page is being
+boxed without the \skip glue from its insertions; so they should be omitted.
+The user who really wants such messages can still get them by saying
+"\setbox255=\vbox to 1ht255{\unbox255}".
+In module 903, insert the followng before the declaration of "wait":
+ save_vbadness:integer; {saved value of |vbadness|}
+ save_vfuzz: scaled; {saved value of |vfuzz|}
+Then in module 924, insert
+ save_vbadness:=vbadness; vbadness:=inf_bad;
+ save_vfuzz:=vfuzz; vfuzz:=max_dimen; {inhibit error messages}
+before the call on vpackage, and
+ vbadness:=save_vbadness; vfuzz:=save_vfuzz;
+after.
+
+20. Module 917 computes |page_size| improperly. (Noticed 10/21/82)
+Delete the statement "page_so_far[1]:=page_so_far[1]+width(q);"
+and change the preceding statement to:
+ page_size:=page_size-h-width(q);
+(The comment about page_so_far in the first paragraph of module 895 is
+correct; I mistakenly introduced a bug in module 917 some months after
+writing the first draft of the code, believing that I was making the
+algorithm more elegant or something.)
+
+** Version 0.4 incorporates the above changes.
+
+21. Since TeX82 applied to (the "woven" documentation) TEX.TEX uses
+about 11500 words of variable-size memory, I'm increasing hi_mem_size
+(in module 12) from 12000 to 13000. Actually, I recommend using considerably
+larger values for mem_max and hi_mem_size, whenever possible.
+
+22. Addition of the \boxmaxdepth parameter (10/22/82):
+This involves renumbering hfuzz_code through dimen_pars, in module 234,
+to numbers 9 through 18; inserting the lines
+ @d box_max_depth_code=8 {maximum depth of explicit vboxes}
+ @d box_max_depth==dimen_par(box_max_depth_code)
+ box_max_depth_code:print_esc("boxmaxdepth");
+to module 234 and
+ primitive("boxmaxdepth",assign_dimen,box_max_depth_code);
+to module 235; and changing the call on vpack in module 996 to
+ vpackage(link(head),saved(2),saved(1),box_max_depth);
+
+** Version 0.5 incorporates the above changes.
+
+23. Module 1224, line 4 (bug found by GMK/HWT on 10/26/82)
+change "(k+x>eqtb_size)" to "(k+x>eqtb_size+1)"
+
+24. Module 247, line 13 (bug found 10/26/82)
+(bug was reflected in TRIP.LOG but not noticed)
+change "ch_code(p)" to "ch_code(p-single_base)"
+
+25. Module 670, line 18 (bug found 10/27/82)
+interchange the statements "fetch(...)" and "math_type(...):=..."
+(since the fetch routine sometimes has a side-effect of changing math_type)
+ A major change (Version 0.6) made on October 28:
+The following list of changes counts as "number 26" on the list.
+Fonts now have identifiers instead of code numbers; the "\:" primitive
+has disappeared; and there are associated new features for "\the".
+
+a. In module 11, delete bad_font_code.
+b. In modules 170 and 172, delete print_esc(":"), and change
+ `print_int(font_code' to `sprint_cs(font_ident'.
+c. In module 205, the comment for set_font is revised.
+d. In module 217, there are now five locations for control sequences
+ that are perpetually defined; undefined_control_sequence
+ is therefore defined to be frozen_control_sequence+5.
+e. In module 248, sprint_cs is now included among <Basic printing procedures>.
+f. Delete the primitive ":" in modules 250 and 251.
+g. Add to module 376: <Declare procedures that scan font-related stuff>
+h. In module 377, seven levels are now distinguished; we define
+ font_val=4, ident_val=5, tok_val=6.
+i. In module 380, delete the previous cases for def_family and set_font,
+ and the following takes the place of case assign_toks:
+ assign_toks,def_family,set_font,def_font: <Fetch a token list or
+ font number or font identifier, provided that level=tok_val>;
+j. Module 382 (which now has a new name) has this new ending:
+ else if cur_cmd=assign_toks then scanned_result(equiv(m))(tok_val)
+ else <Fetch a font number or a font identifier>
+k. Module 389 becomes
+ <Fetch a font number or a font identifier>=
+ if cur_cmd=set_font then scanned_result(cur_chr)(font_val)
+ else if cur_cmd=def_font then
+ scanned_result(font_ident[cur_font])(ident_val)
+ else begin scan_four_bit_int;
+ scanned_result(font_ident[equiv(m+cur_val)])(ident_val);
+ end
+l. In module 393, the relation `<>tok_val' becomes `<=mu_val'.
+m. In module 426, the relation `=tok_val' becomes '>=ident_val'.
+ Also add a new case to the case statement:
+ font_val: begin print(font_name[cur_val]);
+ if font_size[cur_val]<>font_dsize[cur_val] then
+ begin print(" at "); print_scaled(font_size[cur_val]);
+ print("pt");
+ end;
+ end;
+n. The body of module 427 becomes:
+ begin p:=temp_head; link(p):=null;
+ if cur_val_level=ident_val then store_new_token(cs_token_flag+cur_val)
+ else if cur_val<>null then
+ begin r:=link(cur_val); {do not copy the reference count}
+ while r<>null do
+ begin store_new_token(info(r)); r:=link(r);
+ end;
+ end;
+ the_toks:=p;
+ end
+o. In module 480, delete user_font_code; there's a new comment:
+ When the user defines \font\f, say, TeX assigns an internal number
+ to the user's font \f. For example, if this internal number is 13,
+ we will have font_ident[13]=p and equiv(p)=13, where p is the eqtb
+ location of the control sequence \f.
+p. In module 481, delete the declaration of font_number, and
+ replace the declaration of font_code by
+ font_ident:array[internal_font_number] of pointer;
+q. New stuff in module 483 (also delete references to font_number, font_code):
+ define bad_font_ident=frozen_control_sequence+4 {denotes a null font}
+ font_name[undefined_font]:="nullfont";
+ font_ident[undefined_font]:=bad_font_ident;
+ text(bad_font_ident):="nullfont"; eq_level(bad_font_ident):=level_one;
+ eq_type(bad_font_ident):=set_font;
+ equiv(bad_font_ident):=undefined_font;
+r. In module 490, parameter u is new of type pointer, and the
+ read_font_info subroutine is changed to a function that
+ returns an internal_font_number. There's a new local variable
+ g:internal_font_namber; {the number to return}
+ and we set g:=undefined_font immediately upon entering read_font_info.
+ Also set read_font_info:=g just before exiting.
+s. In module 491, print_int(u) becomes sprint_cs(u).
+t. Delete the statements involving font_code and font_number in module 506,
+ and set g:=f at the end of that module.
+u. The body of module 507 becomes:
+ <Declare procedures that scan font-related stuff>=
+ procedure scan_font_ident;
+ var f:internal_font_number;
+ begin <Get the next non-blank non-call...>;
+ if cur_cmd=set_font then f:=cur_chr
+ else begin print_nl("! Missing font identifier");
+ help2("I was looking for a control sequence whose")
+ ("current meaning has been defined by \font.");
+ back_error; f:=undefined_font;
+ end;
+ end;
+v. New beginning of module 508:
+ The following routine is used to implement `\texinfo f n'.
+ The boolean parameter writing is set true if the calling program
+ intends to change the parameter value.
+ <Declare procedures that scan font-related stuff>=
+and "scan_font_number" is changed to "scan_font_ident".
+w. In module 509, "print_int(font_code" becomes "sprint_cs(font_ident".
+ Also "font code is defined" becomes "\font is loaded" in the help.
+x. In module 940, the first line of help is changed to
+ "You have to specify a font identifier,"
+y. The set_font case in module 1138 reduces to
+ set_font: define(cur_font_loc,data,cur_chr);
+z. In module 1153, delete all the complicated stuff starting with "scan_int"
+ and substitute simply this:
+ scan_font_ident; define(p,data,cur_val);
+ end;
+aa. Change new_font to new_font(a) in module 1169, and add parameter
+ (a:small_number)
+ in module 1170. Also add the label common_ending, and declare
+ variable u to have type pointer. The code beginning with "scan_int"
+ is changed to the following:
+ get_token;
+ if cs_ptr=0 then
+ <Complain about the missing control sequence and return>;
+ u:=cs_ptr; scan_optional_equals; scan_file_name;
+ <Scan the ``at'' size specification>;
+ <If this font has already been loaded, set f to the internal
+ font number and goto common_ending>;
+ f:=read_font_info(u,cur_name,cur_area,s);
+ common_ending: define(u,set_font,f); font_ident[f]:=u;
+ exit:end;
+bb. New module 1172:
+ When the user gives a new identifier to a font that was previously
+ loaded, the new value becomes the font_ident of record.
+ Font names `xyz' and `XYZ' are considered to be different.
+ <If this font has already been loaded...>=
+ for f:=font_base+1 to font_ptr do
+ if [the test previously in module 1174] then goto common_ending
+cc. New module 1173:
+ <Complain about the missing control sequence and return>=
+ begin print_nl("! A font identifier must be a control sequence");
+ help2("You should say, e.g., `\font\f=fontfilename'.")
+ ("(I'm going to ignore the \font command you just gave.)");
+ back_error; return;
+ end
+dd. New module 1174:
+ <Cases of print_cmd_chr...>=
+ set_font:begin print("select font "); print(font_name[chr_code]);
+ if font_size[chr_code]<>font_dsize[chr_code] then
+ begin print(" at "); print_scaled(font_size[chr_code]);
+ print("pt");
+ end;
+ end;
+ee. Delete the comment at the beginning of module 1227, and delete the
+ loop for k:=0 to bad_font_code-1, and delete dump_int(undefined_font).
+ff. Delete the repeat loop in module 1228.
+gg. Change font_code to font_ident in module 1229, and change
+ print_int(font_code to sprint_int(font_ident.
+hh. In module 1230,
+ begin undump(single_base)(undefined_control_sequence)(font_ident[k]);
+ undump_qqqq(font_check[k]); [and continue as before]
+
+The changes above have been incorporated into Version 0.6.
+ The ill-fated Version 0.7
+
+27. (Here's a change that I retracted shortly after making it, since I
+discovered that the source was flaky after all; and I also found a reliable
+source [NBS Circular 570] confirming my original information. I include
+the note here only for historical purposes...)
+
+"After years of searching, I've finally found a definitive definition of
+the printer's point; and (unfortunately) my previous conjecture was wrong.
+The truth is that 83pc=35cm, exactly; so I am changing TeX to conform.
+This means some changes in the comments of modules 101 and 517, and the
+following changes to the program:
+
+"27a. In modules 547 and 571, the appropriate DVI numbers are now:
+ dvi_four(109375); dvi_four(2039808); {conversion ratio for sp}
+"27b. The guts of module 418 become:
+ if scan_keyword("in") then set_conversion(63246)(875)
+ else if scan_keyword("pc") then set_conversion(12)(1)
+ else if scan_keyword("cm") then set_conversion(996)(35)
+ else if scan_keyword("mm") then set_conversion(498)(175)
+ else if scan_keyword("bp") then set_conversion(10541)(10500)
+ else if scan_keyword("dd") then set_conversion(996)(931)
+ else if scan_keyword("cc") then set_conversion(11952)(931)
+ else..."
+
+*** Version 0.7 of TeX incorporated the changes above (82/10/30);
+this version was withdrawn on 82/11/2.
+ Changes subsequent to Version 0.6
+
+28. The experience with #27 did lead me to one improvement, thanks
+to Chuck Bigelow, with respect to Didot points. (11/4/82)
+Add the following comment to module 418:
+ According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;
+ this agrees well with the value $\rm1000.333/,mm$ cited by Bosshard
+ in {\sl Technische Grundlagen zur Satzherstellung\/} (Bern, 1980).
+And change two lines of the code there as follows:
+ else if scan_keyword("dd") then set_conversion(1238)(1157)
+ else if scan_keyword("cc") then set_conversion(14856)(1157)
+
+29. The new font material is made more robust by ensuring that \the\font
+always returns a pointer to a control sequence whose command code is
+set_font. (Change 11/4/82)
+
+29a. The code changed in 26aa is changed again, to the following:
+ <If the next token isn't a control sequence, issue a complaint and
+ return; otherwise set u:=cs_ptr, and set hash_used to the
+ location of a ``frozen'' copy of the new font identifier>;
+ define(u,set_font,undefined_font);
+ scan_optional_equals; scan_file_name;
+ <Scan the ``at'' size specification>;
+ <If this font has already been loaded, set f to the internal
+ font number and goto common_ending>;
+ f:=read_font_info(u,cur_name,cur_area,s);
+ common_ending: equiv(u):=f; geq_define(hash_used,set_font,f);
+ font_ident[f]:=hash_used;
+ exit:end;
+29b. Instead of 26cc, here's the new module 1173:
+ We reserve a special control sequence for the font identifier;
+ this one cannot be redefined by the user, so it is safe to
+ return it as a value of \the\font.
+ <If the next token isn't a control sequence...>=
+ get_token;
+ if cs_ptr<hash_base then
+ begin print_nl(
+ "! A font identifier must be a multiletter control sequence");
+ help2("You should say, e.g., `\font\ffn=fontfilename'.")
+ ("(I'm going to ignore the \font command you just gave.)");
+ back_error; return;
+ end;
+ repeat if hash_is_full then overflow("hash size",hash_size);
+ decr(hash_used);
+ until text(hash_used)=0; {search for an empty location in hash}
+ u:=cs_ptr; text(hash_used):=text(u); {copy the name}
+ stat incr(cs_count); tats
+
+30. Module 993, replace lines 5 to 7 (11/5/82):
+else begin if k=vmode then new_save_level(vbox_group)
+ else begin new_save_level(vtop_group); k:=vmode;
+ end;
+ if looseness<>0 then eq_word_define(int_base+looseness_code,0);
+ if hanging_indent<>0 then
+ eq_word_define(dimen_base+hanging_indent_code,0);
+ if par_shape_ptr<>null then eq_define(par_shape_loc,shape_ref,null);
+ end;
+
+31. Module 403, replace line 5 (11/6/82):
+if cur_tok<cs_token_flag then
+ begin cur_val:=cur_chr;
+ if cur_cmd<=right_brace then
+ if cur_cmd=right_brace then incr(align_state)
+ else decr(align_state);
+ end
+
+32. Improvements to error recovery for bad alignments (11/6/82):
+In module 1039, replace "begin align_error; goto reswitch; end" by "align_error"
+In module 1040, delete "cur_cmd:=left_brace;" and "cur_cmd:=right_brace;"
+ and change "error" to "back_error"
+In module 1041, delete "cur_cmd:=relax;"
+
+33. More power to \let (11/8/82):
+33a. Module 1141 becomes:
+ <Assignments>+=
+ let: begin get_token;
+ if cs_ptr<>0 then <Carry out the \let operation>
+ else begin print_nl
+ ("! You can use \let only with control sequences");
+ help2("I'm not \let-ting anything change here,")
+ ("since I can only do things like `\let\a=b'.");
+ back_error;
+ end;
+ end;
+33b. Module 1142 becomes:
+ <Carry out the \let...>=
+ begin p:=cs_ptr;
+ repeat get_token;
+ until cur_cmd<>spacer;
+ if cur_tok=other_token+"=" then
+ begin get_token;
+ if cur_cmd=spacer then get_token;
+ end;
+ if cur_cmd>=call then add_token_ref(cur_chr);
+ define(p,cur_cmd,cur_chr);
+ end
+
+34. This change helps you see an undefined control sequence
+in certain unusual cases (discovered by JDH, 11/8/82):
+Add the clause "(base_ptr=input_ptr) or" to module 294, line 2.
+
+35. Here's an improvement in the formula for demerits; previously
+more weight was given to minimizing bad spacing on lines with penalties,
+so that (slightly loose hyphenated line)(OK line) was considered worse
+than (OK hyphenated line)(quite loose line). (fixed 11/8/82)
+Change lines 2--7 of module 772 to the following:
+ d:=line_penalty+b; d:=d*d;
+ if pi<>0 then
+ if pi>0 then d:=d+pi*pi
+ else if pi>eject_penalty then d:=d-pi*pi;
+
+36. Minor change to save buffer space in non-INITEX (11/10/82):
+Enclose the declaration of pool_file in module 50 by init...tini.
+
+37. Minor improvement in format for the context of error messages (11/13/82):
+37a. Module 289, type "inserted" split into "backed_up=3", "inserted=4"
+and the other type numbers increase: "macro=5", etc.
+37b. In module 296, backed_up: if loc=null then print_nl("<recently read>")
+ else print_nl("<to be read again> ");
+ inserted: print_nl("<inserted text> ");
+37c. Minor changes to comments in modules 289 and 293.
+37d. Change "inserted" to "backed_up" in module 294.
+37e. Add definition "back_list(#)==begin_token_list(#,backed_up)" in module 305.
+37f. In module 306, first test should be ">=backed_up", second "<=inserted".
+37g. Change ins_list to back_list in modules 307, 318, 375, 1195.
+37h. Add definition to module 308:
+ ins_error==begin back_error; token_type:=inserted; end
+37i. Change back_error to ins_error in modules 362, 1040, 1046.
+37j. Change "<to be read again>" to "<inserted text>" in module 973 help.
+
+38. Module 407, the error message is changed (11/11/82) to:
+"! Missing number, treated as zero".
+
+39. Fix anomaly when hbadness or vbadness is small (11/11/82):
+Module 593, line 2, "if (-x-total_shrink[normal]>hfuzz) or (hbadness<100)"
+Module 603, line 2, "if (-x-total_shrink[normal]>vfuzz) or (vbadness<100)"
+
+40. Added the \tokens primitive (11/13/82):
+In module 223, defined tokens_loc and tokens (analogous to every_par).
+In module 225, defined the primitive.
+In module 1146, changed the comment to include tokens_loc as a possibility.
+
+41. Change get_nc_token to get_token in module 374 (11/13/82).
+(In particular \def\foo{...}\foo won't say "undefined c.s." now!)
+(This change later retracted during debugging; it was found that
+"endv" aborts the job, so this cure was worse than the disease. Then
+it was re-established as part of the major change to conditionals,
+because endv needed to be more robust anyway.)
+
+42. In module 699, we make \span expand in a preamble (11/13/82).
+Change lines -7 through -3 to:
+ begin get_nc_token; goto reswitch;
+ end;
+
+43. Modules 321 and 322 have been altered for better efficiency (11/12/82)
+and better exposition; the three conditions of module 322 are now
+in separate if tests.
+
+44. Frozen control sequences are now unredefinable. (11/16/82)
+A new procedure get_r_token has been introduced to give uniform error
+messages for \def, \let, \read, \font, \mathchardef, and to make them
+incapable of changing the frozen equivalents.
+
+Incidentally, get_nc_token is changed to get_x_token; and ch_code
+becomes cat_code.
+ A major change (Version 0.8) made on November 14--16:
+Conditional statements are taken from semantics to syntax.
+
+This change, which counts as number 45 on the list, made it necessary
+to renumber the modules. And it was such a drastic change, the
+differences can only be sketched here, using the old module numbers
+for reference. A variety of other things were cleaned up because this
+change made it more natural for them to be handled differently.
+
+45a. Module 158, inserted a permanently empty token list called null_list.
+45b. Module 204, deleted if_test, case_branch, else_code, convert;
+ inserted end_cs_name.
+45c. Module 206, inserted if_test, fi_or_else, cs_name, convert, and
+ end_template (the latter comes after long_outer_call).
+45d. Module 217, there are now nine frozen control sequences; also null_cs.
+45e. Modules 247 and 248, must be able to print a null control sequence.
+45f. Module 268 (leave_transparent_group) disappears; comments in the
+ previous modules also are appropriately simplified.
+45g. Module 273, delete endv_token.
+45h. Modules 277 and 278, delete references to endv (it no longer appears).
+45i. After module 281, a procedure show_cur_cmd_chr takes the
+ code for tracing commands from module 937.
+45j. Module 317 now forbids \outer control sequences when skipping,
+ and inserts \fi in front of them, for error recovery.
+45k. Module 334 now uses null_cs if carriage-return is an escape.
+45l. Module 343 no longer has endv test.
+45m. Module 344, major extensions to expand_calls make it several modules
+ longer. It saves global variables like cur_val. It changes
+ end_template to endv. It processes cs_name and convert.
+ It processes if_test by calling the "conditional" procedure.
+ It processes fi_or_else by checking their legality, and (if legal)
+ updating the if stack.
+45n. Module 373 (pass_block) disappears.
+45o. After module 400, radix and cur_val and cur_val_level are initialized.
+45p. Module 428 changes so that conv_toks is a procedure rather than a
+ function; this procedure is invoked by expand_calls.
+45q. Modules 436 and 1032, delete reference to conv_toks.
+45r. After module 443, the entire part 48 moves to this part of the program,
+ and the parts are renumbered accordingly. \case is changed to
+ \ifcase, and it resides under the if_test command.
+ New routines are inserted to maintain a linked stack that records
+ the current state of conditionals. There's a procedure
+ pass_text that skips text while looking for \fi or \else or \or
+ on level zero with respect to \if...\fi nesting. The previous
+ routines for skip control via handle_right_brace are eliminated,
+ and the new ones are somewhat simpler. The new \ifcat is mostly
+ combined with the old \if; they no longer ignore spaces.
+ The scanner_status is set to normal while processing \ifx.
+ \ifx will consider \a to equal 0 after \let\a=0.
+45s. Modules 701, 707: endv_token is replaced by a token for a frozen
+ control sequence whose command code end_template makes it behave
+ like an outer_call. After expand_calls, it is converted to another
+ frozen control sequence, whose command code is endv. This two-step
+ facilitates error recovery, instead of giving a fatal error stop.
+45t. Module 874, remove "pass_block(1); goto done".
+45u. After module 1047, routine for end_cs_name prints an error message.
+45v. Module 1049, get_nc_token becomes get_token. (else $\ifmmode fails)
+45w. Module 1202 gets another case (end_template).
+45x. Module 1243, new warning is printed if the if stack isn't empty.
+ Changes after version 0.8
+
+46. Declare c : ascii_code in module 825 (noted by DRF, 11/21/82)
+
+47. Module 776 lines 4-6 (suggested by DRF, 11/21/82)
+threshold:=pretolerance;
+if threshold>=0 then
+ begin stat if tracing_stats>2 then
+ begin begin_diagnostic; print_nl("@@firstpass");
+ end; tats
+ second_pass:=false;
+ end
+else begin threshold:=tolerance; second_pass:=true;
+ end;
+
+48. Protection for DVI files (added 11/16/82)
+Replace lines 2 and 3 of module 570 by:
+ <Update the values of max_h and max_v; but if the page is too large,
+ goto done>;
+Move the statement "dead_cycles:=0" from module 570 to module 568.
+Declare "label done;" in module 568.
+And add the following new module after 570:
+
+@ Sometimes the user will generate a huge page because other error messages
+are being ignored. Such pages are not output to the \.{dvi} file, since they
+may confuse the printing software.
+
+@<Update the values of |max_h| and |max_v|; but if the page is too large...@>=
+if (height(p)>max_dimen)or(depth(p)>max_dimen)or(width(p)>max_dimen) then
+ begin print_nl("! Huge page cannot be shipped out");
+ help2("The page just created is more than 18 feet tall or")@/
+ ("more than 18 feet wide, so I suspect something went wrong.");
+ error;
+ if tracing_output=0 then
+ begin begin_diagnostic;
+ print_nl("The following box has been deleted:");
+ show_box(p);
+ end_diagnostic(true);
+ end;
+ goto done;
+ end;
+if height(p)+depth(p)>max_v then max_v:=height(p)+depth(p);
+if width(p)>max_h then max_h:=width(p)
+
+49. New features \everymath and \everydisplay (12/2/82).
+Make changes analogous to those for "\tokens" (see change 40).
+Put the following just before the end of module 1050:
+ if every_math<>null then begin_token_list(every_math,every_math_text);
+And put the following just before the end of module 1056:
+ if every_display<>null then
+ begin_token_list(every_display,every_display_text);
+
+50. New feature \futurelet (12/2/82):
+Module 1141 changes again. (Also, "let" and "futurelet" share cmd code "let".)
+let: begin n:=cur_chr;
+ get_r_token; p:=cs_ptr;
+ if n=normal then
+ begin repeat get_token;
+ until cur_cmd<>spacer;
+ if cur_tok=other_token+"=" then
+ begin get_token;
+ if cur_cmd=spacer then get_token;
+ end;
+ end
+ else begin get_token; q:=cur_tok; get_token; back_input;
+ cur_tok:=q; back_input; {look ahead, then back up}
+ end; {|back_input| doesn't affect |cur_cmd|, |cur_chr|}
+and continue with "if cur_cmd>=call", as before.
+
+*** The changes above have been incorporated into version 0.9 of TeX.
+ Changes after version 0.9
+
+51. new \endinput primitive (suggested by FY, 12/7/82):
+\input and \endinput both use the same command code. The cases in module
+955 are deleted and replaced by those in module 965 (which disappears),
+because \input is now allowed in any mode. The code for any_mode(input)
+is "if cur_chr=0 then start_input else force_eof:=true", and it moves from
+module 952 to just before module 1197. The global variable force_eof
+is initially false, and module 340 becomes (after first:=start;)
+ if not force_eof then
+ begin if input_ln.... else force_eof:=true;
+ end;
+ if force_eof then begin print_char(")"); force_eof:=false;...
+
+52. Module 1005, line 4 (12/8/82)
+change "if align_state<0" to "if (mode<0)or(align_state<0)"
+(This avoids embarrassing case where TeX says "type a command or say \end"
+but when you type \end it says "You can't use \end in restricted horiz mode".)
+
+53. Patch to the new code for \csname (12/21/82)
+After eq_type(cs_ptr):=relax, also say equiv(cs_ptr):=256.
+(This corrects a bug that would appear only if \csname occurs right
+after a file name.)
+
+54. Change 47 introduced a bug when tracingonline=0 (12/20/82)
+when omitting firstpass, also do "if tracing_stats>2 then begin_diagnostic;"
+
+55. \hskip -1pt plus 2pt was parsed as \hskip -(1pt plus 2pt)! (12/20/82)
+In module 421, before line -4, insert the following:
+ if negative then
+ begin cur_val:=-cur_val; negative:=false;
+ end;
+But then realize that "negative" is always false on line -2; simplify.
+
+56. Cosmetic change to paragraph statistics (12/23/82)
+tight_fit..very_loose_fit codes have been renumbered very_loose_fit..tight_fit.
+
+57. Module 729 changes to make TeX language more consistent (12/23/82):
+else if type(tail)<>glue_node then tail_append(new_penalty(inf_penalty))
+else begin type(tail):=penalty_node; delete_glue_ref(glue_ptr(tail));
+ flush_node_list(leader_ptr(tail)); penalty(tail):=inf_penalty;
+
+58. Commas are allowed as alternates to radix points. (12/23/82)
+define continental_point_token=other_token+"," {decimal point, Eurostyle}
+in module 400, and insert the following twice in 409:
+ if cur_tok=continental_point_token then cur_tok:=point_token;
+
+59. \hangindent becomes a normal parameter. (12/23/82)
+This simplifies the code in obvious ways; for example, module 1148 disappears.
+The command code hang_indent goes away too; what was previously called
+hanging_indent is then renamed hang_indent.
+
+60. \prevgraf becomes accessible. (12/23/82)
+This involves renaming the "after" field "pg_field" in the nest array;
+making a new command code set_prev_graf;
+including the following loop into scan_the:
+ nest[nest_ptr]:=cur_list; p:=nest_ptr;
+ while abs(nest[p].mode_field)<>vmode do decr(p);
+ scanned_result(nest[p].pg_field)(int_val);
+and including the following active procedure for any_mode(set_prev_graf):
+ procedure change_prev_graf;
+ var p:0..nest_size; {index into |nest|}
+ begin nest[nest_ptr]:=cur_list; p:=nest_ptr;
+ while abs(nest[p].mode_field)<>vmode do decr(p);
+ scan_optional_equals; scan_int;
+ if cur_val<0 then
+ begin print_nl("! Bad \prevgraf");
+ help1("I allow only nonnegative values here.");
+ int_error(cur_val);
+ end
+ else begin nest[p].pg_field:=cur_val; cur_list:=nest[nest_ptr];
+ end;
+ end;
+
+61. \clubpenalty is split off from \widowpenalty. (12/23/82)
+
+62. Bad bug in module 1005 (12/24/82)
+(must not go to reswitch if \par is a macro!)
+Instead of setting cur_cmd and cur_chr and goto reswitch, just back_input
+and set token_type:=inserted.
+
+63. \openin not to prompt if file not present (12/25/82)
+Change lines -4 and -3 of module 1183 to:
+ if a_open_in(read_file[n]) then read_open[n]:=just_open
+ else read_open[n]:=closed;
+
+64. New \jobname primitive (12/25/82)
+It is added to the "convert" command in the obvious way.
+In conv_toks, the relevant code is
+ if job_name=0 then open_log_file
+before "selector" is changed and
+ print(job_name)
+after.
+
+65. Better error recovery for math-only things (12/25/82):
+In module 952, don't goto reswitch after insert_dollar_sign.
+In module 954, first back_input, then set cur_tok, and
+don't bother to set cur_chr or cur_cmd; ins_error instead of back_error.
+
+66. Module 1163, line 3, insert "scan_optional_equals" (12/25/82).
+Also make \the\parshape allowed.
+
+67. The location where an \if begins is stacked (12/26/82)
+so that a better error message can be given for \end while \if is incomplete.
+This means two-word nodes instead of one-word nodes in the if stack.
+
+68. Change 30 is extended to \insert, \vadjust, \valign, \output (12/26/82)
+The one-time-only paragraph parameters are now cleared by a
+subroutine called normal_paragraph; hang_after is also set to 1.
+The essential change being made now is to call normal_paragraph in modules
+704, 932, 1009, and 1076.
+
+69. \pagetotal and \pagegoal are added (12/27/82)
+The changes are analogous to, but simpler than, those for \prevgraf.
+
+70. Tracing of page-optimization calculations (12/27/82)
+A bunch of print commands are added to modules 897, 914, and 918,
+activated if tracing_pages>0. Also, \tracingparagraphs is separated
+from \tracingstats.
+
+**** The changes above have been incorporated into version 0.91 of TeX
+
+71. The build_page procedure is broken in two parts (Dec 31, 1982)
+by making module 919 into a procedure called fire_up.
+
+72. \ifeven1\else is made legal by introducing if_code (Dec 31, 1982)
+This improves part of the code in change 45; if_limit has a specific
+value that recovers automatically from a former syntax error.
+
+73. Improvement to alignments when columns don't occur (Dec 31, 1982)
+Delete module 711; and where it was used in module 708, say this:
+ begin fin_col:=true; return;
+ end;
+Also, in module 717, replace the statement "width(q):=0" by
+"<Nullify width(q) and the tabskip glue following the current column>"
+where that new module has the following code:
+ begin width(q):=0; r:=link(q); s:=glue_ptr(r);
+ if s<>zero_glue then
+ begin add_glue_rel(zero_glue); delete_glue_ref(s);
+ glue_ptr(r):=zero_glue;
+ end;
+ end
+
+74. Better error message in overfull alignment (Dec 31, 1982)
+In module 717, don't set both height and width; set the height zero.
+Then in module 719, switch width to height if necessary. (People didn't
+understand the previous error messages, and I couldn't blame them.)
+
+*** The changes above have been incorporated into version 0.92 of TeX82
+*** (which was the last version of 1982, completed 11:59pm on December 31)
+ The first changes after 1982
+
+75. Modules 961 and 962 should be one module. (Jan 3, 1983)
+Also, the absolute constant 100 is replaced, and the test becomes
+ if ((page_head=page_tail)and(head=tail)and(dead_cycles=0))or
+ (dead_cycles>max_dead_cycles) then
+
+76. Surprise bug: module 1010. (Jan 3, 1983)
+The case "if head<>tail" needs an else clause: else pop_nest.
+Also remove the "<Scan an optional space>" in that module.
+
+77. Improvement to change 22 (Jan 4, 1983)
+In module 996, use box_max_depth from inside the \vbox:
+ @!d:scaled; {maximum depth}
+ begin d:=box_max_depth; unsave;... vpackage(...,d);
+
+78. \groupbegin and \groupend changed to \begingroup and \endgroup (Jan 4, 83)
+
+79. \deadcycles made accessible (Jan 4, 83)
+
+80. New calculations for split insertions (Jan 4, 83)
+In module 918, we now work with natural width, and add in the page depth too:
+The line "else w:=x_over_n..." is changed to
+ else begin w:=page_goal-page_total-page_depth;
+ if count(n)<>1000 then w:=x_over_n(w,count(n))*1000;
+ end;
+(Note that cur_page_height and cur_page_depth and page_size have been
+renamed page_total, page_depth, and page_goal, in accordance with new syntax.)
+
+*** The changes above have been incorporated into Version 0.93
+
+81. Old bug finally unearthed by PHY (Jan 6, 1983)
+insert "incompleat_node:=null;" after "push_nest;" in module 1097.
+
+82. Extension of change 69: \pageshrink, etc. added (Jan 6, 1983)
+
+83. \floatingpenalty and \insertpenalties added (Jan 6, 1983)
+Also, the insertion nodes now have a new format, so that the values of
+\floatingpenalty, \splittopskip, and \splitmaxdepth can be stored with
+each insertion; this requires the obvious changes in several places:
+a) Module 136, ins_node has fields float,depth,height,ins_ptr,split_top_ptr
+b) Module 184, these fields are displayed
+c) Module 198, ins_node case, also delete_glue_ref(split_top_ptr(p))
+d) Module 202, ins_node case, also add_glue_ref(split_top_ptr(p))
+e) Modules 226-228, new integer parameter \floatingpenalty
+f) Module 883, add parameter d to vert_break subroutine
+g) Module 885, use d instead of split_max_depth
+h) Module 890, argument split_max_depth to call of vert_break
+i) Module 894, change width to height (better name)
+j) Module 900, initialize insert_penalties here, not in 901
+k) Module 914, cost to be awful_bad if insert_penalties>=10000
+l) Module 916, add float(p) to insert_penalties if type(r)<>inserting
+m) Module 916, subtract page_depth from delta
+n) Module 918, subtract page_shrink from delta
+o) Module 918, argument depth(p) to call of vert_break
+p) Module 921, insert_penalties:=0, save split_top_skip before calling 925
+q) Module 921, restore split_top_skip before calling 924
+r) Module 928, set split_top_skip:=split_top_ptr(p) before prune_page_top
+s) Module 929, after q:=p, incr(insert_penalties)
+t) Module 929, before free_node, delete_glue_ref(split_top_ptr(p))
+u) Module 933, clear insert_penalties before calling 934
+v) Module 978, more local variables needed
+w) Module 1010, build the newfangled ins_node
+
+84. Scanner goes to new_line when <return> is category 13 (Jan 7, 1983)
+Insert state:=new_line in module 323 just before the reference to module 339;
+and delete "state:=new_line;" from modules 328 and 330 (and their names).
+
+85. Distinguish between user \kern and font \kern (Jan 9, 1983)
+The nontrivial parts of this are to change "type(s)<>kern_node" to
+"(type(s)<>kern_node)or(subtype(s)<>normal)" in modules 809 and 810;
+and to say "kern_node: if subtype(s)=explicit then goto done4" in module 812.
+The \kern primitive now has "explicit" instead of "normal" in 967.
+
+86. "ignorespace" becomes "ignorespaces" (Jan 9, 1983)
+
+87. Don't omit a blank space after \def, \message, \mark, etc. (Jan 9, 1983)
+<Scan an optional space> is removed from modules 431, 848, 874.
+"info(r):=space_token;" and "link(r):=get_avail; r:=link(r);" removed from 1278.
+
+*** The above changes appear in Version 0.94.
+ Version 0.95
+
+88. New active characters in math mode (Jan 12, 1983)
+In module 1062, add a label "restart" and change lines -3 and -2 as follows:
+fam(p):=(c div 256) mod 16;
+if c>=var_code then
+ if fam(p)<8 then fam(p):=cur_fam
+ else begin <Convert c to an active character whose equivalent is
+ ready to be scanned next>; goto restart;
+ end;
+In module 1064, the body of the procedure becomes
+begin if c>='4000 then <Convert c ...> else <the former body>; end
+And there's a new module:
+<Convert c...>=
+begin cs_ptr:=(c mod 128)+active_base;
+cur_cmd:=eq_type(cs_ptr); cur_chr:=equiv(cs_ptr); x_token; back_input;
+end
+
+89. Surprise bug: $1-$ treated the - as binary (Jan 15, 1983)
+New module <Convert a final bin_noad to an ord_noad>=
+ if r_type=bin_noad then type(r):=ord_noad
+is called in module 649 before the call of 678, and in module 651
+in the place where that code already appears.
+
+90. Another oversight (Jan 15, 1983)
+Add "space_factor:=1000;" after "push_nest" in modules 1027, 1029
+
+91. And a more embarrassing one (Jan 16, 1983)
+I forgot "spotless:=false;" at the beginning of the procedure in module 80.
+But while fixing this, I decided to make it more general since IBMers want
+a return code at the end of the job. So there's a history variable that has
+four values: spotless, warning_issued, error_message_issued, fatal_error_stop.
+a) module 75: declare history, define spotless etc.
+b) module 76: initialize history:=spotless
+c) module 80: if history<error_mess... then history:=error_mess...
+d) 80 and 90: history:=fatal_error_stop before jump_out
+e) 92: if history<error_message_issued then
+f) 232: if history=spotless then history:=warning_issued
+g) 1243: if history=warning_issued then print_nl("(see the log...)")
+
+92. "This can't happen" could happen, so there's new error recovery (Jan 16, 83)
+In module 933, replace the call on confusion by a call of the following module:
+ @ @<Recover from an unbalanced output routine@>=
+ begin print_nl("! Unbalanced \output routine");
+ help2("Your sneaky output routine has fewer real {'s than }'s.")@/
+ ("I can't handle that very well; good luck."); error;
+ repeat get_token;
+ until loc=null;
+ end
+In module 1278, replace the call on confusion by a call of:
+ @ @<Recover from an unbalanced write command@>=
+ begin print_nl("! Unbalanced \write command");
+ help2("On this page there's a \write with fewer real {'s than }'s.")@/
+ ("I can't handle that very well; good luck."); error;
+ repeat get_token;
+ until cur_tok=end_write_token;
+ end
+
+93. String overflow clobbered the log file (Jan 18, 1983)
+Also, "confusion" before log file open would cause problems. Also start_input
+calling open_log_file calling prompt_file_name calling fatal_error!
+To fix these anomalies, open_log_file no longer calls prompt_file_name,
+if interaction<scrollmode; instead, it terminates after printing what went
+wrong. Also, the fatal_error and overflow and confusion procedures call
+the following new subroutine:
+procedure normalize_selector;
+begin if job_name>0 then selector:=term_and_log else selector:=term_only;
+if interaction=batch_mode then decr(selector);
+if job_name=0 then open_log_file;
+end;
+
+94. \ifeof\fi loops infinitely (Jan 18, discovered by Lamport)
+Change 72 converted such a \fi to <space>\fi. Now it is converted to \relax\fi.
+
+95. \limitswitch changed to \displaylimits et al. (Jan 18, 1983)
+[Incidentally, this fixes a bug in the former positioning of \int\limitswitch]
+a) module 608: subtype of Op can be normal, limits, or no_limits.
+b) 620: display the subtype if not normal
+c) 667: new logic decides limits before looking at the operand (and the operand
+ is now called the nucleus); the italic correction is removed only if
+ it should not be put back
+d) 1069: subtype(tail):=cur_chr
+
+96. Minor changes to math in unusual cases (Jan 19, 1983)
+a:delete "if height(y)<=0 then height(y):=default_rule_thickness" in module 658
+b:move "if thickness(q)=default..." from module 664 to module 661
+c:delete module 1081, that error message isn't worth the bother
+d:in module 1062, char_num case, c:=math_code(cur_val) (if cur_val<128)
+e:in module 1064, a similar change
+
+97. Bad spacing from change 6 is corrected (Jan 19, 1983)
+underline, overline, radical, vcenter, and accent noads now revert to type
+Ord instead of type Inner.
+{...} produces type Ord also.
+There's a new primitive \mathinner.
+The new_noad function now produces an ord_noad (change its calls accordingly).
+And the default is changed in module 679 to t:=ord_noad; the fraction_noad
+case sets t:=inner_noad, and the (inner_noad,ord_noad) cases swap places.
+
+98. New \mathchoice primitive (Jan 19, 1983)
+a) module 204: new command
+b) 254: math_choice_group
+c) 614: style node three words long, so a choice node can be converted to it
+d) 614a: choice node has four subfields: display_mlist, text_mlits, etc.
+e) 1081a: routines to build a choice_node like 1027-1029 build discretionaries
+
+99. \input moves to syntax from semantics (Jan 19, 1983)
+a) 204, 206: renumber commands
+b) When input is to be expanded, if name_in_progress then insert_relax
+c) 459,464: name_in_pr:=true; begin_name;...end_name; name_in_pr:=false;
+d) 406,461: declare name_in_progress, a global boolean initially false
+
+100. \chardef joins \mathchardef (Jan 19, 1983)
+a) 204: math_only becomes math_given; add new command char_given
+b) 205: new command char_def
+c) 250,251: new primitive char_def
+d) 380: char_given,math_given yield integer after \the
+e) 401: char_given,math_given yield integer in context of integer
+f) 936,943: char_given treated like other_char
+g) 1062,1064: same, if cur_chr<128, else assume math_code(x)=x
+h) 1143,1144: char_def is analogous to math_char_def
+
+101. \unbox becomes \unhbox,\unvbox; also add \unhcopy (Jan 19, 1983)
+Module 1020 changes in the obvious way.
+
+102. \spacefactor, \pagetotal, etc. move to prefixed_command (Jan 20, 1983)
+
+103. \hrule in horizontal mode, \vrule in vertical mode: switch modes (Jan 20)
+
+104. \globaldefs parameter, affects prefixed_command (Jan 20, 1983)
+
+105. After looking at frequency counts, some optimizations made (Jan 21, 1983)
+a) "fast_get_avail" and "fast_store_new_token" introduced to speed up the loops
+in modules 360 and 431.
+b) some procedure call overhead eliminated in begin_token_list, end_token_list,
+back_input, and flush_node_list.
+c) a few if tests changed from "if a and b then" to "if a then if b then".
+
+106. Changes for space efficiency in math constructions (Jan 22, 1983)
+a) In module 1102, mlist_penalties:=(mode>0)
+b) The following code is inserted before "free_node" in module 639 (rebox):
+ if (is_char_node(p))and(link(p)=null) then
+ begin f:=font(p); v:=char_width(f)(char_info(f)(character(p)));
+ if v<>width(b) then link(p):=new_kern(width(b)-v);
+ end;
+c) A new module is called just before clean_box exits:
+<Simplify a trivial box>=
+q:=list_ptr(x);
+if is_char_node(q) then
+ begin r:=link(q);
+ if r<>null then if link(r)=null then if type(r)=kern_node then
+ begin free_node(r,small_node_size); link(q):=null;
+ end;
+ end
+
+107. Oversight in rebox routine (module 639) corrected (Jan 22, 1983)
+if type(b)=vlist_node then b:=hpack(b,natural);
+
+108. Module 217 clobbers eqtb[bad_font_ident] set in change 26q (Jan 22, 1983)
+Decided to fix this by making \nullfont a primitive.
+This means the procedure missing_font can be deleted, and the test for
+undefined font can be removed from the inner loop.
+(This reflects a rather dramatic change from TeX80, where
+a missing font was a fatal "Whoa" error!)
+Note: I thought I could delete module 646, but realized that it still provides
+a useful error message. The dump/undump routines (cf. change 26ee) now
+dump the null_font information too, as its parameters can be changed.
+
+109. End of program now lists all incomplete \ifs (Jan 24, 1983)
+
+110. Alignment preamble setup to allow \halign\lb (Jan 29, 1983)
+The statement "align_state:=-1000000;" is inserted near the beginning
+of module 695 (and the comment about align_state=-999999 is deleted).
+The constant -999999 is changed to -1000000 in modules 700 and 701.
+
+111. Forgot to test is_char_node(r) (Jan 30, 1983)
+in the <Simplify a trivial box> code of change 106c.
+By coincidence, this was caught since somebody used font number 11
+in the second character of a list of length 2!
+
+112. Improved format for stats at end of run (suggested by DRF, Jan 30, 1983)
+Module 1242 changes; nothing subtle.
+
+**** The changes above have been incorporated into version 0.95
+ Version 0.96
+
+113. space after one-symbol control sequences NOT to be ignored unless
+the catcode of that symbol is letter or spacer. (Jan 30, 1983)
+The name of module 334 changes slightly; the state is set based
+on cat_code(cur_chr), shortly after label start_cs.
+A new variable cat is introduced and set to cat_code(cur_chr) in modules
+334 and 336.
+
+114. trailing spaces removed on all lines of input (Jan 30, 1983)
+last_nonblank is added to input_ln routine (module 31)
+
+115. mmode+accent gives error but assumes math_accent (Feb 3, 1983)
+This goes into math_ac procedure (module 1075); module 1035 is eliminated.
+
+116. \iftrue and \iffalse (Feb 5, 1983)
+Simple addition of two new conditions.
+
+117. Bad calculation of size for \left and \right (Feb 6, 1983)
+In module 680, the first assignment to delta should be
+ delta:=(delta1 div 500)*delimiter_factor.
+
+118. \delimitershortfall (new name) replaces \delimiterlimit. (Feb 12)
+
+119. \abovewithdelims.. to be equivalent to \above (Feb 12)
+Module 1089 revised so that the delimiters are scanned before the dimension.
+
+120. Remove the kludgy math codes introduced in change 88 (Feb 12)
+\fam becomes a normal integer parameter
+and \mathcode stored with min_halfword added
+and \mathcode allowed to be 32768
+and current family is substituted only when it's in range.
+Also the initialization of mathcode for letters now specifies family 1.
+(This implies a dozen or so obvious revisions.)
+
+121. Bug in module 1152: max spacefactor is 32767 (Feb 12)
+also module 1013 gets a restricted range
+
+122. Octal output to be replaced by hexadecimal. (Feb 14)
+
+123. Forgot to include char_given in module 1037, re change 100 (Feb 14)
+
+124. vmode+valign,hmode+halign made legal transitions (Feb 17)
+
+125. \tracingrestores (Feb 18)
+This involves a lot of new, rather tedious code that's interspersed with the
+eqtb definitions (the body of a procedure called show_eqtb).
+
+126. New error message for hmode+hrule in -hmode. (Feb 25)
+head_for_vmode now suggests \leaders in this case. [improves change 103]
+
+127. under/overfull boxes in alignment: Better message. (Feb 27)
+par_begin_line becomes pack_begin_line, and it is set (negative) in
+module 719, read in modules 590 and 601.
+
+128. New \xcr feature. (suggested by Lamport comments, Mar 4)
+align_peek (module 702) ignores it, otherwise it acts like ordinary \cr.
+
+129. In stats, subtract out TeX's own string requirements (Mar 4)
+(cf. change 112)
+init_pool_ptr and init_str_ptr variables added in obvious way
+(declared in module 39, set in module 1240, used in module 1242)
+
+130. \everyhbox and \everyvbox. (Mar 6)
+The modifications are obvious; for example, module 1076 gets the statement
+ if every_vbox<>null then begin_token_list(every_vbox,every_vbox_text);
+and a similar pair of statements goes into module 993.
+
+131. Precaution in module 1105 error recovery (March 9, 1983)
+Change the first test to "if (a=null)or danger", in order to
+avoid accessing math_quad when the symbol fonts aren't known to be present.
+
+132. Installed float and unfloat to aid portability (suggested by HWT, 3/7/83)
+
+133. \dispskip becomes \abovedisplayskip and \belowdisplayskip (3/9/83)
+Also \dispaskip becomes \abovedisplayshortskip; \dispbskip similar.
+
+134. \romannumeral separated from \number (suggested by FY, March 10)
+Obvious changes; print_roman_int now accepts negative input but gives
+no output in such cases (the test in module 68 becomes "if n<=0 then return").
+
+135. scan_keyword to ignore leading spaces (Mar 12)
+In module 375, change "else begin" to
+"else if (cur_cmd<>spacer)or(p<>backup_head) then begin".
+
+136. Update to change 112 (Mar 14)
+Module 1242 now uses write and write_ln directly (saves space and time).
+
+137. Another change to page-break cost (suggested by Lamport, March 16)
+Cf. change 83k above; the relevant lines of module 914 now read
+ if b<awful_bad then
+ if pi<=eject_penalty then c:=pi
+ else if b<inf_bad then c:=b+pi+insert_penalties
+ else c:=deplorable
+ else c:=b;
+ if insert_penalties>=10000 then c:=awful_bad;
+and a similar change (but without insert_penalties) occurs in module 887.
+
+**** The changes above have been incorporated into version 0.96 (March 16, 1983)
+ Version 0.97
+
+138. \everyjob (suggested by FY, March 18)
+Module 936: main_control inserts every_job as its first action.
+
+139. Improved printout of macro definitions (March 19)
+In module 278, simply treat left_brace like right_brace.
+(This corresponds to the way the manual describes parameter matching.)
+
+140. Omit blanks as non-delimited parameters (March 19)
+In module 360, replace
+ else store_new_token(cur_tok);
+by
+ else @<Store the current token, but |goto continue| if it is
+ a blank space that would become an undelimited parameter@>;
+Then define @<Store the current token...@> to be:
+begin if cur_tok=space_token then
+ if info(r)<=end_match_token then
+ if info(r)>=match_token then goto continue;
+store_new_token(cur_tok);
+end
+
+141. Minor patch in module 386, catches mu_glue (March 21)
+begin cur_val:=zero_glue; cur_val_level:=glue_val;
+if not is_char_node(tail)and(mode<>0) then
+ begin if type(tail)=glue_node then
+ begin cur_val:=glue_ptr(tail);
+ if subtype(tail)=mu_glue then cur_val_level:=mu_val;
+ end;
+ end
+else if (mode=vmode)and(tail=head)and(last_page_glue<>max_halfword) then
+ cur_val:=last_page_glue;
+end
+
+142. Patch in module 699, \span expands only one level (March 21)
+(See previous change #42.) The "get_x_token" in the code
+while (cur_chr=span_code)and(cur_cmd=tab_mark) do get_x_token;
+should be replaced by:
+ begin get_token;
+ if cur_cmd>max_command then
+ begin expand_calls; get_token;
+ end;
+ end
+
+143. Single # in \tokens, \message, etc. (March 22)
+(The previous rule was really bad in connection with \uppercase,
+or with \write when #'s had to be given four times!)
+Module 437 should be prefaced with "if macro_def then".
+And get_token should become get_x_token there, if xpand is true.
+
+144. Keyword "to" required in \read. (March 22)
+This will avoid the common error of a missing space before the \cs.
+Also the stream number can be out of range, for terminal input.
+The stream number in a \write can be out of range too, for terminal output.
+Modules 1145 and 1258 and 1280, etc., change in the obvious ways.
+
+145. \ifeven<countnumber> replaced by \ifodd<number> (March 26)
+This makes the language more consistent.
+
+146. Big surprise bug relating to \if\if aabc\fi (March 26)
+(related to change 45; the possibility that cur_if might not be the
+correct one when the conditional is evaluated was discovered today)
+The main change is to add the change_if_limit procedure, and to add
+the variable save_cond_ptr and the code that now depends on it.
+
+147. \if and \ifcat should tolerate primitives (March 28)
+
+148. "absent" becomes "void", a better word (March 28)
+
+149. Module 990: \lastbox to clear the shift_amount (March 28)
+since I don't want to figure out what it means in all cases (\vsplit, etc)
+
+150. print_err("...") takes the place of print_nl("! ...") (DRF, March 29)
+And wake_up_terminal is introduced in module 34, and used in modules
+37, 70, 341, 441, 457, 463, 1210, 1240, 1246.
+
+151. \halign extended to periodic preambles (April 1)
+Modules 688--690: cur_loop introduced, stacked/unstacked
+Module 695: cur_loop initialized
+Module 700: cur_loop set up
+Module 708--709: cur_loop used and advanced
+
+152. \leaders to align by the smallest enclosing box. (April 1)
+Module 549: new local variable left_edge, initialized to cur_h
+Module 557: cur_h:=left_edge+leader_wd*((cur_h-left_edge) div leader_wd)
+Module 559: new local variable top_edge, initialized to cur_v-height(this_box)
+Module 566: analogous to 557
+
+153. hyphenation after whatsits is OK (April 1)
+In module 809, skip past whatsits
+
+154. \par in vertical mode should build_page (April 2)
+vmode+par_end moves from 952 to 1005
+
+155. Clear aux to zero in module 703 (April 2)
+
+156. Digits will switch families (April 4)
+(initialize their math codes differently in module 225)
+
+157. Refinement to correction 83m (April 7)
+the test for not splitting should be
+ if ((h<=0)or(h<=delta))and(height(p)+height(r)<=dimen(n)) then
+
+158. (re 128) \xcr renamed to \crcr, at Lamport's request. (April 8)
+
+159. Better error recovery in runaway preamble (April 11)
+Module 319, aligning: set align_state:=-1000000
+
+160. \read to get balanced braces (April 12)
+Module 440 changed to look more like 431.
+Module 443 gives error message if the \read goes off end of file.
+Module 319 removes \outer from forbidden control sequence that is \read.
+
+161. Bug found by Jim Sterken (April 14)
+Module 798 can make q a char_node, so module 794 needs this patch:
+ if not is_char_node(q) then
+to be inserted just before "if (type(q)=math_node)..."
+
+162. \uppercase and \lowercase to apply to all characters (April 15)
+module 1196 changes; also I put active_base before single_base in eqtb
+
+**** The changes above have been incorporated into version 0.97 (April 16, 1983)
+**** except the part of 144 about \read-1 was forgotten and put in 0.98 later
+ Version 0.98
+
+163. change small_number to 0..65 in module 814 (found by DRF, April 17)
+
+164. improved error recovery in module 1166 (suggested by DRF, April 17)
+after error: repeat get_token; until cur_cmd=right_brace; {flush the patterns}
+
+165. improved \read from terminal (suggested by Todd Allen at Yale, May 1)
+I had forgotten to implement the extended stream numbers in change 144.
+Also, the prompt is now omitted if n<0.
+
+166. \write n writes only to the log file, if n<0. (May 18)
+
+167. Unified syntax for parameters and registers. (May 18)
+a) Command code changes: def_font moved to before prefix;
+ register eliminated; set_register renamed register and
+ moved (with adv_register...div_register) to before prefix;
+ min_internal and max_internal defined.
+b) scan_the renamed scan_something_internal, and it acts on cur_tok.
+c) scan_int, scan_dimen, scan_glue simplified accordingly; instead of
+ testing for cur_cmd=the or cur_cmd=register, they now test
+ cur_cmd versus min_internal and max_internal.
+d) ins_the is removed.
+e) \minusthe is removed. Consequently "the_toks" needs no parameter.
+
+168. new parameters \hoffset, \voffset (May 18)
+
+169. \everycr (suggested by Spivak, installed May 24)
+
+170. \countdef, \dimendef, etc. (suggested by DRF long ago, installed May 25)
+Straightforward change to internal representation of assign_int and similar
+commands, so that the chr part is now a pointer to the eqtb location.
+
+171. \advance, \multiply, \divide (suggested by FY, installed May 25)
+
+172. \hyphenchar (May 25)
+A new command assign_font_int is introduced, and incorporated into
+scan_something_internal and prefixed_command in the usual way.
+The hyphen_char array entries are initialized in modules 483 and 506,
+allocated in 482, used in modules 809 [is hyphenation to be suppressed?],
+828 [insert the hyphen character], 946 [insert discretionary node
+following hyphen], 1027 [implementation of \-].
+hyphen_char[k] is dumped and undumped in modules 1229 and 1230.
+
+173. \skewchar (May 25)
+Loaded and fetched with the same command code as \hyphenchar.
+Module 659 gets a dozen more lines of program, to compute the skew.
+
+174. \noexpand (May 25)
+This involves: introduction of no_expand and dont_expand command codes;
+frozen_dont_expand as an internal marker; small change to get_next
+when that marker is sensed; change to processing of \if and \ifcat;
+implementation of no_expand in the expand_calls subroutine.
+I also changed the name of expand_calls to "expand".
+
+175. \meaning (May 25)
+This adds one case to the "convert" command.
+print_meaning is a new subroutine, using code that was in show_whatever.
+
+176. "dm" and "vu" are out, ".5\hsize" is in (May 25)
+Straightforward changes to module 416.
+
+177. \texinfo f n becomes \fontdimen n f (May 25)
+
+178. \afterassignment (suggested by ARK, May 27)
+
+179. \chardef\xx=5\xx shouldn't say that \xx is undefined (May 27)
+
+180. \relax to be ignored like spaces in math mode (May 28)
+and in a few other places: <Get next non-blank non-relax non-call token>
+is now used in modules 379, 988, 994, 1062, 1070, 1134, 1179
+(i.e., scan_left_brace, scan_box, scan_math, scan_delimiter, prefixed_command,
+do_assignments, and just after \leaders).
+
+181. improve \mathaccent wrt sub/superscripts (sugg by HWT, May 30)
+
+182. its_all_over: remove dead_cycles>max_dead_cycles (May 30)
+Modules 961 and 962 are combined and simplified.
+
+*** The changes above were installed into version 0.98 on May 31, 1983 ***
+ Version 0.99
+
+183. \mark and \insert and \vadjust allowed in restricted hmode (Jun 3)
+also in math; this is a comparatively big change
+[at present, \mark in a display causes TeX to crash with "can't happen"!]
+modules 652 and 679: mark_node,ins_node,adjust_node now permitted
+modules 576 and 578: t becomes a global variable adjust_tail
+modules 802 and 1110: new calling sequence to get the adjustments
+modules 254, 986, 993, 995, 996: adjusted_hbox_group for the new kind of hbox
+modules 698--690: cur_head and cur_tail added to alignment stack
+modules 703, 712, 715: adjustments gathered and appended during \halign
+
+184. \ht, \wd, and \dp (Jun 6)
+
+185. When displaying noads, use ^ and _ instead of ( and [ (Jun 6)
+
+186. A..F in hex constants could be otherchar as well as letter (Jun 6)
+
+187. Remove <scan optional space> from module 417 (Jun 7)
+(it was redundant code)
+
+188. \mkern .5\thinmuskip and \mkern\thinmuskip should be legal (Jun 7)
+
+189. 2.5\space\space\dimen0 should work (Jun 7)
+previously it worked after "plus" or "minus" only!
+
+190. <font identifier> to allow also \font for current font (Jun 7)
+"if cur_cmd=def_font then f:=cur_font else" added to module 507
+
+191. \gdef not to be global when \globaldefs<0 (Jun 7)
+"and (global_defs>=0)" added to module 1139
+
+192. \advance\spaceskip by-\spaceskip should yield zero_glue (Jun 7)
+the procedure trap_zero_glue is culled from module 1147
+
+193. \show should work with any token (Jun 7)
+
+194. \tokens to become 256 registers (Jun 8)
+\toks and \toksdef added in the straightforward way
+(this affects mainly eqtb, scan_something_internal, prefixed_command)
+
+195. allow \indent in math mode (Jun 8)
+also, \valign in math mode to give missing $ error
+modules 1001 and 1043 disappear; 1004 is generalized slightly.
+
+196. remove redundant code (Jun 8)
+In module 1044, there's no need to check cur_group and call off_save.
+Similarly in module 1053.
+
+197. new_write_whatsit shouldn't allow \openout-1, \closeout-1 (Jun 8)
+(simple change to module 1258)
+
+198. \lastbox should give error in math mode (Jun 8)
+(simple change to module 990)
+
+199. \leaders not followed by proper glue should be back_error (Jun 9)
+[I made the change; TRIP should test this error message!]
+
+200. Module 702, correction to beginning of \noalign (Jun 9)
+if mode=-vmode then normal_paragraph;
+
+201. After alphabetic constant, expand the optional space (Jun 10)
+
+202. Set space_factor:=1000 after rule or constructing an accent (Jun 12)
+That's in modules 964 and 1036.
+
+203. blunder in module 783 (caught by Jim Sterken, fixed Jun 14)
+disc_width:=0 needs to be set before testing if s=null
+(A real bug that existed since the beginning! It showed up on page 37
+ of the September 1982 TRIP manual; my hand-checking was incomplete...)
+
+204. Change to optional spaces after <dimen> (Jun 14)
+The optional space will now be analogous to that after <number>.
+
+205. Fix conflict between \output and \everydisplay (Jun 14)
+In change 49, I should have inserted every_display before calling build_page.
+
+206. Overflow errors to be consistent with statistics reporting (Jun 17)
+(See change 129.)
+
+207. \tracing switches to be all positive vs nonpositive (Jun 17)
+
+*** The changes above were installed into version 0.99 on June 19, 1983 ***
+ Version 0.999
+
+208. \catcode`\%=14 to be done by INITEX (Jun 20)
+
+209. \par in vmode to clear parshape etc. (Jun 21)
+Module 1005, which contains vmode+par_end, now calls normal_paragraph.
+
+210. Improvement to change 39 (Jun 21)
+Module 593, overfull_rule not appended if solely due to hbadness
+
+211. Alignment bug allows glue_set to be less than -1! (Jun 21)
+Modules 723 and 724 need to be patched.
+
+212. Correction to change 134 (found by Debby Clark, Jun 22)
+Module 68: n to be declared integer, not nonnegative_integer.
+
+213. "by" to be optional (suggested by Lamport, Jun 22)
+Module 1158 disappears
+
+214. Module 1235, slight change in format_ident message (Jun 24)
+
+215. New measures needed to thwart trickery (Jun 25)
+Glue set values computed by \span could have been brought into
+TeX's registers via, e.g., \valign and \vsplit; so the
+"kern" idea of module 722 is insufficient and should be abandoned.
+Extra boxes and glue are added; this has additional virtue
+of perfect accuracy in alignment of vertical rules.
+The main change is to introduce a new module after 722, in which s and t
+are updated for spans, and to eliminate the "equivalent kern" code from 719
+(the corresponding glue calculations are now done in the new module).
+
+216. leaders to affect height/width of their boxes (Jun 25)
+Module 583 splits into two parts (one for hpack, one for vpack).
+
+217. \unskip permitted a little more often (Jun 28)
+Module 1018 reports error only if last_page_glue<max_halfword.
+
+218. {\bf A} in math: not to make a box (Jul 1)
+Module 1093 changes as follows: info(saved(0)):=fin_mlist(null) becomes
+p:=fin_mlist(null); info(saved(0)):=p; if <simple case> then <simplify>.
+
+219. "scaled" feature added to \font input.
+
+220. \mathaccent still not working right? (Jul 2)
+Change 181, I forgot to correct delta when box x changed.
+
+221. Remove confusion possible on file of length 1 (found by Lamport)
+Correction suggested by DRF, July 2: introduce bypass_eoln
+
+222. Allow things like ^^b. (July 4)
+This simplifies modules 332 and 335; also affects 48 and 49.
+And (surprise) 58.
+
+223. \escapechar \defaulthyphenchar \defaultskewchar \endlinechar (July 4)
+to make TeX less dependent on the character set
+A lot of error messages are now broken up so that they use print_esc
+
+224. erstat added for file opening/closing (by DRF, July 7)
+That's module 27.
+
+225. \tracingpages output to show total glue too (July 11)
+Added a procedure called print_page_totals, used also by show_activities.
+Broke modules 214 and 896 into two modules each.
+
+226. Guard against insertion into an hbox (July 11)
+A new procedure ensure_vbox is called in modules 917 and 925.
+
+227. <tokenvar>=<tokenvar> allowed (July 11)
+
+228. \errhelp parameter added (July 11)
+
+229. get_preamble_token should look at global_defs (July 11)
+Module 699 is patched.
+
+*** The above changes installed in preliminary version 0.999 on July 12, 1983,
+but I decided later in the day to do a few more things:
+
+230. \string, \noexpand, \meaning to allow \outer (Todd Allen, July 12)
+
+231. \the to be an expandable control sequence (July 12)
+Several things in the language are cleaned up:
+a) \the\tenrm replaced by \fontname\tenrm [\fontname<font>]
+b) when expanding edef, etc., result of \the still expanded only only level
+c) expansion after \def not inhibited, since \noexpand is now present
+d) \the\the disallowed.
+
+232. \unhbox and \unhcopy allowed in math mode if the box is void (July 12)
+Module 1020 is extended to handle this case.
+
+233. Value of default_rule was incorrectly rounded (July 16)
+Module 424: default_rule=26214 {.39999 pt}
+
+234. \mathaccent still not right! (July 16)
+I need to make the final height the max of (height of accented letter w/o
+superscript, height of unaccented letter w superscript).
+
+235. \newlinechar parameter (July 16)
+simple change to print subroutine
+
+236. boxes and rules to be allowed in discretionaries (sugg by HP man, July 16)
+in fact this simply requires omitting of the prohibition (in module 1031)
+and a few more cases equivalent to kern_node in modules 754, 755, 784.
+
+237. \tracingcommands to show all expandable tokens (July 16)
+
+238. \char to be allowed in \hyphenation list (July 16)
+Module 848 changes in the obvious way.
+
+239. \aftergroup (July 16)
+A new save_type.
+
+240. Curtail running dimensions inside alignments (sugg by ARK, July 16)
+Module 720.
+
+241. Strange pattern data could cause PASCAL error (found July 17)
+Put "if hc[1]=127 then hyf[0]:=0;" at beginning of module 878.
+
+242. hc codes for hyphenation are one lower (July 17)
+e.g., hc[...]:=lc_code(...)-1. This makes code 127 impossible to match.
+
+243. whatsits also allowed after hyphenatable words (July 17)
+Module 812.
+
+244. \/ makes an explicit kern (July 17)
+"subtype(tail):=explicit" in module 1023.
+
+*** Version 0.999 installed July 17, 1983.
+But later in the day I decided to do a few more things:
+
+245. Lowercase letters allowed in file names (July 18)
+In module 452, omit the conversion to uppercase.
+
+246. "No output file" becomes "No pages of output." (July 18)
+Module 571.
+
+247. QRS on error leads to confirmation message (sugg by ARK, July 18)
+Module 84.
+
+*** The real version 0.999 finally installed July 18.
+ * Version 1.0
+
+(Changes made after the Version 0.999 listing of TeX82)
+(Henceforth the "final" module numbers are used)
+
+248. Module 1215, allow space in \read n to \cs (by FY, July 25, 1983)
+@x patch in get_r_token routine
+begin restart: get_token;
+@y
+begin restart: repeat get_token;
+until cur_tok<>space_token;
+@z
+
+249. Module 498, we must stack the current if type (FY, July 27)
+@x patch in conditional routine
+begin @<Push the condition stack@>;@+save_cond_ptr:=cond_ptr;@/
+@y
+@!this_if:small_number; {type of this conditional}
+begin @<Push the condition stack@>;@+save_cond_ptr:=cond_ptr;this_if:=cur_chr;@/
+@z
+Also replace cur_if by this_if in modules 501, 503, 506. The following
+patches do only what is necessary to make things work:
+@x
+ print_cmd_chr(if_test,cur_if);
+@y
+ print_cmd_chr(if_test,this_if);
+@z
+@x
+if cur_if=if_int_code then scan_int@+else scan_normal_dimen;
+@y
+if this_if=if_int_code then scan_int@+else scan_normal_dimen;
+@z
+@x
+if cur_if=if_char_code then b:=(n=cur_chr)@+else b:=(m=cur_cmd);
+@y
+if this_if=if_char_code then b:=(n=cur_chr)@+else b:=(m=cur_cmd);
+@z
+
+250. Module 507, \ifx need not put a control sequence in hash table (July 29)
+@x
+get_token; n:=cs_ptr; p:=cur_cmd; q:=cur_chr;
+get_token; if cur_cmd<>p then b:=false
+@y
+get_next; n:=cs_ptr; p:=cur_cmd; q:=cur_chr;
+get_next; if cur_cmd<>p then b:=false
+@z
+
+251. Module 86, message is lost (noticed by HWT, July 31)
+@x
+print("..."); print_ln; return;
+@y
+print("..."); print_ln; update_terminal; return;
+@z
+
+252. Don't put empty at end of \input file! (Aug 1)
+[This simplifies the rules and the program, and also gets around a bug
+that occurred at the end of files with \endlinechar<0.]
+@x Module 362:
+@ An empty line is inserted at the end of the file, if the last line
+wasn't already empty, because |input_ln| sets |last:=first| when
+it discovers an |eof|.
+@^empty line at end of file@>
+
+@<Read next line of file into |buffer|, or
+ |goto restart| if the file has ended@>=
+begin incr(line); first:=start;
+if not force_eof then
+ begin if input_ln(cur_file,true) then {not end of file}
+ firm_up_the_line {this sets |limit|}
+ else if limit<>start then firm_up_the_line
+ {if |pausing|, the user can add more lines}
+ else force_eof:=true;
+@y
+@ @<Read next line of file into |buffer|, or
+ |goto restart| if the file has ended@>=
+begin incr(line); first:=start;
+if not force_eof then
+ begin if input_ln(cur_file,true) then {not end of file}
+ firm_up_the_line {this sets |limit|}
+ else force_eof:=true;
+@z
+
+*** The changes above went into Version 0.9999, which was widely distributed
+
+253. Ridiculous blunder made in change 146 (found by FY, August 16)
+@x Correction to module 497
+else loop@+begin q:=cond_ptr;
+ if link(q)=p then
+ begin type(p):=l; return;
+ end;
+ if q=null then confusion("if");
+@:this can't happen if}{\quad if@>
+ q:=link(q);
+@y
+else begin q:=cond_ptr;
+ loop@+ begin if q=null then confusion("if");
+@:this can't happen if}{\quad if@>
+ if link(q)=p then
+ begin type(q):=l; return;
+ end;
+ q:=link(q);
+ end;
+@z
+
+254. Minor amendment to stat(s) printing (cf. change 129) (August 16)
+@x in module 1334
+ wlog_ln(' ',str_ptr-init_str_ptr:1,' strings out of ',
+ max_strings-init_str_ptr:1);@/
+@y
+ wlog(' ',str_ptr-init_str_ptr:1,' string');
+ if str_ptr<>init_str_ptr+1 then wlog('s');
+ wlog_ln(' out of ',
+@z
+
+255. Bug in \xleader computations (found by FY, August 18)
+@x in module 592
+@!lq,@!lr:integer; {quantities used in calculations for leaders}
+@y
+@!lq,@!lr,@!lx:integer; {quantities used in calculations for leaders}
+@z
+@x in module 626
+ begin edge:=cur_h+rule_wd;
+ @<Let |cur_h| be the position of the first box, and set |leader_wd|
+ to the spacing between corresponding parts of boxes@>;
+ while cur_h+leader_wd<=edge do
+ @<Output a leader box at |cur_h|,
+ then advance |cur_h| by |leader_wd|@>;
+@y
+ begin edge:=cur_h+rule_wd; lx:=0;
+ @<Let |cur_h| be the position of the first box, and set |leader_wd+lx|
+ to the spacing between corresponding parts of boxes@>;
+ while cur_h+leader_wd<=edge do
+ @<Output a leader box at |cur_h|,
+ then advance |cur_h| by |leader_wd+lx|@>;
+@z
+@x in module 627
+ leader_wd:=leader_wd+lx;
+@y
+@z
+@x in module 628
+cur_h:=save_h+leader_wd;
+@y
+cur_h:=save_h+leader_wd+lx;
+@z
+@x in module 635
+ begin edge:=cur_v+rule_ht;
+ @<Let |cur_v| be the position of the first box, and set |leader_ht|
+ to the spacing between corresponding parts of boxes@>;
+ while cur_v+leader_ht<=edge do
+ @<Output a leader box at |cur_v|,
+ then advance |cur_v| by |leader_ht|@>;
+@y
+ begin edge:=cur_v+rule_ht; lx:=0;
+ @<Let |cur_v| be the position of the first box, and set |leader_ht+lx|
+ to the spacing between corresponding parts of boxes@>;
+ while cur_v+leader_ht<=edge do
+ @<Output a leader box at |cur_v|,
+ then advance |cur_v| by |leader_ht+lx|@>;
+@z
+@x in module 636
+ leader_ht:=leader_ht+lx;
+@y
+@z
+@x in module 637
+cur_v:=save_v-height(leader_box)+leader_ht;
+@y
+cur_v:=save_v-height(leader_box)+leader_ht+lx;
+@z
+Also insert the following in modules 619 and 629:
+@!lx:scaled; {extra space between leader boxes}
+
+256. \/ should apply to ligatures! (August 20)
+@x in module 1113
+var f:internal_font_number; {the font in the |char_node|}
+begin if is_char_node(tail)and(tail<>head) then
+ begin f:=font(tail);
+ tail_append(new_kern(char_italic(f)(char_info(f)(character(tail)))));
+@y
+label exit;
+var p:pointer; {|char_node| at the tail of the current list}
+@!f:internal_font_number; {the font in the |char_node|}
+begin if tail<>head then
+ begin if is_char_node(tail) then p:=tail
+ else if type(tail)=ligature_node then p:=lig_char(tail)
+ else return;
+ f:=font(p);
+ tail_append(new_kern(char_italic(f)(char_info(f)(character(p)))));
+@z
+@x later in that same module
+end;
+@y
+exit: end;
+@z
+
+257. Another debugging hack. (August 27)
+@x module 1339
+15: begin font_in_short_display:=null_font; short_display(n);
+ end;
+@y
+15: begin font_in_short_display:=null_font; short_display(n);
+ end;
+16: panicking:=not panicking;
+@z
+
+258. Redundant code eliminated (August 27)
+Module 531 needn't set and reset name_in_progress [but it's harmless].
+
+259. Bug: \input shouldn't occur during font size spec (Spivak; fixed August 27)
+@x module 1258
+@ @<Scan the font size specification@>=
+@y
+@ @<Scan the font size specification@>=
+name_in_progress:=true; {this keeps |cur_name| from being changed}
+@z
+@x module 1258
+else s:=-1000
+@y
+else s:=-1000;
+name_in_progress:=false
+@z
+
+260. \ifhbox and \ifvbox introduced. (August 27)
+@x module 487
+@d ifx_code=10 { `\.{\\ifx}' }
+@d if_eof_code=11 { `\.{\\ifeof}' }
+@d if_true_code=12 { `\.{\\iftrue}' }
+@d if_false_code=13 { `\.{\\iffalse}' }
+@d if_case_code=14 { `\.{\\ifcase}' }
+@y
+@d if_hbox_code=10 { `\.{\\ifhbox}' }
+@d if_vbox_code=11 { `\.{\\ifvbox}' }
+@d ifx_code=12 { `\.{\\ifx}' }
+@d if_eof_code=13 { `\.{\\ifeof}' }
+@d if_true_code=14 { `\.{\\iftrue}' }
+@d if_false_code=15 { `\.{\\iffalse}' }
+@d if_case_code=16 { `\.{\\ifcase}' }
+@z
+@x
+primitive("ifx",if_test,ifx_code);
+@y
+primitive("ifhbox",if_test,if_hbox_code);
+@!@:if_hbox_}{\.{\\ifhbox} primitive@>
+primitive("ifvbox",if_test,if_vbox_code);
+@!@:if_vbox_}{\.{\\ifvbox} primitive@>
+primitive("ifx",if_test,ifx_code);
+@z
+@x module 488
+ ifx_code:print_esc("ifx");
+@y
+ if_hbox_code:print_esc("ifhbox");
+ if_vbox_code:print_esc("ifvbox");
+ ifx_code:print_esc("ifx");
+@z
+@x module 501
+if_void_code: @<Test if a box is void@>;
+@y
+if_void_code, if_hbox_code, if_vbox_code: @<Test box register status@>;
+@z
+@x module 505
+@ @<Test if a box is void@>=
+begin scan_eight_bit_int; b:=(box(cur_val)=null);
+end
+@y
+@ @<Test box register status@>=
+begin scan_eight_bit_int; p:=box(cur_val);
+if this_if=if_void_code then b:=(p=null)
+else if p=null then b:=false
+else if this_if=if_hbox_code then b:=(type(p)=hlist_node)
+else b:=(type(p)=vlist_node);
+end
+
+261. Serious data structure error (found by Todd Allen, August 29)
+@x module 478 (an error introduced in change 231)
+ q:=the_toks; link(p):=link(temp_head); p:=q;
+@y
+ q:=the_toks;
+ if link(temp_head)<>null then
+ begin link(p):=link(temp_head); p:=q;
+ end;
+@z
+
+262. Minor patch for efficiency (August 29)
+@x module 466
+ begin store_new_token(info(r)); r:=link(r);
+@y
+ begin fast_store_new_token(info(r)); r:=link(r);
+@z
+
+263. Minor patch to error message (August 29)
+@module 579
+ print(" has "); print_int(font_params[f]);
+ print(" fontdimen parameters");
+@.Font x has n fontdimen...@>
+@y
+ print(" has only "); print_int(font_params[f]);
+ print(" fontdimen parameters");
+@.Font x has only...@>
+@z
+
+*** The changes above comprise version 0.99999, used only at SAIL (August 29)
+
+264. funny blank spaces are showable (August 30)
+@x module 298
+spacer: print("blank space");
+@y
+spacer: chr_cmd("blank space ");
+@z
+
+265. \newlinechar [change 235] should affect print_char too (August 31)
+@x module 58
+procedure print_char(@!c:ascii_code); {prints a single character}
+begin case selector of
+term_and_log: begin wterm(xchr[c]); write(log_file,xchr[c]);
+ incr(term_offset); incr(file_offset);
+ if term_offset=max_print_line then
+ begin wterm_cr; term_offset:=0;
+ end;
+ if file_offset=max_print_line then
+ begin wlog_cr; file_offset:=0;
+ end;
+ end;
+log_only: begin write(log_file,xchr[c]); incr(file_offset);
+ if file_offset=max_print_line then print_ln;
+ end;
+term_only: begin wterm(xchr[c]); incr(term_offset);
+ if term_offset=max_print_line then print_ln;
+ end;
+no_print: do_nothing;
+pseudo: if tally<trick_count then trick_buf[tally mod error_line]:=c;
+new_string: begin if pool_ptr<pool_size then append_char(c);
+ end; {drop characters if the string space is full}
+othercases write(write_file[selector],xchr[c])
+endcases;@/
+incr(tally);
+end;
+@y
+procedure print_char(@!s:ascii_code); {prints a single character}
+label exit;
+begin if @<Character |s| is the current new-line character@> then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+case selector of
+term_and_log: begin wterm(xchr[s]); wlog(xchr[s]);
+ incr(term_offset); incr(file_offset);
+ if term_offset=max_print_line then
+ begin wterm_cr; term_offset:=0;
+ end;
+ if file_offset=max_print_line then
+ begin wlog_cr; file_offset:=0;
+ end;
+ end;
+log_only: begin wlog(xchr[s]); incr(file_offset);
+ if file_offset=max_print_line then print_ln;
+ end;
+term_only: begin wterm(xchr[s]); incr(term_offset);
+ if term_offset=max_print_line then print_ln;
+ end;
+no_print: do_nothing;
+pseudo: if tally<trick_count then trick_buf[tally mod error_line]:=s;
+new_string: begin if pool_ptr<pool_size then append_char(s);
+ end; {drop characters if the string space is full}
+othercases write(write_file[selector],xchr[s])
+endcases;@/
+incr(tally);
+exit:end;
+
+266. \lastkern,\lastpenalty,\unkern,\unpenalty (September 4)
+@x module 208
+@d unskip=25 {nullify glue ( \.{\\unskip} )}
+@y
+@d remove_item=25 {nullify last item ( \.{\\unpenalty},
+ \.{\\unkern}, \.{\\unskip} )}
+@z
+@x module 208
+@d last_skip=69 {most recent glue ( \.{\\lastskip} )}
+@y
+@d last_item=69 {most recent item ( \.{\\lastpenalty},
+ \.{\\lastkern}, \.{\\lastskip} )}
+@z
+@x module 265
+primitive("lastskip",last_skip,0);@/
+@!@:last_skip_}{\.{\\lastskip} primitive@>
+@y
+@z
+@x module 265
+primitive("the",the,0);
+@!@:the_}{\.{\\the} primitive@>
+primitive("toks",toks_register,0);
+@!@:toks_}{\.{\\toks} primitive@>
+primitive("unskip",unskip,0);@/
+@!@:unskip_}{\.{\\unskip} primitive@>
+@y
+primitive("the",the,0);@/
+@!@:the_}{\.{\\the} primitive@>
+primitive("toks",toks_register,0);@/
+@!@:toks_}{\.{\\toks} primitive@>
+@z
+@x module 266
+last_skip: print_esc("lastskip");
+@y
+@z
+@x module 266
+unskip: print_esc("unskip");
+@y
+@z
+@x module 413
+last_skip: @<Fetch the glue in the current node, if any@>;
+@y
+last_item: @<Fetch an item in the current node, if appropriate@>;
+@z
+@x module 416 [I also changed the comment]
+primitive("dp",set_box_dimen,depth_offset);
+@!@:dp_}{\.{\\dp} primitive@>
+@y
+primitive("dp",set_box_dimen,depth_offset);
+@!@:dp_}{\.{\\dp} primitive@>
+primitive("lastpenalty",last_item,int_val);
+@!@:last_penalty_}{\.{\\lastpenalty} primitive@>
+primitive("lastkern",last_item,dimen_val);
+@!@:last_kern_}{\.{\\lastkern} primitive@>
+primitive("lastskip",last_item,glue_val);
+@!@:last_skip_}{\.{\\lastskip} primitive@>
+@z
+@x module 417
+else print_esc("dp");
+@y
+else print_esc("dp");
+last_item: if chr_code=int_val then print_esc("lastpenalty")
+else if chr_code=dimen_val then print_esc("lastkern")
+else print_esc("lastskip");
+@z
+@x module 424
+@ Here is where \.{\\lastskip} is implemented. The reference count will be
+updated later.
+@:last_skip_}{\.{\\lastskip} primitive@>
+
+@<Fetch the glue in the current node, if any@>=
+begin cur_val:=zero_glue; cur_val_level:=glue_val;
+if not is_char_node(tail)and(mode<>0) then
+ begin if type(tail)=glue_node then
+ begin cur_val:=glue_ptr(tail);
+ if subtype(tail)=mu_glue then cur_val_level:=mu_val;
+ end;
+ end
+else if (mode=vmode)and(tail=head)and(last_page_glue<>max_halfword) then
+ cur_val:=last_page_glue;
+end
+@y
+@ Here is where \.{\\lastpenalty}, \.{\\lastkern}, and \.{\\lastskip} are
+implemented. The reference count for \.{\\lastskip} will be updated later.
+
+@<Fetch an item in the current node...@>=
+begin if cur_chr=glue_val then cur_val:=zero_glue@+else cur_val:=0;
+cur_val_level:=cur_chr;
+if not is_char_node(tail)and(mode<>0) then
+ case cur_chr of
+ int_val: if type(tail)=penalty_node then cur_val:=penalty(tail);
+ dimen_val: if type(tail)=kern_node then cur_val:=width(tail);
+ glue_val: if type(tail)=glue_node then
+ begin cur_val:=glue_ptr(tail);
+ if subtype(tail)=mu_glue then cur_val_level:=mu_val;
+ end;
+ end {there are no other cases}
+else if (mode=vmode)and(tail=head) then
+ case cur_chr of
+ int_val: cur_val:=last_penalty;
+ dimen_val: cur_val:=last_kern;
+ glue_val: if last_glue<>max_halfword then cur_val:=last_glue;
+ end; {there are no other cases}
+end
+@z
+@x module 982 [also the comment changes]
+@!last_page_glue:pointer; {used to implement \.{\\lastskip}}
+@y
+@!last_glue:pointer; {used to implement \.{\\lastskip}}
+@!last_penalty:integer; {used to implement \.{\\lastpenalty}}
+@!last_kern:scaled; {used to implement \.{\\lastkern}}
+@z
+@x module 991
+last_page_glue:=max_halfword;
+@y
+last_glue:=max_halfword; last_penalty:=0; last_kern:=0;
+@z
+@x module 994
+@<Update the value of |last_page_glue|@>;
+@y
+@<Update the values of |last_glue|, |last_penalty|, and |last_kern|@>;
+@z
+@x module 996
+@ @<Update the value of |last_page_glue|@>=
+if last_page_glue<>max_halfword then delete_glue_ref(last_page_glue);
+if type(p)=glue_node then
+ begin last_page_glue:=glue_ptr(p); add_glue_ref(last_page_glue);
+ end
+else last_page_glue:=max_halfword
+@y
+@ @<Update the values of |last_glue|...@>=
+if last_glue<>max_halfword then delete_glue_ref(last_glue);
+last_penalty:=0; last_kern:=0;
+if type(p)=glue_node then
+ begin last_glue:=glue_ptr(p); add_glue_ref(last_glue);
+ end
+else begin last_glue:=max_halfword;
+ if type(p)=penalty_node then last_penalty:=penalty(p)
+ else if type(p)=kern_node then last_kern:=width(p);
+ end
+@z
+@x module 1017
+if last_page_glue<>max_halfword then delete_glue_ref(last_page_glue);
+@<Start a new current page@>; {this sets |last_page_glue:=max_halfword|}
+@y
+if last_glue<>max_halfword then delete_glue_ref(last_glue);
+@<Start a new current page@>; {this sets |last_glue:=max_halfword|}
+@z
+@x module 1048
+vmode+vmove,hmode+hmove,mmode+hmove,any_mode(last_skip),
+@y
+vmode+vmove,hmode+hmove,mmode+hmove,any_mode(last_item),
+@z
+@x module 1104
+any_mode(unskip): delete_skip;
+@y
+any_mode(remove_item): delete_last;
+@z
+@x module 1105
+procedure delete_skip;
+var p:pointer; {runs through the current list}
+begin if (mode=vmode)and(tail=head) then
+ @<Apologize for inability to do \.{\\unskip} now,
+ unless the previous node was not glue@>
+else begin if not is_char_node(tail) then if type(tail)=glue_node then
+@y
+procedure delete_last;
+var p:pointer; {runs through the current list}
+begin if (mode=vmode)and(tail=head) then
+ @<Apologize for inability to do the operation now,
+ unless \.{\\unskip} follows non-glue@>
+else begin if not is_char_node(tail) then if type(tail)=cur_chr then
+@z
+@x module 1106
+@ @<Apologize for inability to do \.{\\unskip}...@>=
+begin if last_page_glue<>max_halfword then
+ begin you_cant;
+ help2("Sorry...I'm usually unable to take things from the current")@/
+ ("page. Try `I\vskip-\lastskip' instead."); error;
+@y
+@ @<Apologize for inability to do the operation...@>=
+begin if (cur_chr<>glue_node)or(last_glue<>max_halfword) then
+ begin you_cant;
+ help2("Sorry...I'm usually unable to take things from the current")@/
+ ("page. Try `I\vskip-\lastskip' instead.");
+ if cur_chr=kern_node then help_line[0]:=
+ ("page. Try `I\kern-\lastkern' instead.")
+ else if cur_chr<>glue_node then help_line[0]:=@|
+ ("page. Perhaps you can make the output routine do it.");
+ error;
+@z
+@x module 1107
+primitive("unhbox",un_hbox,box_code);@/
+@y
+primitive("unpenalty",remove_item,penalty_node);@/
+@!@:un_penalty_}{\.{\\unpenalty} primitive@>
+primitive("unkern",remove_item,kern_node);@/
+@!@:un_kern_}{\.{\\unkern} primitive@>
+primitive("unskip",remove_item,glue_node);@/
+@!@:un_skip_}{\.{\\unskip} primitive@>
+primitive("unhbox",un_hbox,box_code);@/
+@z
+@x module 1108
+un_hbox: if chr_code=copy_code then print_esc("unhcopy")
+@y
+remove_item: if chr_code=glue_node then print_esc("unskip")
+ else if chr_code=kern_node then print_esc("unkern")
+ else print_esc("unpenalty");
+un_hbox: if chr_code=copy_code then print_esc("unhcopy")
+@z
+
+*** The above changes installed in version 0.999999 (September 5, 1983)
+
+267. Undo change 29: it was overkill and not needed (Sep 17)
+@x module 1257
+label exit, common_ending;
+var u:pointer; {user's font identifier}
+@!s:scaled; {stated ``at'' size, or negative of scaled magnification}
+@!f:internal_font_number; {runs through existing fonts}
+begin if job_name=0 then open_log_file;
+ {avoid confusing \.{texput} with the font name}
+@<If the next token isn't a suitable control sequence, issue a complaint
+ and |return|; otherwise set |u:=cs_ptr|, and set |hash_used| to the
+ location of a ``frozen'' copy of the new font identifier@>;
+define(u,set_font,null_font); scan_optional_equals; scan_file_name;
+@<Scan the font size specification@>;
+@<If this font has already been loaded, set |f| to the internal
+ font number and |goto common_ending|@>;
+f:=read_font_info(u,cur_name,cur_area,s);
+common_ending: equiv(u):=f; geq_define(hash_used,set_font,f);
+font_ident[f]:=hash_used;
+exit:end;
+@y
+label common_ending;
+var u:pointer; {user's font identifier}
+@!s:scaled; {stated ``at'' size, or negative of scaled magnification}
+@!f:internal_font_number; {runs through existing fonts}
+begin if job_name=0 then open_log_file;
+ {avoid confusing \.{texput} with the font name}
+get_r_token; u:=cs_ptr;
+define(u,set_font,null_font); scan_optional_equals; scan_file_name;
+@<Scan the font size specification@>;
+@<If this font has already been loaded, set |f| to the internal
+ font number and |goto common_ending|@>;
+f:=read_font_info(u,cur_name,cur_area,s);
+common_ending: equiv(u):=f; font_ident[f]:=u;
+end;
+@z
+@x module 1260
+@ We reserve a special control sequence for the font identifier; this one
+cannot be redefined by the user, so it is safe to return it as a value of
+\.{\\the\\font}.
+
+@<If the next token isn't a suitable control sequence...@>=
+get_r_token;
+if cs_ptr<hash_base then
+ begin print_err("A font identifier must be a multiletter control sequence");
+@.A font identifier...@>
+ help2("You should say, e.g., `\font\ffn=fontfilename'.")@/
+ ("(I'm going to ignore the \font command you just gave.)");
+ back_error; return;
+ end;
+repeat if hash_is_full then overflow("hash size",hash_size);
+@:TeX capacity exceeded hash size}{\quad hash size@>
+decr(hash_used);
+until text(hash_used)=0; {search for an empty location in |hash|}
+u:=cs_ptr; text(hash_used):=text(u); {copy the name}
+@!stat incr(cs_count);@+tats@;@/
+@y
+@z
+Note: Since module 1260 has disappeared, module 1258 has been split into two.
+
+268. Minor change to diagnostic output format (September 18)
+@x module 211 [print_mode]
+ 2:print("displayed math");
+@y
+ 2:print("display math");
+@z
+
+269. Kerns inserted for accents must be explicit (September 20)
+@x module 1123
+@!p,@!q: pointer; {character and box nodes}
+@y
+@!p,@!q,@!r:pointer; {character, box, and kern nodes}
+@z
+@x module 1125
+link(tail):=new_kern(delta); link(link(tail)):=p;
+link(p):=new_kern(-a-delta); tail:=link(p); p:=q;
+@y
+r:=new_kern(delta); subtype(r):=explicit; link(tail):=r; link(r):=p;
+tail:=new_kern(-a-delta); subtype(tail):=explicit; link(p):=tail; p:=q;
+@z
+
+270. "log" changed to "transcript" in a few output messages (Sep 26)
+@x module 535
+prompt_file_name("log file name",".log");
+@y
+prompt_file_name("transcript file name",".log");
+@z
+@x module 1293
+ ("lists on your terminal as well as on the log file.");
+@y
+ ("lists on your terminal as well as in the transcript file.");
+@z
+@x module 1335
+ print_nl("(see the log file for additional information)");
+@.see the log file...@>
+@y
+ print_nl("(see the transcript file for additional information)");
+@.see the transcript file...@>
+@z
+
+271. Uninitialized variable bug (found by Bernd Schulze, 1 Oct 83)
+@x module 944
+ begin if trie_op_ptr>=max_quarterword-1 then {overflow}
+ begin trie_op_ptr:=max_quarterword;
+ new_trie_op:=min_quarterword; return;
+@y we allow one more trie op (OK since trie_op_hash_size is big enough)
+ begin if trie_op_ptr=max_quarterword then {overflow}
+ begin new_trie_op:=min_quarterword; return;
+@z
+
+272. Spaces at end of lines ignored also in TEX.POOL (by DRF, 14 Oct 83)
+@x module 52
+ begin if eoln(pool_file) then bad_pool('! TEX.POOL line too short.');
+@.TEX.POOL line too short@>
+ read(pool_file,m); append_char(xord[m]);
+@y
+ begin if eoln(pool_file) then m:=' '@+else read(pool_file,m);
+ append_char(xord[m]);
+@z
+
+273. |history| updates (by DRF, 14 Oct 83)
+@x module 77
+deletions_allowed:=true; history:=spotless; error_count:=0;
+@y
+deletions_allowed:=true; error_count:=0; {|history| is initialized elsewhere}
+@z
+@x module 1332
+@p begin {@!|start_here|}
+@y
+@p begin {@!|start_here|}
+history:=fatal_error_stop; {in case we quit during initialization}
+@z
+@x ibid.
+main_control; {come to life}
+@y
+history:=spotless; {ready to go!}
+main_control; {come to life}
+@z
+
+274. improved "runaway" messages (suggested by FY, October 18)
+@x module 305 (the introductory comment is changed too)
+@d aligning=4 {|scanner_status| when reading an alignment preamble}
+
+@<Glob...@>=
+@!scanner_status : normal..aligning; {can a subfile end now?}
+@y
+@d aligning=4 {|scanner_status| when reading an alignment preamble}
+@d absorbing=5 {|scanner_status| when reading a balanced text}
+
+@<Glob...@>=
+@!scanner_status : normal..absorbing; {can a subfile end now?}
+@z
+@x module 306 (string space is also now conserved slightly)
+ defining: begin print("definition?"); p:=def_ref;
+ end;
+ matching: begin print("argument?"); p:=temp_head;
+ end;
+ aligning: begin print("preamble?"); p:=hold_head;
+ end;
+ end; {there are no other cases}
+ print_ln; show_token_list(link(p),null,error_line-10);
+@y
+ defining: begin print("definition"); p:=def_ref;
+ end;
+ matching: begin print("argument"); p:=temp_head;
+ end;
+ aligning: begin print("preamble"); p:=hold_head;
+ end;
+ absorbing: begin print("text"); p:=def_ref;
+ end;
+ end; {there are no other cases}
+ print_char("?");print_ln; show_token_list(link(p),null,error_line-10);
+@x module 339 (I also changed the module name)
+end; {there are no other cases}
+@y
+absorbing:begin print("text"); info(p):=right_brace_token+"}";
+ end;
+end; {there are no other cases}
+@z
+@x module 473
+begin scanner_status:=defining; warning_index:=cs_ptr;
+def_ref:=get_avail; info(def_ref):=null;
+@y
+begin if macro_def then scanner_status:=defining
+@+else scanner_status:=absorbing;
+warning_index:=cs_ptr; def_ref:=get_avail; info(def_ref):=null;
+@z
+
+275. similar, but this corrects a real bug (found by FY, October 18)
+@x module 1226
+ cs_ptr:=q;
+ @<Get the next non-blank non-relax non-call token@>;
+ if cur_cmd<>left_brace then @<If the righthand side is a token parameter
+ or token register, finish the assignment and |goto done|@>;
+ back_input; q:=scan_toks(false,false);
+@y
+ @<Get the next non-blank non-relax non-call token@>;
+ if cur_cmd<>left_brace then @<If the righthand side is a token parameter
+ or token register, finish the assignment and |goto done|@>;
+ back_input; cs_ptr:=q; q:=scan_toks(false,false);
+@z
+
+276. Change #119 should have changed module 1090 too (by Barry Smith, Oct 24)
+@x module 1183 [which was module 1090 at the time of change 119]
+begin if c mod delimited_code=above_code then scan_normal_dimen;
+if c>=delimited_code then
+ begin scan_delimiter(garbage,false); scan_delimiter(garbage,false);
+ end;
+@y
+begin if c>=delimited_code then
+ begin scan_delimiter(garbage,false); scan_delimiter(garbage,false);
+ end;
+if c mod delimited_code=above_code then scan_normal_dimen;
+@z
+
+277. Changes for efficiency, based on empirical frequency data (Nov 9)
+@x module 45 [since the result is true almost always]
+begin j:=str_start[s]; result:=false;
+while j<str_start[s+1] do
+ begin if str_pool[j]<>buffer[k] then goto not_found;
+@y
+begin j:=str_start[s];
+while j<str_start[s+1] do
+ begin if str_pool[j]<>buffer[k] then
+ begin result:=false; goto not_found;
+ end;
+@z
+@x module 380 [many compilers don't handle "while true do" very well]
+label done;
+begin loop begin get_next;
+@^inner loop@>
+ if cur_cmd<=max_command then goto done;
+ if cur_cmd>=call then
+ if cur_cmd<end_template then macro_call
+ else begin cs_ptr:=frozen_endv; cur_cmd:=endv;
+ goto done; {|cur_chr=null_list|}
+ end
+ else expand;
+ end;
+@y
+label restart,done;
+begin restart: get_next;
+@^inner loop@>
+if cur_cmd<=max_command then goto done;
+if cur_cmd>=call then
+ if cur_cmd<end_template then macro_call
+ else begin cs_ptr:=frozen_endv; cur_cmd:=endv;
+ goto done; {|cur_chr=null_list|}
+ end
+else expand;
+goto restart;
+@z
+@x module 829 [preparation for change to module 852]
+label exit,done,continue,deactivate;
+@y
+label exit,done,done1,continue,deactivate;
+@z
+@x module 830 [ditto]
+@!save_link:pointer; {temporarily holds value of |link(cur_p)|}
+@y
+@!save_link:pointer; {temporarily holds value of |link(cur_p)|}
+@!shortfall:scaled; {used in badness calculations}
+@z
+@x modue 851 [ditto]
+if cur_active_width[1]<line_width then
+@y
+shortfall:=line_width-cur_active_width[1]; {we're this much too short}
+if shortfall>0 then
+@z
+@x module 852 [avoid calling |badness| in most common case]
+else begin b:=badness(line_width-cur_active_width[1],cur_active_width[2]);
+@y
+else begin if shortfall>7230584 then if cur_active_width[2]<1663497 then
+ begin b:=inf_bad; fit_class:=very_loose_fit; goto done1;
+ end;
+ b:=badness(shortfall,cur_active_width[2]);
+@z
+@x module 852, continued
+ else fit_class:=decent_fit;
+@y
+ else fit_class:=decent_fit;
+ done1:
+@z
+@x module 853 [using |shortfall|, since we now have it]
+begin if cur_active_width[1]-line_width>cur_active_width[6] then
+ b:=inf_bad+1
+else b:=badness(cur_active_width[1]-line_width,cur_active_width[6]);
+@y
+begin if -shortfall>cur_active_width[6] then b:=inf_bad+1
+else b:=badness(-shortfall,cur_active_width[6]);
+@z
+
+278. Forgotten |error| call (noticed by Gabi Kuper, December 3, 1983)
+@x module 500
+ help1("I'm ignoring this; it doesn't match any \if.");
+@y
+ help1("I'm ignoring this; it doesn't match any \if.");
+ error;
+@z
+
+*** Version 1.0 released on December 3, 1983 incorporates all of the above.
+ Version 1.1
+
+279. Problem with change 267 (found by Mike Urban, received 2 Feb 84)
+(I had overlooked many problems, e.g. `{\font\a=x \global\a}\the\font'
+and `\font\a=x \font\b=x \let\b=\undefined \the\a', etc.
+The remedy involves removal of the font_ident array, so there's a
+sprinkling of corrections in lots of modules. But basically the change
+is quite conservative, so it shouldn't spawn any new bugs (it says here).)
+
+@x module 174 (removing a reference to |font_ident|)
+ else sprint_cs(font_ident[font(p)]);
+@y
+ else @<Print the font identifier for |font(p)|@>;
+@z
+@x module 176 (removing a reference to |font_ident|)
+ else sprint_cs(font_ident[font(p)]);
+@y
+ else @<Print the font identifier for |font(p)|@>;
+@z
+@x module 222 (redefining and expanding the `frozen' area)
+@d frozen_null_font=frozen_control_sequence+9 {permanent `\.{\\nullfont}'}
+@d frozen_dont_expand=frozen_control_sequence+10
+ {permanent `\.{\\notexpanded:}'}
+@d undefined_control_sequence=frozen_control_sequence+11 {dummy location}
+@y
+@d frozen_dont_expand=frozen_control_sequence+9
+ {permanent `\.{\\notexpanded:}'}
+@d frozen_null_font=frozen_control_sequence+10
+ {permanent `\.{\\nullfont}'}
+@d font_id_base=frozen_null_font-font_base
+ {begins table of 257 permanent font identifiers}
+@d undefined_control_sequence=frozen_null_font+257 {dummy location}
+@z
+@x module 234 (removing a reference to |font_ident|, awkwardly)
+print_char("="); sprint_cs(font_ident[equiv(n)]);
+@y
+print_char("=");@/
+print_esc(hash[font_id_base+equiv(n)].rh);
+ {that's |text(font_id_base+equiv(n))|}
+@z
+@x module 256 (adding a new macro, font_id_text)
+@d hash_is_full == (hash_used=hash_base) {test if all positions are occupied}
+@y
+@d hash_is_full == (hash_used=hash_base) {test if all positions are occupied}
+@d font_id_text(#) == text(font_id_base+#) {a frozen font identifier's name}
+@z
+@x module 262 (relaxing a former restriction)
+else if (text(p)<128)or(text(p)>=str_ptr) then print_esc("NONEXISTENT.")
+@y
+else if (text(p)<0)or(text(p)>=str_ptr) then print_esc("NONEXISTENT.")
+@z
+@x module 267 (pick up the changes from 174 and 176)
+@!@^Single-character primitives@>
+@y
+@!@^Single-character primitives@>
+
+Meanwhile, this is a convenient place to catch up on something we were unable
+to do before the hash table was defined:
+
+@<Print the font identifier for |font(p)|@>=
+print_esc(font_id_text(font(p)))
+@z
+@x module 415 (removing another reference to font_ident)
+ scanned_result(font_ident[cur_val])(ident_val);
+@y
+ scanned_result(font_id_base+cur_val)(ident_val);
+@z
+@x module 548 (change to the comment only)
+to the user's font~\.{\\f}. For example, if this internal number is 13,
+we will have |font_ident[13]=p| and |equiv(p)=13|, where |p| is the |eqtb|
+location of the control sequence~\.{\\f}.
+@y
+to the user's font~\.{\\f}. Adding this number to |font_id_base| gives the
+|eqtb| location of a ``frozen'' control sequence that will always select
+the font.
+@z
+@x module 549 (deleting the declaration of font_ident)
+@!font_ident:array[internal_font_number] of pointer; {the most recent user
+ font identifier corresponding to an internal font number}
+@y
+@z
+@x module 552 (deleting an unnecessary initialization of font_ident)
+font_ident[null_font]:=frozen_null_font;
+@y
+@z
+@x module 579 (removing another reference to font_ident)
+ begin print_err("Font "); sprint_cs(font_ident[f]);
+@y
+ begin print_err("Font "); print_esc(font_id_text(f));
+@z
+@x module 1257 (this is the real change!)
+begin if job_name=0 then open_log_file;
+ {avoid confusing \.{texput} with the font name}
+get_r_token; u:=cs_ptr;
+define(u,set_font,null_font); scan_optional_equals; scan_file_name;
+@<Scan the font size specification@>;
+@<If this font has already been loaded, set |f| to the internal
+ font number and |goto common_ending|@>;
+f:=read_font_info(u,cur_name,cur_area,s);
+common_ending: equiv(u):=f; font_ident[f]:=u;
+@y
+@!t:str_number; {name for the frozen font identifier}
+@!old_setting:0..max_selector; {holds |selector| setting}
+begin if job_name=0 then open_log_file;
+ {avoid confusing \.{texput} with the font name}
+get_r_token; u:=cs_ptr;
+if u>=hash_base then t:=text(u)
+else if u>=single_base then
+ if u=null_cs then t:="FONT"@+else t:=u-single_base
+else begin old_setting:=selector; selector:=new_string;
+ print("FONT"); print(u-active_base); selector:=old_setting;
+@.FONTx@>
+ str_room(1); t:=make_string;
+ end;
+define(u,set_font,null_font); scan_optional_equals; scan_file_name;
+@<Scan the font size specification@>;
+@<If this font has already been loaded, set |f| to the internal
+ font number and |goto common_ending|@>;
+f:=read_font_info(u,cur_name,cur_area,s);
+common_ending: equiv(u):=f; eqtb[font_id_base+f]:=eqtb[u]; font_id_text(f):=t;
+@z
+@x module 1260 (change to the comment only)
+the new value becomes the |font_ident| of record. Font names `\.{xyz}' and
+@y
+the new name becomes the font identifier of record. Font names `\.{xyz}' and
+@z
+@x module 1322 (no need to dump font_ident)
+begin dump_int(font_ident[k]);
+dump_qqqq(font_check[k]);
+@y
+begin dump_qqqq(font_check[k]);
+@z
+@x module 1322 (or to print from it)
+print_nl("\font"); sprint_cs(font_ident[k]); print_char("=");
+@y
+print_nl("\font"); print_esc(font_id_text(k)); print_char("=");
+@z
+@x module 1323 (or to undump it)
+begin undump(active_base)(undefined_control_sequence)(font_ident[k]);
+undump_qqqq(font_check[k]);@/
+@y
+begin undump_qqqq(font_check[k]);@/
+@z
+
+280. Double interrupt possibility (found by Clint Cuzzo, received 9 Feb 84)
+@x module 1031
+if interrupt>0 then if OK_to_interrupt then
+ begin back_input; pause_for_instructions; goto big_switch;
+@y
+if interrupt<>0 then if OK_to_interrupt then
+ begin back_input; check_interrupt; goto big_switch;
+@z
+
+281. Improve spacing in $(A,<)$. (12 Feb 84)
+@x module 764
+"0234000122*4000133**3**344*0400400*000000234000111*4111112341011"
+@y
+"0234000122*4000133**3**344*0400400*000000234000111*1111112341011"
+@z
+
+282. Bad goto! (diagnosis by Clint Cuzzo and George O'Connor, recd 13 Feb 84)
+@x module 344 (here we simply change the name of module 346)
+any_state_plus(invalid_char): @<Decry the invalid character and
+ |goto switch|@>;
+@y
+any_state_plus(invalid_char): @<Decry the invalid character and
+ |goto restart|@>;
+@z
+@x module 346 (because clear_for_error_prompt might make state=token_list)
+goto switch;
+@y
+goto restart;
+@z
+
+283. String pool economy (suggested by DRF, 13 Feb 84)
+@x module 537
+@<Read the first line of the new file@>;
+@y
+if name=str_ptr-1 then {we can conserve string pool space now}
+ begin flush_string; name:=cur_name;
+ end;
+@<Read the first line of the new file@>;
+@z
+
+284. Nicer scaled output (suggested by METAFONT development, 26 Feb 84)
+@x module 103
+be reproduced exactly. [{\sl Proof:\/} If round$(x)=\lfloor
+x+{1\over2}\rfloor$ and if $\alpha<1$, it is not difficult to verify that
+round$(\alpha\,\hbox{round}( \alpha^{-1}n))=n$ for all integers |n|. In
+our case $\alpha=2^{16}/10^5$.]
+
+@p procedure print_scaled(@!s:scaled); {prints scaled real, rounded to five
+ digits}
+begin if s<0 then
+ begin print_char("-"); negate(s); {print the sign, if negative}
+ end;
+print_int(s div unity); {print the integer part}
+s:=((s mod unity) * 3125 + 1024) div 2048;
+ {now |0<=s<100000| is the fraction part}
+print_char(".");
+repeat print_char("0"+(s div 10000)); s:=10*(s mod 10000);
+until s=0;
+end;
+@y
+be reproduced exactly; the ``simplest'' such decimal number is output,
+but there is always at least one digit following the decimal point.
+
+The invariant relation in the \&{repeat} loop is that a sequence of
+decimal digits yet to be printed will yield the original number if and only if
+they form a fraction~$f$ in the range $s-\delta\L10\cdot2^{16}f<s$.
+We can stop if and only if $f=0$ satisfies this condition; the loop will
+terminate before $s$ can possibly become zero.
+
+@p procedure print_scaled(@!s:scaled); {prints scaled real, rounded to five
+ digits}
+var delta:scaled; {amount of allowable inaccuracy}
+begin if s<0 then
+ begin print_char("-"); negate(s); {print the sign, if negative}
+ end;
+print_int(s div unity); {print the integer part}
+print_char(".");
+s:=10*(s mod unity)+5; delta:=10;
+repeat if delta>unity then s:=s+@'100000-(delta div 2); {round the last digit}
+print_char("0"+(s div unity)); s:=10*(s mod unity); delta:=delta*10;
+until s<=delta;
+end;
+@z
+
+*** Those six changes account for version 1.1 (February 29, 1984).
+*** And we put the following change in too, at the last minute:
+
+285. ".00000762939453126pt" didn't round correctly! (March 2, 1984)
+@x module 452
+ if k<16 then {digits for |k>=16| cannot affect the result}
+@y (Note, I also changed the comment in module 102: 16 -> 17)
+ if k<17 then {digits for |k>=17| cannot affect the result}
+@z
+
+*** Note: I changed "cs_ptr" to "cur_cs", since the name change is more
+indicative of the fact that this variable makes a trio with cur_cmd
+and cur_chr. The TEX.WEB source changed 78 times, as a result, but
+none of the author's change files were affected.
+(But note: "save_cs_ptr" was not changed to "save_cur_cs", because
+of a name conflict.)
+
+*** And the following two were slipped in at the last second:
+
+286. loophole permitted get_next recursion (March 16, 1984)
+@x module 336
+ begin @<Back up an outer control sequence so that it can be reread@>;
+@y
+ begin deletions_allowed:=false;
+ @<Back up an outer control sequence so that it can be reread@>;
+@z
+@x ibid
+ end;
+@y
+ deletions_allowed:=true;
+ end;
+@z [the changes to deletions_allowed in module 338 can now be removed]
+
+287. terminal not open when the program starts bad (March 24, 1984)
+@x module 1332
+initialize; {set global variables to their starting values}
+@<Check the ``constant'' values...@>@;
+if bad>0 then
+ begin wake_up_terminal;
+ wterm('Ouch---my internal constants have been',
+ ' clobbered!---case ',bad:1);
+@.Ouch...clobbered@>
+ goto final_end;
+ end;
+@y
+@<Check the ``constant'' values...@>@;
+if bad>0 then
+ begin t_open_out;
+ wterm('Ouch---my internal constants have been',
+ ' clobbered!---case ',bad:1);
+@.Ouch...clobbered@>
+ goto final_end;
+ end;
+initialize; {set global variables to their starting values}
+@z
+
+*** Note: "Cosmetic" changes were also made in module 363 ("print_ln"
+moved to after "wake_up_terminal") and in some commentary.
+
+*** Another last-minute correction:
+288. \patterns{xxx...xxxdxxxdxxx} anomaly found by JRD (Mar 27, 1984)
+@x module 962
+else begin hyf[k]:=cur_chr-"0"; digit_sensed:=true;
+@y
+else begin hyf[k]:=cur_chr-"0";
+ if k<63 then digit_sensed:=true;
+@z
+
+*** Yoicks, yet ANOTHER:
+289. a whole case of copy_node_list forgotten (Apr 11, 1984)
+@x module 206
+othercases confusion("copying")
+@y
+adjust_node: begin r:=get_node(small_node_size);
+ adjust_ptr(r):=copy_node_list(adjust_ptr(p));
+ end; {|words=1=small_node_size-1|}
+othercases confusion("copying")
+@z
+
+*** And "finally"...
+290. uninitialized variables could be accessed (found by Nick Briggs, June 11)
+@x module 552
+font_size[null_font]:=0; font_dsize[null_font]:=0;
+@y
+font_size[null_font]:=0; font_dsize[null_font]:=0;
+char_base[null_font]:=0; width_base[null_font]:=0;
+height_base[null_font]:=0; depth_base[null_font]:=0;
+italic_base[null_font]:=0; lig_kern_base[null_font]:=0;
+kern_base[null_font]:=0; exten_base[null_font]:=0;
+@z (actual values are immaterial except for debugging safeguards)
+
+291. same, cf. modules 355 and 389 (Nick Briggs, June 11)
+@x module 331
+scanner_status:=normal; first:=1;
+@y
+for first:=0 to buf_size do buffer[first]:=0;
+scanner_status:=normal; warning_index:=null; first:=1;
+@z (error was harmless except that it might trigger debugging checks)
+
+292. missing ligature/kern (found by JRD, June 21)
+@x module 1036
+ if (cur_cmd=letter)or(cur_cmd=other_char) then r:=qi(cur_chr)
+@y
+ if (cur_cmd=letter)or(cur_cmd=other_char)or(cur_cmd=char_given) then
+ r:=qi(cur_chr)
+@z
+
+293. quarterword constraint is made explicit (July 4)
+@x module 111
+if (buf_size>max_halfword) then bad:=18;
+@y
+if buf_size>max_halfword then bad:=18;
+if max_quarterword-min_quarterword<255 then bad:=19;
+@z
+
+294. trivial optimization made for consistency with MF (July 7)
+@x module 363
+if (pausing>0)and(interaction>nonstop_mode) then
+@y
+if pausing>0 then if interaction>nonstop_mode then
+@z
+
+295. \tracingmacros>1 for more diagnostics (July 8)
+@x module 323
+ if t=macro then param_start:=param_ptr@+else loc:=link(p);
+@y
+ if t=macro then param_start:=param_ptr
+ else begin loc:=link(p);
+ if tracing_macros>1 then
+ begin begin_diagnostic; print_nl("");
+ case t of
+ mark_text:print_esc("mark");
+ write_text:print_esc("write");
+ othercases print_cmd_chr(assign_toks,t-output_text+output_routine_loc)
+ endcases;@/
+ print("->"); token_show(p); end_diagnostic(false);
+ end;
+ end;
+@z
+
+*** The changes above were incorporated in Version 1.1, released July 9, 1984.
+ Version 1.2
+
+296. "see the transcript file" on offline show commands. (July 27, 1984)
+@x module 1293
+@ @d show_error==@;@/
+ if interaction<error_stop_mode then
+ begin help0; decr(error_count);
+ end
+ else if tracing_online>0 then
+ begin@t@>@;@/
+ help3("This isn't an error message; I'm just \showing something.")
+ @t\4\4@>@/
+ ("Type `I\show...' to show more (e.g., \show\cs,")@/
+ ("\showthe\count10, \showbox255, \showlists).");
+ end
+ else begin@t@>@;@/
+ help5("This isn't an error message; I'm just \showing something.")
+ @t\4\4@>@/
+ ("Type `I\show...' to show more (e.g., \show\cs,")@/
+ ("\showthe\count10, \showbox255, \showlists).")@/
+ ("And type `I\tracingonline=1\show...' to show boxes and")@/
+ ("lists on your terminal as well as in the transcript file.");
+ end;
+ error
+
+@<Declare act...@>=
+procedure show_whatever;
+var p:pointer; {tail of a token list to show}
+begin case cur_chr of
+show_code: @<Show the current meaning of a token@>;
+show_box_code: @<Show the current contents of a box@>;
+show_the_code: @<Show the current value of some parameter or register@>;
+othercases @<Show the current semantic nest@>
+endcases;
+end;
+@y
+@ @<Declare act...@>=
+procedure show_whatever;
+label common_ending;
+var p:pointer; {tail of a token list to show}
+begin case cur_chr of
+show_lists: begin begin_diagnostic; show_activities;
+ end;
+show_box_code: @<Show the current contents of a box@>;
+show_code: @<Show the current meaning of a token, then |goto common_ending|@>;
+othercases @<Show the current value of some parameter or register,
+ then |goto common_ending|@>
+endcases;@/
+@<Complete a potentially long \.{\\show} command@>;
+common_ending: if interaction<error_stop_mode then
+ begin help0; decr(error_count);
+ end
+else if tracing_online>0 then
+ begin@t@>@;@/
+ help3("This isn't an error message; I'm just \showing something.")@/
+ ("Type `I\show...' to show more (e.g., \show\cs,")@/
+ ("\showthe\count10, \showbox255, \showlists).");
+ end
+else begin@t@>@;@/
+ help5("This isn't an error message; I'm just \showing something.")
+ ("Type `I\show...' to show more (e.g., \show\cs,")@/
+ ("\showthe\count10, \showbox255, \showlists).")@/
+ ("And type `I\tracingonline=1\show...' to show boxes and")@/
+ ("lists on your terminal as well as in the transcript file.");
+ end;
+error;
+end;
+@z
+@x module 1294
+@ @<Show the current meaning of a token@>=
+begin get_token; print_nl("> ");
+if cur_cs<>0 then
+ begin sprint_cs(cur_cs); print_char("=");
+ end;
+print_meaning; show_error;
+@y
+@ @<Show the current meaning of a token...@>=
+begin get_token; print_nl("> ");
+if cur_cs<>0 then
+ begin sprint_cs(cur_cs); print_char("=");
+ end;
+print_meaning; goto common_ending;
+@z
+@x module 1296
+end_diagnostic(true);
+print_err("OK");
+@.OK@>
+show_error;
+@y
+@z
+@x module 1297
+flush_list(link(temp_head)); show_error;
+@y
+flush_list(link(temp_head)); goto common_ending;
+@z
+@x module 1298
+@ @<Show the current semantic nest@>=
+begin begin_diagnostic; show_activities; end_diagnostic(true);
+print_err("OK");
+show_error;
+@.OK@>
+end
+@y
+@ @<Complete a potentially long \.{\\show} command@>=
+end_diagnostic(true); print_err("OK");
+@.OK@>
+if selector=term_and_log then if tracing_online<=0 then
+ begin selector:=term_only; print(" (see the transcript file)");
+ selector:=term_and_log;
+ end
+@z
+
+297. allow `0' in response to error prompts (October 20, 1984)
+@x module 84
+"1","2","3","4","5","6","7","8","9": if deletions_allowed then
+@y
+"0","1","2","3","4","5","6","7","8","9": if deletions_allowed then
+@z
+ Versions 1.3 and 1.4
+
+298. Dirty PASCAL (two quarterword 0's were read as a halfword) (25 Nov 84)
+@x module 846
+print(" -> @@@@"); print_int(serial(prev_break(passive)));
+@y
+print(" -> @@@@");
+if prev_break(passive)=null then print_char("0")
+else print_int(serial(prev_break(passive)));
+@z
+
+299. Ditto! (25 Nov 84)
+@x module 934
+label reswitch, exit, found, not_found;
+@y
+label reswitch, exit, found, not_found, done;
+@z
+@x module 939
+while info(p)>n-3 do {eliminate hyphens \TeX\ doesn't like}
+ begin q:=link(p); free_avail(p); p:=q;
+ end;
+@<Insert the \(p)pair |(s,p)| into the exception table@>;
+@y
+loop@+ begin if p=null then goto done;
+ if info(p)<n-2 then goto done;
+ q:=link(p); free_avail(p); p:=q; {eliminate hyphens that \TeX\ doesn't like}
+ end;
+done: @<Insert the \(p)pair |(s,p)| into the exception table@>;
+@z
+
+300. Major change to memory management (25 Nov 84)
+[The following changes have two main merits: (1) TeX should run faster on
+virtual-memory systems when the jobs are small; (2) it should be possible
+to use the same production version of TeX both for jobs with lots of macros
+and few boxes as well as for jobs with lots of boxes and few macros, because
+the boundary line between the two types of storage is now chosen dynamically.]
+[The user is unaffected, except that there's only one "memory size" overflow
+error now instead of two.]
+[The TRIP test is now changed slightly: The correct settings of memory
+size parameters are now mem_min=mem_bot=1, mem_top=mem_max=3000.]
+
+@x module 11
+@!mem_max=30000; {greatest index in \TeX's internal |mem| array;
+ must be strictly less than |max_halfword|}
+@y
+@!mem_max=30000; {greatest index in \TeX's internal |mem| array;
+ must be strictly less than |max_halfword|;
+ must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|}
+@!mem_min=0; {smallest index in \TeX's internal |mem| array;
+ must be |min_halfword| or more;
+ must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|}
+@z
+@x module 12
+@d mem_base=0 {smallest index in the |mem| array; must not be less
+ than |min_halfword|}
+@d hi_mem_base=13000 {smallest index in the single-word area of |mem|;
+ must be substantially larger than |mem_base| and smaller than |mem_max|}
+@y
+@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX};
+ must not be less than |mem_min|}
+@d mem_top==30000 {largest index in the |mem| array dumped by \.{INITEX};
+ must be substantially larger than |mem_bot|
+ and not greater than |mem_max|}
+@z
+@x module 12
+ about |(mem_max-hi_mem_base)/6|, but 2100 is already quite generous}
+@y
+ about |(mem_max-mem_min)/10|, but 2100 is already quite generous}
+@z
+@x module 14
+if (hi_mem_base<mem_base+100)or(hi_mem_base+100>mem_max) then bad:=4;
+@y
+if mem_bot+1100>mem_top then bad:=4;
+@z
+@x module 111
+if (min_quarterword>0)or(max_quarterword<127) then bad:=11;
+@y
+init if (mem_min<>mem_bot)or(mem_max<>mem_top) then bad:=10;@+tini@;@/
+if (mem_min>mem_bot)or(mem_max<mem_top) then bad:=10;
+if (min_quarterword>0)or(max_quarterword<127) then bad:=11;
+@z
+@x module 111
+if (mem_base<min_halfword)or(mem_max>=max_halfword) then bad:=14;
+@y
+if (mem_min<min_halfword)or(mem_max>=max_halfword) then bad:=14;
+@z
+@x module 115
+value represents a null pointer.
+
+@d pointer==halfword {a flag or a location in |mem| or |eqtb|}
+@d null==mem_base {the null pointer}
+@y
+value represents a null pointer. \TeX\ does not assume that |mem[null]| exists.
+
+@d pointer==halfword {a flag or a location in |mem| or |eqtb|}
+@d null==min_halfword {the null pointer}
+@z
+@x module 116
+@ The |mem| array is divided once and for all into two regions that are
+allocated separately. Locations less than |hi_mem_base| are used for storing
+@y
+@ The |mem| array is divided into two regions that are allocated separately,
+but the dividing line between these two regions is not fixed; they grow
+together until finding their ``natural'' size in a particular job.
+Locations less than or equal to |lo_mem_max| are used for storing
+@z
+@x module 116
+relevant size when a node is freed. The remaining region of |mem| is
+allocated in single words using a conventional \.{AVAIL} stack.
+
+Incidentally, it would be feasible to construct implementations of \TeX\ that
+are based on 16-bit words instead of 32-bit words, for machines having
+comparatively small memories. In such cases it might be desirable to have
+two parallel arrays for the upper part of memory, called say \\{mem\_link}|[p]|
+and \\{mem\_info}|[p]|,
+since the single-word region in the present implementation
+consists entirely of |memory_word| items of type |two_halves|.
+@^small computers@>
+@y
+relevant size when a node is freed. Locations greater than or equal to
+|hi_mem_min| are used for storing one-word records; a conventional
+\.{AVAIL} stack is used for allocation in this region.
+
+Locations of |mem| between |mem_bot| and |mem_top| may be dumped as part
+of preloaded format files, by the \.{INITEX} preprocessor.
+@.INITEX@>
+Production versions of \TeX\ may extend the memory at both ends in order to
+provide more space; locations between |mem_min| and |mem_bot| are always
+used for variable-size nodes, and locations between |mem_top| and |mem_max|
+are always used for single-word nodes.
+
+The key pointers that govern |mem| allocation have a prescribed order:
+$$\hbox{|null<=mem_min<=mem_bot<lo_mem_max<
+ hi_mem_min<mem_top<=mem_end<=mem_max|.}$$
+@z
+@x module 116
+@!mem : array[mem_base..mem_max] of memory_word; {the big dynamic storage area}
+@y
+@!mem : array[mem_min..mem_max] of memory_word; {the big dynamic storage area}
+@!lo_mem_max : pointer; {the largest location of variable-size memory in use}
+@!hi_mem_min : pointer; {the smallest location of one-word memory in use}
+@z
+@x module 117
+@!max_var_used : integer; {how much memory was in use}
+@y
+@z
+@x module 118
+occur between |hi_mem_base| and |mem_end|, inclusive, are of type
+@y
+occur between |hi_mem_min| and |mem_end|, inclusive, are of type
+@z
+@x module 120
+else begin runaway; {if memory is exhausted, display possible runaway text}
+ overflow("macro memory size",mem_max+1-hi_mem_base);
+ {quit; all one-word nodes are busy}
+@:TeX capacity exceeded macro memory size}{\quad macro memory size@>
+ end;
+@y
+else begin decr(hi_mem_min); p:=hi_mem_min;
+ if hi_mem_min<=lo_mem_max then
+ begin runaway; {if memory is exhausted, display possible runaway text}
+ overflow("main memory size",mem_max+1-mem_min);
+ {quit; all one-word nodes are busy}
+@:TeX capacity exceeded main memory size}{\quad main memory size@>
+ end;
+ end;
+@z
+@x module 125
+label found,exit;
+@y
+label found,exit,restart;
+@z
+@x module 125
+begin p:=rover; {start at some free node in the ring}
+@y
+begin restart: p:=rover; {start at some free node in the ring}
+@z
+@x module 125
+overflow("box memory size",hi_mem_base-mem_base);
+ {sorry, nothing satisfactory is left}
+@:TeX capacity exceeded box memory size}{\quad box memory size@>
+found: link(r):=null; {this node is now nonempty}
+@!stat var_used:=var_used+s; {maintain usage statistics}
+if var_used>max_var_used then max_var_used:=var_used;
+@y
+if lo_mem_max+2<hi_mem_min then
+ @<Grow more variable-size memory and |goto restart|@>;
+overflow("main memory size",mem_max+1-mem_min);
+ {sorry, nothing satisfactory is left}
+@:TeX capacity exceeded main memory size}{\quad main memory size@>
+found: link(r):=null; {this node is now nonempty}
+@!stat var_used:=var_used+s; {maintain usage statistics}
+@z
+@x modules 126--127
+@ Empirical tests show that the routine in this section performs a
+|remove_node| operation about 0.75 times per allocation, on the average,
+after which it finds that |r>p+1| about 95\% of the time.
+
+@<Try to allocate...@>=
+q:=p+node_size(p); {find the physical successor}
+@^inner loop@>
+while is_empty(q) do @<Merge node |p| with node |q|@>;
+r:=q-s;
+if r>p+1 then @<Allocate from the top of node |p| and |goto found|@>;
+if r=p then if ((rlink(p)<>rover) or (llink(p)<>rover)) then
+ @<Allocate entire node |p| and |goto found|@>;
+node_size(p):=q-p {reset the size in case it grew}
+
+@ @<Merge node |p| with node |q|@>=
+begin t:=rlink(q);
+@^inner loop@>
+if q=rover then rover:=t;
+llink(t):=llink(q); rlink(llink(q)):=t;@/
+q:=q+node_size(q);
+end
+@y
+@ The lower part of |mem| grows by 1000 words at a time, unless
+we are very close to going under. When it grows, we simply link
+a new node into the available-space list. This method of controlled
+growth helps to keep the |mem| usage consecutive when \TeX\ is
+implemented on ``virtual memory'' systems.
+@^virtual memory@>
+
+@<Grow more variable-size memory and |goto restart|@>=
+begin if lo_mem_max+1000<hi_mem_min then t:=lo_mem_max+1000
+else t:=(lo_mem_max+hi_mem_min+2) div 2; {|lo_mem_max+2<=t<hi_mem_min|}
+p:=llink(rover); q:=lo_mem_max; rlink(p):=q; llink(rover):=q;@/
+rlink(q):=rover; llink(q):=p; link(q):=empty_flag; node_size(q):=t-lo_mem_max;@/
+lo_mem_max:=t; link(lo_mem_max):=null; info(lo_mem_max):=null;
+rover:=q; goto restart;
+end
+
+@ Empirical tests show that the routine in this section performs a
+node-merging operation about 0.75 times per allocation, on the average,
+after which it finds that |r>p+1| about 95\% of the time.
+
+@<Try to allocate...@>=
+q:=p+node_size(p); {find the physical successor}
+@^inner loop@>
+while is_empty(q) do {merge node |p| with node |q|}
+ begin t:=rlink(q);
+ if q=rover then rover:=t;
+ llink(t):=llink(q); rlink(llink(q)):=t;@/
+ q:=q+node_size(q);
+ end;
+r:=q-s;
+if r>p+1 then @<Allocate from the top of node |p| and |goto found|@>;
+if r=p then if ((rlink(p)<>rover) or (llink(p)<>rover)) then
+ @<Allocate entire node |p| and |goto found|@>;
+node_size(p):=q-p {reset the size in case it grew}
+@z
+% module 129 no longer refers to remove_node; I don't recall when it changed!
+@x module 134
+@d is_char_node(#) == (#>hi_mem_base)
+@y
+@d is_char_node(#) == (#>=hi_mem_min)
+@z
+@x module 162
+example, locations |mem_base| to |mem_base+3| are always used to store the
+specification for glue that is `\.{0pt plus 0pt minus 0pt}'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Dynamic allocation of variable-size
+nodes is restricted to locations |first_mem| through |(hi_mem_base-1)|,
+and single-word nodes are dynamically allocated in locations |second_mem|
+through |mem_max|, inclusive. It is harmless to let |lig_trick|, |garbage|,
+and |backup_head| share the same location of |mem|.
+
+@d zero_glue==mem_base {specification for \.{0pt plus 0pt minus 0pt}}
+@y
+example, locations |mem_bot| to |mem_bot+3| are always used to store the
+specification for glue that is `\.{0pt plus 0pt minus 0pt}'. The
+following macro definitions accomplish the static allocation by giving
+symbolic names to the fixed positions. Static variable-size nodes appear
+in locations |mem_bot| through |lo_mem_stat_max|, and static single-word nodes
+appear in locations |hi_mem_stat_min| through |mem_top|, inclusive. It is
+harmless to let |lig_trick|, |garbage|, and |backup_head| share the same
+location of |mem|.
+
+@d zero_glue==mem_bot {specification for \.{0pt plus 0pt minus 0pt}}
+@z
+@x module 162
+@d first_mem==fil_neg_glue+glue_spec_size {first dynamically allocatable word
+ in the variable-size |mem|}
+@#
+@d page_ins_head==hi_mem_base {list of insertion data for current page}
+@d contrib_head==hi_mem_base+1 {vlist of items not yet on current page}
+@d page_head==hi_mem_base+2 {vlist for current page}
+@d temp_head==hi_mem_base+3 {head of a temporary list of some kind}
+@d hold_head==hi_mem_base+4 {head of a temporary list of another kind}
+@d adjust_head==hi_mem_base+5 {head of adjustment list returned by |hpack|}
+@d active==hi_mem_base+6 {head of active list in |line_break|, needs two words}
+@d align_head==hi_mem_base+8 {head of preamble list for alignments}
+@d end_span==hi_mem_base+9 {tail of spanned-width lists}
+@d omit_template==hi_mem_base+10 {a constant token list}
+@d null_list==hi_mem_base+11 {permanently empty list}
+@d lig_trick==hi_mem_base+12 {a ligature masquerading as a |char_node|}
+@d garbage==hi_mem_base+12 {used for scrap information}
+@d backup_head==hi_mem_base+13 {head of token list built by |scan_keyword|}
+@d second_mem==hi_mem_base+14 {first dynamically allocatable word in
+ the one-word |mem|}
+@y
+@d lo_mem_stat_max==fil_neg_glue+glue_spec_size-1 {largest statically
+ allocated word in the variable-size |mem|}
+@#
+@d page_ins_head==mem_top {list of insertion data for current page}
+@d contrib_head==mem_top-1 {vlist of items not yet on current page}
+@d page_head==mem_top-2 {vlist for current page}
+@d temp_head==mem_top-3 {head of a temporary list of some kind}
+@d hold_head==mem_top-4 {head of a temporary list of another kind}
+@d adjust_head==mem_top-5 {head of adjustment list returned by |hpack|}
+@d active==mem_top-6 {head of active list in |line_break|, needs two words}
+@d align_head==mem_top-8 {head of preamble list for alignments}
+@d end_span==mem_top-9 {tail of spanned-width lists}
+@d omit_template==mem_top-10 {a constant token list}
+@d null_list==mem_top-11 {permanently empty list}
+@d lig_trick==mem_top-12 {a ligature masquerading as a |char_node|}
+@d garbage==mem_top-12 {used for scrap information}
+@d backup_head==mem_top-13 {head of token list built by |scan_keyword|}
+@d hi_mem_stat_min==mem_top-13 {smallest statically allocated word in
+ the one-word |mem|}
+@z
+@x module 164
+for k:=mem_base+1 to first_mem-1 do mem[k].sc:=0;
+ {all glue dimensions are zeroed}
+@^data structure assumptions@>
+k:=mem_base;@+while k<first_mem do {set first words of glue specifications}
+@y
+for k:=mem_bot+1 to lo_mem_stat_max do mem[k].sc:=0;
+ {all glue dimensions are zeroed}
+@^data structure assumptions@>
+k:=mem_bot;@+while k<=lo_mem_stat_max do
+ {set first words of glue specifications}
+@z
+@x module 164
+rover:=first_mem; link(rover):=empty_flag; {now initialize the dynamic memory}
+node_size(rover):=hi_mem_base-rover; {which is one big available node}
+llink(rover):=rover; rlink(rover):=rover;@/
+link(hi_mem_base):=null; info(hi_mem_base):=null;
+for k:=hi_mem_base+1 to second_mem-1 do
+ mem[k]:=mem[hi_mem_base];{clear list heads}
+@<Initialize the special list heads and constant nodes@>;
+avail:=null; mem_end:=second_mem-1; {initialize the one-word memory}
+var_used:=first_mem-mem_base; dyn_used:=second_mem-hi_mem_base;
+max_var_used:=var_used; {initialize statistics}
+@y
+rover:=lo_mem_stat_max+1;
+link(rover):=empty_flag; {now initialize the dynamic memory}
+node_size(rover):=1000; {which is a 1000-word available node}
+llink(rover):=rover; rlink(rover):=rover;@/
+lo_mem_max:=rover+1000; link(lo_mem_max):=null; info(lo_mem_max):=null;@/
+for k:=hi_mem_stat_min to mem_top do
+ mem[k]:=mem[lo_mem_max]; {clear list heads}
+@<Initialize the special list heads and constant nodes@>;
+avail:=null; mem_end:=mem_top;
+hi_mem_min:=hi_mem_stat_min; {initialize the one-word memory}
+var_used:=lo_mem_stat_max+1-mem_bot; dyn_used:=mem_top+1-hi_mem_stat_min;
+ {initialize statistics}
+@z
+@x module 165
+@t\hskip1em@>@!was_mem_end: pointer; {previous |mem_end|}
+@y
+@t\hskip1em@>@!was_mem_end,@!was_lo_max,@!was_hi_min: pointer;
+ {previous |mem_end|, |lo_mem_max|,and |hi_mem_min|}
+@z
+@x module 166
+@!debug was_mem_end:=mem_base; {indicate that everything was previously free}
+@y
+@!debug was_mem_end:=mem_min; {indicate that everything was previously free}
+was_lo_max:=mem_min; was_hi_min:=mem_max;
+@z
+@x module 167
+begin for p:=mem_base to mem_end do free[p]:=false; {you can probably
+ do this faster}
+@y
+begin for p:=mem_min to lo_mem_max do free[p]:=false; {you can probably
+ do this faster}
+for p:=hi_mem_min to mem_end do free[p]:=false; {ditto}
+@z
+@x module 167
+for p:=0 to mem_end do was_free[p]:=free[p]; {|was_free:=free| might be faster}
+was_mem_end:=mem_end;
+@y
+for p:=mem_min to lo_mem_max do was_free[p]:=free[p];
+for p:=hi_mem_min to mem_end do was_free[p]:=free[p];
+ {|was_free:=free| might be faster}
+was_mem_end:=mem_end; was_lo_max:=lo_mem_max; was_hi_min:=hi_mem_min;
+@z
+@x module 168
+ begin if (p>mem_end)or(p<second_mem) then clobbered:=true
+@y
+ begin if (p>mem_end)or(p<hi_mem_min) then clobbered:=true
+@z
+@x module 169
+repeat if (p>=hi_mem_base)or(p<first_mem) then clobbered:=true
+ else if (rlink(p)>=hi_mem_base)or(rlink(p)<first_mem) then clobbered:=true
+ else if not(is_empty(p))or(node_size(p)<2)or@|
+ (p+node_size(p)>hi_mem_base)or@| (llink(rlink(p))<>p) then clobbered:=true;
+@y
+repeat if (p>=lo_mem_max)or(p<mem_min) then clobbered:=true
+ else if (rlink(p)>=lo_mem_max)or(rlink(p)<mem_min) then clobbered:=true
+ else if not(is_empty(p))or(node_size(p)<2)or@|
+ (p+node_size(p)>lo_mem_max)or@| (llink(rlink(p))<>p) then clobbered:=true;
+@z
+@x module 170
+p:=mem_base;
+while p<=hi_mem_base do {node |p| should not be empty}
+@y
+p:=mem_min;
+while p<=lo_mem_max do {node |p| should not be empty}
+@z
+@x module 170
+ while (p<=hi_mem_base) and not free[p] do incr(p);
+ while (p<=hi_mem_base) and free[p] do incr(p);
+@y
+ while (p<=lo_mem_max) and not free[p] do incr(p);
+ while (p<=lo_mem_max) and free[p] do incr(p);
+@z
+@x module 171
+for p:=mem_base to mem_end do
+ if not free[p] and ((p>was_mem_end) or was_free[p]) then
+@y
+for p:=mem_min to lo_mem_max do
+ if not free[p] and ((p>was_lo_max) or was_free[p]) then
+ begin print_char(" "); print_int(p);
+ end;
+for p:=hi_mem_min to mem_end do
+ if not free[p] and
+ ((p<was_hi_min) or (p>was_mem_end) or was_free[p]) then
+@z
+@x module 172
+begin for q:=mem_base to mem_end do
+@y
+begin for q:=mem_min to lo_mem_max do
+@z
+@x module 172
+@<Search |eqtb| for equivalents equal to |p|@>;
+@y
+for q:=hi_mem_min to mem_end do
+ begin if link(q)=p then
+ begin print_nl("LINK("); print_int(q); print_char(")");
+ end;
+ if info(q)=p then
+ begin print_nl("INFO("); print_int(q); print_char(")");
+ end;
+ end;
+@<Search |eqtb| for equivalents equal to |p|@>;
+@z
+@x module 176
+if (p<hi_mem_base)or(p>mem_end) then print_esc("CLOBBERED.")
+@y
+if (p<hi_mem_min)or(p>mem_end) then print_esc("CLOBBERED.")
+@z
+@x module 178
+begin if (p<mem_base)or(p>=hi_mem_base) then print_char("*")
+@y
+begin if (p<mem_min)or(p>=lo_mem_max) then print_char("*")
+@z
+@x module 293
+if (p<hi_mem_base) or (p>mem_end) then
+@y
+if (p<hi_mem_min) or (p>mem_end) then
+@z
+@x module 639
+ print_int(dyn_used); print("; max so far: ");
+ print_int(max_var_used); print_char("&");
+ print_int(mem_end+1-hi_mem_base); print_ln;
+@y
+ print_int(dyn_used); print("; still untouched: ");
+ print_int(hi_mem_min-lo_mem_max-1); print_ln;
+@z
+@x module 857
+begin save_link:=link(cur_p); {this is OK even if |cur_p=null|}
+link(cur_p):=null; print_nl(""); short_display(link(printed_node));
+link(cur_p):=save_link; printed_node:=cur_p;
+@y
+begin print_nl("");
+if cur_p=null then short_display(link(printed_node))
+else begin save_link:=link(cur_p);
+ link(cur_p):=null; print_nl(""); short_display(link(printed_node));
+ link(cur_p):=save_link;
+ end;
+printed_node:=cur_p;
+@z
+@x module 1249
+if 2*max_halfword<hi_mem_base-mem_base then bad:=41;
+@y
+if 2*max_halfword<mem_top-mem_min then bad:=41;
+@z
+@x module 1307
+dump_int(hi_mem_base);@/
+@y
+dump_int(mem_bot);@/
+dump_int(mem_top);@/
+@z
+@x module 1308
+if x<>hi_mem_base then goto bad_fmt;
+@y
+if x<>mem_bot then goto bad_fmt;
+undump_int(x);
+if x<>mem_top then goto bad_fmt;
+@z
+@x module 1311
+dump_int(rover);
+p:=mem_base; q:=rover; x:=0;
+@y
+dump_int(lo_mem_max); dump_int(rover);
+p:=mem_bot; q:=rover; x:=0;
+@z
+@x module 1311
+var_used:=var_used+hi_mem_base-p; dyn_used:=mem_end+1-hi_mem_base;@/
+dump_int(mem_end); dump_int(avail);
+for k:=p to mem_end do dump_wd(mem[k]);
+x:=x+mem_end+1-p;
+@y
+var_used:=var_used+lo_mem_max-p; dyn_used:=mem_end+1-hi_mem_min;@/
+for k:=p to lo_mem_max do dump_wd(mem[k]);
+x:=x+lo_mem_max+1-p;
+dump_int(hi_mem_min); dump_int(avail);
+for k:=hi_mem_min to mem_end do dump_wd(mem[k]);
+x:=x+mem_end+1-hi_mem_min;
+@z
+@x module 1312
+undump(min_halfword)(hi_mem_base)(rover);
+p:=mem_base; q:=rover; x:=0;
+repeat for k:=p to q+1 do undump_wd(mem[k]);
+p:=q+node_size(q);
+if (p>hi_mem_base)or((q>=rlink(q))and(rlink(q)<>rover)) then goto bad_fmt;
+q:=rlink(q);
+until q=rover;
+undump_size(hi_mem_base)(mem_max)('mem max')(mem_end);
+undump(null)(mem_end)(avail);
+for k:=p to mem_end do undump_wd(mem[k]);
+undump_int(var_used); undump_int(dyn_used);
+max_var_used:=var_used
+@y
+undump(lo_mem_stat_max+1000)(hi_mem_stat_min-1)(lo_mem_max);
+undump(lo_mem_stat_max+1)(lo_mem_max)(rover);
+p:=mem_bot; q:=rover; x:=0;
+repeat for k:=p to q+1 do undump_wd(mem[k]);
+p:=q+node_size(q);
+if (p>lo_mem_max)or((q>=rlink(q))and(rlink(q)<>rover)) then goto bad_fmt;
+q:=rlink(q);
+until q=rover;
+for k:=p to lo_mem_max do undump_wd(mem[k]);
+if mem_min<mem_bot-2 then {make more low memory available}
+ begin p:=llink(rover); q:=mem_min+1;
+ link(mem_min):=null; info(mem_min):=null; {we don't use the bottom word}
+ rlink(p):=q; llink(rover):=q;@/
+ rlink(q):=rover; llink(q):=p; link(q):=empty_flag;
+ node_size(q):=mem_bot-q;
+ end;
+undump(lo_mem_max+1)(hi_mem_stat_min)(hi_mem_min);
+undump(null)(mem_top)(avail); mem_end:=mem_top;
+for k:=hi_mem_min to mem_end do undump_wd(mem[k]);
+undump_int(var_used); undump_int(dyn_used)
+@z
+@x module 1323
+undump(min_halfword)(hi_mem_base)(font_glue[k]);
+@y
+undump(min_halfword)(lo_mem_max)(font_glue[k]);
+@z
+@x module 1334
+ wlog_ln(' ',max_var_used:1,'&',mem_end+1-hi_mem_base:1,@|
+ ' words of memory out of ',
+ hi_mem_base-mem_base:1,'&',mem_max+1-hi_mem_base:1);@/
+@y
+ wlog_ln(' ',lo_mem_max-mem_min+mem_end-hi_mem_min+2:1,@|
+ ' words of memory out of ',mem_end+1-mem_min:1);@/
+@z that's the end of change number 300!
+
+301. node_size field could overflow if low mem was too large (Dec 20, 1984)
+[This bug existed from the beginning, if hi_mem_base-first_mem>max_halfword!]
+@x module 111
+if (mem_min<min_halfword)or(mem_max>=max_halfword) then bad:=14;
+@y
+if (mem_min<min_halfword)or(mem_max>=max_halfword)or@|
+ (mem_bot-mem_min>max_halfword+1) then bad:=14;
+@z
+@x module 125
+@!t:pointer; {temporary register}
+@y
+@!t:integer; {temporary register}
+@z
+@x module 125
+if lo_mem_max+2<hi_mem_min then
+@y
+if lo_mem_max+2<hi_mem_min then if lo_mem_max+2<=mem_bot+max_halfword then
+@z
+@x module 126
+rlink(q):=rover; llink(q):=p; link(q):=empty_flag; node_size(q):=t-lo_mem_max;@/
+@y
+if t>mem_bot+max_halfword then t:=mem_bot+max_halfword;
+rlink(q):=rover; llink(q):=p; link(q):=empty_flag; node_size(q):=t-lo_mem_max;@/
+@z
+
+302. Improvement to missing-format-file error (DRF, 5 Jan 85)
+@x module 524
+var j:0..buf_size; {the first space after the file name}
+begin if buffer[loc]="&" then
+ begin incr(loc); j:=loc; buffer[last]:=" ";
+ while buffer[j]<>" " do incr(j);
+ pack_buffered_name(0,loc,j-1); {try first without the system file area}
+ if w_open_in(fmt_file) then
+ begin loc:=j; goto found;
+ end;@/
+ pack_buffered_name(format_area_length,loc,j-1);
+ {now try the system format file area}
+ if w_open_in(fmt_file) then
+ begin loc:=j; goto found;
+ end;
+ wake_up_terminal;
+ wterm_ln('Sorry, I can''t find that format;',' will try PLAIN.');
+@.Sorry, I can't find...@>
+ end;
+ {now pull out all the stops: try for the system \.{PLAIN} file}
+pack_buffered_name(format_default_length-format_ext_length,1,0);
+if not w_open_in(fmt_file) then
+ begin wake_up_terminal;
+ wterm_ln('I can''t find the PLAIN format file!');
+@.I can't find PLAIN...@>
+@.PLAIN@>
+ open_fmt_file:=false; return;
+ end;
+found:open_fmt_file:=true;
+@y
+var j:0..buf_size; {the first space after the format file name}
+begin j:=loc;
+if buffer[loc]="&" then
+ begin incr(loc); j:=loc; buffer[last]:=" ";
+ while buffer[j]<>" " do incr(j);
+ pack_buffered_name(0,loc,j-1); {try first without the system file area}
+ if w_open_in(fmt_file) then goto found;
+ pack_buffered_name(format_area_length,loc,j-1);
+ {now try the system format file area}
+ if w_open_in(fmt_file) then goto found;
+ wake_up_terminal;
+ wterm_ln('Sorry, I can''t find that format;',' will try PLAIN.');
+@.Sorry, I can't find...@>
+ update_terminal;
+ end;
+ {now pull out all the stops: try for the system \.{PLAIN} file}
+pack_buffered_name(format_default_length-format_ext_length,1,0);
+if not w_open_in(fmt_file) then
+ begin wake_up_terminal;
+ wterm_ln('I can''t find the PLAIN format file!');
+@.I can't find PLAIN...@>
+@.PLAIN@>
+ open_fmt_file:=false; return;
+ end;
+found:loc:=j; open_fmt_file:=true;
+@z
+
+303. Welcoming message appears sooner (DRF, Jan 7)
+@x module 61
+else begin print(format_ident); print_ln;
+ end;
+@y
+else begin print(format_ident); print_ln;
+ end;
+update_terminal;
+@z
+
+304. Minor change to help message in "confusion" (Jan 23)
+@x module 95
+ help2("One of your earlier faux pas has wounded me deeply,")@/
+ ("so I'm barely conscious. Please fix it and try again.");
+@y
+ help2("One of your faux pas seems to have wounded me deeply...")@/
+ ("in fact, I'm barely conscious. Please fix it and try again.");
+@z
+
+305. Improved logic for `(see the transcript file...)' (Jan 23)
+@x module 245
+if history=spotless then history:=warning_issued;
+if (tracing_online<=0)and(selector=term_and_log) then decr(selector);
+@y
+if (tracing_online<=0)and(selector=term_and_log) then
+ begin decr(selector);
+ if history=spotless then history:=warning_issued;
+ end;
+@z
+
+306. Change 291 violated standard PASCAL (CET1, Feb 18)
+@x module 331
+for first:=0 to buf_size do buffer[first]:=0;
+@y since some procedures `threaten' |first| globally [BS/6192 sec 6.8.3.9]
+first:=buf_size; repeat buffer[first]:=0; decr(first); until first=0;
+@z
+
+307. Nonexistent character could be output via ligature hyphenation (April 11)
+@x module 582 (slight inefficiency removed while correcting this)
+begin if (font_bc[f]<=c)and(font_ec[f]>=c) then
+@y
+begin if font_bc[f]<=c then if font_ec[f]>=c then
+@z
+@x module 892 (likewise)
+@!hu:array[1..63] of ASCII_code; {like |hc|, before conversion to lowercase}
+@y
+@!hu:array[1..63] of ASCII_code; {like |hc|, before conversion to lowercase}
+@!hyf_char:integer; {hyphen character of the relevant font}
+@z
+@x module 896 (likewise)
+done2: if hyphen_char[hf]<0 then goto done1;
+if hyphen_char[hf]>255 then goto done1;
+@y
+done2: hyf_char:=hyphen_char[hf];
+if hyf_char<0 then goto done1;
+if hyf_char>255 then goto done1;
+@z
+@x module 912 and another local variable
+@!c:ASCII_code; {character temporarily replaced by a hyphen}
+@y
+@!c:ASCII_code; {character temporarily replaced by a hyphen}
+@!hyf_node:pointer; {the hyphen, if it exists}
+@z
+@x module 915 (this is the real bugfix)
+minor_tail:=null; c:=hu[i+1]; hu[i+1]:=hyphen_char[hf];
+repeat l:=reconstitute(l+1,i+1);
+if minor_tail=null then pre_break(r):=link(hold_head)
+else link(minor_tail):=link(hold_head);
+minor_tail:=link(hold_head);
+if link(minor_tail)<>null then minor_tail:=link(minor_tail);
+until l>i;
+hu[i+1]:=c; {restore the character in the hyphen position}
+decr(l); hyf[l]:=0
+@y
+minor_tail:=null; hyf_node:=new_character(hf,hyf_char);
+if hyf_node<>null then
+ begin incr(i); c:=hu[i]; hu[i]:=hyf_char;
+ end;
+repeat l:=reconstitute(l+1,i);
+if minor_tail=null then pre_break(r):=link(hold_head)
+else link(minor_tail):=link(hold_head);
+minor_tail:=link(hold_head);
+if link(minor_tail)<>null then minor_tail:=link(minor_tail);
+until l=i;
+if hyf_node<>null then
+ begin hu[i]:=c; {restore the character in the hyphen position}
+ free_avail(hyf_node); decr(i); l:=i;
+ end;
+hyf[i]:=0
+@z
+@x module 918
+begin r:=new_disc; pre_break(r):=new_character(hf,hyphen_char[hf]);
+@y
+begin r:=new_disc; pre_break(r):=new_character(hf,hyf_char);
+@z
+
+308. Improper memory usage computed by INITEX in change 300. (DRF, April 15)
+@x module 162
+@d hi_mem_stat_min==mem_top-13 {smallest statically allocated word in
+ the one-word |mem|}
+@y
+@d hi_mem_stat_min==mem_top-13 {smallest statically allocated word in
+ the one-word |mem|}
+@d hi_mem_stat_usage=14 {the number of one-word nodes always present}
+@z
+@x module 164 (text macro without parentheses strikes again!)
+var_used:=lo_mem_stat_max+1-mem_bot; dyn_used:=mem_top+1-hi_mem_stat_min;
+@y
+var_used:=lo_mem_stat_max+1-mem_bot; dyn_used:=hi_mem_stat_usage;
+@z
+
+309. A faster |flush_list| routine for the inner loop. (DRF, April 16)
+@x module 123
+var q:pointer; {the successor of node |p|}
+begin while p<>null do
+ begin q:=link(p); free_avail(p); p:=q;
+ end;
+@y
+var @!q,@!r:pointer; {list traversers}
+begin if p<>null then
+ begin r:=p;
+ repeat q:=r; r:=link(r); @!stat decr(dyn_used);@+tats@/
+ until r=null; {now |q| is the last node on the list}
+ link(q):=avail; avail:=p;
+ end;
+@z
+
+310. Kern for accent positioning could disappear after a line break (April 17)
+(Change 269 fixed only part of the problem!)
+@x module 155
+@d explicit=1 {|subtype| of kern nodes from \.{\\kern} and \.{\\/} and accents}
+@y
+@d explicit=1 {|subtype| of kern nodes from \.{\\kern} and \.{\\/}}
+@d acc_kern=2 {|subtype| of kern nodes from accents}
+@z
+@x module 191
+if subtype(p)<=explicit then
+ begin print_esc("kern");
+ if subtype(p)=explicit then print_char(" ");
+ print_scaled(width(p));
+@y
+if subtype(p)<>mu_glue then
+ begin print_esc("kern");
+ if subtype(p)<>normal then print_char(" ");
+ print_scaled(width(p));
+ if subtype(p)=acc_kern then print(" (for accent)");
+@.for accent@>
+@z
+@x module 837
+ math_node,kern_node: break_width[1]:=break_width[1]-width(s);
+@y
+ math_node,kern_node: if subtype(s)=acc_kern then goto done
+ else break_width[1]:=break_width[1]-width(s);
+@z
+@x module 879
+ if non_discardable(q) then goto done1;
+@y
+ if non_discardable(q) then goto done1;
+ if subtype(q)=acc_kern then if type(q)=kern_node then goto done1;
+@z
+@x module 1125
+r:=new_kern(delta); subtype(r):=explicit; link(tail):=r; link(r):=p;
+tail:=new_kern(-a-delta); subtype(tail):=explicit; link(p):=tail; p:=q;
+@y
+r:=new_kern(delta); subtype(r):=acc_kern; link(tail):=r; link(r):=p;
+tail:=new_kern(-a-delta); subtype(tail):=acc_kern; link(p):=tail; p:=q;
+@z
+
+311. \lastbox and \unkern must not remove discretionary replacements (April 18)
+(Change 236 introduced this bug!)
+@x module 1079
+label exit;
+var p:pointer; {runs through the current list}
+@y
+label exit, done;
+var @!p,@!q:pointer; {run through the current list}
+@!m:quarterword; {the length of a replacement list}
+@z
+@x modules 1080 and 1081
+ @<Apologize for inability to do \.{\\lastbox} now@>
+else begin if not is_char_node(tail) then
+ if (type(tail)=hlist_node)or(type(tail)=vlist_node) then
+ begin p:=head; cur_box:=tail; shift_amount(cur_box):=0;
+ while link(p)<>tail do p:=link(p);
+ tail:=p; link(p):=null;
+ end;
+ end;
+end
+
+@ @<Apologize for inability to do \.{\\lastbox} now@>=
+begin you_cant;
+help2("Sorry...I'm usually unable to take things from the current")@/
+ ("page. This \lastbox will therefore be void."); error;
+end
+@y
+ begin you_cant;
+ help2("Sorry...I usually can't take things from the current page.")@/
+ ("This \lastbox will therefore be void."); error;
+ end
+else begin if not is_char_node(tail) then
+ if (type(tail)=hlist_node)or(type(tail)=vlist_node) then
+ @<Remove the last box, unless it's part of a discretionary@>;
+ end;
+end
+
+@ @<Remove the last box...@>=
+begin q:=head;
+repeat p:=q;
+if not is_char_node(q) then if type(q)=disc_node then
+ begin for m:=1 to replace_count(q) do p:=link(p);
+ if p=tail then goto done;
+ end;
+q:=link(p);
+until q=tail;
+cur_box:=tail; shift_amount(cur_box):=0;
+tail:=p; link(p):=null;
+done: end
+@z
+@x module 1105
+var p:pointer; {runs through the current list}
+@y
+label exit;
+var @!p,@!q:pointer; {run through the current list}
+@!m:quarterword; {the length of a replacement list}
+@z
+@x module 1105
+ begin p:=head;
+ while link(p)<>tail do p:=link(p);
+ link(p):=null; flush_node_list(tail); tail:=p;
+ end;
+ end;
+end;
+@y
+ begin q:=head;
+ repeat p:=q;
+ if not is_char_node(q) then if type(q)=disc_node then
+ begin for m:=1 to replace_count(q) do p:=link(p);
+ if p=tail then return;
+ end;
+ q:=link(p);
+ until q=tail;
+ link(p):=null; flush_node_list(tail); tail:=p;
+ end;
+ end;
+exit:end;
+@z
+@x module 1106
+ help2("Sorry...I'm usually unable to take things from the current")@/
+ ("page. Try `I\vskip-\lastskip' instead.");
+ if cur_chr=kern_node then help_line[0]:=
+ ("page. Try `I\kern-\lastkern' instead.")
+ else if cur_chr<>glue_node then help_line[0]:=@|
+ ("page. Perhaps you can make the output routine do it.");
+@y
+ help2("Sorry...I usually can't take things from the current page.")@/
+ ("Try `I\vskip-\lastskip' instead.");
+ if cur_chr=kern_node then help_line[0]:=
+ ("Try `I\kern-\lastkern' instead.")
+ else if cur_chr<>glue_node then help_line[0]:=@|
+ ("Perhaps you can make the output routine do it.");
+@z
+@x module 1120
+if n<128 then replace_count(tail):=n
+@y
+if n<=max_quarterword then replace_count(tail):=n
+@z
+
+
+*** Note by DEK, 18 Apr 1985
+(The code for version 1.3 has been published by Addison-Wesley under the
+title "TeX: The Program". It was phototypeset on our APS, but does not
+contain changes > 300. Some of those changes have been made in versions
+of TeX called 1.3; but the exact definition of version 1.3 is somewhat
+vague. Version 1.4 was released on April 18, 1985, after
+making change 311. At present I believe Version 1.4 will be identical
+to Version 2.0 except perhaps for things like index entries in the
+documentation and slightly revised help messages. Version 2.0 will
+coincide with the publication of Volume 1 of Computers and Typesetting,
+which will come out when METAFONT and Computer Modern are both finished.)
+ Version 1.5
+312. if nonstandard area specified, don't try TEX_area too. (DRF, 26 Apr 85)
+@x module 537
+ pack_file_name(cur_name,TEX_area,cur_ext);
+ if a_open_in(cur_file) then goto done;
+@y
+ if cur_area="" then
+ begin pack_file_name(cur_name,TEX_area,cur_ext);
+ if a_open_in(cur_file) then goto done;
+ end;
+@z
+
+313. length of \write need no longer be limited (cf 235). (NBT, 30 Apr 85)
+@x module 1370
+show_token_list(link(def_ref),null,buf_size-10); print_ln;
+@y
+show_token_list(link(def_ref),null,10000000); print_ln;
+@z
+
+314. bug introduced in #300, just lucky it didn't cause trouble (CET1, 8 May 85)
+@x module 162
+@d active==mem_top-6 {head of active list in |line_break|, needs two words}
+@y
+@d active==mem_top-7 {head of active list in |line_break|, needs two words}
+@z
+
+315. Missing eoln after last typeout (Gropp, 11 May 85)
+@x module 1332
+ wterm('Ouch---my internal constants have been',
+@y
+ wterm_ln('Ouch---my internal constants have been',
+@z
+
+316. Redundancy (CET1, 17 May 85)
+[Change 287 was apparently introduced because of a faulty assumption,
+although its change to the calling of "initialize" was valid.]
+@x module 1332
+ begin t_open_out;
+ wterm_ln('Ouch---my internal constants have been',
+ ' clobbered!---case ',bad:1);
+@y
+ begin wterm_ln('Ouch---my internal constants have been clobbered!',
+ '---case ',bad:1);
+@z
+
+317. batchmode to see if log file couldn't be opened (DRF, 22 May 85)
+@x module 92
+if interaction=batch_mode then decr(selector);
+if job_name=0 then open_log_file;
+@y
+if job_name=0 then open_log_file;
+if interaction=batch_mode then decr(selector);
+@z
+
+318. If the string pool overflows while reading the command line... (22 May 85)
+[This bug was first found in METAFONT, when it could occur more easily]
+@x module 525
+begin str_room(name_length);
+for k:=1 to name_length do append_char(xord[name_of_file[k]]);
+make_name_string:=make_string;
+@y
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings) then
+ make_name_string:="?"
+else begin for k:=1 to name_length do append_char(xord[name_of_file[k]]);
+ make_name_string:=make_string;
+ end;
+@z
+
+319. Bug in \edef\foo{\iffalse\fi\the\toks0} (found by Dan Brotsky, 7 Aug 85)
+@x module 478
+ if cur_cmd<>the then goto done2;
+ q:=the_toks;
+ if link(temp_head)<>null then
+ begin link(p):=link(temp_head); p:=q;
+ end;
+@y
+ if cur_cmd<=max_command then goto done2;
+ if cur_cmd<>the then expand
+ else begin q:=the_toks;
+ if link(temp_head)<>null then
+ begin link(p):=link(temp_head); p:=q;
+ end;
+ end;
+@z
+
+*** Version 1.5 was released on August 7, 1985.
+
+320. Lowercase `plain' for consistency with the manual
+@x module 521
+TEX_format_default:='TeXformats:PLAIN.fmt';
+@.TeXformats@>
+@.PLAIN@>
+@y
+TEX_format_default:='TeXformats:plain.fmt';
+@.TeXformats@>
+@.plain@>
+@z (index entries also changed to lowercase in modules 524, 1331)
+
+321. Terminal woken up by \show and \showthe (November 27, 1985)
+@x module 1294
+begin get_token; print_nl("> ");
+@y
+begin get_token;
+if interaction=error_stop_mode then wake_up_terminal;
+print_nl("> ");
+@z
+@x module 1297
+begin p:=the_toks; print_nl("> "); token_show(temp_head);
+@y
+begin p:=the_toks;
+if interaction=error_stop_mode then wake_up_terminal;
+print_nl("> "); token_show(temp_head);
+@z
+ Changes subsequent to `Version 2.0' as published in C&T, Volume B:
+
+322. Trivial change to a help message.
+@x module 1283
+ ("Pretend that you're Hercule Poirot, examine all clues,")@/
+@y
+ ("Pretend that you're Hercule Poirot: Examine all clues,")@/
+@z
+
+323. Precaution since |index| can be as high as |max_in_open|. (DRF)
+@x module 14
+if hash_prime>hash_size then bad:=5;
+@y
+if hash_prime>hash_size then bad:=5;
+if max_in_open>=128 then bad:=6;
+@z
+
+324. \kern clobbered at end of pre-break list in discretionary break.
+@x module 881
+ |disc_break:=true|@>;
+ if not is_char_node(q) then
+ if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0;
+@y
+ |disc_break:=true|@>
+ else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0;
+@z
+
+325. width after discretionary didn't take account of discarded nodes.
+@x module 830 (slight redefinition)
+@!t:quarterword; {replacement count, if |cur_p| is a discretionary node}
+@y
+@!t:integer; {node count, if |cur_p| is a discretionary node}
+@z
+@x module 837 (slight rearrangement)
+if (break_type=unhyphenated)or(cur_p=null) then
+ begin s:=cur_p;
+ while s<>null do
+ begin if is_char_node(s) then goto done;
+ case type(s) of
+ glue_node:@<Subtract glue from |break_width|@>;
+ penalty_node: do_nothing;
+ math_node,kern_node: if subtype(s)=acc_kern then goto done
+ else break_width[1]:=break_width[1]-width(s);
+ othercases goto done
+ endcases;@/
+ s:=link(s);
+ end;
+ end
+else @<Compute the discretionary |break_width| values@>;
+@y
+s:=cur_p;
+if break_type>unhyphenated then if cur_p<>null then
+ @<Compute the discretionary |break_width| values@>;
+while s<>null do
+ begin if is_char_node(s) then goto done;
+ case type(s) of
+ glue_node:@<Subtract glue from |break_width|@>;
+ penalty_node: do_nothing;
+ math_node,kern_node: if subtype(s)=acc_kern then goto done
+ else break_width[1]:=break_width[1]-width(s);
+ othercases goto done
+ endcases;@/
+ s:=link(s);
+ end;
+@z
+@x module 840 (this is the main change to fix the bug)
+begin t:=replace_count(cur_p); s:=cur_p;
+while t>0 do
+ begin decr(t); s:=link(s);
+ @<Subtract the width of node |s| from |break_width|@>;
+ end;
+s:=post_break(cur_p);
+while s<>null do
+ begin @<Add the width of node |s| to |break_width|@>;
+@y
+begin t:=replace_count(cur_p); v:=cur_p; s:=post_break(cur_p);
+while t>0 do
+ begin decr(t); v:=link(v);
+ @<Subtract the width of node |v| from |break_width|@>;
+ end;
+while s<>null do
+ begin @<Add the width of node |s| to |break_width| and increase |t|,
+ unless it's discardable@>;
+@z
+@x module 840, continued
+break_width[1]:=break_width[1]+disc_width;
+@y
+break_width[1]:=break_width[1]+disc_width;
+if t=0 then s:=link(v); {more nodes may also be discardable after the break}
+@z
+@x module 841 (here we just change |s| to |v|)
+@<Subtract the width of node |s|...@>=
+if is_char_node(s) then
+ begin f:=font(s);
+ break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(s)));
+ end
+else case type(s) of
+ ligature_node: begin f:=font(lig_char(s));@/
+ break_width[1]:=@|break_width[1]-
+ char_width(f)(char_info(f)(character(lig_char(s))));
+ end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]-width(s);
+@y
+@<Subtract the width of node |v|...@>=
+if is_char_node(v) then
+ begin f:=font(v);
+ break_width[1]:=break_width[1]-char_width(f)(char_info(f)(character(v)));
+ end
+else case type(v) of
+ ligature_node: begin f:=font(lig_char(v));@/
+ break_width[1]:=@|break_width[1]-
+ char_width(f)(char_info(f)(character(lig_char(v))));
+ end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]-width(v);
+@z
+@x module 842
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]+width(s);
+ othercases confusion("disc2")
+@:this can't happen disc2}{\quad disc2@>
+ endcases
+@y
+ hlist_node,vlist_node,rule_node:break_width[1]:=break_width[1]+width(s);
+ kern_node: if (t=0)and(subtype(s)<>acc_kern) then t:=-1 {discardable}
+ else break_width[1]:=break_width[1]+width(s);
+ othercases confusion("disc2")
+@:this can't happen disc2}{\quad disc2@>
+ endcases;
+incr(t)
+@z
+
+*** Version 2.1 was released on January 26, 1987.
+
+326. Removal of redundant code (found by Pat Monardo, 5 Feb 87)
+@x module 1224 [this change need not be made, since it has no effect]
+ char_def_code: define(p,char_given,cur_val);
+ math_char_def_code: define(p,math_given,cur_val);
+@y the cases cannot occur, so we simply don't list them
+@z
+
+327. More robustness is needed when debugging (Ronaldo Am\'a, 14 Apr 87)
+@x module 174
+begin while p>null do
+@y maybe mem_min>null (but nodes shouldn't be put in location mem_min exactly)
+begin while p>mem_min do
+@z
+@x module 182
+@p procedure show_node_list(@!p:pointer); {prints a node list symbolically}
+@y
+@p procedure show_node_list(@!p:integer); {prints a node list symbolically}
+@z
+@x module 182, continued
+while p>null do
+@y
+while p>mem_min do
+@z
+
+328. Storage allocation can be more elegant and efficient (4/21/87)
+@x module 127
+if r=p then if ((rlink(p)<>rover) or (llink(p)<>rover)) then
+@y
+if r=p then if rlink(p)<>p then
+@z
+
+329. Miscalculation of empty-line condition (April 22, 1987)
+@x module 360
+ begin if limit=start then {previous line was empty}
+@y
+ begin if (end_line_char<0)or(end_line_char>127) then incr(limit);
+ if limit=start then {previous line was empty}
+@z
+
+330. A case where we don't have to assume system bookkeeping (April 28, 1987)
+@x module 560
+done: b_close(tfm_file); read_font_info:=g;
+@y [suggested by Jim Sterken]
+done: if file_opened then b_close(tfm_file);
+read_font_info:=g;
+@z [this was not a bug, according to the comment in module 28]
+
+331. jump_out must fix unfinished output (Found by Klaus Gunterman, 3 Aug 87)
+@x module 593
+doing_leaders:=false; dead_cycles:=0;
+@y
+doing_leaders:=false; dead_cycles:=0; cur_s:=-1;
+@z
+@x module 617
+cur_s:=-1; ensure_dvi_open;
+@y
+ensure_dvi_open;
+@z
+@x module 640
+dvi_out(eop); incr(total_pages);
+@y
+dvi_out(eop); incr(total_pages); cur_s:=-1;
+@z
+@x module 642
+if total_pages=0 then print_nl("No pages of output.")
+@y
+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;
+if total_pages=0 then print_nl("No pages of output.")
+@z
+
+332. \hangindent=1pt$$\halign{...\cr\noalign{\hrule}}$$ problem (19 Aug 87)
+@x module 805
+q:=link(head);
+@y
+q:=link(head); s:=head;
+@z
+@x module 805, continued
+ q:=link(q);
+@y
+ s:=q; q:=link(q);
+@z
+@x module 806
+if is_running(depth(q)) then depth(q):=depth(p);
+@y
+if is_running(depth(q)) then depth(q):=depth(p);
+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;
+@z
+
+333. \hskip 0pt plus 1fil\ifdim problem (found by Alan Guth, 20 Aug 87)
+@x module 366
+@!cvl_backup,@!radix_backup:small_number; {to save |cur_val_level| and |radix|}
+@y
+@!cvl_backup,@!radix_backup,@!co_backup:small_number;
+ {to save |cur_val_level|, etc.}
+@z
+@x
+backup_backup:=link(backup_head);
+@y
+co_backup:=cur_order; backup_backup:=link(backup_head);
+@z
+@x
+link(backup_head):=backup_backup;
+@y
+cur_order:=co_backup; link(backup_head):=backup_backup;
+@z
+
+334. leaders too sensitive near exact multiples (M. F. Bridgland, 9 Nov 87)
+@x module 626
+ begin edge:=cur_h+rule_wd; lx:=0;
+@y
+ begin rule_wd:=rule_wd+10; {compensate for floating-point rounding}
+ edge:=cur_h+rule_wd; lx:=0;
+@z
+@x ibid
+ cur_h:=edge; goto next_p;
+@y
+ cur_h:=edge-10; goto next_p;
+@z
+@x module 635
+ begin edge:=cur_v+rule_ht; lx:=0;
+@y
+ begin rule_ht:=rule_ht+10; {compensate for floating-point rounding}
+ edge:=cur_v+rule_ht; lx:=0;
+@z
+@x ibid
+ cur_v:=edge; goto next_p;
+@y
+ cur_v:=edge-10; goto next_p;
+@z
+
+335. Glitch in fixed-point multiplication of negatives (W.G. Sullivan, 17Nov87)
+@x module 572
+begin alpha:=16*z; beta:=16;
+while z>=@'40000000 do
+ begin z:=z div 2; beta:=beta div 2;
+ end;
+@y
+begin alpha:=16;
+while z>=@'40000000 do
+ begin z:=z div 2; alpha:=alpha+alpha;
+ end;
+beta:=256 div alpha; alpha:=alpha*z;
+@z
+
+336. If there are no \patterns and some \lccode is 1 (Breitenlohner, 12Dec87)
+@x module 952
+trie_link(0):=0; trie_char(0):=0; trie_op(0):=0;
+@y
+trie_link(0):=0; trie_char(0):=0; trie_op(0):=min_quarterword;
+@z
+
+337. \csname might encounter undefined_cs in a group (Chris Thompson, 23Dec87)
+@x module 372
+ begin eqtb[cur_cs]:=eqtb[frozen_relax];
+@y
+ begin eq_define(cur_cs,relax,256);
+@z
+
+338. \outer\def\a0{}\a\a shows temp_head list garbage (Silvio Levy, 20Apr88)
+@x module 391
+repeat if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+else begin match_chr:=info(r)-match_token; s:=link(r); r:=s;
+ p:=temp_head; link(p):=null; m:=0;
+@y
+repeat link(temp_head):=null;
+if (info(r)>match_token+127)or(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;
+@z
+
+339. \def\\#1{}\input a\\\z failed (Robert Messer, 24Apr88)
+@x module 259
+var h:integer; {hash code}
+@y
+var h:integer; {hash code}
+@!d:integer; {number of characters in incomplete current string}
+@z
+@x module 260
+str_room(l);
+for k:=j to j+l-1 do append_char(buffer[k]);
+text(p):=make_string;
+@y
+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;
+@z
+
+340. Make patterns work when trie_min=0 (Peter Breitenlohner, 10May88)
+@x module 951
+trie_max:=128; trie_min:=128; trie_link(0):=1; trie_taken[0]:=false;
+@y
+trie_max:=128; trie_min:=128; trie_link(0):=1; trie_taken[0]:=false;
+trie_link(trie_size):=0; trie_back(0):=trie_size; {wrap around}
+@z
+@x module 953
+begin c:=trie_c[p]; {we have |c>0|}
+if c<trie_min then trie_min:=c;
+z:=trie_link(trie_min-1); {get the first conceivably good hole}
+@y
+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}
+@z
+@x module 966
+r:=0; {finally, we will zero out the holes}
+@y
+r:=trie_size; {finally, we will zero out the holes}
+@z
+
+341. Avoid possible trie_pointer out of range (24May88)
+@x module 923
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=256; {insert delimiters}
+@y
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=128; {insert delimiters}
+@z
+
+342. \input a\romannumeral1 etc.; similar to bug 339. (25May88)
+@x module 464
+@p function str_toks:pointer; {changes the current string to a token list}
+@y
+@p function str_toks(@!b:pool_pointer):pointer;
+ {changes the string |str_pool[b..pool_ptr]| to a token list}
+@z
+@x module 464, continued
+p:=temp_head; link(p):=null; k:=str_start[str_ptr];
+@y
+p:=temp_head; link(p):=null; k:=b;
+@z
+@x module 464, concluded
+pool_ptr:=str_start[str_ptr]; str_toks:=p;
+@y
+pool_ptr:=b; str_toks:=p;
+@z
+@x module 465
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string;
+@y
+@!b:pool_pointer; {base of temporary string}
+begin get_x_token; scan_something_internal(tok_val,false);
+if cur_val_level>=ident_val then @<Copy the token list@>
+else begin old_setting:=selector; selector:=new_string; b:=pool_ptr;
+@z
+@x module 465, continued
+ selector:=old_setting; the_toks:=str_toks;
+@y
+ selector:=old_setting; the_toks:=str_toks(b);
+@z
+@x module 470
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks; ins_list(link(temp_head));
+@y
+@!b:pool_pointer; {base of temporary string}
+begin c:=cur_chr; @<Scan the argument for command |c|@>;
+old_setting:=selector; selector:=new_string; b:=pool_ptr;
+@<Print the result of command |c|@>;
+selector:=old_setting; link(garbage):=str_toks(b); ins_list(link(temp_head));
+@z
+
+343. **\input\romannumeral6 confusion bypassed (25May88)
+@x module 525
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings) then
+@y
+begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings)or
+ (cur_length>0) then
+@z
+
+344. Avoid negative dividend rounding upward (Chris Thompson, fixed 19Jun88)
+@x module 126
+else t:=(lo_mem_max+hi_mem_min+2) div 2; {|lo_mem_max+2<=t<hi_mem_min|}
+@y
+else t:=lo_mem_max+1+(hi_mem_min-lo_mem_max)div 2; {|lo_mem_max+2<=t<hi_mem_min|}
+@z
+
+345. Better strategy when near memory overflow (Chris Thompson)
+@x module 126
+begin if lo_mem_max+1000<hi_mem_min then t:=lo_mem_max+1000
+@y
+begin if hi_mem_min-lo_mem_max>=1998 then t:=lo_mem_max+1000
+@z
+
+346. An omission from change 333 (Tsunetoshi Hayashi, reported 20June88)
+@x module 439
+cur_val:=0; cur_val_level:=int_val; radix:=0;
+@y
+cur_val:=0; cur_val_level:=int_val; radix:=0; cur_order:=0;
+@z
+
+347. Avoid fatal_error after terminal eof (Tim Morgan, reported 25Oct88)
+@x module 71 [serious problem occurred if this was called in open_log_file]
+if not input_ln(term_in,true) then fatal_error("End of file on the terminal!");
+@y
+if not input_ln(term_in,true) then t_open_in;
+@z
+
+348. Force terminal output when open_log_file aborts (6Nov88)
+@x module 535
+ begin print_err("I can't write on file `");
+@y
+ begin selector:=term_only; print_err("I can't write on file `");
+@z
+
+349. By popular request, undo #347 and fix the bug a more complex way.
+@x module 71 [this undoes change #347]
+if not input_ln(term_in,true) then t_open_in;
+@y
+if not input_ln(term_in,true) then fatal_error("End of file on the terminal!");
+@z
+@x module 92 [now we get to the new stuff]
+begin if job_name>0 then selector:=term_and_log
+@y
+begin if log_opened then selector:=term_and_log
+@z
+@x module 93
+ error;
+@y
+ if log_opened then error;
+@z
+@x module 527
+@!job_name:str_number; {principal file name}
+@y
+@!job_name:str_number; {principal file name}
+@!log_opened:boolean; {has the transcript file been opened?}
+@z
+@x module 528
+@<Initialize the output...@>=job_name:=0; name_in_progress:=false;
+@y
+@<Initialize the output...@>=
+job_name:=0; name_in_progress:=false; log_opened:=false;
+@z
+@x module 534
+selector:=log_only;
+@y
+selector:=log_only; log_opened:=true;
+@z
+@x module 535
+begin if interaction<scroll_mode then {bypass |fatal_error|}
+ begin selector:=term_only; print_err("I can't write on file `");
+@.I can't write on file x@>
+ print_file_name(cur_name,cur_area,cur_ext); print("'.");@/
+ job_name:=0; history:=fatal_error_stop; jump_out;
+ end; {abort the program without a log file}
+@y
+begin selector:=term_only;
+@z
+@x module 1265 [this change is optional, but it's a slight improvement]
+if job_name<>0 then selector:=selector+2;
+@y
+if log_opened then selector:=selector+2;
+@z
+@x module 1333
+if job_name>0 then
+@y
+if log_opened then
+@z
+@x module 1334
+if job_name>0 then {the log file is open}
+@y
+if log_opened then
+@z
+
+350. Forgotten update in error recovery (Breitenlohner, 20 Jan 89)
+@x module 976
+ glue_ptr(p):=r;
+@y
+ glue_ptr(p):=r; q:=r;
+@z
+@x module 1004
+ glue_ptr(p):=r;
+@y
+ glue_ptr(p):=r; q:=r;
+@z
+
+351. Avoid error \aftergroup\relax\dump (Mittelbach&Schoepf, 17 Feb 89)
+@x module 280
+begin check_full_save_stack;
+save_type(save_ptr):=insert_token; save_level(save_ptr):=level_zero;
+save_index(save_ptr):=t; incr(save_ptr);
+@y
+begin if cur_level>level_one then
+ begin check_full_save_stack;
+ save_type(save_ptr):=insert_token; save_level(save_ptr):=level_zero;
+ save_index(save_ptr):=t; incr(save_ptr);
+ end;
+@z
+
+352. Cosmetic change to validate comment in 115 (Breitenlohner, 20 Mar 89)
+@x module 791
+begin q:=link(cur_align);
+if (cur_align=null)or(q=null) then confusion("endv");
+@y
+begin if cur_align=null then confusion("endv");
+q:=link(cur_align);@+if q=null then confusion("endv");
+@z
+
+353. $$\begingroup\halign{#\cr}$$ caused confusion (Mittelbach, 7 Jun 89)
+@x module 1130
+mmode+halign: if privileged then init_align;
+@y
+mmode+halign: if privileged then
+ if cur_group=math_shift_group then init_align
+ else off_save;
+@z
+
+354. Conflict in global array dig with .5\ifdim.6 (Mittelbach, 20 Jun 89)
+@x module 450
+@!k:small_number; {number of digits in a decimal fraction}
+@y
+@!k,@!kk:small_number; {number of digits in a decimal fraction}
+@!p,@!q:pointer; {top of decimal digit stack}
+@z
+@x module 452
+begin k:=0; get_token; {|point_token| is being re-scanned}
+loop@+ begin get_x_token;
+ if (cur_tok>zero_token+9)or(cur_tok<zero_token) then goto done1;
+ if k<17 then {digits for |k>=17| cannot affect the result}
+ begin dig[k]:=cur_tok-zero_token; incr(k);
+ end;
+ end;
+done1: f:=round_decimals(k);
+@y
+begin k:=0; p:=null; get_token; {|point_token| is being re-scanned}
+loop@+ begin get_x_token;
+ if (cur_tok>zero_token+9)or(cur_tok<zero_token) then goto done1;
+ if k<17 then {digits for |k>=17| cannot affect the result}
+ begin q:=get_avail; link(q):=p; info(q):=cur_tok-zero_token;
+ p:=q; incr(k);
+ end;
+ end;
+done1: for kk:=k downto 1 do
+ begin dig[kk-1]:=info(p); q:=p; p:=link(p); free_avail(q);
+ end;
+f:=round_decimals(k);
+@z
+
+355. String startup problems (Wayne Sullivan, 17 Jul 89)
+@x module 31 (Warning: This affects most change files!)
+ overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+@y
+ @<Report overflow of the input buffer, and abort@>;
+@z
+@x module 35
+consist of the remainder of the command line, after the part that invoked
+\TeX.
+@y
+consist of the remainder of the command line, after the part that invoked
+\TeX.
+
+The first line is special also because it may be read before \TeX\ has
+input a format file. In such cases, normal error messages cannot yet
+be given. The following code uses concepts that will be explained later.
+
+@<Report overflow of the input buffer, and abort@>=
+if format_ident=0 then
+ begin write_ln(term_out,'Buffer size exceeded!'); goto final_end;
+@.Buffer size exceeded@>
+ end
+else begin cur_input.loc_field:=first; cur_input.limit_field:=last-1;
+ overflow("buffer size",buf_size);
+@:TeX capacity exceeded buffer size}{\quad buffer size@>
+ end
+@z
+@x module 1310
+k:=pool_ptr-4; undump_four_ASCII
+@y
+k:=pool_ptr-4; undump_four_ASCII;
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr
+@z
+@x module 1332
+tini@/
+@y
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr; fix_date_and_time;
+tini@/
+@z
+@x module 1332
+init_str_ptr:=str_ptr; init_pool_ptr:=pool_ptr;@/
+@y
+@z
+
+356. Allow integer products to be 31 bits long (Mittelbach, 16 Aug 89)
+@x module 105
+@p function nx_plus_y(@!n:integer;@!x,@!y:scaled):scaled;
+begin if n<0 then
+ begin negate(x); negate(n);
+ end;
+if n=0 then nx_plus_y:=y
+else if ((x<=(@'7777777777-y) div n)and(-x<=(@'7777777777+y) div n)) then
+ nx_plus_y:=n*x+y
+else begin arith_error:=true; nx_plus_y:=0;
+ end;
+end;
+@y
+@d nx_plus_y(#)==mult_and_add(#,@'7777777777)
+@d mult_integers(#)==mult_and_add(#,0,@'17777777777)
+
+@p function mult_and_add(@!n:integer;@!x,@!y,@!max_answer:scaled):scaled;
+begin if n<0 then
+ begin negate(x); negate(n);
+ end;
+if n=0 then mult_and_add:=y
+else if ((x<=(max_answer-y) div n)and(-x<=(max_answer+y) div n)) then
+ mult_and_add:=n*x+y
+else begin arith_error:=true; mult_and_add:=0;
+ end;
+end;
+@z
+@x module 1240
+ if q=multiply then cur_val:=nx_plus_y(eqtb[l].int,cur_val,0)
+@y
+ if q=multiply then
+ if p=int_val then cur_val:=mult_integers(eqtb[l].int,cur_val)
+ else cur_val:=nx_plus_y(eqtb[l].int,cur_val,0)
+@z
+
+357. Raise the maximum number of tokens normally shown (pointed out by
+John Lavagnino in TeXhax on 19 May 89; corrected on 31 Aug 89).
+@x module 295
+begin if p<>null then show_token_list(link(p),null,1000);
+@y
+begin if p<>null then show_token_list(link(p),null,10000000);
+@z
+@x module 1370 (this part of the change is cosmetic only)
+show_token_list(link(def_ref),null,10000000); print_ln;
+@y
+token_show(def_ref); print_ln;
+@z
+
+358. Like 353, but with $$\begingroup\eqno$$ (Mittelbach, 25 Jul 89)
+@x module 1140
+mmode+eq_no: if privileged then start_eq_no;
+@y
+mmode+eq_no: if privileged then
+ if cur_group=math_shift_group then start_eq_no
+ else off_save;
+@z
+
+359. Major extension to 8-bit character input. (These changes, and a few that
+follow, were discussed during the 10th TUG meeting and installed during
+the week of 10 Sep 1989. They bring the implementation of TeX82 up to date with
+international developments and experience, and I believe they mark the
+final development of this program into a completely stable system.)
+Several changes to the documentation (not the program) are omitted here.
+@x module 18
+@!ASCII_code=0..127; {seven-bit numbers}
+@y
+@!ASCII_code=0..255; {eight-bit numbers}
+@z
+@x module 19
+@d last_text_char=127 {ordinal number of the largest element of |text_char|}
+
+@<Local variables for init...@>=
+@!i:0..last_text_char;
+@y
+@d last_text_char=255 {ordinal number of the largest element of |text_char|}
+
+@<Local variables for init...@>=
+@!i:integer;
+@z
+@x module 21
+xchr[0]:=' '; xchr[@'177]:=' ';
+ {ASCII codes 0 and |@'177| do not appear in text}
+@y
+@z
+@x module 23
+for i:=1 to @'37 do xchr[i]:=' ';
+@y changing ' ' to chr(i) here will allow all 8-bit characters to get in
+for i:=0 to @'37 do xchr[i]:=' ';
+for i:=@'177 to @'377 do xchr[i]:=' ';
+@z
+@x module 24
+for i:=1 to @'176 do xord[xchr[i]]:=i;
+@y
+for i:=@'200 to @'377 do xord[xchr[i]]:=i;
+for i:=0 to @'176 do xord[xchr[i]]:=i;
+@z
+@x module 38
+@<Types...@>=
+@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|}
+@!str_number = 0..max_strings; {for variables that point into |str_start|}
+
+@ @<Glob...@>=
+@!str_pool:packed array[pool_pointer] of ASCII_code; {the characters}
+@y [OK to make si(#)==#-128 and so(#)==#+128 (without parens) in change files]
+Some \PASCAL\ compilers won't pack integers into a single byte unless the
+integers lie in the range |-128..127|. To accommodate such systems
+we access the string pool only via macros that can easily be redefined.
+
+@d si(#) == # {convert from |ASCII_code| to |packed_ASCII_code|}
+@d so(#) == # {convert from |packed_ASCII_code| to |ASCII_code|}
+
+@<Types...@>=
+@!pool_pointer = 0..pool_size; {for variables that point into |str_pool|}
+@!str_number = 0..max_strings; {for variables that point into |str_start|}
+@!packed_ASCII_code = 0..255; {elements of |str_pool| array}
+
+@ @<Glob...@>=
+@!str_pool:packed array[pool_pointer] of packed_ASCII_code; {the characters}
+@z
+@x module 42
+begin str_pool[pool_ptr]:=#; incr(pool_ptr);
+@y
+begin str_pool[pool_ptr]:=si(#); incr(pool_ptr);
+@z
+@x module 45
+ begin if str_pool[j]<>buffer[k] then
+@y
+ begin if so(str_pool[j])<>buffer[k] then
+@z
+@x module 47
+var k,@!l:0..127; {small indices or counters}
+@y
+var k,@!l:0..255; {small indices or counters}
+@z
+@x module 47
+@<Make the first 128 strings@>;
+@y
+@<Make the first 256 strings@>;
+@z
+@x module 48
+@ @<Make the first 128...@>=
+for k:=0 to 127 do
+ begin if (@<Character |k| cannot be printed@>) then
+ begin append_char("^"); append_char("^");
+ if k<@'100 then append_char(k+@'100)
+ else append_char(k-@'100);
+@y
+@ @d app_lc_hex(#)==l:=#;
+ if l<10 then append_char(l+"0)@+else append_char(l-10+"a")
+
+@<Make the first 256...@>=
+for k:=0 to 255 do
+ begin if (@<Character |k| cannot be printed@>) then
+ begin append_char("^"); append_char("^");
+ if k<@'100 then append_char(k+@'100)
+ else if k<@'200 then append_char(k-@'100)
+ else begin app_lc_hex(k div 16); app_lc_hex(k mod 16);
+ end;
+@z
+@x module 59
+ begin print_char(str_pool[j]); incr(j);
+@y
+ begin print_char(so(str_pool[j])); incr(j);
+@z
+@x modules 59 and 60
+else if s<128 then
+@y
+else if s<256 then
+@z
+@x module 60
+ begin print(str_pool[j]); incr(j);
+@y
+ begin print(so(str_pool[j])); incr(j);
+@z
+@x module 63
+if c>=0 then if c<128 then print(c);
+@y
+if c>=0 then if c<256 then print(c);
+@z
+@x module 68
+@ In certain situations, \TeX\ prints either a standard visible ASCII
+character or its hexadecimal ASCII code.
+
+@p procedure print_ASCII(@!c:integer); {prints a character or its code}
+begin if (c>=0) and (c<=127) then print(c)
+else begin print_char("[");
+ if c<0 then print_int(c)@+else print_hex(c);
+ print_char("]");
+ end;
+end;
+@y
+@ Old versions of \TeX\ needed a procedure called |print_ASCII| whose function
+is now subsumed by |print|. We retain the old name here as a possible aid to
+future software arch\ae ologists.
+
+@d print_ASCII == print
+@z
+@x module 69
+ begin print_char(str_pool[j]); n:=n-v;
+ end;
+ if n<=0 then return; {nonpositive input produces no output}
+ k:=j+2; u:=v div (str_pool[k-1]-"0");
+ if str_pool[k-1]="2" then
+ begin k:=k+2; u:=u div (str_pool[k-1]-"0");
+ end;
+ if n+u>=v then
+ begin print_char(str_pool[k]); n:=n+u;
+ end
+ else begin j:=j+2; v:=v div (str_pool[j-1]-"0");
+@y
+ begin print_char(so(str_pool[j])); n:=n-v;
+ end;
+ if n<=0 then return; {nonpositive input produces no output}
+ k:=j+2; u:=v div (so(str_pool[k-1])-"0");
+ if str_pool[k-1]=si("2") then
+ begin k:=k+2; u:=u div (so(str_pool[k-1])-"0");
+ end;
+ if n+u>=v then
+ begin print_char(so(str_pool[k])); n:=n+u;
+ end
+ else begin j:=j+2; v:=v div (so(str_pool[j-1])-"0");
+@z
+@x module 70
+ begin print_char(str_pool[j]); incr(j);
+@y
+ begin print_char(so(str_pool[j])); incr(j);
+@z
+@x module 222
+@d single_base=active_base+128 {equivalents of one-letter control sequences}
+@d null_cs=single_base+128 {equivalent of \.{\\csname\\endcsname}}
+@y
+@d single_base=active_base+256 {equivalents of one-character control sequences}
+@d null_cs=single_base+256 {equivalent of \.{\\csname\\endcsname}}
+@z
+@x module 230
+ {table of 128 command codes (the ``catcodes'')}
+@d lc_code_base=cat_code_base+128 {table of 128 lowercase mappings}
+@d uc_code_base=lc_code_base+128 {table of 128 uppercase mappings}
+@d sf_code_base=uc_code_base+128 {table of 128 spacefactor mappings}
+@d math_code_base=sf_code_base+128 {table of 128 math mode mappings}
+@d int_base=math_code_base+128 {beginning of region 5}
+@y
+ {table of 256 command codes (the ``catcodes'')}
+@d lc_code_base=cat_code_base+256 {table of 256 lowercase mappings}
+@d uc_code_base=lc_code_base+256 {table of 256 uppercase mappings}
+@d sf_code_base=uc_code_base+256 {table of 256 spacefactor mappings}
+@d math_code_base=sf_code_base+256 {table of 256 math mode mappings}
+@d int_base=math_code_base+256 {beginning of region 5}
+@z
+@x module 232
+for k:=0 to 127 do
+@y
+for k:=0 to 255 do
+@z
+@x module 236
+@d del_code_base=count_base+256 {128 delimiter code mappings}
+@d dimen_base=del_code_base+128 {beginning of region 6}
+@y
+@d del_code_base=count_base+256 {256 delimiter code mappings}
+@d dimen_base=del_code_base+256 {beginning of region 6}
+@z
+@x module 240
+for k:=0 to 127 do del_code(k):=-1;
+@y
+for k:=0 to 255 do del_code(k):=-1;
+@z
+@x module 264
+begin if s<128 then cur_val:=s+single_base
+@y
+begin if s<256 then cur_val:=s+single_base
+@z
+@x ibid
+ for j:=0 to l-1 do buffer[j]:=str_pool[k+j];
+@y
+ for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]);
+@z
+@x module 289
+@d cs_token_flag==@'10000 {amount added to the |eqtb| location in a
+ token that stands for a control sequence; is a multiple of~256}
+@y
+@d cs_token_flag==@'7777 {amount added to the |eqtb| location in a
+ token that stands for a control sequence; is a multiple of~256, less~1}
+@z
+@x module 293
+ if (info(p)<0)or(c>127) then print_esc("BAD.")
+@y
+ if info(p)<0 then print_esc("BAD.")
+@z
+@x module 341
+@!cat:0..15; {|cat_code(cur_chr)|, usually}
+@y
+@!cat:0..15; {|cat_code(cur_chr)|, usually}
+@!c,@!cc:ASCII_code; {constituents of a possible expanded code}
+@!d:2..3; {number of excess characters in an expanded code}
+@z
+@x module 352
+@<If this |sup_mark| starts a control character...@>=
+begin if (cur_chr=buffer[loc])and(loc<limit) then
+ begin if buffer[loc+1]<@'100 then cur_chr:=buffer[loc+1]+@'100
+ else cur_chr:=buffer[loc+1]-@'100;
+ loc:=loc+2; goto reswitch;
+ end;
+@y
+@ Notice that a code like \.{\^\^8} becomes \.x if not followed by a hex digit.
+
+@d is_hex(#)==(((#>="0")and(#<="9"))or((#>="a")and(#<="f")))
+@d hex_to_cur_chr==
+ if c<="9" then cur_chr:=c-"0" @+else cur_chr:=c-"a"+10;
+ if cc<="9" then cur_chr:=16*cur_chr+cc-"0"
+ else cur_chr:=16*cur_chr+cc-"a"+10
+
+@<If this |sup_mark| starts an expanded character...@>=
+begin if cur_chr=buffer[loc] then if loc<limit then
+ begin c:=buffer[loc+1]; @+if c<@'200 then {yes we have an expanded char}
+ begin loc:=loc+2;
+ if is_hex(c) then if loc<=limit then
+ begin cc:=buffer[loc]; @+if is_hex(cc) then
+ begin incr(loc); hex_to_cur_chr; goto reswitch;
+ end;
+ end;
+ if c<@'100 then cur_chr:=c+@'100 @+else cur_chr:=c-@'100;
+ goto reswitch;
+ end;
+ end;
+@z
+@x module 355
+ begin cur_chr:=buffer[k+1];
+ if cur_chr<@'100 then buffer[k-1]:=cur_chr+@'100
+ else buffer[k-1]:=cur_chr-@'100;
+ limit:=limit-2; first:=first-2;
+ while k<=limit do
+ begin buffer[k]:=buffer[k+2]; incr(k);
+ end;
+ goto start_cs;
+ end;
+@y
+begin c:=buffer[k+1]; @+if c<@'200 then {yes, one is indeed present}
+ begin d:=2;
+ if is_hex(c) then @+if k+2<=limit then
+ begin cc:=buffer[k+2]; @+if is_hex(cc) then incr(d);
+ end;
+ if d>2 then
+ begin hex_to_cur_chr; buffer[k-1]:=cur_chr;
+ end
+ else if c<@'100 then buffer[k-1]:=c+@'100
+ else buffer[k-1]:=c-@'100;
+ limit:=limit-d; first:=first-d;
+ while k<=limit do
+ begin buffer[k]:=buffer[k+d]; incr(k);
+ end;
+ goto start_cs;
+ end;
+ end;
+@z
+@x module 360
+There is one more branch.
+@y
+There is one more branch.
+
+@d end_line_char_inactive == (end_line_char<0)or(end_line_char>255)
+@z
+@x ibid
+ if (end_line_char<0)or(end_line_char>127) then decr(limit)
+@y
+ if end_line_char_inactive then decr(limit)
+@z
+@x modules 362 and 483 and 538 and 1337
+if (end_line_char<0)or(end_line_char>127) then decr(limit)
+@y
+if end_line_char_inactive then decr(limit)
+@z
+@x module 391
+if (info(r)>match_token+127)or(info(r)<match_token) then s:=null
+@y
+if (info(r)>match_token+255)or(info(r)<match_token) then s:=null
+@z
+@x module 407
+ ((cur_chr=str_pool[k])or(cur_chr=str_pool[k]-"a"+"A")) then
+@y
+ ((cur_chr=so(str_pool[k]))or(cur_chr=so(str_pool[k])-"a"+"A")) then
+@z
+@x module 414
+begin scan_seven_bit_int;
+@y
+begin scan_char_num;
+@z
+@x module 432
+|scan_something_internal|:
+
+@<Declare procedures that scan restricted classes of integers@>=
+procedure scan_seven_bit_int;
+begin scan_int;
+if (cur_val<0)or(cur_val>127) then
+ begin print_err("Bad character code");
+@.Bad character code@>
+ help2("The numeric code for a character must be between 0 and 127.")@/
+ ("I changed this one to zero."); int_error(cur_val); cur_val:=0;
+ end;
+end;
+@y
+|scan_something_internal|.
+@z (and I'll interchange modules 434 and 435)
+@x module 442
+if cur_val>127 then
+@y
+if cur_val>255 then
+@z
+@x module 464
+ begin t:=str_pool[k];
+@y
+ begin t:=so(str_pool[k]);
+@z
+@x module 506 (correction needed twice)
+if (cur_cmd>active_char)or(cur_chr>127) then
+@y
+if (cur_cmd>active_char)or(cur_chr>255) then
+@z
+@x module 519
+for j:=str_start[a] to str_start[a+1]-1 do append_to_name(str_pool[j]);
+for j:=str_start[n] to str_start[n+1]-1 do append_to_name(str_pool[j]);
+for j:=str_start[e] to str_start[e+1]-1 do append_to_name(str_pool[j]);
+@y
+for j:=str_start[a] to str_start[a+1]-1 do append_to_name(so(str_pool[j]));
+for j:=str_start[n] to str_start[n+1]-1 do append_to_name(so(str_pool[j]));
+for j:=str_start[e] to str_start[e+1]-1 do append_to_name(so(str_pool[j]));
+@z
+@x module 526
+if (cur_cmd>active_char)or(cur_chr>127) then
+@y
+if (cur_cmd>active_char)or(cur_chr>255) then
+@z
+@x module 603 (change to be made twice)
+ dvi_out(str_pool[k]);
+@y
+ dvi_out(so(str_pool[k]));
+@z
+@x module 617
+ for s:=str_start[str_ptr] to pool_ptr-1 do dvi_out(str_pool[s]);
+@y
+ for s:=str_start[str_ptr] to pool_ptr-1 do dvi_out(so(str_pool[s]));
+@z
+@x module 766
+ begin case str_pool[r_type*8+t+magic_offset] of
+@y
+ begin case so(str_pool[r_type*8+t+magic_offset]) of
+@z
+@x module 780
+@d span_code=128 {distinct from any character}
+@d cr_code=129 {distinct from |span_code| and from any character}
+@y
+@d span_code=256 {distinct from any character}
+@d cr_code=257 {distinct from |span_code| and from any character}
+@z
+@x module 815
+label done,done1,done2,done3,done4;
+@y
+label done,done1,done2,done3,done4,continue;
+@z
+@x module 896
+ else if (type(s)=kern_node)and(subtype(s)=normal) then c:=128
+ else if type(s)=whatsit_node then c:=128
+ else goto done1;
+ if c<128 then if lc_code(c)<>0 then
+ if (lc_code(c)=c)or(uc_hyph>0) then goto done2
+ else goto done1;
+ s:=link(s);
+@y
+ else if (type(s)=kern_node)and(subtype(s)=normal) then goto continue
+ else if type(s)=whatsit_node then goto continue
+ else goto done1;
+ if lc_code(c)<>0 then
+ if (lc_code(c)=c)or(uc_hyph>0) then goto done2
+ else goto done1;
+continue: s:=link(s);
+@z
+@x module 897
+ if c>=128 then goto done3;
+ if (lc_code(c)=0)or(hn=63) then goto done3;
+ hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c)-1;
+@y
+ if lc_code(c)=0 then goto done3;
+ if hn=63 then goto done3;
+ hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c);
+@z
+@x module 898
+if c>=128 then goto done3;
+if (lc_code(c)=0)or(j=63) then goto done3;
+incr(j); hu[j]:=c; hc[j]:=lc_code(c)-1;@/
+@y
+if lc_code(c)=0 then goto done3;
+if j=63 then goto done3;
+incr(j); hu[j]:=c; hc[j]:=lc_code(c);@/
+@z
+@x module 923
+hc[0]:=127; hc[hn+1]:=127; hc[hn+2]:=128; {insert delimiters}
+@y
+hc[0]:=0; hc[hn+1]:=0; hc[hn+2]:=256; {insert delimiters}
+@z
+@x ibid
+ while hc[l]=trie_char(z) do
+@y
+ while hc[l]=qo(trie_char(z)) do
+@z
+@x module 931
+ repeat if str_pool[u]<hc[j] then goto not_found;
+ if str_pool[u]>hc[j] then goto done;
+@y
+ repeat if so(str_pool[u])<hc[j] then goto not_found;
+ if so(str_pool[u])>hc[j] then goto done;
+@z
+@x module 937
+else begin if (cur_chr>127)or(lc_code(cur_chr)=0) then
+@y
+else begin if lc_code(cur_chr)=0 then
+@z
+@x ibid
+ begin incr(n); hc[n]:=lc_code(cur_chr)-1;
+@y
+ begin incr(n); hc[n]:=lc_code(cur_chr);
+@z
+@x module 945
+@!init @!trie_c:packed array[trie_pointer] of ASCII_code; {characters to match}
+@y
+@!init @!trie_c:packed array[trie_pointer] of packed_ASCII_code;
+ {characters to match}
+@z
+% In modules 951--954, change "127" to "255" and "128" to "256"
+@x module 952
+trie_link(0):=0; trie_char(0):=0; trie_op(0):=min_quarterword;
+@y
+trie_link(0):=0; trie_char(0):=min_quarterword; trie_op(0):=min_quarterword;
+@z
+@x module 953
+begin c:=trie_c[p];
+@y
+begin c:=so(trie_c[p]);
+@z
+@x module 955
+ begin if trie_link(h+trie_c[q])=0 then goto not_found;
+@y
+ begin if trie_link(h+so(trie_c[q]))=0 then goto not_found;
+@z
+@x module 956
+repeat z:=h+trie_c[q]; trie_back(trie_link(z)):=trie_back(z);
+@y
+repeat z:=h+so(trie_c[q]); trie_back(trie_link(z)):=trie_back(z);
+@z
+@x module 959
+ begin q:=trie_l[p]; c:=trie_c[p];
+ trie_link(z+c):=trie_ref[q]; trie_char(z+c):=c; trie_op(z+c):=trie_o[p];
+@y
+ begin q:=trie_l[p]; c:=so(trie_c[p]);
+ trie_link(z+c):=trie_ref[q]; trie_char(z+c):=qi(c); trie_op(z+c):=trie_o[p];
+@z
+@x module 962
+ begin if cur_chr="." then cur_chr:=128 {edge-of-word delimiter}
+ else begin cur_chr:=lc_code(cur_chr);
+ if cur_chr=0 then
+ begin print_err("Nonletter");
+@.Nonletter@>
+ help1("(See Appendix H.)"); error; cur_chr:=128;
+ end;
+ end;
+ if k<63 then
+ begin incr(k); hc[k]:=cur_chr-1; hyf[k]:=0; digit_sensed:=false;
+ end;
+ end
+else begin hyf[k]:=cur_chr-"0";
+ if k<63 then digit_sensed:=true;
+ end
+@y
+ begin if cur_chr="." then cur_chr:=0 {edge-of-word delimiter}
+ else begin cur_chr:=lc_code(cur_chr);
+ if cur_chr=0 then
+ begin print_err("Nonletter");
+@.Nonletter@>
+ help1("(See Appendix H.)"); error;
+ end;
+ end;
+ if k<63 then
+ begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digit_sensed:=false;
+ end;
+ end
+ else if k<63 then
+ begin hyf[k]:=cur_chr-"0"; digit_sensed:=true;
+ end;
+ end
+@z
+@x module 963
+ while (p>0)and(c>trie_c[p]) do
+@y
+ while (p>0)and(c>so(trie_c[p])) do
+@z
+@x ibid
+ if (p=0)or(c<trie_c[p]) then
+@y
+ if (p=0)or(c<so(trie_c[p])) then
+@z
+@x module 964
+trie_c[p]:=c; trie_o[p]:=min_quarterword;
+@y
+trie_c[p]:=si(c); trie_o[p]:=min_quarterword;
+@z
+@x module 965
+if hc[1]=127 then hyf[0]:=0;
+if hc[k]=127 then hyf[k]:=0;
+@y
+if hc[1]=0 then hyf[0]:=0;
+if hc[k]=0 then hyf[k]:=0;
+@z
+@x module 966
+h.rh:=0; h.b0:=min_quarterword; h.b1:=0; {|trie_link:=0|,
+ |trie_op:=min_quarterword|, |trie_char:=0|}
+@y
+h.rh:=0; h.b0:=min_quarterword; h.b1:=min_quarterword; {|trie_link:=0|,
+ |trie_op:=min_quarterword|, |trie_char:=qi(0)|}
+@z
+@x module 1034
+if c<128 then
+@y
+@z
+@x ibid
+else space_factor:=1000
+@y
+@z
+@x module 1151
+letter,other_char,char_given: if cur_chr>=128 then c:=cur_chr
+ else begin c:=ho(math_code(cur_chr));
+@y
+letter,other_char,char_given: begin c:=ho(math_code(cur_chr));
+@z
+@x module 1154
+mmode+letter,mmode+other_char,mmode+char_given: if cur_chr<128 then
+ set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr);
+mmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ if cur_chr<128 then set_math_char(ho(math_code(cur_chr)))
+ else set_math_char(cur_chr);
+@y
+mmode+letter,mmode+other_char,mmode+char_given:
+ set_math_char(ho(math_code(cur_chr)));
+mmode+char_num: begin scan_char_num; cur_chr:=cur_val;
+ set_math_char(ho(math_code(cur_chr)));
+@z
+@x module 1232
+ p:=cur_chr; scan_seven_bit_int; p:=p+cur_val; scan_optional_equals;
+@y
+ p:=cur_chr; scan_char_num; p:=p+cur_val; scan_optional_equals;
+@z
+@x module 1233
+else n:=127
+@y
+else n:=255
+@z
+@x module 1289
+ begin if t>=cs_token_flag then t:=t-active_base;
+ c:=t mod 256;
+ if c<128 then if equiv(b+c)<>0 then t:=256*(t div 256)+equiv(b+c);
+ if t>=cs_token_flag then info(p):=t+active_base
+ else info(p):=t;
+@y
+ begin c:=t mod 256;
+ if equiv(b+c)<>0 then info(p):=t-c+equiv(b+c);
+@z
+@x module 1309
+ w.b0:=str_pool[k]; w.b1:=str_pool[k+1];
+ w.b2:=str_pool[k+2]; w.b3:=str_pool[k+3];
+@y [often qi(so(x))=x, but not e.g. when "quarterwords" are two bytes]
+ w.b0:=qi(so(str_pool[k])); w.b1:=qi(so(str_pool[k+1]));
+ w.b2:=qi(so(str_pool[k+2])); w.b3:=qi(so(str_pool[k+3]));
+@z
+@x module 1310
+ str_pool[k]:=w.b0; str_pool[k+1]:=w.b1;
+ str_pool[k+2]:=w.b2; str_pool[k+3]:=w.b3
+@y
+ str_pool[k]:=si(qo(w.b0)); str_pool[k+1]:=si(qo(w.b1));
+ str_pool[k+2]:=si(qo(w.b2)); str_pool[k+3]:=si(qo(w.b3))
+@z
+@x module 1368
+for k:=str_start[str_ptr] to pool_ptr-1 do dvi_out(str_pool[k]);
+@y
+for k:=str_start[str_ptr] to pool_ptr-1 do dvi_out(so(str_pool[k]));
+@z
+
+360. Major change to allow multiple hyphenation tables.
+I've combined this with the code for a minor change:
+361. New parameters \lefthyphenmin and \righthyphenmin.
+@x module 11 (affects most change files!)
+@!trie_size=8000; {space for hyphenation patterns; should be larger for
+ \.{INITEX} than it is in production versions of \TeX}
+@y
+@!trie_size=8000; {space for hyphenation patterns; should be larger for
+ \.{INITEX} than it is in production versions of \TeX}
+@!trie_op_size=500; {space for ``opcodes'' in the hyphenation patterns}
+@z
+@x module 212
+known as |space_factor|; it holds the current space factor used in spacing
+calculations. In math mode, |aux| is also known as |incompleat_noad|; if
+@y
+known as |space_factor| and |clang|; it holds the current space factor used in
+spacing calculations, and the current language used for hyphenation.
+(The value of |clang| is undefined in restricted horizontal mode.)
+In math mode, |aux| is also known as |incompleat_noad|; if
+@z
+@x ibid
+ @!pg_field,@!aux_field,@!ml_field: integer;
+@y
+ @!pg_field,@!ml_field: integer;
+ @!aux_field: memory_word;
+@z
+@x module 213
+@d prev_depth==aux {the name of |aux| in vertical mode}
+@d space_factor==aux {the name of |aux| in horizontal mode}
+@d incompleat_noad==aux {the name of |aux| in math mode}
+@y
+@d prev_depth==aux.sc {the name of |aux| in vertical mode}
+@d space_factor==aux.hh.lh {part of |aux| in horizontal mode}
+@d clang==aux.hh.rh {the other part of |aux| in horizontal mode}
+@d incompleat_noad==aux.int {the name of |aux| in math mode}
+@z
+@x module 218
+@!a:integer; {auxiliary}
+@y
+@!a:memory_word; {auxiliary}
+@z
+@x module 219
+ if a<=ignore_depth then print("ignored")
+ else print_scaled(a);
+ if nest[p].pg_field<>0 then
+ begin print(", prevgraf ");
+ print_int(nest[p].pg_field); print(" line");
+ if nest[p].pg_field<>1 then print_char("s");
+ end;
+ end;
+1: begin print_nl("spacefactor "); print_int(a);
+ end;
+2: if a<>null then
+ begin print("this will be denominator of:"); show_box(a);
+@y
+ if a.sc<=ignore_depth then print("ignored")
+ else print_scaled(a.sc);
+ if nest[p].pg_field<>0 then
+ begin print(", prevgraf ");
+ print_int(nest[p].pg_field); print(" line");
+ if nest[p].pg_field<>1 then print_char("s");
+ end;
+ end;
+1: begin print_nl("spacefactor "); print_int(a.hh.lh);
+ if m>0 then if a.hh.rh>0 then
+ begin print(", current language "); print_int(a.hh.rh);
+ end;
+ end;
+2: if a.int<>null then
+ begin print("this will be denominator of:"); show_box(a.int);
+@z
+@x modules 236--238
+@d int_pars=50 {total number of integer parameters}
+@y
+@d language_code=50 {current hyphenation table}
+@d left_hyphen_min_code=51 {minimum left hyphenation fragment size}
+@d right_hyphen_min_code=52 {minimum right hyphenation fragment size}
+@d int_pars=53 {total number of integer parameters}
+@z and define/print these new parameters appropriately (mimicking new_line_char)
+@x module 418
+else begin cur_val:=aux;
+ if m=vmode then cur_val_level:=dimen_val@+else cur_val_level:=int_val;
+ end
+@y
+else if m=vmode then
+ begin cur_val:=prev_depth; cur_val_level:=dimen_val;
+ end
+else begin cur_val:=space_factor; cur_val_level:=int_val;
+ end
+@z
+@x module 775
+ begin mode:=-vmode; prev_depth:=nest[nest_ptr-2].aux_field;
+@y
+ begin mode:=-vmode; prev_depth:=nest[nest_ptr-2].aux_field.sc;
+@z
+@x module 786
+begin push_nest; mode:=(-hmode-vmode)-mode; aux:=0;
+@y
+begin push_nest; mode:=(-hmode-vmode)-mode;
+if mode=-hmode then space_factor:=0 @+else prev_depth:=0;
+@z
+@x module 863
+loop@+ begin @<Create an active breakpoint representing the beginning of
+ the paragraph@>;
+@y
+loop@+ begin if threshold>inf_bad then threshold:=inf_bad;
+ if second_pass then @<Initialize for hyphenating a paragraph@>;
+ @<Create an active breakpoint representing the beginning of the paragraph@>;
+@z
+@x module 891
+passes on only about 5 per cent of the paragraphs.
+@y
+passes on only about 5 per cent of the paragraphs.
+
+@<Initialize for hyphenating...@>=
+begin @!init if trie_not_ready then init_trie; @+tini@;@/
+l_hyf:=left_hyphen_min-1;@+if l_hyf<0 then l_hyf:=0;
+r_hyf:=right_hyphen_min-1;@+if r_hyf<0 then r_hyf:=0;
+min_hyf:=l_hyf+r_hyf+2; cur_lang:=0;
+end
+@z
+@x module 892
+@!hyf_char:integer; {hyphen character of the relevant font}
+@y
+@!hyf_char:integer; {hyphen character of the relevant font}
+@!cur_lang:ASCII_code; {current hyphenation table of interest}
+@!l_hyf,@!r_hyf,@!min_hyf:integer; {limits on fragment sizes}
+@z
+@x module 894
+begin s:=link(cur_p);
+@y
+begin if min_hyf>63 then goto done1;
+s:=link(cur_p);
+@z
+@x module 896
+ else if type(s)=whatsit_node then goto continue
+@y
+ else if type(s)=whatsit_node then
+ begin @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>;
+ goto continue;
+ end
+@z
+@x module 899 (title of this module also changes appropriately)
+if hn<5 then goto done1;
+@y
+if hn<min_hyf then goto done1;
+@z
+@x module 902
+for j:=2 to hn-3 do if odd(hyf[j]) then goto found1;
+@y
+for j:=l_hyf+1 to hn-r_hyf-1 do if odd(hyf[j]) then goto found1;
+@z
+@x module 920
+$p_1\ldots p_k$ by setting |@t$z_1$@>:=@t$p_1$@>| and then, for |1<i<=k|,
+@y
+$p_1\ldots p_k$ by letting $z_0$ be one greater than the relevant language index
+and then, for |1<=i<=k|,
+@z
+@x ibid
+the letters in |hc[(l-k+1)..l@,]|, we perform all of the required operations
+for this pattern by carrying out the following little program: Set
+|v:=trie_op(@t$z_k$@>)|. Then set |hyf[l-hyf_distance[v]]:=@tmax@>(
+hyf[l-hyf_distance[v]], hyf_num[v])|, and |v:=hyf_next[v]|; repeat, if
+necessary, until |v=min_quarterword|.
+@y
+the letters in |hc[(l-k+1)..l@,]| of language |t|,
+we perform all of the required operations
+for this pattern by carrying out the following little program: Set
+|v:=trie_op(@t$z_k$@>)|. Then set |v:=v+op_start[t]|,
+|hyf[l-hyf_distance[v]]:=@tmax@>(hyf[l-hyf_distance[v]], hyf_num[v])|,
+and |v:=hyf_next[v]|; repeat, if necessary, until |v=min_quarterword|.
+@z
+@x module 921
+@!hyf_distance:array[quarterword] of small_number; {position |k-j| of $n_j$}
+@!hyf_num:array[quarterword] of small_number; {value of $n_j$}
+@!hyf_next:array[quarterword] of quarterword; {continuation of this |trie_op|}
+@y
+@!hyf_distance:array[1..trie_op_size] of small_number; {position |k-j| of $n_j$}
+@!hyf_num:array[1..trie_op_size] of small_number; {value of $n_j$}
+@!hyf_next:array[1..trie_op_size] of quarterword; {continuation code}
+@!op_start:array[ASCII_code] of 0..trie_op_size; {offset for current language}
+@z
+@x module 922
+@!v:quarterword; {an index into |hyf_distance|, etc.}
+@y
+@!v:integer; {an index into |hyf_distance|, etc.}
+@z
+@x module 923
+for j:=0 to hn-2 do
+ begin z:=hc[j]; l:=j;
+@y
+if trie_char(cur_lang+1)<>qi(cur_lang) then return; {no patterns for |cur_lang|}
+for j:=0 to hn-r_hyf do
+ begin z:=trie_link(cur_lang+1)+hc[j]; l:=j;
+@z
+@x ibid
+found: hyf[1]:=0; hyf[hn-2]:=0; hyf[hn-1]:=0; hyf[hn]:=0
+@y
+found: for j:=0 to l_hyf do hyf[j]:=0;
+for j:=0 to r_hyf do hyf[hn-j]:=0
+@z
+@x module 924
+repeat i:=l-hyf_distance[v];
+@y
+repeat v:=v+op_start[cur_lang]; i:=l-hyf_distance[v];
+@z
+@x module 930
+h:=hc[1];
+@y
+h:=hc[1]; incr(hn); hc[hn]:=cur_lang;
+@z
+@x ibid
+not_found:
+@y
+not_found: decr(hn)
+@z
+@x module 931
+ goto found;
+@y
+ decr(hn); goto found;
+@z
+@x module 934
+@p procedure new_hyph_exceptions; {enters new exceptions}
+label reswitch, exit, found, not_found, done;
+@y
+@d set_cur_lang==if language<=0 then cur_lang:=0
+ else if language>255 then cur_lang:=0
+ else cur_lang:=language
+
+@p procedure new_hyph_exceptions; {enters new exceptions}
+label reswitch, exit, found, not_found;
+@z
+@x ibid
+begin scan_left_brace; {a left brace must follow \.{\\hyphenation}}
+@y
+begin scan_left_brace; {a left brace must follow \.{\\hyphenation}}
+set_cur_lang;
+@z
+@x module 935
+ spacer,right_brace: begin if n>4 then @<Enter a hyphenation exception@>;
+@y
+ spacer,right_brace: begin if n>1 then @<Enter a hyphenation exception@>;
+@z
+@x module 938
+begin if n>1 then
+@y
+begin if n<63 then
+@z
+@x module 939
+begin str_room(n); h:=0;
+@y
+begin incr(n); hc[n]:=cur_lang; str_room(n); h:=0;
+@z
+@x ibid
+loop@+ begin if p=null then goto done;
+ if info(p)<n-2 then goto done;
+ q:=link(p); free_avail(p); p:=q; {eliminate hyphens that \TeX\ doesn't like}
+ end;
+done: @<Insert the \(p)pair |(s,p)| into the exception table@>;
+@y
+@<Insert the \(p)pair |(s,p)| into the exception table@>;
+@z
+@x module 942
+@p@!init @<Declare procedures for preprocessing hyphenation patterns@>@;
+@y
+@<Declare subprocedures for |line_break|@>=
+@!init @<Declare procedures for preprocessing hyphenation patterns@>@;
+@z
+@x module 943
+@d quarterword_diff=max_quarterword-min_quarterword
+@d trie_op_hash_size=quarterword_diff+quarterword_diff {double}
+
+@<Glob...@>=
+@!init@! trie_op_hash:array[0..trie_op_hash_size] of quarterword;
+ {trie op codes for triples}
+tini@;@/
+@t\hskip1em@>@!trie_op_ptr:quarterword; {highest |trie_op| assigned}
+@y
+@<Glob...@>=
+@!init@! trie_op_hash:array[-trie_op_size..trie_op_size] of 0..trie_op_size;
+ {trie op codes for quadruples}
+@!trie_used:array[ASCII_code] of quarterword;
+ {largest opcode used so far for this language}
+@!trie_op_lang:array[1..trie_op_size] of ASCII_code;
+ {language part of a hashed quadruple}
+@!trie_op_val:array[1..trie_op_size] of quarterword;
+ {opcode corresponding to a hashed quadruple}
+@!trie_op_ptr:0..trie_op_size; {number of stored ops so far}
+tini
+@z
+@x module 944 should be entirely replaced
+@y by the following code:
+@ It's tempting to remove the |overflow| stops in the following procedure;
+|new_trie_op| could return |min_quarterword| (thereby simply ignoring
+part of a hyphenation pattern) instead of aborting the job. However, that would
+lead to different hyphenation results on different installations of \TeX\
+using the same patterns. The |overflow| stops are necessary for portability
+of patterns.
+
+@<Declare procedures for preprocessing hyph...@>=
+function new_trie_op(@!d,@!n:small_number;@!v:quarterword):quarterword;
+label exit;
+var h:-trie_op_size..trie_op_size; {trial hash location}
+@!u:quarterword; {trial op code}
+@!l:0..trie_op_size; {pointer to stored data}
+begin h:=abs(n+313*d+361*v+1009*cur_lang) mod (trie_op_size+trie_op_size)
+ - trie_op_size;
+loop@+ begin l:=trie_op_hash[h];
+ if l=0 then {empty position found for a new op}
+ begin if trie_op_ptr=trie_op_size then
+ overflow("pattern memory ops",trie_op_size);
+ u:=trie_used[cur_lang];
+ if u=max_quarterword then
+ overflow("pattern memory ops per language",
+ max_quarterword-min_quarterword);
+ incr(trie_op_ptr); incr(u); trie_used[cur_lang]:=u;
+ hyf_distance[trie_op_ptr]:=d;
+ hyf_num[trie_op_ptr]:=n; hyf_next[trie_op_ptr]:=v;
+ trie_op_lang[trie_op_ptr]:=cur_lang; trie_op_hash[h]:=trie_op_ptr;
+ trie_op_val[trie_op_ptr]:=u; new_trie_op:=u; return;
+ end;
+ if (hyf_distance[l]=d)and(hyf_num[l]=n)and(hyf_next[l]=v)
+ and(trie_op_lang[l]=cur_lang) then
+ begin new_trie_op:=trie_op_val[l]; return;
+ end;
+ if h>-trie_op_size then decr(h)@+else h:=trie_op_size;
+ end;
+exit:end;
+@z
+@x module 945: move the code from this module into 946, and introduce new code:
+@y
+@ After |new_trie_op| has compressed the necessary opcode information,
+plenty of information is available to unscramble the data into the
+final form needed by our hyphenation algorithm.
+
+@<Sort the hyphenation op tables into proper order@>=
+op_start[0]:=-min_quarterword;
+for j:=1 to 255 do op_start[j]:=op_start[j-1]+qo(trie_used[j-1]);
+for j:=1 to trie_op_ptr do
+ trie_op_hash[j]:=op_start[trie_op_lang[j]]+trie_op_val[j]; {destination}
+for j:=1 to trie_op_ptr do while trie_op_hash[j]>j do
+ begin k:=trie_op_hash[j];@/
+ t:=hyf_distance[k]; hyf_distance[k]:=hyf_distance[j]; hyf_distance[j]:=t;@/
+ t:=hyf_num[k]; hyf_num[k]:=hyf_num[j]; hyf_num[j]:=t;@/
+ t:=hyf_next[k]; hyf_next[k]:=hyf_next[j]; hyf_next[j]:=t;@/
+ trie_op_hash[j]:=trie_op_hash[k]; trie_op_hash[k]:=k;
+ end
+@z
+@x module 949: Move this code to just after the new module 945!
+mentioned so far, let's write a procedure that does the initialization.
+
+@<Declare procedures for preprocessing hyph...@>=
+procedure init_pattern_memory; {gets ready to build a linked trie}
+var h:0..trie_op_hash_size; {an index into |trie_op_hash|}
+@!p:trie_pointer; {an index into |trie_hash|}
+begin for h:=0 to trie_op_hash_size do trie_op_hash[h]:=min_quarterword;
+trie_op_ptr:=min_quarterword; trie_root:=0; trie_c[0]:=0; trie_ptr:=0;
+for p:=0 to trie_size do trie_hash[p]:=0;
+end;
+@y
+mentioned so far, let's write down the code that gets them started.
+
+@<Initialize table entries...@>=
+for k:=-trie_op_size to trie_op_size do trie_op_hash[k]:=0;
+for k:=0 to 255 do trie_used[k]:=min_quarterword;
+trie_op_ptr:=0;
+@z
+@x module 950
+@t\hskip1em@>@!trie_min:trie_pointer;
+ {all locations |<=trie_min| are vacant in |trie|}
+tini@;@/
+@t\hskip1em@>@!trie_max:trie_pointer; {largest location used in |trie|}
+@y
+@t\hskip10pt@>@!trie_min:array[ASCII_code] of trie_pointer;
+ {the first possible slot for each character}
+@t\hskip10pt@>@!trie_max:trie_pointer; {largest location used in |trie|}
+@t\hskip10pt@>@!trie_not_ready:boolean; {is the trie still in linked form?}
+tini
+@z
+@x modules 951 and 952
+@ Here is how these data structures are initialized.
+
+@<Declare procedures for preprocessing hyph...@>=
+procedure init_trie_memory; {gets ready to pack into |trie|}
+var p:trie_pointer; {index into |trie_ref|, |trie|, |trie_taken|}
+begin for p:=0 to trie_ptr do trie_ref[p]:=0;
+trie_max:=256; trie_min:=256; trie_link(0):=1; trie_taken[0]:=false;
+trie_link(trie_size):=0; trie_back(0):=trie_size; {wrap around}
+for p:=1 to 256 do
+ begin trie_back(p):=p-1; trie_link(p):=p+1; trie_taken[p]:=false;
+ end;
+end;
+
+@ Each time \.{\\patterns} appears, it overrides any patterns that were
+entered earlier, so the arrays are not initialized until \TeX\ sees
+\.{\\patterns}. However, some of the global variables must be
+initialized when \.{INITEX} is loaded, in case the user never mentions
+any \.{\\patterns}.
+
+@<Initialize table entries...@>=
+trie_op_ptr:=min_quarterword;@/
+trie_link(0):=0; trie_char(0):=min_quarterword; trie_op(0):=min_quarterword;
+for k:=1 to 255 do trie[k]:=trie[0];
+trie_max:=255;
+@y
+@ Each time \.{\\patterns} appears, it contributes further patterns to
+the future trie, which will be built only when hyphenation is attempted or
+when a format file is dumped. The boolean variable |trie_not_ready|
+will change to |false| when the trie is compressed; this will disable
+further patterns.
+
+@<Initialize table entries...@>=
+trie_not_ready:=true; trie_root:=0; trie_c[0]:=si(0); trie_ptr:=0;
+
+@ Here is how the trie-compression data structures are initialized.
+If storage is tight, it would be possible to overlap |trie_op_hash|,
+|trie_op_lang|, and |trie_op_val| with |trie|, |trie_hash|, and |trie_taken|,
+because we finish with the former just before we need the latter.
+
+@<Get ready to compress the trie@>=
+@<Sort the hyphenation...@>;
+for p:=0 to trie_size do trie_hash[p]:=0;
+trie_root:=compress_trie(trie_root); {identify equivalent subtries}
+for p:=0 to trie_ptr do trie_ref[p]:=0;
+for p:=0 to 255 do trie_min[p]:=p+1;
+trie_link(0):=1; trie_max:=0
+@z
+@x module 953
+begin c:=so(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}
+loop@+ begin if z<c then goto not_found;
+ h:=z-c;@/
+@y
+@!l,@!r:trie_pointer; {left and right neighbors}
+@!ll:1..256; {upper limit of |trie_min| updating}
+begin c:=so(trie_c[p]);
+z:=trie_min[c]; {get the first conceivably good hole}
+loop@+ begin h:=z-c;@/
+@z
+@x module 956
+repeat z:=h+so(trie_c[q]); trie_back(trie_link(z)):=trie_back(z);
+trie_link(trie_back(z)):=trie_link(z); trie_link(z):=0; q:=trie_r[q];
+@y
+repeat z:=h+so(trie_c[q]); l:=trie_back(z); r:=trie_link(z);
+trie_back(r):=l; trie_link(l):=r; trie_link(z):=0;
+if l<256 then
+ begin if z<256 then ll:=z @+else ll:=256;
+ repeat trie_min[l]:=r; incr(l);
+ until l=ll;
+ end;
+q:=trie_r[q];
+@z
+@x module 958 is entirely replaced
+@y by the following new code:
+@ When the whole trie has been allocated into the sequential table, we
+must go through it once again so that |trie| contains the correct
+information. Null pointers in the linked trie will be represented by the
+value~0, which properly implements an ``empty'' family.
+
+@<Move the data into |trie|@>=
+h.rh:=0; h.b0:=min_quarterword; h.b1:=min_quarterword; {|trie_link:=0|,
+ |trie_op:=min_quarterword|, |trie_char:=qi(0)|}
+if trie_root=0 then {no patterns were given}
+ begin for r:=0 to 256 do trie[r]:=h;
+ trie_max:=256;
+ end
+else begin trie_fix(trie_root); {this fixes the non-holes in |trie|}
+ r:=0; {now we will zero out all the holes}
+ repeat s:=trie_link(r); trie[r]:=h; r:=s;
+ until r>trie_max;
+ end;
+trie_char(0):=qi("?"); {make |trie_char(c)<>c| for all |c|}
+@z
+@x module 960
+@!r,@!s:trie_pointer; {used to clean up the packed |trie|}
+@!h:two_halves; {template used to zero out |trie|'s holes}
+begin scan_left_brace; {a left brace must follow \.{\\patterns}}
+init_pattern_memory;@/
+@<Enter all of the patterns into a linked trie, until coming to a right
+ brace@>;
+trie_root:=compress_trie(trie_root); {compress the trie}
+@<Pack the trie@>;
+end;
+@y
+begin if trie_not_ready then
+ begin set_cur_lang; scan_left_brace; {a left brace must follow \.{\\patterns}}
+ @<Enter all of the patterns into a linked trie, until coming to a right
+ brace@>;
+ end
+else begin print_err("Too late for "); print_esc("patterns");
+ help1("All patterns must be given before typesetting begins.");
+ error; link(garbage):=scan_toks(false,false); flush_list(def_ref);
+ end;
+end;
+@z
+@x module 963
+q:=0;
+while l<k do
+ begin incr(l); c:=hc[l]; p:=trie_l[q]; first_child:=true;
+@y
+q:=0; hc[0]:=cur_lang;
+while l<=k do
+ begin c:=hc[l]; incr(l); p:=trie_l[q]; first_child:=true;
+@z
+@x module 966 now says that the first call ``takes'' location 1,
+@y and the Pascal code in this module is entirely replaced by the following:
+@<Declare procedures for preprocessing hyphenation patterns@>=
+procedure init_trie;
+var @!p:trie_pointer; {pointer for initialization}
+@!j,@!k,@!t:integer; {all-purpose registers for initialization}
+@!r,@!s:trie_pointer; {used to clean up the packed |trie|}
+@!h:two_halves; {template used to zero out |trie|'s holes}
+begin @<Get ready to compress the trie@>;
+if trie_root<>0 then
+ begin first_fit(trie_root); trie_pack(trie_root);
+ end;
+@<Move the data into |trie|@>;
+trie_not_ready:=false;
+end;
+@z
+@x module 1033 gets new code before main_loop_1
+@y
+if mode>0 then if language<>clang then fix_language;
+@z
+@x modules 1091 and 1200
+push_nest; mode:=hmode; space_factor:=1000;
+@y
+push_nest; mode:=hmode; space_factor:=1000; clang:=0;
+@z
+@x module 1324
+for k:=0 to trie_max do dump_hh(trie[k]);
+dump_int(trie_op_ptr);
+for k:=min_quarterword+1 to trie_op_ptr do
+ begin dump_int(hyf_distance[k]);
+ dump_int(hyf_num[k]);
+ dump_int(hyf_next[k]);
+ end;
+print_ln; print_int(hyph_count); print(" hyphenation exception");
+if hyph_count<>1 then print_char("s");
+print_nl("Hyphenation trie of length "); print_int(trie_max);
+@.Hyphenation trie...@>
+print(" has "); print_int(qo(trie_op_ptr)); print(" op");
+if trie_op_ptr<>min_quarterword+1 then print_char("s")
+@y
+print_ln; print_int(hyph_count); print(" hyphenation exception");
+if hyph_count<>1 then print_char("s");
+if trie_not_ready then init_trie;
+dump_int(trie_max);
+for k:=0 to trie_max do dump_hh(trie[k]);
+dump_int(trie_op_ptr);
+for k:=1 to trie_op_ptr do
+ begin dump_int(hyf_distance[k]);
+ dump_int(hyf_num[k]);
+ dump_int(hyf_next[k]);
+ end;
+print_nl("Hyphenation trie of length "); print_int(trie_max);
+@.Hyphenation trie...@>
+print(" has "); print_int(trie_op_ptr); print(" op");
+if trie_op_ptr<>1 then print_char("s");
+print(" out of "); print_int(trie_op_size);
+for k:=255 downto 0 do if trie_used[k]>min_quarterword then
+ begin print_nl(" "); print_int(qo(trie_used[k]));
+ print(" for language "); print_int(k);
+ dump_int(k); dump_int(qo(trie_used[k]));
+ end
+@z
+@x module 1325
+undump_size(0)(trie_size)('trie size')(trie_max);
+for k:=0 to trie_max do undump_hh(trie[k]);
+undump(min_quarterword)(max_quarterword)(trie_op_ptr);
+for k:=min_quarterword+1 to trie_op_ptr do
+ begin undump(0)(63)(hyf_distance[k]); {a |small_number|}
+ undump(0)(63)(hyf_num[k]);
+ undump(min_quarterword)(max_quarterword)(hyf_next[k]);
+ end
+@y
+undump_size(0)(trie_size)('trie size')(j); {|trie_max|}
+for k:=0 to j do undump_hh(trie[k]);
+undump_size(0)(trie_op_size)('trie op size')(j); {|trie_op_ptr|}
+for k:=1 to j do
+ begin undump(0)(63)(hyf_distance[k]); {a |small_number|}
+ undump(0)(63)(hyf_num[k]);
+ undump(min_quarterword)(max_quarterword)(hyf_next[k]);
+ end;
+k:=256;
+while j>0 do
+ begin undump(0)(k-1)(k); undump(1)(j)(x); j:=j-x; op_start[k]:=qo(j);
+ end;
+@!init trie_not_ready:=false @+tini
+@z
+@x module 1341 gets two new definitions
+@y
+@d language_node=4 {|subtype| in whatsits that change the current language}
+@d stored_language(#)==mem[#+1].int {language number, in the range |0..255|}
+@z
+@x module 1344 gets a new definition and a new Pascal statement
+@y
+@d set_language_code=5 {command modifier for \.{\\setlanguage}}
+primitive("setlanguage",extension,set_language_code);@/
+@!@:set_language_}{\.{\\setlanguage} primitive@>
+@z
+@x module 1346 gets a new case
+@y
+ set_language_code:print_esc("setlanguage");
+@z
+@x module 1348 gets a new case
+@y
+set_language_code:@<Implement \.{\\setlanguage}@>;
+@z
+@x module 1356 gets a new case
+@y
+language_node:begin print_esc("setlanguage");
+ print_int(stored_language(p));
+ end;
+@z
+% in modules 1357 and 1358, change "close_node" to "close_node,language_node".
+@x module 1362 becomes two modules
+@ @<Advance \(p)past a whatsit node in the |line_break| loop@>=do_nothing
+@y
+@ @<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=
+if subtype(cur_p)=language_node then cur_lang:=stored_language(cur_p)
+
+@ @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>=
+if subtype(s)=language_node then cur_lang:=stored_language(s)
+@z and old module 1367 is moved to just before the old module 1378
+@x module 1373 gets a new case
+@y
+language_node:do_nothing;
+@z
+@x new modules before the system-dependent changes (i.e. before the old 1376)
+@y
+@ @<Implement \.{\\setlanguage}@>=
+if abs(mode)<>hmode then report_illegal_case
+else begin new_whatsit(language_node,small_node_size);
+ scan_int;
+ if cur_val<=0 then clang:=0
+ else if cur_val>255 then clang:=0
+ else clang:=cur_val;
+ stored_language(tail):=clang;
+ end
+
+@ Finally, we need a subroutine that comes into play when a character of
+a non-|clang| language is being appended to the current paragraph.
+
+@<Declare action...@>=
+procedure fix_language;
+var @!l:ASCII_code; {the new current language}
+begin if language<=0 then l:=0
+else if language>255 then l:=0
+else l:=language;
+if l<>clang then
+ begin new_whatsit(language_node,small_node_size);
+ stored_language(tail):=l; clang:=l;
+ end;
+end;
+@z
+
+362. Major extension to ligature capability.
+@x module 143
+a linked list of character nodes for those characters.
+@y
+a linked list of character nodes for all original characters that have been
+deleted. (This list might be empty if the characters that generated the
+ligature were retained in other nodes.)
+
+The |subtype| field is 0, plus 2 and/or 1 if the original source of the
+ligature included implicit left and/or right boundaries.
+@z
+@x in module 144 add the following procedure to the existing code
+@y
+function new_lig_item(@!c:quarterword):pointer;
+var p:pointer; {the new node}
+begin p:=get_node(small_node_size); character(p):=c; lig_ptr(p):=null;
+new_lig_item:=p;
+end;
+@z
+@x module 193
+font_in_short_display:=font(lig_char(p));
+short_display(lig_ptr(p)); print_char(")");
+@y
+if subtype(p)>1 then print_char("|");
+font_in_short_display:=font(lig_char(p)); short_display(lig_ptr(p));
+if odd(subtype(p)) then print_char("|");
+print_char(")");
+end
+@z
+@x modules 208 and 209
+@d radical=65 {square root and similar signs ( \.{\\radical} )}
+@y
+@d no_boundary=65 {suppress boundary ligatures ( \.{\\noboundary} )}
+@d radical=66 {square root and similar signs ( \.{\\radical} )}
+@z and so on, adding 1 to each definition until getting to max_command=100
+@x module 265 gets a new statement
+@y
+primitive("noboundary",no_boundary,0);@/
+@!@:no_boundary_}{\.{\\noboundary} primitive@>
+@z
+@x module 266 gets a new case
+@y
+no_boundary:print_esc("noboundary");
+@z
+@x module 545 is entirely replaced
+@y by the following new specifications:
+@ The |lig_kern| array contains instructions in a simple programming language
+that explains what to do for special letter pairs. Each word in this array is a
+|@!lig_kern_command| of four bytes.
+
+\yskip\hang first byte: |skip_byte|, indicates that this is the final program
+ step if the byte is 128 or more, otherwise the next step is obtained by
+ skipping this number of intervening steps.\par
+\hang second byte: |next_char|, ``if |next_char| follows the current character,
+ then perform the operation and stop, otherwise continue.''\par
+\hang third byte: |op_byte|, indicates a ligature step if less than~128,
+ a kern step otherwise.\par
+\hang fourth byte: |remainder|.\par
+\yskip\noindent
+In a kern step, an
+additional space equal to |kern[256*(op_byte-128)+remainder]| is inserted
+between the current character and |next_char|. This amount is
+often negative, so that the characters are brought closer together
+by kerning; but it might be positive.
+
+There are eight kinds of ligature steps, having |op_byte| codes $4a+2b+c$ where
+$0\le a\le b+c$ and $0\le b,c\le1$. The character whose code is
+|remainder| is inserted between the current character and |next_char|;
+then the current character is deleted if $b=0$, and |next_char| is
+deleted if $c=0$; then we pass over $a$~characters to reach the next
+current character (which may have a ligature/kerning program of its own).
+
+If the very first instruction of the |lig_kern| array has |skip_byte=255|,
+the |next_char| byte is the so-called right boundary character of this font;
+the value of |next_char| need not lie between |bc| and~|ec|.
+If the very last instruction of the |lig_kern| array has |skip_byte=255|,
+there is a special ligature/kerning program for a left boundary character,
+beginning at location |256*op_byte+remainder|.
+The interpretation is that \TeX\ puts implicit boundary characters
+before and after each consecutive string of characters from the same font.
+These implicit characters do not appear in the output, but they can affect
+ligatures and kerning.
+
+If the very first instruction of a character's |lig_kern| program has
+|skip_byte>128|, the program actually begins in location
+|256*op_byte+remainder|. This feature allows access to large |lig_kern|
+arrays, because the first instruction must otherwise
+appear in a location |<=255|.
+
+Any instruction with |skip_byte>128| in the |lig_kern| array must have
+|256*op_byte+remainder<nl|. If such an instruction is encountered during
+normal program execution, it denotes an unconditional halt; no ligature
+command is performed.
+
+@d stop_flag=qi(128) {value indicating `\.{STOP}' in a lig/kern program}
+@d kern_flag=qi(128) {op code for a kern step}
+@d skip_byte(#)==#.b0
+@d next_char(#)==#.b1
+@d op_byte(#)==#.b2
+@d rem_byte(#)==#.b3
+@z
+@x module 549
+@<Glob...@>=
+@y
+@d non_char==qi(256) {a |halfword| code that can't match a real character}
+@d non_address==font_mem_size {a spurious |font_index|}
+
+@<Glob...@>=
+@z
+@x module 548 gets a new type definition
+@y
+@!font_index=0..font_mem_size;
+@z
+@x module 549
+ {current \.{\\skewchar} values}
+@y
+ {current \.{\\skewchar} values}
+@!bchar_label:array[internal_font_number] of font_index;
+ {start of |lig_kern| program for left boundary character,
+ |non_address| if there is none}
+@!font_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {right boundary character, |non_char| if there is none}
+@!font_false_bchar:array[internal_font_number] of min_quarterword..non_char;
+ {|font_bchar| if it doesn't exist in the font, otherwise |non_char|}
+@z
+@x module 557
+@d char_kern_end(#)==rem_byte(#)].sc
+@y NOTE: Optimize kern_base_offset in your change file! It's a constant.
+@d char_kern_end(#)==256*op_byte(#)+rem_byte(#)].sc
+@d kern_base_offset==256*(kern_flag)
+@d lig_kern_restart_end(#)==256*op_byte(#)+rem_byte(#)+32768-kern_base_offset
+@d lig_kern_restart(#)==lig_kern_base[#]+lig_kern_restart_end
+@z
+@x module 560
+@!z:scaled; {the design size or the ``at'' size}
+@y
+@!bch_label:integer; {left boundary start location, or infinity}
+@!bchar:0..256; {right boundary character, or 256}
+@!z:scaled; {the design size or the ``at'' size}
+@z
+@x module 566
+kern_base[f]:=lig_kern_base[f]+nl;
+exten_base[f]:=kern_base[f]+nk;
+@y
+kern_base[f]:=lig_kern_base[f]+nl-kern_base_offset;
+exten_base[f]:=kern_base[f]+kern_base_offset+nk;
+@z
+@x module 573: The entire module is replaced
+@y by the following code.
+@ @d check_existence(#)==@t@>@;@/
+ begin check_byte_range(#);
+ qw:=char_info(f)(#); {N.B.: not |qi(#)|}
+ if not char_exists(qw) then abort;
+ end
+
+@<Read ligature/kern program@>=
+bch_label:=@'77777; bchar:=256;
+if nl>0 then
+ begin for k:=lig_kern_base[f] to kern_base[f]+kern_base_offset-1 do
+ begin store_four_quarters(font_info[k].qqqq);
+ if a>128 then
+ begin if 256*c+d>=nl then abort;
+ if a=255 then if k=lig_kern_base[f] then bchar:=b;
+ end
+ else begin if b<>bchar then check_existence(b);
+ if c<128 then check_existence(d) {check ligature}
+ else if 256*(c-128)+d>=nk then abort; {check kern}
+ if a<128 then if k-lig_kern_base[f]+a+1>=nl then abort;
+ end;
+ end;
+ if a=255 then bch_label:=256*c+d;
+ end;
+for k:=kern_base[f]+kern_base_offset to exten_base[f]-1 do
+ store_scaled(font_info[k].sc);
+@z
+@x module 574 (actually a bugfix)
+ if a<>0 then check_byte_range(a);
+ if b<>0 then check_byte_range(b);
+ if c<>0 then check_byte_range(c);
+ check_byte_range(d);
+@y
+ if a<>0 then check_existence(a);
+ if b<>0 then check_existence(b);
+ if c<>0 then check_existence(c);
+ check_existence(d);
+@z
+@x module 576
+font_name[f]:=nom;
+@y
+if bch_label<nl then bchar_label[f]:=bch_label+lig_kern_base[f]
+else bchar_label[f]:=non_address;
+font_bchar[f]:=qi(bchar);
+font_false_bchar[f]:=qi(bchar);
+if bchar<=ec then if bchar>=bc then
+ begin qw:=char_info(f)(bchar); {N.B.: not |qi(bchar)|}
+ if char_exists(qw) then font_false_bchar[f]:=non_char;
+ end;
+font_name[f]:=nom;
+@z
+@x module 708 (slight but optional optimization)
+continue: if (qo(y)>=font_bc[g])and(qo(y)<=font_ec[g]) then
+ begin q:=char_info(g)(y);
+@y
+if (qo(y)>=font_bc[g])and(qo(y)<=font_ec[g]) then
+ begin continue: q:=char_info(g)(y);
+@z
+@x module 740 (another bugfix)
+ i:=char_info(f)(y);
+@y
+ i:=char_info(f)(y);
+ if not char_exists(i) then goto done;
+@z
+@x module 741
+ repeat cur_i:=font_info[a].qqqq;
+ if qo(next_char(cur_i))=skew_char[cur_f] then
+ begin if op_bit(cur_i)>=kern_flag then
+ s:=char_kern(cur_f)(cur_i);
+ goto done1;
+ end;
+ incr(a);
+ until stop_bit(cur_i)>=stop_flag;
+@y
+ cur_i:=font_info[a].qqqq;
+ if skip_byte(cur_i)>stop_flag then
+ begin a:=256*(qo(op_byte(cur_i)))+rem_byte(cur_i);
+ cur_i:=font_info[a].qqqq;
+ end;
+ loop begin if qo(next_char(cur_i))=skew_char[cur_f] then
+ begin if op_byte(cur_i)>=kern_flag then
+ if skip_byte(cur_i)<=stop_flag then s:=char_kern(cur_f)(cur_i);
+ goto done1;
+ end;
+ if skip_byte(cur_i)>=stop_flag then goto done1
+ else a:=a+qo(skip_byte(cur_i))+1;
+ cur_i:=font_info[a].qqqq;
+ end;
+@z
+@x module 749 (yet another bugfix of the same type!)
+@!p,@!v,@!x,@!y,@!z:pointer; {temporary registers for box construction}
+@y
+@!p,@!v,@!x,@!y,@!z:pointer; {temporary registers for box construction}
+@!c:quarterword;@+@!i:four_quarters; {registers for character examination}
+@z
+@x ibid
+ begin cur_c:=rem_byte(cur_i); character(nucleus(q)):=cur_c;
+ cur_i:=char_info(cur_f)(cur_c);
+@y
+ begin c:=rem_byte(cur_i); i:=char_info(cur_f)(c);
+ if char_exists(i) then
+ begin cur_c:=c; cur_i:=i; character(nucleus(q)):=c;
+ end;
+@z
+@x module 752
+@!p:pointer; {temporary register for list manipulation}
+@y
+@!p,@!r:pointer; {temporary registers for list manipulation}
+@z
+@x ibid
+ repeat cur_i:=font_info[a].qqqq;@/
+ @<If instruction |cur_i| is a kern with |cur_c|,
+ attach the kern after |q| and |return|;
+ or if it is a ligature with |cur_c|, combine
+ noads |q| and |p| and |goto restart|@>;
+ incr(a);
+ until stop_bit(cur_i)>=stop_flag;
+@y
+ cur_i:=font_info[a].qqqq;
+ if skip_byte(cur_i)>stop_flag then
+ begin a:=lig_kern_restart(cur_f)(cur_i);
+ cur_i:=font_info[a].qqqq;
+ end;
+ loop@+ begin @<If instruction |cur_i| is a kern with |cur_c|, attach
+ the kern after~|q|; or if it is a ligature with |cur_c|, combine
+ noads |q| and~|p| appropriately; then |return| if the cursor has
+ moved past a noad, or |goto restart|@>;
+ if skip_byte(cur_i)>=stop_flag then return;
+ a:=a+qo(skip_byte(cur_i))+1;
+ cur_i:=font_info[a].qqqq;
+ end;
+@z
+@x The entire code of module 753 is revised
+@y and should be replaced by the following:
+@ Note that a ligature between an |ord_noad| and another kind of noad
+is replaced by an |ord_noad|, when the two noads collapse into one.
+But we could make a parenthesis (say) change shape when it follows
+certain letters. Presumably a font designer will define such
+ligatures only when this convention makes sense.
+
+\chardef\?='174 % vertical line to indicate character retention
+
+@<If instruction |cur_i| is a kern with |cur_c|, ...@>=
+if next_char(cur_i)=cur_c then if skip_byte(cur_i)<=stop_flag then
+ if op_byte(cur_i)>=kern_flag then
+ begin p:=new_kern(char_kern(cur_f)(cur_i));
+ link(p):=link(q); link(q):=p; return;
+ end
+ else begin check_interrupt; {allow a way out of infinite ligature loop}
+ case op_byte(cur_i) of
+ qi(1),qi(5): character(nucleus(q)):=rem_byte(cur_i); {\.{=:\?}, \.{=:\?>}}
+ qi(2),qi(6): character(nucleus(p)):=rem_byte(cur_i); {\.{\?=:}, \.{\?=:>}}
+ qi(3),qi(7),qi(11):begin r:=new_noad; {\.{\?=:\?}, \.{\?=:\?>}, \.{\?=:\?>>}}
+ character(nucleus(r)):=rem_byte(cur_i);
+ fam(nucleus(r)):=fam(nucleus(q));@/
+ link(q):=r; link(r):=p;
+ if op_byte(cur_i)<qi(11) then math_type(nucleus(r)):=math_char
+ else math_type(nucleus(r)):=math_text_char; {prevent combination}
+ end;
+ othercases begin link(q):=link(p);
+ character(nucleus(q)):=rem_byte(cur_i); {\.{=:}}
+ mem[subscr(q)]:=mem[subscr(p)]; mem[supscr(q)]:=mem[supscr(p)];@/
+ free_node(p,noad_size);
+ end
+ endcases;
+ if op_byte(cur_i)>qi(3) then return;
+ math_type(nucleus(q)):=math_char; goto restart;
+ end
+@z
+@x module 862
+@!q,@!r,@!s:pointer; {miscellaneous nodes of temporary interest}
+@y
+@!q,@!r,@!s,@!prev_s:pointer; {miscellaneous nodes of temporary interest}
+@z
+@x module 892
+nodes $p_a$ and~$p_b$ in the description above are placed into variables
+@y
+nodes $p_{a-1}$ and~$p_b$ in the description above are placed into variables
+@z
+@x ibid
+@!hc:array[0..65] of halfword; {word to be hyphenated}
+@y
+@!hc:array[0..65] of 0..256; {word to be hyphenated}
+@z
+@x ibid
+@!hu:array[1..63] of ASCII_code; {like |hc|, before conversion to lowercase}
+@y
+@!hu:array[0..63] of 0..256; {like |hc|, before conversion to lowercase}
+@z
+@x module 894
+s:=link(cur_p);
+@y
+prev_s:=cur_p; s:=link(prev_s);
+@z
+@x module 895
+label done,found,not_found,found1,exit;
+@y
+label common_ending,done,found,found1,not_found,not_found+1,exit;
+@z
+@x module 896
+ else if type(s)=ligature_node then
+ begin q:=lig_ptr(s); c:=qo(character(q)); hf:=font(q);
+ end
+@y
+ else if type(s)=ligature_node then
+ if lig_ptr(s)=null then goto continue
+ else begin q:=lig_ptr(s); c:=qo(character(q)); hf:=font(q);
+ end
+@z
+@x ibid
+continue: s:=link(s);
+@y
+continue: prev_s:=s; s:=link(prev_s);
+@z
+@x ibid
+ha:=s
+@y
+ha:=prev_s
+@z
+@x module 898
+begin j:=hn; q:=lig_ptr(s);
+if font(q)<>hf then goto done3;
+repeat c:=qo(character(q));
+if lc_code(c)=0 then goto done3;
+if j=63 then goto done3;
+incr(j); hu[j]:=c; hc[j]:=lc_code(c);@/
+q:=link(q);
+until q=null;
+@y
+begin if font(lig_char(s))<>hf then goto done3;
+j:=hn; q:=lig_ptr(s);
+while q>null do
+ begin c:=qo(character(q));
+ if lc_code(c)=0 then goto done3;
+ if j=63 then goto done3;
+ incr(j); hu[j]:=c; hc[j]:=lc_code(c);@/
+ q:=link(q);
+ end;
+@z
+@x module 900 gets three new global variables
+@y
+@!init_list:pointer; {list of punctuation characters preceding the word}
+@!init_lig:boolean; {does |init_list| represent a ligature?}
+@!init_lft:boolean; {if so, did the ligature involve a left boundary?}
+@z
+@x module 901
+@!q,@!r,@!s:pointer; {temporary registers for list manipulation}
+@y
+@!p,@!q,@!r,@!s:pointer; {temporary registers for list manipulation}
+@!bchar:halfword; {right boundary character of hyphenated word, or |non_char|}
+@z
+@x module 903 should be entirely replaced
+@y by the following:
+@ If hyphens are in fact going to be inserted, \TeX\ first deletes the
+subsequence of nodes between |ha| and~|hb|. An attempt is made to
+preserve the effect that implicit boundary characters and punctuation marks
+had on ligatures inside the hyphenated word, by storing a left boundary or
+preceding character in |hu[0]| and by storing a possible right boundary
+in |bchar|. We set |j:=0| if |hu[0]| is to be part of the reconstruction;
+otherwise |j:=1|.
+The variable |s| will point to the tail of the current hlist, and
+|q| will point to the node following |hb|, so that
+things can be hooked up after we reconstitute the hyphenated word.
+
+@<Replace nodes |ha..hb| by a sequence of nodes...@>=
+q:=link(hb); link(hb):=null; r:=link(ha); link(ha):=null; bchar:=non_char;
+if type(hb)=ligature_node then if odd(subtype(hb)) then
+ bchar:=font_bchar[hf];
+if is_char_node(ha) then
+ begin init_list:=ha; init_lig:=false; hu[0]:=qo(character(ha));
+ end
+else if type(ha)=ligature_node then
+ begin init_list:=lig_ptr(ha); init_lig:=true; init_lft:=(subtype(ha)>1);
+ hu[0]:=qo(character(lig_char(ha)));
+ if init_list=null then if init_lft then
+ begin hu[0]:=256; init_lig:=false;
+ end; {in this case a ligature will be reconstructed from scratch}
+ free_node(ha,small_node_size);
+ end
+else goto not_found+1; {no punctuation found}
+s:=cur_p; {we have |cur_p<>ha| because |type(cur_p)=glue_node|}
+while link(s)<>ha do s:=link(s);
+j:=0; goto common_ending;
+not_found+1: j:=1; s:=ha; init_list:=null;
+if not is_char_node(r) then if type(r)=ligature_node then
+ if subtype(r)>1 then
+ begin j:=0; hu[0]:=256; init_lig:=false;
+ end;
+common_ending: flush_node_list(r);
+@<Reconstitute nodes for the hyphenated word, inserting discretionary hyphens@>;
+flush_list(init_list)
+@z
+@x modules 905--911 are entirely replaced
+@y by the following new code:
+Still further complications arise in the presence of ligatures that do not
+delete the original characters. When punctuation precedes the word being
+hyphenated, \TeX's method is not perfect under all possible scenarios,
+because punctuation marks and letters can propagate information back and forth.
+For example, suppose the original pre-hyphenation pair
+\.{*a} changes to \.{*y} via a \.{\?=:} ligature, which changes to \.{xy}
+via a \.{=:\?} ligature; if $p_{a-1}=\.x$ and $p_a=\.y$, the reconstitution
+procedure isn't smart enough to obtain \.{xy} again. In such cases the
+font designer should include a ligature that goes from \.{xa} to \.{xy}.
+
+@ The processing is facilitated by a subroutine called |reconstitute|. Given
+a string of characters $x_j\ldots x_n$, there is a smallest index $m\ge j$
+such that the ``translation'' of $x_j\ldots x_n$ by ligatures and kerning
+has the form $y_1\ldots y_t$ followed by the translation of $x_{m+1}\ldots x_n$,
+where $y_1\ldots y_t$ is some nonempty sequence of character, ligature, and
+kern nodes. We call $x_j\ldots x_m$ a ``cut prefix'' of $x_j\ldots x_n$.
+For example, if $x_1x_2x_3=\.{fly}$, and if the font contains `fl' as a
+ligature and a kern between `fl' and `y', then $m=2$, $y=2$, and $y_1$ will
+be a ligature node for `fl' followed by an appropriate kern node~$y_2$.
+In the most common case, $x_j$~forms no ligature with $x_{j+1}$ and we
+simply have $m=j$, $y_1=x_j$. If $m<n$ we can repeat the procedure on
+$x_{m+1}\ldots x_n$ until the entire translation has been found.
+
+The |reconstitute| function returns the integer $m$ and puts the nodes
+$y_1\ldots y_t$ into a linked list starting at |link(hold_head)|,
+getting the input $x_j\ldots x_n$ from the |hu| array. If $x_j=256$,
+we consider $x_j$ to be an implicit left boundary character; in this
+case |j| must be strictly less than~|n|. There is a
+parameter |bchar|, which is either 256 or an implicit right boundary character
+assumed to be present just following~$x_n$. (The value |hu[n+1]| is never
+explicitly examined, but the algorithm imagines that |bchar| is there.)
+
+If there exists an index |k| in the range $j\le k\le m$ such that |hyf[k]|
+is odd and such that the result of reconstitute would have been different
+if $x_{k+1}$ had been |hchar|, then |reconstitute| sets |hyphen_passed|
+to the smallest such~|k|. Otherwise it sets |hyphen_passed| to zero.
+
+A special convention is used in the case |j=0|: Then we assume that the
+translation of |hu[0]| appears in a special list of charnodes starting at
+|init_list|; moreover, if |init_lig| is |true|, then |hu[0]| will be
+a ligature character, involving a left boundary if |init_lft| is |true|.
+This facility is provided for cases when a hyphenated
+word is preceded by punctuation (like single or double quotes) that might
+affect the translation of the beginning of the word.
+
+@<Glob...@>=
+@!hyphen_passed:small_number; {first hyphen in a ligature, if any}
+
+@ @<Declare the function called |reconstitute|@>=
+function reconstitute(@!j,@!n:small_number;@!bchar,@!hchar:halfword):
+ small_number;
+label continue,done;
+var @!p:pointer; {temporary register for list manipulation}
+@!t:pointer; {a node being appended to}
+@!q:four_quarters; {character information or a lig/kern instruction}
+@!cur_rh:halfword; {hyphen character for ligature testing}
+@!test_char:halfword; {hyphen or other character for ligature testing}
+@!w:scaled; {amount of kerning}
+@!k:font_index; {position of current lig/kern instruction}
+begin hyphen_passed:=0; t:=hold_head; w:=0; link(hold_head):=null;
+ {at this point |ligature_present=lft_hit=rt_hit=false|}
+@<Set up data structures with the cursor following position |j|@>;
+continue:@<If there's a ligature or kern at the cursor position, update the data
+ structures, possibly advancing~|j|; continue until the cursor moves@>;
+@<Append a ligature and/or kern to the translation;
+ |goto continue| if the stack of inserted ligatures is nonempty@>;
+reconstitute:=j;
+end;
+
+@ The reconstitution procedure shares many of the global data structures
+by which \TeX\ has processed the words before they were hyphenated.
+There is an implied ``cursor'' between characters |cur_l| and |cur_r|;
+these characters will be tested for possible ligature activity. If
+|ligature_present| then |cur_l| is a ligature character formed from the
+original characters following |cur_q| in the current translation list.
+There is a ``ligature stack'' between the cursor and character |j+1|,
+consisting of pseudo-ligature nodes linked together by their |link| fields.
+This stack is normally empty unless a ligature command has created a new
+character that will need to be processed later. A pseudo-ligature is
+a special node having a |character| field that represents a potential
+ligature and a |lig_ptr| field that points to a |char_node| or is |null|.
+We have
+$$|cur_r|=\cases{|character(lig_stack)|,&if |lig_stack>null|;\cr
+ |qi(hu[j+1])|,&if |lig_stack=null| and |j<n|;\cr
+ bchar,&if |lig_stack=null| and |j=n|.\cr}$$
+
+@<Glob...@>=
+@!cur_l,@!cur_r:halfword; {characters before and after the cursor}
+@!cur_q:pointer; {where a ligature should be detached}
+@!lig_stack:pointer; {unfinished business to the right of the cursor}
+@!ligature_present:boolean; {should a ligature node be made for |cur_l|?}
+@!lft_hit,@!rt_hit:boolean; {did we hit a ligature with a boundary character?}
+
+@ @d append_charnode_to_t(#)== begin link(t):=get_avail; t:=link(t);
+ font(t):=hf; character(t):=#;
+ end
+@d set_cur_r==begin if j<n then cur_r:=qi(hu[j+1])@+else cur_r:=bchar;
+ if odd(hyf[j]) then cur_rh:=hchar@+else cur_rh:=non_char;
+ end
+
+@<Set up data structures with the cursor following position |j|@>=
+cur_l:=qi(hu[j]); cur_q:=t;
+if j=0 then
+ begin ligature_present:=init_lig; p:=init_list;
+ if ligature_present then lft_hit:=init_lft;
+ while p>null do
+ begin append_charnode_to_t(character(p)); p:=link(p);
+ end;
+ end
+else if cur_l<non_char then append_charnode_to_t(cur_l);
+lig_stack:=null; set_cur_r
+
+@ We may want to look at the lig/kern program twice, once for a hyphen
+and once for a normal letter. (The hyphen might appear after the letter
+in the program, so we'd better not try to look for both at once.)
+
+@<If there's a ligature or kern at the cursor position, update...@>=
+if cur_l=non_char then
+ begin k:=bchar_label[hf];
+ if k=non_address then goto done@+else q:=font_info[k].qqqq;
+ end
+else begin q:=char_info(hf)(cur_l);
+ if char_tag(q)<>lig_tag then goto done;
+ k:=lig_kern_start(hf)(q); q:=font_info[k].qqqq;
+ if skip_byte(q)>stop_flag then
+ begin k:=lig_kern_restart(hf)(q); q:=font_info[k].qqqq;
+ end;
+ end; {now |k| is the starting address of the lig/kern program}
+if cur_rh<non_char then test_char:=cur_rh@+else test_char:=cur_r;
+loop@+begin if next_char(q)=test_char then if skip_byte(q)<=stop_flag then
+ if cur_rh<non_char then
+ begin hyphen_passed:=j; hchar:=non_char; cur_rh:=non_char;
+ goto continue;
+ end
+ else begin if hchar<non_char then if odd(hyf[j]) then
+ begin hyphen_passed:=j; hchar:=non_char;
+ end;
+ if op_byte(q)<kern_flag then
+ @<Carry out a ligature replacement, updating the cursor structure
+ and possibly advancing~|j|; |goto continue| if the cursor doesn't
+ advance, otherwise |goto done|@>;
+ w:=char_kern(hf)(q); goto done; {this kern will be inserted below}
+ end;
+ if skip_byte(q)>=stop_flag then
+ if cur_rh=non_char then goto done
+ else begin cur_rh:=non_char; goto continue;
+ end;
+ k:=k+qo(skip_byte(q))+1; q:=font_info[k].qqqq;
+ end;
+done:
+
+@ @d wrap_lig(#)==if ligature_present then
+ begin p:=new_ligature(hf,cur_l,link(cur_q));
+ if lft_hit then
+ begin subtype(p):=2; lft_hit:=false;
+ end;
+ if # then if lig_stack=null then
+ begin incr(subtype(p)); rt_hit:=false;
+ end;
+ link(cur_q):=p; t:=p; ligature_present:=false;
+ end
+@d pop_lig_stack==begin if lig_ptr(lig_stack)>null then
+ begin link(t):=lig_ptr(lig_stack); {this is a charnode for |hu[j+1]|}
+ t:=link(t); incr(j);
+ end;
+ p:=lig_stack; lig_stack:=link(p); free_node(p,small_node_size);
+ if lig_stack=null then set_cur_r@+else cur_r:=character(lig_stack);
+ end {if |lig_stack| isn't |null| we have |cur_rh=non_char|}
+
+@<Append a ligature and/or kern to the translation...@>=
+wrap_lig(rt_hit);
+if w<>0 then
+ begin link(t):=new_kern(w); t:=link(t); w:=0;
+ end;
+if lig_stack>null then
+ begin cur_q:=t; cur_l:=character(lig_stack); ligature_present:=true;
+ pop_lig_stack; goto continue;
+ end
+
+@ @<Carry out a ligature replacement, updating the cursor structure...@>=
+begin if cur_l=non_char then lft_hit:=true;
+if j=n then if lig_stack=null then rt_hit:=true;
+check_interrupt; {allow a way out in case there's an infinite ligature loop}
+case op_byte(q) of
+qi(1),qi(5):begin cur_l:=rem_byte(q); {\.{=:\?}, \.{=:\?>}}
+ ligature_present:=true;
+ end;
+qi(2),qi(6):begin cur_r:=rem_byte(q); {\.{\?=:}. \.{\?=:>}}
+ if lig_stack>null then character(lig_stack):=cur_r
+ else begin lig_stack:=new_lig_item(cur_r);
+ if j=n then bchar:=non_char
+ else begin p:=get_avail; lig_ptr(lig_stack):=p;
+ character(p):=qi(hu[j+1]); font(p):=hf;
+ end;
+ end;
+ end;
+qi(3):begin cur_r:=rem_byte(q); {\.{\?=:\?}}
+ p:=lig_stack; lig_stack:=new_lig_item(cur_r); link(lig_stack):=p;
+ end;
+qi(7),qi(11):begin wrap_lig(false); {\.{\?=:\?>}, \.{\?=:\?>>}}
+ cur_q:=t; cur_l:=rem_byte(q); ligature_present:=true;
+ end;
+othercases begin cur_l:=rem_byte(q); ligature_present:=true; {\.{=:}}
+ if lig_stack>null then pop_lig_stack
+ else if j=n then goto done
+ else begin append_charnode_to_t(cur_r); incr(j); set_cur_r;
+ end;
+ end
+endcases;
+if op_byte(q)>qi(4) then if op_byte(q)<>qi(7) then goto done;
+goto continue;
+end
+@z
+@x module 912
+@!c:ASCII_code; {character temporarily replaced by a hyphen}
+@y
+@!c:ASCII_code; {character temporarily replaced by a hyphen}
+@!c_loc:0..63; {where that character came from}
+@!r_count:integer; {replacement count for discretionary}
+@z
+@x modules 913--918 are to be completely replaced
+@y by the following code:
+@ When the following code is performed, |hyf[0]| and |hyf[hn]| will be zero.
+
+@<Reconstitute nodes for the hyphenated word...@>=
+repeat l:=j; j:=reconstitute(j,hn,bchar,qi(hyf_char))+1;
+if hyphen_passed=0 then
+ begin link(s):=link(hold_head);
+ while link(s)>null do s:=link(s);
+ if odd(hyf[j-1]) then
+ begin l:=j; hyphen_passed:=j-1; link(hold_head):=null;
+ end;
+ end;
+if hyphen_passed>0 then
+ @<Create and append a discretionary node as an alternative to the
+ unhyphenated word, and continue to develop both branches until they
+ become equivalent@>;
+until j>hn;
+link(s):=q
+
+@ @d advance_major_tail==begin major_tail:=link(major_tail); incr(r_count);
+ end
+
+@<Create and append a discretionary node as an alternative...@>=
+begin r:=get_node(small_node_size);
+link(r):=link(hold_head); type(r):=disc_node;
+major_tail:=r; r_count:=0;
+while link(major_tail)>null do advance_major_tail;
+i:=hyphen_passed;
+@<Put the \(c)characters |hu[l..i]| and a hyphen into |pre_break(r)|@>;
+@<Put the \(c)characters |hu[i+1..@,]| into |post_break(r)|, appending to this
+ list and to |major_tail| until synchronization has been achieved@>;
+@<Move pointer |s| to the end of the current list, and set |replace_count(r)|
+ appropriately@>;
+end
+
+@ The new hyphen might combine with the previous character via ligature
+or kern. At this point we have |l-1<=i<=j| and |i<hn|.
+
+@<Put the \(c)characters |hu[l..i]| and a hyphen into |pre_break(r)|@>=
+minor_tail:=null; pre_break(r):=null; hyf_node:=new_character(hf,hyf_char);
+if hyf_node<>null then
+ begin incr(i); c:=hu[i]; hu[i]:=hyf_char; free_avail(hyf_node);
+ end;
+while l<=i do
+ begin l:=reconstitute(l,i,font_bchar[hf],non_char)+1;
+ if link(hold_head)>null then
+ begin if minor_tail=null then pre_break(r):=link(hold_head)
+ else link(minor_tail):=link(hold_head);
+ minor_tail:=link(hold_head);
+ while link(minor_tail)>null do minor_tail:=link(minor_tail);
+ end;
+ end;
+if hyf_node<>null then
+ begin hu[i]:=c; {restore the character in the hyphen position}
+ l:=i; decr(i);
+ end
+
+@ The synchronization algorithm begins with |l=i+1<=j|.
+
+@<Put the \(c)characters |hu[i+1..@,]| into |post_break(r)|...@>=
+minor_tail:=null; post_break(r):=null; c_loc:=0;
+if bchar_label[hf]<non_address then {put left boundary at beginning of new line}
+ begin decr(l); c:=hu[l]; c_loc:=l; hu[l]:=256;
+ end;
+while l<j do
+ begin repeat l:=reconstitute(l,hn,bchar,non_char)+1;
+ if c_loc>0 then
+ begin hu[c_loc]:=c; c_loc:=0;
+ end;
+ if link(hold_head)>null then
+ begin if minor_tail=null then post_break(r):=link(hold_head)
+ else link(minor_tail):=link(hold_head);
+ minor_tail:=link(hold_head);
+ while link(minor_tail)>null do minor_tail:=link(minor_tail);
+ end;
+ until l>=j;
+ while l>j do
+ @<Append characters of |hu[j..@,]| to |major_tail|, advancing~|j|@>;
+ end
+
+@ @<Append characters of |hu[j..@,]|...@>=
+begin j:=reconstitute(j,hn,bchar,non_char)+1;
+link(major_tail):=link(hold_head);
+while link(major_tail)>null do advance_major_tail;
+end
+
+@ Ligature insertion can cause a word to grow exponentially in size. Therefore
+we must test the size of |r_count| here, even though the hyphenated text
+was at most 63 characters long.
+
+@<Move pointer |s| to the end of the current list...@>=
+if r_count>127 then {we have to forget the discretionary hyphen}
+ begin link(s):=link(r); link(r):=null; flush_node_list(r);
+ end
+else begin link(s):=r; replace_count(r):=r_count;
+ end;
+s:=major_tail
+@z
+@x module 1030
+@d main_loop=70 {go here to typeset |cur_chr| in the current font}
+@d main_loop_1=71 {like |main_loop|, but |(f,c)| = current font and char}
+@d main_loop_2=72 {like |main_loop_1|, but |c| is known to be in range}
+@d main_loop_3=73 {like |main_loop_2|, but several variables are set up}
+@d append_normal_space=74 {go here to append a normal space between words}
+@y
+@d main_loop=70 {go here to typeset a string of consecutive characters}
+@d main_loop_wrapup=80 {go here to finish a character or ligature}
+@d main_loop_move=90 {go here to advance the ligature cursor}
+@d main_loop_move_lig=95 {same, when advancing past a generated ligature}
+@d main_loop_lookahead=100 {go here to bring in another character, if any}
+@d main_lig_loop=110 {go here to check for ligatures or kerning}
+@d append_normal_space=120 {go here to append a normal space between words}
+@z
+@x ibid
+label big_switch,reswitch,main_loop,main_loop_1,main_loop_2,main_loop_3,
+@y
+label big_switch,reswitch,main_loop,main_loop_wrapup,
+ main_loop_move,main_loop_move+1,main_loop_move+2,main_loop_move_lig,
+ main_loop_lookahead,main_loop_lookahead+1,
+ main_lig_loop,main_lig_loop+1,main_lig_loop+2,
+@z
+@x ibid
+@<Local variables for the inner loop of |main_control|@>@;
+@y
+@z
+@x ibid
+hmode+char_num: begin scan_char_num; cur_chr:=cur_val; goto main_loop;
+ end;
+@y
+hmode+char_num: begin scan_char_num; cur_chr:=cur_val; goto main_loop;@+end;
+hmode+no_boundary: begin get_x_token;
+ if (cur_cmd=letter)or(cur_cmd=other_char)or(cur_cmd=char_given)or
+ (cur_cmd=char_num) then cancel_boundary:=true;
+ goto reswitch;
+ end;
+@z
+@x modules 1032--1040 are all to be replaced
+@y by the following code:
+@ The following part of the program was first written in a structured
+manner, according to the philosophy that ``premature optimization is
+the root of all evil.'' Then it was rearranged into pieces of
+spaghetti so that the most common actions could proceed with little or
+no redundancy.
+
+The original unoptimized form of this algorithm resembles the
+|reconstitute| procedure, which was described earlier in connection with
+hyphenation. Again we have an implied ``cursor`` between characters
+|cur_l| and |cur_r|. The main difference is that the |lig_stack| can now
+contain a charnode as well as pseudo-ligatures; that stack is now
+usually nonempty, because the next character of input (if any) has been
+appended to it. In |main_control| we have
+$$|cur_r|=\cases{|character(lig_stack)|,&if |lig_stack>null|;\cr
+ |font_bchar[cur_font]|,&otherwise.\cr}$$
+Several additional global variables are needed.
+
+@<Glob...@>=
+@!main_f:internal_font_number; {the current font}
+@!main_i:four_quarters; {character information bytes for |cur_l|}
+@!main_j:four_quarters; {ligature/kern command}
+@!main_k:font_index; {index into |font_info|}
+@!main_p:pointer; {temporary register for list manipulation}
+@!main_s:integer; {space factor value}
+@!bchar:halfword; {right boundary character of current font, or |non_char|}
+@!false_bchar:halfword; {nonexistent character matching |bchar|, or |non_char|}
+@!cancel_boundary:boolean; {should the left boundary be ignored?}
+@!ins_disc:boolean; {should we insert a discretionary node?}
+
+@ The boolean variables of the main loop are normally false, and always reset
+to false before the loop is left. That saves us the extra work of initializing
+each time.
+
+@<Set init...@>=
+ligature_present:=false; cancel_boundary:=false; lft_hit:=false; rt_hit:=false;
+ins_disc:=false;
+
+@ We leave |space_factor| unchanged if |sf_code(cur_chr)=0|; otherwise we
+set it to |sf_code(cur_chr)|, except that the space factor never changes
+from a value less than 1000 to a value exceeding 1000. The most common
+case is |sf_code(cur_chr)=1000|, so we want that case to be fast.
+
+The overall structure of the main loop is presented here. Some program labels
+are inside the individual sections.
+
+@d adjust_space_factor==@t@>@;@/
+ main_s:=sf_code(cur_chr);
+ if main_s=1000 then space_factor:=1000
+ else if main_s<1000 then
+ begin if main_s>0 then space_factor:=main_s;
+ end
+ else if space_factor<1000 then space_factor:=1000
+ else space_factor:=main_s
+
+@<Append character |cur_chr|...@>=
+adjust_space_factor;@/
+main_f:=cur_font;
+bchar:=font_bchar[main_f]; false_bchar:=font_false_bchar[main_f];
+if mode>0 then if language<>clang then fix_language;
+fast_get_avail(lig_stack); font(lig_stack):=main_f; cur_l:=qi(cur_chr);
+character(lig_stack):=cur_l;@/
+cur_q:=tail;
+if cancel_boundary then
+ begin cancel_boundary:=false; main_k:=non_address;
+ end
+else main_k:=bchar_label[main_f];
+if main_k=non_address then goto main_loop_move+2; {no left boundary processing}
+cur_r:=cur_l; cur_l:=non_char;
+goto main_lig_loop+1; {begin with cursor after left boundary}
+@#
+main_loop_wrapup:@<Make a ligature node, if |ligature_present|;
+ insert a null discretionary, if appropriate@>;
+main_loop_move:@<If the cursor is immediately followed by the right boundary,
+ |goto reswitch|; if it's followed by an invalid character, |goto big_switch|;
+ otherwise move the cursor one step to the right and |goto main_lig_loop|@>;
+main_loop_lookahead:@<Look ahead for another character, or leave |lig_stack|
+ empty if there's none there@>;
+main_lig_loop:@<If there's a ligature/kern command relevant to |cur_l| and
+ |cur_r|, adjust the text appropriately; exit to |main_loop_wrapup|@>;
+main_loop_move_lig:@<Move the cursor past a pseudo-ligature, then
+ |goto main_loop_lookahead| or |main_lig_loop|@>
+
+@ If the current horizontal list is empty, the reference to |character(tail)|
+here is not strictly legal, since |tail| will be a node freshly returned by
+|get_avail|. But this should cause no problem on most implementations, and we
+do want the inner loop to be fast.
+@^dirty Pascal@>
+
+A discretionary break is not inserted for an explicit hyphen when we are in
+restricted horizontal mode. In particular, this avoids putting discretionary
+nodes inside of other discretionaries.
+
+@d pack_lig(#)== {the parameter is either |rt_hit| or |false|}
+ begin main_p:=new_ligature(main_f,cur_l,link(cur_q));
+ if lft_hit then
+ begin subtype(main_p):=2; lft_hit:=false;
+ end;
+ if # then if lig_stack=null then
+ begin incr(subtype(main_p)); rt_hit:=false;
+ end;
+ link(cur_q):=main_p; tail:=main_p; ligature_present:=false;
+ end
+
+@d wrapup(#)==if cur_l<non_char then
+ begin if character(tail)=qi(hyphen_char[main_f]) then if link(cur_q)>null then
+ ins_disc:=true;
+ if ligature_present then pack_lig(#);
+ if ins_disc then
+ begin ins_disc:=false;
+ if mode>0 then tail_append(new_disc);
+ end;
+ end
+
+@<Make a ligature node, if |ligature_present|;...@>=
+wrapup(rt_hit)
+
+@ @<If the cursor is immediately followed by the right boundary...@>=
+if lig_stack=null then goto reswitch;
+cur_q:=tail; cur_l:=cur_r; {or |character(lig_stack)|}
+main_loop_move+1:if not is_char_node(lig_stack) then goto main_loop_move_lig;
+main_loop_move+2:if(cur_chr<font_bc[main_f])or(cur_chr>font_ec[main_f]) then
+ begin char_warning(main_f,cur_chr); free_avail(lig_stack); goto big_switch;
+ end;
+main_i:=char_info(main_f)(cur_l);
+if not char_exists(main_i) then
+ begin char_warning(main_f,cur_chr); free_avail(lig_stack); goto big_switch;
+ end;
+tail_append(lig_stack) {|main_loop_lookahead| is next}
+
+@ Here we are at |main_loop_move_lig|.
+When we begin this code we have |cur_l=character(lig_stack)| and |cur_q=tail|.
+
+@<Move the cursor past a pseudo-ligature...@>=
+main_p:=lig_ptr(lig_stack);
+if main_p>null then tail_append(main_p);
+temp_ptr:=lig_stack; lig_stack:=link(temp_ptr);
+free_node(temp_ptr,small_node_size);
+main_i:=char_info(main_f)(cur_l); ligature_present:=true;
+if lig_stack=null then
+ if main_p>null then goto main_loop_lookahead
+ else cur_r:=bchar
+else cur_r:=character(lig_stack);
+goto main_lig_loop
+
+@ The result of \.{\\char} can participate in a ligature or kern, so we must
+look ahead for it.
+
+@<Look ahead for another character...@>=
+get_next; {set only |cur_cmd| and |cur_chr|, for speed}
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then goto main_loop_lookahead+1;
+x_token; {now expand and set |cur_cmd|, |cur_chr|, |cur_tok|}
+if cur_cmd=letter then goto main_loop_lookahead+1;
+if cur_cmd=other_char then goto main_loop_lookahead+1;
+if cur_cmd=char_given then goto main_loop_lookahead+1;
+if cur_cmd=char_num then
+ begin scan_char_num; cur_chr:=cur_val; goto main_loop_lookahead+1;
+ end;
+if cur_cmd=no_boundary then bchar:=non_char;
+cur_r:=bchar; lig_stack:=null; goto main_lig_loop;
+main_loop_lookahead+1: adjust_space_factor;
+fast_get_avail(lig_stack); font(lig_stack):=main_f;
+cur_r:=qi(cur_chr); character(lig_stack):=cur_r;
+if cur_r=false_bchar then cur_r:=non_char {this prevents spurious ligatures}
+
+@ Even though comparatively few characters have a lig/kern program, several
+of the instructions here count as part of \TeX's inner loop, since a
+potentially long sequential search must be performed. For example, tests with
+Computer Modern Roman showed that about 40 per cent of all characters
+actually encountered in practice had a lig/kern program, and that about four
+lig/kern commands were investigated for every such character.
+
+At the beginning of this code we have |main_i=char_info(main_f)(cur_l)|.
+
+@<If there's a ligature/kern command...@>=
+if char_tag(main_i)<>lig_tag then goto main_loop_wrapup;
+main_k:=lig_kern_start(main_f)(main_i); main_j:=font_info[main_k].qqqq;
+if skip_byte(main_j)<=stop_flag then goto main_lig_loop+2;
+main_k:=lig_kern_restart(main_f)(main_j);
+main_lig_loop+1:main_j:=font_info[main_k].qqqq;
+main_lig_loop+2:if next_char(main_j)=cur_r then
+ if skip_byte(main_j)<=stop_flag then
+ @<Do ligature or kern command, returning to |main_lig_loop|
+ or |main_loop_wrapup| or |main_loop_move|@>;
+if skip_byte(main_j)=qi(0) then incr(main_k)
+else begin if skip_byte(main_j)>=stop_flag then goto main_loop_wrapup;
+ main_k:=main_k+qo(skip_byte(main_j))+1;
+ end;
+goto main_lig_loop+1
+
+@ When a ligature or kern instruction matches a character, we know from
+|read_font_info| that the character exists in the font, even though we
+haven't verified its existence in the normal way.
+
+This section could be made into a subroutine, if the code inside
+|main_control| needs to be shortened.
+
+\chardef\?='174 % vertical line to indicate character retention
+
+@<Do ligature or kern command...@>=
+begin if op_byte(main_j)>=kern_flag then
+ begin wrapup(rt_hit);
+ tail_append(new_kern(char_kern(main_f)(main_j))); goto main_loop_move;
+ end;
+if cur_l=non_char then lft_hit:=true
+else if lig_stack=null then rt_hit:=true;
+check_interrupt; {allow a way out in case there's an infinite ligature loop}
+case op_byte(main_j) of
+qi(1),qi(5):begin cur_l:=rem_byte(main_j); {\.{=:\?}, \.{=:\?>}}
+ main_i:=char_info(main_f)(cur_l); ligature_present:=true;
+ end;
+qi(2),qi(6):begin cur_r:=rem_byte(main_j); {\.{\?=:}, \.{\?=:>}}
+ if lig_stack=null then {right boundary character is being consumed}
+ begin lig_stack:=new_lig_item(cur_r); bchar:=non_char;
+ end
+ else if is_char_node(lig_stack) then {|link(lig_stack)=null|}
+ begin main_p:=lig_stack; lig_stack:=new_lig_item(cur_r);
+ lig_ptr(lig_stack):=main_p;
+ end
+ else character(lig_stack):=cur_r;
+ end;
+qi(3):begin cur_r:=rem_byte(main_j); {\.{\?=:\?}}
+ main_p:=lig_stack; lig_stack:=new_lig_item(cur_r);
+ link(lig_stack):=main_p;
+ end;
+qi(7),qi(11):begin wrapup(false); {\.{\?=:\?>}, \.{\?=:\?>>}}
+ cur_q:=tail; cur_l:=rem_byte(main_j);
+ main_i:=char_info(main_f)(cur_l); ligature_present:=true;
+ end;
+othercases begin cur_l:=rem_byte(main_j); ligature_present:=true; {\.{=:}}
+ if lig_stack=null then goto main_loop_wrapup
+ else goto main_loop_move+1;
+ end
+endcases;
+if op_byte(main_j)>qi(4) then
+ if op_byte(main_j)<>qi(7) then goto main_loop_wrapup;
+if cur_l<non_char then goto main_lig_loop;
+main_k:=bchar_label[main_f]; goto main_lig_loop+1;
+end
+@z
+% HINTS for making main_control shorter if you need to conserve space:
+% (1) make pack_lig(#) a procedure call instead of a macro call
+% (2) make the code of @<Do ligature...@> a function that returns one of
+% four values; you goto a label based on the value returned.
+@x module 1042
+begin p:=font_glue[cur_font];
+if p=null then
+ begin f:=cur_font; p:=new_spec(zero_glue); k:=param_base[f]+space_code;
+ width(p):=font_info[k].sc; {that's |space(f)|}
+ stretch(p):=font_info[k+1].sc; {and |space_stretch(f)|}
+ shrink(p):=font_info[k+2].sc; {and |space_shrink(f)|}
+ font_glue[f]:=p;
+@y
+begin main_p:=font_glue[cur_font];
+if main_p=null then
+ begin main_p:=new_spec(zero_glue); main_k:=param_base[cur_font]+space_code;
+ width(main_p):=font_info[main_k].sc; {that's |space(cur_font)|}
+ stretch(main_p):=font_info[main_k+1].sc; {and |space_stretch(cur_font)|}
+ shrink(main_p):=font_info[main_k+2].sc; {and |space_shrink(cur_font)|}
+ font_glue[cur_font]:=main_p;
+@z
+@x module 1045
+any_mode(relax),vmode+spacer,mmode+spacer,mmode+no_boundary:do_nothing;
+@y
+any_mode(relax),vmode+spacer,mmode+spacer:do_nothing;
+@z
+@x module 1090
+ vmode+ex_space:@t@>@;@/
+@y
+ vmode+ex_space,vmode+no_boundary:@t@>@;@/
+@z
+@x module 1322
+dump_int(font_glue[k]);@/
+@y
+dump_int(font_glue[k]);@/
+dump_int(bchar_label[k]);
+dump_int(font_bchar[k]);
+dump_int(font_false_bchar[k]);@/
+@z
+@x module 1323
+undump(min_halfword)(lo_mem_max)(font_glue[k]);@/
+@y
+undump(min_halfword)(lo_mem_max)(font_glue[k]);@/
+undump(0)(font_mem_size)(bchar_label[k]);
+undump(min_quarterword)(non_char)(font_bchar[k]);
+undump(min_quarterword)(non_char)(font_false_bchar[k]);
+@z
+
+363. New \inputlineno feature desired by Spivak
+@x module 416 gets a new definition and a new statement
+@y
+@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}}
+primitive("inputlineno",last_item,input_line_no_code);
+@!@:input_line_no_}{\.{\\inputlineno} primitive@>
+@z and module 417 changes in the obvious way
+@x module 424 gets new code at the beginning
+@y
+if cur_chr>glue_val then
+ begin cur_val:=line; cur_val_level:=int_val;
+ end
+else
+@z
+
+364. New feature \holdinginserts suggested by Mittelbach.
+@x modules 236--238 get a new integer parameter
+@d int_pars=53 {total number of integer parameters}
+@y
+@d holding_inserts_code=53 {do not remove insertion nodes from \.{\\box255}}
+@d int_pars=54 {total number of integer parameters}
+@z and appropriate further lines are added to match all the other parameters
+@x module 1014
+@<Prepare all the boxes involved in insertions to act as queues@>;
+q:=hold_head; link(q):=null; prev_p:=page_head; p:=link(prev_p);
+while p<>best_page_break do
+ begin if type(p)=ins_node then @<Either insert the material
+ specified by node |p| into the appropriate box, or
+ hold it for the next page; also delete node |p| from
+ the current page@>
+@y
+if holding_inserts<=0 then
+ @<Prepare all the boxes involved in insertions to act as queues@>;
+q:=hold_head; link(q):=null; prev_p:=page_head; p:=link(prev_p);
+while p<>best_page_break do
+ begin if type(p)=ins_node then
+ begin if holding_inserts<=0 then
+ @<Either insert the material specified by node |p| into the
+ appropriate box, or hold it for the next page;
+ also delete node |p| from the current page@>;
+ end
+@z
+% also insert begin...end around the Pascal code of module 1018
+
+365. New \badness feature (which I'd been resisting for years)
+@x module 416 gets a new definition and a new statement
+@y
+@d badness_code=glue_val+2 {code for \.{\\badness}}
+primitive("badness",last_item,badness_code);
+@!@:badness_}{\.{\\badness} primitive@>
+@z and module 417 changes in the obvious way
+@x module 424 (the new code just added in #363)
+ begin cur_val:=line; cur_val_level:=int_val;
+@y
+ begin if cur_chr=input_line_no_code then cur_val:=line
+ else cur_val:=last_badness; {|cur_chr=badness_code|}
+ cur_val_level:=int_val;
+@z
+@x module 646 gets a new global variable
+@y
+@!last_badness:integer; {badness of the most recently packaged box}
+@z
+@x module 648
+@ @<Set init...@>=adjust_tail:=null;
+@y
+@ @<Set init...@>=adjust_tail:=null; last_badness:=0;
+@z
+@x modules 649 and 668
+@!b:integer; {badness of the new box}
+begin r:=get_node(box_node_size); type(r):=hlist_node;
+@y (except it's vlist_node in 668)
+begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node;
+@z (except it's vlist_node in 668)
+% change b to last_badness in modules 660&674 (4 times), 667&678 (3 times)
+@x modules 658 and 673
+if (hbadness<inf_bad)and(o=normal)and(list_ptr(r)<>null) then
+@y (except it's vbadness in 673)
+if o=normal then if list_ptr(r)<>null then
+@z
+@x modules 664 and 676
+ begin set_glue_ratio_one(glue_set(r)); {this is the maximum shrinkage}
+@y
+ begin last_badness:=1000000;
+ set_glue_ratio_one(glue_set(r)); {use the maximum shrinkage}
+@z
+@x ibid
+else if (hbadness<100)and(o=normal)and(list_ptr(r)<>null) then
+@y (except it's vbadness in 676)
+else if o=normal then if list_ptr(r)<>null then
+@z
+
+366. New \emergencystretch feature
+@x modules 247--248 get a new dimen parameter
+@d dimen_pars=20 {total number of dimension parameters}
+@y
+@d emergency_stretch_code=20 {reduces badnesses on final pass of line-breaking}
+@d dimen_pars=21 {total number of dimension parameters}
+@z and appropriate further lines are added to match all the other parameters
+@x module 828
+@!second_pass:boolean; {is this our second attempt to break this paragraph?}
+@y
+@!second_pass:boolean; {is this our second attempt to break this paragraph?}
+@!final_pass:boolean; {is this our final attempt to break this paragraph?}
+@z
+% change second_pass to final_pass in modules 854 and 873
+@x module 863
+ second_pass:=false;
+ end
+else begin threshold:=tolerance; second_pass:=true;
+@y
+ second_pass:=false; final_pass:=false;
+ end
+else begin threshold:=tolerance; second_pass:=true;
+ final_pass:=(emergency_stretch<=0);
+@z
+@x ibid
+ @!stat if tracing_paragraphs>0 then print_nl("@@secondpass");@;@+tats@/
+ threshold:=tolerance; second_pass:=true; {if at first you don't
+ succeed, \dots}
+@y
+ if not second_pass then
+ begin@!stat if tracing_paragraphs>0 then print_nl("@@secondpass");@;@+tats@/
+ threshold:=tolerance; second_pass:=true; final_pass:=(emergency_stretch<=0);
+ end {if at first you don't succeed, \dots}
+ else begin @!stat if tracing_paragraphs>0 then
+ print_nl("@@finalpass");@;@+tats@/
+ background[2]:=background[2]+emergency_stretch; final_pass:=true;
+ end;
+@z
+
+367. New \errorcontextlines feature suggested by a TUG participant
+@x modules 236--238 get a new integer parameter
+@d int_pars=54 {total number of integer parameters}
+@y
+@d error_context_lines_code=54 {maximum intermediate line pairs shown}
+@d int_pars=55 {total number of integer parameters}
+@z and appropriate further lines are added to match all the other parameters
+@x module 311
+@<Local variables for formatting calculations@>@/
+begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
+ {store current state}
+loop@+begin cur_input:=input_stack[base_ptr]; {enter into the context}
+ @<Display the current context@>;
+ if (state<>token_list) then
+ if (name>17) or (base_ptr=0) then goto done;
+@y
+@!nn:integer; {number of contexts shown so far, less one}
+@!bottom_line:boolean; {have we reached the final context to be shown?}
+@<Local variables for formatting calculations@>@/
+begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
+ {store current state}
+nn:=-1; bottom_line:=false;
+loop@+begin cur_input:=input_stack[base_ptr]; {enter into the context}
+ if (state<>token_list) then
+ if (name>17) or (base_ptr=0) then bottom_line:=true;
+ if (base_ptr=input_ptr)or bottom_line or(nn<error_context_lines) then
+ @<Display the current context@>
+ else if nn=error_context_lines then
+ begin print_nl("..."); incr(nn); {omitted if |error_context_lines<0|}
+ end;
+ if bottom_line then goto done;
+@z
+% also insert begin...end around the Pascal code of module 312
+% and add the statement "incr(nn)" to that module
+
+368. char_warning inside hyphenation could clobber old_setting
+@x module 863
+done: @!stat if tracing_paragraphs>0 then end_diagnostic(true);@;@+tats@/
+@y
+done: @!stat if tracing_paragraphs>0 then
+ begin end_diagnostic(true); normalize_selector;
+ end;@+tats@/
+@z
+
+369. Make ".fmt" more easily switchable (Don Hosek).
+@x module 520 gets a new definition
+@y
+@d format_extension=".fmt" {the extension, as a \.{WEB} constant}
+@z now replace ".fmt" by format_extension in modules 529 and 1328.
+
+370. Possible range check on weird nullfont (Breitenlohner, 16 Oct 89).
+@x module 565
+if (bc>ec+1)or(ec>255) then abort;
+@y
+if (bc>ec+1)or(ec>255) then abort;
+if bc>255 then {|bc=256| and |ec=255|}
+ begin bc:=1; ec:=0;
+ end;
+@z
+
+371. Prevent save_stack conflicts, e.g. in {\hbox\expandafter{\csname
+ \endcsname}} (found by Sullivan).
+@x module 645
+@p procedure scan_spec; {scans a box specification and left brace}
+label found;
+begin if scan_keyword("to") then saved(0):=exactly
+@.to@>
+else if scan_keyword("spread") then saved(0):=additional
+@.spread@>
+else begin saved(0):=additional; saved(1):=0;
+ goto found;
+ end;
+scan_normal_dimen; saved(1):=cur_val;
+found: save_ptr:=save_ptr+2; scan_left_brace;
+@y
+@p procedure scan_spec(@!c:group_code;@!three_codes:boolean);
+ {scans a box specification and left brace}
+label found;
+var @!s:integer; {temporarily saved value}
+@!spec_code:exactly..additional;
+begin if three_codes then s:=saved(0);
+if scan_keyword("to") then spec_code:=exactly
+@.to@>
+else if scan_keyword("spread") then spec_code:=additional
+@.spread@>
+else begin spec_code:=additional; cur_val:=0;
+ goto found;
+ end;
+scan_normal_dimen;
+found: if three_codes then
+ begin saved(0):=s; incr(save_ptr);
+ end;
+saved(0):=spec_code; saved(1):=cur_val; save_ptr:=save_ptr+2;
+new_save_level(c); scan_left_brace;
+@z
+@x module 774
+scan_spec; new_save_level(align_group);@/
+@y
+scan_spec(align_group,false);@/
+@z
+@x module 1073
+ if t=0 then saved(0):=cur_val@+else saved(0):=-cur_val;
+ scan_box;
+ end;
+any_mode(leader_ship): begin saved(0):=leader_flag-a_leaders+cur_chr; scan_box;
+ end;
+any_mode(make_box): begin saved(0):=0; begin_box;
+ end;
+@y
+ if t=0 then scan_box(cur_val)@+else scan_box(-cur_val);
+ end;
+any_mode(leader_ship): scan_box(leader_flag-a_leaders+cur_chr);
+any_mode(make_box): begin_box(0);
+@z
+@x module 1075
+procedure box_end;
+var p:pointer; {|ord_noad| for new box in math mode}
+begin if saved(0)<box_flag then @<Append box |cur_box| to the current list,
+ shifted by |saved(0)|@>
+else if saved(0)<ship_out_flag then @<Store \(c)|cur_box| in a box register@>
+else if cur_box<>null then
+ if saved(0)>ship_out_flag then @<Append a new leader node that
+ uses |cur_box|@>
+@y
+procedure box_end(@!box_context:integer);
+var p:pointer; {|ord_noad| for new box in math mode}
+begin if box_context<box_flag then @<Append box |cur_box| to the current list,
+ shifted by |box_context|@>
+else if box_context<ship_out_flag then @<Store \(c)|cur_box| in a box register@>
+else if cur_box<>null then
+ if box_context>ship_out_flag then @<Append a new leader node that
+ uses |cur_box|@>
+@z
+@x module 1076
+ begin shift_amount(cur_box):=saved(0);
+@y
+ begin shift_amount(cur_box):=box_context;
+@z
+@x module 1077
+if saved(0)<box_flag+256 then
+ eq_define(box_base-box_flag+saved(0),box_ref,cur_box)
+else geq_define(box_base-box_flag-256+saved(0),box_ref,cur_box)
+@y
+if box_context<box_flag+256 then
+ eq_define(box_base-box_flag+box_context,box_ref,cur_box)
+else geq_define(box_base-box_flag-256+box_context,box_ref,cur_box)
+@z
+@x module 1078
+ begin append_glue; subtype(tail):=saved(0)-(leader_flag-a_leaders);
+@y
+ begin append_glue; subtype(tail):=box_context-(leader_flag-a_leaders);
+@z
+@x module 1079
+procedure begin_box;
+@y
+procedure begin_box(@!box_context:integer);
+@z
+@x ibid
+box_end; {in simple cases, we use the box immediately}
+@y
+box_end(box_context); {in simple cases, we use the box immediately}
+@z
+@x module 1083
+incr(save_ptr); scan_spec;
+if k=hmode then
+ if (saved(-3)<box_flag)and(abs(mode)=vmode) then
+ new_save_level(adjusted_hbox_group)
+ else new_save_level(hbox_group)
+else begin if k=vmode then new_save_level(vbox_group)
+ else begin new_save_level(vtop_group); k:=vmode;
+@y
+saved(0):=box_context;
+if k=hmode then
+ if (box_context<box_flag)and(abs(mode)=vmode) then
+ scan_spec(adjusted_hbox_group,true)
+ else scan_spec(hbox_group,true)
+else begin if k=vmode then scan_spec(vbox_group,true)
+ else begin scan_spec(vtop_group,true); k:=vmode;
+@z
+@x module 1084
+procedure scan_box; {the next input should specify a box or perhaps a rule}
+begin @<Get the next non-blank non-relax...@>;
+if cur_cmd=make_box then begin_box
+else if (saved(0)>=leader_flag)and((cur_cmd=hrule)or(cur_cmd=vrule)) then
+ begin cur_box:=scan_rule_spec; box_end;
+@y
+procedure scan_box(@!box_context:integer);
+ {the next input should specify a box or perhaps a rule}
+begin @<Get the next non-blank non-relax...@>;
+if cur_cmd=make_box then begin_box(box_context)
+else if (box_context>=leader_flag)and((cur_cmd=hrule)or(cur_cmd=vrule)) then
+ begin cur_box:=scan_rule_spec; box_end(box_context);
+@z
+@x module 1086
+pop_nest; box_end;
+@y
+pop_nest; box_end(saved(0));
+@z
+@x module 1117
+else begin incr(save_ptr); saved(-1):=0; scan_left_brace;
+ new_save_level(disc_group); push_nest; mode:=-hmode; space_factor:=1000;
+@y
+else begin incr(save_ptr); saved(-1):=0; new_save_level(disc_group);
+ scan_left_brace; push_nest; mode:=-hmode; space_factor:=1000;
+@z
+@x module 1119
+incr(saved(-1)); scan_left_brace; new_save_level(disc_group);
+@y
+incr(saved(-1)); new_save_level(disc_group); scan_left_brace;
+@z
+@x module 1167
+mmode+vcenter: begin scan_spec; new_save_level(vcenter_group); normal_paragraph;
+@y
+mmode+vcenter: begin scan_spec(vcenter_group,false); normal_paragraph;
+@z
+@x module 1172
+scan_left_brace; push_math(math_choice_group);
+@y
+push_math(math_choice_group); scan_left_brace;
+@z
+@x module 1174
+incr(saved(-1)); scan_left_brace; push_math(math_choice_group);
+@y
+incr(saved(-1)); push_math(math_choice_group); scan_left_brace;
+@z
+@x module 1241
+ if global then saved(0):=box_flag+256+cur_val
+ else saved(0):=box_flag+cur_val;
+ scan_optional_equals; scan_box;
+@y
+ if global then n:=256+cur_val@+else n:=cur_val;
+ scan_optional_equals; scan_box(box_flag+n);
+@z
+
+372. Bugfix 339 didn't go far enough (found by Sch\"opf and Mittelbach).
+@x module 516 [NOTE: THIS AFFECTS ALMOST ALL CHANGE FILES!]
+@ And here's the second.
+@^system dependencies@>
+
+@p function more_name(@!c:ASCII_code):boolean;
+begin if c=" " then more_name:=false
+else begin if (c=">")or(c=":") then
+ begin area_delimiter:=pool_ptr; ext_delimiter:=0;
+ end
+ else if (c=".")and(ext_delimiter=0) then ext_delimiter:=pool_ptr;
+ str_room(1); append_char(c); {contribute |c| to the current string}
+@y
+@ And here's the second. The string pool might change as the file name is
+being scanned, since a new \.{\\csname} might be entered; therefore we keep
+|area_delimiter| and |ext_delimiter| relative to the beginning of the current
+string, instead of assigning an absolute address like |pool_ptr| to them.
+@^system dependencies@>
+
+@p function more_name(@!c:ASCII_code):boolean;
+begin if c=" " then more_name:=false
+else begin str_room(1); append_char(c); {contribute |c| to the current string}
+ if (c=">")or(c=":") then
+ begin area_delimiter:=cur_length; ext_delimiter:=0;
+ end
+ else if (c=".")and(ext_delimiter=0) then ext_delimiter:=cur_length;
+@z
+@x module 517 [NOTE: THIS DOES TOO, AND SO DOES THE NEXT!]
+else begin cur_area:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=area_delimiter+1;
+@y
+else begin cur_area:=str_ptr;
+ str_start[str_ptr+1]:=str_start[str_ptr]+area_delimiter; incr(str_ptr);
+@z
+@x ibid
+else begin cur_name:=str_ptr; incr(str_ptr);
+ str_start[str_ptr]:=ext_delimiter; cur_ext:=make_string;
+@y
+else begin cur_name:=str_ptr;
+ str_start[str_ptr+1]:=str_start[str_ptr]+ext_delimiter-area_delimiter-1;
+ incr(str_ptr); cur_ext:=make_string;
+@z
+
+373. Allow multiple hyphenmins in the same paragraph (Mike Ferguson).
+@x module 212, two new fields for list_state_record
+@y
+ @!lhm_field,@!rhm_field: quarterword;
+@z
+@x module 213, two new macros to access those fields
+@y
+@d lhmin==cur_list.lhm_field {\.{\\lefthyphenmin} at start of paragraph}
+@d rhmin==cur_list.rhm_field {\.{\\righthyphenmin} at start of paragraph}
+@z
+@x module 215, two new initializations
+@y
+lhmin:=0; rhmin:=0;
+@z
+@x module 218
+ if nest[p].ml_field<0 then print(" (\output routine)");
+@y
+ if m=hmode then@+if(nest[p].lhm_field<>2)or(nest[p].rhm_field<>3)then
+ begin print(" (hyphenmin "); print_int(nest[p].lhm_field); print_char(",");
+ print_int(nest[p].rhm_field); print_char(")");
+ end;
+ if nest[p].ml_field<0 then print(" (\output routine)");
+@z
+@x module 891
+l_hyf:=left_hyphen_min-1;@+if l_hyf<0 then l_hyf:=0;
+r_hyf:=right_hyphen_min-1;@+if r_hyf<0 then r_hyf:=0;
+min_hyf:=l_hyf+r_hyf+2; cur_lang:=0;
+@y
+l_hyf:=lhmin; r_hyf:=rhmin; cur_lang:=0;
+@z
+@x module 892
+@!l_hyf,@!r_hyf,@!min_hyf:integer; {limits on fragment sizes}
+@y
+@!l_hyf,@!r_hyf:integer; {limits on fragment sizes}
+@z
+@x module 894
+begin if min_hyf>63 then goto done1;
+prev_s:=cur_p; s:=link(prev_s);
+if s<>null then
+ begin @<Skip to node |ha|, or |goto done1| if no hyphenation
+ should be attempted@>;
+ @<Skip to node |hb|, putting letters into |hu| and |hc|@>;
+ @<Check that the nodes following |hb| permit hyphenation and that at least
+ |min_hyf| letters have been found, otherwise |goto done1|@>;
+@y
+begin prev_s:=cur_p; s:=link(prev_s);
+if s<>null then
+ begin @<Skip to node |ha|, or |goto done1| if no hyphenation
+ should be attempted@>;
+ if l_hyf+r_hyf>63 then goto done1;
+ @<Skip to node |hb|, putting letters into |hu| and |hc|@>;
+ @<Check that the nodes following |hb| permit hyphenation and that at least
+ |l_hyf+r_hyf| letters have been found, otherwise |goto done1|@>;
+@z
+@x module 899
+if hn<min_hyf then goto done1;
+@y
+if hn<l_hyf+r_hyf then goto done1;
+@z
+@x module 902
+for j:=l_hyf+1 to hn-r_hyf-1 do if odd(hyf[j]) then goto found1;
+@y
+for j:=l_hyf to hn-r_hyf do if odd(hyf[j]) then goto found1;
+@z
+@x module 923
+for j:=0 to hn-r_hyf do
+@y
+for j:=0 to hn-r_hyf+1 do
+@z
+@x ibid
+found: for j:=0 to l_hyf do hyf[j]:=0;
+for j:=0 to r_hyf do hyf[hn-j]:=0
+@y
+found: for j:=0 to l_hyf-1 do hyf[j]:=0;
+for j:=0 to r_hyf-1 do hyf[hn-j]:=0
+@z
+@x module 1091 begins with a new subroutine
+@y
+function norm_min(@!h:integer):small_number;
+begin if h<=0 then norm_min:=1@+else if h>=63 then norm_min:=63@+
+else norm_min:=h;
+end;
+@z
+@x module 1091 then uses the new subroutine
+push_nest; mode:=hmode; space_factor:=1000; clang:=0;
+@y
+lhmin:=norm_min(left_hyphen_min); rhmin:=norm_min(right_hyphen_min);
+push_nest; mode:=hmode; space_factor:=1000; clang:=0;
+@z
+@x module 1341
+@d stored_language(#)==mem[#+1].int {language number, in the range |0..255|}
+@y
+@d what_lang(#)==link(#+1) {language number, in the range |0..255|}
+@d what_lhm(#)==type(#+1) {minimum left fragment, in the range |1..63|}
+@d what_rhm(#)==subtype(#+1) {minimum right fragment, in the range |1..63|}
+@z
+@x module 1356
+ print_int(stored_language(p));
+@y
+ print_int(what_lang(p)); print(" (hyphenmin ");
+ print_int(what_lhm(p)); print_char(",");
+ print_int(what_rhm(p)); print_char(")");
+@z
+@x modules 1362 and 1363
+@ @<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=
+if subtype(cur_p)=language_node then cur_lang:=stored_language(cur_p)
+
+@ @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>=
+if subtype(s)=language_node then cur_lang:=stored_language(s)
+@y
+@ @d adv_past(#)==@+if subtype(#)=language_node then
+ begin cur_lang:=what_lang(#); l_hyf:=what_lhm(#); r_hyf:=what_rhm(#);@+end
+
+@<Advance \(p)past a whatsit node in the \(l)|line_break| loop@>=@+
+adv_past(cur_p)
+
+@ @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>=@+
+adv_past(s)
+@z
+@x module 1376
+ stored_language(tail):=l; clang:=l;
+@y
+ what_lang(tail):=l; clang:=l;@/
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@z
+@x module 1377
+ stored_language(tail):=clang;
+@y
+ what_lang(tail):=clang;
+ what_lhm(tail):=norm_min(left_hyphen_min);
+ what_rhm(tail):=norm_min(right_hyphen_min);
+@z
+
+374. Make \par and end_template definitely non-character (Marc van Leeuwen)
+@x module 14 gets a new line
+@y
+if mem_top<256+11 then bad:=7; {we will want |null_list>255|}
+@z
+@x module 334
+primitive("par",par_end,0); par_loc:=cur_val; par_token:=cs_token_flag+par_loc;
+@y
+primitive("par",par_end,256); {cf. |scan_file_name|}
+par_loc:=cur_val; par_token:=cs_token_flag+par_loc;
+@z
+
+375. Alignments must be more robust to prevent crashes (Marc van Leeuwen)
+@x module 324
+else if token_type=u_template then align_state:=0;
+@y
+else if token_type=u_template then
+ if align_state>500000 then align_state:=0
+ else fatal_error("(interwoven alignment preambles are not allowed)");
+@.interwoven alignment preambles...@>
+@z
+@x module 782
+if (cur_cmd=assign_glue)and(cur_chr=glue_base+tab_skip_code) then
+@y
+if cur_cmd=endv then
+ fatal_error("(interwoven alignment preambles are not allowed)");
+@.interwoven alignment preambles...@>
+if (cur_cmd=assign_glue)and(cur_chr=glue_base+tab_skip_code) then
+@z
+@x module 791
+p:=link(q);
+@y
+if align_state<500000 then
+ fatal_error("(interwoven alignment preambles are not allowed)");
+@.interwoven alignment preambles...@>
+p:=link(q);
+@z
+
+376. Avoid kern removal in discretionary breaks (Marc van Leeuwen)
+@x module 815
+label done,done1,done2,done3,done4,continue;
+@y
+label done,done1,done2,done3,done4,done5,continue;
+@z
+@x module 866
+glue_node: begin @<If node |cur_p| is a legal breakpoint, call |try_break|@>;
+ @<Update the active widths by including the glue in |glue_ptr(cur_p)|@>;
+@y
+glue_node: begin @<If node |cur_p| is a legal breakpoint, call |try_break|;
+ then update the active widths by including the glue in |glue_ptr(cur_p)|@>;
+@z
+@x ibid
+disc_node: @<Try to break after a discretionary fragment@>;
+@y
+disc_node: @<Try to break after a discretionary fragment, then |goto done5|@>;
+@z
+@x ibid
+end
+@y
+done5:end
+@z
+Combine modules 868 and 869 into a single module, with a semicolon between.
+@x module 870 (which becomes module 869) gets ... in its title
+@y and the following new code just before its final "end":
+r:=replace_count(cur_p); s:=link(cur_p);
+while r>0 do
+ begin @<Add the width of node |s| to |act_width|@>;
+ decr(r); s:=link(s);
+ end;
+prev_p:=cur_p; cur_p:=s; goto done5;
+@z
+@x Now module 871 becomes 870, and we add a new (very similar) module 871:
+@y
+@ @<Add the width of node |s| to |act_width|@>=
+if is_char_node(s) then
+ begin f:=font(s);
+ act_width:=act_width+char_width(f)(char_info(f)(character(s)));
+ end
+else case type(s) of
+ ligature_node: begin f:=font(lig_char(s));
+ act_width:=act_width+
+ char_width(f)(char_info(f)(character(lig_char(s))));
+ end;
+ hlist_node,vlist_node,rule_node,kern_node:
+ act_width:=act_width+width(s);
+ othercases confusion("disc4")
+@:this can't happen disc4}{\quad disc4@>
+ endcases
+@z
+@x module 877
+@!disc_break:boolean; {was the current break at a discretionary node?}
+@y
+@!disc_break:boolean; {was the current break at a discretionary node?}
+@!post_disc_break:boolean; {and did it have a nonempty post-break part?}
+@z
+@x ibid
+if cur_p<>null then @<Prune unwanted nodes at the beginning of the next line@>;
+@y
+if cur_p<>null then if not post_disc_break then
+ @<Prune unwanted nodes at the beginning of the next line@>;
+@z
+@x module 881
+q:=cur_break(cur_p); disc_break:=false;
+@y
+q:=cur_break(cur_p); disc_break:=false; post_disc_break:=false;
+@z
+@x module 883
+ if not is_char_node(s) then if next_break(cur_p)<>null then
+ if cur_break(next_break(cur_p))=s then s:=r;
+@y that subtle bug is no longer possible so we can remove the code
+@z
+@x module 884
+link(s):=r; r:=post_break(q); post_break(q):=null;
+@y
+link(s):=r; r:=post_break(q); post_break(q):=null; post_disc_break:=true;
+@z
+
+377. Pick up a few discretionary hyphens that were lost because of
+the new (cautious) algorithm.
+@x module 914
+@ @d advance_major_tail==begin major_tail:=link(major_tail); incr(r_count);
+ end
+
+@<Create and append a discretionary node as an alternative...@>=
+begin r:=get_node(small_node_size);
+@y
+@ In this repeat loop we will insert another discretionary if |hyf[j-1]| is
+odd, after both branches of the previous discretionary end at position |j-1|.
+Strictly speaking, we aren't justified in doing this, because we don't know
+that a hyphen after |j-1| is truly independent of those branches. But in almost
+all applications we would rather not lose a potentially valuable hyphenation
+point. (Consider the word `difficult', where the letter `c' is in position |j|.)
+
+@d advance_major_tail==begin major_tail:=link(major_tail); incr(r_count);
+ end
+
+@<Create and append a discretionary node as an alternative...@>=
+repeat r:=get_node(small_node_size);
+@z
+@x ibid
+i:=hyphen_passed;
+@y
+i:=hyphen_passed; hyf[i]:=0;
+@z
+@x ibid
+end
+@y
+hyphen_passed:=j-1; link(hold_head):=null;
+until not odd(hyf[j-1])
+@z
+
+378. Undumped trie must also be dumpable again (Breitenlohner, 11 Dec 89)
+@x module 1325
+undump_size(0)(trie_size)('trie size')(j); {|trie_max|}
+for k:=0 to j do undump_hh(trie[k]);
+undump_size(0)(trie_op_size)('trie op size')(j); {|trie_op_ptr|}
+@y
+undump_size(0)(trie_size)('trie size')(j); @+init trie_max:=j;@+tini
+for k:=0 to j do undump_hh(trie[k]);
+undump_size(0)(trie_op_size)('trie op size')(j); @+init trie_op_ptr:=j;@+tini
+@z
+@x ibid
+k:=256;
+while j>0 do
+ begin undump(0)(k-1)(k); undump(1)(j)(x); j:=j-x; op_start[k]:=qo(j);
+@y
+init for k:=0 to 255 do trie_used[k]:=min_quarterword;@+tini
+k:=256;
+while j>0 do
+ begin undump(0)(k-1)(k); undump(1)(j)(x);@+init trie_used[k]:=qi(x);@+tini
+ j:=j-x; op_start[k]:=qo(j);
+@z
+
+379. Allow output routine to access page totals. (Suggested by Frank
+Mittelbach and Chris Rowley, December 1989)
+@x module 421
+begin if page_contents=empty then
+@y
+begin if (page_contents=empty) and (not output_active) then
+@z
+
+380. Slightly more robust recovery and detection of \output anomalies.
+(Suggested by Chris Thompson, provoked by George Russell, January 1990)
+@x module 1026
+begin if loc<>null then @<Recover from an unbalanced output routine@>;
+@y
+begin if (loc<>null) or
+ ((token_type<>output_text)and(token_type<>backed_up)) then
+ @<Recover from an unbalanced output routine@>;
+@z
+@x module 1027
+help2("Your sneaky output routine has fewer real {'s than }'s.")@/
+@y
+help2("Your sneaky output routine has problematic {'s and/or }'s.")@/
+@z
+
+381. \eqno\aftergroup*$$ should yield * after the $$ (Michael Downes, 29 Jan 90)
+@x module 1194
+ begin cur_mlist:=p; cur_style:=text_style; mlist_penalties:=false;
+@y
+ begin @<Check that another \.\$ follows@>;
+ cur_mlist:=p; cur_style:=text_style; mlist_penalties:=false;
+@z
+@x ibid
+else begin @<Check that another \.\$ follows@>;
+@y
+else begin if a=null then @<Check that another \.\$ follows@>;
+@z
+
+382. Missed a case in the 8-bit change (Wayne Sullivan, 1 Feb 1990)
+@x module 360
+ begin if (end_line_char<0)or(end_line_char>127) then incr(limit);
+@y
+ begin if end_line_char_inactive then incr(limit);
+@z
+
+383. Linebreaking needs to be more robust when total demerits get
+very high (Frank Mittelbach, 22 Feb 1990)
+@x module 830
+@!artificial_badness:boolean; {has |b| been forced to zero?}
+@y
+@!artificial_demerits:boolean; {has |d| been forced to zero?}
+@z
+@x module 833 (this change is cosmetic only)
+@!minimal_demerits:array[very_loose_fit..tight_fit] of scaled; {best total
+ demerits known for current line class and position, given the fitness}
+@!minimum_demerits:scaled; {best total demerits known for current line class
+@y
+@!minimal_demerits:array[very_loose_fit..tight_fit] of integer; {best total
+ demerits known for current line class and position, given the fitness}
+@!minimum_demerits:integer; {best total demerits known for current line class
+@z
+@x module 836 here we want to ensure that total_demerits < awful_bad
+minimum_demerits:=minimum_demerits+abs(adj_demerits);
+@y
+if abs(adj_demerits)>=awful_bad-minimum_demerits then
+ minimum_demerits:=awful_bad-1
+else minimum_demerits:=minimum_demerits+abs(adj_demerits);
+@z
+@x module 851
+begin @!stat artificial_badness:=false;@+tats@/
+@y
+begin artificial_demerits:=false;@/
+@z
+@x module 854
+ begin b:=0; {set badness zero, this break is forced}
+ @!stat artificial_badness:=true;@+tats
+ end
+@y
+ artificial_demerits:=true {set demerits zero, this break is forced}
+@z
+@x module 855
+@<Compute the demerits, |d|, from |r| to |cur_p|@>;
+@y
+if artificial_demerits then d:=0
+else @<Compute the demerits, |d|, from |r| to |cur_p|@>;
+@z
+@x module 856
+if artificial_badness then print_char("*")@+else print_int(b);
+@.*\relax@>
+print(" p="); print_int(pi);
+print(" d="); print_int(d);
+@y
+if b>inf_bad then print_char("*")@+else print_int(b);
+@.*\relax@>
+print(" p="); print_int(pi); print(" d=");
+if artificial_demerits then print_char("*")@+else print_int(d);
+@z
+@x module 859
+d:=line_penalty+b; d:=d*d;
+@y
+begin d:=line_penalty+b;
+if abs(d)>=10000 then d:=100000000@+else d:=d*d;
+@z
+@x ibid
+if abs(fit_class-fitness(r))>1 then d:=d+adj_demerits
+@y
+if abs(fit_class-fitness(r))>1 then d:=d+adj_demerits;
+end
+@z
+
+384. Math fonts may disappear outside of \eqno (Marc van Leeuwen).
+@x module 1194
+ if danger then flush_math;
+@y
+ danger:=false;
+ @<Check that the necessary fonts for math symbols are present;
+ if not, flush the current math lists and set |danger:=true|@>;
+@z
+
+385. Forgot to rule out charnode when testing for node type (Marc van Leeuwen).
+@x module 805
+ begin if type(q)=unset_node then
+ @<Set the unset box |q| and the unset boxes in it@>
+ else if type(q)=rule_node then
+ @<Make the running dimensions in rule |q| extend to the
+ boundaries of the alignment@>;
+@y
+ begin if not is_char_node(q) then
+ if type(q)=unset_node then
+ @<Set the unset box |q| and the unset boxes in it@>
+ else if type(q)=rule_node then
+ @<Make the running dimensions in rule |q| extend to the
+ boundaries of the alignment@>;
+@z
+@x module 903
+if type(hb)=ligature_node then if odd(subtype(hb)) then
+@y
+if not is_char_node(hb) then
+ if type(hb)=ligature_node then if odd(subtype(hb)) then
+@z
+@x module 1202
+ if p<>null then if type(p)=glue_node then d:=0;
+@y
+ if p<>null then if not is_char_node(p) then if type(p)=glue_node then d:=0;
+@z
+
+386. Don't change the font of punctuation before a hyphenated word
+ (Scott Allendorf, reported 7 Mar 90)
+@x module 895
+label common_ending,done,found,found1,not_found,not_found+1,exit;
+@y
+label common_ending,done,found,found1,found2,not_found,exit;
+@z
+@x module 903
+if is_char_node(ha) then
+ begin init_list:=ha; init_lig:=false; hu[0]:=qo(character(ha));
+ end
+else if type(ha)=ligature_node then
+ begin init_list:=lig_ptr(ha); init_lig:=true; init_lft:=(subtype(ha)>1);
+ hu[0]:=qo(character(lig_char(ha)));
+ if init_list=null then if init_lft then
+ begin hu[0]:=256; init_lig:=false;
+ end; {in this case a ligature will be reconstructed from scratch}
+ free_node(ha,small_node_size);
+ end
+else goto not_found+1; {no punctuation found}
+s:=cur_p; {we have |cur_p<>ha| because |type(cur_p)=glue_node|}
+while link(s)<>ha do s:=link(s);
+j:=0; goto common_ending;
+not_found+1: j:=1; s:=ha; init_list:=null;
+if not is_char_node(r) then if type(r)=ligature_node then
+ if subtype(r)>1 then
+ begin j:=0; hu[0]:=256; init_lig:=false;
+ end;
+@y
+if is_char_node(ha) then
+ if font(ha)<>hf then goto found2
+ else begin init_list:=ha; init_lig:=false; hu[0]:=qo(character(ha));
+ end
+else if type(ha)=ligature_node then
+ if font(lig_char(ha))<>hf then goto found2
+ else begin init_list:=lig_ptr(ha); init_lig:=true; init_lft:=(subtype(ha)>1);
+ hu[0]:=qo(character(lig_char(ha)));
+ if init_list=null then if init_lft then
+ begin hu[0]:=256; init_lig:=false;
+ end; {in this case a ligature will be reconstructed from scratch}
+ free_node(ha,small_node_size);
+ end
+else begin {no punctuation found; look for left boundary}
+ if not is_char_node(r) then if type(r)=ligature_node then
+ if subtype(r)>1 then goto found2;
+ j:=1; s:=ha; init_list:=null; goto common_ending;
+ end;
+s:=cur_p; {we have |cur_p<>ha| because |type(cur_p)=glue_node|}
+while link(s)<>ha do s:=link(s);
+j:=0; goto common_ending;
+found2: s:=ha; j:=0; hu[0]:=256; init_lig:=false; init_list:=null;
+@z
+
+387. Balance the parens showing on the terminal (for Lispers).
+@x module 304
+@!in_open : 0..max_in_open; {the number of lines in the buffer, less one}
+@y
+@!in_open : 0..max_in_open; {the number of lines in the buffer, less one}
+@!open_parens : 0..max_in_open; {the number of open text files}
+@z
+@x module 331
+in_open:=0; max_buf_stack:=0;
+@y
+in_open:=0; open_parens:=0; max_buf_stack:=0;
+@z
+@x module 362
+ begin print_char(")"); force_eof:=false;
+ update_terminal; {show user that file has been read}
+@y
+ begin print_char(")"); decr(open_parens);
+ update_terminal; {show user that file has been read}
+ force_eof:=false;
+@z
+@x module 537
+print_char("("); print(name); update_terminal; state:=new_line;
+@y
+print_char("("); incr(open_parens); print(name); update_terminal;
+state:=new_line;
+@z
+@x module 1334
+if job_name=0 then open_log_file;
+@y
+if job_name=0 then open_log_file;
+while open_parens>0 do
+ begin print(" )"); decr(open_parens);
+ end;
+@z
+
+388. Optimize \ifx\p\q after \let\p=\q (Marc van Leeuwen says that
+ AmS-TeX uses this a lot).
+@x module 508
+ while (p<>null)and(q<>null) do
+ if info(p)<>info(q) then p:=null
+ else begin p:=link(p); q:=link(q);
+ end;
+b:=((p=null)and(q=null));
+@y
+if p=q then b:=true
+else begin while (p<>null)and(q<>null) do
+ if info(p)<>info(q) then p:=null
+ else begin p:=link(p); q:=link(q);
+ end;
+ b:=((p=null)and(q=null));
+ end;
+@z
+@x module 538 (while we're at it, might as well optimize this too)
+begin if not input_ln(cur_file,false) then do_nothing;
+@y
+begin if input_ln(cur_file,false) then do_nothing;
+@z
+@x module 1020 (and this)
+else begin wait:=false; s:=ins_ptr(p);
+ link(last_ins_ptr(r)):=s; s:=last_ins_ptr(r);
+@y
+else begin wait:=false; s:=last_ins_ptr(r); link(s):=ins_ptr(p);
+@z
+
+389. Treat migration properly in displays (Marc van Leeuwen).
+@x module 1199 (a bad bug that really has bitten)
+adjust_tail:=adjust_head; b:=hpack(p,natural);
+@y
+adjust_tail:=adjust_head; b:=hpack(p,natural); p:=list_ptr(b);
+@z
+@x module 1204
+shift_amount(b):=s+d; append_to_vlist(b);
+if t<>adjust_head then
+ begin link(tail):=link(adjust_head); tail:=t;
+ end
+@y
+shift_amount(b):=s+d; append_to_vlist(b)
+@z
+@x module 1205
+ tail_append(new_penalty(post_display_penalty));
+ end
+else begin tail_append(new_penalty(post_display_penalty));
+ tail_append(new_param_glue(g2));
+ end
+@y
+ g2:=0;
+ end;
+if t<>adjust_head then {migrating material comes after equation number}
+ begin link(tail):=link(adjust_head); tail:=t;
+ end;
+tail_append(new_penalty(post_display_penalty));
+if g2>0 then tail_append(new_param_glue(g2))
+@z
+
+-----------Here I draw the line with respect to further changes
+
+390. Uninitialized nullfont parameters (found by Lance Carnes, 11 May 90).
+@x module 552
+hyphen_char[null_font]:="-"; skew_char[null_font]:=-1;
+@y
+hyphen_char[null_font]:="-"; skew_char[null_font]:=-1;
+bchar_label[null_font]:=non_address;
+font_bchar[null_font]:=non_char; font_false_bchar[null_font]:=non_char;
+@z
+
+391. Disable \write{\the\prevgraf} (B. Jackowski, July 1990).
+@x module 422
+begin nest[nest_ptr]:=cur_list; p:=nest_ptr;
+while abs(nest[p].mode_field)<>vmode do decr(p);
+scanned_result(nest[p].pg_field)(int_val);
+end
+@y
+if mode=0 then scanned_result(0)(int_val) {|prev_graf=0| within \.{\\write}}
+else begin nest[nest_ptr]:=cur_list; p:=nest_ptr;
+ while abs(nest[p].mode_field)<>vmode do decr(p);
+ scanned_result(nest[p].pg_field)(int_val);
+ end
+@z
+
+392. Report correct line number when buffer overflows (George Russell).
+@x module 538
+begin if input_ln(cur_file,false) then do_nothing;
+firm_up_the_line;
+if end_line_char_inactive then decr(limit)
+else buffer[limit]:=end_line_char;
+first:=limit+1; loc:=start; line:=1;
+@y
+begin line:=1;
+if input_ln(cur_file,false) then do_nothing;
+firm_up_the_line;
+if end_line_char_inactive then decr(limit)
+else buffer[limit]:=end_line_char;
+first:=limit+1; loc:=start;
+@z
+
+-------------
+Note: When making change 376, I forgot to delete the redundant
+code in module 883, and I should also have changed the name of that
+module. These cosmetic changes (and some changes to the comments)
+were made in version 3.14, in addition to the following two changes.
+-------------
+
+393. Show unprintable characters in font id's (Wayne Sullivan, Dec 1990)
+@x module 63
+print(s);
+@y
+slow_print(s);
+@z
+@x module 262 can now be spruced up
+else begin print_esc(""); slow_print(text(p));
+@y
+else begin print_esc(text(p));
+@z
+@x and module 263 likewise
+else begin print_esc(""); slow_print(text(p));
+ end;
+@y
+else print_esc(text(p));
+@z
+
+394. Avoid range check if total_pages>65535 (Eberhard Mattes, Dec 1990)
+@x module 642
+ dvi_out(total_pages div 256); dvi_out(total_pages mod 256);@/
+@y
+ dvi_out((total_pages div 256) mod 256); dvi_out(total_pages mod 256);@/
+@z
+
+395. Less confusing error message (18 Sep 91)
+@x module 436
+ begin print_err("Bad math code");
+@.Bad math code@>
+ help2("A numeric math code must be between 0 and 32767.")@/
+@y (because a \mathcode can be 32768, but not a \mathchar)
+ begin print_err("Bad mathchar");
+@.Bad mathchar@>
+ help2("A mathchar number must be between 0 and 32767.")@/
+@z
+
+396. Internal strings should not be expanded even if unprintable;
+i.e., selector=new_string => print(c)==print_char(c), print(s)==slow_print(s).
+This change completes what I began with number 393 (18 Sep 91).
+@x modules 59 and 60 (same change to both)
+ else if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+@y
+ else if selector>pseudo then
+ begin print_char(s); return; {internal strings are not expanded}
+ end
+ else if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+@z
+@x module 61
+else begin print(format_ident); print_ln;
+@y
+else begin slow_print(format_ident); print_ln;
+@z
+@x module 84
+ print(input_stack[base_ptr].name_field);
+@y
+ slow_print(input_stack[base_ptr].name_field);
+@z
+@x module 518
+begin print(a); print(n); print(e);
+@y
+begin slow_print(a); slow_print(n); slow_print(e);
+@z
+@x module 536
+print(format_ident); print(" ");
+@y
+slow_print(format_ident); print(" ");
+@z
+@x module 537
+print_char("("); incr(open_parens); print(name); update_terminal;
+@y
+print_char("("); incr(open_parens); slow_print(name); update_terminal;
+@z
+@x module 581
+ print(font_name[f]); print_char("!"); end_diagnostic(false);
+@y
+ slow_print(font_name[f]); print_char("!"); end_diagnostic(false);
+@z
+@x module 642
+ print_nl("Output written on "); print(output_file_name);
+@y
+ print_nl("Output written on "); slow_print(output_file_name);
+@z
+@x module 1261
+set_font:begin print("select font "); print(font_name[chr_code]);
+@y
+set_font:begin print("select font "); slow_print(font_name[chr_code]);
+@z
+@x module 1280
+print(s); update_terminal;
+@y
+slow_print(s); update_terminal;
+@z
+@x module 1283
+begin print_err(s);
+@y
+begin print_err(""); slow_print(s);
+@z
+@x module 1328
+print(w_make_name_string(fmt_file)); flush_string;
+print_nl(format_ident)
+@y
+slow_print(w_make_name_string(fmt_file)); flush_string;
+print_nl(""); slow_print(format_ident)
+@z
+@x module 1333
+ print(log_name); print_char(".");
+@y
+ slow_print(log_name); print_char(".");
+@z
+@x module 1339
+10: print(n);
+@y
+10: slow_print(n);
+@z
+
+397. Retain more right context for reconstructing ligatures (19 Sep 91)
+@x module 892
+@!l_hyf,@!r_hyf:integer; {limits on fragment sizes}
+@y
+@!l_hyf,@!r_hyf:integer; {limits on fragment sizes}
+@!hyf_bchar:halfword; {boundary character after $c_n$}
+@z
+@x module 897
+ c:=qo(character(s));
+@y
+ hyf_bchar:=character(s); c:=qo(hyf_bchar);
+@z
+@x module 897 again
+ s:=link(s);
+@y
+ s:=link(s); hyf_bchar:=non_char;
+@z
+@x module 898
+j:=hn; q:=lig_ptr(s);
+@y
+j:=hn; q:=lig_ptr(s);@+if q>null then hyf_bchar:=character(q);
+@z
+@x module 903
+q:=link(hb); link(hb):=null; r:=link(ha); link(ha):=null; bchar:=non_char;
+@y
+q:=link(hb); link(hb):=null; r:=link(ha); link(ha):=null; bchar:=hyf_bchar;
+@z
+
+398. Patch the previous code, which could cause double kerning (CET1, 29 Sep 91)
+@x module 897
+ hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c);
+ end
+ else if type(s)=ligature_node then
+ @<Move the characters of a ligature node to |hu| and |hc|;
+ but |goto done3| if they are not all letters@>
+ else if (type(s)<>kern_node)or(subtype(s)<>normal) then goto done3;
+ s:=link(s); hyf_bchar:=non_char;
+@y
+ hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c); hyf_bchar:=non_char;
+ end
+ else if type(s)=ligature_node then
+ @<Move the characters of a ligature node to |hu| and |hc|;
+ but |goto done3| if they are not all letters@>
+ else if (type(s)=kern_node)and(subtype(s)=normal) then hb:=s
+ else goto done3;
+ s:=link(s);
+@z
+@x module 898
+hb:=s; hn:=j;
+@y
+hb:=s; hn:=j;
+if odd(subtype(s)) then hyf_bchar:=font_bchar[hf]@+else hyf_bchar:=non_char;
+@z
+@x module 903
+if not is_char_node(hb) then
+ if type(hb)=ligature_node then if odd(subtype(hb)) then
+ bchar:=font_bchar[hf];
+@y
+@z
+
+399. Disallow \setbox in do_assignments (problem found by Robert Hunt, Nov 91)
+@x module 76
+@!deletions_allowed:boolean; {is it safe for |error| to call |get_token|?}
+@y
+@!deletions_allowed:boolean; {is it safe for |error| to call |get_token|?}
+@!set_box_allowed:boolean; {is it safe to do a \.{\\setbox} assignment?}
+@z
+@x module 77
+deletions_allowed:=true; error_count:=0; {|history| is initialized elsewhere}
+@y
+deletions_allowed:=true; set_box_allowed:=true;
+error_count:=0; {|history| is initialized elsewhere}
+@z
+@x module 1241
+ scan_optional_equals; scan_box(box_flag+n);
+@y
+ if set_box_allowed then scan_box(box_flag+n)
+ else begin print_err("Improper "); print_esc("setbox");
+@.Improper \\setbox@>
+ help2("Sorry, \setbox is not allowed after \halign in a display,")@/
+ ("or between \accent and an accented character."); error;
+ end;
+@z
+@x module 1270
+ prefixed_command;
+@y
+ set_box_allowed:=false; prefixed_command; set_box_allowed:=true;
+@z
+
+400. Defend against negative cur_mu (Wayne Sullivan, Nov 91)
+@x module 716
+begin n:=x_over_n(m,@'200000); f:=remainder;@/
+@y
+begin n:=x_over_n(m,@'200000); f:=remainder;@/
+if f<0 then
+ begin decr(n); f:=f+@'200000;
+ end;
+@z
+@x module 717
+ begin n:=x_over_n(m,@'200000); f:=remainder;@/
+@y
+ begin n:=x_over_n(m,@'200000); f:=remainder;@/
+ if f<0 then
+ begin decr(n); f:=f+@'200000;
+ end;
+@z
+
+401. Defend against `|}{|' in |\read| (Michael Downes).
+@x module 483
+ store_new_token(cur_tok);
+@y
+ if align_state<1000000 then {unmatched `\.\}' aborts the line}
+ begin repeat get_token; until cur_tok=0;
+ align_state:=1000000; goto done;
+ end;
+ store_new_token(cur_tok);
+@z
+
+402. Economize string storage under multiple \font defs (B. Jackowski)
+@x module 1257
+@!old_setting:0..max_selector; {holds |selector| setting}
+@y
+@!old_setting:0..max_selector; {holds |selector| setting}
+@!flushable_string:str_number; {string not yet referenced}
+@z
+@x module 1260
+for f:=font_base+1 to font_ptr do
+ if str_eq_str(font_name[f],cur_name)and str_eq_str(font_area[f],cur_area) then
+ begin if s>0 then
+@y
+flushable_string:=str_ptr-1;
+for f:=font_base+1 to font_ptr do
+ if str_eq_str(font_name[f],cur_name)and str_eq_str(font_area[f],cur_area) then
+ begin if cur_name=flushable_string then
+ begin flush_string; cur_name:=font_name[f];
+ end;
+ if s>0 then
+@z
+
+403. Don't look for \newlinechar within unprintable chars (B. Raichle, Nov 91)
+@x module 59
+var j:pool_pointer; {current character code position}
+@y
+var j:pool_pointer; {current character code position}
+@!nl:integer; {new-line character to restore}
+@z
+@x
+ else if selector>pseudo then
+ begin print_char(s); return; {internal strings are not expanded}
+ end
+ else if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+@y
+ else begin if selector>pseudo then
+ begin print_char(s); return; {internal strings are not expanded}
+ end;
+ if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+ nl:=new_line_char; new_line_char:=-1;
+ {temporarily disable new-line character}
+ j:=str_start[s];
+ while j<str_start[s+1] do
+ begin print_char(so(str_pool[j])); incr(j);
+ end;
+ new_line_char:=nl; return;
+ end;
+@z
+@x module 60
+label exit;
+var j:pool_pointer; {current character code position}
+begin if s>=str_ptr then s:="???" {this can't happen}
+@.???@>
+else if s<256 then
+ if s<0 then s:="???" {can't happen}
+ else if selector>pseudo then
+ begin print_char(s); return; {internal strings are not expanded}
+ end
+ else if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+j:=str_start[s];
+while j<str_start[s+1] do
+ begin print(so(str_pool[j])); incr(j);
+ end;
+exit:end;
+label exit;
+var j:pool_pointer; {current character code position}
+begin if s>=str_ptr then s:="???" {this can't happen}
+@.???@>
+else if s<256 then
+ if s<0 then s:="???" {can't happen}
+ else if selector>pseudo then
+ begin print_char(s); return; {internal strings are not expanded}
+ end
+ else if (@<Character |s| is the current new-line character@>) then
+ if selector<pseudo then
+ begin print_ln; return;
+ end;
+j:=str_start[s];
+while j<str_start[s+1] do
+ begin print(so(str_pool[j])); incr(j);
+ end;
+exit:end;
+@y
+var j:pool_pointer; {current character code position}
+begin if (s>=str_ptr) or (s<256) then print(s)
+else begin j:=str_start[s];
+ while j<str_start[s+1] do
+ begin print(so(str_pool[j])); incr(j);
+ end;
+ end;
+end;
+@z
+
+404. False boundary character logic was incorrect (found by Eberhard
+ Mattes and Bernd Raichle, 6 Feb 92)
+@x module 1036
+cur_q:=tail; cur_l:=cur_r; {or |character(lig_stack)|}
+@y the following is needed since cur_r might have been changed to non_char
+cur_q:=tail; cur_l:=character(lig_stack);
+@z
+
+405. New paragraph and resume-after-display should continue current
+ \language (Sch\"opf and Thompson, 17 July 92)
+@@@ Undo the changes to modules 212, 213, 215 in change number 373.
+@x module 218
+ if m=hmode then@+if(nest[p].lhm_field<>2)or(nest[p].rhm_field<>3)then
+ begin print(" (hyphenmin "); print_int(nest[p].lhm_field); print_char(",");
+ print_int(nest[p].rhm_field); print_char(")");
+ end;
+@y
+ if m=hmode then if (nest[p].pg_field <> @'40600000) then
+ begin print(" (language"); print_int(nest[p].pg_field mod @'200000);
+ print(":hyphenmin"); print_int(nest[p].pg_field div @'20000000);
+ print_char(","); print_int((nest[p].pg_field div @'200000) mod @'100);
+ print_char(")");
+ end;
+@z
+@x module 816
+pop_nest;
+@y prev_graf now carries the language parameters at start of horizontal mode
+init_cur_lang:=prev_graf mod @'200000;
+init_l_hyf:=prev_graf div @'20000000;
+init_r_hyf:=(prev_graf div @'200000) mod @'100;
+pop_nest;
+@z
+@x module 891
+l_hyf:=lhmin; r_hyf:=rhmin; cur_lang:=0;
+@y
+cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf;
+@z
+@x module 892
+@!cur_lang:ASCII_code; {current hyphenation table of interest}
+@!l_hyf,@!r_hyf:integer; {limits on fragment sizes}
+@y
+@!cur_lang,@!init_cur_lang:ASCII_code; {current hyphenation table of interest}
+@!l_hyf,@!r_hyf,@!init_l_hyf,@!init_r_hyf:integer; {limits on fragment sizes}
+@z
+@x module 1091
+lhmin:=norm_min(left_hyphen_min); rhmin:=norm_min(right_hyphen_min);
+push_nest; mode:=hmode; space_factor:=1000; clang:=0;@/
+@y
+push_nest; mode:=hmode; space_factor:=1000; set_cur_lang; clang:=cur_lang;
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+cur_lang;
+@z
+@x module 1200
+push_nest; mode:=hmode; space_factor:=1000; clang:=0;
+@y
+push_nest; mode:=hmode; space_factor:=1000; set_cur_lang; clang:=cur_lang;
+prev_graf:=(norm_min(left_hyphen_min)*@'100+norm_min(right_hyphen_min))
+ *@'200000+cur_lang;
+@z
+
+406. Avoid (harmless) range errors (Philip Taylor and CET1, 17 Dec 92).
+@x module 934
+var n:small_number; {length of current word}
+@!j:small_number; {an index into |hc|}
+@y
+var n:0..64; {length of current word; not always a |small_number|}
+@!j:0..64; {an index into |hc|}
+@z
+@x module 960
+var k,@!l:small_number; {indices into |hc| and |hyf|}
+@y
+var k,@!l:0..64; {indices into |hc| and |hyf|;
+ not always in |small_number| range}
+@z
+
+407. Kerns inserted via boundary chars should not disappear (William E. Baxter,
+ 25 Feb 93)
+@x module 837
+Kern nodes for accents are treated specially: They do not
+disappear at a line break.
+@y
+Kern nodes do not disappear at a line break unless they are |explicit|.
+@z
+@x ibid
+ math_node,kern_node: if subtype(s)=acc_kern then goto done
+ else break_width[1]:=break_width[1]-width(s);
+@y
+ math_node: break_width[1]:=break_width[1]-width(s);
+ kern_node: if subtype(s)<>explicit then goto done
+ else break_width[1]:=break_width[1]-width(s);
+@z
+@x module 839
+plus $l_1$, so the length from |cur_p| to |cur_p| should be $\gamma+l_0+l_1-l$,
+minus the length of nodes that will be discarded after the discretionary break.
+@y (this change and the next two should have been made long ago, with #376!)
+plus $l_1$, so the length from |cur_p| to |cur_p| should be $\gamma+l_0+l_1-l$.
+If the post-break text of the discretionary is empty, a break may also
+discard~|q|; in that unusual case we subtract the length of~|q| and any
+other nodes that will be discarded after the discretionary break.
+@z
+@x module 840
+ begin @<Add the width of node |s| to |break_width| and increase |t|,
+ unless it's discardable@>;
+ s:=link(s);
+ end;
+break_width[1]:=break_width[1]+disc_width;
+if t=0 then s:=link(v); {more nodes may also be discardable after the break}
+@y
+ begin @<Add the width of node |s| to |break_width|@>;
+ s:=link(s);
+ end;
+break_width[1]:=break_width[1]+disc_width;
+if post_break(cur_p)=null then s:=link(v);
+ {nodes may be discardable after the break}
+@z
+@x module 842 (which now has a new title)
+ hlist_node,vlist_node,rule_node:break_width[1]:=break_width[1]+width(s);
+ kern_node: if (t=0)and(subtype(s)<>acc_kern) then t:=-1 {discardable}
+ othercases confusion("disc2")
+@:this can't happen disc2}{\quad disc2@>
+ endcases;
+incr(t)
+@y
+ hlist_node,vlist_node,rule_node,kern_node:
+ break_width[1]:=break_width[1]+width(s);
+ othercases confusion("disc2")
+@:this can't happen disc2}{\quad disc2@>
+ endcases
+@z
+@x module 866
+kern_node: kern_break;
+@y
+kern_node: if subtype(cur_p)=explicit then kern_break
+ else act_width:=act_width+width(cur_p);
+@z
+@x module 868
+ else if precedes_break(prev_p) then try_break(0,unhyphenated);
+@y
+ else if precedes_break(prev_p) then try_break(0,unhyphenated)
+ else if (type(prev_p)=kern_node)and(subtype(prev_p)<>explicit) then
+ try_break(0,unhyphenated);
+@z
+@x module 879
+ if subtype(q)=acc_kern then if type(q)=kern_node then goto done1;
+@y
+ if type(q)=kern_node then if subtype(q)<>explicit then goto done1;
+@z
+
+408. Prevent boundary kern from disappearing after hyphenation (25 Feb 93)
+@x module 897
+ else if (type(s)=kern_node)and(subtype(s)=normal) then hb:=s
+@y
+ else if (type(s)=kern_node)and(subtype(s)=normal) then
+ begin hb:=s;
+ hyf_bchar:=font_bchar[hf];
+ end
+@z
+
+409. Avoid potential future bug [P Breitenlohner] (26 Jun 93)
+@x module 628 [shift_amount(leader_box)=0 now but maybe not in extensions]
+dvi_v:=save_v; dvi_h:=save_h; cur_v:=save_v;
+@y
+dvi_v:=save_v; dvi_h:=save_h; cur_v:=base_line;
+@z
+@x module 637
+dvi_v:=save_v; dvi_h:=save_h; cur_h:=save_h;
+@y
+dvi_v:=save_v; dvi_h:=save_h; cur_h:=left_edge;
+@z
+
+410. Mustn't let |non-address| depend on |font_mem_size|
+@x module 549
+@d non_address==font_mem_size {a spurious |font_index|}
+@y
+@d non_address=0 {a spurious |bchar_label|}
+@z
+@x module 916
+if bchar_label[hf]<non_address then {put left boundary at beginning of new line}
+@y
+if bchar_label[hf]<>non_address then {put left boundary at beginning of new line}
+@z
+@x module 1323, this will detect obsolete format files
+undump(0)(font_mem_size)(bchar_label[k]);
+@y
+undump(0)(fmem_ptr-1)(bchar_label[k]);
+@z
+
+411. Allow large |font_mem_size|, many font parameters.
+@x module 549
+@!font_params:array[internal_font_number] of halfword; {how many font
+@y
+@!font_params:array[internal_font_number] of font_index; {how many font
+@z
+
+412. Math kerns are explicit; this matters, after change 405 (W Carlip, Sep 94)
+@x module 717
+ width(p):=mu_mult(width(p)); subtype(p):=normal;
+@y
+ width(p):=mu_mult(width(p)); subtype(p):=explicit;
+@z
+
+413. Avoid overflow on real-to-integer conversion
+@x module 619
+@!edge:scaled; {left edge of sub-box, or right edge of leader space}
+@y
+@!edge:scaled; {left edge of sub-box, or right edge of leader space}
+@!glue_temp:real; {glue value before rounding}
+@z
+@x module 625
+@ @<Move right or output leaders@>=
+begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ rule_wd:=rule_wd+round(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ end
+ else begin if shrink_order(g)=g_order then
+ rule_wd:=rule_wd-round(float(glue_set(this_box))*shrink(g));
+@y
+@ @d vet_glue(#)== glue_temp:=#;
+ if glue_temp>float_constant(1000000000) then
+ glue_temp:=float_constant(1000000000)
+ else if glue_temp<-float_constant(1000000000) then
+ glue_temp:=-float_constant(1000000000)
+
+@<Move right or output leaders@>=
+begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_wd:=rule_wd+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_wd:=rule_wd-round(glue_temp);
+@z
+@x module 629
+@!edge:scaled; {bottom boundary of leader space}
+@y
+@!edge:scaled; {bottom boundary of leader space}
+@!glue_temp:real; {glue value before rounding}
+@z
+@x module 634
+ rule_ht:=rule_ht+round(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ end
+ else begin if shrink_order(g)=g_order then
+ rule_ht:=rule_ht-round(float(glue_set(this_box))*shrink(g));
+@y
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_ht:=rule_ht+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_ht:=rule_ht-round(glue_temp);
+@z
+
+414. final cleanup should not retain spurious reference counts (20 Mar 95)
+@x module 1335
+while open_parens>0 do
+@y
+while input_ptr>0 do
+ if state=token_list then end_token_list@+else end_file_reading;
+while open_parens>0 do
+@z
+@x module 1335, continued
+ cur_if:=subtype(cond_ptr); cond_ptr:=link(cond_ptr);
+@y
+ cur_if:=subtype(cond_ptr); temp_ptr:=cond_ptr;
+ cond_ptr:=link(cond_ptr); free_node(temp_ptr,if_node_size);
+@z
+@x module 1335, concluded
+ begin @!init store_fmt_file; return;@+tini@/
+@y
+ begin @!init for c:=top_mark_code to split_bot_mark_code do
+ if cur_mark[c]<>null then delete_token_ref(cur_mark[c]);
+ store_fmt_file; return;@+tini@/
+@z
+
+415. we need not raise hassles about two-digit years (23 Nov 98)
+@x module 1328
+print_int(year mod 100); print_char(".");
+@y
+print_int(year); print_char(".");
+@z
+
+416. \xleaders often drops the final box (Hiroshi Nakashima, 12 July 99)
+@x modules 627 and 636
+ else begin lx:=(2*lr+lq+1) div (2*lq+2); {round|(lr/(lq+1))|}
+@y
+ else begin lx:=lr div (lq+1);
+@z
+
+417. disallow 100000 unbalanced }s outside of alignment (Ralf Roth, 30 Aug 01)
+@x module 789
+to another alignment is being scanned.
+
+@<Insert the \(v)\<v_j>...@>=
+begin if scanner_status=aligning then
+@y
+to another alignment is being scanned, or when no alignment preamble is active.
+
+@<Insert the \(v)\<v_j>...@>=
+begin if (scanner_status=aligning) or (cur_align=null) then
+@z
+
+418. don't allow end-template except at end of template (Roth, 30 Aug 01)
+@x module 325
+while (state=token_list)and(loc=null) do end_token_list; {conserve stack space}
+@y
+while (state=token_list)and(loc=null)and(token_type<>v_template) do
+ end_token_list; {conserve stack space}
+@z
+@x module 390
+while (state=token_list)and(loc=null) do end_token_list; {conserve stack space}
+@y
+while (state=token_list)and(loc=null)and(token_type<>v_template) do
+ end_token_list; {conserve stack space}
+@z
+@x module 1131
+during an entire alignment, until |fin_align| removes it.
+
+@<Declare act...@>=
+procedure do_endv;
+begin if cur_group=align_group then
+@y
+during an entire alignment, until |fin_align| removes it.
+
+A devious user might force an |endv| command to occur just about anywhere;
+we must defeat such hacks.
+
+@<Declare act...@>=
+procedure do_endv;
+begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input;
+while (input_stack[base_ptr].index_field<>v_template) and
+ (input_stack[base_ptr].loc_field=null) and
+ (input_stack[base_ptr].state_field=token_list) do decr(base_ptr);
+if (input_stack[base_ptr].index_field<>v_template) or
+ (input_stack[base_ptr].loc_field<>null) or
+ (input_stack[base_ptr].state_field<>token_list) then
+ fatal_error("(interwoven alignment preambles are not allowed)");
+@.interwoven alignment preambles...@>
+ if cur_group=align_group then
+@z
+
+419. Improve rounding of glue during output.
+@x module 3
+@!@^dirty \PASCAL@>
+@y
+@!@^dirty \PASCAL@>
+
+Incidentally, \PASCAL's standard |round| function can be problematical,
+because it disagrees with the IEEE floating-point standard.
+Many implementors have
+therefore chosen to substitute their own home-grown rounding procedure.
+@z
+@x module 619
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+@!cur_glue:real; {glue seen so far}
+@!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio}
+begin cur_g:=0; cur_glue:=float_constant(0);
+this_box:=temp_ptr; g_order:=glue_order(this_box);
+@z
+@x module 625
+begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_wd:=rule_wd+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_wd:=rule_wd-round(glue_temp);
+ end;
+ end;
+@y
+begin g:=glue_ptr(p); rule_wd:=width(g)-cur_g;
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin cur_glue:=cur_glue+stretch(g);
+ vet_glue(float(glue_set(this_box))*cur_glue);
+@^real multiplication@>
+ cur_g:=round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin cur_glue:=cur_glue-shrink(g);
+ vet_glue(float(glue_set(this_box))*cur_glue);
+ cur_g:=round(glue_temp);
+ end;
+ end;
+rule_wd:=rule_wd+cur_g;
+@z
+@x module 629
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+@!cur_glue:real; {glue seen so far}
+@!cur_g:scaled; {rounded equivalent of |cur_glue| times the glue ratio}
+begin cur_g:=0; cur_glue:=float_constant(0);
+this_box:=temp_ptr; g_order:=glue_order(this_box);
+@z
+@x module 634
+begin g:=glue_ptr(p); rule_ht:=width(g);
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ rule_ht:=rule_ht+round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin vet_glue(float(glue_set(this_box))*shrink(g));
+ rule_ht:=rule_ht-round(glue_temp);
+ end;
+ end;
+@y
+begin g:=glue_ptr(p); rule_ht:=width(g)-cur_g;
+if g_sign<>normal then
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ begin cur_glue:=cur_glue+stretch(g);
+ vet_glue(float(glue_set(this_box))*cur_glue);
+@^real multiplication@>
+ cur_g:=round(glue_temp);
+ end;
+ end
+ else if shrink_order(g)=g_order then
+ begin cur_glue:=cur_glue-shrink(g);
+ vet_glue(float(glue_set(this_box))*cur_glue);
+ cur_g:=round(glue_temp);
+ end;
+ end;
+rule_ht:=rule_ht+cur_g;
+@z
+
+-----------
+420. The absolutely final change (to be made after my death)
+@x module 2
+@d banner=='This is TeX, Version 3.141592' {printed when \TeX\ starts}
+@y
+@d banner=='This is TeX, Version $\pi$' {printed when \TeX\ starts}
+@z
+When this change is made, the corresponding line should be changed in
+Volume B, and also on page 23 of The TeXbook.
+My last will and testament for TeX is that no further changes be made
+under any circumstances. Improved systems should not be called simply `TeX';
+that name, unqualified, should refer only to the program for which I have
+taken personal responsibility. -- Don Knuth
+
+ * Possibly nice ideas that will not be implemented
+
+. classes of marks analogous to classes of insertions
+
+. \showcontext to show the current location without stopping for error
+
+. \show commands to be less like errors
+
+. \everyeof to insert tokens before an \input file ends
+ (strange example: \everyeof{\noexpand} will allow things
+ like \xdef\a{\input foo}!)
+
+. generalize \leftskip and \rightskip to token lists (problems with
+ displayed math then)
+
+. generalize \widowline and \clubline to go further into a paragraph
+
+. \lastbox to remove and box a charnode if one is there
+
+. \lastbox to set a new quantity \lastboxshift, to preserve info now lost
+
+. \posttolerance for third pass of line breaking
+
+* Design errors that are too late to fix
+
+. additional parameters should be in symbol fonts to govern the space between
+ rules and text in \over, \sqrt, etc.
+
+. multilingual typesetting doesn't work properly when the \lccode changes
+ within a paragraph
+
+. large accents cannot be brought close to small letters in math mode
+
+. \hyphenation is not sensitive to \language
+
+* Bad ideas that will not be implemented
+
+. several people want to be able to remove arbitrary elements of lists,
+ but that must never be done because some of those elements (e.g. kerns
+ for accents) depend on floating point arithmetic
+
+. if anybody wants letter spacing desperately they should put it in their own
+ private version (e.g. generalize the hpack routine) and NOT call it TeX.
diff --git a/Master/texmf-doc/doc/english/knuth/errorlog.tex b/Master/texmf-doc/doc/english/knuth/errorlog.tex
new file mode 100644
index 00000000000..ff41f9b3bcd
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/errorlog.tex
@@ -0,0 +1,2914 @@
+% Appendix to the Errors of TeX paper (updated)
+% Section numbers now adjusted to TeX 3.0 equivalents
+% NB: tab marks are significant in this file, they signal continuation lines
+%\magnification=\magstephalf
+%\pageno=35
+\input logmac
+* 10 Mar 1978
+L1. Rename a few external variables to make their first six letters unique.
+D2. Initialize \\{escape_char} to $-1$, not 0 [it will be set to the
+ first character input]. @240
+L3. Fix bug: The test `$\\{id}<\O{200}$' was supposed to distinguish one-letter
+ identifiers from longer (packed) ones, but negative values of
+ \\{id} also pass this test. @356
+B4. Fix bug: I wrote `{\bf while} $\alpha\land(\beta\lor\gamma)$' when I meant
+ `{\bf while} $(\alpha\land\beta)\lor\gamma$'. @259
+R5. Initialize the input routines in |INITEX| [at this time a short,
+ separate program not under user control], in case errors occur. @1337
+E6. Don't initialize \\{mem} in |INITEX|, it wastes time. @164
+B7. Change `\\{new_line}' [which denotes a lexical scanning state] to
+ `\\{next_line}' [which denotes
+ \\{carriage_return} and \\{line_feed}] in print commands.
+F8. Include additional test `$\\{mem}[p] \ne 0\; \land$' in \\{check_mem}. @168
+M9. Fix inconsistency between the \\{eq_level} conventions of \\{macro_def} and
+ \\{eq_define}. @277
+# About six hours of debugging time today.
+# |INITEX| appears to work,
+ and the test routine got through \\{start_input},
+ \\{chcode} [the \TeX78 command for assigning a \\{cat_code}],
+ \\{get_next}, and \\{back_input} the first time.
+* 11 Mar 1978
+I10. Insert space before `|(|' on terminal when opening a new file. @537
+F11. Put `$p\gets \\{link}(p)$' into the loop of \\{show_token_list},
+ so that it doesn't loop forever. @292
+L12. Shift the last item found by \\{scan_toks} into the \\{info} field.
+ [With |SAIL| all packing of fields was done by arithmetic operations,
+ not by the compiler.] @474
+B13\>12. Fix the previous bugfix: I shifted by the wrong amount. @474
+I14. Add a feature that prints a warning when the end of a file page occurs within
+ a macro definition or call. [System dependent.] @336
+# Unintended bugs in my test routine [a format intended eventually to typeset
+ {\sl The Art of Computer Programming\/}] helped check out the
+ error recovery mechanisms.
+ For example, I had `|\lft{#}|' instead of `|\lft{##}|' inside a macro,
+ and three cases of improper |{|~and~|}| nesting.
+F15. Add the forgotten case `\\{set_font}:' to \\{eq_destroy}. @275
+C16. Change |\require| to |\input|. @376
+F17. Add code for the case $\\{cur_cmd}=0$ [later known as the case
+ `$\,t\ge\\{cs_token_flag}$'] when scanning a tokenlist. @357
+# That's the first ``big'' error I've spotted so far.
+I18. Introduce a `|d|' option in the error routine, to facilitate debugging. @84
+L19. Assign a floating-point constant \\{ignore_depth} to \\{prev_depth},
+ instead of assigning the integer constant \\{flag}
+ [since \\{prev_depth} is type \\{real} in \TeX78]. @215
+I20. Improve the readability and spacing of \\{show_node_list} output. @182,187
+F21. Set the variable $v$ before using the {\bf case} construction in
+ \\{show_node_list}, because there's one case where $v$
+ didn't receive a value [as part of the field unpacking]. @182
+# About seven hours today.
+* 12 Mar 1978
+# One hour to enter yesterday's corrections and recompile.
+# At this point \TeX\ correctly located further unintended syntax errors
+ in |acphdr| [the test file].
+I22. Insert \\{debug_help} into \\{succumb}, giving a chance to look at memory
+ before the system dies. @93
+D23. Use \\{eq_destroy} wherever necessary in \\{unsave}. @283
+L24. Change `$t \gets (t-1)$ mod 8' to `$t \gets (t-1)$ land~7' in \\{id_name},
+ since |SAIL| has $-1$~mod~$8 = -1$. [At this time, \\{id_name} is a
+ routine that unpacks control sequence names, according to a scheme
+ that will become obsolete after change \#422.]
+S25. Remove the space that appears at end of paragraph.
+ (I hadn't anticipated that.) @816
+L26. Throw away unwanted \\{line_feed} after getting a \\{carriage_return}
+ in response to \\{in_chr_w} [a system routine for
+ input from the terminal]. @83
+B27. Delete spurious call to \\{flush_list} in \\{end_token_list}. @324
+# Why did I make such a silly mistake?
+F28. Fix bug in \\{get_x_token}: I forgot to say `\\{macro_call}' (which is the
+ main point of that routine)! @380
+# While tracking that bug down, I found out incidentally that kerning is okay.
+# Also \TeX\ correctly caught an error |0p| for |0pt|.
+L29. Fix bug in \\{scan_spec} ({\bf while} instead of {\bf repeat}). @404
+M30. Make the table entries for |\hfill| and |\hskip| consistent with the
+ program conventions. @1058
+L31. Disable unforeseen coercion: When \\{scan_spec} put \\{hsize} on
+ \\{save_stack}, the value changed from \\{real} to \\{integer}. @645
+I32. Use `|*|' instead of `|-1.0|' for running dimensions
+ of rules in \\{show_node_list}. @176
+D33. Clear \\{mem}[\\{head}] to null in \\{push_nest} [in \TeX82, this
+ will be done by \\{get_avail}]. @216
+# A vrule link got clobbered because I forgot to do this.
+I34. Translate ASCII control codes to special form when displaying them. @48,68
+# Ligatures work, but \\{show_node_list} showed them funny.
+F35. Remember to clear parameters off \\{save_stack} in \\{package} routine. @1086
+# About eight hours today.
+* 13 Mar 1978
+D36. Introduce a new variable \\{hang_first} [later the sign of \\{hang_after}]. @849
+E37\>36. Simplify the new code, realizing that if $\\{hang_indent}=0$ then
+ \\{hang_first} is irrelevant. @848
+# Time sharing is very slow today, so I'm mostly reading technical reports while
+ waiting\/ {\bf three hours} for compiler, editor, and loading routine.
+# I'm not counting this as debugging time!
+# (Came back in the evening.)
+P38. Spruce up the comments in the \\{line_break} routine, which appears to be
+ almost working. @813
+D39. Rethink the setting of \\{best_line}; it's 1 too high in many cases.
+ [The final line of a paragraph was handled in a treacherous way.] @874
+D40. Compute proper initialization for
+ \\{prev_depth} when beginning an |\hbox|
+ with a paragraph inside. [This refers to a special `paragraph box'
+ construction, used when an hbox of specified size becomes overfull;
+ \TeX78 doesn't have the concept of internal vertical mode.] @1083
+D41. Also initialize \\{tail} in that case. @1083
+M42. Also put the result of line-breaking into the correct list.
+T43. Fix a typo in the \\{free_node} routine (`\\{link}' not `\\{llink}');
+ by strange chance it had been harmless until today. @130
+F44. Fix bug: \\{post_line_break} forgot to set \\{adjust_tail}. @889
+D45. Update \\{act_width} properly when looking for end of word while
+ line breaking. @866
+B46. Repair the ``tricky'' part of \\{get_node}: I used the \\{info} field
+ when I meant to say \\{llink}. @127
+# Now the |\corners| macro of |acphdr| works! [See |\setcornerrules|
+ in {\sl The \TeX book}, page 417.]
+D47. Reset \\{contrib_tail} properly in \\{build_page}. @995
+T48. Fix typo (|-| for |+|) in computation of \\{page_total}. @1004
+S49. Change the page-breaking logic: \TeX\ reached \\{fire_up} with
+ $\\{best_page_break}=\\{null}$ in one case,
+ since the badness was too bad. @1005
+M50. Perform the operation \\{delete_token_ref}(\\{top_mark}) only when
+ $\\{top_mark}\ne0$. @1012
+F51. Make \\{scan_toks} omit the initial |{| of an |\output| routine. @473
+I52. Insert a comma to make memory usage statistics look better. @639
+# About seven good hours of debugging today.
+# Tomorrow will be first-output day (I hope).
+* 14 Mar 1978
+# (Came in evening after sleeping most of day, to get computer at better time.)
+# (Some day we will have personal computers and will live more normally.)
+# 8:30pm, began to enter corrections to yesterday's problems.
+I53. Issue an error message for non-character in filename or in font name. @771
+I54. Display `|...|' for omitted stuff in \\{show_context} routine. @643
+L55. Watch out for the |SAIL| syntax `$\alpha+\beta\mathbin{\rm lsh}\gamma$';
+ it doesn't shift $\alpha+\beta$ left (only $\beta$). @464
+# That error was very hard to track down; it created a spurious link field
+ and sent $\\{hash}[0]=\null$|\beta| to the scanner!
+# I could have found this bug an hour sooner if I had looked at the correct
+ stack entries for \\{name} and \\{token_type}.
+D56. Show the correct page number when tracing pages before output is shipped. @638
+F57. Remember to nullify a box after using it. @1079
+I58. Issue an error message if\/ |\box255| isn't consumed by the output routine. @1015
+# I'm having trouble with the |BAIL| debugger;
+ it makes an illegal memory reference and dies,
+ when single-stepping past the entry to recursive procedures
+ \\{hlist_out} and \\{vlist_out}. So I have to reload and be careful
+ to go thru these procedures at high speed.
+P59. Fix bug in comment (memory parameter description said $\ge$ not $\le$). @11
+B60. Fix typo in definition of rule output (said $x,y$ not $\\{x0},\\{y0}$).
+ [This part of the code went away when |DVI| files were introduced.]
+B61. Correct the embarrassing bug in shellsort, where I said `$\le\\{str}[k]$'
+ not `$\le t$'.
+ [The first \TeX\ had to sort all output by vertical position on page.]
+M62. Make \\{start_input} set up \\{job_name} in the form needed by \\{shipout};
+ it uses obsolete conventions. @532,537
+L63. Insert |(| and |)| into the |SAIL| macro definition of \\{new_string}.
+ [This macro was for pre-|DVI| output.]
+M64. Unscramble the parameters of \\{out_rule}:
+ The declaration was $(\\{x0},\\{y0},\\{x1},\\{y1})$
+ while the call was $(\\{x0},\\{x1},\\{y0},\\{y1})$.
+# 4:30am, \TeX's first page is successfully output!
+# (It was `|\titlepage\setcpage1\corners\eject\end|'.)
+* 15 Mar 1978
+# 10:30pm. Today I'm instrumenting the line-breaking routine and putting it
+ through a bunch of tests.
+# (The inserted instrumentation had bugs that won't be mentioned here.)
+C65. Don't abort the job when \\{eq_destroy} redefines a
+ \TeX\ control sequence. @275
+# The first word of a paragraph won't be hyphenated \dots\ so be it!
+T66. Fix the typo in \\{line_break} that spoils the test for
+ `letters in the same font'. @896
+# The effect of that typo was to suppress all hyphenation attempts.
+B67\>25. Replace the space at paragraph end by fillglue, not by zero. @816
+L68. Pack the hyphen character properly into its node. @582
+T69. Fix a typo (`{\tentex\char'30}' for `|+|')
+ in the computation of \\{break_width}. @838
+M70. Change the |\end| maneuver; the present code doesn't end the job,
+ since I forgot that \\{back_input} uses \\{cur_tok}. @1054
+A71. Add a parameter to \\{try_break}, since the width is different at
+ a discretionary hyphen. [This problem will be solved differently in \TeX82,
+ when discretionaries become much more general.] @840
+F72. Bypass kern nodes in pre-hyphenation. @896
+F73. Supply code for the forgotten case `$<$ |"a"|' in pre-hyphenation.
+ [This case was later generalized to a test of \\{lc_code}.] @897
+B74. Change $\\{mem}[q]$ to $\\{prev_break}(q)$ in the
+ reverse-linking loop. @878
+# (Such blunders. Am I getting feeble-minded?)
+A75. Introduce special logic for \\{eject_penalty}; I was wrong
+ to think that forced ejection was exactly like an
+ infinitely negative penalty. @851
+A76. Use $(1+b)^2-p^2$ when computing demerits with $p<0$. @859
+# 6:30am. The line-breaking algorithm appears to be working fine
+ and efficiently.
+ On small measures (about 20 characters per line), it gives overfull boxes
+ instead of spaced out ones. Surprising but satisfactory.
+* 16 Mar 1978
+# 9pm. The plan for tonight is to test page breaking and more paragraphing.
+G77. Insert `|\topskip|' glue at beginning of page. @1001
+I78. Add `|\pausing|' feature. @363
+M79. Fix discrepancy: In \\{make_accent} I called \\{vpackage}
+ with a pointer to the first list item, but \\{vpackage} itself assumes
+ that the parameter is a pointer to that pointer. [The
+ \\{vpackage} of \TeX82 will be different.] @668
+# I checked for other lapses like that. Result: 14 calls OK, 12 NG.
+M80. Create a new temporary list head location, \\{hold_head}, since there's
+ a case where \\{vpackage} is improperly called with
+ parameter \\{temp_head}. [At this time \\{vpackage} uses \\{temp_head}
+ to make a list of all insertions found.] @1014
+# 11:30pm. The machine is tied up again.
+F81. Write code to handle charnodes in vlists; I forgot that I'd decided
+ to allow them. [Later I prohibited them again!] @669
+F82. Combine the page lists before pruning off glue
+ in \\{fire_up}; otherwise the pruning doesn't go far enough. @1017
+B83\>25. Fix typo where line-breaking starts: `\\{fill_glue}' should be
+ `\\{new_glue}(\\{fill_glue})'. @816
+I84. Add |/q| to |xspool| command (cosmetic change). [This changes a system
+ command that causes \TeX\ output to be printed on the Xerox Graphics
+ Printer (XGP), the progenitor of future laser printers;
+ the |/q| option says that the queue of printing requests should be
+ displayed on the user's terminal.] @642
+E85. Don't write a form feed after the last page of output. @642
+# To fix this, I reorganized \\{ship_out}, and it became simpler.
+T86. Correct a typo (`{\tentex\char'30}' for `|+|') in the \\{vlist_node} case
+ within \\{hlist_out}. [The output routines were quite different
+ at this time, because output went directly to the XGP.] @622
+I87. Change the message `|completed page|' to `|Completed for page|'. @638
+B88\>48. Fix yet another typo in the computation of \\{page_total}: My original
+ code said $\\{stretch}(p)$ instead of $\\{stretch}(q)$ (terrible). @1004
+P89. Document the dirty trick about \\{bot_mark}'s reference count.
+ [That trick is, fortunately, no longer useful.] @1016
+A90. Rethink the algorithm for contributing an insertion: The original code
+ tests for a page break after incrementing the totals but
+ before the \\{contrib_list} is updated. [\TeX78 handles insertions
+ in a hardwired manner that will be greatly generalized in \TeX82.]
+F91. Fix \\{get_node} again:
+ After the variable memory overflows, control falls through to \\{found}
+ instead of going to the \\{overflow} call. @125
+# I spent several hours tracking down that data structure bug!
+B92. Change \\{new_line} to \\{next_line} in yet another print command (see \#7).
+A93\>75. Amend the line-breaking algorithm:
+ |\break| in paragraph doesn't work with really bad breaks. @851
+# A problem to be diagnosed tomorrow: Each time I run the test program,
+ the amount of memory in use grows by 13 cells not returned.
+# Seven hours tonight.
+* 17 Mar 1978
+G94. Introduce \\{dead_cycles} to keep |\end| active until \\{ship_out}
+ occurs. @1054
+E95. Don't call \\{line_break} with an empty list. @1096
+S96. Take proper account of the (infinite) fillglue when computing
+ the width of a paragraph line preceding a display. @1146
+M97. Add a new parameter to \\{hpack} so that \\{line_break} won't be called
+ at the wrong time.
+ [This is for the soon-to-be-obsolete feature described in \#40.]
+L98. Give a warning message if there's an |\hfill| in the middle of a paragraph;
+ fillglue upsets the line breaker,
+ because floating-point calculations don't have sufficient accuracy. @868
+# I spent an hour looking for another bug in \TeX, but the following one was in \MF:
+ The \\{xgp_height} data in fonts had been supplied wrong.
+# It took two hours to recompile 32 fonts with proto-\MF.
+R99. Make \\{show_node_list} and \\{show_token_list}
+ more robust in the presence of software bugs. @182
+D100\>97. Do not remove nodes with \\{eject_penalty},
+ when the new parameter to \\{hpack} is \\{true}.
+E101\>97. Put a fast exit into \\{hpack}; e.g., at glue nodes, test `{\bf if}
+ \\{paragraphing} $\land$ $\langle$current width is large$\rangle$'.
+# 2am. I have to go to bed ``early'' tonight.
+* 18 Mar 1978
+# 3:30pm. (Saturday)
+I102. Add a parameter to \\{check_mem} (to suppress display unless needed). @167
+G103. Introduce a user-settable parameter |\maxdepth|, and
+ pass it as a parameter to \\{vpackage}. @668
+# I realized the need for |\maxdepth| while fixing insertions (see \#90).
+G104. Introduce a user-settable parameter for \\{line_break}: The constant
+ 2.0 in my original algorithm becomes |\jpar|
+ [later |\tolerance|], to be set like |\tracing|. @828
+D105. Reclaim the \\{eject_penalty} nodes removed during line-breaking. @879
+# (Those were the 13 extra nodes reported on Thursday.)
+# The \\{init_align} procedure worked right the first time!
+# Also \\{init_row}, \\{init_col}. But then\thinspace\dots
+S106. Rethink the command codes: \\{endv} in a token list has too high a
+ code for the assumptions of \\{get_next}. @207
+A107. Add a \\{prev_cmd} variable for processing delimited macro parameters;
+ the original algorithm loses track of braces.
+ [The rules will change slightly in \TeX82, and
+ \\{rbrace_ptr} will take on a similar function.] @400
+S108. Make the \\{get_next} routine intercept |&| and |\cr| tokens. @342
+# I'd thought I could just put |&| and |\cr| into
+ \\{big_switch} [i.e., in the stomach of \TeX, not the eyes];
+ that was a great big mistake.
+R109. Make more error checks on \\{endv}; e.g., it must not occur in
+ a macro definition or call. @780
+S110\>108. No, rethink alignments again; the new program still fails! @768
+# For the first time I can glimpse the
+ hairiness of alignment in general (e.g., `|\halign{\u#\v&...|'
+ when |\u| and |\v| are defined to include |&|'s and possible
+ alignments themselves).
+# I think there's a ``simple'' solution, by considering only whether
+ an alignment is currently active [in \S342].
+# 11:30pm. Went to bed.
+* 19 Mar 1978
+# Woke up with ``better'' idea on how to handle |&| and |\cr|.
+# (Namely, to consider a special kind of\/ |\def| whose parameters don't interrupt
+ on |&|'s and |\cr|'s.)
+# But replaced this by a much better idea (to introduce \\{align_state}).
+# 11pm. Began to use computer. Performed major surgery
+ (inserting \\{align_state} and updating the associated routines
+ and documentation).
+D111. Pop the alignment stacks in \\{fin_align}. @800
+T112\>110. Fix a (newly inserted) typo in \\{show_context}. @314
+D113\>110. Set \\{align_state} false when a live |&| or |\cr| is found.
+ [Originally \\{align_state} was of type \\{boolean}.] @789
+I114. Insert |\cr| when `|}|' occurs prematurely in an alignment. @1132
+M115. Remember to record \\{glue_stretch} when packaging an unset node. @796
+# I had a mistake in |acphdr| definition of\/ |\quoteformat|; also extra spaces.
+# My first test programs, used before today, were contrived to test macro
+ expansion, line-breaking, and page layout.
+# Next I'm using a test program based on Volume 2.
+C116. Make carriage-return, space, and tab equivalent for macro matching. @348
+F117. Omit the reference count node when displaying a mark. @176
+B118. Correct a silly slip: I wrote `\\{type_displacement}' instead of
+ `\\{value_displacement}' when packing data in a penalty node. @158
+M119. Don't go to \\{build_page} after seeing |\noindent|; \TeX\ isn't
+ ready for that.
+ [In the original program, this was an instance of a bad {\bf goto}.] @1091
+# I had undesired spaces coming thru the scanner in my macro definitions
+ of\/ |\tenpoint| [see {\sl The \TeX book}, page 414].
+# 4am. \TeX\ now knows enough to typeset page 1 of Volume 2!
+# Also it did its first ``math formula'' (namely `|$X$|') without crucial error.
+# (Except that the italic correction was missing for some reason.)
+D120. Remember to decrement \\{cur_level} in \\{fin_align}. [The routines will
+ eventually become more general and use \\{unsave} here.] @800
+D121. Remember to increment \\{cur_level} in error corrections by
+ \\{handle_right_brace}. [A better procedure will be adopted later.] @1069
+T122. Fix a typo: (`|{|' instead of `|}|') in error message for $\\{mmode}+
+ \\{math_shift}$. @1065
+R123\>99. Make \\{show_noad_list} more robust and more like the new
+ \\{show_node_list}. [The routines will be combined in \TeX82.] @690
+L124. Fix a typo in \\{char_box}: should say \\{font_info_real}.
+ [In \TeX78 a single array
+ is used for both \\{real} and \\{integer}; in \TeX82 things will be
+ \\{scaled}.] @554
+B125. Fix typos in the definitions of \\{default_rule_thickness} and
+ \\{big_op_spacing}; they shouldn't start at \\{mathex}(7). @701
+B126. Reverse the \\{before} and \\{after} conventions in math nodes. @1196
+# I had them backwards; this turned
+ hyphenation on just before math, and off just after it!
+# Seven and a half hours debugging today.
+ Got through the test program a little more.
+ But \TeX\ blew up on `|$Y+1$|'; tomorrow I hope to find out why.
+* 20 Mar 1978
+# 8pm. I decided to work next on a super-hairy formula.
+C127. Change `|\ascii|' to `|\cc|' (character code). [This name will change again
+ later, to `|\char|'.] @265
+E128. Don't bother to store a penalty node at the beginning of |$$| when
+ the paragraph-so-far fits on a single line, since such a penalty
+ has already been stored. [These conventions will change later, and
+ the |\predisplaypenalty| will always be stored.] @1203
+S129. Avoid reference to \\{tail} in \\{build_page},
+ if $\\{nest_ptr}>0$. @995
+B130. Correct a silly
+ slip in \\{math_comp} (the exact opposite of what I did in \#118). @1158
+B131. Rectify my mental lapse in \\{make_fraction}; I said \\{nucleus} instead of
+ \\{thickness}. @743
+F132. Mask off the math class when scanning delimiters. @1160
+C133. Allow an optional space after |\def{...}|. [This decision
+ will be retracted later.] @473
+# My test example is so complicated it causes the semantic stacks to overflow!
+L134. Don't test for no pages output by looking at the channel status. @642
+T135. Fix typo in definition of\/ |\mathop| (\\{open_noad} not \\{op_noad}). @1156
+A136. Rewrite \\{fin_mlist}, because `|\left(...\above...\right)|' doesn't
+ parse correctly; the |\left| goes into the numerator,
+ the |\right| into the denominator. @1184
+B137. Correct the use of \\{depth_threshold} in \\{print_subsidiary_data}:
+ Simple fields get shown while others look empty. @692
+I138\>78. Return the carriage before showing the first line of a new file
+ when pausing. @538
+M139. Fix bug: The call \\{show_noad_list}(\\{mem}[|..|]) should be
+ \\{show_noad_list}(|..|), in the \\{incompleat_noad} case
+ of \\{show_activities}. @219
+# 3am. The whole messy formula has been parsed correctly into a tree.
+# The easy part is done, now comes the harder part.
+F140. Don't shift single characters down in \\{make_op}. @749
+D141. Make \\{clean_box} return a box (as its name implies), not an hlist. @720
+# Font info still isn't quite right, it has the wrong value of \\{quad}.
+A142. Retain the italic correction when doing \\{rebox};
+ can make $\\{glue_set}\ne0$ a flag for this. [A better
+ solution will be adopted later.] @715
+B143. Fix the bug that makes \\{rebox} bomb out: $\\{value}(p)$ should be
+ $\\{value}(\\{mem}[p])$. @715
+# 6am; ten hours today. \TeX\ didn't do |$\pi\over2$| correctly, but was close.
+# I found that the \\{rebox} problem (\#142) went away when I fixed the
+ \\{clean_box} problem (\#141); but I
+ will leave the extra stuff about $\\{glue_set} \ne 0$
+ in the program anyway, just for weird cases.
+E144. Omit extra levels of boxing when possible in \\{clean_box}. @721
+# (To do this, I need to face the \\{rebox} problem anyway.)
+* 21 Mar 1978
+# 10pm. The computer is rather heavily loaded tonight.
+F145. Don't forget \\{thickness} when making a square-root sign (see \#131).
+ [The rule thickness will later be derived from the character height.] @737
+L146. Define $p$ local to the \\{make_fraction} routine. @743
+# Unwittingly using the global $p$ was a disaster.
+I147. Don't show the amount of \\{glue_set} when it's zero. @186
+D148\>142. Make \\{glue_set} nonzero in the result of \\{var_delimiter}. @706
+F149. Fix bug: The \\{math_glue} function didn't return any result. @716
+T150. Fix typo in \\{char_box} ($c$ not $w$); this caused a subscripted~$P$ to come
+ out the same width as an unsubscripted~$P$. [Later changes in the rules
+ will move this computation to \S755.] @709
+P151\>144. Revise \\{clean_box} to do operations that are needed
+ often because of the \\{rebox} change. @720
+D152. Use the new \\{clean_box} to avoid a bug in |\sqrt{\raise...}|. @737
+Q153. Change the definition of\/ |\not| so that it's a relation
+ (which will butt against the following relation). [All math
+ symbols and Greek letters are defined in |INITEX| at this
+ time, not in a changeable format definition.]
+I154. Give error message `{\tt Large delimiter must be
+ in mathex font}', instead of calling \\{confusion},
+ since the error can occur.
+ [This particular error is impossible in \TeX82.] @706
+F155. Change the use of $p$ in \\{var_delimiter}; it isn't always set when I say
+ {\bf goto} \\{found}. @706
+# Another font problem now surfaced: The mathex meta-font didn't compute \TeX\ info
+ in a machine-independent way.
+ (It took two hours to correct this.)
+D156. Don't forget to set $\\{type}(b)$ in all relevant cases of
+ \\{var_delimiter}. @708
+B157. Use the correct sign convention for \\{shift_amount} in \\{hpackage}. @653
+F158. Always kern by \\{delta} when there's no superscript. @755
+M159. Declare \\{space_table} to be $[0\,.\,.\,6,0\,.\,.\,6]$
+ not $[0\,.\,.\,7,0\,.\,.\,7]$; otherwise its entries are
+ pre\-loaded into the wrong positions. [The \\{space_table} in \TeX78 is
+ $7\times7$; it will become $8\times8$ in \TeX82,
+ represented as a string called \\{math_spacing}.] @764
+C160. Use a negative value, not zero, to represent a null delimiter.
+ [Actually zero will come back again later.] @685
+C161\>127. Change |\cc| to |\char|. @265
+L162. Don't use tricky subtraction on packed data when changing $q$ to
+ an \\{ord_noad} in \\{mlist_to_hlist}; subtraction isn't always safe. @729
+B163. Fix two typos in the \\{space_table} (|*| for |0|). @764
+F164. Initialize \\{cur_size} everywhere (I forgot it in two places). @703
+A165. Reset \\{op_noad} before resetting \\{bin_noad}. @728
+F166. Treat $\\{display_style}+\\{cramped}$ the same as \\{display_style}
+ inside \\{make_op}. @749
+B167. Shift the character correctly in the non-|\displaystyle| case of
+ \\{make_op}. @749
+# Still another font problem: The italic corrections are wrong because
+ the corresponding array was declared \\{real} in proto-\MF\ (and
+ italic corrections were used in nonstandard way in |mathex|).
+B168. Use \\{depth} instead of \\{height} in \\{var_delimiter}.
+ [Later, both were used.] @714
+Q169. Skew the accents according to the font \\{slant}. [Soon retracted.] @741
+# At this point I think nearly all the math routines have been exercised.
+# Tomorrow they should work!
+# Eight hours debugging today.
+* 22 Mar 1978
+# (Wednesday, but actually Thursday:
+ I began at midnight because I was proofreading a paper.)
+# I checked out the font access tables, slowly (i.e., all the |\mathcode|
+ and special-character name entries were catalogued).
+Q170\>169. Do {\bf not\/} consider slants after all in the math accent
+ routine, since slanted math letters are put differently into fonts. @741
+B171. Don't use $q$ for two different things simultaneously
+ in \\{make_math_accent}. @738
+F172. Fix bug in \\{compact_list} (I forgot to advance the loop variable).
+ [This procedure became unnecessary in \TeX82.]
+M173. Avoid conflict between \\{var_delimiter} and \\{mlist_to_hlist}, which
+ want to use \\{temp_head} simultaneously. @713
+T174. Fix bad typo in \\{overbar} routine ($b$ for $p$). @705
+# Finally \TeX\ got to \\{after_math} after dealing with that
+ hairy formula\thinspace\dots
+T175. Fix another bad typo: $p$ for $b$ this time. @1199
+L176. Insert more parentheses (twice) because of `|lsh|' precedence
+ in |SAIL|. @1199
+M177\>36. Use the new hanging-indentation conventions when formatting displayed
+ equations. @1199
+Q178. Recompute penalties so that break is allowed after \\{punct_noad}s. @761
+F179. Center the large delimiters vertically. @749
+Q180. Round all rule sizes (up) before drawing them. @589
+Q181. Provide more space over $x$ in $\sqrt x$, and more space atop vincula.
+ @705,737
+Q182. Make large delimiters large enough to cover formula height
+ (important for subscripts, superscripts). @762
+I183. Insert |/ntn=33| on XGP prompt message so that complex math
+ won't blow the device driver. [See \#84.]
+P184\>161. Update the comment about the meaning of\/ |\char|, since it
+ can be used in math mode. @208
+# Six hours today.
+* 23 Mar 1978
+# 11pm, Maundy Thursday.
+C185\>104. Make |\tracing| and |\jpar| follow block structure. @283
+# It took me two hours to enter yesterday's corrections,
+ because the changes were so numerous.
+M186. Fix bad call on \\{begin_token_list} when marks are to be scanned. @396
+# Now the formula looks like it should, modulo problems in fonts.
+Q187. Prevent an exponent from going below baseline + xheight/4. @758
+B188. Change \\{quad} to \\{math_quad} when finishing a display
+ (several places). @1199
+A189. Don't use \\{append_to_vlist} when putting an |\eqno| box on a separate
+ line, because the page shouldn't break at glue there.
+ [Later, the \\{append} will be used but preceded by an
+ infinite penalty.] @1205
+S190. Increase the input \\{stack_size}; \TeX\ may need to back up a lot. @11
+A191. Don't assume that $p$ always points to a glue node when
+ a page is broken. @1017
+A192. Use \\{epsilon} in \\{scan_spec} (I had used a different
+ small constant). [This was a kludge to avoid the extra
+ parameter later called \\{exactly} or \\{additional}.] @645
+R193. Introduce a new procedure \\{scan_positive_length}, to prevent
+ negative or zero lengths in \\{scan_rule_spec}.
+ [This restrictive rule will be ``overruled'' later.] @463
+B194. Fix ridiculous bug in the leaders routine of \\{vlist_out}:
+ I had the initialization {\sl inside\/} the loop! @635
+L195. Eliminate confusion between the two temp variables named $h$;
+ one is \\{real} and the other is \\{integer}. @629
+F196. Include forgotten case (\\{leader_node}) in \\{hlist_out}.
+ [Type \\{leader_node} will be absorbed
+ into \\{glue_node} in \TeX82.] @622
+F197. Don't forget to compute \\{x0} in variable horizontal rules. @624
+# Seven and a half hours today.
+# \TeX\ seems to be ready to tackle my test file based on Volume 2.
+S198. Calculate \\{y00} in horizontal rules as an integer number of pixels
+ from the baseline, so that the baseline doesn't jump. @589
+* 25 Mar 1978
+# 2am Saturday. (Might as well drop Friday.)
+D199\>185. Make \\{def_code} consistent with the new |\tracing| conventions.
+ [Many tracing options are packed into a single
+ parameter called |\tracing|.] @1233
+R200\>185. Don't allow users to change nonexistent things like |\catcode1000|. @1232
+F201\>110. Reset \\{align_state} at beginning of \\{init_align}. @774
+F202. Don't forget \\{scan_left_brace} after |\noalign|. @785
+F203\>110. Set $\\{cur_cs}\gets 0$ in \\{get_next}, after |\cr|
+ causes a switch to the $\langle v_j\rangle$ template. @342
+# Ouch, that was a big bad bug, which took me three hours to find
+ (since I thought \TeX's low-level scanning mechanism was working).
+# Note to myself: I\/ {\bf knew\/} it would be cleaner to define \\{get_next}
+ so that it sets \\{cur_cs} to zero every time it begins [i.e.,
+ in \S341, where this change will in fact be made in \TeX82].
+ But I had avoided this on grounds of efficiency in the inner loop.
+ Well, now I have earned this tiny bit of efficiency.
+D204. Prohibit the first word of an unavailable node from becoming negative.
+ [The storage allocator of \TeX78 uses
+ a negative value to signify a node that is available, just as
+ `$\\{link}=\\{max_halfword}$' will signal availability in \TeX82.] @124
+# That was another bad one, it's not my night.
+# At least I'm developing more subtle diagnostic techniques.
+M205. Remember to un-negate the top \\{save_stack} entry
+ when \\{handle_right_brace} finishes an \\{insert_group}.
+ [This routine was completely revised in \TeX82.] @1100
+F206\>185. Initialize |\jpar| [i.e., |\tolerance|]. @240
+B207. Correct the display of insertion nodes by \\{show_node_list}. @188
+R208. Prevent \\{show_token_list} from generating really long strings
+ when in a loop. @292
+D209. Increase the reference count of \\{bot_mark} when
+ \\{vpackage} finds it. [This was later the job of \\{fire_up}.] @1016
+M210. Remember that the tokenlist for a mark ends with a |}|. @1101
+D211. Don't let \\{vpackage} lose the top insert. (It fails when
+ the very first item is a |\topinsert|.) @1014
+A212. And when that stupid code is corrected, make it handle
+ insertions first-in-first-out. @1018
+# Seven hours today.
+* 26 Mar 1978
+# Easter Sunday, will work till sunrise.
+I213. Add an `|i|' feature to the \\{error} recovery routine. @87
+I214. Include a prompt. @87
+C215. Ignore space after |\noalign{...}|. @1133
+# Otherwise, things are going well tonight;
+ I'm finding more bugs in my test program than in \TeX.
+# The `|i|' feature is proving to be very helpful.
+# I increased the size of \\{mem}
+ (now $\\{lo_mem_max}=3500$, $\\{mem_max}=10000$).
+# In fact I just needed to increase it again
+ (now $\\{lo_mem_max}=4500$, $\\{mem_max}=11000$).
+R216. Make |INITEX| output \\{mem_top} for consistency checking. @1307
+A217. Calculate the size of delimiters by considering the enclosed formula's
+ distance from the axis, not from the baseline. @762
+# I'm having trouble with a |SAIL| compiler bug; I must rearrange the program,
+ more or less at random, until it
+ compiles correctly. I hope the bug isn't more severe than it appears.
+D218\>210. Don't put a new group on \\{save_stack} if a null mark is expanded.
+ [\TeX82 will remove the `|}|' from the mark text.] @386
+# I had to redo the typewriter-style font since its width tables were wrong.
+# And I increased low-memory size again to 5500, then 6500.
+# Finally the entire test program was \TeX ed. Happy Easter! Six hours today.
+* 27 Mar 1978
+# Beginning at 2:30am.
+A219. Move |\vcenter| processing to the first pass of \\{mlist_to_hlist};
+ otherwise the height, depth, subscripts, etc., are way off. @733
+C220. Omit space after closing |$$|. @1200
+# Spacing is wrong in the formula $Y_1+\cdots+Y_k$; I have to rethink the use
+ of three dots.
+G221. Make conditional thin space available to user as |\|{\tentex\char'34}.
+ [Later will retract this.] @226
+Q222. Introduce |\dispaskip| and |\dispbskip| [later called
+ |\abovedisplayshortskip| and |\belowdisplayshortskip|]. @226
+# Reminder: I need to test line-breaking with embedded math formulas.
+I223. Make sure that $\\{interaction}\ne\\{error_stop_mode}$
+ in the `|Whoa|' error [\\{fatal_error}]. @93
+B224. Fix a big mistake in the \\{style_node} routine (which points to a glue spec,
+ not to glue itself); somehow this didn't cause trouble yesterday.
+ [In \TeX78, style nodes double as placeholders for math glue
+ like thin spaces.] @732
+C225. Make |\fntfam| obey group structure. [\TeX78's |\fntfam| operation
+ is a combination of \TeX82's
+ |\textfont|, |\scriptfont|, and |\scriptscriptfont|.] @1234
+# At this point the test routine for Volume 2 works perfectly.
+# But I will change the page width in order to check harder cases.
+Q226\>178. Disable automatic line breaks after punctuation in math
+ (e.g., consider $f(x,y)$). @761
+S227. Represent italic corrections as boxes, not glue, so that they won't be broken.
+ [The |\kern| command doesn't exist yet.] @1113
+# Eight hours today.
+B228. Fix a bug that just clobbered the memory: Call \\{free_avail}, not
+ \\{free_node}, in the \\{ins_node} case of \\{vpackage}.
+ [This logic will change completely in \TeX82.] @1019
+* 29 Mar 1978
+# (Wednesday) Again beginning at 2:30am.
+Q229. Put still more space above and below fraction lines in displayed
+ formulas. @746
+G230\>189. Install an infinite penalty feature, which positively suppresses breaks;
+ use it in displayed formulas whose |\eqno| doesn't fit. @1205
+F231. Call \\{build_page} after finishing a display; and don't
+ go to the |\noindent| routine because of the next remark. @1200
+S232. Put |\parskip| glue just before a paragraph, not just after
+ (since it interferes with a penalty after). @1091
+# Although the test program gives correct output, it generates 46 locations
+ of variable-size memory and 280 of one-word memory that are not freed.
+F233. Recycle the ulists and vlists in \\{fin_align}. @801
+M234\>25. Fix bug when deleting space at end of paragraph:
+ \\{delete_glue_ref}(\\{cur_node}) not
+ \\{delete_glue_ref}(\\{value}(\\{cur_node})). @816
+# There's also a more mysterious type of uncollected garbage,
+ a \\{fraction_noad} corresponding to
+ |$p\choose$|, an \\{incompleat_noad} not completed.
+# Couldn't find that one, so I recompiled with \#233 and \#234 corrected.
+# Now it gains just 10 locations of variable-size memory and 7 of the other kind.
+I235. Extend \\{search_mem} to search \\{eqtb} also. @255
+D236\>143. Fix bug in \\{rebox} when $\\{list_ptr}(b)=0$. @715
+# The seven one-word nodes were generated by this bug;
+ \\{rebox}\kern-1pt\ put them onto a linked list starting with
+ $\\{mem}[0]$, growing at the far end!
+D237. Remember to complete each \\{incompleat_noad}. @1184
+# This solved the other mystery. I had never noticed that my test output
+ was actually wrong: |$p\choose k$| came out as `$k$'.
+# After these corrections, the test routine worked\thinspace\dots\ I feel
+ that \TeX\ is now pretty well debugged
+ (except perhaps for error recovery)---it's time to celebrate!
+* 1 Apr 1978
+I238. Don't quit after file lookup fails. @530
+* 2 Apr 1978
+P239. Add \\{\TeX_font_area}, so that it's easier to change the
+ default library area associated with a device. @514
+* 3 Apr 1978
+L240. Insert parentheses again, to cope with the precedence of\/ |lsh|
+ when packing data. (See \#55 and \#176.) @1114
+# I had never tried $\\{hmode}+\\{discretionary}$ before!
+M241. Remember that \\{back_error} requires \\{cur_tok} to be set.
+ (Problem can arise during error recovery on parameter |#|$n$
+ with $n$ out of range.) @476
+* 4 Apr 1978
+I242. Add a deletion feature to the \\{error} routine. @88
+* 5 Apr 1978
+Q243. Reset \\{space_factor} after |\/| [this was later rescinded]
+ and after math in text. @1196
+* 10 Apr 1978
+G244\>104. Replace |\jpar| and |\tracing| by a new primitive |\chpar| for parameters.
+ It allows a user to change those quantities as well as the penalties for
+ hyphens, relations, binary ops, widows. @209
+* 14 May 1978
+# Beginning to typeset a real book (Volume 2, second edition), not just a test.
+Q245. Make math in text end with spacing as if it were
+ followed by punctuation. [This rule will soon be rescinded.] @760
+F246. Insert |\times| into the hash table; I left it out by mistake.
+ [It will eventually move into |plain.tex|.]
+C247. Change the names of Scandinavian accents from |\o|, |\oslash|,
+ |\Oslash| to |\a|, |\o|, |\O|. [This will also move to |plain|.]
+* 17 May 1978
+B248. Fix a silly bug that hasn't been tweaked until today:
+ `|\halign to size|' [obsolete in \TeX82] used \\{vsize}
+ instead of \\{hsize}. @645
+* 19 May 1978
+G249. Add a |\topbaseline| feature [later called |\topskip|]. @1001
+Q250\>245. Subtract the math spacing change of May 14. @760
+A251. Skip past blanks in the \\{scan_math} procedure. [This blank-skipping
+ will eventually go into \\{scan_left_brace}.] @403
+I252. Introduce a \\{missing_brace} routine [later generalized] to improve
+ error recovery in $\\{mmode}+\\{math_shift}$, when the top
+ of \\{save_stack} isn't a \\{math_shift_group}. @1065
+Q253. Adjust the math spacing between closing parentheses and
+ Ord, Op, Open, Punct. @764
+Q254. Make the underline go further under. @735
+S255\>96. Compute the proper natural width when a displayed equation follows
+ a paragraph whose fillglue has been deleted by \\{line_break}. @1146
+* 20 May 1978
+A256. Fix the spurious value of \\{prev_depth} inside alignments. @775
+S257. Consider (and defeat) the following scenario:
+ The u and v lists are built in \\{init_align} using \\{temp_head};
+ then while scanning `|\tabskip 2pt\rt{...}|' the macro |\rt| is expanded,
+ clobbering \\{temp_head}. @779
+# That bug was more subtle than usual.
+Q258. Add the parameter \\{num3}, so that the positioning of\/ |\atop|
+ can be different from that for fractions. @700
+Q259. Add new parameters \\{delim1} and \\{delim2}, so that
+ |\comb| can use fixed size delimiters, not computed as with |\left|. @748
+* 22 May 1978
+C260\>221. Change |\|{\tentex\char'34} to |\|{\tentex\char'35} and introduce
+ |\|{\tentex\char'34} as the negative of\/ |\|{\tentex\char'35}.
+ [Later obsolete.] @226
+L261. Fix the display of negative penalty nodes; \\{show_node_list} is confused
+ when a negative value has been packed into the middle of a word. @194
+# Memory overflow just occurred with $\\{lo_mem_max}=7500$ and $\\{mem_max}=16384$.
+ So I have to go to 15-bit pointers. (A problem on 32-bit machines?)
+* 23 May 1978
+Q262. Add a new parameter \\{big_op_spacing5}, for
+ extra space above and below limits of big displayed operators. @751
+F263. Initialize \\{incompleat_noad} in |$$\halign{...}$$|. @775
+# That was another heretofore-untested operation. How much of the code
+ has not yet been exercised?
+F264\>238. Close the file when doing lookup-failure recovery. @27
+I265. Improve the error recovery for `|Extra &|'. @792
+R266. The top piece must be calculated mod 128 in \\{var_delimiter},
+ to guarantee a valid subscript range. [Obsolete in \TeX82.] @546
+B267\>252. Fix a blunder in new \\{missing_brace} code. @1065
+B268\>262. Fix a blunder in new code for limits on display operators. @751
+* 26 May 1978
+Q269. Don't insert a new penalty after an explicit penalty in math mode. @767
+# The hash table overflowed; I ought to make it much bigger.
+R270\>110. Avoid possible bad memory references in alignment
+ when there is erroneous input after |\cr|. [Instead of
+ \\{extra_info}, the value of \\{cur_align} in \TeX78 is negated,
+ because we need only distinguish |\cr| from |&|.] @789
+S271. Make the dimension parameters like |\hsize| all global, so that they can
+ be set in the |\output| routine. @279
+# This led to major simplifications, also to major surgery.
+# [But it was a kludgy decision, overruled in \TeX82.]
+D272\>94. Don't forget to set the type of the new null box in the |\end| routine. @1054
+* 27 May 1978
+# The data overflowed memory again, both low and high, doing Section 3.3.2.
+R273\>184. Mask off extra bits of\/ |\char| in math mode,
+ to avoid bad memory references. @1151
+B274. Zero out the negative |\medmuskip| in script styles. @732
+* 29 May 1978
+S275. Be prepared to handle an undefined control sequence during \\{get_x_token}.
+ (Can fix this by brute force, using \\{get_token} instead of \\{get_next}.)
+ @380
+D276. Correct the superscript shift when a single character is raised. @758
+R277\>184. Mask off all but 7 bits in |\char| routine,
+ to avoid space-factor index out of range. @435
+# More memory capacity overflows.
+E278\>22. Fix \TeX's overflow stop so that I don't have to wait for loading of the
+ |BAIL| debug routines. [System dependent.] @93
+F279. Remember to adjust the page number
+ when a file page ends in mid-macro. [System dependent.] @306
+* 5 Jun 1978
+R280. Make sure that the arguments of positioning commands don't overflow
+ their field size. @610
+I281. Report the excess amount when giving an overfull box warning. @666,677
+* 7 Jun 1978
+Q282. Use $\ge$ instead of $>$ as termination criterion in \\{var_delimiter}. @714
+R283. Disallow |\eject| in math mode. [In \TeX78, |\eject| is
+ distinct from |\break|; in horizontal mode it includes
+ \TeX82's `|\vadjust{\break}|'.] @1102
+Q284. Don't put too much clearance above |\sqrt| in text style. @737
+* 9 Jun 1978
+G285\>110. Make \\{align_state} an integer variable, not \\{boolean},
+ so that |\eqalign| can be within another |\eqalign|. @309
+C286. A |\mark| should expand its input. @1101
+* 10 Jun 1978
+E287. Provide for preloading of fonts. @1320
+L288. Close the output file before switching to edit the input file with
+ the `|e|' option. @84
+E289. Return adjustments found by \\{hpack} to free storage if
+ they're not used. [Later, \\{hpack} will detach them only
+ when they're used.] @655
+Q290. Strive for consistency between \\{make_under} and \\{make_over}.
+ @735
+* 18 Jun 1978
+B291\>236. Fix a serious error in \\{rebox}
+ (`$b$' instead of `$\\{list_ptr}(b)$'). @715
+# Strange that such a bug would now surface for the first time!
+C292. Remove |\deg| from |INITEX|, since macros suffice.
+Q293. Add an extra hyphenation penalty for two hyphenated lines in a row. @859
+* 19 Jun 1978
+S294. Introduce the `\\{no_new_control_sequence}' switch. Among other things,
+ this will prevent an undefined control sequence following \\{scan_math}
+ from clobbering the save stack. @259
+* 20 Jun 1978
+L295. Change the badness test
+ `$\\{glue}\le0.0$' to `$\\{glue}\le0.0001$'. [\TeX82 will avoid such
+ problems by calculating badness without floating point arithmetic.] @99
+R296. Force \\{badness} to be at most $10^{19}$. @108
+I297. Add \\{end_template} for better error recovery in alignments. @375
+E298\>287. Make |INITEX| more like the real \TeX; my simple scheme for
+ font preloading was no good because it left thousands of `dead'
+ words in memory. @8
+E299. Economize disk space by using internal arrays in load
+ modules that aren't being reinitialized. [System dependent.]
+E300. Move the declaration of \\{mem} to the semantics module, so that the
+ object code will be more efficient. [System dependent. The code of
+ \TeX78 was divided into separately compiled modules for syntax,
+ semantics, output, extensions, and general organization.]
+* 21 Jun 1978
+# Today I'm working on the user manual.
+C301. Disallow |\input| except in vertical mode. [I will change this in
+ \TeX82, treating |\input| as a case of expansion.] @378
+I302. Add error recovery for \\{endv} and \\{par_end} occurring in math mode.
+ @1047
+G303. Generalize |\ifT| to |\if T|. @506
+* 22 Jun 1978
+F304. Preload the |\bullet| [later done by |plain.tex|].
+D305\>256. Get the correct \\{prev_depth} at the beginning of an alignment. @775
+C306. Change |\eject| so that it ejects only once. @1000
+* 14 Jul 1978
+I307. Look in standard area if a file isn't found in the user's area. @537
+I308. Echo all online inputs in the transcript file. @71
+* 19 Jul 1978
+Q309. Equalize spacing when only one of numerator/denominator is big. @745
+Q310. Prevent subscript from getting too high above baseline. @757
+R311. Avoid infinite loop when stack overflows: \\{push_input} should say
+ `{\bf if} $\\{input_ptr}\ge\\{stack_size}\;\land\;\\{interaction}=
+ \\{error_stop_mode}$'. @321
+* 22 Jul 1978
+C312. Make |\quad| meaningful outside math mode. (All fonts must
+ be generated again!) @558
+I313. Show the nesting level at the end of \\{show_activities}.
+ [But I decided not to do this in \TeX82.] @218
+C314. Put in |\>| [namely, |\mskip\medmuskip|;
+ \TeX78 already has |\|{\tentex\char'35}, for conditional |\thinmuskip|,
+ as well as the negative amounts |\<|,~|\|{\tentex\char'34}].
+ Change the name of vector accent from |\>| to |\b|. [Math spacing
+ operators will become much more general in \TeX82.] @716
+* 25 Jul 1978
+Q315\>94. Give the correct |\hsize| and |\vsize| to the null boxes created
+ at |\end|. @1054
+A316\>94. And don't ``append'' them. [Later this was changed, so
+ that it would work better with generalized output routines.] @1054
+I317\>297. Remove the control sequence |\endv|,
+ since error recovery is now better. @375
+I318. Define another mode of tracing: It says `|OK|' and stops after
+ |\showlists|. @1298
+Q319\>244. Give better defaults to parameters. [Later done by |plain.tex|.] @209
+I320. Allow more bits in the packed representation of\/ |\showboxdepth|. @238
+I321. Scan past delimiters and/or dimensions when recovering from
+ ambiguous fractions. @1183
+R322. Reduce accent numbers modulo 128 or 512, depending on the
+ mode. @1165
+I323. Include a warning, `|(\end occurred on level ...)|'. @1335
+* 28 Jul 1978
+# (I'm writing Chapter 27 of the manual: `Recovery From Errors'.)
+I324. Improve the error message in \\{scan_digit}. [This procedure will change
+ its name to \\{scan_eight_bit_int}, when the number of registers
+ increases from 10 to~256.] @433
+I325. Don't report overfull boxes if they're less than .1~point
+ over. @666,677
+I326. Give the user extra chances to define the font, if \\{read_font_info}
+ is unsuccessful. @560
+I327. Change default recovery for bad parameter number from |#1| to |##|, since
+ |#1| won't always work and since |##| is probably intended. @479
+I328. Omit the |"Negative?"| message on things like \\{scan_char_num}. @435
+I329. Improve error recovery when a large delimiter isn't in family~3.
+ [Obsolete.]
+I330. Give a more appropriate error message when the input is `|$\right|'. @1192
+# Currently \TeX\ says `|Missing $|'!
+I331. Call \\{back_input} before the error message in \\{back_error},
+ not afterwards. @327
+* 1 Aug 1978
+I332. Give an appropriate warning when there's no input file and the user
+ types `|e|'. @84
+L333. Increase the system pushdownlist size so that the manual will compile.
+ [Procedures \\{hlist_out} and \\{vlist_out} can recurse deeply.]
+# Yesterday I distributed 45 preliminary copies of the manual; today I
+ took out the ``debugging hooks'' and put \TeX\ up as a system program.
+* 2 Aug 1978
+# I'm typing Volume 2 again (currently in Section 4.2.2). Culture shock!
+G334. Introduce a |\ragged| parameter, to indicate a degree of raggedness.
+ [Previously, ragged-right setting was performed when the
+ |\tolerance|/100 was odd! Eventually a better approach,
+ with |\rightskip| and such things, will be discovered.] @886
+Q335. Omit the `widow penalty' in one-line paragraphs. @890
+* 5 Aug 1978
+G336. Generalize |\pageno| to |\count|\<digit>. @236
+D337\>285. Update \\{align_state} when recovering from `|Missing {|' and
+ `|Extra }|' errors. @1069,1127
+I338. Show ``runaway'' tokens, making it easier to pinpoint an error. @306
+* 22 Aug 1978
+G339. Add |\predisplaypenalty|. @1203
+I340. Clarify error messages; they should indicate when something has been
+ inserted, etc. @1064
+* 23 Aug 1978
+I341\>114. Substitute `|Extra }|' for the losing `|Missing \cr|' error message. @1069
+I342\>213. Go past online insertions in \\{show_context}. @311
+Q343. Exact no penalty for breaking one line before a display. @1145
+I344\>338. Check for runaways at end of file. @362
+I345. Give error message when a macro argument begins with |}|. @395
+* 24 Aug 1978
+L346\>213. Remove extra line-feed in \\{show_context} after printing insertions.
+ [System dependent.] @318
+* 25 Aug 1978
+Q347. Leave no glue at top of page, even after |\eject|. @997
+* 27 Aug 1978
+P348. Adopt Guy Steele's new version of the \TeX\ source files. [He has
+ recently made a copy and modified it by introducing
+ compile-time switches for MIT conventions as an alternative to SUAI.
+ This is the first time that \TeX\ is being ported to another site;
+ additional switches for PARC, TENEX, TOPS10, and TOPS20 will be
+ added later, using the Steele style.]
+* 1 Sep 1978
+Q349. Don't pass over leader nodes in the \\{try_break} background
+ computation. [At this time, leaders have not yet been
+ unified with glue.] @837
+Q350\>82. Prune away all penalties at the top of a page. @997
+* 4 Sep 1978
+I351\>338. Include `|\|' in error message about a runaway argument. @306
+* 8 Sep 1978
+# I just remade all the fonts, with increased ligature field size.
+B352\>350. Insert a necessary {\bf goto} statement in the first branch of
+ the new penalty routine within \\{build_page}. @997
+* 30 Sep 1978
+M353\>338. Make the token list for runaway arguments meaningful outside
+ of \\{macro_call}. (I just had a runaway argument ending with
+ `|\lcm|', which turned out to be the
+ control sequence in hashtable location 0.) @371
+R354. Avoid infinite loop when recovering from |$$| in
+ restricted horizontal mode. @1138
+L355. Fix two hyphenation bugs related to |-ages|, |-ers|.
+ [A completely new algorithm for hyphenation will go into \TeX82.]
+Q356. Add |-est| to hyphenation routine;
+ also disable |puz-zled| and |rat-tled|, etc.
+* 4 Oct 1978
+G357. Add new primitive |\vtop|. @1087
+Q358. Treat implicit kerns properly after discretionary hyphens have been
+ inserted. @914
+* 4 Nov 1978
+Q359. Forget the half quad originally required at left and right when
+ centering displayed equations without equation numbers. @1202
+* 11 Nov 1978
+R360. Don't let the postamble come out empty. [This could occur if no fonts were
+ selected.] @642
+* 15 Nov 1978
+C361. Allow optional space after digit in \\{scan_int} routine. @444
+* 17 Nov 1978
+R362. Make the \\{check_mem} procedure slightly more robust. @167
+* 20 Nov 1978
+C363. Make the |\par| in a |\def| match the |\par| that comes automatically with
+ a blank line. (Suggested by Terry Winograd.) @351
+G364. Add new parameter |\mathsurround| for spacing before and after
+ math in text. @1196
+G365. Extend |\advance| to allow increase by other than unity. [At this
+ time it applies only to the ten |\count| registers, and it is
+ called |\advcount|.] @1238
+* 25 Nov 1978
+G366. Add a new primitive: |\unskip|. @1105
+G367. Add new primitives |\uppercase| and |\lowercase|. @1288
+* 28 Nov 1978
+M368\>338. Don't let |\mark| and \\{macro_call} interfere with each other's
+ \\{scanner_status}. @306
+M369. Omit extra |}| after \\{show_node_list} shows a |\mark|,
+ since the right brace is already there. (See \#210.) @176
+G370. Add a new primitive suggested by Terry Winograd: |\xdef|. @1218
+* 29 Nov 1978
+S371. Delete a space following |\else{...}| also in the
+ false case. [\TeX78 uses braces, not |\fi|, for conditionals.]
+D372\>320. Make |\tracing| set |\showboxbreadth| as advertised. @198
+F373. Account properly for kerns in width calculations of \\{line_break}.
+ @866
+Q374\>364. Delete a \\{math_node} at the beginning of a line. @148
+A375\>339. Guarantee that |\predisplaypenalty=10000| will suppress page breaking
+ before a display. @1005
+* 6 Dec 1978
+L376. Change the file opening statement to allow lines up to 150 characters long.
+ [System dependent.]
+* 16 Jan 1979
+F377\>365. Initialize \\{negative} properly in the |\advance| routine
+ with a |\count| as argument. @440
+* 20 Jan 1979
+R378. Try to keep complex, buggy preambles of alignments from
+ crashing the program. @789
+* 17 Feb 1979
+I379\>376. Give more detailed information when warning about a
+ long line being broken. [System dependent;
+ the buffer size in \TeX78 is very limited.]
+L380. Declare $p$ local to \\{try_break}, for the ``rare'' case code.
+ [My original program included the following comment:
+ ``This case can arise only in weird circumstances due to
+ changing line lengths, and the code may in fact never be executed.''
+ Later Michael Plass will discover that variable line lengths require an
+ entirely different algorithm, using \\{last_special_line}.]
+ @847
+F381\>334. Don't omit the raggedness correction when the
+ last line of paragraph has to shrink. [Obsolete in \TeX82.]
+* 22 Feb 1979
+F382\>363. Don't forget to return from \\{get_x_token} after finding |\par|. @351
+Q383. Add a new parameter: |\lineskiplimit|. @679
+C384. Change the syntactic sugar:
+ `|\hbox par|' replaces `|\hjust to ...{overfull}|'. [This vastly improves on
+ the old idea (see \#40), but there still is no internal vertical mode.]
+C385. Introduce new names |\hbox| and |\vbox| for |\hjust| and |\vjust|. @1071
+G386. Add a new condition: |\ifpos|. [It will later be
+ generalized to |\ifnum| and |\ifdim|.] @513
+G387. Add |vu| and |\varunit|. [\TeX82 will eventually allow arbitrary
+ internal dimensions as units of measure.] @453
+G388\>312. Add an |em| unit. @455
+C389. Legalize |\hbox spread |\<negative dimension> [since \\{scan_spec}
+ no longer uses the sign as a flag]. @645
+* 10 Mar 1979
+C390\>370. Make \\{scan_toks} expand |\count| during |\xdef|. [This will
+ change later when |\the| and |\number| are introduced.] @367
+* 23 Mar 1979
+Q391. Put only 100000\thinspace pt stretch at the end of a paragraph instead of
+ 10000000000\thinspace pt.
+ [In \TeX78, ``infinite'' glue is actually finite but large; in the
+ language of \TeX82 we would say that |\parfillskip|, which is
+ not yet user-settable, is being changed to be like |\hfil| instead of
+ like |\hfill|.] @816
+Q392. Treat the last line of a paragraph more consistently with
+ the other lines (e.g., when |\hfil| appears in mid-paragraph), by
+ effectively inserting \\{inf_penalty} at the end. @816
+* 31 Mar 1979
+S393. Ensure that penalty nodes aren't wiped out, in weird cases where
+ breaks occur at penalties that normally disappear. @879
+* 27 Apr 1979
+A394. Correct the page number count when files begin with an empty page.
+ [System dependent.]
+G395. Allow the \\{math_code} table to be changeable via |\chcode|.
+ [In \TeX82, |\chcode| will split into |\mathcode| and |\catcode|.] @1232
+I396\>332. Don't accept `|e|' after an error message if not
+ inputting from a file. @84
+* 29 May 1979
+F397. Don't call \\{end_file_reading} if you haven't already invoked
+ \\{begin_file_reading}; this could happen when trying to
+ recover from an error in \\{start_input}.@537
+* 7 Jun 1979
+A398\>306. Be sure to eject two pages,
+ when |\eject| comes just at the time another break is preferable
+ (e.g., when the page has just become too full). @1005
+* 27 Jun 1979
+I399\>354. Don't say `|You can't do that in math mode|' when the user
+ says `|$$|' in restricted horizontal mode! @1138
+* 30 Jun 1979
+G400. Add |wd|, |dp|, |ht| dimension units. @455
+I401\>307. Don't try the system area for file names whose area is explicitly
+ indicated. @537
+* 1 Jul 1979
+G402. Allow letters as (ASCII) numbers [without the |`| marker introduced
+ later]. @442
+* 2 Jul 1979
+F403. Fix a |\gdef| bug: If the control sequence was never defined before
+ [this later became the \\{restore_zero} option],
+ don't remove it at group end. @282
+* 16 Jul 1979
+I404\>320. Update \\{show_noad_list} to be like \\{show_node_list}.
+ [The two routines, originally separate, will be merged in \TeX82.] @238
+* 18 Jul 1979
+G405. Extend capacity from 32 fonts to 64 fonts if desired. @134
+Q406. Add new \\{extra_space} parameter to all text fonts (requested
+ by Frances Yao). @558
+F407. Make each \\{node_noad} print properly in \\{show_noad_list}. @183
+Q408. Make |\jpar| allow any break if it is 1000000 or more.
+ [In \TeX82, a |\tolerance| of 10000 or more allows any break.] @851
+* 23 Jul 1979
+E409. Introduce new primitives |\hfil|, |vfil|, |\hfilneg|, |\vfilneg|. @1058
+G410. Add |\ifmmode|. @501
+G411. Add |\firstmark|. @1012,1016
+C412. Allow break at leaders (horizontal mode only). @149
+* 25 Jul 1979
+I413\>213. Revise \\{error} so that online insertions work properly
+ after end-of-file errors. @336
+B414\>411. Change `{\bf if} $\\{first_mark}\ne0$' to
+ `{\bf if} $\\{first_mark}\ge0$' [because $-1$
+ is used to indicate `not yet given a value']. @1012
+* 28 Jul 1979
+C415\>370. Stop |\xdef| from expanding control sequences after |\def|'s.
+ [This decision will be rescinded later, after several more years of
+ experience with macro expansion will suggest better ways to cure
+ the problem.] @366
+I416. Change symbolic printout for control symbols. [System dependent.] @49
+L417\>308. Avoid linefeeds in the transcript file. [System dependent.]
+C418\>370. Expand |topmark|, etc., in |\xdef|. @366
+* 4 Aug 1979
+B419\>413. Fix an error introduced recently: |\par| was suddenly
+ omitted at end of page. [System dependent.]
+* 11 Aug 1979
+P420. Change error messages that use |SAIL| characters not in
+ standard ASCII. @360
+* 28 Aug 1979
+D421\>411. Move the command `$\\{first_mark}\gets-1$' from \\{vpackage}
+ to \\{fire_up}. @1012
+S422\>403. Correct a serious |\gdef| bug:
+ Control sequences don't obey a last-in-first-out
+ discipline, so \TeX\ loses things from the hash table when deleting a
+ control sequence. @259
+# To fix this, I either need to restrict \TeX\ (so that
+ |\gdef| can be used inside a group only for control sequences already
+ defined on the outer level) or need to change the hash table algorithm.
+ Although all applications of \TeX\ known to me will agree to the
+ former restriction, I've chosen the latter alternative, because it gives me
+ a chance to improve the language: Control sequences
+ of arbitrary length will now be recognized.
+D423. Make sure that \\{unsave} cannot call \\{eq_destroy}
+ with a value from the upper part of \\{eqtb}. @282
+# I noticed this long-standing bug while fixing \#422. It had very
+ low probability of causing damage (e.g., it required a certain field
+ of a floating-point number to have a certain value), but it would have
+ been devastating on the day it first showed up!
+* 29 Aug 1979
+F424. Call \\{eq_destroy} when a control sequence is |\gdef|'ed
+ after being |\def|'ed. @283
+F425\>418. Treat the first token consistently
+ when |\topmark| and its cousins are expanded in \\{scan_toks}. @477
+# Now I've checked things pretty carefully and I think \TeX\ is ``fully debugged.''
+* 25 Jan 1980
+I426\>338. Display runaway alignment preambles. @306
+G427. Introduce active characters (one-stroke control sequences).
+ [I don't yet go
+ all the way: The meanings of `|x|' and `|\x|' have to be identical.] @344
+* 7 Feb 1980
+F428\>314. Fix a glaring omission: Op space |\>| was
+ never implemented in math mode! @716
+* 25 Feb 1980
+G429. Add a new dimension `|ex|' (for units of xheight). @455
+* 3 Mar 1980
+C430\>427. Allow the control sequence |\:| to be redefined
+ [it was the `select font' operator];
+ this allows the character |:| to be active. [Obsolete.]
+* 23 Mar 1980
+# An extend-\TeX-for-the-eighties party:
+G431. Add a new |\copy| feature. @204
+G432. Add a new |\unbox| feature. @1110
+G433. Add a new |\open| feature [later |\openout|]. @1351
+G434. Add a new |\send| feature [later |\write|]. @1352.
+G435. Add a new |\leqno| feature, requested by MDS. @1204
+G436. Add a new |\ifdimen| feature [later |\ifdim|]. @513
+C437. Make |\|\<space> in vertical mode begin a paragraph. @1090
+G438. Add a new |\font| feature [replacing the silly previous convention that
+ a font must be defined when it is first selected]. @1256
+G439. Add new |\parval| and |\codeval| features [later
+ |\the|\thinspace\<whatever>\thinspace]. @413
+C440\>427. Don't let active characters gobble the following space. @344
+G441\>208. Add a new parameter to govern amount of token list dumped. [Obsolete.] @295
+G442. Add a new |\linebreak| feature [later replaced by |\break|]. @831
+* 25 Mar 1980
+# (Still working on the above, also thought of more.)
+G443. Add a new |\mskip| feature. @716
+G444. Add a new |\newname| feature (soon changed to |\let|). @1221
+G445\>430. Allow any control sequence to be redefined. @275
+I446. Send the output to the user's current file area, even when
+ input comes from elsewhere. @532
+* 27 Mar 1980
+Q447. Compute the xheight for accents in math mode from
+ family~1, not family~3. [Obsolete.]
+* 28 Mar 1980
+Q448. Increase minimum clearance between subscript and superscript. @759
+* 29 Mar 1980
+Q449\>222. When a display follows a display, the second should have the
+ `shortskip' glue. @1146
+* 4 Apr 1980
+A450\>445. Look at current token meanings when trying to recognize
+ |\tabskip| in alignment preambles. @782
+* 23 Apr 1980
+I451. Estimate the length of printed output, for the new
+ priority feature on our XGP device driver. [System dependent.]
+C452\>434. Break long |\send| lines
+ into pieces so that the file can be read in again. [System dependent.]
+* 19 May 1980
+Q453\>182. Don't make |\left| and |\right| delimiters too large; they
+ need to be only 90\% of the enclosed size. [This eventually
+ became |\delimiterfactor|.] @762
+* 21 May 1980
+G454. Add a new |\pagebreak| feature [later |\vadjust{\break}|]. @655
+* 13 Jun 1980
+# Today I'm beginning to overhaul the line-breaking routine,
+ and I'll also install miscellaneous goodies.
+G455. Allow a radical sign to be in different font positions. @737
+E456. Clear empty tokenlists off input stacks to allow deeper recursions
+ (suggested by Jim Boyce's macros for chess positions). @325
+G457. Make |\spaceskip| and |\parfillskip| changeable. @1228
+G458. Add a new parameter |\rfudge| (per request of Zippel) [later |\mag|]. @288
+G459. Add a new parameter |\loose| [later |\looseness|];
+ now parameters are allowed to take negative values. @875
+E460. Remove the variable \\{just_par}. [Obsolete; it was the \\{real} equivalent
+ of an \\{integer}].
+* 14 Jun 1980
+Q461. Install new line-breaking routines, including |\parshape|.
+ (These major changes are introduced as Michael Plass
+ and I write our article.) @813
+G462. Add a new parameter |\exhyf| [later |\exhyphenpenalty|]. @869
+* 16 Jun 1980
+S463\>444. Change conventions in \\{eqtb} so that glue is distinguishable
+ from other equivalents. @275
+A464\>444. Don't expand |\b| in |\xdef{\d\b{...}}| after |\let\d=\def|.
+ [Obsolete.]
+D465\>444. Avoid creating dead storage when doing \\{unsave} in certain regions. @275
+* 17 Jun 1980
+C466. Allow negative dimensions in rules. @138
+* 19 Jun 1980
+B467\>463. Make the new test for glue at the outer level of \\{show_eqtb}. @252
+* 27 Jun 1980
+Q468\>453. Don't let |\left| and |\right| become too small for big matrices.
+ [This eventually became |\delimitershortfall|.] @762
+* 3 Aug 1980
+Q469. Don't move extra-wide, numbered equations flush left unless
+ they begin with glue. @1202
+* 15 Sep 1980
+M470\>461. Say `$\ge\\{fz}$' instead of `$>\\{fz}$' in the pre-hyphenation
+ routine; I'd forgotten my definition of \\{fz} [a variable used to test
+ for a sequence of lowercase letters in the same font]. @897
+R471\>395. Check the range of the index in |\chcode| before saving the old value.
+ @1232
+* 18 Sep 1980
+D472\>457. Don't forget to increase the reference count to |\parfillskip|,
+ or it will mysteriously vanish. @816
+* 19 Sep 1980
+C473\>412. Make leaders break like glue in both horizontal and vertical modes.
+ @149
+Q474\>364. Make |\mathsurround| break properly at left and right end of lines.
+ @879
+* 13 Oct 1980
+I475\>461. Remove spurious overfull boxes generated when the looseness criterion
+ fails. [Obsolete.]
+A476\>461. Redesign the iteration for looseness; breakpoints were not chosen
+ optimally. @875
+E477\>461. Avoid storing a lot of breakpoints when they are dominated by
+ others. @836
+B478\>366. Don't say `\\{cur_node}' when you mean `\\{mem}[\\{cur_node}]'. @1105
+Q479\>461. Prefer the oldest break to the youngest break
+ when two break nodes have the same total demerits. @836
+L480\>461. Don't make badness too big for floating-point calculations,
+ when forced to make an overfull box. [Obsolete.]
+* 10 Dec 1980
+R481. Make it impossible to get unmatched `|}|' in a delimited macro
+ argument. @392
+G482. Add new |\topsep| and |\botsep| features. [These are \TeX78's
+ way to put space at the edge of inserts,
+ replaced in \TeX82 by the |\skip| register corresponding
+ to an |\insert| class.] @1009
+* 6 Jan 1981
+P483. Install new routines for reading the font metrics, using Ramshaw's
+ |TFM| files instead of\/ |TFX| files. @539
+I484. Abort after reporting 100 errors, if not pausing on errors. @82
+G485. Add new |\spacefactor| and |\specskip| and |\skip| primitives.
+ [At this time we write `|\specskip3=10pt|' and `|\skip3|' for what
+ will become `|\skip3=10pt|' and `|\hskip\skip3|' in \TeX82.] @1060
+G486\>366. |\unskip| is now allowed in internal vertical mode. @1105
+* 26 Jan 1981
+B487\>482. Don't say `\\{mem}[$q$]' when you mean `$q$'. (See \#143 and \#478.) @1009
+* 27 Feb 1981
+I488\>417. Put some linefeeds back into the transcript file, in order
+ to prevent overprinting in listings. [System dependent.]
+G489. Add a new |\dpenalty| feature [later |\postdisplaypenalty|]. @1205
+G490. Add the dimension |cc| for European users. @458
+C491. Make \\{scan_keyword} match uppercase letters as alternatives
+ to lowercase ones (suggested by Barbara Beeton's experiments
+ with |\uppercase|). @407
+I492. Add nonstop mode so that overnight batch processing is possible. @73
+* 2 Mar 1981
+S493\>422. Fix a still more serious |\gdef| bug: The generality
+ of\/ |\gdef| almost makes it a crime to
+ forget {\sl any\/} control sequence names, ever! (The previous bug was
+ only the tip of an iceberg.) @259
+I494. Issue warning message at the end of a file page if nesting level isn't zero.
+ [System dependent.]
+* 5 Mar 1981
+I495. Keep track of maximum memory usage, for statistical
+ reporting. [Obsolete.] @125
+Q496\>350. Prune away glue and penalties at top of page after marks, sends,
+ inserts. @1000
+G497. Allow |\mark| in horizontal mode. [Later it will
+ be |\vadjust{\mark...}|.] @655
+C498. Allow optional space before a required left brace, e.g., |\if AA {...}|.
+ [See \#251.] @403
+I499. Issue an incomplete |\if| error, to help catch a bad |\if|. @336
+* 17 Mar 1981
+I500\>494. Omit the warning message at end of a file page unless
+ the nesting level has changed on that page. [System dependent.]
+Q501\>310. Fix the spacing when there is a very tall subscript with
+ a superscript. @759
+* 20 Mar 1981
+S502\>371. Make space-eating after |\else| fully consistent between the
+ true and false cases. [Obsolete.]
+* 24 Mar 1981
+B503\>496. Change \\{glue_spec_size} to \\{ins_spec_size}
+ in \\{vpackage} [where insertions are done]. [Obsolete.]
+* 5 Apr 1981
+B504\>501. Fix a typo (`|+|' instead of `|-|') in the new subscript code;
+ this shifted certain subscripts down instead of up. @759
+* 18 Apr 1981
+G505. Make leaders with rules of specified size act like variable rules.
+ @626,635
+* 29 Apr 1981
+A506\>461. Don't consider $\\{badness}>\\{threshold}$ at a line |\break|
+ except in an emergency. @854
+* 13 Jul 1981
+C507\>402. Allow other characters as numbers. @442
+R508\>294. Avoid dead storage if a \\{no_new_control_sequence} error occurs.
+ [Obsolete.] @259
+G509. Add a new |\ifx| feature. @507
+G510. Add new features |\xleaders| and |\cleaders|. @626,635
+* 14 Jul 1981
+S511\>507. Amend the new code for constants;
+ the `|.|' in `|.5|' is thought to mean \O{056}! @442
+L512\>507. And fix an egregious blunder in that code: New commands at the
+ end of a procedure are ignored when earlier statements
+ exit via {\bf return}. @442
+* 4 Aug 1981
+P513. Accept alphabetic codes for all online error recovery options,
+ instead of insisting on control codes like line feed or form feed.
+ [The original error-recovery codes were suggested by the
+ conventions of the |SAIL| compiler.] @84
+G514. Add a new |\thebox| feature [later |\lastbox|]. @1079
+* 7 Aug 1981
+G515. Add |fil|, |fill|, and |filll| as units for glue stretching
+ or shrinking. @454
+I516. Suppress the overfull box error when shrinkage amount is negative. @664
+* 9 Aug 1981
+Q517. Let unset boxes inherit the size of their parent in alignments. @810
+* 12 Apr 1982
+F518. Make |INITEX| dump out the \\{font_dsize} array needed by
+ the new |DVI| output module. @1322
+* 1 May 1982
+S519\>151. Fix \\{clean_box} so that \\{mlist_to_hlist} cannot make
+ $\\{link}(q)=0$ and $\\{type}(q)=\\{glue_node}$. @720
+# [That was the historic final change to \TeX78. All subsequent entries
+ in this log refer to \TeX82.]
+* 15 Jul 1982
+# Finished draft of test program and began debugging about 1430
+ [2:30\thinspace pm]. Taking my time.
+BX1. Change \\{eqtb}[\\{cur_font}] to \\{eqtb}[\\{cur_font_loc}]. @232
+# Not logging changes to the exposition.
+# Compile time is about 2 minutes CPU, times 5 for time-sharing;
+ add another half minute for linking and loading.
+# Hash table and \\{get_next} seem to be working, with no changes needed!
+# Time out 1630--1815 for Jill's birthday party.
+LX2. Insert {\bf begin} \dots~{\bf end} around \\{dump_int} macro. @1305
+IX3. Print two blank spaces before date in \\{open_log_file}. @536
+AX4. Update $x$ and \\{var_used} outside the {\bf for} loop. @1311
+BX5. Change {\bf if} $=$ to {\bf if} $\ne$ as loop exit condition. @1315,1316
+# The |TRIP| test should preload more fonts.
+LX6. Insert {\bf begin} \dots~{\bf end} around statistics output. @1334
+FX7. Must \\{get_x_token} when scanning a number. @445
+IX8. Interactive \\{debug_help} needs to print a newline. @1338
+FX9. Include \\{ignore_spaces} and \\{math_accent} in \\{print_cmd_char} cases. @266
+IX10. Don't call \\{confusion} when \\{print_cmd_char} sees unknown code. @298
+# Compiler bug causes stack overflow. Retiring for the night at 2145.
+* 16 Jul 1982
+# Starting at 0700; DRF has fixed the compiler.
+RX11. Allow arbitrary integer parameters in diagnostic print routines. @237,699
+TX12. Say \\{cur_tok}, not \\{cur_val}, when you mean \\{cur_tok}. @440
+FX13. Make |\pause| effective also on first line of a file. @538
+FX14. Show context after online deletion. @88
+IX15. Bypass reference count when \\{debug_help} shows a token list. @1339
+BX16. Change `{\bf case} $p$' to `{\bf case} \\{type}($p$)'. @1000
+FX17. Fix timing of \\{print_ln} when scrolling help messages. @90
+PX18. Make \\{other_char} the default category for ASCII control codes too. @232
+AX19. Use special scanning method for font number in \\{new_font}. @1257
+# Eating lunch, 1020--1035, while the machine slowly recompiles everything.
+FX20. Don't forget to increase $k$ in the {\bf while} loop. @355
+DX21. Adjust \\{limit} properly after line changed when pausing. @363
+FX22. Remember to return a value in \\{new_spec} and \\{new_penalty}. @151,158
+# Now stepping through \\{line_break} in simple case.
+AX23. Don't prune unwanted nodes if $\\{cur_p}=\\{null}$. @877
+FX24. Print a closing parenthesis when displaying glue nodes. @189
+SX25. Use \\{last}, not \\{limit}, in \\{term_input}; else error prompt causes
+ trouble when $\\{state}=\\{token_list}$. @71,87
+DX26. Set $\\{first}\gets\\{limit}+1$ after \\{init_terminal}. @331
+DX27. Make sure \\{set_trick_count} is always performed. @317
+* 17 Jul 1982
+IX28. Add new diagnostic feature |\tracingcommands|. @299,1031
+# Debugging of system-dependent code not shown in this log.
+# Tangling \TeX\ now takes 1.75 minutes; about 75K bytes, 108K tokens.
+# Redundant semicolon sends Pascal compiler into infinite loop!
+FX29. Initialize $\\{passive}\gets\\{null}$. @864
+AX30. Fix pseudoprinting when the line is empty. @318
+EX31. Merge adjacent free areas of dynamic memory before dumping. @131
+FX32. Print the word |mode| in \\{print_mode}. @211
+IX33. Improve message and help in case of weird error. @415
+GX34. Allow optional space after |\def| and similar constructions. @473
+MX35. Declare \\{alpha} to be integer in \\{read_font_info}. @560
+AX36. Fix timing of \\{back_input} in \\{scan_dimen}. @448
+IX37. Back up after missing number error. @446
+IX38. Show the `|at|' size that is considered improper. @1259
+IX39. Streamline the dialog in \\{debug_help}. @1338
+MX40. Take output of \\{the_toks} from the advertised place. @467,1297
+TX41. Say \\{trie_fix}($q$), not \\{trie_fix}($p$). @959
+SX42. Decrease low limit of \\{error_count} to $-1$. @76
+* 18 Jul 1982
+FX43. Clear initial reference count of macro definitions. @473
+AX44. Fix timing of \\{back_input} in \\{scan_glue}. @461
+BX45. Use \\{cur_val_level}, not \\{cur_val}, when checking levels. @461
+BX46. Multiply |fil| units by $2^{16}$ for correct scaling. @454
+BX47. Don't confuse \\{glue_base} with \\{skip_base}. @1237
+AX48. Fix \\{print_scaled} so that 0.01 doesn't come out |0.1|. @103
+IX49\>X28. Show mode changes when tracing commands. @299
+LX50. Don't say {\bf if} $(n=0)\lor(\,\ldots\;\hbox{\bf div}\;n)$ in Pascal. @105
+BX51. Don't confuse \\{box_flag} with \\{box_code}. @1075
+SX52. Reset \\{offset} on \\{print_ln} even in \\{no_print} mode. @57
+SX53. Fix restarting of interrupts after \\{big_switch}. @1031
+LX54. Don't loop {\bf for} $k\gets a$ {\bf to} $b-1$ when $b=0$ if $k$ is
+ declared nonnegative.
+IX55. Put `|=|' sign into the \\{format_ident}. @1328
+SX56. Allow $r$ to be any integer in \\{get_node}. @125
+IX57. Don't put the output of \\{print_file_name} in quotes. @518
+IX58. Say `|dumped|' after dumping. @1311
+EX59. Eliminate unnecessary initialization code. @1332
+LX60. Get the file reading started right when beginning to undump. @1308
+IX61. Give forlorn message if format file can't be loaded. @1303
+FX62. Assign value to \\{cur_val} after glue arithmetic. @1239,1240
+* 19 Jul 1982
+LX63. Don't say {\bf if} $p>\\{max}\lor\\{free}[p]$ in Pascal. @169
+AX64. Fix memory-undump logic; loops are out of phase with input. @1312
+BX65. Undump \\{hyph_word}[$j$], not \\{hyph_word}[$k$]. @1325
+# At last |trip.fmt| loads without bombing out.
+PX66. Remove assignment of array to array, not allowed by IBM Pascal
+ (Susan Plass). @167
+PX67. Simplify an expression that's too big for IBM Pascal (Susan Plass). @1009
+AX68. Go to \\{contribute}, not \\{done}, after insertions. @1000
+IX69. Decrease \\{depth_threshold} if there's not enough string space. @198
+IX70. Show rules as `{\tt\char`\|}' in short displays. @175
+IX71. Don't show null glue in short displays. @175
+SX72. Set $\\{job_name}\gets0$ as part of output initialization. @528
+SX73. Don't complain of infinite shrinkage on |0pt minus 0fil|. @825,976,1009
+IX74. Use different prompt at beginning when accepting a file name. @37
+FX75. Reset \\{last_glue} on nonglue nodes. @996
+BX76. Remember to call \\{error} after printing |OK|. @1293
+LX77. Insert {\bf begin} \dots{ \bf end} around program text of section. @1025
+FX78. Define the |\shipout| primitive. @1071,1073
+AX79. Introduce \\{write_loc} analogous to \\{par_loc}. @1344,1371
+FX80. Dump and undump \\{par_loc} and \\{write_loc}. @1313,1314
+FX81. Allow \\{the} in \\{scan_the} [later \\{scan_something_internal}]. @413
+EX82. Interchange command codes $\\{the}:=:\\{number}$ [later \\{convert}]. @210
+BX83. Don't confuse \\{breadth} with \\{depth}. @236
+IX84. Add string printing feature to \\{debug_help}. @1339
+FX85. Set $\\{state}\gets\\{mid_line}$ in \\{begin_file_reading}. @328
+# Time out 2105--2200 to pick up Jenny from driving lesson.
+LX86. Keep $c\le127$ when deleting 99 tokens. @88
+SX87. Don't check for \\{str_room} error when $\\{selector}=\\{new_string}$. @1328
+* 21 Jul 1982
+IX88. Gather more statistics: String usage, font info, hyphen exceptions, stacks. @1334
+DX89\>X79. Initialize \\{write_loc} from \\{cur_val}, not from \\{cs_ptr}. @1344
+FX90. Remember to pack file name for |\open|. @1374
+SX91\>X34. Defuse |\outer| test before scanning optional space after `|}|'. @473
+SX92. Don't allow \\{prepare_mag} to cause errors after \\{jump_out}. @84
+# The first page of |DVI| output is {\sl perfect\/}! Pause to play piano.
+BX93. Don't confuse \\{dimen_base} with \\{scaled_base}. @1237
+DX94. Initialize $\\{link}(\\{page_head})\gets\\{null}$ when beginning a page. @991
+SX95. Correct \\{cur_height} more often, since \\{max_depth} might be negative. @972,973
+AX96. Calculate page dimensions properly after vertical kerns. @973
+SX97. Install new \\{page_contents} logic to handle interaction between
+ insertions and |\topskip|. @987,1008
+SX98. Allow \\{top_skip} glue to be a valid breakpoint. @1001
+FX99. Don't forget to count \\{dyn_used} in inner loop [erroneous analysis
+ retracted later]. @1034
+FX100. Set $p\gets q$ after migration step. @655
+FX101. Clear \\{prev_graf} to zero at start of paragraph. @1091
+LX102. Put parens into negated \\{leader_flag} macro. @1078
+# Time out 1720--1920 for John's birthday dinner.
+DX103. Scale \\{best_height} when adjusting \\{page_goal}. @1010
+AX104. Simplify logic of split insertions; three states become two. @981,1019,1020
+MX105. Don't omit first character when showing a macro argument. @400
+RX106. Prevent clobberage if macros have too many parameters. @390
+* 22 Jul 1982
+IX107. Tell how many |DVI| bytes were output. @642
+IX108\>X88. Adjust for singular or plural statistics. @1320,1334
+SX109\>X98. Consider \\{page_head} a glue node, to inhibit unwanted break. @988
+DX110. Introduce \\{new_skip_param} to keep reference counts updated. @679,969,1001
+DX111. Record the correct size of new insertion after it's split. @1010
+DX112. Use \\{free_node}, not \\{flush_node_list}, when recycling insertion
+ nodes. @1022
+SX113. Make online insertions work after \\{get_next} is interrupted. @87,324,343
+BX114. Print newline on interruption stop. @98
+SX115\>X34. Put space before \\{end_write_token}. @1371
+BX116. Don't confuse \\{glue_order} with \\{stretch_order}. @838
+TX117. Set $\\{max_dimen}\gets\hbox{\it'7777777777\/}$, not {\it'777777777}. @421
+MX118. Make |\global\textfont| legal. @1211
+BX119. Fetch |\the\textfont| with \\{equiv}, not \\{fam_font}. @415
+BX120. Call $\\{new_ligature}(f,l,\ldots)$ not $(f,c,\ldots)$. @1035
+RX121. Make \\{show_box} work on random garbage. @174,177
+DX122. Count reference to \\{zero_glue} from \\{cond_math_glue}. @1171
+* 23 Jul 1982
+RX123. Allow $\\{avail}=\\{null}$ when undumping. @1312
+BX124\>X110. Set $\\{width}(\\{glue_ptr}(p))$, not $\\{width}(p)$. @679
+AX125. Put \\{begin_file_reading} inside the \\{start_input} loop. @537
+BX126\>X116. Don't confuse \\{glue_stretch} with \\{stretch_order} [the previous
+ fix went only half\-way]. @838
+BX127. Negate $x$ when calculating badness of shrinkage. @667,678
+LX128\>X121. Remove dangling {\bf else} that parses wrong. @174
+IX129\>X28. Print newline before |{|, not after |}|, when tracing commands. @299
+IX130. Remove colon from overfull box messages. @663,675
+DX131\>X97. Compute \\{page_goal} properly when the first box arrives after
+ inserts. @1001
+BX132. Don't confuse \\{page_size} [now \\{page_goal}] with \\{best_size}. @1017
+AX133. Put heldover insertions at front of contribution list. @1023
+SX134\>X88. Output stats before closing |DVI| file, since the latter
+ decreases \\{font_ptr}. @1333
+TX135. Don't call a |\vbox| an |\hbox|. @674
+TX136. Fix misplaced {\bf end} caused by editing error. @675
+* 24 Jul 1982
+DX137. Don't \\{eq_destroy} any paragraph shape when \\{par_shape} is null. @275
+IX138. Omit blank before |\message| at the beginning of a line. @1280
+AX139\>X104. Don't try to split an insertion when \\{best_node} isn't the
+ split one. @1021
+LX140. Correct another case of `{\bf if} $x\land y$' misunderstood by Pascal.
+ @1021
+IX141. Provide diagnostic info about insertions via |\showlists|. @986
+IX142. Add `|inside a group|' to clarify a warning message. @1335
+IX143. Report \\{prev_depth} on a separate line in |\showlists|. @219
+SX144. Back up input to avoid unexpected clobberage of \\{cur_tok}. @1090
+# Wow what a bug: \\{new_graf} calls \\{build_page}, which invokes the
+ output routine, after which `\/{\bf goto} \\{reswitch}' is a {\sl disaster}.
+DX145. Add insertion glue to \\{page_so_far} instead of subtracting it from
+ the goal. @1009
+IX146. Put extra blank line before overfull box warning. @660
+CX147. Define break at kern consistently between horizontal and vertical lists. @973,1000
+DX148. Renumber so that math nodes are nondiscardable. @147
+TX149. Correct the \\{char_kern} macro: |#|, not $f$. @557
+FX150. Decrease $l$ after reconstituting discretionary break. @916
+EX151. Simplify the hyphen routine, knowing that $\\{link}(s)=\\{null}$. @918
+FX152. Initialize $r\gets q$ in discretionary destruction routine. @883
+* 25 Jul 1982
+AX153. Don't add interline penalty after last line of paragraph. @890
+IX154. Adjust spacing in diagnostic messages. @245
+DX155. Avoid simultaneous use of \\{temp_head} by \\{prune_page_top} and the
+ page builder. @1017
+FX156. Clear the \\{post_break} field of simple discretionaries. @916
+AX157. Split \\{offset} into independent variables \\{term_offset},
+ \\{file_offset}. @54,57,58
+# Am freezing current program as version $-0.25$; a week of TUG lectures
+ begins tomorrow.
+* 5 Aug 1982
+IX158. The `|.err|' file should be `|.log|' instead. @534
+GX159. Allow |\special| strings to contain more than 256 bytes. @585,1368
+MX160\>X99. Undo ``correction'' to a non-bug. @1034
+IX161. Suggest |\&| in help message for unexpected |&|. @1128
+GX162. Make `|E|' a standard option for exiting. @84
+GX163. Restore the use of dead cycles \`a la \TeX78. @1024,1054
+# The previous six changes were suggested during discussions with \TeX82 class.
+SX164. Fix global variable conflict between \\{open_log_file} and \\{new_font}. @1257
+CX165. Allow optional `|=|' when assign to font parameter. @1253
+FX166. Set \\{cur_val} after increasing the number of font parameters. @580
+DX167. Set \\{hash_brace} when matching `|{|'. @476
+IX168\>X88. Clarify meaning of statistics printed. @1334
+GX169. Change |DVI| format to include design size. @602,1260
+DX170. Introduce \\{def_ref} for \\{runaway} messages. @306
+MX171. Restore \\{cur_cs} before calling \\{scan_toks}. @1226
+AX172\>X157. Update \\{print_nl} to dual offset conventions. @62
+AX173\>X163. Move endgame logic inside \\{main_control}, because the output
+ routine becomes active. @1054
+* 6 Aug 1982
+CX174. Allow |INITEX| to load format files. @1337
+EX175. Conserve input stack space by deleting finished token lists. @325
+IX176\>X74. Print the opening `|**|' in the transcript file. @534
+# Now ready to try breaking new ground in |TRIP|.
+SX177. Preserve \\{align_state} from tokens deleted online. @88
+DX178. Set $t$ in all branches of \\{scan_toks}. @473
+SX179. Change `$\\{cur_cmd}\le\\{right_brace}$' to `$\\{cur_tok}\le
+ \\{right_brace_limit}$'; otherwise |\relax| gets through. @477
+CX180. Allow optional |=| when setting |\spacefactor|; disallow zero. @1243
+BX181. Change \\{vpackage}(\\{head}) to \\{vpackage}(\\{link}(\\{head})). @796
+# Shades of 1978!
+LX182. Insert missing {\bf begin} \dots{ \bf end}. @798
+* 7 Aug 1982
+LX183. Keep \\{trie_max} declared in non-|INITEX| [later rescinded]. @950
+DX184. Watch out for empty token list when copying. @466
+DX185. Free unused reference count slot when defining |\everypar|. @1226
+GX186\>X163. Introduce |\maxdeadcycles|. @1012
+# I believe the \\{line_break} routine has passed its test perfectly.
+SX187. Don't put discretionary after |-| inside a discretionary. @1039
+CX188. Change `|\minus|' to `|\minusthe|' [this feature retracted later]. @413
+BX189. Change \\{cur_p} to $r$ (three places). @875
+AX190. Increase range of \\{hc} to \\{halfword}; otherwise end-of-word mark
+ might match a vacant entry in the trie. @892
+FX191. Initialize $b$ in \\{shift_case} routine. @1288
+EX192. Don't back up if a space follows a decimal fraction. @452
+BX193. Don't confuse \\{glue_base} with \\{dimen_base}. @1145
+LX194. Guard against anomalous floating-point values in glue display. @186
+* 8 Aug 1982
+SX195. Avoid infinite loop when |\outer| leads to runaways. @339
+# I worked on that problem about two hours before fixing it.
+IX196. Move final \\{debug_help} to \\{succumb}, except in batch mode. @93
+RX197. Insert kern after spanned box, to defeat access to floating point. @808
+* 9 Aug 1982
+CX198. Include |\leftskip| and |\rightskip| in displayed equations [rescinded
+ later]. @1199
+IX199. Trace line-break computations if $\\{tracing_stats}>2$. @846,856
+DX200. Keep \\{prev_p} up to date when passing a string. @867
+# Now stepping through math stuff; a lot is working.
+DX201. Set $\\{link}(p)\gets z$ when making a fraction. @747
+CX202. Don't reset space factor when beginning |\valign|. @775
+IX203. Don't show glue setting if $\\{glue_sign}=\\{normal}$. @186
+DX204. Clear \\{glue_stretch} and \\{glue_shrink} when creating an unset box. @801
+BX205. Do \\{vpack} in hmode and vice versa when aligning. @804
+AX206. Remove fallacious call to \\{confusion} after alignment in display. @1206
+AX207. Don't test $\\{mode}=\\{vmode}$ in display, test $\\{nest_ptr}=1$. @1145
+FX208. Show an \\{inner_noad} as well as the other types. @690,696
+DX209. Renumber \\{mu_glue} and \\{cond_math_glue} so that the glue display logic
+ works. @149
+BX210. Don't confuse \\{cur_size} with \\{cur_style}. @703
+FX211. Advance $p\gets q$ during second pass over mlist. @761
+IX212. Add helpful hint about |\tracingonline=1|. @1293
+TX213. Delete spurious statement left from sloppy editing. @710
+DX214. Change the subtype when \\{mskip} becomes \\{hskip}. @732
+FX215. Don't forget to use the remainder when computing math glue. @716
+IX216\>X199. Improve paragraph diagnostics using \\{short_display}. @857
+IX217\>X199. Introduce \\{artificial_badness} for better diagnostics. @854,856
+* 11 Aug 1982
+AX218. Introduce \\{char_box} subroutine so that \\{var_delimiter} adds italic
+ correction. @709
+SX219. Save font and char in local variables of \\{make_math_accent}, since
+ it can be recursive. @738
+FX220. Call \\{error} after decrying an invalid character. @346
+* 12 Aug 1982
+IX221\>X199. Install new format for showing break nodes. @846
+# I have been testing \\{line_break} and I think it's working fine.
+BX222. Change $q$ to $p$, in order to catch empty alignments. @812,1206
+SX223. Disallow third part of discretionary in math mode. @1120
+DX224. Don't change \\{tail} if discretionary third part is empty. @1120
+IX225. Say |nonscript|, not |non_script|. @189
+SX226. Inhibit math if |\scriptfont3| is improper. @1195
+IX227\>X199. Introduce {\tt\@}|firstpass| and {\tt\@}|secondpass| comments. @863
+TX228. Change $p$ to $r$ when you mean $r$. @1204
+IX229\>X108. Say |page|, not |pages|, if there's only |1|. @642
+IX230. Insert space before |[]| on truncated |\showlists|. @182
+* 28 Aug 1982
+# Back from vacation after having looked at hardcopy listing of |TRIP| test.
+GX231. Allow |dm| as a unit [later |.5dm1| will be |.5\dimen1|]. @455
+IX232\>X108. Singularize |prevgraf 1 lines|. @219
+IX233. Omit trailing zero count registers when showing completed page numbers. @638
+LX234. Avoid clobbering $a$ by introducing a new local variable $t$. @986
+DX235\>X216. Fix diagnostic printing of discretionaries. @858
+IX236. Don't show unset stretch/shrink that's zero. @185
+CX237\>X198. Make |\halign| in displays consistent with other displays. (Namely,
+ ignore |\leftskip| and |\rightskip| in nonaligned displays;
+ respect the paragraph shape in aligned displays.) @800,1199
+IX238. Parenthesize `|If you're confused ...|'. @403
+IX239. Say `|\fraction|', not `|\xabovex|'. @697
+FX240. Remember to {\bf return} when you should. @1153
+PX241. Use absolute value to make sure {\bf div} is unambiguous. @737
+BX242\>X218. Don't confuse depth with height. @709
+BX243. Use $\\{delta}-\\{height}$, not $\\{height}-\\{delta}$. @736
+BX244. Increase \\{shift_down} to increase the clearance. @745
+IX245. Don't back up after improper use of |\the|. @428
+IX246. Don't give |0pt| as the default result when looking for \\{tok_val}. @428
+FX247. Initialize \\{second_indent} in the easy case. @848
+FX248. Package the equation number. @1204
+QX249. Don't resort to $v\gets\\{max_dimen}$ when glue doesn't stretch or
+ shrink. @1148
+IX250. Insert newline before showing current |\botmark|.
+FX251. Call \\{error} after giving error message. @784
+AX252. Change implementation of |\number|; it should \\{scan_int}, not
+ something internal. @471
+PX253. Introduce symbolic constants like \\{format_area_length}. @524
+PX254. Change \\{quit} to \\{jump_out}, since some compilers treat \\{quit}
+ as a reserved word. @81
+LX255. Add more parentheses to get proper parsing. @1260
+IX256. Say |please| in order to be friendly (or at least polite). @360
+BX257. Don't confuse \\{cur_vcmd} with \\{cur_chr}. @508
+IX258. Use |&| instead of |!| to specify a preloaded format. @1337
+TX259\>X177. Correct |s3| to |s4|. @88
+GX260. Introduce new primitive |\mathchardef|, to save space and time. @1224
+CX261. Use the |[]| convention for noads as well as nodes. @692
+TX262. Correct spelling in call to \\{primitive}: |\xatopx| should be |\xoverx|
+ [later renamed, thank goodness]. @1178
+* 30 Aug 1982
+RX263. Don't fetch \\{link}(\\{null}) in malformed list. @175
+SX264. Initialize \\{align_state} at a better time so that \\{align_peek}
+ doesn't see |&| or |\span|. @785,791
+SX265. Outlaw preamble interfering with $\\{align_state}=0$. @789
+CX266. Add level of grouping to alignment to tabskip locality. @774
+FX267. Check \\{align_state} when scanning $\langle u_j\rangle$. @783
+AX268. Move `\\{unsave}; \\{new_save_level}' from \\{main_control} into
+ \\{fin_col}. @791,1131
+SX269\>X180. Remember \\{cur_chr} when you're looking for optional `|=|'. @1243
+TX270. Change $q$ to $r$ [in code now obsolete]. @804
+IX271. Disable interrupts during \\{back_error} so that help messages aren't
+ clobbered. @327
+SX272. Introduce \\{slow_print} for printing control sequences. @60
+IX273. Initialize \\{del_code}(|"."|$)\gets0$ for error recovery. @240
+SX274. Call \\{end_file_reading} before calling \\{check_outer_validity}. @362
+IX275. Don't delete an extra `|}|' when |\par| will help find a runaway. @395
+* 31 Aug 1982
+BX276. Don't confuse \\{thin_muskip} with \\{thin_muskip_code}. @413
+FX277\>X266. Recover from error if new \\{align_group} ends abnormally. @1132
+IX278. Recover from error if |\par| occurs when $\\{align_state}<0$. @1094
+CX279. Make |\hskip\the\thinmuskip| and |\mskip\the\baselineskip| erroneous. @413
+GX280. Add |\muskip| and |\setmuskip| analogs to |skip| and |\setskip|. @413,1228
+EX281. Don't output |pop| right after |push|. @601
+# The |TRIP| test looks right; now to test for wasted memory.
+# When memory should be empty I find $\\{dyn_used}=18$, $\\{var_used}=267$.
+* 1 Sep 1982
+# Made special |MEMTEX| program, designed to track all memory allocation.
+DX282. Delete reference to \\{last_glue} when a page is packaged. @1017
+IX283. Include \\{save_stack} in the \\{search_mem} debugging routine. @285
+CX284. Disallow |\vfill| in restricted horizontal mode. @1095
+# Most of the memory locations I thought were wasted were actually in good use.
+# Total 192 hours (approx) debugging time so far since July 15.
+* 2 Sep 1982
+# Now looking at all zero counts in profile and extending |TRIP|.
+EX285. Simplify the creation of |vtop| boxes. @1087
+CX286. Set $\\{space_factor}\gets1000$ after |\hbox|. @1076
+PX287. Introduce preamble into |DVI| format. @617
+SX288. Give special \\{chr_code} to |\relax|. @265
+IX289. Don't show `|(null)|' when token list is null, just show nothing. @295
+EX290. Delete the procedure \\{write_name_string}, which is never used.
+CX291. Rename |\xabovex| to |\abovewithdelims|; do the same for
+ |\xatopx| and |\xoverx|. @1178
+QX292. Improve \\{clean_box} so that it recognizes cleanliness better. @720
+IX293. Report a |Missing delimiter| more meaningfully. @1161
+RX294. Give \\{endv_token} a \\{chr} code of 128 so that it will end a file name. @289
+RX295. Test present of math fonts {\sl after\/} parsing an mlist, not
+ before. @1138,1195
+IX296. Omit `|recent contributions|' and/or `|current page|' when they are
+ empty. @218,986
+IX297. Display what \TeX\ has deleted after improper discretionary list
+ has arisen. @1121
+IX298. Show what math character was undefined. @723
+IX299. Improve the |Incompatible magnification| error; break it into two lines. @288
+DX300. Put new cases into \\{flush_node_list}, to recycle mlist noads. @698
+* 6 Sep 1982
+FX301\>X300. Insert a necessary `{\bf goto} \\{done}' in that new material. @698
+# It took two hours to diagnose that {\bf goto} problem.
+TX302\>X295. Change `|2|' to `|3|' in help message for extension fonts. @1195
+IX303. Add a special note if material is being held over for the next output. @986
+RX304. Divide before multiplying in \\{make_left_right}, to avoid overflow. @762
+IX305. Introduce the \\{box_error} routine. @992
+FX306. Clear \\{arith_error} after overflow has been reported. @460
+BX307\>X249. Don't confuse \\{stretch} with \\{glue_stretch}. @1148
+DX308. Set $\\{glue_sign}\gets\\{normal}$ when packaging with glue ratio
+ zero. @558,664
+AX309. Test for overflow before attaching the sign. @448
+# That all worked! Now trying |min_quarterword| negative.
+LX310. Take absolute value before applying {\bf mod} in \\{new_trie_op}. @944
+LX311. Say $\\{qi}(c)$, not $c$, when testing |TFM| flags [now obsolete]. @573
+LX312. Initialize \\{token_ref_count}(\\{def_ref}) to \\{null}, not zero. @473
+LX313. Change the type of \\{vsplit} parameter $n$ from \\{quarterword} to
+ \\{eight_bits}. @977
+LX314. Initialize \\{null-delimiter} different form \\{null_character}. @685
+LX315. Insert \\{qi} twice in \\{scan_delimiter}. @1160
+FX316. Insert \\{qi} in \\{scan_math}. @1151
+FX317. Insert \\{qo} in \\{fetch}. @722,723
+FX318. Insert \\{qi} in \\{set_math_char}. @1155
+FX319. Insert \\{qi} in \\{math_ac}. @1165
+FX320. Insert \\{qo} in \\{mlist_to_hlist}. @755
+IX321. Use brackets around 8-bit characters in \\{print_ASCII}. @68
+IX322. Include \\{hyph_list} in the \\{search_mem} debugging routine. @933
+# Now compiling non-|INITEX| to try an industrial-strength version.
+LX323. Add {\bf return} to \\{final_cleanup}, because some Pascal compilers
+ insist that each label be used. @1335
+DX324. Compute \\{par_token} when undumping. @1314
+* 11 Sep 1982
+IX325. Emit newline before file name, if near end of line. @537
+CX326. Define |\ifx| for arbitrary tokens. @507
+* 12 Sep 1982
+IX327. Don't ask users to type |x| twice before exiting. @84
+GX328. Install new features |\openin|, |\read|, |\ifeof|, |\closein|; rename
+ existing |\open|, |\send|, |\close| to be |\openout|, |\write|,
+ |\closeout|. @209,313,1275
+GX329. Install new feature |\expandafter|. @368
+PX330. Change the default file area from `|<TeX>|' to `|TeXinputs:|'. @574
+* 13 Sep 1982
+GX331. Install new feature |\string|. @472
+AX332. Remove spurious space printed by |sprint_cs|. @263
+# All tests passed now! But when I played with the system I found another bug
+ (undetected by |TRIP|):
+FX333. Set $r\gets s$ after matching macro parameter tokens. @397
+* 16 Sep 1982
+IX334\>X199. Introduce serial numbers in line-break records, improving
+ readability and independence. @846
+IX335. Don't abort when \\{file_name_size} is exceeded. @519
+* 17 Sep 1982
+IX336. Remove unwanted period from font capacity message. @567
+* 18 Sep 1982
+GX337\>X329. Make |\expandafter| more powerful by moving it from semantics
+ to syntax [i.e., from stomach to mouth]. @368
+* 19 Sep 1982
+IX338. Improve error recovery for `|Missing number|'. @415
+* 22 Sep 1982
+QX339. Suppress italic correction between letters in math mode except in math
+ fonts. @752
+* 24 Sep 1982
+PX340. Define $\\{null}=\\{mem_bot}$, not \\{min_halfword}, because there's
+ a reference to \\{link}(\\{null}) in \\{try_break}. @115
+DX341. Initialize $\\{str_start}[0]\gets0$. @47
+IX342. Avoid blank space at beginning of line. @638
+DX343. Set type of new box in math mode to \\{ord_noad}, not \\{inner_noad}. @1076
+* 28 Sep 1982
+# Here are the first changes made to the preliminary listing of \TeX82 that was
+ published by the \TeX\ project earlier this month.
+F520. Insert the missing cases \\{letter} and \\{other_char} after
+ \\{x_token} looks ahead. @1038
+C521. Change `|\pause|' to `|\pausing|'. @236
+D522. Reset \\{overfull_rule} when determining tabskip glue. @804
+A523. Fix the logic for scanning |\ifcase| [in obsolete syntax---everything
+ is still done with braces since `|\fi|' doesn't exist yet]. @509
+* 30 Sep 1982
+I524. Change |"0.0"| to |"?.?"| (suggested by DRF). @186
+* 2 Oct 1982
+Q525. Use conditional thin spacing next to `Inner' noads. @764
+Q526. Make thick spaces conditional. @766
+* 4 Oct 1982
+P527. Increase \\{trie_size} from 7000 to 8000, because of Frank Liang's improved
+ (but longer) hyphenation patterns. @11
+* 6 Oct 1982
+F528\>X330. Change the string lengths to match the new \\{\TeX_format_default}. @520
+# Version 0 of \TeX\ is being released today!
+* 8 Oct 1982
+B529. Fix a blunder: I decreased $h$ mod a quarterword when it should have
+ been decreased mod \\{trie_op_hash_size} (HWT). @944
+* 9 Oct 1982
+P530\>X258. Fix a typo (`|!|' not `|&|') in the |WEB| documentation. @524
+F531. Remember to call \\{initialize} if a different format was preloaded
+ (Max D{\'\i}az). @1337
+# Version 0.1 incorporates the above changes.
+* 12 Oct 1982
+G532. Add the `|\immediate|' feature, by popular request. @1375
+# Version 0.2 incorporates this (somewhat extensive) change.
+* 13 Oct 1982
+P533. Introduce new |WEB| macros so that \\{glue_ratio} is more easily changed. @109
+# I began writing {\sl The \TeX book\/} today: edited the old preface and
+ searched in the library for quotations.
+* 14 Oct 1982
+B534. Change the type of \\{hd} to \\{eight_bits}; it's
+ not a \\{quarterword} (HWT). @649
+S535\>X281. Revise the optimization of\/ |DVI| commands: It's not always safe to eliminate
+ \\{pop} when the preceding byte is \\{push}, since |DVI| commands
+ have variable length! (Embarrassing oversight caught by DRF.) @601
+* 15 Oct 1982
+C536. Test `$\\{prev_depth}>\\{ignore_depth}$', not `$\ne$'. @679
+# Version 0.3 incorporates the above changes.
+* 16 Oct 1982
+P537. Omit definition of \\{align_size}; it's never used (Bill Scherlis). @11
+I538. Inhibit error messages when packaging box 255. @1017
+* 21 Oct 1982
+A539\>X145. Subtract $\\{width}(q)$ from \\{page_goal}, don't add it to
+ $\\{page_so_far}[1]$. @1009
+# Version 0.4 incorporates the above changes.
+* 22 Oct 1982
+P540. Increase the amount of lower (variable-size) memory from 12000 to 13000,
+ since the \TeX\ program listing now needs about 11500. [At this time
+ there still is a fixed boundary between upper and lower memory.] @12
+G541. Add a new parameter |\boxmaxdepth|. @1086
+# Version 0.5 incorporates the above changes.
+* 26 Oct 1982
+B542. Fix an off-by-one error caught by Gabi Kuper and HWT.
+ (I forgot `${}+1$'). @1317
+B543. Fix the spacing of displayed control sequences: \\{print_cs} should base its
+ decision on $\\{cat_code}(p-\\{single_base})$, not $\\{cat_code}(p)$. @262
+# The |TRIP| test detected this bug, but I didn't notice.
+* 27 Oct 1982
+S544. Set \\{math_type} before saying $\\{fetch}(\\{nucleus}(q))$, since
+ fetching can have a side effect. @752
+* 28 Oct 1982
+G545. Install a major change: Fonts now have identifiers instead of code letters.
+ Eliminate the `|\:|' primitive, and give corresponding new
+ features to `|\the|'. @209
+# Actually I began making these changes on October 26, but I needed two days
+ to debug them and to put Humpty Dumpty together again.
+# At this time I'm also drafting macros for typesetting {\sl The \TeX book}.
+# The above changes have been incorporated into Version 0.6.
+* 30 Oct 1982
+# After years of searching, I've finally found a definitive definition of
+ the printer's point; and (unfortunately) my previous conjecture was
+ wrong. The truth is that $\rm83\,pc=35\,cm$, exactly;
+ so I am changing \TeX\ to conform.
+C546. Revise unit definitions for the `real' printer's point. @458,617
+# Version 0.7 incorporates the above.
+* 1 Nov 1982
+# Oops! Retract error \#546, and retract \TeX\ Version 0.7;
+ the source of my information about points was flaky after all.
+ My original suppositions were correct,
+ as confirmed by NBS Circular 570.
+* 4 Nov 1982
+C547. Revise the definition of |dd|, conforming to the definitive value
+ shown me by Chuck Bigelow. @458
+R548\>545. Introduce ``frozen'' copies of
+ font identifiers, to be returned by |\the\font|, so that font
+ manipulation is more robust. @1257
+* 5 Nov 1982
+D549. Reset \\{looseness} and paragraph shape when beginning a |\vbox|. @1083
+* 6 Nov 1982
+D550. De-update \\{align_state} when braces are in constants. @442
+I551\>X294. Improve error recovery for bad alignments. @1127
+# Today I wrapped up Chapters 4 and 5.
+* 8 Nov 1982
+G552. Give more power to |\let|: the right-hand side needn't be a control
+ sequence. @1221
+I553. Amend \\{show_context} to say
+ `$(\\{base_ptr}=\\{input_ptr})\lor{}$'; otherwise undefined control
+ sequences can be invisible in unusual cases (John Hobby). @312
+A554. Compute demerits more suitably by adding a penalty squared, instead of
+ adding penalties before squaring. @859
+# Previously a slightly loose hyphenated line followed by a decent line
+ was considered worse than a decent hyphenated line followed by
+ a quite loose line.
+* 10 Nov 1982
+E555. Save a bit of buffer space by declaring \\{pool_file} only in
+ |INITEX|. @50
+* 11 Nov 1982
+I556. Introduce a new context indicator to clarify \TeX's scanning state:
+ A special type
+ called \\{backed_up} is distinguished from other kinds of \\{inserted}
+ lists; it is called `recently read' or `to be read again', while
+ others are called `inserted'. @314
+I557. Append a comment, `|treated as zero|', to the missing-number message. @446
+I558. Ignore the settings of\/ |\hfuzz| or |\vfuzz| if\/ |\hbadness| or |\vbadness|
+ is less than 100. @666,677
+* 13 Nov 1982
+# Major surgery on the program is planned for today, because of new ideas
+ suggested by correspondence with MDS and other macro writers.
+G559. Introduce a new |\tokens| register; this will be useful and easy to add,
+ since \TeX\ already can handle |\everypar| and |\output|. @1227
+C560\>X34. Change \\{get_x_token} to \\{get_token} when scanning an optional
+ space; then a construction like
+ |\def\foo{...}\foo| won't complain that |\foo| is undefined. @443
+# This change was retracted when it was being debugged, because it could
+ cause \\{endv} to abort the job. Then it was re-established again
+ when I found that \\{endv} needed to be more robust anyway.
+ [But it was eventually rescinded again.]
+G561. Make |\span| mean `expand' in a preamble. @782
+E562. Use three separate {\bf if\/} tests instead of
+ `$\land$' in the inner loop of \\{get_next}, to gain efficiency. @342
+R563. Introduce \\{get_r_token} so that assignments have uniform error
+ messages and so that frozen equivalents cannot be changed. @1215
+# I gave a few variables more mnemonic names as I made these changes.
+C564. Move conditional statements from the semantics (`stomach') part of
+ \TeX\ to the syntax (`mouth') part, by introducing `|\fi|'.
+ Also introduce |\csname| and |\endcsname|. @372,489\hbox{--}500
+# This makes macros much more predictable and logical, but it is by far
+ the most drastic change ever made to \TeX. The program began to come
+ back to life only after three days of solid hacking.
+# Several other things were cleaned up as part of this change
+ because it is now more natural to handle them differently.
+ For example, a null control sequence has now become more logical.
+# The result of all this is called Version 0.8.
+* 18 Nov 1982
+# Today I resumed writing Chapter 8. Tomorrow I'm $\,2^{14}$ days old!
+* 21 Nov 1982
+F565. Declare $c$ as a local variable for hyphenation (DRF). @912
+E566. Omit the ``first pass'' and try hyphenations immediately,
+ if\/ |\pretolerance| is negative (suggested by DRF). @863
+R567. Don't ship out incredibly huge pages; they might foul up
+ |DVI| files. @641
+* 2 Dec 1982
+G568. Add new features |\everymath| and |\everydisplay|. @1139,1145
+G569. Add a new feature |\futurelet|. @1221
+# The changes above have been incorporated into Version 0.9 of TeX.
+* 7 Dec 1982
+G570. Add a new |\endinput| primitive (suggested by FY). @362,378
+* 8 Dec 1982
+I571. Try \\{off_save}, if\/ |\par| occurs in restricted horizontal mode.
+ (This avoids embarrassment if \TeX\ says `type a command or
+ say |\end|', then when you type |\end| it says you can't!)
+ [However, I soon retracted this change.] @1094
+* 21 Dec 1982
+A572. Redefine |\relax| so that its \\{chr} field exceeds 127. (This facilitates
+ the test for end in \\{scan_file_name}.) @265
+F573\>566. Call \\{begin_diagnostic} when omitting
+ the first pass of line breaking. @863
+A574. Fix the logic of glue scanning: In |\hskip-1pt plus2pt| the minus should
+ apply only to the |1pt|. @461
+* 23 Dec 1982
+I575. Renumber the decimal codes in paragraph statistics for loose and tight
+ lines; they were ordered backwards. @817
+C576. Treat a paragraph that ends with leaders like a paragraph that
+ ends with glue. @816
+C577. Allow commas as alternates to radix points, for Europeans. @438
+C578. Change |\hangindent| to a normal dimension parameter. [It had been
+ a combination of\/ |\hangindent| and |\hangafter|, with special
+ syntax.] @247
+G579. Make |\prevgraf| accessible to users. @422,1244
+G580. Split |\clubpenalty| off from |\widowpenalty|. @890
+# I'm typing Chapter 14 while making these changes.
+* 24 Dec 1982
+S581. Use \\{back_input} instead of {\bf goto} \\{reswitch} when
+ inserting |\par|, because |\par| may have changed. @1095
+* 25 Dec 1982
+# It's 10pm after a very Merry Christmas!
+I582\>X328. Don't prompt for a new file name if\/ |\openin| doesn't find a file. @1275
+G583. Add a new |\jobname| primitive. @472
+I584. Give the user a way to delete the dollar sign, when \TeX\ decides
+ to insert one. @1047
+C585. Allow optional equals after |\parshape|, and implement |\the\parshape|.
+ @423,1248
+* 26 Dec 1982
+I586. Add an \\{if_line_field} to the condition stack entries,
+ so that more informative error messages can be given. @489
+D587\>549. Introduce a \\{normal_paragraph} procedure, since initialization is needed
+ also within |\insert|, |\vadjust|, |\valign|, |\output|. @1070
+* 27 Dec 1982
+G588. Give users access to |\pagetotal| and |\pagegoal|. (Analogous to
+ \#679 and \#585, but simpler.) @1245
+I589\>X199. Introduce |\tracingpages|, allowing users to see
+ page-optimization calculations. Also split |\tracingparagraphs| off from
+ |\tracingstats|. @987,1005,1011
+# The changes above have been incorporated into Version 0.91 of \TeX.
+* 31 Dec 1982
+P590. Break the \\{build_page} procedure into two parts, by extracting
+ the section now called \\{fire_up}. [This is necessary because
+ some Pascal compilers, notably for IBM mainframes, cannot
+ deal with large procedures.] @1012
+S591\>564. Make |\ifodd1\else| legal by introducing \\{if_code}. @489
+Q592. Improve alignments when columns don't occur: Don't append null boxes
+ for columns missing before |\cr|, and zero out the tabskip
+ glue after nonpresent columns. @802
+I593. Make the error message about overfull alignment more intelligible.
+ @801,804
+# The changes above have been incorporated into Version 0.92 of \TeX82,
+ which was the last version of 1982,
+ completed at 11:59pm on December 31.
+* 3 Jan 1983
+# Today I'm beginning to write Chapter 15, and
+ planning the |\output| routine of |plain.tex|.
+C594\>X186. Change the logic of \\{its_all_over}; use \\{max_dead_cycles}
+ here too, instead of the fixed constant~100. @1054
+F595\>X34. Don't forget to \\{pop_nest} when an insert is empty. Also disallow
+ optional space after |\insert|$\,n\,$|{...}|. @1100
+* 4 Jan 1983
+C596\>541. Use the |\boxmaxdepth| that's declared inside a |\vbox| when packaging it.
+ @1086
+C597. Rename |\groupbegin| and |\groupend| as |\begingroup| and
+ |\endgroup|. @265
+G598\>594. Make |\deadcycles| accessible to users. @1246
+Q599. Base the split insertions on natural height plus depth, not
+ on \\{delta}. @1010
+# The changes above have been incorporated into Version 0.93.
+* 6 Jan 1983
+D600. Add \\{push_math} to handle a case where I forgot
+ to clear \\{incompleat_noad}. (This long-standing bug was
+ unearthed today by Phyllis Winkler.) @1136
+G601\>588. Add |\pageshrink|, etc., too. @1245
+G602. Introduce new parameters |\floatingpenalty|, |\insertpenalties|. Also
+ adopt a new internal representation of insertion nodes,
+ so that |\floatingpenalty|, |\splittopskip| and |\splitmaxdepth|
+ can be stored with each insertion. @140,1008
+* 7 Jan 1983
+Q603. Improve the rules for entering \\{new_line}, in particular
+ when the end-of-line character is active. @343
+* 9 Jan 1983
+Q604. Distinguish between implicit and explicit kerns. @155,896
+C605. Change the name |\ignorespace| to |\ignorespaces|. @265
+C606\>560. Don't omit a blank space after |\def|, |\message|, |\mark|, etc.;
+ the previous hodge-podge of rules is impossible to learn. @473
+# The above changes appear in Version 0.94.
+* 12 Jan 1983
+# Beginning to write the chapters on math today.
+G607. Add a new feature: active characters in math mode. @1151
+* 15 Jan 1983
+A608. Fix a surprise bug: `|$1-$|' treated the |-| as binary. @729
+D609. Initialize \\{space_factor} inside discretionaries. @1117
+* 16 Jan 1983
+F610. Fix an incredibly embarrassing bug: I forgot to update \\{spotless} in the
+ \\{error} routine!
+# While fixing this, I decided to change
+ \\{spotless} to a more general \\{history} variable, as suggested
+ by IBMers who want a return code. @76,82,1335
+I611. Replace two calls of \\{confusion} by attempts at error recovery, in places
+ where `|This can't happen|' could actually happen. @1027,1372
+* 18 Jan 1983
+R612. Introduce the \\{normalize_selector} routine
+ to protect against startup anomalies
+ when the transcript file isn't open. Also make \\{open_log_file}
+ terminate in some cases. @92,535
+R613\>591. Insert |\relax|, not a blank space, to cure infinite
+ loop like |\ifeof\fi| (LL). @510
+G614. Change the old |\limitswitch| to |\limits|, |\nolimits|, and
+ |\displaylimits|. Incidentally, this fixes a bug in the former
+ positioning of integral signs. @682,749
+C615. Give a |\char| in math mode its inherited |\mathcode|. @1151
+Q616\>525. Make underline, overline, radical, vcenter, accent noads and |{...}|
+ all revert to type Ord instead of type Inner. Introduce a new primitive
+ |\mathinner|. (This fixes the spacing, which
+ got worse in some ways after change \#525.) @761
+# I'm working on Appendix G today.
+* 19 Jan 1983
+G617. Introduce a |\mathchoice| primitive. @1174
+C618. Move |\input| from the stomach to the mouth. @378
+C619\>X260. Introduce |\chardef|, analogous to |\mathchardef|. @1038,1224
+G620. Change |\unbox| to |\unhbox| and |\unvbox|; also add |\unhcopy|. @1110
+C621. Consider |\spacefactor|, |\pagetotal|, etc., as part of
+ \\{prefixed_command}, even though they are always global. @1211
+* 20 Jan 1983
+C622. Switch modes when |\hrule| occurs in horizontal mode or |\vrule|
+ in vertical. @1090,1094
+G623. Add a new |\globaldefs| feature. @1211
+* 21 Jan 1983
+E624. Optimize the code, in places where it's important (based on
+ frequency counts of \TeX\ usage
+ accumulated during the past week): Introduce \\{fast_get_avail}
+ and \\{fast_store_new_token}; reduce procedure-call overhead
+ in \\{begin_token_list}, \\{end_token_list}, \\{back_input},
+ \\{flush_node_list}; change some tests from `{\bf if} $a\land b$' to
+ `{\bf if}~$a$ {\bf then if}~$b$'. @122,371
+* 22 Jan 1983
+E625. Save space in math lists: Don't insert penalties within restricted
+ horizontal mode; simplify trivial boxes. @721,1196
+S626. Fix a surprising oversight in the \\{rebox} routine:
+ Ensure that $b$ isn't a vbox. @715
+C627\>545. Make |\nullfont| a primitive, so that \\{cur_font} always
+ has a value. (This is a dramatic improvement over \TeX78, where a
+ missing font was a fatal error called `|Whoa|'!) @552
+* 24 Jan 1983
+I628\>586. List all incomplete |\if|'s when the job ends. @1335
+* 29 Jan 1983
+C629\>552. Change initialization of \\{align_state} so that |\halign\bgroup|
+ works. @777
+* 30 Jan 1983
+D630\>625. Be sure to test `\\{is_char_node}($q$)' when checking for a trivial
+ box. @721
+# By extraordinary coincidence, this bug was caught when somebody
+ used font number~11 ($=\\{kern_node}$) in the second character
+ of a list of length~2!
+I631\>X168. Improve format for stats at end of run, as suggested by DRF. @1334
+# The changes above have been incorporated into Version 0.95.
+C632. Don't ignore the space after a control symbol (except `|\ |'). @354
+P633. Remove all trailing spaces at the right of input lines,
+ so that there's perfect compatibility with IBM systems that
+ extend short lines with spaces. @31
+* 3 Feb 1983
+I634. Assume that a \\{math_accent} was intended, after giving an error
+ message in the case $\\{mmode}+\\{accent}$. @1165
+G635. Add new primitives |\iftrue| and |\iffalse|. @488
+* 6 Feb 1983
+A636\>X304. Improve the accuracy of fixed-point arithmetic when
+ calculating sizes for |\left| and |\right|. (I had started by
+ dividing \\{delimiter_factor}, not \\{delta1}, by 500.) @762
+* 12 Feb 1983
+C637. Change the name |\delimiterlimit| to |\delimitershortfall|. @248
+C638. Make |\abovewithdelims..| equivalent to |\above|; change the
+ order of operands so that delimiters precede the dimension. @1182
+C639\>607. Remove the kludgy math codes introduced earlier;
+ make |\fam| a normal integer parameter and allow |\mathcode|
+ to equal $2^{15}$. @1233
+R640. Don't let |\spacefactor| become more than $2^{15}$. @1233,1243
+# I finished drafting Chapter 17 today.
+* 14 Feb 1983
+I641\>639. Replace octal output (\\{print_octal}) by hexadecimal (\\{print_hex})
+ so that math codes are clearer. @67
+F642\>619. Don't forget \\{char_given} in the \\{math_accent} routine. @1124
+* 17 Feb 1983
+C643\>622. Switch modes when |\halign| occurs in horizontal mode, or |\valign|
+ in vertical mode. @1090,1094
+* 18 Feb 1983
+I644. Add a new feature |\tracingrestores|. This requires a new procedure called
+ \\{show_eqtb}, whose code can be
+ interspersed with the \\{eqtb} definitions. @252
+* 25 Feb 1983
+I645\>622. Suggest using |\leaders| when the user tries a horizontal rule
+ in restricted horizontal mode. @1095
+* 27 Feb 1983
+I646. Specify the range of source lines, when giving warning messages
+ for underfull or overfull boxes in alignments. @662,675
+# Why did it take me all day to type the middle part of Chapter 18?
+* 4 Mar 1983
+G647. Introduce a new feature |\xcr| (suggested by LL). [Changed later to
+ `|\crcr|'.] @785
+I648\>631. Subtract out \TeX's own string requirements from the stats. @1334
+* 6 Mar 1983
+G649. Add new features |\everyhbox| and |\everyvbox|. @1083,1167
+* 9 Mar 1983
+R650\>X295. Avoid accessing \\{math_quad} when the symbol fonts aren't known
+ to be present. @1199
+P651\>533. Introduce \\{float} and \\{unfloat} macros to aid portability (HWT). @109
+C652. Introduce new names |\abovedisplayskip| and |\belowdisplayskip| for
+ the old |\dispskip|; also |\abovedisplayshortskip| and
+ |\belowdisplayshortskip| for the old |\dispaskip| and |\dispbskip|. @226
+* 10 Mar 1983
+C653. Unbundle |\romannumeral| from |\number| (suggested by FY). @468
+* 12 Mar 1983
+C654. Ignore leading spaces in \\{scan_keyword}. @407
+* 14 Mar 1983
+E655\>631. Use \\{write} and \\{write_ln} directly when printing stats. @1334
+* 16 Mar 1983
+Q656\>602. Refine the page-break cost function (introducing `\\{deplorable}',
+ which is not quite `\\{awful_bad}'), after suggestion by LL. @974,1005
+# The changes above have been incorporated into Version 0.96.
+* 18 Mar 1983
+G657. Add a new feature |\everyjob| suggested by FY. @1030
+* 19 Mar 1983
+I658. Don't treat left braces specially when showing macros. @294
+C659. Ignore blanks that would otherwise become undelimited arguments. @393
+* 21 Mar 1983
+F660\>X280. Make |\lastskip| handle \\{mu_glue} as well as ordinary glue. @424
+C661\>561. Expand only one level in a preamble |\span|. @782
+* 22 Mar 1983
+C662. Let a single |#| suffice in |\tokens|, |\message|, etc. (The previous rule,
+ in which |##| was always required as in macros, was a loser especially
+ in |\write| where you had to say |####|!) @477
+C663\>X328. Require the keyword `|to|' in |\read|. (This will avoid the common error
+ of an incomplete constant when no space appears
+ before the |\cs|.) Also allow terminal
+ I/O as a default when a stream number is out of range. @482,1225,1370
+* 26 Mar 1983
+C664. Replace |\ifeven|\<countnumber> by |\ifodd|\<number>, for better
+ consistency of language. @504
+S665\>564. Introduce the \\{change_if_limit}, to overcome a big surprise
+ bug relating to |\if\if aabc\fi|. @497
+# Such examples show that \\{cur_if} might not be current,
+ in my original implementation.
+* 28 Mar 1983
+G666\>X326. Tolerate non-characters as arguments to |\if| and |\ifcat|. @506
+C667. Change `|absent|' to `|void|', a better word. @487
+C668. Clear the \\{shift_amount} in |\lastbox|, since I don't
+ want to figure out what it means in all cases. @1081
+* 29 Mar 1983
+I669. Wake up the terminal before giving an error message. (This
+ means a special \\{print_err} procedure is introduced.)
+ (Suggested by DRF.) @34,73
+* 1 Apr 1983
+# Today I finished Chapter 21 (boxes) and began to draft Chapter 22 (alignments).
+G670. Allow periodic preambles in alignments. @793
+C671. Make |\leaders| line up according to the smallest
+ enclosing box. @627,636
+Q672. Allow hyphenation after whatsits (e.g., after items for an index). @896
+* 2 Apr 1983
+Q673. Call \\{build_page} when |\par| occurs in vertical mode. @1094
+C674. Clear \\{aux} in \\{init_row}, for tidyness. @786
+* 4 Apr 1983
+C675. Let digits switch families in math mode. @232
+* 7 Apr 1983
+Q676\>602. Refine the test for not splitting an insertion. @1008
+* 8 Apr 1983
+C677\>647. Rename |\xcr| as |\crcr|, at LL's request. @780
+* 9 Apr 1983
+# Took a day off and had a chance to help print a sample page on
+ a 150-year-old letterpress in Murphys, California.
+* 11 Apr 1983
+I678. Recover more sensibly after a runaway preamble. @339
+* 12 Apr 1983
+C679\>X328. Make |\read| span several input lines, if necessary to get
+ balanced braces. @482
+* 14 Apr 1983
+S680. Fix a subtle bug found by JS: \S882 can make $q$ a \\{char_node},
+ so we need to test `{\bf if} $\lnot\\{is_char_node}(q)$'.
+ [Actually I discovered much later that the real bug was
+ to omit `{\bf else}' at this point.] @881
+* 15 Apr 1983
+C681. Make |\uppercase| and |\lowercase| apply to all characters, regardless
+ of category. @1289
+# 7:30am. After working all night, I completed a draft of the manual thru
+ Chapter 22, for distribution to volunteer readers.
+# 5pm. The changes above have been incorporated into Version 0.97.
+* 17 Apr 1983
+R682. Change `\\{small_number}' to `$0\,.\,.\,65$' in the
+ hyphenation routine (DRF). @901
+I683. Flush patterns in the input when the user tries |\patterns|
+ outside of\/ |INITEX| (suggested by DRF). @1252
+# Tomorrow I fly to England, where I'll lecture and write a paper about
+ `Literate Programming' [{\sl Comp.~J. \bf27} (1984), 97--111].
+* 14 May 1983
+I684\>663. Improve the behavior of\/ |\read| from terminal
+ (suggested by Todd Allen at Yale).
+ [I'd forgotten to implement the extended stream numbers in \#663.
+ Also, the prompt is now omitted if $n<0$.] @484
+* 18 May 1983
+I685. Restrict |\write| $n$ to the transcript file only, if $n<0$. @1350
+C686\>X188. Unify the syntax for registers and internal quantities. (Remove
+ primitives called `|\insthe|' and `|\minusthe|'; rename
+ \\{scan_the} to \\{scan_something_internal}, and change its
+ interface accordingly; clean up command codes generally.) @209,413
+G687. Introduce new parameters |\hoffset|, |\voffset|. @617
+* 24 May 1983
+G688. Introduce a new parameter |\everycr| (suggested by MDS). @774,799
+# Many macro writers and preliminary-manual readers have been requesting
+ new features; I'll try to keep the language as concise and consistent
+ as possible.
+* 25 May 1983
+G689. Introduce |\countdef|, |\dimendef|, etc.\ (suggested by DRF long ago,
+ easy now in view of \#686). @1224
+G690. Introduce |\advance|, |\multiply|, |\divide| (suggested by FY). @1240
+G691. Introduce |\hyphenchar|; this requires a new command
+ \\{assign_font_int}, plus minor changes to about 15 modules. @915
+G692. Introduce |\skewchar| (easy because of \#691). @741
+G693. Introduce |\noexpand|. (I had difficulty thinking of how to
+ implement this one!) @358,369
+G694. Introduce |\meaning|. @296
+G695\>X231. Remove `|dm|' and `|vu|'; allow the more general `|.5\hsize|'. @455
+C696. Change `|\texinfo| $f$ $n$' to `|\fontdimen| $n$ $f$'. @578
+* 27 May 1983
+G697. Add a new feature |\afterassignment| (suggested by ARK). @1269
+C698\>619. Adjust the timing so that commands like `|\chardef\xx=5\xx|'
+ behave sensibly. @1224
+* 28 May 1983
+C699. Ignore `|\relax|' as if it were a space, in math mode and in a few other
+ places where |\relax| would otherwise be erroneous. @404
+Q700. Improve |\mathaccent| spacing with respect to subscripts
+ and superscripts (suggested by HWT). @742
+* 30 May 1983
+C701\>598. Terminate a job only when $\\{dead_cycles}=0$. @1054
+# The changes above constitute Version 0.98.
+* 3 Jun 1983
+# I finished the draft of Chapter 23 (output routines) today.
+G702. Allow |\mark| and |\insert| and |\vadjust| in restricted
+ horizontal mode, and also in math mode. (This is a comparatively
+ big change, triggered by the fact that |\mark| in a display
+ presently causes \TeX\ to crash with `|This can't happen|'!)
+ The global variable \\{adjust_tail} is introduced. @796,888,1085
+* 6 Jun 1983
+G703\>695. Replace (and generalize) the previous uses of\/ |ht|, |wd|, and |dp|
+ in dimensions by introducing the new control sequences
+ |\ht|, |\wd|, and |\dp|. @1247
+I704. Display sub-parts of noads with the symbols |^| and |_| instead of
+ |(| and~|[|. @696
+C705\>694. Allow |A..F| in hex constants to be \\{other_char} as well as
+ \\{letter}. @445
+* 7 Jun 1983
+E706\>654. Remove an instance of \<Scan optional space>, since it's now
+ redundant. @457
+C707. Legalize |\mkern\thinmuskip| and |\mkern5\thinmuskip|. @456
+C708. Clean up the treatment of optional spaces in numerical specifications. @455
+# A construction like |2.5\space\space\dimen0| was previously
+ valid after `|plus|' or `|minus|' only!
+# I'm obviously working on Chapter~24 today.
+C709\>545. Allow `|\font|' as a \<font identifier> for the current font. @577
+C710\>623. Don't make |\gdef| global when $\\{global_defs}<0$. @1218
+E711. Produce \\{zero_glue} as the outcome of
+ |\advance\spaceskip by-\spaceskip|. @1229
+I712. Make |\show| do something appropriate for every possible token. @1294
+G713\>559. Replace the (single) |\tokens| parameter by an array of
+ 256 token registers. @230
+C714. Allow |\indent| in math mode; also make |\valign| in math mode produce the
+ `|Missing|~|$|' error. @1046,1093
+E715. Remove redundant code: There's no need to check \\{cur_group}
+ or call \\{off_save} when starting alignments or equation numbers
+ in displays. @1130,1142
+* 8 Jun 1983
+C716. Disallow |\openout-1| and |\closeout-1|. @1350
+C717. Disallow |\lastbox| in math mode. @1080
+* 9 Jun 1983
+I718. Call \\{back_error}, not \\{error}, when |\leaders| aren't followed by
+ proper glue. @1078
+D719. Initialize for a possible paragraph, after |\noalign|
+ in a |\valign|. @785
+* 10 Jun 1983
+C720\>708. Expand the optional space after an ASCII constant. @442
+* 12 Jun 1983
+C721. Set $\\{space_factor}\gets1000$ after a rule or a
+ constructed accent. @1056,1123
+* 14 Jun 1983
+D722. Correct a serious blunder: Set $\\{disc_width}\gets0$ before testing
+ if $s$ is null (caught by JS). @869
+# This is a real bug that existed since the beginning!
+ It showed up on page~37 of the
+ Version~0 |TRIP| manual, but I didn't notice the problem.
+C723\>708. Make optional spaces after \<dimen> like those after \<number>. @448
+C724\>568. Insert \\{every_display} before calling \\{build_page}. @1145
+I725\>648. Report \TeX's capacity on overflow errors in a way that's
+ fully consistent with other statistical reports. @42
+* 17 Jun 1983
+C726. Make all |\tracing| decisions on the basis of $\ge$ versus $<$,
+ not $\ne$ versus~$=$. @581
+# Today I finished the draft of Chapter 27 (the last chapter)!
+# The changes above were released as Version 0.99 on June 19, 1983.
+* 20 Jun 1983
+C727. Set |\catcode`\%=14| in |INITEX|. @232
+C728\>587. Call \\{normal_paragraph} when |\par| occurs in vertical mode. @1094
+# Once again I'm retiring about 8am and awaking about 4pm.
+* 21 Jun 1983
+C729\>558. Don't append an overfull rule solely because of\/ |\hbadness|. @666
+R730. Don't allow the glue-ratio of shrinking to be less than~$-1$. @810,811
+* 22 Jun 1983
+B731\>653. Declare the parameter to \\{print_roman_int} to be of type \\{integer},
+ instead of \\{nonnegative_integer} (found by Debby Clark). @69
+C732\>690. Make the keyword `|by|' optional (suggested by LL). @1236
+* 24 Jun 1983
+I733. Say `|preloaded|' when announcing \\{format_ident}. @1328
+* 25 Jun 1983
+R734. Add extra boxes and
+ glue to the output of alignment. [This thwarts possible attempts
+ at trickery by which system-dependent glue set values
+ computed by |\span| could have gotten into \TeX's registers by
+ things like |\valign| and |\vsplit|. It also has the advantage
+ of perfect accuracy in alignment of vertical rules.] @809
+C735. Make leaders affect the height or width of the enclosing boxes. @656,671
+# Today I'm mainly installing a much-improved format for change files
+ in |WEB| programs (suggested by DRF).
+* 28 Jun 1983
+C736. Permit |\unskip| in vertical mode when we know that it does nothing. @1106
+* 1 Jul 1983
+E737\>700. Avoid redundant boxes when things like `|{\bf A}|' occur in math. @1186
+G738. Add a `|scaled|' feature to |\font| input. @1258
+D739\>700. Remember to correct \\{delta} when an accented box changes. @742
+* 2 Jul 1983
+R740.Introduce \\{bypass_eoln}, to remove anomalous behavior on input files
+ of length~1. (Suggested by DRF after the problem was discovered by LL). @31
+* 4 Jul 1983
+G741. Allow codes like |^^b| as well as |^^B|. @352,355
+G742. Introduce new parameters |\escapechar|, |\endlinechar|, |\defaulthyphenchar|,
+ and |\defaultskewchar|, to make \TeX\ less dependent on the
+ character set. (This affects many modules, since a lot of
+ error messages must be broken up so that they use \\{print_esc}.)
+* 7 Jul 1983
+P743. Use a system-dependent function \\{erstat} when opening or closing
+ files (suggested by DRF). @27
+* 11 Jul 1983
+# The computer is back up after more than 50 hours down time
+ (due to air conditioning failure).
+I744. Show total glue in the output of\/ |\tracingpages|. @985
+R745. Guard against insertion into an hbox. @993
+C746. Legalize the assignment \<tokenvar>=\<tokenvar>. @1227
+I747. Introduce a new parameter |\errhelp|. @1283
+F748\>623. Don't forget to check \\{global_defs} when |\tabskip| is changed. @782
+* 12 Jul 1983
+C749. Allow an |\outer| macro to appear after |\string|, |\noexpand|,
+ and |\meaning| (Todd Allen). @369,471
+C750. Make `|\the|' an expandable control sequence (i.e., move it
+ from the stomach to the throat); this cleans up
+ several annoying glitches. @367
+C751\>620. Allow |\unhbox| and |\unhcopy| in math mode if the box is void. @1110
+* 13 Jul 1983
+# I lectured for four hours at the TUG meeting today after very little sleep!
+* 16 Jul 1983
+# The following were suggested by TUG meeting discussions.
+L752. Round the value of \\{default_rule} more properly: It should be 26215. @463
+Q753\>700. Fix |\mathaccent| again; it's still not right!
+ The final height should be the maximum of
+ the height of accented letter without superscript and
+ the height of unaccented letter with superscript. @742
+G754. Add a new feature |\newlinechar|. @59
+G755. Allow boxes and rules in discretionaries (suggested by somebody
+ from Hewlett-Packard). @1121
+I756\>X28. Show all token expansions, not just macros,
+ when |\tracingcommands|. @367
+C757. Allow |\char| in a |\hyphenation| list. @935
+G758. Introduce a new feature |\aftergroup|; it can be implemented with
+ \\{save_stack}. @326
+C759. Run the running dimensions to alignment boundaries (suggested
+ by ARK). @806
+* 17 Jul 1983
+R760. Zero out \\{hyf} values at the edges, so that
+ weird pattern data cannot lead to Pascal range checks. @965
+R761\>X190. Decrease the |hc| codes for hyphenation, so that code~127 cannot
+ possibly be matched. @937,962
+C762\>672. Allow whatsits after hyphenatable words. @899
+C763\>604. Represent an italic correction as an explicit kern. @1113
+* 18 Jul 1983
+C764. Allow lowercase letters in file names. @519
+I765. Change the message `|No output file|' to: `|No pages of output|'. @642
+I766. Confirm that a quiet mode is being entered, when error
+ interaction ends with |Q|, |R|, or |S| (suggested by ARK). @86
+# Version 0.999 was finally installed today; a new program listing has
+ been printed.
+# From now on, I plan to keep all section numbers unchanged.
+# I'm done writing Appendix~H; beginning to revise Chapter~20.
+* 25 Jul 1983
+C767\>663. Allow space after `|to|' in the |\read| command (FY). @1215
+# To bed at 1pm today.
+* 27 Jul 1983
+S768\>665. Stack the current type of\/ |\if|; this precaution is necessary
+ in general (FY). @498
+# To bed at 2pm today.
+* 29 Jul 1983
+E769. Avoid putting a control sequence in the hash table
+ when it occurs after |\ifx|. (Requested by Math Reviews people.) @507
+# Finished a version of {\sl The \TeX book\/} lacking only Appendices
+ D, E, and~I, for distribution to interested readers.
+# To bed at 10:30pm, planning to arise regularly at 6am for a change.
+* 31 Jul 1983
+I770\>766. Call \\{update_terminal} when going quiet (HWT). @86
+* 1 Aug 1983
+C771. Don't put an empty line at the end of an |\input| file! (This simplifies
+ the rules and the program, and also gets around a bug that occurred
+ at the end of files with $\\{end_line_char}<0$.) @362
+# The changes above went into Version 0.9999, which was widely distributed.
+* 16 Aug 1983
+B772\>665. Rectify a ridiculous gaffe: I initialized $q$ every time the loop
+ of \\{change_if_limit} was performed! (Found by FY.) @497
+I773\>648. Distinguish `|string|' from `|strings|' when reporting statistics. @1334
+A774. Introduce \\{lx}, to correct a bug in |\xleader| computations
+ (found by FY). @627
+* 20 Aug 1983
+F775. Don't forget to apply |\/| to ligatures. @1113
+# Today I began to read all previous issues of {\sl TUGboat}, in preparation for
+ Appendix~D.
+* 27 Aug 1983
+I776. Add debugging hack number~16, to help catch subtle data structure bugs. @1339
+E777. Remove redundant setting and resetting of \\{name_in_progress}. @531
+S778\>618. Suppress |\input| during a font size spec; otherwise
+ \\{cur_name} is clobbered (found by MDS). @1258
+G779. Introduce new conditionals |\ifhbox| and |\ifvbox|. @505
+* 29 Aug 1983
+D780\>750. Test for an empty list, if emptiness will mess up the data structure.
+ (Found by Todd Allen.) @478
+E781\>624. Use \\{fast_store_new_token} in another place for efficiency. @466
+I782. Say `|has only|' instead of `|has|'. @579
+# These changes yield Version 0.99999, used only at Stanford.
+* 30 Aug 1983
+C783. Make funny blank spaces showable. @298
+* 31 Aug 1983
+C784\>754. Make |\newlinechar| affect \\{print_char}, not just \\{print}. @58
+* 4 Sep 1983
+G785. Add new features |\lastkern|, |\lastpenalty|, |\unkern|, |\unpenalty|.
+ @424,996,1105
+# OK, Appendix D is finished!!
+# The above changes have been installed in Version 0.999999.
+* 17 Sep 1983
+P786\>548. Don't bother making duplicate font identifiers; that
+ was overkill, not really needed. @1258
+# Will this be the historic last change to \TeX?
+* 18 Sep 1983
+I787. Correct a minor inconsistency, `|display|' not `|displayed|'. @211
+* 20 Sep 1983
+C788\>604. Treat the kerns inserted for accents as explicit kerns. @1125
+* 26 Sep 1983
+I789. Change `|log|' to `|transcript|' in several messages. @535,1335
+# The index was finished today; I mailed the entire {\sl \TeX book\/} to
+ Massachusetts for final proofreading before publication.
+* 1 Oct 1983
+D790. Prevent uninitialized trie positions in case of overflow
+ (found by Bernd Schulze). @944
+* 7 Oct 1983
+# Henceforth our weekly `\TeX\ lunch' meetings will be called `\MF\ lunch'.
+# DRF begins to produce {\sl The \TeX book\/} on our APS phototypesetter.
+* 14 Oct 1983
+P791\>633. Ignore spaces at the ends of lines also in |TEX.POOL| (found
+ by DRF). @52
+D792\>610. Initialize the \\{history} variable at \\{start_here} (DRF). @1332
+* 18 Oct 1983
+I793. Extend \\{runaway} to catch runaway text (suggested by FY). @306
+D794. Reset \\{cur_cs} after \\{back_input}, not after scanning the
+ `|=|' (found by FY). @1226
+* 24 Oct 1983
+I795\>638. Change the error recovery for bad delimiters, in accordance with
+ the changed syntax. (Found by Barry Smith.) @1183
+* 9 Nov 1983
+E796. Optimize the code a bit more, based on empirical frequency data gathered
+ during September and October: In \S45, use the fact that the
+ result is almost always true. In \S380, delete `{\bf while}
+ \\{true} {\bf do}' since many compilers implement that badly.
+ Rewrite \S852 to avoid calling \\{badness} in the most common case.
+ @45,380,852
+* 3 Dec 1983
+F797. Don't forget to call |error| after the message has been
+ given (noticed by Gabi Kuper). @500
+# Version 1.0 released today incorporates all of the above.
+* 9 Dec 1983
+# Dinner party with 36 guests to celebrate \TeX's coming of age.
+* 2 Feb 1984
+S798\>786. Reinstall |\font| precautions that I thought were unnecessary.
+ I overlooked many problematic possibilities, like
+ `|{\font\a=x| |\global\a}| |\the\font|'
+ and `|\font\a=x| |\font\b=x| |\let\b=\undefined| |\the\a|', etc.
+ (Found by Mike Urban.) The new remedy involves removal of the
+ \\{font_ident} array and putting the identifiers into a frozen
+ part of the hash table; so there's a sprinkling of corrections
+ in lots of modules. But basically the change is quite conservative,
+ so it shouldn't spawn any new bugs (it says here). @222,267,1257
+* 9 Feb 1984
+S799. Remove the possibility of double interrupt, in a scenario
+ found by Clint Cuzzo. @1031
+* 12 Feb 1984
+Q800. Improve spacing in a formula like |$(A,<)$|. @764
+* 13 Feb 1984
+A801. Avoid a bad {\bf goto}, as diagnosed by Clint Cuzzo and George O'Connor.
+ (Must not go directly to \\{switch}.) @346
+E802. Conserve string pool space by not storing file name in two
+ guises (suggested by DRF). @537
+* 26 Feb 1984
+I803. Make scaled output look cleaner by printing fewer decimals whenever
+ this involves no loss of accuracy. (Suggested by \MF\ development.) @103
+* 2 Mar 1984
+R804. Maintain 17-digit accuracy, not 16; now
+ constants like `|.00000762939453126pt|' will round correctly. @452
+* 16 Mar 1984
+R805. Plug a loophole that permitted recursion in \\{get_next}, by disallowing
+ deletions in \\{check_outer_validity}. @336
+* 24 Mar 1984
+I806. Open the terminal before trying to wake it up, when the program starts bad.
+ @1332
+* 27 Mar 1984
+R807. Check that $k<63$, to avoid the
+ |\patterns{xxx...xxxdxxxdxxx}| anomaly found by Jacques D\'esarm\'enien. @962
+* 11 Apr 1984
+F808. Supply code for the missing case \\{adjust_node} in \\{copy_node_list}. @206
+# Yoicks, how could serious bugs like that have escaped detection?
+* 11 Jun 1984
+D809\>627. Initialize \\{char_base}, etc., for \\{null_font}.
+ (Found by Nick Briggs.) @552
+R810. Clear the \\{buffer} array initially (Briggs). @331
+* 21 Jun 1984
+C811. Look ahead for ligature or kern after a |\chardef|'d item
+ (D\'esarm\'enien). @1038
+* 4 Jul 1984
+R812. Make the quarterword constraint explicit with a
+ new `\\{bad}' case (19). @111
+* 7 Jul 1984
+E813. Optimize \\{firm_up_the_line} slightly,
+ to be consistent with the \MF\ program. @363
+* 8 Jul 1984
+I814. Give additional diagnostics when |\tracingmacros>1|. @323
+# The changes above were incorporated in Version 1.1, released July 9, 1984.
+* 27 Jul 1984
+I815. Say `|see| |the| |transcript| |file|' after handling offline |\show|
+ commands. (Suggested by \MF.) @1298
+* 20 Oct 1984
+I816. Allow `|0|' in response to error prompts. @84
+# Those two changes led to Version 1.2.
+* 25 Nov 1984
+R817. Don't forget to check for \\{null} before looking at subfields
+ of a node. (This was ``dirty Pascal,'' with two quarterword 0's
+ read as a halfword.) @846
+R818. Ditto in another place! @939
+E819. Remove the fixed-at-compile-time
+ partition between lower and upper memory. @116,125,162
+# This major change in memory management
+ completes Version 1.3, which was published in preliminary
+ looseleaf form as `\TeX: The Program'.
+* 20 Dec 1984
+R820. Keep the \\{node_size} field from overflowing if the lower part of memory
+ is too large. @125
+# That was another bug in existence from the beginning!
+* 5 Jan 1985
+I821. Improve the missing-format-file error (DRF). @524
+* 7 Jan 1985
+I822. Update the terminal right away so that the welcoming message will
+ appear as soon as possible (DRF). @61
+* 23 Jan 1985
+I823. Convey more uncertainty in the
+ help message at times of \\{confusion}. @95
+I824\>610. Improve the \\{history} logic in the \\{warning_issued} case. @245
+* 18 Feb 1985
+P825\>810. Stick to standard Pascal: Don't
+ use \\{first} in a {\bf for} loop. [Some procedures ``threaten'' it
+ globally, according to British Standard 6192, section 6.8.3.9.]
+ (Pointed out by CET.) @331
+* 11 Apr 1985
+S826. Prevent nonexistent characters from being output by
+ unusual combinations of ligatures and hyphenation. @915
+* 15 Apr 1985
+L827\>819. Compute memory usage correctly in |INITEX|; the previous number
+ was wrong because of a |WEB| text macro without parentheses (DRF). @164
+* 16 Apr 1985
+E828. Speed up \\{flush_list} by not calling \\{free_avail} (DRF). @123
+* 17 Apr 1985
+A829\>788. Introduce a special kind of kern for accent positioning;
+ it must not disappear after a line break. @837,879,1125
+* 18 Apr 1985
+R830\>755. Prevent |\lastbox| and |\unkern| from removing discretionary replacements.
+ @1081,1105
+# That completes Version 1.4.
+* 26 Apr 1985
+C831. Don't try \\{\TeX_area} if a nonstandard file area has been specified
+ (DRF). @537
+# That was \#401 in \TeX78; I never learn!
+* 30 Apr 1985
+C832\>754. Eliminate the limitation on |\write| length; the reason for it
+ has disappeared (Nancy Tuma). @1370
+* 8 May 1985
+D833\>819. Allocate two words for the head of the \\{active} list (CET). @162
+* 11 May 1985
+I834. Change \\{wterm} to \\{wterm_ln} after a bad beginning (Bill Gropp). @1332
+E835\>806. Don't open the terminal twice (CET). @1332
+* 22 May 1985
+R836. Test for \\{batch_mode} after trying to open the transcript file,
+ not before (DRF). @92
+R837. Be prepared for string pool overflow while reading the command line!
+ (This bug was first found in \MF, when it could occur more easily.) @525
+* 7 Aug 1985
+A838. Fix a bug in |\edef\foo{\iffalse\fi\the\toks0}|: \TeX\ should stay in the
+ loop when expanding non-|\the|. (Found by Dan Brotsky.) @478
+# The above changes were incorporated in Version 1.5.
+* 27 Nov 1985
+C839\>764. Make `|plain|' a lowercase name, for consistency with the manual. @521
+I840\>669. Wake up the terminal for |\show| commands. @1294,1297
+# The above changes were incorporated in Version 2.0, which was published
+ as Volume~B of the {\sl Computers \& Typesetting\/} series.
+* 15 Dec 1986
+I841. Punctuate the Poirot help message more carefully. @1283
+* 28 Jan 1987
+R842. Make sure that \\{max_in_open} doesn't exceed 127 (DRF). @14
+D843\>680. Don't allow a |\kern| to be clobbered at the end of a pre-break list
+ when a discretionary break is taken. (A missing `{\bf else}' was the
+ source of the error, diagnosed incorrectly before.) @881
+D844. Take account of discarded nodes when computing the background width
+ after a discretionary. @840
+# That was the first really serious bug detected for more than 17 months! I found it
+ while experimenting with right-to-left extensions.
+# Version 2.1 was released on January 26, 1987.
+* 5 Feb 1987
+E845. Remove cases in \\{shorthand_def} that cannot occur (found by Pat Monardo). @1224
+* 14 Apr 1987
+R846. Improve robustness of data structure display
+ when debugging (Ronaldo Am\'a). @174,182
+* 21 Apr 1987
+E847. Make the storage allocation algorithm more elegant and efficient. @127
+* 22 Apr 1987
+A848\>742. Calculate the empty-line condition properly when \\{end_line_char} is
+ absent. @360
+# The previous three changes were found while I was teaching a class based
+ on Volume~B; they led to Version 2.2.
+* 28 Apr 1987
+E849. Avoid closing a file when \TeX\ knows that it isn't open (JS). @560
+* 3 Aug 1987
+S850. Clean up unfinished output if it's necessary to
+ \\{jump_out} (Klaus Gunterman). @642
+# That makes Version 2.3; subsequent version numbers won't be logged here.
+* 19 Aug 1987
+A851. Indent rules properly in cases like\hfil\break
+ |\hangindent=1pt$$\halign{...\cr\noalign{\hrule}}$$|. @806
+* 20 Aug 1987
+S852. Introduce \\{co_backup} because of cases like
+ |\hskip 0pt plus 1fil\ifdim| (Alan Guth). @366
+* 9 Nov 1987
+S853. Change the calculation for number of leader boxes, so that
+ it won't be too sensitive to roundoff error near exact multiples
+ (M. F. Bridgland). @626
+* 17 Nov 1987
+A854. Replace my stupid algorithm
+ for fixed-point multiplication of negatives (WGS). @572
+* 12 Dec 1987
+B855. Fix a typo in the initialization of hyphenation tables (PB). @952
+# That error was almost completely harmless, thus undetectable,
+ except if some |\lccode| is~1 and no |\patterns| are given.
+* 23 Dec 1987
+S856\>564. Be more cautious when ``relaxing'' a previously undefined |\csname|;
+ you might be inside a group (CET). @372
+* 20 Apr 1988
+S857. Make sure \\{temp_head} is well-formed whenever it can be
+ printed in a ``runaway'' message: Consider constructions like
+ |\outer\def\a0{}\a\a| (Silvio Levy). @391
+* 24 Apr 1988
+S858\>618. Avoid conflicting use of the string pool in constructions like
+ |\def\\#1{}\input a\\\z| (Robert Messer). @260
+* 10 May 1988
+R859. Amend the |\patterns| data structure when $\\{trie_min}=0$
+ (PB). @951,953
+* 25 May 1988
+R860. Guarantee that \\{trie_pointer} cannot be out of range. @923
+S861\>618. Avoid additional bugs like \#858 in constructions
+ like |\input a\romannumeral1|, etc. @464,465,470
+R862\>618. Prevent similar string pool confusion that could occur
+ during the processing of |**\input\romannumeral6|. @525
+* 19 Jun 1988
+S863\>819. Prevent a negative dividend from rounding upward,
+ causing a loop (CET). @126
+E864\>819. Adopt a smoother allocation strategy when
+ memory is nearly gone (CET). @126
+* 20 Jun 1988
+D865\>852. Initialize \\{cur_order}, now that it's being backed up
+ (Tsunetoshi Hayashi). @439
+* 6 Nov 1988
+S866\>612. Disable \\{fatal_error} in \\{prompt_input}, so that
+ \\{open_log_file} can use it safely (Tim Morgan). @71
+S867\>836. Force terminal output whenever \\{open_log_file} fails. @535
+* 14 Dec 1988
+P868\>866. Restore \\{fatal_error} in \\{prompt_input}, but don't
+ let it be unsafe for \\{open_log_file}. @92,534
+* 23 Jan 1989
+D869. Give $q$ a legal value when recovering from ``infinite shrinkage''
+ error. @976,1004
+* 17 Feb 1989
+D870\>758. Avoid spurious error message for |\aftergroup\relax\dump| by avoiding
+ inaccessible |\aftergroup| tokens (FM and Rainer Sch\"opf). @280
+* 20 Mar 1989
+R871. Don't refer to \\{link}(\\{null}) even when it ``can't happen''
+ (PB). @791
+* 7 Jun 1989
+S872. Avoid confusion from |$$\begingroup\halign{#\cr}$$| (FM). @1130
+* 20 Jun 1989
+S873. Put fraction digits into dynamic memory, not the global \\{dig} array,
+ because of constructions like |.5\ifdim.6| (FM). @452
+* 17 Jul 1989
+S874. Prevent embarrassing attempts to report errors before the string
+ mechanism has been fully initialized, for example when the
+ command line exceeds the buffer size (WGS). @31
+* 16 Aug 1989
+M875. Allow integer products to be 31 bits long (FM). @105
+* 31 Aug 1989
+C876\>441. Increase the number of tokens shown by \\{token_show}
+ (J. Lavagnino). @295
+S877. Avoid confusion from |$$\begingroup\eqno$$| (FM). @1140
+# The recent TUG meeting turned out to be an extend-\TeX-for-the-nineties
+ party! I agreed that some extensions for non-English languages
+ ought to be made while I still knew how to do them. (In other words,
+ I broke my firm commitment to keeping \TeX\ completely stable;
+ but in this case nobody objected.) The following eleven changes
+ were coded during the month of September.
+* 30 Sep 1989
+G878. Install major change allowing general 8-bit code input. @38,352
+G879. Install major change allowing multiple hyphenation tables
+ (M. Ferguson). @923
+G880. Introduce new parameters |\lefthyphenmin| and |\righthyphenmin|. @923
+G881. Introduce major new ligature capabilities including implicit
+ boundary characters. @908,1037
+G882. Install new |\inputlineno| feature suggested by MDS. @424
+G883. Install new |\holdinginserts| feature suggested by FM. @1014
+G884. Install new |\badness| feature. @424,664
+G885. Install new |\emergencystretch| feature. @863
+G886. Install new |\errorcontextlines| feature suggested by FM. @311
+S887. Recover from anomaly when hyphenation |char_warning| clobbers
+ |old_setting|. @863
+P888. Make it easier to change the format extension (Don Hosek). @520,1328
+* 16 Oct 1989
+R889. Avoid range check in null font with |bc=256| (PB). @565
+* 22 Nov 1989
+S890\>856. Prevent \\{save_stack} conflicts in
+ |{\hbox\expandafter{\csname\endcsname}}| and\kern-3pt\break
+ similar constructions (WGS). @645,1117
+S891\>858. System-dependent parts of file names must be addressed relatively,
+ not absolutely (FM and Rainer Sch\"opf). @516,517
+* 3 Dec 1989
+G892\>880. Allow different hyphenmins in the same paragraph (M. Ferguson). @1376
+S893. Distinguish |\par| from characters on |\if| tests. (MVL). @334
+S894\>378. Alignments need to be more robust against malicious
+ attacks (MVL). @782
+C895. Don't let kerns in discretionaries disappear at breaks (MVL). @869
+Q896\>881. Make the new hyphenation reconstruction procedure less cautious,
+ so that it doesn't lose hyphens found by the old method. @914
+* 11 Dec 1989
+D897\>879. Make an undumped trie dumpable again (PB). @1325
+* 18 Dec 1989
+G898\>588. Allow access to page totals in |\output| routines
+ (FM and Chris Rowley). @421
+* 22 Jan 1990
+R899\>611. Recognize more cases of unbalanced |\output| (CET). @1026
+* 29 Jan 1990
+S900\>758. Make |\aftergroup| work properly after |\eqno| (Michael Downes).
+ @1194
+* 1 Feb 1990
+S901\>878. Fix one more case of \\{end_line_char_inactive} (WGS). @360
+* 22 Feb 1990
+R902. Don't lose the last active node when total demerits are very high (FM).
+ @836,854
+* 13 Mar 1990
+D903. Doublecheck math fonts after making equation number (MVL). @1194
+D904. Don't forget to rule out charnodes before testing \\{type} (MVL).
+ @805,1202
+* 23 Mar 1990
+F905\>881. Don't change the font of punctuation preceding a hyphenated word
+ (Scott C. Allendorf). @903
+I906. Balance the parentheses shown on the terminal during normal runs. @1335
+E907. Optimize |\ifx\p\q| after |\let\p=\q| (MVL). @508
+S908. Treat migration properly in displays (MVL). @1199,1205
+# We're now up to Version 3.0; I sincerely hope all bugs have been found.
+* 11 May 1990
+F909\>881. Initialize |\nullfont| ligature parameters (Lance Carnes). @552
+* 22 July 1990
+S910\>579. Treat |\prevgraf| as zero within |\write| (Bogus\l aw Jackowski).
+ @422
+* 26 July 1990
+S911. Report `|l.1|' when first line of file overflows buffer
+ (George Russell). @538
+* 5 December 1990
+S912\>878. Translate unprintable characters in font identifiers (WGS). @63
+* 28 December 1990
+R913. Avoid range check when there are 65536 or more pages (Eberhard Mattes).
+ @642
+* 20 September 1991
+I914\>878. Improve error message for |\mathchar| out of range. @436
+S915\>878. Retain unprintable internal strings in 8-bit form (FM). @59
+S916\>881. Retain right punctuation context for ligature reconstruction
+ (problem found by Brian Hamilton Kelly). @903
+* 10 January 1992
+S917\>881. Also avoid producing a double kern at boundary (CET). @897
+S918. Disallow |\setbox| where it doesn't work (Robert Hunt). @1241,1270
+S919. Robustify |\mskip| and |\mkern| in presence of negative quad (WGS).
+ @716,717
+S920\>679. Defend against `|}{|' in |\read| (Michael Downes). @483
+E921\>798. Save string memory if font occurs repeatedly (Bogus\l aw Jackowski).
+ @1260
+S922\>784. Don't let |\newlinechar| interrupt unprintable expansion (Bernd
+ Raichle). @59,60
+* 7 February 1992
+D923\>881. Restore |cur_l| properly when boundary character doesn't exist
+ (Mattes and Raichle). @1036
+* 17 July 1992
+C924\>892. Use current language at beginning of horizontal mode (Rainer
+ Sch\"opf and CET). @1091,1200
+* 17 December 1992
+R925\>879. Avoid (harmless) range errors (Philip Taylor and CET). @934,960
+* 25 February 1993
+C926\>881. Protect kerns inserted by boundary characters (William Baxter).
+ @837,866
+S927\>917. Don't let boundary kern disappear after hyphenation. @897
+* 26 June 1993
+R928\>668. Avoid potential future bug (Peter Breitenlohner). @628,637
+* 17 December 1993
+S929\>881. Boundary character representation shouldn't depend on font
+ memory size (Berthold Horn). @549,1323
+* 10 March 1994
+R930. Huge font parameter number may exceed array bound (CET). @549
+* 4 September 1994
+F931\>926. Math kerns are explicit (Walter Carlip). @717
+R932. Avoid overflow on huge real-to-integer conversion. @625,634
+* 19 March 1995
+R933. Avoid spurious reference counts in format files (PB). @1335
+\relax
+\bye
+
+Up to a point it is better to let the snags [bugs] be there
+than to spend such time in design that there are none
+(how many decades would this course take?).
+-- A M Turing
+ Proposals for Development in the Mathematics Division
+ of an Automatic Computing Engine (ACE)
+ Report E882, Executive Committee, National Physical Laboratory (NPL)
+ 1945; reprinted in April 1972 as NPL report Com Sci 57
+ page 18
+ quoted by Carpenter and Doran in The Computer Journal 20 (1977), 273.
+
+DRF David Fuchs
+HWT Howard Trickey
+FY Frank Yellin
+LL Leslie Lamport
+JS Jim Sterken
+ARK Arthur Keller
+CET Chris Thompson
+FM Frank Mittelbach (added subsequent to publication of paper)
+PB Peter Breitenlohner (ditto)
+WGS Wayne G. Sullivan (ditto)
+MVL Marc van Leeuwen (ditto)
+MDS Michael D. Spivak (ditto)
diff --git a/Master/texmf-doc/doc/english/knuth/expr.mf b/Master/texmf-doc/doc/english/knuth/expr.mf
new file mode 100644
index 00000000000..fe05a01322f
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/expr.mf
@@ -0,0 +1,5 @@
+string s[]; s1="abra";
+path p[]; p1=(0,0)..(3,3); p2=(0,0)..(3,3)..cycle;
+tracingonline:=1; scrollmode;
+forever: message "gimme an expr: "; s0:=readstring;
+show scantokens s0; endfor
diff --git a/Master/texmf-doc/doc/english/knuth/index.html b/Master/texmf-doc/doc/english/knuth/index.html
new file mode 100644
index 00000000000..b3b0e7b9658
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/index.html
@@ -0,0 +1,193 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML>
+<HEAD>
+<TITLE>Index of texmf/doc/knuth/</TITLE>
+<!-- Created: UV, 1996/02/25 -->
+<!-- Last Updated: UV, 1998/08/15 -->
+</HEAD>
+
+<BODY>
+<H1>Index of <CODE>texmf/doc/knuth/</CODE></H1>
+
+<HR>
+
+<P> This page provides access to documentation from Donald Knuth
+about various aspects of TeX:
+<UL>
+ <LI><A HREF="#manuals">
+ TeX &amp; METAFONT Manuals</A>
+ <LI><A HREF="#examples">
+ TeX &amp; METAFONT Examples</A>
+ <LI><A HREF="#errorlog">
+ TeX &amp; METAFONT Errata</A>
+ <LI><A HREF="#triptrap">
+ Literate Programming</A>
+ <LI><A HREF="#triptrap">
+ Trip &amp; Trap Test Manuals</A>
+ <LI><A HREF="#errata">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+</UL>
+
+
+<HR>
+<H2><A NAME="manuals">TeX &amp; METAFONT Manuals</A></H2>
+
+<P>
+These manuals are distributed only for people to see the
+examples of TeX input, not for use in the preparation of books
+like <CITE>The TeXbook</CITE> or <CITE>The TeXbook</CITE>.
+These manuals are copyrighted and should not be TeXed!
+<DL>
+ <DT><A HREF="texbook.tex">texbook.tex</A><BR>
+ <DD>This file is the TeX source of <CITE>The TeXbook</CITE>
+ by Donald E. Knuth, last updated in August 1998.
+
+ <DT><A HREF="mfbook.tex">mfbook.tex</A><BR>
+ <DD>This file is the TeX source of <CITE>The METAFONTbook</CITE>
+ by Donald E. Knuth, last updated in August 1998.
+
+ <DT><A HREF="mfman.mf">mfman.mf</A><BR>
+ <DD>This file is the METAFONT source of most of the figures
+ in the <CITE>The METAFONTbook</CITE>. It can be run
+ through METAFONT and GFtoDVI to produce proof sheets.
+</DL>
+
+
+<H2><A NAME="examples">TeX &amp; METAFONT Examples</A></H2>
+<DL>
+ <DT><A HREF="story.tex">story.tex</A><BR>
+ <DD>This is the canonical example file for TeX which is
+ described in Chapter 6 of <CITE>The TeXbook</CITE>.
+
+ <DT><A HREF="io.mf">io.mf</A><BR>
+ <DD>This is the canonical example file for METAFONT which is
+ described in Chapter 5 of <CITE>The METAFONTbook</CITE>.
+
+ <DT><A HREF="expr.mf">expr.mf</A><BR>
+ <DD>This is another example file for METAFONT which is
+ described in Chapter 8 of <CITE>The METAFONTbook</CITE>.
+</DL>
+
+
+<H2><A NAME="errorlog">TeX &amp; METAFONT Errata</A></H2>
+<DL>
+ <DT><A HREF="errorlog.dvi"><CITE>The Error Log of TeX</CITE></A> (DVI)<BR>
+ <DD>This is an updated version of the appendix of the paper
+ <CITE>The Errors of TeX</CITE>, last updated in March 1995.
+ It includes a chronological listing of all changes and bug
+ fixes in TeX (both TeX78 and TeX82) that have been
+ applied since March 1978.
+
+ <DT><A HREF="errata/tex82.bug">tex82.bug</A><BR>
+ <DD>This is a chronological listing of all changes and bug
+ fixes in TeX (specifically TeX82) that have been
+ applied since September 1982.
+
+ <DT><A HREF="errata/mf84.bug">mf84.bug</A><BR>
+ <DD>This is a chronological listing of all changes and bug
+ fixes in METAFONT (specifcally MF84) that have been
+ applied since March 1984.
+
+ <DT><A HREF="errata/cm85.bug">cm85.bug</A><BR>
+ <DD>This is a chronological listing of all changes and bug
+ fixes in the Computer Modern fonts (CM85) that have been
+ applied since April 1985.
+</DL>
+
+
+<H2><A NAME="litprog">Literate Programming</A></H2>
+<DL>
+ <DT><A HREF="webman.dvi">
+ <CITE>The WEB System of Structured Documentation</CITE></A> (DVI)<BR>
+ <DD>This is an abridged version of the manual that describes
+ the WEB system. Not included here are the WEB listings of
+ the <code>tangle</code> and <code>weave</code> programs.
+
+ <DT><A HREF="web.dvi">
+ <CITE>Literate Programming</CITE></A> (DVI)<BR>
+ <DD>This is an online version of the article
+ <CITE>Literate Programming</CITE> by Donald E. Knuth
+ published in <CITE>The Computer Journal</CITE> 1984
+ that describes the philosophy of the WEB system.
+
+ <DT><A HREF="primes.web">primes.web</A><BR>
+ <DD>This is the WEB source of the example program discussed
+ in the article <CITE>Literate Programming</CITE>.
+ (A PASCAL program to print a table of prime numbers.)
+</DL>
+
+
+<H2><A NAME="triptrap">Trip &amp; Trap Test Manuals</A></H2>
+<DL>
+ <DT><A HREF="tripman.dvi">
+ <CITE>A torture test for TeX</CITE></A> (DVI)<BR>
+ <DD>This is an abridged version of the manual that describes
+ the <CODE>trip</CODE> test, a torture test for TeX.
+ (Most of the appendices have been left out since nobody
+ really would want to read that anyway.)
+
+ <DT><A HREF="trapman.dvi">
+ <CITE>A torture test for METAFONT</CITE></A> (DVI)<BR>
+ <DD>This is an abridged version of the manual that describes
+ the <CODE>trap</CODE> test, a torture test for METAFONT.
+ (Most of the appendices have been left out since nobody
+ really would want to read that anyway.)
+</DL>
+
+<H2><A NAME="errata">Errata in <CITE>Computers &amp; Typesetting</CITE></A></H3>
+<UL>
+ <!-- Note: files have been renamed to avoid name conflicts -->
+ <!-- since errata.{one,two,...,tex} all produce errata.dvi -->
+
+ <LI><A HREF="errata/errata1.dvi">
+ Errata in <CITE>The TeXbook</CITE></A> (in the first printing)
+ (October 1984)
+ <LI><A HREF="errata/errata2.dvi">
+ Errata in <CITE>The TeXbook</CITE></A> (in the second printing)
+ (January 1986)
+
+ <LI><A HREF="errata/errata3.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+ (15 June 1987)
+ <LI><A HREF="errata/errata4.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+ (20 February 1989)
+ <LI><A HREF="errata/errata5.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+ (30 September 1989)
+ <LI><A HREF="errata/errata6.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+ (31 December 1990)
+ <LI><A HREF="errata/errata7.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A>
+ (15 March 1992)
+ <LI><A HREF="errata/errata8.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A><BR>
+ (unntil the publication of the `final' printing of Volume C, June 1993)
+ <LI><A HREF="errata/errata9.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A><BR>
+ (unntil the publication of the `final' printing of Volume A, April 1996)
+ <LI><A HREF="errata/errata.dvi">
+ Errata in <CITE>Computers &amp; Typesetting</CITE></A><BR>
+ (since the publication of the `final' printings, as of August 1998)
+</UL>
+<UL>
+ <LI><A HREF="http://www-cs-faculty.stanford.edu/~knuth/abcde.html">
+ http://www-cs-faculty.stanford.edu/~knuth/abcde.html</A><BR>
+ Don Knuth's <CITE>Computers &amp; Typesetting</CITE> WWW page.
+
+ <LI><A HREF="http://www-cs-faculty.stanford.edu/~knuth/err-abcde.ps.gz">
+ http://www-cs-faculty.stanford.edu/~knuth/err-abcde.ps.gz</A><BR>
+ Don Knuth's latest errata for <CITE>Computers &amp; Typesetting</CITE>.
+</UL>
+<BR>
+
+<A HREF="../index.html">
+<IMG ALT="Index of texmf/doc/" SRC="../html/icons/back.xbm"></A>
+<HR>
+<ADDRESS></ADDRESS>
+<!-- hhmts start -->
+Last modified: Sat Aug 15 19:22:01 CEST 1998
+<!-- hhmts end -->
+</BODY>
+</HTML>
diff --git a/Master/texmf-doc/doc/english/knuth/io.mf b/Master/texmf-doc/doc/english/knuth/io.mf
new file mode 100644
index 00000000000..58a8be68db2
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/io.mf
@@ -0,0 +1,23 @@
+mode_setup;
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar=round 1/18em;
+beginchar("O",0.8em#,cap#,0); "The letter O";
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle;
+ penlabels(1,2,3,4); endchar;
+def test_I(expr code,trial_stem,trial_width) =
+ stem#:=trial_stem*pt#; define_blacker_pixels(stem);
+ beginchar(code,trial_width*em#,cap#,0); "The letter I";
+ penpos1(stem,15); penpos2(.9stem,12); penpos3(stem,10);
+ x1=x2=x3=.5w; y1=h; y2=.55h; y3=0; x2l:=1/6[x2l,x2];
+ penstroke z1e..z2e{down}..z3e;
+ penlabels(1,2,3); endchar; enddef;
diff --git a/Master/texmf-doc/doc/english/knuth/mfman.mf b/Master/texmf-doc/doc/english/knuth/mfman.mf
new file mode 100644
index 00000000000..0bbe24f9de6
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/mfman.mf
@@ -0,0 +1,2474 @@
+% This file generates most of the figures for The METAFONTbook
+
+def clear_all = clearit; clearxy; pickup standardpen;
+proofrulethickness 0;
+enddef;
+
+def heavy_dot expr z =
+ makelabel.top("",z-(1,0));
+ makelabel.top("",z+(1,0));
+ makelabel.top("",z-(0,1));
+ makelabel.top("",z+(0,1));
+ makelabel.top("",z+(1,1)/sqrt2);
+ makelabel.top("",z+(1,-1)/sqrt2);
+ makelabel.top("",z-(1,1)/sqrt2);
+ makelabel.top("",z-(1,-1)/sqrt2);
+ enddef;
+
+def font_setup=
+define_pixels(u,tiny,axis,hheight,border);
+define_blacker_pixels(hair,thin,thick,rulethickness);
+pickup if tiny<.5: nullpen else: pencircle scaled tiny fi;
+tinypen:=savepen;
+currenttransform:=identity slanted slant yscaled aspect_ratio;
+enddef;
+
+mode=proof; mode_setup;
+standardpen=savepen;
+
+"Figure 2a"; % 6 points and a grid
+clear_all;
+pair offset; offset=(.5,.5);
+z1=(0,100)+offset;
+z2=(100,100)+offset;
+z3=(200,100)+offset;
+z4=(0,0)+offset;
+z5=(100,0)+offset;
+z6=(200,0)+offset;
+proofrulethickness .8;
+proofrule (z1+(0,5),z4-(0,5)); proofrule (z4-(5,0),z6+(5,0));
+makelabel.top("1 ",z1);
+makelabel.top("2 ",z2);
+makelabel.top("3 ",z3);
+makelabel.bot("4 ",z4);
+makelabel.bot("5 ",z5);
+makelabel.bot("6 ",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+pickup pencircle;
+for x=10 step 10 until 200: draw (x,-5)+offset..(x,105)+offset; endfor
+for y=10 step 10 until 100: draw (-5,y)+offset..(205,y)+offset; endfor
+showit;
+shipit;
+
+"Figure A2a"; % 6 points and a grid and two more points
+clear_all;
+proofoffset(30,0);
+pair offset; offset=(.5,.5);
+z1=(0,100)+offset;
+z2=(100,100)+offset;
+z3=(200,100)+offset;
+z4=(0,0)+offset;
+z5=(100,0)+offset;
+z6=(200,0)+offset;
+proofrulethickness .8;
+proofrule (z1+(0,5),z4-(0,5)); proofrule (z4-(5,0),z6+(5,0));
+makelabel.top("1 ",z1);
+makelabel.top("2 ",z2);
+makelabel.top("3 ",z3);
+makelabel.bot("4 ",z4);
+makelabel.bot("5 ",z5);
+makelabel.bot("6 ",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+makelabel.lft("(-5,15)",(-5,15)+offset);
+makelabel.top("(60,30) ",(60,30)+offset);
+%makelabel.top(" ,30) ",(60,30)+offset);
+%makelabel.top("(60 ",(60,30)+offset);
+heavy_dot (-5,15)+offset;
+heavy_dot (60,30)+offset;
+pickup pencircle;
+for x=10 step 10 until 200: draw (x,-5)+offset..(x,105)+offset; endfor
+for y=10 step 10 until 100: draw (-5,y)+offset..(205,y)+offset; endfor
+showit;
+shipit;
+
+"Figure 2b"; % 6 points and a line
+clear_all;
+z1=(0,100);
+z2=(100,100);
+z3=(200,100);
+z4=(0,0);
+z5=(100,0);
+z6=(200,0);
+draw (x1-epsilon,y1)..(x6,y6);
+makelabel.lft("1 ",z1);
+makelabel.lft("2",z2);
+makelabel.rt("3",z3);
+makelabel.lft("4",z4);
+makelabel.lft("5",z5);
+makelabel.rt(" 6",z6);
+showit;
+shipit;
+
+"Figure 2c"; % 6 points and three lines (hex symbol, version 1)
+clear_all;
+z1=(0,100);
+z2=(100,100);
+z3=(200,100);
+z4=(0,0);
+z5=(100,0);
+z6=(200,0);
+draw z1..z6; draw z2..z5; draw z3..z4;
+for k=1 upto 6: drawdot z[k]; endfor
+makelabel.lft("1 ",z1);
+makelabel.lft("2 ",z2);
+makelabel.rt(" 3",z3);
+makelabel.lft("4 ",z4);
+makelabel.lft("5 ",z5);
+makelabel.rt(" 6",z6);
+showit;
+shipit;
+
+"Figure 2d"; % hex symbols with top and bottom adjusted
+clear_all;
+top z1=(0,100);
+top z2=(100,100);
+top z3=(200,100);
+bot z4=(0,0);
+bot z5=(100,0);
+bot z6=(200,0);
+draw z1..z6; draw z2..z5; draw z3..z4;
+for k=1 upto 6: drawdot z[k]; endfor
+makelabel.lft("1 ",z1);
+makelabel.lft("2 ",z2);
+makelabel.rt(" 3",z3);
+makelabel.lft("4 ",z4);
+makelabel.lft("5 ",z5);
+makelabel.rt(" 6",z6);
+showit;
+clearxy; pair offset; offset=(250,0);
+pickup pencircle scaled .6pt;
+top z1=(0,100)+offset;
+top z2=(100,100)+offset;
+top z3=(200,100)+offset;
+bot z4=(0,0)+offset;
+bot z5=(100,0)+offset;
+bot z6=(200,0)+offset;
+draw z1..z6; draw z2..z5; draw z3..z4;
+for k=1 upto 6: drawdot z[k]; endfor
+makelabel.lft("1 ",z1);
+makelabel.lft("2 ",z2);
+makelabel.rt(" 3",z3);
+makelabel.lft("4 ",z4);
+makelabel.lft("5 ",z5);
+makelabel.rt(" 6",z6);
+proofrule ((-5,100),(210,100)+offset);
+proofrule ((-5,0),(210,0)+offset);
+showit;
+shipit;
+
+"Figure 2e"; % stick-letter A
+b#:=250/36pt#; a#:=150/36pt#; s#:=30/36pt#;
+define_pixels(b,a,s);
+def A(expr alpha)=
+beginchar (incr(charcode),s#+a#+s#,b#,0);
+pickup standardpen;
+bot z1=(good.x s,0); z5=z1+(a,0);
+z3=(1/2[x1,x5],good.y b);
+z2=alpha[z1,z3]; z4=alpha[z5,z3];
+draw z1..z3; draw z3..z5; draw z2..z4;
+drawdot z1; drawdot z5; drawdot z3;
+makelabel.lft("1 ",z1);
+makelabel.lft("2 ",z2);
+makelabel.top("3 ",z3);
+makelabel.rt(" 4",z4);
+makelabel.rt(" 5",z5);
+endchar; enddef;
+
+A((3-sqrt5)/2); % (area above bar / area below) = golden ratio
+
+"Figure 3a"; % 4 points and 3 midpoints
+clear_all;
+z1=(.5,.5); z2=(40.5,80.5); z3=(150.5,100.5); z4=(300.5,.5);
+z12=1/2[z1,z2]; z23=1/2[z2,z3]; z34=1/2[z3,z4];
+pickup pencircle;
+draw z1--z2--z3--z4;
+heavy_dot z1; heavy_dot z2; heavy_dot z3; heavy_dot z4;
+makelabel.lft("1",z1);
+makelabel.lft("2",z2);
+makelabel.top(" 3",z3);
+makelabel.rt("4",z4);
+makelabel.rt("12",z12);
+makelabel.bot(" 23",z23);
+makelabel.bot("34 ",z34);
+showit;
+shipit;
+
+"Figure 3b"; % 4 points and 6 midpoints
+clear_all;
+z1=(.5,.5); z2=(40.5,80.5); z3=(150.5,100.5); z4=(300.5,.5);
+z12=1/2[z1,z2]; z23=1/2[z2,z3]; z34=1/2[z3,z4];
+z123=1/2[z12,z23]; z234=1/2[z23,z34]; z1234=1/2[z123,z234];
+heavy_dot z1; heavy_dot z2; heavy_dot z3; heavy_dot z4;
+pickup pencircle;
+draw z1--z2--z3--z4; draw z12--z23--z34; draw z123--z234;
+makelabel.lft("1",z1);
+makelabel.lft("2",z2);
+makelabel.top(" 3",z3);
+makelabel.rt("4",z4);
+makelabel.lft("12",z12);
+makelabel.top("23 ",z23);
+makelabel.rt("34",z34);
+makelabel.bot(" 123",z123);
+makelabel.bot("234 ",z234);
+makelabel.bot("1234",z1234);
+showit;
+shipit;
+
+"Figure 3c"; % 4 points and infinitely many midpoints
+clear_all;
+z1=(.5,.5); z2=(40.5,80.5); z3=(150.5,100.5); z4=(300.5,.5);
+heavy_dot z1; heavy_dot z2; heavy_dot z3; heavy_dot z4;
+pickup pencircle;
+
+def makedot(expr x)= special " 1";
+ numspecial xpart x; numspecial ypart x enddef;
+
+def recurse(expr a,b,c,d)=
+dist:=abs(a-d);
+if dist>4:
+begingroup save e,f,g,h,i,j; pair e,f,g,h,i,j;
+e=(a+b)/2; makedot(e);
+f=(b+c)/2; makedot(f);
+g=(c+d)/2; makedot(g);
+h=(e+f)/2; makedot(h);
+i=(f+g)/2; makedot(i);
+j=(h+i)/2; makedot(j);
+if dist>20: draw a--b--c--d; draw e--f--g; draw h--i; fi
+recurse(a,e,h,j); recurse(j,i,g,d);
+endgroup;
+fi enddef;
+
+makedot(z1); makedot(z2); makedot(z3); makedot(z4); recurse(z1,z2,z3,z4);
+shipit;
+
+"Figure 3d"; % 4 points and various cubics
+clear_all;
+z1=(0,0); z2=5/6(40,80); z3=5/6(150,100); z4=5/6(300,0);
+draw z1..controls z2 and z3..z4;
+drawdot z1; drawdot z4;
+makelabel.lft("1 ",z1);
+makelabel.lft("2",z2);
+makelabel.rt("3",z3);
+makelabel.rt(" 4",z4);
+pair offset; offset:=(325,0);
+draw (z1..controls z3 and z2..z4) shifted offset;
+drawdot z1+offset; drawdot z4+offset;
+makelabel.lft("1 ",z1+offset);
+makelabel.lft("3",z2+offset);
+makelabel.rt("2",z3+offset);
+makelabel.rt(" 4",z4+offset);
+offset:=(0,-100);
+draw (z2..controls z1 and z3..z4) shifted offset;
+drawdot z2+offset; drawdot z4+offset;
+makelabel.lft("2",z1+offset);
+makelabel.lft("1 ",z2+offset);
+makelabel.rt("3",z3+offset);
+makelabel.rt(" 4",z4+offset);
+offset:=(325,-100);
+draw (z1..controls z4 and z2..z3) shifted offset;
+drawdot z1+offset; drawdot z3+offset;
+makelabel.lft("1 ",z1+offset);
+makelabel.lft("3",z2+offset);
+makelabel.rt(" 4",z3+offset);
+makelabel.rt("2",z4+offset);
+showit;
+shipit;
+
+"Figure 3e"; % example curves with automatic control points
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4..z1..z2..z6;
+draw p;
+drawdot z4; drawdot z6;
+makelabel.bot.nodot(" 1",z1);
+makelabel.top.nodot(" 2",z2);
+makelabel.rt.nodot("3",z3+(2,0));
+makelabel.rt.nodot(" 4",z4);
+makelabel.rt.nodot("5",z5+(2,0));
+makelabel.rt.nodot(" 6",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+pair offset; offset=(325,0);
+p:=(z5..z4..z1..z3..z6..z5) shifted offset; draw p;
+drawdot z5+offset;
+makelabel.bot.nodot(" 1",z1+offset);
+makelabel.top.nodot("2",z2+offset+(0,2));
+makelabel.bot.nodot("3 ",z3+offset);
+makelabel.top.nodot(" 4",z4+offset);
+makelabel.top.nodot("5",z5+offset+(0,5));
+makelabel.top.nodot("6 ",z6+offset);
+for k=1 upto 6: heavy_dot z[k]+offset; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3f"; % bean shape with automatic control points
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..z3..z6..cycle;
+draw p;
+makelabel.bot.nodot(" 1",z1);
+makelabel.bot.nodot("2",z2-(0,2));
+makelabel.bot.nodot("3 ",z3);
+makelabel.top.nodot(" 4",z4+(-1,1));
+makelabel.top.nodot("5",z5+(0,5));
+makelabel.top.nodot("6 ",z6+(1,1));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3g"; % bean shape with more tension between 1 and 3
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..tension1.2..z3..z6..cycle;
+draw p;
+makelabel.bot.nodot(" 1",z1);
+makelabel.bot.nodot("2",z2-(0,2));
+makelabel.bot.nodot("3 ",z3);
+makelabel.top.nodot(" 4",z4+(-1,1));
+makelabel.top.nodot("5",z5+(0,5));
+makelabel.top.nodot("6 ",z6+(1,1));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3h"; % bean shape with more tension before and after 1
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..tension 1 and 1.5..z1..tension 1.5 and 1..z3..z6..cycle;
+draw p;
+makelabel.bot.nodot(" 1",z1);
+makelabel.bot.nodot("2",z2-(0,2));
+makelabel.bot.nodot("3 ",z3);
+makelabel.top.nodot(" 4",z4+(-1,1));
+makelabel.top.nodot("5",z5+(0,5));
+makelabel.top.nodot("6 ",z6+(1,1));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3i"; % bean shape with straight bottom
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4{left}..z1..z3..z6{left}..cycle;
+draw p;
+makelabel.bot.nodot(" 1",z1-(1,1));
+makelabel.bot.nodot("2",z2-(0,2));
+makelabel.bot.nodot("3 ",z3+(1,-1));
+makelabel.top.nodot(" 4",z4+(0,5));
+makelabel.top.nodot("5",z5+(0,5));
+makelabel.top.nodot("6 ",z6+(0,5));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3j"; % example with direction specified
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4..z2{z3-z4}..z3;
+draw p;
+makelabel.rt.nodot("1",z1+(0,-9));
+makelabel.rt.nodot("2",z2+(1,-11));
+makelabel.rt.nodot("3",z3+(1,-11));
+makelabel.rt.nodot("4",z4+(1,-11));
+makelabel.rt.nodot("5",z5+(0,-9));
+makelabel.rt.nodot("6",z6+(0,-9));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3k"; % wiggly shape for exercise
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4{z4-z2}..z1..z3..z6{z2-z6}..cycle;
+draw p;
+makelabel.bot.nodot(" 1",z1-(2,2));
+makelabel.bot.nodot("2",z2-(0,2));
+makelabel.bot.nodot("3 ",z3+(2,-2));
+makelabel.bot.nodot(" 4",z4);
+makelabel.top.nodot("5",z5+(0,5));
+makelabel.bot.nodot("6 ",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+showit;
+shipit;
+
+"Figure 3l"; % examples of varying curl
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4{curl0}..z2{z3-z4}..{curl0}z3;
+draw p;
+drawdot z4; drawdot z3;
+makelabel.rt.nodot("1",z1+(0,-9));
+makelabel.rt.nodot("2",z2+(1,-11));
+makelabel.rt.nodot("3",z3+(1,-11));
+makelabel.rt.nodot("4",z4+(1,-11));
+makelabel.rt.nodot("5",z5+(0,-9));
+makelabel.rt.nodot("6",z6+(0,-9));
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+pair offset; offset=(325,0);
+p:=(z4{curl2}..z2{z3-z4}..{curl2}z3) shifted offset; draw p;
+drawdot z4+offset; drawdot z3+offset;
+makelabel.rt.nodot("1",z1+(0,-9)+offset);
+makelabel.rt.nodot("2",z2+(1,-11)+offset);
+makelabel.rt.nodot("3",z3+(1,-11)+offset);
+makelabel.rt.nodot("4",z4+(1,-11)+offset);
+makelabel.rt.nodot("5",z5+(0,-9)+offset);
+makelabel.rt.nodot("6",z6+(0,-9)+offset);
+for k=1 upto 6: heavy_dot z[k]+offset; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3m"; % two directions specified
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4{z2-z4}..z6{down};
+draw p;
+drawdot z4; drawdot z6;
+makelabel.rt.nodot("1",z1+(2,0));
+makelabel.rt.nodot("2",z2+(2,0));
+makelabel.rt.nodot("3",z3+(2,0));
+makelabel.bot.nodot(" 4",z4);
+makelabel.rt.nodot("5",z5+(2,0));
+makelabel.rt.nodot(" 6",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+for k=1 upto length p: heavy_dot postcontrol k-1 of p;
+ heavy_dot precontrol k of p; endfor
+showit;
+shipit;
+
+"Figure 3n"; % two control points specified
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4..controls z1 and z2..z6;
+draw p;
+drawdot z4; drawdot z6;
+makelabel.rt.nodot("1",z1+(2,0));
+makelabel.rt.nodot("2",z2+(2,0));
+makelabel.rt.nodot("3",z3+(2,0));
+makelabel.rt.nodot(" 4",z4);
+makelabel.rt.nodot("5",z5+(2,0));
+makelabel.rt.nodot(" 6",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+showit;
+shipit;
+
+"Figure 4a"; % bean shape with elliptical pens
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..z3..z6..cycle;
+pickup pencircle xscaled .8pt yscaled .2pt rotated 30;
+draw p;
+makelabel.bot(" 1",z1);
+makelabel.bot("2",z2);
+makelabel.bot(" 3",z3);
+makelabel.top("4 ",z4);
+makelabel.top("",z5); makelabel.top.nodot("5",z5+(0,5));
+makelabel.top("",z6); makelabel.top.nodot("6 ",z6+(1,1));
+pair offset; offset=(325,0);
+pickup pencircle xscaled .8pt rotated 30;
+draw p shifted offset;
+makelabel.bot(" 1",z1+offset);
+makelabel.bot("2",z2+offset);
+makelabel.bot(" 3",z3+offset);
+makelabel.top("4 ",z4+offset);
+makelabel.top("",z5+offset); makelabel.top.nodot("5",z5+(0,5)+offset);
+makelabel.top("",z6+offset); makelabel.top.nodot("6 ",z6+(1,1)+offset);
+showit;
+shipit;
+
+"Figure 4b"; % T of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar(T,13);
+if odd(w-ph): w:=w+1; fi % allows a symmetric stem
+x1+x2=2x3=2x4=w; lft.x1=-epsilon; % I tried s-o instead; was not as good
+y1=y2=y3; top.y1=h; bot.y4=-o;
+draw z1..z2; draw z3..z4;
+labels.rt(2,3);
+makelabel.top("1",z1);
+makelabel.top("4",z4);
+endchar;
+
+"Figure 4c"; % M of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar(M,18);
+x1+x5=x2+x4=2x3=w; x1=x2=leftstemloc;
+y1=y5; y2=y4; bot.y1=-o; top y2=h+o; y3=y1+yy;
+draw z1--z2--z3--z4--z5;
+labels.rt(3,5);
+makelabel.lft("1",z1);
+makelabel.bot("2",z2);
+makelabel.bot("4",z4);
+endchar;
+
+"Figure 4d"; % solid kidney bean
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..z3..z6..cycle;
+fill p;
+makelabel.bot(" 1",z1);
+makelabel.bot("2",z2);
+makelabel.bot("3 ",z3);
+makelabel.top(" 4",z4);
+makelabel.top("5",z5);
+makelabel.top("6 ",z6);
+showit;
+shipit;
+
+"Figure 4e"; % black triangle character for exercises
+beginchar(oct"170", 5pt#, 6.25pt#, 0);
+t:=(2-sqrt3)/2;
+x1=x2=w-x3+.5-t=round .43pt; y3=.5+floor.5h; % MANUAL font has it different!
+%x1=x2=w-x3=round .43pt; y3=.5+floor.5h;
+z1-z2=(z3-z2) rotated 60;
+y2:=t+round(y2-t); y1:=h-y2;
+fill z1--z2--z3--cycle;
+labels.lft(1,2); labels.rt(3); endchar;
+
+"Figure 4f"; % black bean with white holes
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..z3..z6..cycle;
+fill p;
+unfill 1/4[z4,z2]..3/4[z4,z2]..cycle;
+unfill 1/4[z6,z2]..3/4[z6,z2]..cycle;
+makelabel.bot(" 1",z1);
+makelabel.bot("2",z2);
+makelabel.bot("3 ",z3);
+makelabel.top(" 4",z4);
+makelabel.top("5",z5);
+makelabel.top("6 ",z6);
+showit;
+shipit;
+
+"Figure 4g"; % black bean with skewed interior cutout
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z5..z4..z1..z3..z6..cycle;
+fill p;
+z0=(.8[x1,x2],.5[y1,y4]);
+for k=1 upto 6: z[k]'=.2[z[k],z0]; endfor
+unfill z5'..z4'..z1'..z3'..z6'..cycle;
+makelabel.bot("0",z0);
+makelabel.top("1 ",z1);
+makelabel.top("2",z2);
+makelabel.top(" 3",z3);
+makelabel.bot("4 ",z4);
+makelabel.bot("5",z5);
+makelabel.bot(" 6",z6);
+makelabel.bot(" 1'",z1');
+makelabel.bot(" 2'",z2');
+makelabel.bot("3' ",z3');
+makelabel.top(" 4'",z4');
+makelabel.top("5'",z5');
+makelabel.top("6' ",z6');
+showit;
+shipit;
+
+"Figure 4h"; % sample penstroke
+clear_all;
+penpos1(1.2pt,30); penpos2(1.0pt,45); penpos3(0.8pt,90);
+z1=(0,2pt); z2=(4pt,0); x3=9pt; y3l=y2r;
+penstroke z1e..z2e{right}..z3e{right};
+labels.top(2r,3r);
+labels.bot(2l,3l);
+labels.rt(3,1r);
+labels.lft(1l,2);
+makelabel.top("1 ",z1);
+showit;
+shipit;
+
+"Figure 4i"; % cyclic penstroke example
+clear_all;
+d:=25;
+penpos1(d,30);
+penpos2(d,60);
+penpos3(d,210);
+penpos4(d,240);
+y1=.51y2r; y2r=175; y3=.49y2r; y4r=0;
+x1r=175; x2=x4=.5x1r; x3r=0;
+penstroke z1e{up}..z2e{left}..z3e{down}..z4e{right}..cycle;
+labels.lft(1l,2,3r,4);
+labels.rt(1r,3l);
+labels.top(2r,3,4l);
+labels.bot(1,2l,4r);
+showit;
+shipit;
+
+"Figure 4j"; % I from IOnian font
+clear_all;
+em#:=10pt#; cap#:=7pt#;
+bar#:=.8pt#;
+stem#:=.9pt#;
+thin#:=.8pt#;
+thick#:=1pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick,bar,stem);
+beginchar(27,.35em#,cap#,0); % "The letter I"; \IOI=27
+ penpos1(stem,15); penpos2(.9stem,12); penpos3(stem,10);
+ x1=x2=x3=.5w; y1=h; y2=.55h; y3=0;
+ x2l:=1/6[x2l,x2];
+ penstroke z1e..z2e{down}..z3e;
+labels.top(1,2,1r);
+labels.lft(2l);
+labels.rt(2r);
+labels.bot(3,3l);
+makelabel("",z1l); makelabel("",z3r);
+makelabel.lft.nodot("1l",z1l-(0,2));
+makelabel.rt.nodot("3r",z3r+(0,2));
+endchar;
+
+"Figure 4k"; % fixed pens versus penstrokes
+clear_all;
+z1=(0,0); z2=(150,0);
+pickup pencircle xscaled 0.8pt rotated 25;
+draw z1..z2..cycle;
+labels.lft(1,2);
+clearxy;
+pair offset; offset=(250,0);
+penpos1(0.8pt,25); penpos2(0.8pt,25);
+z1=(0,0)+offset; z2=(150,0)+offset;
+penstroke z1e..z2e..cycle;
+labels.lft(1l,2l);
+labels.rt(1r,2r);
+labels.bot(1,2);
+showit;
+shipit;
+
+"Figure 4l"; % hex symbol with pen-pressure adjustments
+%b#:=1.0pt#; define_blacker_pixels(b); % FOR INITIAL TESTS ONLY
+%beginchar(0,500/36pt#,250/36pt#,0); % that's magnified 2.5 as in the type
+b#:=0.4pt#; define_blacker_pixels(b);
+beginchar(0,200/36pt#,100/36pt#,0);
+pickup pencircle scaled b;
+w:=2good.x .5w;
+top z1=(0,h); top z2=(.5w,h); top z3=(w,h);
+bot z4=(0,0); bot z5=(.5w,0); bot z6=(w,0);
+draw z2..z5;
+for k=1 upto 6: drawdot z[k]; endfor
+z1'=.25[z1,z6]; z6'=.75[z1,z6];
+z3'=.25[z3,z4]; z4'=.75[z3,z4];
+ theta1:=angle(z6-z1)+90;
+ theta3:=angle(z4-z3)+90;
+penpos1'(b,theta1); penpos6'(b,theta1); penpos7(.6b,theta1);
+penpos3'(b,theta3); penpos4'(b,theta3); penpos8(.6b,theta3);
+z7=z8=.5[z1,z6];
+draw z1..z1'; draw z6'..z6;
+ penstroke z1'e{z6'-z1'}..z7e..{z6'-z1'}z6'e;
+draw z3..z3'; draw z4'..z4;
+ penstroke z3'e{z4'-z3'}..z8e..{z4'-z3'}z4'e;
+labels.top(1'r,3'l,4'l,6'r);
+labels.bot(1'l,3'r,4'r,6'l);
+forsuffixes $=1',3',4',6': makelabel("",z$); endfor
+makelabel.lft("1 ",z1);
+makelabel.lft("2 ",z2);
+makelabel.rt(" 3",z3);
+makelabel.lft("4 ",z4);
+makelabel.lft("5 ",z5);
+makelabel.rt(" 6",z6);
+makelabel.top("8l ",z8l);
+makelabel.top(" 7r",z7r);
+makelabel.bot("7l ",z7l);
+makelabel.bot(" 8r",z8r);
+endchar;
+
+"Figure 4m"; % same, cut sharp at the terminals, and inside the box
+%b#:=1.0pt#; define_blacker_pixels(b); % FOR INITIAL TESTS ONLY
+%beginchar(0,500/36pt#,250/36pt#,0); % that's magnified 2.5 as in the type
+b#:=0.4pt#; define_blacker_pixels(b);
+beginchar(0,200/36pt#,100/36pt#,0);
+pickup pencircle scaled b;
+w:=2good.x .5w;
+x1l=x4l=0;x2=x5=.5w;x3r=x6r=w;
+y1r=y2=y3l=h; y4r=y5=y6l=0;
+z1'=.25[z1,z6]; z6'=.75[z1,z6]; theta1:=angle(w,-h)+90;
+z3'=.25[z3,z4]; z4'=.75[z3,z4]; theta3:=angle(-w,-h)+90;
+z7=z8=.5[z1,z6];
+penpos1(b,theta1); penpos6(b,theta1);
+penpos1'(b,theta1); penpos6'(b,theta1); penpos7(.6b,theta1);
+penpos3(b,theta3); penpos4(b,theta3);
+penpos3'(b,theta3); penpos4'(b,theta3); penpos8(.6b,theta3);
+penstroke z1e..z1'e{z6'-z1'}..z7e..{z6'-z1'}z6'e..z6e;
+penpos2(b,0); penpos5(b,0); penstroke z2e..z5e;
+penstroke z3e..z3'e{z4'-z3'}..z8e..{z4'-z3'}z4'e..z4e;
+penlabels(1,1',2,3,3',4,4',5,6,6');
+labels.top(1r,1'r,2,3l,3'l,4l,4'l,6r,6'r);
+labels.bot(1l,1'l,3r,3'r,4r,4'r,5,6l,6'l);
+labels.lft(2l,5l);
+labels.rt(2r,5r);
+forsuffixes $=1,1',3,3',4,4',6,6': makelabel("",z$); endfor
+makelabel.top("8l ",z8l);
+makelabel.top(" 7r",z7r);
+makelabel.bot("7l ",z7l);
+makelabel.bot(" 8r",z8r);
+endchar;
+
+"Figure A5a"; % S from IOnian font
+clear_all;
+em#:=10pt#; cap#:=7pt#;
+slab#:=.8pt#;
+stem#:=.9pt#;
+thin#:=.8pt#;
+thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_corrected_pixels(o);
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick,slab,stem);
+beginchar(25,5/9em#,cap#,0); % "The letter S"; /IOS=25
+penpos1(slab,70);
+penpos2(.5slab,80);
+penpos3(.5[slab,thick],200);
+penpos5(.5[slab,thick],210);
+penpos6(.7slab,80);
+penpos7(.25[slab,thick],72);
+x1=x5; y1r=.94h+o;
+x2=x4=x6=.5w; y2r=h+o; y4=.54h; y6l=-o;
+x3r=.04em; y3=.5[y4,y2];
+x5l=w-.03em; y5=.5[y4,y6];
+.5[x7l,x7]=.04em; y7l=.12h-o;
+path trial; trial=z3{down}..z4..{down}z5;
+pair dz; dz=direction 1 of trial;
+penpos4(thick,angle dz-90);
+penstroke z1e..z2e{left}..z3e{down}..z4e{dz}..z5e{down}..z6e{left}..z7e;
+labels.lft(2,3r,5r,6,7);
+labels.rt(1,3l,4,5l);
+labels.top(1r,2r,3,4l,5,6r,7r);
+labels.bot(1l,2l,4r,6l,7l);
+endchar;
+
+"Figure 8a"; % twenty points on p2
+clear_all;
+path p[]; p1=(0,0)..(3,3); p2=(0,0)..(3,3)..cycle;
+transform t; t=identity scaled 60 shifted (50,0);
+pair zz;
+z=(1.5,1.5) transformed t;
+pickup pencircle;
+draw p2 transformed t;
+for n=0 upto 19: zz:=point n/10 of p2 transformed t;
+ heavy_dot zz;
+ makelabel.top.nodot(decimal(n/10) if n mod 10=0:&".0" fi,
+.09[zz,z] shifted(.05xpart(z-zz),-6.5)); endfor
+%.1[zz,z] shifted(.1xpart(z-zz),-8)); endfor
+shipit;
+showit;
+
+"Figure 11a"; % E of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar(E,14);
+x1=x2=x3=leftstemloc; x4=x6=w-x1+o; x5=x4-xx;
+y1=y6; y2=y5; y3=y4; bot.y1=0; top.y3=h; y2=barheight;
+draw z6--z1--z3--z4; draw z2..z5;
+labels.rt(1,2,3);
+labels.lft(4,5,6);
+endchar;
+
+"Figure 12a"; % cmr10 left parenthesis
+u#:=20/36pt#;
+tiny#:=0;
+axis#:=90/36pt#;
+hheight#:=250/36pt#;
+border#:=20/36pt#;
+hair#:=8/36pt#;
+thin#:=9/36pt#;
+thick#:=25/36pt#;
+slant:=0;
+rulethickness:=.4pt#;
+
+font_setup;
+beginchar("(",7u#, hheight#+border#, hheight#+border#-2axis#);
+italcorr (hheight#+border#)*slant-.5u#;
+pickup tinypen;
+penpos1(hair-tiny,0); penpos3(hair-tiny,0);
+penpos2(.75[thin,thick]-tiny,0);
+rt x1r = rt x3r = w-u; lft x2l = x1-4u;
+top y1=h; y2=.5[y1,y3]=axis;
+filldraw z1l{curl 4}..z2l..{curl 4}z3l--
+ z3r{curl 4}..z2r..{curl 4}z1r--cycle;
+labels.top(3,2);
+labels.bot(1);
+labels.lft(1l,2l,3l);
+labels.rt(1r,2r,3r);
+endchar;
+
+"Figure 12b"; % cmbx10 left parenthesis
+u#:=23/36pt#;
+tiny#:=0;
+axis#:=90/36pt#;
+hheight#:=250/36pt#;
+border#:=20/36pt#;
+hair#:=13/36pt#;
+thin#:=17/36pt#;
+thick#:=41/36pt#;
+slant:=0;
+
+font_setup;
+beginchar("(",7u#, hheight#+border#, hheight#+border#-2axis#);
+italcorr (hheight#+border#)*slant-.5u#;
+pickup tinypen;
+penpos1(hair-tiny,0); penpos3(hair-tiny,0);
+penpos2(.75[thin,thick]-tiny,0);
+rt x1r = rt x3r = w-u; lft x2l = x1-4u;
+top y1=h; y2=.5[y1,y3]=axis;
+filldraw z1l{curl 4}..z2l..{curl 4}z3l--
+ z3r{curl 4}..z2r..{curl 4}z1r--cycle;
+labels.top(3,2);
+labels.bot(1);
+labels.lft(1l,2l,3l);
+labels.rt(1r,2r,3r);
+endchar;
+
+"Figure 12c"; % cmvtt10 left parenthesis
+u#:=21/36pt#;
+tiny#:=22/36pt#;
+axis#:=110/36pt#;
+hheight#:=220/36pt#;
+border#:=30/36pt#;
+hair#:=22/36pt#;
+thin#:=25/36pt#;
+thick#:=25/36pt#;
+slant:=0;
+
+font_setup;
+beginchar("(",7u#, hheight#+border#, hheight#+border#-2axis#);
+italcorr (hheight#+border#)*slant-.5u#;
+pickup tinypen;
+penpos1(hair-tiny,0); penpos3(hair-tiny,0);
+penpos2(.75[thin,thick]-tiny,0);
+rt x1r = rt x3r = w-u; lft x2l = x1-4u;
+top y1=h; y2=.5[y1,y3]=axis;
+filldraw z1l{curl 4}..z2l..{curl 4}z3l--
+ z3r{curl 4}..z2r..{curl 4}z1r--cycle;
+labels.top(3,2);
+labels.bot(1);
+labels.lft(1l,2l,3l);
+labels.rt(1r,2r,3r);
+endchar;
+
+"Figure 12d"; % cmssdc10 left parenthesis
+u#:=19/36pt#;
+tiny#:=8/36pt#;
+axis#:=95/36pt#;
+hheight#:=250/36pt#;
+border#:=20/36pt#;
+hair#:=23/36pt#;
+thin#:=40/36pt#;
+thick#:=40/36pt#;
+slant:=0;
+
+font_setup;
+beginchar("(",7u#, hheight#+border#, hheight#+border#-2axis#);
+italcorr (hheight#+border#)*slant-.5u#;
+pickup tinypen;
+penpos1(hair-tiny,0); penpos3(hair-tiny,0);
+penpos2(.75[thin,thick]-tiny,0);
+rt x1r = rt x3r = w-u; lft x2l = x1-4u;
+top y1=h; y2=.5[y1,y3]=axis;
+filldraw z1l{curl 4}..z2l..{curl 4}z3l--
+ z3r{curl 4}..z2r..{curl 4}z1r--cycle;
+labels.top(3,2);
+labels.bot(1);
+labels.lft(1l,2l,3l);
+labels.rt(1r,2r,3r);
+endchar;
+
+"Figure 12e"; % cmti10 left parenthesis
+u#:=18.4/36pt#;
+tiny#:=7/36;
+axis#:=90/36pt#;
+hheight#:=250/36pt#;
+border#:=20/36pt#;
+hair#:=8/36pt#;
+thin#:=11/36pt#;
+thick#:=23/36pt#;
+slant:=.25;
+
+font_setup;
+beginchar("(",7u#, hheight#+border#, hheight#+border#-2axis#);
+italcorr (hheight#+border#)*slant-.5u#;
+pickup tinypen;
+penpos1(hair-tiny,0); penpos3(hair-tiny,0);
+penpos2(.75[thin,thick]-tiny,0);
+rt x1r = rt x3r = w-u; lft x2l = x1-4u;
+top y1=h; y2=.5[y1,y3]=axis;
+filldraw z1l{curl 4}..z2l..{curl 4}z3l--
+ z3r{curl 4}..z2r..{curl 4}z1r--cycle;
+labels.top(3,2);
+labels.bot(1);
+labels.lft(1l,2l,3l);
+labels.rt(1r,2r,3r);
+endchar;
+currenttransform:=identity yscaled aspect_ratio;
+
+"Figure 12f"; % Dangerous bend symbol
+def font_setup=
+define_pixels(u,tiny,axis,hheight,border);
+define_blacker_pixels(hair,thin,thick,rulethickness);
+pickup if tiny<.5: nullpen else: pencircle scaled tiny fi;
+tinypen:=savepen;
+currenttransform:=identity slanted slant;
+enddef;
+
+% typical cmr10 parameters
+u#:=20/36pt#;
+tiny#:=0;
+axis#:=90/36pt#;
+hheight#:=250/36pt#;
+border#:=20/36pt#;
+hair#:=8/36pt#;
+thin#:=9/36pt#;
+thick#:=25/36pt#;
+fixwidth:=0;
+slant:=0;
+rulethickness#:=.4pt#;
+
+baselinedistance#:=11pt#;
+heavyline#:=50/36pt#;
+font_setup;
+define_whole_pixels(baselinedistance);
+define_blacker_pixels(heavyline);
+
+beginchar(127,25u#,hheight#+border#,0);
+pickup pencircle scaled rulethickness;
+top y1=25/27h; lft x4=0;
+x1+x1=x1a+x1b=x4b+x2a=x4+x2=x4a+x2b=x3b+x3a=x3+x3=w;
+x4a=x4b=x4+u; x3b=x1a=x1-2u;
+y4+y4=y4a+y4b=y3b+y1a=y3+y1=y3a+y1b=y2b+y2a=y2+y2=0;
+y1a=y1b=y1-2/27h; y4b=y2a=y4+4/27h;
+draw z1a..z1..z1b---z2a..z2..z2b---
+ z3a..z3..z3b---z4a..z4..z4b---cycle; % signboard
+x10=x11=x12=x13=good.x(.5w-u); x14=x15=x16=x17=w-x10;
+y10=y14=28/27h+epsilon; bot y13=-baselinedistance;
+z11=(z10..z13) intersectionpoint (z1a{z1a-z4b}..z1{right});
+y15=y11; y16=y12=-y11; y17=y20=y21=y13;
+draw z11--z10--z14--z15; draw z12--z13; draw z16--z17; % signpost
+x20=w-x21; x21-x20=16u; draw z20--z21; % ground level
+x36=w-x31; x36-x31=8u; x32=x33=x36; x31=x34=x35;
+y31=-y36=12/27h; y32=-y35=9/27h; y33=-y34=3/27h;
+pickup pencircle scaled heavyline;
+draw z32{z32-z31}..z33---z34..z35{z36-z35}; % the dangerous bend
+pickup penrazor xscaled heavyline rotated (angle(z32-z31)+90);
+draw z31--z32; draw z35--z36; % upper and lower bars
+labels.top(11,15,2a,4b,4,2,32,34);
+labels.bot(10,14,2b,4a,33,35);
+labels.lft(1a,3b,12,13,21,36);
+labels.rt(1,1b,3a,3,16,20,17,31);
+endchar;
+
+"Figure 13a"; % Possible cube
+clear_all;
+fudge_factor:=1/2;
+s#:=5pt#*fudge_factor; define_pixels(s); % side of the square
+z1=(-epsilon,-epsilon); z2=(s+epsilon,-epsilon);
+ z3=(-epsilon,s+epsilon); z4=(s+epsilon,s+epsilon);
+for k=1 upto 4: z[k+4]=z[k]+(2/3s,1/3s); endfor
+pickup pencircle scaled (.4pt*fudge_factor);
+draw z5--z6--z8--z7--cycle;
+pickup pencircle scaled (1.6pt*fudge_factor);
+erase draw z2--z4--z3;
+pickup pencircle scaled (.4pt*fudge_factor);
+draw z1--z2--z4--z3--cycle;
+for k=1 upto 4: draw z[k]--z[k+4]; endfor
+labels.top(1,2,5,6);
+labels.bot(3,4,7,8);
+showit;
+shipit;
+
+"Figure 14a"; % El Palo Alto
+begingroup save flex; clear_all;
+def flex(text t) = % puts dots into normal flex
+ hide(n_:=0;
+ for z=t: z_[incr n_]:=z; makelabel("",z); endfor
+ dz_:=z_[n_]-z_1)
+ z_1 for k=2 upto n_-1: ...z_[k]{dz_} endfor ...z_[n_] enddef;
+
+def grid= proofoffset (30,0);
+ for y:=0 step 50 until 650: proofrule((-110,y),(110,y));
+ makelabel.lft.nodot(str[y],(100,y+5));
+ endfor;
+ for x:=-100 step 50 until 100: proofrule((x,-10),(x,660));endfor enddef;
+
+path branch[],trunk;
+
+branch1=
+ flex((0,660),(-9,633),(-22,610))
+ &flex((-22,610),(-3,622),(17,617))
+ &flex((17,617),(7,637),(0,660))
+ &cycle;
+
+branch2=
+ flex((30,570),(10,590),(-1,616))
+ &flex((-1,616),(-11,592),(-29,576),(-32,562))
+ &flex((-32,562),(-10,577),(30,570))
+ &cycle;
+
+branch3=
+ flex((-1,570),(-17,550),(-40,535))
+ &flex((-40,535),(-45,510),(-60,477))
+ &flex((-60,477),(-20,505),(40,512))
+ &flex((40,512),(31,532),(8,550),(-1,570))
+ &cycle;
+
+branch4=
+ flex((0,509),(-14,492),(-32,481))
+ &flex((-32,481),(-42,455),(-62,430))
+ &flex((-62,430),(-20,450),(42,448))
+ &flex((42,448),(38,465),(4,493),(0,509))
+ &cycle;
+
+branch5=
+ flex((-22,470),(-23,435),(-44,410))
+ &flex((-44,410),(-10,421),(35,420))
+ &flex((35,420),(15,455),(-22,470))
+ &cycle;
+
+branch6=
+ flex((18,375),(9,396),(5,420))
+ &flex((5,420),(-5,410),(-50,375),(-50,350))
+ &flex((-50,350),(-25,375),(18,375))
+ &cycle;
+
+branch7=
+ flex((0,400),(-13,373),(-30,350))
+ &flex((-30,350),(0,358),(30,350))
+ &flex((30,350),(13,373),(0,400))
+ &cycle;
+
+branch8=
+ flex((50,275),(45,310),(3,360))
+ &flex((3,360),(-20,330),(-70,300),(-100,266))
+ &flex((-100,266),(-75,278),(-60,266))
+ &flex((-60,266),(0,310),(50,275))
+ &cycle;
+
+branch9=
+ flex((10,333),(-15,290),(-43,256))
+ &flex((-43,256),(8,262),(58,245))
+ &flex((58,245),(34,275),(10,333))
+ &cycle;
+
+branch10=
+ flex((8,262),(-21,249),(-55,240))
+ &flex((-55,240),(-51,232),(-53,220))
+ &flex((-53,220),(-28,229),(27,235))
+ &flex((27,235),(16,246),(8,262))
+ &cycle;
+
+branch11=
+ flex((0,250),(-25,220),(-70,195))
+ &flex((-70,195),(-78,180),(-90,170))
+ &flex((-90,170),(-5,188),(74,183))
+ &flex((74,183),(34,214),(0,250))
+ &cycle;
+
+branch12=
+ flex((8,215),(-35,175),(-72,155))
+ &flex((-72,155),(-75,130),(-92,110),(-95,88))
+ &flex((-95,88),(-65,117),(-54,104))
+ &flex((-54,104),(10,151),(35,142))..flex((42,130),(60,123),(76,124))
+ &flex((76,124),(62,146),(26,180),(8,215))&cycle;
+
+trunk=(0,660)---(-12,70)..{curl 5}(-28,-8)
+ &flex((-28,-8),(-16,-4),(-10,-11))
+ &flex((-10,-11),(0,-5),(14,-10))
+ &flex((14,-10),(20,-6),(29,-11))
+ &(29,-11){curl 4}..(10,100)---cycle;
+
+makelabel("",(-12,70));
+makelabel("",(10,100));
+
+pickup pencircle scaled 2;
+draw trunk;
+for n=1 upto 12: draw branch[n]; endfor
+grid;
+showit;shipit;
+endgroup;
+
+"Figure 14b"; % Detail of one branch
+clear_all;
+pair zz[];
+zz1=(0,509);
+zz2=(-14,492);
+zz3=(-32,481);
+zz4=(-42,455);
+zz5=(-62,430);
+zz6=(-20,450);
+zz7=(42,448);
+zz8=(38,465);
+zz9=(4,493);
+for n=1 upto 9: z[n]=(zz[n]+(62,-430)) scaled 2.5; endfor
+pickup pencircle;
+filldraw flex(z1,z2,z3)&flex(z3,z4,z5)
+ &flex(z5,z6,z7)&flex(z7,z8,z9,z1)&cycle;
+labels.lft(2,3,4,5);
+labels.rt(1,7,8,9);
+labels.bot(6);
+showit; shipit;
+
+"Figure 14c"; % superellipses
+clear_all;
+w:=100; h:=150;
+pickup pencircle xscaled 0.7pt yscaled 0.2pt rotated 30;
+forsuffixes ss=65,70,75,80: s:=ss/100;
+draw superellipse((w,.5h),(.5w,h),(0,.5h),(.5w,0),s) shifted (150/.05(s-.65),0);
+makelabel.top.nodot("."&str ss,(.5w,.45h) shifted (150/.05(s-.65),0));
+endfor
+showit;
+shipit;
+
+"Figure 14d"; % demo of joinery
+clear_all;
+pickup standardpen;
+z0=(0,100); z1=(50,0); z2=(180,0);
+for n=3 upto 9: z[n]=z[n-3]+(200,0); endfor
+draw z0..z1---z2...{up}z3
+ & z3..z4--z5...{up}z6
+ & z6...z7---z8..{up}z9;
+makelabel.bot("0 ",z0);
+makelabel.bot("6 ",z6);
+labels.bot(3,9);
+labels.rt(1,4,7);
+labels.lft(2,5,8);
+showit;
+shipit;
+
+"Figure 14e"; % JofA logo
+beginchar("A",29mm#*.22,25mm#*.22,0);
+interim autorounding:=0; interim smoothing:=0;
+if odd(w-h): h:=h-1; fi
+thick#:=2mm#*.22; thin#:=5/4mm#*.22;
+define_whole_blacker_pixels(thick,thin);
+forsuffixes @=a,b,c: transform @;
+ forsuffixes e=l,r: path @e,@'e; numeric t@[]e; endfor endfor
+penpos1(thick,0); penpos2(thick,90); penpos3(thick,180); penpos4(thick,270);
+penpos5(thick,0); penpos6(thick,90); penpos7(thick,180); penpos8(thick,270);
+x2=x4=x6=x8=.5[x5,x7]=.5w; x1r=w; x3r=0; x5-x7=y6-y8;
+y1=y3=y5=y7=.5[y6,y8]=.5h; y2r=h; y4r=0; y6r=round.75h;
+forsuffixes e=l,r: a.e=b'e=c'e=superellipse(z1e,z2e,z3e,z4e,.75);
+ a'e=b.e=c.e=superellipse(z5e,z6e,z7e,z8e,.72); endfor
+penpos.a1(thin,0); penpos.a5(whatever,-90); penpos.a9(thin,180);
+x.a1l-x.a9l=1/3(x5l-x7l); x.a5=.5w; y.a1=y.a9; y.a5r=4/7h;
+x.a3l=x.a1l; x.a3r=x.a1r; x.a4r=1/6[x.a3r,x1l]; x0=.5w; y0=.52h;
+x.a6l+x.a4l=x.a6r+x.a4r=x.a7l+x.a3l=x.a7r+x.a3r=x.a9+x.a1=w;
+y.a3r=y.a4r=y.a6r=y.a7r=.2[y2l,y0]; y.a3l=y.a4l=y.a6l=y.a7l=y.a3r-thin;
+z.a4l=z.a4r+(thin,0)rotated(angle(z.a4r-z.a5r)+90)
+ +whatever*(z.a4r-z.a5r); z.a4l-z.a5l=whatever*(z.a4r-z.a5r);
+z=a.r intersectionpoint (z0--(w,0)); y.a1-y.a5=length(z-z0);
+b=identity shifted(0,y0-y.a1)rotatedaround(z0,90-angle(z0-(w,0)));
+c=b reflectedabout (z2,z4);
+for n=1,3,4,5,6,7,9: forsuffixes e=l,,r: forsuffixes @=b,c:
+ z@[n]e=z.a[n]e transformed @; endfor endfor endfor
+forsuffixes e=l,r: forsuffixes @=a,b,c:
+ z@2e=@r intersectionpoint (z@1e--z@3e);
+ z@8e=@r intersectionpoint (z@9e--z@7e);
+ t@1e=xpart(@e intersectiontimes (z@1l--z@3l));
+ t@9e=xpart(@e intersectiontimes (z@9l--z@7l));
+ t@4e=xpart(@'e intersectiontimes (z@5r--z@4l));
+ t@6e=xpart(@'e intersectiontimes (z@5r--z@6l)); endfor endfor
+penstroke subpath(t.a9e,t.b6e) of a.e;
+penstroke subpath(t.b4e,t.c4e) of b'e;
+penstroke subpath(t.c6e,t.a1e+8) of c'e;
+penstroke subpath(t.a6e,t.b9e) of a'e;
+penstroke subpath(t.b1e,t.c1e) of b.e;
+penstroke subpath(t.c9e,t.a4e+8) of c.e;
+forsuffixes @=a,b,c:
+ penstroke z@2e--z@3e--z@4e--z@5e--z@6e--z@7e--z@8e; endfor
+labels.lft(0,1l,3r,3,5l,7r,7,a1l,a2l,a3l,a6l,
+ a6r,a8r,a9r,b2l,b5,b5r,b9,c1,c2r,c5l);
+labels.rt(1,1r,3l,5,5r,7l,a1r,a2r,a4l,a4r,a7l,
+ a9l,b1,b2r,b5l,c2l,c5,c5r,c9);
+labels.top(2r,2,2l,4l,6r,6,6l,8l,a3r,a7r,a8l,
+ b1l,b3l,b3r,b6r,b6l,b8r,b9r,c1l,c3l,c3r,c6r,c6l,c8r,c9r);
+labels.bot(2r,2,2l,4,4r,8,8r,a1,a5l,a5,a5r,a9,
+ b1r,b4l,b4r,b7l,b7r,b8l,c1r,c4l,c4r,c7l,c7r,c8l);
+makelabel("",z.b9l);
+makelabel("",z.c9l);
+makelabel.lft.nodot("b9l",z.b9l-(0,3));
+makelabel.rt.nodot("c9l",z.c9l-(0,3));
+endchar;
+
+"Figure 15a"; % four u's
+beginchar("4",11pt#,11pt#,0);
+pickup pencircle scaled 3/4pt yscaled 1/3 rotated 30;
+save t; transform t;
+t=identity rotatedaround((.5w,.5h),-90);
+x2=.35w; x3=good.x .6w;
+y2=good.y .1h; top y3=round .4h+eps;
+save p; path p; p=z2{right}...{up}z3;
+top z1=point .5 of p transformed t;
+draw z1...z2{right}...{up}z3;
+addto currentpicture also currentpicture transformed t;
+addto currentpicture also currentpicture transformed(t transformed t);
+labels.bot(1,3); labels.rt(2); endchar;
+
+"Figure 16a"; % circular pen polygon
+clear_all;
+path p;
+p=makepath(pencircle scaled 20) scaled 10 shifted (110,110);
+if length p<>32: error; fi
+fill p;
+for k=1 upto length p: heavy_dot point k of p; endfor
+for x=0 step 10 until 220: proofrule((x,0),(x,220)); endfor
+for y=0 step 10 until 220: proofrule((0,y),(220,y)); endfor
+proofrulethickness .8;
+proofrule ((0,110),(220,110)); proofrule ((110,0),(110,220));
+showit;
+shipit;
+
+"Figure 16b"; % elliptical pen polygon
+clear_all;
+path p;
+p=makepath(pencircle xscaled 30 yscaled 20) scaled 10 shifted (160,110);
+if length p<>40: error; fi
+fill p;
+for k=1 upto length p: heavy_dot point k of p; endfor
+for x=0 step 10 until 320: proofrule((x,0),(x,220)); endfor
+for y=0 step 10 until 220: proofrule((0,y),(320,y)); endfor
+proofrulethickness .8;
+proofrule ((0,110),(320,110)); proofrule ((160,0),(160,220));
+showit;
+shipit;
+
+"Figure 16c"; % elliptical pen hexagon
+clear_all;
+path p;
+p=makepath((pencircle xscaled 30) yscaled 20) scaled 10 shifted (160,110);
+if length p<>6: error; fi
+fill p;
+for k=1 upto length p: heavy_dot point k of p; endfor
+for x=0 step 10 until 320: proofrule((x,0),(x,220)); endfor
+for y=0 step 10 until 220: proofrule((0,y),(320,y)); endfor
+proofrulethickness .8;
+proofrule ((0,110),(320,110)); proofrule ((160,0),(160,220));
+showit;
+shipit;
+
+"Figure 16d"; % cutoff version of Figure 3n
+clear_all;
+z1=(0,100); z2=(100,100); z3=(200,100);
+z4=(0,0); z5=(100,0); z6=(200,0);
+path p; p=z4..controls z1 and z2..z6;
+cutdraw p;
+makelabel.rt.nodot("1",z1+(2,0));
+makelabel.rt.nodot("2",z2+(2,0));
+makelabel.rt.nodot("3",z3+(2,0));
+makelabel.rt.nodot(" 4",z4);
+makelabel.rt.nodot("5",z5+(2,0));
+makelabel.rt.nodot(" 6",z6);
+for k=1 upto 6: heavy_dot z[k]; endfor;
+showit;
+shipit;
+
+"Figure 16e"; % cutoff version of Figure 4b
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar(T,13);
+if odd(w-ph): w:=w+1; fi % allows a symmetric stem
+x1+x2=2x3=2x4=w; lft.x1=0;
+y1=y2=y3; top.y1=h; y4=0;
+draw z1--z2;
+cutoff(z1,170);
+cutoff(z2,-10);
+draw z3--z4;
+cutoff(z4,-80);
+labels.rt(1);
+labels.lft(2);
+labels.bot(3);
+makelabel.top("4",z4);
+endchar;
+
+"Figure 16f"; % tilde with pencircle
+clear_all;
+pickup pencircle xscaled .8pt yscaled .2pt rotated 50;
+z1=(0,0); z4=(200,30);
+z2-z1=z4-z3=whatever*dir 50;
+y2-y1=3(y4-y1);
+draw z1..controls z2 and z3..z4;
+makelabel.lft("1 ",z1);
+makelabel.rt(" 4",z4);
+showit;
+shipit;
+
+"Figure 16g"; % tilde with pensquare
+clear_all;
+pickup pensquare xscaled .8pt yscaled .2pt rotated 50;
+z1=(0,0); z4=(200,30);
+z2-z1=z4-z3=whatever*dir 50;
+y2-y1=3(y4-y1);
+draw z1..controls z2 and z3..z4;
+makelabel.lft("1 ",z1);
+makelabel.rt(" 4",z4);
+showit;
+shipit;
+
+"Figure 16h"; % fancy serif with pencircle
+clear_all;
+pickup pencircle xscaled .8pt yscaled .2pt rotated 20;
+z1=(20,175); bot z3=(0,0);
+z4=(50,0); z6=(25,175);
+x2=x1; z2=z3+whatever*dir 20;
+x5=x6; z5=z4+whatever*dir -20;
+pair dishing; dishing=(8,0) rotated 20;
+filldraw z1..controls z2..z3
+--(flex(z3,.5[z3,z4]+dishing,z4))shifted(0,-epsilon)
+-- z4..controls z5..z6--cycle;
+showit;
+labels.lft(1,2,3);
+labels.rt(4,5,6);
+shipit;
+
+"Figure 16i"; % fancy serif with pensquare
+clear_all;
+pickup pensquare xscaled .8pt yscaled .2pt rotated 20;
+z1=(20,175); bot z3=(0,0);
+z4=(50,0); z6=(25,175);
+x2=x1; z2=z3+whatever*dir 20;
+x5=x6; z5=z4+whatever*dir -20;
+pair dishing; dishing=(8,0) rotated 20;
+filldraw z1..controls z2..z3
+--(flex(z3,.5[z3,z4]+dishing,z4))shifted(0,-epsilon)
+-- z4..controls z5..z6--cycle;
+showit;
+labels.lft(1,2,3);
+labels.rt(4,5,6);
+shipit;
+
+"Figure 18a"; % O of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(expr c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+def super_half(suffix i,j,k) =
+ draw z.i{0,y.j-y.i}
+ ... (.8[x.j,x.i],.8[y.i,y.j]){z.j-z.i}
+ ... z.j{x.k-x.i,0}
+ ... (.8[x.j,x.k],.8[y.k,y.j]){z.k-z.j}
+ ... z.k{0,y.k-y.j} enddef;
+
+beginlogochar("O",15);
+x1=x4=.5w; top y1=h+o; bot y4=-o;
+x2=w-x3=good.x(1.5u+s);
+y2=y3=barheight;
+super_half(2,1,3); super_half(3,4,2);
+labels.lft(2); labels.rt(1,3,4); endchar;
+
+"Figure A18a"; % A of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(expr c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+def super_half(suffix i,j,k) =
+ draw z.i{0,y.j-y.i}
+ ... (.8[x.j,x.i],.8[y.i,y.j]){z.j-z.i}
+ ... z.j{x.k-x.i,0}
+ ... (.8[x.j,x.k],.8[y.k,y.j]){z.k-z.j}
+ ... z.k{0,y.k-y.j} enddef;
+
+beginlogochar("A",15);
+x1=.5w;
+x2=x4=leftstemloc;
+x3=x5=w-x2;
+top y1=h+o;
+y2=y3=barheight;
+bot y4=bot y5=-o;
+draw z4--z2--z3--z5;
+super_half(2,1,3);
+labels.top(2,3,4,5);
+labels.rt(1);
+endchar;
+
+"Figure 18b"; % serif points
+clear_all;
+def serif(suffix $)(expr breadth,theta,left_jut,right_jut)=
+ penpos$(breadth/abs sind theta,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=y$d; y$b=y$e=y$; y$b-y$c=if theta<0:-fi slab;
+x$b=x$c=x$l-left_jut; x$d=x$e=x$r+right_jut;
+enddef;
+
+def serif_edge suffix $ =
+ (serif_bracket($a,$l,$b)--z$c
+ --z$d--reverse serif_bracket($f,$r,$e)) enddef;
+
+def serif_bracket(suffix i,j,k) =
+ (z.i{z.j-z.i}...serif_darkness[z.j,.5[z.i,z.k] ]{z.k-z.i}
+ ...z.k{z.k-z.j}) enddef;
+
+serif_darkness:=1/4; slab:=50; bracket:=175;
+z$=(150,slab);
+serif($,100,75,80,90);
+pickup pencircle scaled 2; draw serif_edge $;
+labels.lft($l,$a);
+labels.rt($,$r,$f);
+labels.top($b,$e);
+labels.bot($c,$d);
+showit;
+shipit;
+
+"Figure 18c"; % AI by outlines
+clear_all;
+def serif(suffix $)(expr breadth,theta,left_jut,right_jut)=
+ penpos$(breadth/abs sind theta,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=y$d; y$b=y$e=y$; y$b-y$c=if theta<0:-fi slab;
+x$b=x$c=x$l-left_jut; x$d=x$e=x$r+right_jut;
+enddef;
+
+def serif_edge suffix $ =
+ (serif_bracket($a,$l,$b)--z$c
+ --z$d--reverse serif_bracket($f,$r,$e)) enddef;
+
+def serif_bracket(suffix i,j,k) =
+ (z.i{z.j-z.i}...serif_darkness[z.j,.5[z.i,z.k] ]{z.k-z.i}
+ ...z.k{z.k-z.j}) enddef;
+
+serif_darkness:=1/3;
+slab#:=1/4pt#;
+bracket#:=1pt#;
+jut#:=.9pt#;
+u#:=3/5pt#;
+ht#:=7pt#;
+thin#:=.5pt#;
+thick#:=1.1pt#;
+define_pixels(slab,bracket,jut,u,ht,thin,thick);
+
+beginchar("A",13u#,ht#,0);
+z1=(.5w,round 1.05h); x4l=w-x5r=u; y4l=y5r=slab;
+numeric theta[]; theta4=angle(z1-z4l); theta5=angle(z1-z5r);
+serif(4,thin,theta4,.6jut,jut); serif(5,thick,theta5,jut,.6jut);
+z0=z4r+whatever*dir theta4=z5l+whatever*dir theta5;
+fill z1--serif_edge4--z0 & z0--serif_edge5--z1 & cycle;
+penpos2(whatever,theta4); penpos3(whatever,theta5);
+y2r=y3r=.5[y4,y0]; y2l=y3l=y2r-thin;
+z2=whatever[z1,z4r]; z3=whatever[z1,z5l];
+penstroke z2e--z3e;
+labels.lft(3,5l,5,4a,5a);
+labels.rt(2,4r,4f,5f);
+labels.top(1,2r,3r,4l,5r,4b,4e,5b,5e);
+labels.bot(0,2l,3l,4,4c,4d,5c,5d);
+
+ww:=w; % special hacks to get two on one
+picture tmp; tmp:=currentpicture;
+proofrule((w,-d.o_),(w,h.o_));
+endgroup;
+
+beginchar("I",6u#,ht#,0);
+currentpicture:=tmp;
+currenttransform:=currenttransform shifted(ww,0);
+x1=x2=.5w; y1=h-y2; y2=slab;
+serif(1,thick,-90,1.1jut,1.1jut); serif(2,thick,90,1.1jut,1.1jut);
+fill serif_edge 2 -- reverse serif_edge 1 -- cycle;
+w:=w+ww;
+labels.lft(1a,2a,1l);
+labels.rt(1f,2f,1,1r);
+labels.top(2l,2,2r,2e,1c,1d);
+labels.bot(2d,1b,1e);
+makelabel("",z2b); makelabel("",z2c);
+makelabel.rt.nodot("2b",z2b+(0,3));
+makelabel.rt.nodot("2c",z2c-(0,3));
+endchar;
+
+currenttransform:=identity yscaled aspect_ratio;
+
+"Figure A18b"; % H by outlines
+clear_all;
+def serif(suffix $)(expr breadth,theta,left_jut,right_jut)=
+ penpos$(breadth/abs sind theta,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=y$d; y$b=y$e=y$; y$b-y$c=if theta<0:-fi slab;
+x$b=x$c=x$l-left_jut; x$d=x$e=x$r+right_jut;
+enddef;
+
+def serif_edge suffix $ =
+ (serif_bracket($a,$l,$b)--z$c
+ --z$d--reverse serif_bracket($f,$r,$e)) enddef;
+
+def serif_bracket(suffix i,j,k) =
+ (z.i{z.j-z.i}...serif_darkness[z.j,.5[z.i,z.k] ]{z.k-z.i}
+ ...z.k{z.k-z.j}) enddef;
+
+serif_darkness:=1/3;
+slab#:=1/4pt#;
+bracket#:=1pt#;
+jut#:=.9pt#;
+u#:=3/5pt#;
+ht#:=7pt#;
+thin#:=.5pt#;
+thick#:=1.1pt#;
+define_pixels(slab,bracket,jut,u,ht,thin,thick);
+
+beginchar("H",13u#,ht#,0);
+x1=x2=x5=3u; x3=x4=x6=w-x1; y1c=y3c=h; y2c=y4c=0;
+serif(1,thick,-90,jut,jut);
+serif(2,thick,90,jut,jut);
+serif(3,thick,-90,jut,jut);
+serif(4,thick,90,jut,jut);
+fill serif_edge 2 -- reverse serif_edge 1 -- cycle;
+fill serif_edge 4 -- reverse serif_edge 3 -- cycle;
+penpos5(thin,90); penpos6(thin,90);
+y5=y6=.52h; penstroke z5e--z6e;
+labels.lft(1a,2a,3a,4a,5,1,2,1l,2l,3l,4l);
+labels.rt(1f,2f,3f,4f,6,3,4,1r,2r,3r,4r);
+labels.top(1c,1d,2b,2e,4b,4e,3c,3d,5r,6r);
+labels.bot(1b,1e,2c,2d,4c,4d,3b,3e,5l,6l);
+endchar;
+
+"Figure 18d"; % AI by broadpen
+clear_all;
+def bot_serif(suffix $)(expr xx,theta,left_jut,right_jut)=
+ penpos$(xx,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=top y$l; y$d=y$r; x$c=x$l-left_jut; x$d=x$r+right_jut;
+z$b=z$l+whatever*dir theta=z$c+whatever*dir phi;
+z$e=z$r+whatever*dir theta=z$d+whatever*dir -phi;
+enddef;
+
+def top_serif(suffix $)(expr xx,theta,left_jut,right_jut)=
+ penpos$(xx,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+%y$c=top y$l; y$d=y$r; x$c=x$l-left_jut; x$d=x$r+right_jut;
+y$c=y$d=y$; x$c=x$l-left_jut; x$d=x$r+right_jut;
+z$b=z$l+whatever*dir theta=z$c+whatever*dir -phi;
+z$e=z$r+whatever*dir theta=z$d+whatever*dir phi;
+enddef;
+
+def bot_serif_edge suffix $ =
+ (z$a..controls z$b..z$c
+ --(flex(z$c,.5[z$c,z$d]+dishing,z$d)) shifted (0,-epsilon)
+ -- z$d..controls z$e..z$f) enddef;
+
+def top_serif_edge suffix $ =
+ (z$a..controls z$b..z$c
+ --(flex(z$c,.5[z$c,z$d]-dishing,z$d)) shifted (0,+epsilon)
+ -- z$d..controls z$e..z$f) enddef;
+
+phi:=20;
+pair dishing; dishing:=(1/4pt,0) rotated phi;
+bracket#:=1pt#;
+jut#:=.9pt#;
+u#:=3/5pt#;
+ht#:=7pt#;
+px#:=.8pt#;
+py#:=.2pt#;
+xx#:=.3pt#;
+define_pixels(bracket,jut,u,ht,px,py,xx);
+
+pickup pensquare xscaled px yscaled py rotated phi; broad_pen:=savepen;
+
+beginchar("A",13u#,ht#,0); pickup broad_pen;
+z1=(.5w,top h); lft x4l=w-rt x5r=1.2u; y4l=y5r=0;
+numeric theta[]; theta4=angle(z1-z4l); theta5=angle(z1-z5r);
+numeric xxx;
+px*sind(theta5-phi)+xxx*sind theta5 = px*cosd phi+xx;
+bot_serif(4,0,theta4,.8jut,.8jut);
+bot_serif(5,xxx,theta5,.6jut,.8jut);
+z0=z4r+whatever*dir theta4=z5l+whatever*dir theta5;
+filldraw z1--bot_serif_edge4--z0 & z0--bot_serif_edge5--z1 & cycle;
+top y2=top y3=.45 bot y0; z2=whatever[z1,z4r]; z3=whatever[z1,z5l];
+draw z2--z3;
+labels.lft(4a,4b,4c,4,5l,5a,5c);
+labels.rt(4f,4e,5r,5d,5e,5f);
+labels.top(1,2,3,5b);
+labels.bot(0,4d,5);
+
+ww:=w; % special hacks to get two on one
+picture tmp; tmp:=currentpicture;
+proofrule((w,-d.o_),(w,h.o_));
+endgroup;
+
+beginchar("I",6u#,ht#,0); pickup broad_pen;
+currentpicture:=tmp;
+currenttransform:=currenttransform shifted(ww,0);
+x1=x2=.5w; y1=h; y2=0;
+top_serif(1,xx,-90,1.1jut,1.1jut);
+bot_serif(2,xx,90,1.1jut,1.1jut);
+filldraw bot_serif_edge 2 -- reverse top_serif_edge 1 -- cycle;
+labels.lft(1l,2l,1a,1b,1c,2a,2b);
+labels.rt(1r,2r,1d,1e,1f,2d,2e,2f);
+labels.top(1);
+labels.bot(2,2c);
+w:=w+ww;
+endchar;
+
+currenttransform:=identity yscaled aspect_ratio;
+
+"Figure A18c"; % H by broadpen
+clear_all;
+def bot_serif(suffix $)(expr xx,theta,left_jut,right_jut)=
+ penpos$(xx,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=top y$l; y$d=y$r; x$c=x$l-left_jut; x$d=x$r+right_jut;
+z$b=z$l+whatever*dir theta=z$c+whatever*dir phi;
+z$e=z$r+whatever*dir theta=z$d+whatever*dir -phi;
+enddef;
+
+def top_serif(suffix $)(expr xx,theta,left_jut,right_jut)=
+ penpos$(xx,0);
+z$a-z$l=z$f-z$r=(bracket/abs sind theta)*dir theta;
+y$c=y$d=y$; x$c=x$l-left_jut; x$d=x$r+right_jut;
+z$b=z$l+whatever*dir theta=z$c+whatever*dir -phi;
+z$e=z$r+whatever*dir theta=z$d+whatever*dir phi;
+enddef;
+
+def bot_serif_edge suffix $ =
+ (z$a..controls z$b..z$c
+ --(flex(z$c,.5[z$c,z$d]+dishing,z$d))shifted (0,-epsilon)
+ -- z$d..controls z$e..z$f) enddef;
+
+def top_serif_edge suffix $ =
+ (z$a..controls z$b..z$c
+ --(flex(z$c,.5[z$c,z$d]-dishing,z$d))shifted (0,+epsilon)
+ -- z$d..controls z$e..z$f) enddef;
+
+phi:=20;
+pair dishing; dishing:=(1/4pt,0) rotated phi;
+bracket#:=1pt#;
+jut#:=.9pt#;
+u#:=3/5pt#;
+ht#:=7pt#;
+px#:=.8pt#;
+py#:=.2pt#;
+xx#:=.3pt#;
+define_pixels(bracket,jut,u,ht,px,py,xx);
+
+pickup pensquare xscaled px yscaled py rotated phi; broad_pen:=savepen;
+
+beginchar("H",13u#,ht#,0); pickup broad_pen;
+x1=x2=x5=3u; x3=x4=x6=w-x1; y1=y3=h; y2=y4=0;
+top_serif(1,xx,-90,jut,jut);
+bot_serif(2,xx,90,jut,jut);
+top_serif(3,xx,-90,jut,jut);
+bot_serif(4,xx,90,jut,jut);
+filldraw bot_serif_edge 2 -- reverse top_serif_edge 1 -- cycle;
+filldraw bot_serif_edge 4 -- reverse top_serif_edge 3 -- cycle;
+y5=y6=.52h; draw z5--z6;
+labels.lft(l1,2l,3l,4l,1a,1b,1c,2a,2b,2c,3a,3b,3c,4a,4b,4c);
+labels.rt(1r,2r,3r,4r,1d,1e,1f,2d,2e,2f,3d,3e,3f,4d,4e,4f);
+labels.top(1,3);
+labels.bot(2,4,5,6);
+endchar;
+
+currenttransform:=identity yscaled aspect_ratio;
+
+"Figure 20a"; % example of `solve'
+clear_all;
+z1=(0,25); z2=(100,100); z3=(300,100); z4=(320,0);
+vardef upward(expr x)=
+ ypart direction 1 of (z1{z2-z1}..(x,y2)..{z4-z3}z4)>0 enddef;
+z=(solve upward(x2,x3),y2);
+pickup pencircle scaled 4;
+draw z1{z2-z1}..z..{z4-z3}z4;
+pickup pencircle scaled 2;
+draw z1--z2; draw z3--z4;
+makelabel.lft("z1 ",z1);
+makelabel.lft("z2 ",z2);
+makelabel.rt(" z3",z3);
+makelabel.rt(" z4",z4);
+makelabel.top.nodot("z",z+(0,2));
+forsuffixes $=1,2,3,4,: heavy_dot z$; endfor
+showit;
+shipit;
+
+"Figure 21a"; % N of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(expr c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar("N",15);
+x1+x4=x1+x3=x2+x5=w; x1=x2=leftstemloc;
+y1=y4=y3-yy; bot.y1=-o; y2=y5; top.y5=h+o;
+draw z1--z2--z3; draw z4..z5;
+labels.top(1,3,4);
+labels.bot(2,5);
+endchar;
+
+"Figure 21b"; % random N of METAFONT logo, nine-point size
+randomseed:=1;
+
+vardef noise=normaldeviate*.1pt enddef;
+
+ht#:=.9*6pt#;
+xgap#:=.9*0.6pt#;
+u#:=.91*4/9pt#;
+s#:=.08pt#;
+o#:=1/10pt#;
+px#:=.9*2/3pt#;
+ygap#:=(ht#/13.5u#)*xgap#;
+leftstemloc#:=2.5u#+s#;
+barheight#:=.45ht#;
+define_pixels(s,u,xgap,ygap,leftstemloc,barheight);
+py#:=.9px#; define_blacker_pixels(px,py);
+pickup pencircle xscaled px yscaled py; logo_pen:=savepen;
+define_corrected_pixels(o);
+
+def beginlogochar(expr c,n) =
+ beginchar(c,n*u#+2s#,ht#,0); pickup logo_pen enddef;
+
+beginlogochar("N",15);
+x1=leftstemloc+noise;
+x2=leftstemloc+noise;
+x4=w-leftstemloc+noise;
+x5=w-leftstemloc+noise;
+bot y1=noise-o;
+top y2=h+o+noise;
+y3=y4+ygap+noise;
+bot y4=noise-o;
+top y5=h+o+noise;
+z3=whatever[z4,z5];
+draw z1--z2--z3; draw z4--z5;
+labels.top(1,3,4);
+labels.bot(2,5);
+endchar;
+
+"Figure 21c"; % random N of METAFONT logo, nine-point size
+randomseed:=2;
+
+vardef noise=normaldeviate*.1pt enddef;
+
+ht#:=.9*6pt#;
+xgap#:=.9*0.6pt#;
+u#:=.91*4/9pt#;
+s#:=.08pt#;
+o#:=1/10pt#;
+px#:=.9*2/3pt#;
+ygap#:=(ht#/13.5u#)*xgap#;
+leftstemloc#:=2.5u#+s#;
+barheight#:=.45ht#;
+define_pixels(s,u,xgap,ygap,leftstemloc,barheight);
+py#:=.9px#; define_blacker_pixels(px,py);
+pickup pencircle xscaled px yscaled py; logo_pen:=savepen;
+define_corrected_pixels(o);
+
+def beginlogochar(expr c,n) =
+ beginchar(c,n*u#+2s#,ht#,0); pickup logo_pen enddef;
+
+beginlogochar("N",15);
+x1=leftstemloc+noise;
+x2=leftstemloc+noise;
+x4=w-leftstemloc+noise;
+x5=w-leftstemloc+noise;
+bot y1=noise-o;
+top y2=h+o+noise;
+y3=y4+ygap+noise;
+bot y4=noise-o;
+top y5=h+o+noise;
+z3=whatever[z4,z5];
+draw z1--z2--z3; draw z4--z5;
+labels.top(1,3,4);
+labels.bot(2,5);
+endchar;
+
+"Figure 21d"; % random N of METAFONT logo, nine-point size
+randomseed:=3;
+
+vardef noise=normaldeviate*.1pt enddef;
+
+ht#:=.9*6pt#;
+xgap#:=.9*0.6pt#;
+u#:=.91*4/9pt#;
+s#:=.08pt#;
+o#:=1/10pt#;
+px#:=.9*2/3pt#;
+ygap#:=(ht#/13.5u#)*xgap#;
+leftstemloc#:=2.5u#+s#;
+barheight#:=.45ht#;
+define_pixels(s,u,xgap,ygap,leftstemloc,barheight);
+py#:=.9px#; define_blacker_pixels(px,py);
+pickup pencircle xscaled px yscaled py; logo_pen:=savepen;
+define_corrected_pixels(o);
+
+def beginlogochar(expr c,n) =
+ beginchar(c,n*u#+2s#,ht#,0); pickup logo_pen enddef;
+
+beginlogochar("N",15);
+x1=leftstemloc+noise;
+x2=leftstemloc+noise;
+x4=w-leftstemloc+noise;
+x5=w-leftstemloc+noise;
+bot y1=noise-o;
+top y2=h+o+noise;
+y3=y4+ygap+noise;
+bot y4=noise-o;
+top y5=h+o+noise;
+z3=whatever[z4,z5];
+draw z1--z2--z3; draw z4--z5;
+labels.top(1,3,4);
+labels.bot(2,5);
+endchar;
+
+"Figure 24a"; % Ionian O at 200 pixels/inch
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:=round 1/18em;
+pair u,uu,v;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+forsuffixes e=l,r:
+ u:=round((point 0 of path_.e)/ss);
+ for t=0 step 1/64 until 4:
+ v:=round((point t of path_.e)/ss);
+ if u<>v: if abs(u-v)=1: proofrule(u*ss,v*ss);
+ else: del:=1/128; tt:=t-del;
+ forever: uu:=round((point tt of path_.e)/ss);
+ exitif abs(u-uu)=1;
+ if del=epsilon:ddt;fi
+ del:=del/2;
+ tt:=tt if uu=u:+ else:-fi del; endfor
+ proofrule(u*ss,uu*ss); proofrule(uu*ss,v*ss); fi
+ u:=v; fi endfor
+ endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u,uu,v;
+
+"Figure 24b"; % Ionian O at 200 pixels/inch, unrounded position
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+pair u,uu,v;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+forsuffixes e=l,r:
+ u:=round((point 0 of path_.e)/ss);
+ for t=0 step 1/64 until 4:
+ v:=round((point t of path_.e)/ss);
+ if u<>v: if abs(u-v)=1: proofrule(u*ss,v*ss);
+ else: del:=1/128; tt:=t-del;
+ forever: uu:=round((point tt of path_.e)/ss);
+ exitif abs(u-uu)=1;
+ if del=epsilon:ddt;fi
+ del:=del/2;
+ tt:=tt if uu=u:+ else:-fi del; endfor
+ proofrule(u*ss,uu*ss); proofrule(uu*ss,v*ss); fi
+ u:=v; fi endfor
+ endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u,uu,v;
+
+"Figure 24c"; % Fig 24b shifted right .05 pixel
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+pair u,uu,v;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) shifted (.05,0) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+forsuffixes e=l,r:
+ u:=round((point 0 of path_.e)/ss);
+ for t=0 step 1/64 until 4:
+ v:=round((point t of path_.e)/ss);
+ if u<>v: if abs(u-v)=1: proofrule(u*ss,v*ss);
+ else: del:=1/128; tt:=t-del;
+ forever: uu:=round((point tt of path_.e)/ss);
+ exitif abs(u-uu)=1;
+ if del=epsilon:ddt;fi
+ del:=del/2;
+ tt:=tt if uu=u:+ else:-fi del; endfor
+ proofrule(u*ss,uu*ss); proofrule(uu*ss,v*ss); fi
+ u:=v; fi endfor
+ endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u,uu,v;
+
+"Figure 24d"; % Fig 24c shifted right .05 pixel
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+pair u,uu,v;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) shifted (.1,0) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+forsuffixes e=l,r:
+ u:=round((point 0 of path_.e)/ss);
+ for t=0 step 1/64 until 4:
+ v:=round((point t of path_.e)/ss);
+ if u<>v: if abs(u-v)=1: proofrule(u*ss,v*ss);
+ else: del:=1/128; tt:=t-del;
+ forever: uu:=round((point tt of path_.e)/ss);
+ exitif abs(u-uu)=1;
+ if del=epsilon:ddt;fi
+ del:=del/2;
+ tt:=tt if uu=u:+ else:-fi del; endfor
+ proofrule(u*ss,uu*ss); proofrule(uu*ss,v*ss); fi
+ u:=v; fi endfor
+ endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u,uu,v;
+
+"Figure 24e"; % hash mark
+numeric u;
+u#:=10/18pt#; define_pixels(u);
+beginchar(0,15u#,250/36pt#,70/36pt#);
+pickup pencircle scaled (.4pt+blacker);
+lft x1=round u-eps; x3=x1; x2=x4=w-x1;
+y1=y2=good.y(.5[-d,h]+1.1pt); y3=y4=h-d-y1;
+draw z1--z2; draw z3--z4;
+lft x6=round 3u; x7=w-x6;
+x8=good.x .5w; x5-x6=x7-x8;
+top y5=top y7=h+eps; bot y6=bot y8=-d-eps;
+draw z5--z6; draw z7--z8;
+labels.top(6,8);
+labels.bot(5,7);
+labels.lft(2,4);
+labels.rt(1,3);
+endchar;
+
+"Figure 24f"; % Ionian O at 200 pixels/inch, autorounding=1
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+interim autorounding:=1;
+interim granularity:=10;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+pair u;
+for v= % pairs gotten from tracingedges on a separate run!
+(2,9), (2,6), (3,6), (3,4), (4,4), (4,3), (5,3), (5,2), (6,2),
+(6,1), (8,1), (8,0), (14,0), (14,1), (16,1), (16,2), (17,2), (17,3),
+(18,3), (18,4), (19,4), (19,7), (20,7), (20,13), (19,13), (19,15),
+(18,15), (18,16), (17,16), (17,17), (16,17), (16,18), (14,18), (14,19),
+(8,19), (8,18), (6,18), (6,17), (5,17), (5,16), (4,16), (4,15), (3,15),
+(3,12), (2,12), (2,9)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+
+pair u;
+for v=
+(4,9), (4,7), (5,7), (5,5), (6,5),
+(6,4), (7,4), (7,3), (9,3), (9,2), (14,2), (14,3), (15,3), (15,4), (16,4),
+(16,5), (17,5), (17,7), (18,7), (18,12), (17,12), (17,14), (16,14),
+(16,15), (15,15), (15,16), (13,16), (13,17), (8,17), (8,16), (7,16),
+(7,15), (6,15), (6,14), (5,14), (5,12), (4,12), (4,9)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u;
+
+"Figure 24g"; % Ionian O at 200 pixels/inch, autorounding=2
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+interim autorounding:=2;
+interim granularity:=10;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+pair u;
+for v=
+(2,9), (2,6), (3,6),
+(3,4), (4,4), (4,3), (5,3), (5,2), (6,2), (6,1), (8,1), (8,0), (14,0),
+(14,1), (16,1), (16,2), (17,2), (17,3), (18,3), (18,4), (19,4), (19,7),
+(20,7), (20,13), (19,13), (19,15), (18,15), (18,16), (17,16), (17,17),
+(16,17), (16,18), (14,18), (14,19), (8,19), (8,18), (6,18), (6,17),
+(5,17), (5,16), (4,16), (4,15), (3,15), (3,12), (2,12), (2,9)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+
+pair u;
+for v=
+(4,9), (4,7), (5,7), (5,5), (6,5),
+(6,4), (7,4), (7,3), (9,3), (9,2), (13,2), (13,3), (15,3), (15,4), (16,4),
+(16,5), (17,5), (17,7), (18,7), (18,12), (17,12), (17,14), (16,14),
+(16,15), (15,15), (15,16), (13,16), (13,17), (9,17), (9,16), (7,16),
+(7,15), (6,15), (6,14), (5,14), (5,12), (4,12), (4,9)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u;
+
+"Figure 24h"; % Ionian O at 200 pixels/inch, autorounding=0, smoothing=1
+ss:=10;
+begingroup interim hppp:=200/72.27; % lowres parameters
+interim blacker:=.65; % make pens a bit blacker
+interim o_correction:=.4; % but don't overshoot as much
+ em#:=10pt#; cap#:=7pt#;
+ thin#:=1/3pt#; thick#:=5/6pt#;
+ o#:=1/5pt#;
+define_pixels(em,cap);
+define_blacker_pixels(thin,thick);
+define_corrected_pixels(o);
+ curve_sidebar:= 1/18em;
+beginchar("O",0.8em#,cap#,0);
+ penpos1(thick,10); penpos2(.1[thin,thick],90-10);
+ penpos3(thick,180+10); penpos4(thin,270-10);
+ x1l=w-x3l=curve_sidebar; x2=x4=.5w;
+ y1=.49h; y2l=-o; y3=.51h; y4l=h+o;
+ penstroke (z1e{down}..z2e{right}
+ ..z3e{up}..z4e{left}..cycle) scaled ss;
+for m=0 upto w: proofrule((m*ss,0),(m*ss,h*ss)); endfor
+for n=0 upto h: proofrule((0,n*ss),(w*ss,n*ss)); endfor
+proofrulethickness 1;
+pair u;
+for v=
+(2,9), (2,5), (3,5),
+(3,3), (4,3), (4,2), (6,2), (6,1), (8,1), (8,0), (14,0), (14,1), (16,1),
+(16,2), (17,2), (17,3), (18,3), (18,4), (19,4), (19,6), (20,6), (20,14),
+(19,14), (19,16), (18,16), (18,17), (16,17), (16,18), (14,18), (14,19),
+(8,19), (8,18), (6,18), (6,17), (5,17), (5,16), (4,16), (4,15), (3,15),
+(3,13), (2,13), (2,9)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+
+pair u;
+for v=
+(4,10), (4,9), (5,9), (5,5), (6,5),
+(6,4), (7,4), (7,3), (8,3), (8,2), (14,2), (14,3), (15,3), (15,4), (16,4),
+(16,6), (17,6), (17,8), (18,8), (18,10), (17,10), (17,13), (16,13),
+(16,15), (15,15), (15,16), (14,16), (14,17), (8,17), (8,16), (7,16),
+(7,15), (6,15), (6,13), (5,13), (5,11), (4,11), (4,10)
+:if known u: proofrule(u*ss,v*ss) ; fi
+u:=v; endfor
+showit;
+shipit;
+endgroup;
+endgroup;
+numeric u;
+
+"Figure 27a"; % Modification of Fig. 14b
+clear_all;
+pair zz[];
+zz1=(0,509);
+zz2=(-14,492);
+zz3=(-32,481);
+zz4=(-42,455);
+zz5=(-62,430);
+zz6=(-20,452);
+zz7=(42,448);
+zz8=(38,465);
+zz9=(4,493);
+for n=1 upto 9: z[n-1]=(zz[n]+(62,-430)) scaled 2.5; heavy_dot z[n-1]; endfor
+pickup pencircle scaled 3;
+draw flex(z0,z1,z2)&flex(z2,z3,z4)
+ &flex(z4,z5,z6)&flex(z6,z7,z8,z0)&cycle;
+labels.lft(1,2,3,4);
+labels.rt(0,6,7,8);
+labels.bot(5);
+showit; shipit;
+
+"Figure Da"; % Neenie's problem
+clear_all;
+z1l=(0,240-y); z1r=(15,288-y);
+z0l-z0r=z1l-z1r; z0r=(144,189-y); y0l=0;
+pickup pencircle scaled 2;
+numeric a,b,c,d;
+a=x1l; b=y1r; (c,d)=z0r;
+draw z0l--z0r--z1r--z1l--cycle;
+proofrule((a,d),(a,b)); proofrule((a,b),(a-d+b,b));
+for z=z0l,z0r,z1l,z1r,(a,b): heavy_dot z; endfor
+makelabel.bot.nodot("<=",z1r+(3,-8));
+makelabel.lft("(a,b)",(a,b));
+makelabel.top("z1r",z1r);
+makelabel.lft("z1l",z1l);
+makelabel.rt("(c,d)",z0r);
+makelabel.lft("z0r ",z0r);
+makelabel.lft("z0l ",z0l);
+showit; shipit;
+
+"Figure Ea"; % T of METAFONT logo, with italic correction
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+slant:=0;
+
+beginlogochar(T,13);
+italcorr h#*slant+.5u#;
+if odd(w-ph): w:=w+1; fi % allows a symmetric stem
+x1+x2=2x3=2x4=w; lft.x1=-epsilon; % I tried s-o instead; was not as good
+y1=y2=y3; top.y1=h; bot.y4=-o;
+draw z1..z2; draw z3..z4;
+labels.rt(2,3);
+makelabel.top("1",z1);
+makelabel.top("4",z4);
+endchar;
+
+"Figure Eb"; % F of METAFONT logo
+alpha:=.45; % controls bar location and similar things
+beta:=.2; % controls squareness of bowls
+numeric h#, xx#, yy#, o#, s#, u#, ph#, pv#;
+numeric leftstemloc, barheight;
+ h#=6; % height of characters, in pt
+ xx#=0.6; % extra length of certain features, in pt
+ u#=4/9; % unit width, in pt
+ s#=0; % extra sidebar, in pt
+ o#=1/9; % overshoot of curves, in pt
+ ph#=2/3; % horizontal thickness of pen, in pt
+yy#=xx#; define_whole_pixels(xx,yy);
+define_pixels(s,u);
+define_corrected_pixels(o);
+pv#=.9ph#; define_blacker_pixels(ph,pv);
+pickup pencircle xscaled ph yscaled pv;
+logo_pen:=savepen;
+leftstemloc:=good.x((2.5u#+s#)*pt);
+barheight:=good.y(alpha*h#*pt);
+def beginlogochar(suffix c)(expr n) = % code c; width is n units plus sidebars
+ beginchar(str c,n*u#+2s#,h#,0); pickup logo_pen enddef;
+
+beginlogochar(F,14);
+x1=x2=x3=leftstemloc; x4=w-x1+o; x5=x4-xx;
+y2=y5; y3=y4; bot.y1=-o; top.y3=h; y2=barheight;
+draw z1--z3--z4; draw z2--z5;
+labels.rt(2,3);
+labels.lft(4,5);
+labels.top(1);
+endchar;
+
+"Figure Ec"; % cmr10 period
+u#:=20/36pt#;
+dot_diam#:=38/36pt#;
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+x_height#:=155/36pt#; % height of lowercase without ascenders
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+body_depth#:=90/36pt#;
+fine#:=7/36pt#;
+
+define_pixels(u);
+define_whole_blacker_pixels(dot_diam,fine);
+define_whole_vertical_pixels(body_height,asc_height,x_height,bar_height,
+ desc_depth,body_depth);
+
+beginchar(".",5u#,dot_diam#,0);
+def makebox(text rule) =
+ for y=0,asc_height,body_height,x_height,bar_height,-desc_depth,-body_depth:
+ rule((0,y),(w,y)); endfor % horizontals
+ for x=0,w: rule((x,-body_depth),(x,body_height)); endfor % verticals
+ for x=u step u until w-1:
+ rule((x,-body_depth),(x,body_height)); endfor % more verticals
+ if charic<>0:
+ rule((w+charic*pt,h.o_),(w+charic*pt,.5h.o_)); fi % italic correction
+ enddef;
+pickup pencircle scaled fine;
+penpos1(dot_diam-fine,0); penpos2(dot_diam-fine,90);
+x1l=good.x(x1l+.5w-x1); bot y2l=0; z1=z2;
+filldraw z1l...z2l...z1r...z2r...cycle; % roundish dot
+labels.lft(1,1l);
+labels.rt(2,1r);
+labels.top(2r);
+labels.bot(2l);
+endchar;
+
+"Figure Ed"; % cmr10 emdash
+u#:=20/36pt#;
+dot_diam#:=38/36pt#;
+body_height#:=270/36pt#; % height of tallest characters
+asc_height#:=250/36pt#; % height of lowercase ascenders
+x_height#:=155/36pt#; % height of lowercase without ascenders
+bar_height#:=87/36pt#; % height of crossbar in lowercase e
+desc_depth#:=70/36pt#; % depth of lowercase descenders
+body_depth#:=90/36pt#;
+vair#:=8/36pt#; % vertical diameter of hairlines
+
+define_pixels(u);
+define_whole_blacker_pixels(dot_diam,vair);
+define_whole_vertical_pixels(body_height,asc_height,x_height,bar_height,
+ desc_depth,body_depth);
+
+beginchar(oct"174",18u#,x_height#,0);
+def makebox(text rule) =
+ for y=0,asc_height,body_height,x_height,bar_height,-desc_depth,-body_depth:
+ rule((0,y),(w,y)); endfor % horizontals
+ for x=0,w: rule((x,-body_depth),(x,body_height)); endfor % verticals
+ for x=u step u until w-1:
+ rule((x,-body_depth),(x,body_height)); endfor % more verticals
+ if charic<>0:
+ rule((w+charic*pt,h.o_),(w+charic*pt,.5h.o_)); fi % italic correction
+ enddef;
+italcorr .61803x_height#*0 + .5u#;
+pickup nullpen;
+penpos1(vair,90); penpos2(vair,90);
+y1r=y2r=good.y(y1r+.61803h-y1);
+lft x1=-eps; rt x2=w+eps;
+penstroke z1e--z2e; % crossbar
+labels.lft(1);
+labels.rt(2);
+labels.top(1r,2r);
+labels.bot(1l,2l);
+endchar;
+
+bye
diff --git a/Master/texmf-doc/doc/english/knuth/primes.web b/Master/texmf-doc/doc/english/knuth/primes.web
new file mode 100644
index 00000000000..e68aab9a011
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/primes.web
@@ -0,0 +1,414 @@
+% limbo material
+\font\ninerm=cmr9 % was amr9
+\let\mc=\ninerm % medium caps for names like PASCAL
+\def\WEB{{\tt WEB}}
+\def\PASCAL{{\mc PASCAL}}
+\def\[{\ifhmode\ \fi$[\![$}
+\def\]{$]\!]$\ }
+\def\<{$\langle\,$}
+\def\>{$\,\rangle$}
+\def\Dijk{{2}} % unnecessary when combined with text of paper
+\def\goto{{3}} % ditto
+\hyphenation{Dijk-stra} % ditto
+\def\sec{{\tensy x}}
+\hsize=84mm
+
+@* Printing primes: An example of \WEB.
+The following program is essentially the same as Edsger Dijkstra's
+@^Dijkstra, Edsger@> ``first example of step-wise program composition,''
+found on pages 26--39 of his {\sl Notes on Structured Programming},$^{\Dijk}$
+but it has been translated into the \WEB\ language. @.WEB@>
+
+\[Double brackets will be used in what follows to enclose comments
+relating to \WEB\ itself, because the chief purpose of this program
+is to introduce the reader to the \WEB\ style of documentation.
+\WEB\ programs are always broken into small sections, each
+of which has a serial number; the present section is number~1.\]
+
+Dijkstra's program prints a table of the first thousand prime numbers. We
+shall begin as he did, by reducing the entire program to its top-level
+description. \[Every section in a \WEB\ program begins with optional {\it
+commentary\/} about that section, and ends with optional {\it program
+text\/} for the section. For example, you are now reading part of the
+commentary in \sec1, and the program text for \sec1 immediately follows
+the present paragraph. Program texts are specifications of \PASCAL\
+programs; they either use \PASCAL\ language directly, or they use angle
+brackets to represent \PASCAL\ code that appears in other sections. For
+example, the angle-bracket notation `\X2:Program to print $\ldots$
+numbers\X' is \WEB's way of saying the following: ``The \PASCAL\ text to
+be inserted here is called `Program to print $\ldots$ numbers', and you
+can find out all about it by looking at section~2.'' One of the main
+characteristics of \WEB\ is that different parts of the program are
+usually abbreviated, by giving them such an informal top-level
+description.\]
+
+@p @<Program to print the first thousand prime numbers@>
+
+@ This program has no input, because we want to keep it rather simple.
+The result of the program will be to produce a list of the first
+thousand prime numbers, and this list will appear on the |output| file.
+
+Since there is no input, we declare the value |m=1000| as a compile-time
+constant. The program itself is capable of generating the first
+|m| prime numbers for any positive |m|, as long as the computer's
+finite limitations are not exceeded.
+
+\[The program text below specifies the ``expanded meaning'' of `\X2:Program
+to print $\ldots$ numbers\X'; notice that it involves the top-level
+descriptions of three other sections. When those top-level descriptions
+are replaced by their expanded meanings, a syntactically correct \PASCAL\
+program will be obtained.\]
+
+@<Program to print...@>=
+program print_primes(output);
+const @!m=1000; @<Other constants of the program@>@;
+var @<Variables of the program@>@;
+begin @<Print the first |m| prime numbers@>;
+end.
+
+@* Plan of the program.
+We shall proceed to fill out the rest of the program by making whatever
+decisions seem easiest at each step; the idea will be to strive for
+simplicity first and efficiency later, in order to see where this leads us.
+The final program may not be optimum, but we want it to be reliable,
+well motivated, and reasonably fast.
+
+Let us decide at this point to maintain a table that includes all of the
+prime numbers that will be generated, and to separate the generation
+problem from the printing problem.
+
+\[The \WEB\ description you are reading once again follows a pattern that
+will soon be familiar: A typical section begins with comments and
+ends with program text. The comments motivate and explain noteworthy
+features of the program text.\]
+
+@<Print the first...@>=
+@<Fill table |p| with the first |m| prime numbers@>;
+@<Print table |p|@>
+
+@ How should table |p| be represented? Two possibilities suggest
+themselves: We could construct a sufficiently large array
+of boolean values in which the $k$th entry is |true| if and only if the
+number~|k| is prime; or we could build an array of integers in which
+the |k|th entry is the |k|th prime number. Let us choose the latter
+alternative, by introducing an integer array called |p[1..m]|.
+
+In the documentation below, the notation `|p[k]|' will refer to the
+|k|th element of array~|p|, while `$p_k$' will refer to the $k$th
+prime number. If the program is correct, |p[k]| will either be
+equal to $p_k$ or it will not yet have been assigned any value.
+
+\[Incidentally, our program will eventually make use of several
+more variables as we refine the data structures. All of the sections
+where variables are declared will be called `\X4:Variables of the
+program\X'; the number `{\eightrm4}' in this name refers to the
+present section, which is the first section to specify the
+expanded meaning of `\<Variables of the program\>'.
+The note `{\eightrm See also $\ldots$}' refers to all of the other
+sections that have the same top-level description. The expanded meaning of
+`\X4:Variables of the program\X' consists of all the program texts
+for this name, not just the text found in~\sec4.\]
+
+@<Variables...@>=@!p:array[1..m] of integer;
+ {the first |m| prime numbers, in increasing order}
+
+@* The output phase.
+Let's work on the second part of the program first. It's not as interesting
+as the problem of computing prime numbers; but the job of printing must be
+done sooner or later, and we might as well do it sooner, since it will
+be good to have it done. \[And it is easier to learn \WEB\ when reading a
+program that has comparatively few distracting complications.\]
+
+Since |p| is simply an array of integers, there is little difficulty
+in printing the output, except that we need to decide upon a suitable
+output format. Let us print the table on separate pages, with |rr| rows
+and |cc| columns per page, where every column is |ww| character positions
+wide. In this case we shall choose |rr=50|, |cc=4|, and |ww=10|, so that
+the first 1000 primes will appear on five pages. The program will
+not assume that |m| is an exact multiple of $|rr|\cdot|cc|$.
+@^output format@>
+
+@<Other constants...@>=
+@!rr=50; {this many rows will be on each page in the output}
+@!cc=4; {this many columns will be on each page in the output}
+@!ww=10; {this many character positions will be used in each column}
+
+@ In order to keep this program reasonably free of notations that
+are uniquely \PASCAL esque, \[and in order to illustrate more of the
+facilities of \WEB,\] a few macro definitions for low-level output
+instructions are introduced here. All of the output-oriented commands
+in the remainder of the program will be stated in terms of five
+simple primitives called |print_string|, |print_integer|, |print_entry|,
+|new_line|, and |new_page|.
+
+\[Sections of a \WEB\ program are allowed to contain {\it macro definitions\/}
+between the opening comments and the closing program text. The
+general format for each section is actually tripartite: commentary,
+then definitions, then program. Any of the three parts may be absent;
+for example, the present section contains no program text.\]
+
+\[Simple macros simply substitute a bit of \PASCAL\ code for an
+identifier. Parametric macros are similar, but they also substitute
+an argument wherever `\#' occurs in the macro definition. The first three
+macro definitions here are parametric; the other two are simple.\]
+
+@d print_string(#)==write(#) {put a given string into the |output| file}
+@d print_integer(#)==write(#:1) {put a given integer into the |output|
+ file, in decimal notation, using only as many digit positions as necessary}
+@d print_entry(#)==write(#:ww) {like |print_integer|, but |ww| character
+ positions are filled, inserting blanks at the left}
+@d new_line==write_ln {advance to a new line in the |output| file}
+@d new_page==page {advance to a new page in the |output| file}
+
+@ Several variables are needed to govern the output process. When we begin
+to print a new page, the variable |page_number| will be the ordinal number
+of that page, and |page_offset| will be such that |p[page_offset]| is the
+first prime to be printed. Similarly, |p[row_offset]| will be the first
+prime in a given row.
+
+\[Notice the notation `$+\S$' below; this indicates that the present
+section has the same name as a previous section, so the program text
+will be appended to some text that was previously specified.\]
+
+@<Variables...@>=
+@!page_number:integer; {one more than the number of pages printed so far}
+@!page_offset:integer; {index into |p| for the first entry on the current page}
+@!row_offset:integer; {index into |p| for the first entry in the current row}
+@!c:0..cc; {runs through the columns in a row}
+
+@ Now that appropriate auxiliary variables have been introduced, the process
+of outputting table~|p| almost writes itself.
+
+@<Print table |p|@>=
+begin page_number:=1; page_offset:=1;
+while page_offset<=m do
+ begin @<Output a page of answers@>;
+ page_number:=page_number+1;
+ page_offset:=page_offset+rr*cc;
+ end;
+end
+
+@ A simple heading is printed at the top of each page.
+@^output format@> @^page headings@>
+
+@<Output a page of answers@>=
+begin print_string('The First ');
+print_integer(m);@/
+print_string(' Prime Numbers --- Page ');
+print_integer(page_number);
+new_line; new_line; {there's a blank line after the heading}
+for row_offset:=page_offset to page_offset+rr-1 do
+ @<Output a line of answers@>;
+new_page;
+end
+
+@ The first row will contain
+$$\hbox{|p[1]|, |p[1+rr]|, |p[1+2*rr]|, \dots;}$$
+a similar pattern holds for each value of the |row_offset|.
+
+@<Output a line of answers@>=
+begin for c:=0 to cc-1 do
+ if row_offset+c*rr<=m then print_entry(p[row_offset+c*rr]);
+new_line;
+end
+
+@* Generating the primes.
+The remaining task is to fill table~|p| with the correct numbers.
+Let us do this by generating its entries one at a time: Assuming that
+we have computed all primes that are |j|~or less, we will advance |j|
+to the next suitable value, and continue doing this until the
+table is completely full.
+
+The program includes a provision to initialize the variables in certain
+data structures that will be introduced later.
+
+@<Fill table |p|...@>=
+@<Initialize the data structures@>;
+while k<m do
+ begin @<Increase |j| until it is the next prime number@>;
+ k:=k+1; p[k]:=j;
+ end
+
+@ We need to declare the two variables |j| and~|k| that were just
+introduced.
+
+@<Variables...@>=
+@!j:integer; {all primes |<=j| are in table |p|}
+@!k:0..m; {this many primes are in table |p|}
+
+@ So far we haven't needed to confront the issue of what a prime number
+is. But everything else has been taken care of, so we must delve into
+a bit of number theory now.
+
+By definition, a number is called prime if it is an integer greater
+than~1 that is not evenly divisible by any smaller prime number. Stating
+this another way, the integer |j>1| is not prime if and only if there
+exists a prime number $p_n<j$ such that |j| is a multiple of~$p_n$.
+@^prime number, definition of@>
+
+Therefore the section of the program that is called `\<Increase |j| until
+it is the next prime number\>' could be coded very simply:
+`\ignorespaces|repeat j:=j+1;|\unskip\
+\<Give to~|j_prime| the meaning: |j|~is a prime number\>;
+\ignorespaces|until j_prime|\unskip'.
+And to compute the boolean value |j_prime|, the following
+would suffice: `\ignorespaces|j_prime:=true; for n:=1 to k do|\unskip\
+\<If |p[n]| divides |j|, set |j_prime:=false|\>'.
+
+@ However, it is possible to obtain a much more efficient algorithm by
+using more facts of number theory. In the first place, we can speed
+things up a bit by recognizing that $p_1=2$ and that all subsequent
+primes are odd; therefore we can let |j| run through odd values only.
+Our program now takes the following form:
+
+@<Increase |j| until...@>=
+repeat j:=j+2; @<Update variables that depend on~|j|@>;
+@<Give to |j_prime| the meaning: |j|~is a prime number@>;
+until j_prime
+
+@ The |repeat| loop in the previous section introduces a boolean
+variable |j_prime|, so that it will not be necessary to resort to
+a |goto| statement. (We are following Dijkstra,$^\Dijk$ not Knuth.$^\goto$)
+@^Dijkstra, Edsger@> @^Knuth, Donald E.@>
+
+@<Variables...@>=
+@!j_prime:boolean; {is |j| a prime number?}
+
+@ In order to make the odd-even trick work, we must of course initialize
+the variables |j|, |k|, and |p[1]| as follows.
+
+@<Init...@>=
+j:=1; k:=1; p[1]:=2;
+
+@ Now we can apply more number theory in order to obtain further
+economies. If |j| is not prime, its smallest prime factor $p_n$ will
+be $\sqrt j$ or less. Thus if we know a number |ord| such that
+$$p[|ord|]^2>j,$$ and if |j| is odd, we need only test for divisors
+in the set $\{p[2], \ldots, p[|ord|-1]\}$. This is much faster than
+testing divisibility by $\{p[2],\ldots,p[k]\}$, since |ord| tends
+to be much smaller than~|k|. \ (Indeed, when |k| is large, the
+celebrated ``prime number theorem'' implies that the value of |ord|
+will be approximately $2\sqrt{k/\!\ln k}$.)
+
+Let us therefore introduce |ord| into the data structure. A moment's
+thought makes it clear that |ord| changes in a simple way when |j|
+increases, and that another variable |square| facilitates the
+updating process.
+
+@<Variables...@>=
+@!ord:2..ord_max; {the smallest index |>=2| such that $p_{ord}^2>j$}
+@!square:integer; {$|square|=p_{ord}^2$}
+
+@ @<Init...@>=
+ord:=2; square:=9;
+
+@ The value of |ord| will never get larger than a certain value
+|ord_max|, which must be chosen sufficiently large. It turns out that
+|ord| never exceeds~30 when |m=1000|.
+
+@<Other const...@>=
+@!ord_max=30; {$p_{ord\_max}^2$ must exceed $p_m$}
+
+@ When |j| has been increased by~2, we must increase |ord| by unity
+when $j=p_{ord}^2$, i.e., when |j=square|.
+
+@<Update variables that depend on~|j|@>=
+if j=square then
+ begin ord:=ord+1;
+ @<Update variables that depend on~|ord|@>;
+ end
+
+@ At this point in the program, |ord| has just been increased by unity,
+and we want to set $|square|:=p_{ord}^2$. A surprisingly subtle point
+arises here: How do we know that $p_{ord}$ has already been computed,
+i.e., that |ord<=k|? If there were a gap in the sequence of prime numbers,
+such that $p_{k+1}>p_k^2$ for some~$k$, then this part of the program would
+refer to the yet-uncomputed value |p[k+1]| unless some special test were
+made.
+
+Fortunately, there are no such gaps. But no simple proof of this fact is
+known. For example, Euclid's famous demonstration that there are
+infinitely many prime numbers is strong enough to prove only that
+$p_{k+1}<=p_1\ldots p_k+1$. Advanced books on number theory come to our
+rescue by showing that much more is true; for example, ``Bertrand's
+postulate'' @^Bertrand, Joseph, postulate@> states that $p_{k+1}<2p_k$
+for all~$k$.
+
+@<Update variables that depend on~|ord|@>=
+square:=p[ord]*p[ord]; {at this point |ord<=k|}
+
+@* The inner loop.
+Our remaining task is to determine whether or not a given integer~|j| is prime.
+The general outline of this part of the program is quite simple,
+using the value of |ord| as described above.
+
+@<Give to |j_prime|...@>=
+n:=2; j_prime:=true;
+while (n<ord) and j_prime do
+ begin @<If |p[n]| is a factor of~|j|, set |j_prime:=false|@>;
+ n:=n+1;
+ end
+
+@ @<Var...@>=
+@!n:2..ord_max; {runs from 2 to |ord| when testing divisibility}
+
+@ Let's suppose that division is very slow or nonexistent on our
+machine. We want to detect nonprime odd numbers, which are odd multiples
+of the set of primes $\{p_2,\ldots,p_{ord}\}$.
+
+Since |ord_max| is small, it is reasonable to maintain an auxiliary table of
+the smallest odd multiples that haven't already been used to show that
+some~|j| is nonprime. In other words, our goal is to ``knock out'' all
+of the odd multiples of each $p_n$ in the set $\{p_2,\ldots,p_{ord}\}$,
+and one way to do this is to introduce an auxiliary table that serves as
+a control structure for a set of knock-out procedures that are being
+simulated in parallel. (The so-called ``sieve of Eratosthenes''
+@^Eratosthenes, sieve of@> generates primes by a similar method, but
+it knocks out the multiples of each prime serially.)
+
+The auxiliary table suggested by these considerations is a |mult|
+array that satisfies the following invariant condition: For |2<=n<ord|,
+|mult[n]| is an odd multiple of $p_n$ such that $|mult|[n]<j+2p_n$.
+
+@<Var...@>=
+@!mult:array[2..ord_max] of integer; {runs through multiples of primes}
+
+@ When |ord| has been increased, we need to initialize a new element of
+the |mult| array. At this point $j=p[|ord|-1]^2$, so there is no
+need for an elaborate computation.
+
+@<Update variables that depend on~|ord|@>=
+mult[ord-1]:=j;
+
+@ The remaining task is straightforward, given the data structures
+already prepared. Let us recapitulate the current situation: The
+goal is to test whether or not |j|~is divisible by~$p_n$, without
+actually performing a division. We know that $j$~is odd, and that
+|mult[n]| is an odd multiple of~$p_n$ such that $|mult|[n]<j+2p_n$.
+If |mult[n]<j|, we can increase |mult[n]| by $2p_n$ and the same
+conditions will hold. On the other hand if |mult[n]>=j|, the
+conditions imply that |j|~is divisible by~$p_n$ if and only if
+|j=mult[n]|.
+
+@<If...@>=
+while mult[n]<j do mult[n]:=mult[n]+p[n]+p[n];
+if mult[n]=j then j_prime:=false
+
+@* Index.
+Every identifier used in this program is shown here together with a list
+of the section numbers where that identifier appears. The section number
+is underlined if the identifier was defined in that section. However,
+one-letter identifiers are indexed only at their point of definition,
+since such identifiers tend to appear almost everywhere. \[An index like
+this is prepared automatically by the \WEB\ software, and it is appended
+to the final section of the program. However, underlining of section
+numbers is not automatic; the user is supposed to mark identifiers
+at their point of definition in the \WEB\ source file.\]
+
+This index also refers to some of the places where key elements of the
+program are treated. For example, the entries for `Output format' and
+`Page headings' indicate where details of the output format are
+discussed. Several other topics that appear in the documentation
+(e.g., `Bertrand's postulate') have also been indexed. \[Special
+instructions within a \WEB\ source file can be used to insert
+essentially anything into the index.\]
diff --git a/Master/texmf-doc/doc/english/knuth/story.tex b/Master/texmf-doc/doc/english/knuth/story.tex
new file mode 100644
index 00000000000..fcbaa4151af
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/story.tex
@@ -0,0 +1,18 @@
+\hrule
+\vskip 1in
+\centerline{\bf A SHORT STORY}
+\vskip 6pt
+\centerline{\sl by A. U. Thor} % !`?`?! (modified)
+\vskip .5cm
+Once upon a time, in a distant
+ galaxy called \"O\"o\c c,
+there lived a computer
+named R.~J. Drofnats.
+
+Mr.~Drofnats---or ``R. J.,'' as
+he preferred to be called---% error has been fixed!
+was happiest when he was at work
+typesetting beautiful documents.
+\vskip 1in
+\hrule
+\vfill\eject
diff --git a/Master/texmf-doc/doc/english/knuth/trap.mf b/Master/texmf-doc/doc/english/knuth/trap.mf
new file mode 100644
index 00000000000..adf4d7bd48b
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/trap.mf
@@ -0,0 +1,170 @@
+% This is a diabolical test file for MF84. Don't get stuck.
+if not known inimf: .inimf.=.0. % next lines are skipped if format loaded
+ inimf; nonstopmode; tracingtitles:=day; showstopping:=year; hppp:=1000;
+ << == >> ::: || `` '' -- !! ?? ## && @@ $$ [[ ]] {{ }} . (( 5.5.5 )) ++ "..";
+ begingroup save =; let=,; save,; newinternal $=,; let ):=, endgroup;
+ let year=month; showvariable errorstopmode,readstring,2,"2",,,(,),<<,year;
+ tracingrestores:=tracingcommands:=.00000762939453125; % that's 2^(-17)
+ if tracingcommands>0:tracingcommands:=if not cycle "":1.1 forever;fi;
+ tracingcommands:=2.1 exitif tracingcommands>2 endfor; showtoken |=:|>;
+ tracingedges:=1/.00001; tracingequations:=$+1; p~=tracingedges+.00001;
+ interim tracingspecs:=tracingpens:=tracingchoices:=tracingstats:=
+ warningcheck:=tracingoutput:=tracingmacros:=1; $:=ASCII""; $:=x; p~:=p~;
+ delimiters (); delimiters begintext endtext; vardef foo(text t)=t enddef;
+ def lig(text t,|)=ligtable0::for *=1step1until60:0kern boundarychar+*,endfor
+ skipto0;ligtable t:t|0,skipto255;boundarychar:=boundarychar+51.29999enddef;
+ foo begintext interim proofing:=(-.5; shipout nullpicture; special"3" endtext;
+ for n=tracingpens step 1 until proofing:fi endfor showstats; let!!=skipto;
+ path p~; p~=(0,0)..controls (15,4) and (-15,-12)..(4,0); everyjob /*\;;
+ vardef /*\`'@#=message @ & str#@ &jobname&char ASCII'`&str@#!enddef;
+ let next=dump; vardef `'='` enddef; def '`="\*/" enddef;
+elseif known"": `'pass[2.]; outer\; let next=\; delimiters ^~7! fi
+next\; % the second pass will now compute silently; the first pass will halt
+batchmode; ^~7,endgroup pausing:=1; exitif p exitif boolean pen pencircle endfor
+scantokens begingroup message char0&"watch this"; "pair p[],';"&char-1endgroup
+path p[][]p,w,qw; qw=(1,-2)..(2,-1)..(2.5,0.5)..(1,2)..(turningnumber',2.5);
+numeric p[][]; p[[ [$] ]]=10000000000000000; "this string constant is incomplete
+string foo[]p,p~if true:[]; p~000=char34&char200&char34;
+boolean p[]~,boolean fi.boolean; showvariable boolean; def\\= =end enddef;
+picture e[]e[], e[], p~[]~[][]; show length scantokens p~0;
+pen p~[]~,q["a",qq; p~1~=q=pencircle scaled mexp(-3016.57654);
+transform p,pp0; if p=p:qq=makepen((1,0)..cycle) xscaled hex "1000";fi
+qq:=makepen((0,0)..(1,0)..(0,1)..(0,0)..(1,0)..(0,1)..cycle);
+vardef p[][]p~ begintext suffix a,b endtext())suffix@=show #@; p.a.b() enddef;
+expandafter let\endtext\\; outer endtext,\,;;qq:=pencircle scaled 4.5 yscaled 2;
+(6,12)-p7=(0,1)transformed p=(2/(x-x),3/0)transformed p;
+p1\2p=p007=begintext if string p~[$]: p.1.2-p.1.199999,1 endtext transformed p;
+showstopping:=0;showvariable p; p=p; let [[=begingroup; let ]]=endgroup;
+(xxpart p+.002,yxpart p)=1[p1,p2]=(5,y+.00001)=(5,y)=(yypart p,xypart p);
+reverse(p~..cycle) transformed p=p2. 3.p;
+p[000000000001]2p~(,[2]3p~,-)=p~1~2[pausing];
+vardef p~[]@# tertiary t:=if p@ @=@ @p fi; vardef p[][]p~[]=BAD; inner ;;
+show p~[-2]~[3000,x]++4000>path p3; showvariable p,P;
+numeric p[]~; p3~=2alpha; p[1/$]~=3beta;
+begingroup save p; showvariable p; 3beta=1]]; showvariable p;
+def//expr;=enddef;def!primary!false):!fi enddef;
+def _aa__ secondary _a_=if(true enddef; qq:=makepen(qw..(qw scaled$)..cycle);
+primarydef _**__=[[show _*__]] enddef;
+secondarydef _***__=expandafter __ scantokens"**oct"_ enddef;
+// //pencircle slanted length p~**makepen reverse subpath p7-p2 of
+ (p7{p2}..controls _aa__ not odd.1(15) and known p or !p2and-p2..{1,1}(-p2
+ {curl- +1)..tension atleast1..cycle sqrt2++sqrt2***[[]];
+[[interim proofing:=charcode:=-20.5;chardp:=-2048;shipout nullpicture]];
+if charexists -275.50002>known p0 0p=known p~: randomseed charcode; fi
+randomseed:="goof"; a[($,18++1+-+18),(2,3)]=b[(3,2),(1,$);
+show (^+1,~+2) slanted-1 yscaled-2 zscaled-(3,4), p transformed(pp xscaled 9),
+ pp shifted (1,2) transformed(p transformed p), -_[0][1,2]; show
+floor sind mlog sqrt mexp200cosd angle(normaldeviate,uniformdeviate-chardp);
+string s[]; s1=s2=s4; s3=s5; s1=s2; if s1<=s4<>(s1<>s3):show[[char34=s2:=s3]]fi;
+substring penoffset point.1of.p~of[[pencircle]]rotated1080/2/1/3of decimal
+ directiontime postcontrol-1.5of(p~&cycle)-precontrol1/2of p~(p~)=s1:=s4:=s4;
+path p~[]; p~1=p2{length" "}&cycle; p~1=p2=p~0; p2..controls-p2..cycle=p~2;(p7
+..tension1.2..p~[length p~2]..p~2&{0,1}p2..tension1and atleast1..cycle)..tension
+ x..{curl1}-p7{curl hex "IsBad"}..tension.75and.74999..p2{0,1}&p2{_,'}..cycle:=p
+ ~4; subpath(-9,9)of subpath(3.5001,7.00001)of p~4=p~6;
+show p~6, directiontime(1,2) of p~6, directiontime(1,-1.00001) of p~6;
+p~3=(0,0)..controls (1,1) and (0,1)..(1,0); show p2..p2{p7}&{$,$}cycle,
+ (directiontime(1,1) of subpath(.314159,1) of p~3)[.314159,1];
+p~5=(subpath(0,.25)of p~3&subpath(.25,1)of p~3)shifted begintext1,0;
+p~3:=2/3'zscaled'{p~3}..controls(2,2/3(3))and penoffset(1/2x,y)of(0,1)(1,0);
+show p~3 intersectiontimes reverse p~3, point.17227 of p~3, point1-.28339of p~3;
+show point xpart(p~5 intersectiontimes p~5 shifted (.01,0))of p~5-
+ point ypart(p~5 intersectiontimes p~5 shifted (.01,0))of p~5;
+[[interim tracingedges:=1; e[-1+-+ -1.00001]=nullpicture; addto e1 also[[
+addto e0 doublepath p~5 scaled 3 withpen q; e0=e1=e2; cull e1 dropping (0,.1);
+nullpicture]];show e1 shifted(4089,-4095), e2 shifted(-4095,4092)shifted (-3,0),
+e2 shifted(4089,-4095)]];addto e1 also e2 shifted(-2,$); e1:=e1 shifted(-4,$);
+addto e0 also e1rotated89.999+e1scaled$; show e0 xscaled-10 yscaled2 xscaled82
+yscaled683;addto e1 doublepath (0,9) withweight-3 withweight turningnumber p~6
+ withpen pencircle xscaled(oct"180"++1) rotated-angle(64,$) shifted (9,8)
+ withpen makepen(($,$)..(1,0)..(1,1)..($,0)..($,$)&cycle)xscaled4095.49999;
+show e1, totalweight e1; chardp:=charcode:=5; xoffset:=-1.5; shipout e1;
+showstats; addto e2doublepath p~ yscaled1/60; e3:=e2 yscaled 0;
+autorounding:=2; addto e3doublepath(.5,0)..(3.5,1.5)withweight2;
+tracingspecs:=0; q:=makepen((1,1)..cycle) yscaled 1.5;
+p~8=(($,yy)rotated p{0,1}..{0,$}(1,0){0,$}..cycle)scaled2shifted(1000.49,9);
+turningcheck:=1;addto e2doublepath p~8 withpen q withweight p withpen cycle p;
+[[interim autorounding:=xx=.1; addto e2 contour p~8 withpen q withweight2]];
+chardx:=chardp:=charext:=-14.5;shipout-(-e0-e2)+e2shifted(0,6turningnumber p~8);
+p~9=(0,0)..(1,.5)..(5,1.5)..(7,2.5)..(12,3.5)..(13,4);addto e3 doublepath p~9;
+smoothing:=1; addto e3 doublepath p~9; addto e3 doublepath (-4095,0)..tension
+3/4 and 999..(0,2); show e3 rotated-90, (e0+e0) rotated90$ rotated90;
+if "a" if "ab">"b" elseif path reverse (3,4): >="aa":foo elseif fi "bar"
+else if '-(1,yy)<': :fi else def dup text t=[[t;save enddef;def|suffix$=,$
+enddef; def||tertiary p=show substring p of("a" enddef;||(2,$)&"bc");
+tertiarydef x++y=[[dup showtoken x;]];def quote x expr z of y=z enddef;
+ texts(quote x=(y+0)y+y)("xx",foo(x))=0]] enddef; def texts(text t,tt)expr?=
+ for n:=,for n"yy":n,length if false:endfor tt,t,:if string n:forsuffixes n=
+ foo1,[foo(n)],':show t,tt|(n;exitif not('<='+(?,yy)) endfor for m= :+endfor
+ for m=alpha step-1.1 3$: +m endfor fi endfor enddef; show (0,0){curl2}..
+ subpath(23.3,4.5)of p~9{curl3}..($,$){curl4}..cycle;numspecial p~++2+3;[[
+let?=if;save if,\;def if=endinput?enddef;def texts=input enddef;texts trap ]];
+dup[[def texts secondary x=primarydef y++y=x@y enddef; showtoken++;x enddef]]\;
+proofing:=1;texts:="a"&"b";% strings "yy" and "ab" no longer appear in memory
+texts-1.00001a1=-(a2+a3+a4+a5+a6);-(a3,a2)/.99999=-(a4+a5+[[showdependencies;
+a6]],a3+a4+a5+a6)]]; 1.00001a4+1=a5+a6; alpha:=.9alpha+7; showdependencies;
+a5=a6=2/3-a6; cull e1 dropping($,4a5)withweight1.5; charcode:=chardp:=27;
+openwindow 3 from (0,0) to (0,0) at "whoops"; addto p; shipout p; cull p;
+openwindow -.5 from ($,$) to ($,$) at (0,0); special p; numspecial "p";
+openwindow 15.49999 from (0,32*1024) to (1,31*1057) at (0,0); shipout e1;
+openwindow 5 from (0,length((0,0){0,0})) to (4,2) at ($,1);
+openwindow 6 from (length($,0),1) to (3,10) at (-5,2);
+display nullpicture; display p inwindow 3; display p inwindow 6;
+display e1 inwindow 6; cull e0 dropping (0.1,4095.999999) withweight 3.5
+withweight-3.5; display e0 inwindow 5.5; addto e0 also p; addto e0 contour 0;
+display e0 inwindow 5.49999; addto e0 contour p~9;
+display e1 inwindow 3+3; display e0e0 inwindow[[vardef e[]e=enddef;6]];
+addto e0 also e1; display e0 inwindow 5; ligtable||:255|=:|>>0,skipto0;
+display e1 inwindow 15; display e1 inwindow 6;
+show [[interim tracingcommands:=0; lig("g")(=:|); lig("h":"i")(|=:);
+lig("j")(|=:>);lig("k")(=:|>); lig("l")(|=:|>)]];
+b1:=c.a[ [[let c=++;vardef b=enddef;1]] ]; ligtable"m":0=:0,skipto5;
+!!; errhelp 0; errmessage "Be like Jane";
+errhelp "He%%%lp%"; errmessage""; errhelp ""; errmessage "Another";
+headerbyte 0; headerbyte(48.5)substring(-9,9)of"long"; for\=0:\
+headerbyte 9:2a6,"q"; fontdimen 9:2a6,"q"; fontdimen 1:2048;
+fontmaking:=1; extensible 5 5,"c"255.5,"d"; charlist 0:5:"a":"d";
+ligtable255:255::"a"=:"b","d" kern -2048,"c":0:99.5:"e"|=:|"f",0kern';
+ligtable 5:0; def clear(text x)=interim x:=$ enddef; clear(hppp); vppp=0;
+[[clear(tracingmacros); clear(tracingcommands); clear(tracingoutput\;
+ clear(proofing);designsize:=.99999;charcode:=ASCII char-418.5;vppp:=designsize;
+ def dp expr d = charcode:=charcode+1; chardp:=d; shipout nullpicture enddef;
+ dp 13; dp 12; dp 0; dp 21; dp -2; dp 17; dp 11; dp 3; charic:=-1000; dp -1;
+ dp 25; dp 31; dp 19; dp 7; charwd:=256; chardy:=6; dp 23; dp 30]];
+def f(suffix@@)(expr a,b)(text t)=numeric w; show a; % wipes out the old w
+addto @@ contour (0,0)..(2,0)..(1,$)..(1,1)..cycle withpen qq; % strange path
+addto @@ doublepath (0,0){1,1}..{2,1}(2,1) withpen qq; % carefully chosen
+addto @@ doublepath(($,$){1,0}..(1,1){1,0})scaled.5 withpen nullpen;
+cull @@ keeping (4,4) withweight1.5; enddef; def g(suffix$)=show $ enddef;
+addto e0 contour (0,0){1,0}..{1,0}(1,0){0,$}..{0,1}cycle withpen qq;
+f(e[3,w); g(e3,transformed p,penoffset-(1,1.3)of(pencircle scaled20 yscaled-.5),
+ directiontime (0,1) of ((0,0)..controls(1,1)and($,1)..(3,0)),
+ point 3.14159 of p~9 intersectiontimes subpath (3.14159,4) of p~9,
+ (($,1.1)..(1,$)) intersectiontimes precontrol$ of (0,0);
+addto e3 doublepath(-4094.99998,0)..(4094.99998,-.00001) withpen penoffset 0 of
+pencircle; addto e3 also e3 shifted (0,257); ,"flushed with pride"; numeric xx;
+def f(expr x,y,z)=showdependencies;tracingcapsules:=1;showdependencies;show
+ 1/3(3,6)*((x+y)+(y-x)), (1,1)/sqrt2 zscaled (x+1,x+2) - (x+1,x+2) rotated 45,
+ (0,1) zscaled (1,y+2)-(1,y+2) rotated 90 enddef; f((xx+1)/.3,(yy-1)/.5,(xx,0));
+'=(1000o3-4000(o1-o2)+4000o2+9,-.01o3+3ooo+
+ [[oo=9/10(o2+o4+o5-20);o4=o5=8/9(o1+.5o2); o6=-.0001o2;showdependencies;
+ numeric o[];xpart(alfa,[[pair alfa;0]])]])=-2/3[[save p;(p$,1-p$)]];
+xoffset:=yoffset:=4000[[oo=.5ooo=2*-1/2(ooo+[[numeric ooo;1]]);oo]];
+for @=angle(sqrt$,mlog$):charext:=uniformdeviate$;charht:=2048;granularity:=-8;
+addto e3 contour (0,-100)..tension 500..(100,-99)..tension 3000..cycle;
+tracingoutput:=@; shipout e3; special "bye"; interim char 99 = "c"; true=false;
+[[clear(tracingcommands); charcode:=ASCII char 269-13; shipout+nullpicture;
+"careful" quote for for = @ step 200 until 2*2600: &" METAFONT" endfor;]];
+scrollmode; "hello again"&char31; save p; fillin:=-.043;
+def f expr x=let )=]; let [=(; show _ enddef; begingroup tracingspecs:=1;
+show nullpen, makepath.qq, makepath(q rotated1), makepath pencircle rotated $;
+addto e0 doublepath (0,2){0,$}..{0,$}(0,1)..{1,0}(3,0)..(4,0){1,0}..cycle
+ withpen makepen((0,0)..(5,2.9)..(4,3)..cycle); tracingonline:=1; f xx[1);
+showdependencies; qq:=q; showstats; bye endtext
+% things not tested:
+% interaction (error insertion/deletion, interrupts, \pausing, files not there)
+% date, time; initialization of random number generator without randomseed
+% system-dependent parsing of file names, areas, extensions
+% certain error messages, especially fatal ones
+% things that can't happen in INIMF
+% unusual cases of fixed-point arithmetic
diff --git a/Master/texmf-doc/doc/english/knuth/trap.pl b/Master/texmf-doc/doc/english/knuth/trap.pl
new file mode 100644
index 00000000000..bae32a41fb4
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/trap.pl
@@ -0,0 +1,490 @@
+(CODINGSCHEME Q)
+(DESIGNSIZE R 128.0)
+(COMMENT DESIGNSIZE IS IN POINTS)
+(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)
+(CHECKSUM O 5546464252)
+(FONTDIMEN
+ (SLANT R 2047.999999)
+ (SPACE R 0.0)
+ (STRETCH R 0.0)
+ (SHRINK R 0.0)
+ (XHEIGHT R 0.0)
+ (QUAD R 0.0)
+ (EXTRASPACE R 0.0)
+ (PARAMETER D 8 R 0.0)
+ (PARAMETER D 9 R 0.005208)
+ (PARAMETER D 10 R 0.0)
+ )
+(BOUNDARYCHAR O 377)
+(LIGTABLE
+ (COMMENT THIS PART OF THE PROGRAM IS NEVER USED!
+ )
+ (LABEL BOUNDARYCHAR)
+ (/LIG/>> O 377 O 0)
+ (KRN O 0 R 0.0)
+ (KRN O 0 R 0.0078125)
+ (KRN O 0 R 0.015625)
+ (KRN O 0 R 0.0234375)
+ (KRN O 0 R 0.03125)
+ (KRN O 0 R 0.0390625)
+ (KRN O 0 R 0.046875)
+ (KRN O 0 R 0.0546875)
+ (KRN O 0 R 0.0625)
+ (KRN O 0 R 0.0703125)
+ (KRN O 0 R 0.078125)
+ (KRN O 0 R 0.0859375)
+ (KRN O 0 R 0.09375)
+ (KRN O 0 R 0.1015625)
+ (KRN O 0 R 0.109375)
+ (KRN O 0 R 0.1171875)
+ (KRN O 0 R 0.125)
+ (KRN O 0 R 0.1328125)
+ (KRN O 0 R 0.140625)
+ (KRN O 0 R 0.1484375)
+ (KRN O 0 R 0.15625)
+ (KRN O 0 R 0.1640625)
+ (KRN O 0 R 0.171875)
+ (KRN O 0 R 0.1796875)
+ (KRN O 0 R 0.1875)
+ (KRN O 0 R 0.1953125)
+ (KRN O 0 R 0.203125)
+ (KRN O 0 R 0.2109375)
+ (KRN O 0 R 0.21875)
+ (KRN O 0 R 0.2265625)
+ (KRN O 0 R 0.234375)
+ (KRN O 0 R 0.2421875)
+ (KRN O 0 R 0.25)
+ (KRN O 0 R 0.2578125)
+ (KRN O 0 R 0.265625)
+ (KRN O 0 R 0.2734375)
+ (KRN O 0 R 0.28125)
+ (KRN O 0 R 0.2890625)
+ (KRN O 0 R 0.296875)
+ (KRN O 0 R 0.3046875)
+ (KRN O 0 R 0.3125)
+ (KRN O 0 R 0.3203125)
+ (KRN O 0 R 0.328125)
+ (KRN O 0 R 0.3359375)
+ (KRN O 0 R 0.34375)
+ (KRN O 0 R 0.3515625)
+ (KRN O 0 R 0.359375)
+ (KRN O 0 R 0.3671875)
+ (KRN O 0 R 0.375)
+ (KRN O 0 R 0.3828125)
+ (KRN O 0 R 0.390625)
+ (KRN O 0 R 0.3984375)
+ (KRN O 0 R 0.40625)
+ (KRN O 0 R 0.4140625)
+ (KRN O 0 R 0.421875)
+ (KRN O 0 R 0.4296875)
+ (KRN O 0 R 0.4375)
+ (KRN O 0 R 0.4453125)
+ (KRN O 0 R 0.453125)
+ (KRN O 0 R 0.4609375)
+ (SKIP D 1)
+ (LABEL C g)
+ (LIG/ C g O 0)
+ (STOP)
+ (KRN O 0 R 0.400782)
+ (KRN O 0 R 0.408594)
+ (KRN O 0 R 0.416407)
+ (KRN O 0 R 0.424219)
+ (KRN O 0 R 0.432032)
+ (KRN O 0 R 0.439844)
+ (KRN O 0 R 0.447657)
+ (KRN O 0 R 0.455469)
+ (KRN O 0 R 0.463282)
+ (KRN O 0 R 0.471094)
+ (KRN O 0 R 0.478907)
+ (KRN O 0 R 0.486719)
+ (KRN O 0 R 0.494532)
+ (KRN O 0 R 0.502344)
+ (KRN O 0 R 0.510157)
+ (KRN O 0 R 0.517969)
+ (KRN O 0 R 0.525782)
+ (KRN O 0 R 0.533594)
+ (KRN O 0 R 0.541407)
+ (KRN O 0 R 0.549219)
+ (KRN O 0 R 0.557032)
+ (KRN O 0 R 0.564844)
+ (KRN O 0 R 0.572657)
+ (KRN O 0 R 0.580469)
+ (KRN O 0 R 0.588282)
+ (KRN O 0 R 0.596094)
+ (KRN O 0 R 0.603907)
+ (KRN O 0 R 0.611719)
+ (KRN O 0 R 0.619532)
+ (KRN O 0 R 0.627344)
+ (KRN O 0 R 0.635157)
+ (KRN O 0 R 0.642969)
+ (KRN O 0 R 0.650782)
+ (KRN O 0 R 0.658594)
+ (KRN O 0 R 0.666407)
+ (KRN O 0 R 0.674219)
+ (KRN O 0 R 0.682032)
+ (KRN O 0 R 0.689844)
+ (KRN O 0 R 0.697657)
+ (KRN O 0 R 0.705469)
+ (KRN O 0 R 0.713282)
+ (KRN O 0 R 0.721094)
+ (KRN O 0 R 0.728907)
+ (KRN O 0 R 0.736719)
+ (KRN O 0 R 0.744532)
+ (KRN O 0 R 0.752344)
+ (KRN O 0 R 0.760157)
+ (KRN O 0 R 0.767969)
+ (KRN O 0 R 0.775782)
+ (KRN O 0 R 0.783594)
+ (KRN O 0 R 0.791407)
+ (KRN O 0 R 0.799219)
+ (KRN O 0 R 0.807032)
+ (KRN O 0 R 0.814844)
+ (KRN O 0 R 0.822657)
+ (KRN O 0 R 0.830469)
+ (KRN O 0 R 0.838282)
+ (KRN O 0 R 0.846094)
+ (KRN O 0 R 0.853907)
+ (KRN O 0 R 0.861719)
+ (SKIP D 1)
+ (LABEL C h)
+ (LABEL C i)
+ (/LIG C i O 0)
+ (STOP)
+ (KRN O 0 R 0.801562)
+ (KRN O 0 R 0.809375)
+ (KRN O 0 R 0.817187)
+ (KRN O 0 R 0.825)
+ (KRN O 0 R 0.832812)
+ (KRN O 0 R 0.840625)
+ (KRN O 0 R 0.848437)
+ (KRN O 0 R 0.85625)
+ (KRN O 0 R 0.864062)
+ (KRN O 0 R 0.871875)
+ (KRN O 0 R 0.879687)
+ (KRN O 0 R 0.8875)
+ (KRN O 0 R 0.895312)
+ (KRN O 0 R 0.903125)
+ (KRN O 0 R 0.910937)
+ (KRN O 0 R 0.91875)
+ (KRN O 0 R 0.926562)
+ (KRN O 0 R 0.934375)
+ (KRN O 0 R 0.942187)
+ (KRN O 0 R 0.95)
+ (KRN O 0 R 0.957812)
+ (KRN O 0 R 0.965625)
+ (KRN O 0 R 0.973437)
+ (KRN O 0 R 0.98125)
+ (KRN O 0 R 0.989062)
+ (KRN O 0 R 0.996875)
+ (KRN O 0 R 1.004687)
+ (KRN O 0 R 1.0125)
+ (KRN O 0 R 1.020312)
+ (KRN O 0 R 1.028125)
+ (KRN O 0 R 1.035937)
+ (KRN O 0 R 1.04375)
+ (KRN O 0 R 1.051562)
+ (KRN O 0 R 1.059375)
+ (KRN O 0 R 1.067187)
+ (KRN O 0 R 1.075)
+ (KRN O 0 R 1.082812)
+ (KRN O 0 R 1.090625)
+ (KRN O 0 R 1.098437)
+ (KRN O 0 R 1.10625)
+ (KRN O 0 R 1.114062)
+ (KRN O 0 R 1.121875)
+ (KRN O 0 R 1.129687)
+ (KRN O 0 R 1.1375)
+ (KRN O 0 R 1.145312)
+ (KRN O 0 R 1.153125)
+ (KRN O 0 R 1.160937)
+ (KRN O 0 R 1.16875)
+ (KRN O 0 R 1.176562)
+ (KRN O 0 R 1.184375)
+ (KRN O 0 R 1.192187)
+ (KRN O 0 R 1.2)
+ (KRN O 0 R 1.207812)
+ (KRN O 0 R 1.215625)
+ (KRN O 0 R 1.223437)
+ (KRN O 0 R 1.23125)
+ (KRN O 0 R 1.239062)
+ (KRN O 0 R 1.246875)
+ (KRN O 0 R 1.254687)
+ (KRN O 0 R 1.2625)
+ (SKIP D 1)
+ (LABEL C j)
+ (/LIG> C j O 0)
+ (SKIP D 123)
+ (KRN O 0 R 1.202344)
+ (KRN O 0 R 1.210156)
+ (KRN O 0 R 1.217969)
+ (KRN O 0 R 1.225781)
+ (KRN O 0 R 1.233594)
+ (KRN O 0 R 1.241406)
+ (KRN O 0 R 1.249219)
+ (KRN O 0 R 1.257031)
+ (KRN O 0 R 1.264844)
+ (KRN O 0 R 1.272656)
+ (KRN O 0 R 1.280469)
+ (KRN O 0 R 1.288281)
+ (KRN O 0 R 1.296094)
+ (KRN O 0 R 1.303906)
+ (KRN O 0 R 1.311719)
+ (KRN O 0 R 1.319531)
+ (KRN O 0 R 1.327344)
+ (KRN O 0 R 1.335156)
+ (KRN O 0 R 1.342969)
+ (KRN O 0 R 1.350781)
+ (KRN O 0 R 1.358594)
+ (KRN O 0 R 1.366406)
+ (KRN O 0 R 1.374219)
+ (KRN O 0 R 1.382031)
+ (KRN O 0 R 1.389844)
+ (KRN O 0 R 1.397656)
+ (KRN O 0 R 1.405469)
+ (KRN O 0 R 1.413281)
+ (KRN O 0 R 1.421094)
+ (KRN O 0 R 1.428906)
+ (KRN O 0 R 1.436719)
+ (KRN O 0 R 1.444531)
+ (KRN O 0 R 1.452344)
+ (KRN O 0 R 1.460156)
+ (KRN O 0 R 1.467969)
+ (KRN O 0 R 1.475781)
+ (KRN O 0 R 1.483594)
+ (KRN O 0 R 1.491406)
+ (KRN O 0 R 1.499219)
+ (KRN O 0 R 1.507031)
+ (KRN O 0 R 1.514844)
+ (KRN O 0 R 1.522656)
+ (KRN O 0 R 1.530469)
+ (KRN O 0 R 1.538281)
+ (KRN O 0 R 1.546094)
+ (KRN O 0 R 1.553906)
+ (KRN O 0 R 1.561719)
+ (KRN O 0 R 1.569531)
+ (KRN O 0 R 1.577344)
+ (KRN O 0 R 1.585156)
+ (KRN O 0 R 1.592969)
+ (KRN O 0 R 1.600781)
+ (KRN O 0 R 1.608594)
+ (KRN O 0 R 1.616406)
+ (KRN O 0 R 1.624219)
+ (KRN O 0 R 1.632031)
+ (KRN O 0 R 1.639844)
+ (KRN O 0 R 1.647656)
+ (KRN O 0 R 1.655469)
+ (KRN O 0 R 1.663281)
+ (SKIP D 1)
+ (LABEL C k)
+ (LIG/> C k O 0)
+ (SKIP D 62)
+ (KRN O 0 R 1.603125)
+ (KRN O 0 R 1.610937)
+ (KRN O 0 R 1.61875)
+ (KRN O 0 R 1.626562)
+ (KRN O 0 R 1.634375)
+ (KRN O 0 R 1.642187)
+ (KRN O 0 R 1.65)
+ (KRN O 0 R 1.657812)
+ (KRN O 0 R 1.665625)
+ (KRN O 0 R 1.673437)
+ (KRN O 0 R 1.68125)
+ (KRN O 0 R 1.689062)
+ (KRN O 0 R 1.696875)
+ (KRN O 0 R 1.704687)
+ (KRN O 0 R 1.7125)
+ (KRN O 0 R 1.720312)
+ (KRN O 0 R 1.728125)
+ (KRN O 0 R 1.735937)
+ (KRN O 0 R 1.74375)
+ (KRN O 0 R 1.751562)
+ (KRN O 0 R 1.759375)
+ (KRN O 0 R 1.767187)
+ (KRN O 0 R 1.775)
+ (KRN O 0 R 1.782812)
+ (KRN O 0 R 1.790625)
+ (KRN O 0 R 1.798437)
+ (KRN O 0 R 1.80625)
+ (KRN O 0 R 1.814062)
+ (KRN O 0 R 1.821875)
+ (KRN O 0 R 1.829687)
+ (KRN O 0 R 1.8375)
+ (KRN O 0 R 1.845312)
+ (KRN O 0 R 1.853125)
+ (KRN O 0 R 1.860937)
+ (KRN O 0 R 1.86875)
+ (KRN O 0 R 1.876562)
+ (KRN O 0 R 1.884375)
+ (KRN O 0 R 1.892187)
+ (KRN O 0 R 1.9)
+ (KRN O 0 R 1.907812)
+ (KRN O 0 R 1.915625)
+ (KRN O 0 R 1.923437)
+ (KRN O 0 R 1.93125)
+ (KRN O 0 R 1.939062)
+ (KRN O 0 R 1.946875)
+ (KRN O 0 R 1.954687)
+ (KRN O 0 R 1.9625)
+ (KRN O 0 R 1.970312)
+ (KRN O 0 R 1.978125)
+ (KRN O 0 R 1.985937)
+ (KRN O 0 R 1.99375)
+ (KRN O 0 R 2.001562)
+ (KRN O 0 R 2.009375)
+ (KRN O 0 R 2.017187)
+ (KRN O 0 R 2.025)
+ (KRN O 0 R 2.032812)
+ (KRN O 0 R 2.040625)
+ (KRN O 0 R 2.048437)
+ (KRN O 0 R 2.05625)
+ (KRN O 0 R 2.064062)
+ (STOP)
+ (LABEL C l)
+ (/LIG/> C l O 0)
+ (SKIP D 1)
+ (LABEL C m)
+ (LIG O 0 O 0)
+ (STOP)
+ (LIG C a C b)
+ (KRN C d R -15.999999)
+ (LABEL C c)
+ (LABEL C d)
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ (STOP)
+ (COMMENT THIS PART OF THE PROGRAM IS NEVER USED!
+ )
+ )
+(CHARACTER O 0
+ (CHARWD R 2.0)
+ (CHARHT R 15.999999)
+ (CHARDP R 0.234375)
+ (CHARIC R -7.8125)
+ (NEXTLARGER O 5)
+ )
+(CHARACTER O 5
+ (CHARWD R 0.0)
+ (CHARDP R -0.113281)
+ (VARCHAR
+ (TOP O 5)
+ (MID C c)
+ (REP C d)
+ )
+ )
+(CHARACTER O 33
+ (CHARWD R 0.0)
+ (CHARDP R 0.2109375)
+ )
+(CHARACTER O 137
+ (CHARWD R 0.0)
+ (CHARDP R 0.1015625)
+ )
+(CHARACTER O 140
+ (CHARWD R 0.0)
+ (CHARDP R 0.089844)
+ )
+(CHARACTER C a
+ (CHARWD R 0.0)
+ (NEXTLARGER C d)
+ )
+(CHARACTER C b
+ (CHARWD R 0.0)
+ (CHARDP R 0.1640625)
+ )
+(CHARACTER C c
+ (CHARWD R 0.0)
+ (CHARDP R -0.011719)
+ (COMMENT
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ )
+ )
+(CHARACTER C d
+ (CHARWD R 0.0)
+ (CHARDP R 0.1328125)
+ (COMMENT
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ )
+ )
+(CHARACTER C e
+ (CHARWD R 0.0)
+ (CHARDP R 0.089844)
+ )
+(CHARACTER C f
+ (CHARWD R 0.0)
+ (CHARDP R 0.0234375)
+ )
+(CHARACTER C g
+ (CHARWD R 0.0)
+ (CHARDP R -0.011719)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (LIG/ C g O 0)
+ )
+ )
+(CHARACTER C h
+ (CHARWD R 0.0)
+ (CHARDP R 0.1953125)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (/LIG C i O 0)
+ )
+ )
+(CHARACTER C i
+ (CHARWD R 0.0)
+ (CHARDP R 0.2421875)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (/LIG C i O 0)
+ )
+ )
+(CHARACTER C j
+ (CHARWD R 0.0)
+ (CHARDP R 0.1484375)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (/LIG> C j O 0)
+ (LIG C a C b)
+ (KRN C d R -15.999999)
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ )
+ )
+(CHARACTER C k
+ (CHARWD R 0.0)
+ (CHARDP R 0.0546875)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (LIG/> C k O 0)
+ (LIG C a C b)
+ (KRN C d R -15.999999)
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ )
+ )
+(CHARACTER C l
+ (CHARWD R 2.0)
+ (CHARDP R 0.1796875)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (/LIG/> C l O 0)
+ (LIG C a C b)
+ (KRN C d R -15.999999)
+ (/LIG/ C e C f)
+ (KRN O 0 R 0.0)
+ )
+ )
+(CHARACTER C m
+ (CHARWD R 2.0)
+ (CHARHT R 15.999999)
+ (CHARDP R 0.234375)
+ (CHARIC R -7.8125)
+ (COMMENT
+ (LIG O 0 O 0)
+ )
+ )
+(CHARACTER O 354
+ (CHARWD R 0.0)
+ (CHARDP R -15.999999)
+ )
diff --git a/Master/texmf-doc/doc/english/knuth/trapman.tex b/Master/texmf-doc/doc/english/knuth/trapman.tex
new file mode 100644
index 00000000000..7968c6e44ea
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/trapman.tex
@@ -0,0 +1,400 @@
+% The TRAP manual: How to validate MF --- last updated by D E Knuth on 4 Dec 89
+\font\eighttt= cmtt8
+\font\eightrm= cmr8
+\font\titlefont=cmssdc10 at 40pt
+\let\mc=\eightrm
+\font\logo=manfnt % font used for the METAFONT logo
+\def\MF{{\logo META}\-{\logo FONT}}
+\rm
+\let\mainfont=\tenrm
+
+\def\.#1{\hbox{\tt#1}}
+\def\\#1{\hbox{\it#1\/\hskip.05em}} % italic type for identifiers
+
+\parskip 2pt plus 1pt
+\baselineskip 12pt plus .25pt
+
+\def\verbatim#1{\begingroup \frenchspacing
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =\active \catcode`\^^M=\active
+ \tt \def\par{\ \endgraf} \obeylines \obeyspaces
+ \input #1 \endgroup}
+% a blank line will be typeset at the end of the file;
+% if you're unlucky it will appear on a page by itself!
+{\obeyspaces\global\let =\ }
+
+\output{\shipout\box255\global\advance\pageno by 1} % for the title page only
+\null
+\vfill
+\centerline{\titlefont A Torture Test}
+\vskip8pt
+\centerline{\titlefont for \logo ()*+,-.*}
+\vskip 24pt
+\centerline{by Donald E. Knuth}
+\centerline{Stanford University}
+\vskip 6pt
+\centerline{({\sl Version 2, January 1990\/})}
+\vfill
+\centerline{\vbox{\hsize 4in
+\noindent Programs that claim to be implementations of \MF84 are
+supposed to be able to process the test routine contained in this
+report, producing the outputs contained in this report.}}
+\vskip 24pt
+{\baselineskip 9pt
+\eightrm\noindent
+The preparation of this report was supported in part by the National Science
+Foundation under grants IST-8201926 and MCS-8300984,
+and by the System Development Foundation.
+{\logo opqrstuq} is a trademark of Addison-Wesley Publishing Company.
+
+
+}\pageno=0\eject
+
+\output{\shipout\vbox{ % for subsequent pages
+ \baselineskip0pt\lineskip0pt
+ \hbox to\hsize{\strut
+ \ifodd\pageno \hfil\eightrm\firstmark\hfil
+ \mainfont\the\pageno
+ \else\mainfont\the\pageno\hfil
+ \eightrm\firstmark\hfil\fi}
+ \vskip 10pt
+ \box255}
+ \global\advance\pageno by 1}
+\let\runninghead=\mark
+\outer\def\section#1.{\noindent{\bf#1.}\quad
+ \runninghead{\uppercase{#1} }\ignorespaces}
+
+\section Introduction.
+People often think that their programs are ``debugged'' when large applications
+have been run successfully. But system programmers know that a typical large
+application tends to use at most about 50 per cent of the instructions
+in a typical compiler. Although the other half of the code---which tends
+to be the ``harder half''---might be riddled with errors, the system seems
+to be working quite impressively until an unusual case shows up on the
+next day. And on the following day another error manifests itself, and so on;
+months or years go by before certain parts of the compiler are even
+activated, much less tested in combination with other portions of the system,
+if user applications provide the only tests.
+
+How then shall we go about testing a compiler? Ideally we would like to
+have a formal proof of correctness, certified by a computer.
+This would give us a lot of confidence,
+although of course the formal verification program might itself be incorrect.
+A more serious drawback of automatic verification is that the formal
+specifications of the compiler are likely to be wrong, since they aren't
+much easier to write than the compiler itself. Alternatively, we can
+substitute an informal proof of correctness: The programmer writes his or
+her code in a structured manner and checks that appropriate relations
+remain invariant, etc. This helps greatly to reduce errors, but it cannot
+be expected to remove them completely; the task of checking a large
+system is sufficiently formidable that human beings cannot do it without
+making at least a few slips here and there.
+
+Thus, we have seen that test programs are unsatisfactory if they are simply
+large user applications; yet some sort of test program is needed because
+proofs of correctness aren't adequate either. People have proposed schemes
+for constructing test data automatically from a program text, but such
+approaches run the risk of circularity, since they cannot assume that a
+given program has the right structure.
+
+I have been having good luck with a somewhat different approach,
+first used in 1960 to debug an {\mc ALGOL} compiler. The idea is to
+construct a test file that is about as different from a typical user
+application as could be imagined. Instead of testing things that people
+normally want to do, the file tests complicated things that people would
+never dare to think of, and it embeds these complexities in still
+more arcane constructions. Instead of trying to make the compiler do the
+right thing, the goal is to make it fail (until the bugs have all been found).
+
+To write such a fiendish test routine, one simply gets into a nasty frame
+of mind and tries to do everything in the unexpected way. Parameters
+that are normally positive are set negative or zero; borderline cases
+are pushed to the limit; deliberate errors are made in hopes that the
+compiler will not be able to recover properly from them.
+
+A user's application tends to exercise 50\%\ of a compiler's logic,
+but my first fiendish tests tend to improve this to about 90\%. As the
+next step I generally make use of frequency-counting software to identify
+the instructions that have still not been called upon. Then I add ever more
+fiendishness to the test routine, until more than 99\%\ of the code
+has been used at least once. (The remaining bits are things that
+can occur only if the source program is really huge, or if certain
+fatal errors are detected; or they are cases so similar to other well-tested
+things that there can be little doubt of their validity.)
+
+Of course, this is not guaranteed to work. But my experience in 1960 was
+that only two bugs were ever found in that {\mc ALGOL} compiler after it
+correctly translated that original fiendish test. And one of those bugs
+was actually present in the results of the test; I simply had failed to
+notice that the output was incorrect. Similar experiences occurred later
+during the 60s and 70s, with respect to a few assemblers, compilers,
+and simulators that I wrote.
+
+This method of debugging, combined with the methodology of structured
+programming and informal proofs (otherwise known as careful desk checking),
+leads to greater reliability of production software than any other
+method I know. Therefore I have used it in developing \MF84, and the
+main bulk of this report is simply a presentation of the test program
+that was used to get the bugs out of \MF.
+
+Such a test file is useful also after a program has been debugged, since
+it can be used to give some assurance that subsequent modifications don't
+mess things up.
+
+The test file is called \.{TRAP.MF}, because of my warped sense of humor:
+\MF's companion system, \TeX, has a similar test file called \.{TRIP}, and I
+couldn't help thinking about Billy Goat Gruff and the story of ``trip,
+trap, trip, trap.''
+
+The contents of this test file are so remote from what people actually
+do with \MF, I feel apologetic if I have to explain the correct
+translation of \.{TRAP.MF}; nobody really cares about most of the
+nitty-gritty rules that are involved. Yet I believe \.{TRAP} exemplifies
+the sort of test program that has outstanding diagnostic ability, as
+explained above.
+
+If somebody claims to have a correct implementation of \MF, I will not
+believe it until I see that \.{TRAP.MF} is translated properly.
+I propose, in fact, that a program must meet two criteria before it
+can justifiably be called \MF: (1)~The person who wrote it must be
+happy with the way it works at his or her installation; and (2)~the
+program must produce the correct results from \.{TRAP.MF}.
+
+\MF\ is in the public domain, and its algorithms are published;
+I've done this since I do not want to discourage its use by placing
+proprietary restrictions on the software. However, I don't want
+faulty imitations to masquerade as \MF\ processors, since users
+want \MF\ to produce identical results on different machines.
+Hence I am planning to do whatever I can to suppress any systems that
+call themselves \MF\ without meeting conditions (1) and~(2).
+I have copyrighted the programs so that I have some chance to forbid
+unauthorized copies; I explicitly authorize copying of correct
+\MF\ implementations, and not of incorrect ones!
+
+The remainder of this report consists of appendices, whose contents ought
+to be described briefly here:
+
+Appendix A explains in detail how to carry out a test of \MF, given
+a tape that contains copies of the other appendices.
+
+Appendix B is \.{TRAP.MF}, the fiendish test file that has already
+been mentioned. People who think that they understand \MF\ are challenged
+to see if they know what \MF\ is supposed to do with this file.
+People who know only a little about \MF\ might still find it
+interesting to study Appendix~B, just to get some insights into the
+methodology advocated here.
+
+Appendix C is \.{TRAPIN.LOG}, a correct transcript file \.{TRAP.LOG}
+that results if \.{INIMF} is applied to \.{TRAP.MF}. (\.{INIMF} is
+the name of a version of \MF\ that does certain initializations;
+this run of \.{INIMF} also creates a binary base file called \.{TRAP.BASE}.)
+
+Appendix D is a correct transcript file \.{TRAP.LOG} that results if
+\.{INIMF} or any other version of \MF\ is applied to \.{TRAP.MF}
+with base file \.{TRAP.BASE}.
+
+Appendix E is \.{TRAP.TYP}, the symbolic version of a correct output
+file \.{TRAP.72270GF} that was produced at the same time as the \.{TRAP.LOG}
+file of Appendix~D.
+
+Appendix F is \.{TRAP.PL}, the symbolic version of a correct output
+file \.{TRAP.TFM} that was produced at the same time as the \.{TRAP.LOG}
+file of Appendix~D.
+
+Appendix G is \.{TRAP.FOT}, an abbreviated version of Appendix D that
+appears on the user's terminal during the run that produces \.{TRAP.LOG},
+\.{TRAP.72270GF}, and \.{TRAP.TFM}.
+
+The debugging of \MF\ and the testing of the adequacy of \.{TRAP.MF}
+could not have been done nearly as well as reported here except for
+the magnificent software support provided by my colleague David R. Fuchs.
+In particular, he extended our local Pascal compiler so that
+frequency counting and a number of other important features were added
+to its online debugging abilities.
+
+The method of testing advocated here has one chief difficulty that deserves
+comment: I had to verify by hand that \MF\ did the right things
+to \.{TRAP.MF}. This took many hours, and perhaps I have missed
+something (as I did in 1960); I must confess that I have not checked
+every single number in Appendices D, E, and~F. However, I'm willing to pay
+$\$$81.92 to the first finder of any remaining bug in \MF, and I will
+be surprised if that bug doesn't show up also in one of these appendices.
+
+\vfill\eject
+
+\section Appendix A: How to test \MF.
+
+\item{0.} Let's assume that you have a tape containing \.{TRAP.MF},
+\.{TRAPIN.LOG}, \.{TRAP.LOG}, \.{TRAP.TYP}, \.{TRAP.PL}, and \.{TRAP.FOT},
+as in Appendices B, C, D, E, F, and~G. Furthermore, let's suppose that you
+have a working \.{WEB} system, and that you have working programs
+\.{TFtoPL} and \.{GFtype}, as described in the \TeX ware and \MF ware reports.
+
+\item{1.} Prepare a version of \.{INIMF}. (This means that your \.{WEB}
+change file should have {\bf init} and {\bf tini} defined to be null.)
+The {\bf debug} and {\bf gubed} macros should be null, in order to
+activate special printouts that occur when $\\{tracingedges}>1.0$.
+The {\bf stat} and {\bf tats} macros should also be null, so that
+statistics are kept. Set \\{mem\_top} and \\{mem\_max} to 3000
+(or to \\{mem\_min} plus 3000, if \\{mem\_min} isn't zero),
+for purposes of this test version.
+Also set $\\{error\_line}=64$, $\\{half\_error\_line}=32$,
+$\\{max\_print\_line}=72$, $\\{screen\_width}=100$, and
+$\\{screen\_depth}=200$; these parameters affect many of the lines of
+the test output, so your job will be much easier if you use the same
+settings that were used to produce Appendix~E. Also (if possible) set
+$\\{gf\_buf\_size}=8$, since this tests more parts of the program.
+You probably should also use the ``normal'' settings of other parameters
+found in \.{MF.WEB} (e.g., $\\{max\_internal}=100$, $\\{buf\_size}=500$,
+etc.), since these show up in a few lines of the test output. Finally,
+change \MF's screen-display routines by putting the following simple lines
+in the change file:
+$$\vbox{\halign{\tt#\hfil\cr
+\char`\@x Screen routines:\cr
+begin init\char`\_screen:=false;\cr
+\char`\@y\cr
+begin init\char`\_screen:=true;
+ \char`\{screen instructions will be logged\char`\}\cr
+\char`\@z\cr}}$$
+None of the other screen routines (\\{update\_screen}, \\{blank\_rectangle},
+\\{paint\_row}) should be changed in any way; the effect will be to have
+\MF's actions recorded in the transcript files instead of on the screen,
+in a machine-independent way.
+
+\item{2.} Run the \.{INIMF} prepared in step 1. In response to the first
+`\.{**}' prompt, type carriage return (thus getting another `\.{**}').
+Then type `\.{\char`\\input trap}'. You should get an output that matches
+the file \.{TRAPIN.LOG} (Appendix~C). Don't be alarmed by the error
+messages that you see, unless they are different from those in Appendix~C.
+
+\def\sp{{\char'40}}
+\item{3.} Run \.{INIMF} again. This time type `\.{\sp\&trap\sp\sp trap\sp}'.
+(The spaces in this input help to check certain parts of \MF\ that
+aren't otherwise used.) You should get outputs \.{TRAP.LOG}, \.{TRAP.72270GF},
+and \.{TRAP.TFM}.
+Furthermore, your terminal should receive output that matches \.{TRAP.FOT}
+(Appendix~G). During the middle part of this test, however, the terminal
+will not be getting output, because \.{batchmode} is being
+tested; don't worry if nothing seems to be happening for a while---nothing
+is supposed to.
+
+\item{4.} Compare the \.{TRAP.LOG} file from step 3 with the ``master''
+\.{TRAP.LOG} file of step~0. (Let's hope you put that master file in a
+safe place so that it wouldn't be clobbered.) There should be perfect
+agreement between these files except in the following respects:
+
+\itemitem{a)} The dates and possibly the file names will
+naturally be different.
+
+\itemitem{b)} If you had different values for \\{stack\_size}, \\{buf\_size},
+etc., the corresponding capacity values will be different when they
+are printed out at the end.
+
+\itemitem{c)} Help messages may be different; indeed, the author encourages
+non-English help messages in versions of \MF\ for people who don't
+understand English as well as some other language.
+
+\itemitem{d)} The total number and length of strings at the end and/or
+``still untouched'' may well be different.
+
+\itemitem{e)} If your \MF\ uses a different memory allocation or
+packing scheme, the memory usage statistics may change.
+
+\itemitem{f)} If you use a different storage allocation scheme, the
+capsule numbers will probably be different, but the order of variables
+should be unchanged when dependent variables are shown. \MF\ should also
+choose the same variables to be dependent.
+
+\itemitem{g)} If your computer handles integer division of negative operands
+in a nonstandard way, you may get results that are rounded differently.
+Although \TeX\ is careful to be machine-independent in this regard,
+\MF\ is not, because integer divisions are present in so many places.
+
+\item{5.} Use \.{GFtype} to convert your file \.{TRAP.72270GF} to a file
+\.{TRAP.TYP}. (Both of \.{GFtype}'s options, i.e., mnemonic output and image
+output, should be enabled so that you get the maximum amount of output.)
+The resulting file should agree with the master \.{TRAP.TYP} file of step~0,
+assuming that your \.{GFtype} has the ``normal'' values of compile-time
+constants ($\\{top\_pixel}=69$, etc.).
+
+\item{6.} Use \.{TFtoPL} to convert your file \.{TRAP.TFM} to a file
+\.{TRAP.PL}. The resulting file should agree with the master \.{TRAP.PL}
+file of step~0.
+
+\item{7.} You might also wish to test \.{TRAP} with other versions of
+\MF\ (i.e., \.{VIRMF} or a production version with another base file
+preloaded). It should work unless \MF's primitives have been redefined in
+the base file. However, this step isn't essential, since all the code of
+\.{VIRMF} appears in \.{INIMF}; you probably won't catch any more errors
+this way, unless they would already become obvious from normal use of
+the~system.
+
+\vfill\eject
+
+\section Appendix B: The \.{TRAP.MF} file.
+The contents of the test routine are prefixed here with line numbers, for
+ease in comparing this file with the error messages printed later; the
+line numbers aren't actually present.
+\runninghead{APPENDIX B: \.{TRAP.MF} (CONTINUED)}
+
+\vskip 8pt
+\begingroup\count255=0
+\everypar{\global\advance\count255 by 1
+ \hbox to 20pt{\sevenrm\hfil\the\count255\ \ }}
+\verbatim{trap.mf}
+\endgroup
+\vfill\eject
+
+\section Appendix C: The \.{TRAPIN.LOG} file.
+When \.{INIMF} makes the \.{TRAP.BASE} file, it also creates a file called
+\.{TRAP.LOG} that looks like this.
+\runninghead{APPENDIX C: \.{TRAPIN.LOG} (CONTINUED)}
+
+\vskip8pt
+\verbatim{trapin.log}
+\vfill\eject
+
+\section Appendix D: The \.{TRAP.LOG} file.
+Here is the major output of the \.{TRAP} test; it is generated by running
+\.{INIMF} and loading \.{TRAP.BASE}, then reading \.{TRAP.MF}.
+\runninghead{APPENDIX D: \.{TRAP.LOG} (CONTINUED)}
+
+{\let\tt=\eighttt\leftskip 1in\baselineskip 9pt plus .1pt minus .1pt
+\vskip8pt
+\verbatim{trap.log}
+}
+\vfill\eject
+
+\section Appendix E: The \.{TRAP.TYP} file.
+Here is another major component of the test. It shows the output of \.{GFtype}
+applied to the file \.{TRAP.72270GF} that is created at the same time
+Appendix D was produced.
+\runninghead{APPENDIX E: \.{TRAP.TYP} (CONTINUED)}
+
+{\let\tt=\eighttt\leftskip 1in\baselineskip 9pt plus .1pt minus .1pt
+\vskip8pt
+\verbatim{trap.typ}
+}
+\vfill\eject
+
+\section Appendix F: The \.{TRAP.PL} file.
+In this case we have the output of \.{TFtoPL}
+applied to the file \.{TRAP.TFM} that is created at the same time
+Appendix D was produced.
+\runninghead{APPENDIX F: \.{TRAP.PL} (CONTINUED)}
+
+{\let\tt=\eighttt\leftskip 1in\baselineskip 9pt plus .1pt minus .1pt
+\vskip8pt
+\verbatim{trap.pl}
+}
+\vfill\eject
+
+\section Appendix G: The \.{TRAP.FOT} file.
+This shows what appeared on the terminal while Appendix D was being produced.
+\runninghead{APPENDIX G: \.{TRAP.FOT} (CONTINUED)}
+
+\vskip8pt
+\verbatim{trap.fot}
+
+\vfill\end
diff --git a/Master/texmf-doc/doc/english/knuth/trip.pl b/Master/texmf-doc/doc/english/knuth/trip.pl
new file mode 100644
index 00000000000..6a38a92316b
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/trip.pl
@@ -0,0 +1,833 @@
+(FAMILY UNSPECIFIED)
+(FACE F MRR)
+(CODINGSCHEME TEX TEST: NOT A REAL FONT)
+(DESIGNSIZE R 10.0)
+(COMMENT DESIGNSIZE IS IN POINTS)
+(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)
+(CHECKSUM O 32107654321)
+(FONTDIMEN
+ (SLANT R -2.0)
+ (SPACE R 0.400001)
+ (STRETCH R 0.200001)
+ (SHRINK R 0.1)
+ (XHEIGHT R 0.45)
+ (QUAD R 1.0)
+ (EXTRASPACE R 0.200001)
+ (PARAMETER D 8 R 0.05)
+ (PARAMETER D 9 R 0.1)
+ (PARAMETER D 10 R 0.200001)
+ (PARAMETER D 11 R 0.3)
+ (PARAMETER D 12 R 0.400001)
+ (PARAMETER D 13 R 0.5)
+ )
+(BOUNDARYCHAR C Z)
+(LIGTABLE
+ (LABEL C t)
+ (KRN O 0 R -1.0)
+ (KRN O 0 R -0.01)
+ (KRN O 0 R -0.02)
+ (KRN O 0 R -0.03)
+ (KRN O 0 R -0.04)
+ (KRN O 0 R -0.05)
+ (KRN O 0 R -0.06)
+ (KRN O 0 R -0.07)
+ (KRN O 0 R -0.08)
+ (KRN O 0 R -0.09)
+ (KRN O 0 R -0.1)
+ (KRN O 0 R -0.11)
+ (KRN O 0 R -0.12)
+ (KRN O 0 R -0.13)
+ (KRN O 0 R -0.14)
+ (KRN O 0 R -0.15)
+ (KRN O 0 R -0.16)
+ (KRN O 0 R -0.17)
+ (KRN O 0 R -0.18)
+ (KRN O 0 R -0.19)
+ (KRN O 0 R -0.2)
+ (KRN O 0 R -0.21)
+ (KRN O 0 R -0.22)
+ (KRN O 0 R -0.23)
+ (KRN O 0 R -0.24)
+ (KRN O 0 R -0.25)
+ (KRN O 0 R -0.26)
+ (KRN O 0 R -0.27)
+ (KRN O 0 R -0.28)
+ (KRN O 0 R -0.29)
+ (KRN O 0 R -0.3)
+ (KRN O 0 R -0.31)
+ (KRN O 0 R -0.32)
+ (KRN O 0 R -0.33)
+ (KRN O 0 R -0.34)
+ (KRN O 0 R -0.35)
+ (KRN O 0 R -0.36)
+ (KRN O 0 R -0.37)
+ (KRN O 0 R -0.38)
+ (KRN O 0 R -0.39)
+ (KRN O 0 R -0.4)
+ (KRN O 0 R -0.41)
+ (KRN O 0 R -0.42)
+ (KRN O 0 R -0.43)
+ (KRN O 0 R -0.44)
+ (KRN O 0 R -0.45)
+ (KRN O 0 R -0.46)
+ (KRN O 0 R -0.47)
+ (KRN O 0 R -0.48)
+ (KRN O 0 R -0.49)
+ (KRN O 0 R -0.5)
+ (KRN O 0 R -0.51)
+ (KRN O 0 R -0.52)
+ (KRN O 0 R -0.53)
+ (KRN O 0 R -0.54)
+ (KRN O 0 R -0.55)
+ (KRN O 0 R -0.56)
+ (KRN O 0 R -0.57)
+ (KRN O 0 R -0.58)
+ (KRN O 0 R -0.59)
+ (KRN O 0 R -0.6)
+ (KRN O 0 R -0.61)
+ (KRN O 0 R -0.62)
+ (KRN O 0 R -0.63)
+ (KRN O 0 R -0.64)
+ (KRN O 0 R -0.65)
+ (KRN O 0 R -0.66)
+ (KRN O 0 R -0.67)
+ (KRN O 0 R -0.68)
+ (KRN O 0 R -0.69)
+ (KRN O 0 R -0.7)
+ (KRN O 0 R -0.71)
+ (KRN O 0 R -0.72)
+ (KRN O 0 R -0.73)
+ (KRN O 0 R -0.74)
+ (KRN O 0 R -0.75)
+ (KRN O 0 R -0.76)
+ (KRN O 0 R -0.77)
+ (KRN O 0 R -0.78)
+ (KRN O 0 R -0.79)
+ (KRN O 0 R -0.8)
+ (KRN O 0 R -0.81)
+ (KRN O 0 R -0.82)
+ (KRN O 0 R -0.83)
+ (KRN O 0 R -0.84)
+ (KRN O 0 R -0.85)
+ (KRN O 0 R -0.86)
+ (KRN O 0 R -0.87)
+ (KRN O 0 R -0.88)
+ (KRN O 0 R -0.89)
+ (KRN O 0 R -0.9)
+ (KRN O 0 R -0.91)
+ (KRN O 0 R -0.92)
+ (KRN O 0 R -0.93)
+ (KRN O 0 R -0.94)
+ (KRN O 0 R -0.95)
+ (KRN O 0 R -0.96)
+ (KRN O 0 R -0.97)
+ (KRN O 0 R -0.98)
+ (KRN O 0 R -0.99)
+ (KRN O 0 R -1.0)
+ (KRN O 0 R -1.01)
+ (KRN O 0 R -1.02)
+ (KRN O 0 R -1.03)
+ (KRN O 0 R -1.04)
+ (KRN O 0 R -1.05)
+ (KRN O 0 R -1.06)
+ (KRN O 0 R -1.07)
+ (KRN O 0 R -1.08)
+ (KRN O 0 R -1.09)
+ (KRN O 0 R -1.1)
+ (KRN O 0 R -1.11)
+ (KRN O 0 R -1.12)
+ (KRN O 0 R -1.13)
+ (KRN O 0 R -1.14)
+ (KRN O 0 R -1.15)
+ (KRN O 0 R -1.16)
+ (KRN O 0 R -1.17)
+ (KRN O 0 R -1.18)
+ (KRN O 0 R -1.19)
+ (KRN O 0 R -1.2)
+ (KRN O 0 R -1.21)
+ (KRN O 0 R -1.22)
+ (KRN O 0 R -1.23)
+ (KRN O 0 R -1.24)
+ (KRN O 0 R -1.25)
+ (KRN O 0 R -1.26)
+ (KRN O 0 R -1.27)
+ (KRN O 0 R -1.28)
+ (KRN O 0 R -1.29)
+ (KRN O 0 R -1.3)
+ (KRN O 0 R -1.31)
+ (KRN O 0 R -1.32)
+ (KRN O 0 R -1.33)
+ (KRN O 0 R -1.34)
+ (KRN O 0 R -1.35)
+ (KRN O 0 R -1.36)
+ (KRN O 0 R -1.37)
+ (KRN O 0 R -1.38)
+ (KRN O 0 R -1.39)
+ (KRN O 0 R -1.4)
+ (KRN O 0 R -1.41)
+ (KRN O 0 R -1.42)
+ (KRN O 0 R -1.43)
+ (KRN O 0 R -1.44)
+ (KRN O 0 R -1.45)
+ (KRN O 0 R -1.46)
+ (KRN O 0 R -1.47)
+ (KRN O 0 R -1.48)
+ (KRN O 0 R -1.49)
+ (KRN O 0 R -1.5)
+ (KRN O 0 R -1.51)
+ (KRN O 0 R -1.52)
+ (KRN O 0 R -1.53)
+ (KRN O 0 R -1.54)
+ (KRN O 0 R -1.55)
+ (KRN O 0 R -1.56)
+ (KRN O 0 R -1.57)
+ (KRN O 0 R -1.58)
+ (KRN O 0 R -1.59)
+ (KRN O 0 R -1.6)
+ (KRN O 0 R -1.61)
+ (KRN O 0 R -1.62)
+ (KRN O 0 R -1.63)
+ (KRN O 0 R -1.64)
+ (KRN O 0 R -1.65)
+ (KRN O 0 R -1.66)
+ (KRN O 0 R -1.67)
+ (KRN O 0 R -1.68)
+ (KRN O 0 R -1.69)
+ (KRN O 0 R -1.7)
+ (KRN O 0 R -1.71)
+ (KRN O 0 R -1.72)
+ (KRN O 0 R -1.73)
+ (KRN O 0 R -1.74)
+ (KRN O 0 R -1.75)
+ (KRN O 0 R -1.76)
+ (KRN O 0 R -1.77)
+ (KRN O 0 R -1.78)
+ (KRN O 0 R -1.79)
+ (KRN O 0 R -1.8)
+ (KRN O 0 R -1.81)
+ (KRN O 0 R -1.82)
+ (KRN O 0 R -1.83)
+ (KRN O 0 R -1.84)
+ (KRN O 0 R -1.85)
+ (KRN O 0 R -1.86)
+ (KRN O 0 R -1.87)
+ (KRN O 0 R -1.88)
+ (KRN O 0 R -1.89)
+ (KRN O 0 R -1.9)
+ (KRN O 0 R -1.91)
+ (KRN O 0 R -1.92)
+ (KRN O 0 R -1.93)
+ (KRN O 0 R -1.94)
+ (KRN O 0 R -1.95)
+ (KRN O 0 R -1.96)
+ (KRN O 0 R -1.97)
+ (KRN O 0 R -1.98)
+ (KRN O 0 R -1.99)
+ (KRN O 0 R -2.0)
+ (KRN O 0 R -2.01)
+ (KRN O 0 R -2.02)
+ (KRN O 0 R -2.03)
+ (KRN O 0 R -2.04)
+ (KRN O 0 R -2.05)
+ (KRN O 0 R -2.06)
+ (KRN O 0 R -2.07)
+ (KRN O 0 R -2.08)
+ (KRN O 0 R -2.09)
+ (KRN O 0 R -2.1)
+ (KRN O 0 R -2.11)
+ (KRN O 0 R -2.12)
+ (KRN O 0 R -2.13)
+ (KRN O 0 R -2.14)
+ (KRN O 0 R -2.15)
+ (KRN O 0 R -2.16)
+ (KRN O 0 R -2.17)
+ (KRN O 0 R -2.18)
+ (KRN O 0 R -2.19)
+ (KRN O 0 R -2.2)
+ (KRN O 0 R -2.21)
+ (KRN O 0 R -2.22)
+ (KRN O 0 R -2.23)
+ (KRN O 0 R -2.24)
+ (KRN O 0 R -2.25)
+ (KRN O 0 R -2.26)
+ (KRN O 0 R -2.27)
+ (KRN O 0 R -2.28)
+ (KRN O 0 R -2.29)
+ (KRN O 0 R -2.3)
+ (SKIP D 3)
+ (LABEL O 55)
+ (LIG O 0 O 55)
+ (/LIG> C q C p)
+ (LABEL O 57)
+ (KRN C A R 0.1)
+ (STOP)
+ (KRN O 0 R -2.31)
+ (KRN O 0 R -2.32)
+ (KRN O 0 R -2.33)
+ (KRN O 0 R -2.34)
+ (KRN O 0 R -2.35)
+ (KRN O 0 R -2.36)
+ (KRN O 0 R -2.37)
+ (KRN O 0 R -2.38)
+ (KRN O 0 R -2.39)
+ (KRN O 0 R -2.4)
+ (KRN O 0 R -2.41)
+ (KRN O 0 R -2.42)
+ (KRN O 0 R -2.43)
+ (KRN O 0 R -2.44)
+ (KRN O 0 R -2.45)
+ (KRN O 0 R -2.46)
+ (KRN O 0 R -2.47)
+ (KRN O 0 R -2.48)
+ (KRN O 0 R -2.49)
+ (KRN O 0 R -2.5)
+ (KRN O 0 R -2.51)
+ (KRN O 0 R -2.52)
+ (KRN O 0 R -2.53)
+ (KRN O 0 R -2.54)
+ (KRN O 0 R -2.55)
+ (KRN O 0 R -2.56)
+ (KRN O 0 R -2.57)
+ (/LIG/>> C r C s)
+ (SKIP D 9)
+ (LABEL C p)
+ (/LIG/ C q C r)
+ (/LIG/> C r C t)
+ (LIG C t C t)
+ (STOP)
+ (LABEL C q)
+ (/LIG/ C u C p)
+ (/LIG/ C s C r)
+ (KRN C t R 0.1)
+ (/LIG> C r C t)
+ (SKIP D 2)
+ (LABEL C r)
+ (LIG/ C u C q)
+ (/LIG C q C u)
+ (STOP)
+ (/LIG/ C p C s)
+ (KRN C s R 0.3)
+ (STOP)
+ (LABEL C s)
+ (LIG/> C p C q)
+ (KRN C r R 0.1)
+ (STOP)
+ (LABEL C u)
+ (/LIG C Z C p)
+ (LIG C p C r)
+ (STOP)
+ (LABEL BOUNDARYCHAR)
+ (LIG/ C q C q)
+ (/LIG C 1 C 5)
+ (KRN O 55 R -0.1)
+ (STOP)
+ (LABEL C 1)
+ (/LIG/ C 1 C 2)
+ (/LIG/ C 2 C 3)
+ (/LIG> O 55 C 1)
+ (SKIP D 1)
+ (LABEL C 2)
+ (/LIG/ C 1 C 3)
+ (/LIG/ C 3 C 4)
+ (SKIP D 2)
+ (LABEL C 3)
+ (/LIG/ C 1 C 4)
+ (/LIG/ C 2 C 4)
+ (/LIG/ C 4 C 5)
+ (SKIP D 3)
+ (LABEL C 4)
+ (/LIG/ C 1 C 5)
+ (/LIG/ C 2 C 5)
+ (/LIG/ C 3 C 5)
+ (/LIG/ C 5 C 6)
+ (SKIP D 4)
+ (LABEL C 5)
+ (/LIG/ C 1 C 6)
+ (/LIG/ C 2 C 6)
+ (/LIG/ C 3 C 6)
+ (/LIG/ C 4 C 6)
+ (/LIG/ C 6 C 7)
+ (SKIP D 5)
+ (LABEL C 6)
+ (/LIG/ C 1 C 7)
+ (/LIG/ C 2 C 7)
+ (/LIG/ C 3 C 7)
+ (/LIG/ C 4 C 7)
+ (/LIG/ C 5 C 7)
+ (/LIG/>> C Z C 7)
+ (STOP)
+ (LABEL C 7)
+ (KRN C Z R 0.1)
+ (LABEL C A)
+ (LIG C A C A)
+ (KRN C B R 0.200001)
+ (KRN O 55 R 0.3)
+ (KRN C 1 R -0.200001)
+ (STOP)
+ (LABEL C B)
+ (LIG C B C A)
+ (LIG O 55 C C)
+ (KRN C C R 0.400001)
+ (STOP)
+ (LABEL C C)
+ (LIG C A O 202)
+ (LIG O 57 C B)
+ (STOP)
+ )
+(CHARACTER O 0
+ (CHARWD R 0.700001)
+ (CHARHT R -0.1)
+ (CHARDP R 0.200001)
+ )
+(CHARACTER O 55
+ (CHARWD R -0.5)
+ (COMMENT
+ (LIG O 0 O 55)
+ (/LIG> C q C p)
+ (KRN C A R 0.1)
+ )
+ )
+(CHARACTER O 57
+ (CHARWD R 0.1)
+ (COMMENT
+ (KRN C A R 0.1)
+ )
+ )
+(CHARACTER C 1
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 2)
+ (/LIG/ C 2 C 3)
+ (/LIG> O 55 C 1)
+ (/LIG/ C 3 C 4)
+ (/LIG/ C 4 C 5)
+ (/LIG/ C 5 C 6)
+ (/LIG/ C 6 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 2
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 3)
+ (/LIG/ C 3 C 4)
+ (/LIG/ C 4 C 5)
+ (/LIG/ C 5 C 6)
+ (/LIG/ C 6 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 3
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 4)
+ (/LIG/ C 2 C 4)
+ (/LIG/ C 4 C 5)
+ (/LIG/ C 5 C 6)
+ (/LIG/ C 6 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 4
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 5)
+ (/LIG/ C 2 C 5)
+ (/LIG/ C 3 C 5)
+ (/LIG/ C 5 C 6)
+ (/LIG/ C 6 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 5
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 6)
+ (/LIG/ C 2 C 6)
+ (/LIG/ C 3 C 6)
+ (/LIG/ C 4 C 6)
+ (/LIG/ C 6 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 6
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C 1 C 7)
+ (/LIG/ C 2 C 7)
+ (/LIG/ C 3 C 7)
+ (/LIG/ C 4 C 7)
+ (/LIG/ C 5 C 7)
+ (/LIG/>> C Z C 7)
+ )
+ )
+(CHARACTER C 7
+ (CHARWD R 0.0)
+ (COMMENT
+ (KRN C Z R 0.1)
+ (LIG C A C A)
+ (KRN C B R 0.200001)
+ (KRN O 55 R 0.3)
+ (KRN C 1 R -0.200001)
+ )
+ )
+(CHARACTER C A
+ (CHARWD R 0.200001)
+ (CHARHT R 0.700001)
+ (CHARDP R 0.1)
+ (CHARIC R 0.1)
+ (COMMENT
+ (LIG C A C A)
+ (KRN C B R 0.200001)
+ (KRN O 55 R 0.3)
+ (KRN C 1 R -0.200001)
+ )
+ )
+(CHARACTER C B
+ (CHARWD R 0.3)
+ (CHARHT R 0.8)
+ (CHARDP R 0.200001)
+ (COMMENT
+ (LIG C B C A)
+ (LIG O 55 C C)
+ (KRN C C R 0.400001)
+ )
+ )
+(CHARACTER C C
+ (CHARWD R 0.400001)
+ (COMMENT
+ (LIG C A O 202)
+ (LIG O 57 C B)
+ )
+ )
+(CHARACTER C M
+ (CHARWD R 0.6)
+ (CHARIC R 0.200001)
+ (VARCHAR
+ (MID C A)
+ (BOT C B)
+ (REP O 0)
+ )
+ )
+(CHARACTER C a
+ (CHARWD R 0.200001)
+ (CHARHT R 0.700001)
+ (CHARDP R 0.1)
+ (CHARIC R 0.1)
+ (NEXTLARGER O 202)
+ )
+(CHARACTER C b
+ (CHARWD R 0.3)
+ (CHARHT R 0.8)
+ (CHARDP R 0.200001)
+ (NEXTLARGER C M)
+ )
+(CHARACTER C p
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C q C r)
+ (/LIG/> C r C t)
+ (LIG C t C t)
+ )
+ )
+(CHARACTER C q
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG/ C u C p)
+ (/LIG/ C s C r)
+ (KRN C t R 0.1)
+ (/LIG> C r C t)
+ (/LIG/ C p C s)
+ (KRN C s R 0.3)
+ )
+ )
+(CHARACTER C r
+ (CHARWD R 0.0)
+ (COMMENT
+ (LIG/ C u C q)
+ (/LIG C q C u)
+ )
+ )
+(CHARACTER C s
+ (CHARWD R 0.0)
+ (COMMENT
+ (LIG/> C p C q)
+ (KRN C r R 0.1)
+ )
+ )
+(CHARACTER C t
+ (CHARWD R 0.0)
+ (COMMENT
+ (KRN O 0 R -1.0)
+ (KRN O 0 R -0.01)
+ (KRN O 0 R -0.02)
+ (KRN O 0 R -0.03)
+ (KRN O 0 R -0.04)
+ (KRN O 0 R -0.05)
+ (KRN O 0 R -0.06)
+ (KRN O 0 R -0.07)
+ (KRN O 0 R -0.08)
+ (KRN O 0 R -0.09)
+ (KRN O 0 R -0.1)
+ (KRN O 0 R -0.11)
+ (KRN O 0 R -0.12)
+ (KRN O 0 R -0.13)
+ (KRN O 0 R -0.14)
+ (KRN O 0 R -0.15)
+ (KRN O 0 R -0.16)
+ (KRN O 0 R -0.17)
+ (KRN O 0 R -0.18)
+ (KRN O 0 R -0.19)
+ (KRN O 0 R -0.2)
+ (KRN O 0 R -0.21)
+ (KRN O 0 R -0.22)
+ (KRN O 0 R -0.23)
+ (KRN O 0 R -0.24)
+ (KRN O 0 R -0.25)
+ (KRN O 0 R -0.26)
+ (KRN O 0 R -0.27)
+ (KRN O 0 R -0.28)
+ (KRN O 0 R -0.29)
+ (KRN O 0 R -0.3)
+ (KRN O 0 R -0.31)
+ (KRN O 0 R -0.32)
+ (KRN O 0 R -0.33)
+ (KRN O 0 R -0.34)
+ (KRN O 0 R -0.35)
+ (KRN O 0 R -0.36)
+ (KRN O 0 R -0.37)
+ (KRN O 0 R -0.38)
+ (KRN O 0 R -0.39)
+ (KRN O 0 R -0.4)
+ (KRN O 0 R -0.41)
+ (KRN O 0 R -0.42)
+ (KRN O 0 R -0.43)
+ (KRN O 0 R -0.44)
+ (KRN O 0 R -0.45)
+ (KRN O 0 R -0.46)
+ (KRN O 0 R -0.47)
+ (KRN O 0 R -0.48)
+ (KRN O 0 R -0.49)
+ (KRN O 0 R -0.5)
+ (KRN O 0 R -0.51)
+ (KRN O 0 R -0.52)
+ (KRN O 0 R -0.53)
+ (KRN O 0 R -0.54)
+ (KRN O 0 R -0.55)
+ (KRN O 0 R -0.56)
+ (KRN O 0 R -0.57)
+ (KRN O 0 R -0.58)
+ (KRN O 0 R -0.59)
+ (KRN O 0 R -0.6)
+ (KRN O 0 R -0.61)
+ (KRN O 0 R -0.62)
+ (KRN O 0 R -0.63)
+ (KRN O 0 R -0.64)
+ (KRN O 0 R -0.65)
+ (KRN O 0 R -0.66)
+ (KRN O 0 R -0.67)
+ (KRN O 0 R -0.68)
+ (KRN O 0 R -0.69)
+ (KRN O 0 R -0.7)
+ (KRN O 0 R -0.71)
+ (KRN O 0 R -0.72)
+ (KRN O 0 R -0.73)
+ (KRN O 0 R -0.74)
+ (KRN O 0 R -0.75)
+ (KRN O 0 R -0.76)
+ (KRN O 0 R -0.77)
+ (KRN O 0 R -0.78)
+ (KRN O 0 R -0.79)
+ (KRN O 0 R -0.8)
+ (KRN O 0 R -0.81)
+ (KRN O 0 R -0.82)
+ (KRN O 0 R -0.83)
+ (KRN O 0 R -0.84)
+ (KRN O 0 R -0.85)
+ (KRN O 0 R -0.86)
+ (KRN O 0 R -0.87)
+ (KRN O 0 R -0.88)
+ (KRN O 0 R -0.89)
+ (KRN O 0 R -0.9)
+ (KRN O 0 R -0.91)
+ (KRN O 0 R -0.92)
+ (KRN O 0 R -0.93)
+ (KRN O 0 R -0.94)
+ (KRN O 0 R -0.95)
+ (KRN O 0 R -0.96)
+ (KRN O 0 R -0.97)
+ (KRN O 0 R -0.98)
+ (KRN O 0 R -0.99)
+ (KRN O 0 R -1.0)
+ (KRN O 0 R -1.01)
+ (KRN O 0 R -1.02)
+ (KRN O 0 R -1.03)
+ (KRN O 0 R -1.04)
+ (KRN O 0 R -1.05)
+ (KRN O 0 R -1.06)
+ (KRN O 0 R -1.07)
+ (KRN O 0 R -1.08)
+ (KRN O 0 R -1.09)
+ (KRN O 0 R -1.1)
+ (KRN O 0 R -1.11)
+ (KRN O 0 R -1.12)
+ (KRN O 0 R -1.13)
+ (KRN O 0 R -1.14)
+ (KRN O 0 R -1.15)
+ (KRN O 0 R -1.16)
+ (KRN O 0 R -1.17)
+ (KRN O 0 R -1.18)
+ (KRN O 0 R -1.19)
+ (KRN O 0 R -1.2)
+ (KRN O 0 R -1.21)
+ (KRN O 0 R -1.22)
+ (KRN O 0 R -1.23)
+ (KRN O 0 R -1.24)
+ (KRN O 0 R -1.25)
+ (KRN O 0 R -1.26)
+ (KRN O 0 R -1.27)
+ (KRN O 0 R -1.28)
+ (KRN O 0 R -1.29)
+ (KRN O 0 R -1.3)
+ (KRN O 0 R -1.31)
+ (KRN O 0 R -1.32)
+ (KRN O 0 R -1.33)
+ (KRN O 0 R -1.34)
+ (KRN O 0 R -1.35)
+ (KRN O 0 R -1.36)
+ (KRN O 0 R -1.37)
+ (KRN O 0 R -1.38)
+ (KRN O 0 R -1.39)
+ (KRN O 0 R -1.4)
+ (KRN O 0 R -1.41)
+ (KRN O 0 R -1.42)
+ (KRN O 0 R -1.43)
+ (KRN O 0 R -1.44)
+ (KRN O 0 R -1.45)
+ (KRN O 0 R -1.46)
+ (KRN O 0 R -1.47)
+ (KRN O 0 R -1.48)
+ (KRN O 0 R -1.49)
+ (KRN O 0 R -1.5)
+ (KRN O 0 R -1.51)
+ (KRN O 0 R -1.52)
+ (KRN O 0 R -1.53)
+ (KRN O 0 R -1.54)
+ (KRN O 0 R -1.55)
+ (KRN O 0 R -1.56)
+ (KRN O 0 R -1.57)
+ (KRN O 0 R -1.58)
+ (KRN O 0 R -1.59)
+ (KRN O 0 R -1.6)
+ (KRN O 0 R -1.61)
+ (KRN O 0 R -1.62)
+ (KRN O 0 R -1.63)
+ (KRN O 0 R -1.64)
+ (KRN O 0 R -1.65)
+ (KRN O 0 R -1.66)
+ (KRN O 0 R -1.67)
+ (KRN O 0 R -1.68)
+ (KRN O 0 R -1.69)
+ (KRN O 0 R -1.7)
+ (KRN O 0 R -1.71)
+ (KRN O 0 R -1.72)
+ (KRN O 0 R -1.73)
+ (KRN O 0 R -1.74)
+ (KRN O 0 R -1.75)
+ (KRN O 0 R -1.76)
+ (KRN O 0 R -1.77)
+ (KRN O 0 R -1.78)
+ (KRN O 0 R -1.79)
+ (KRN O 0 R -1.8)
+ (KRN O 0 R -1.81)
+ (KRN O 0 R -1.82)
+ (KRN O 0 R -1.83)
+ (KRN O 0 R -1.84)
+ (KRN O 0 R -1.85)
+ (KRN O 0 R -1.86)
+ (KRN O 0 R -1.87)
+ (KRN O 0 R -1.88)
+ (KRN O 0 R -1.89)
+ (KRN O 0 R -1.9)
+ (KRN O 0 R -1.91)
+ (KRN O 0 R -1.92)
+ (KRN O 0 R -1.93)
+ (KRN O 0 R -1.94)
+ (KRN O 0 R -1.95)
+ (KRN O 0 R -1.96)
+ (KRN O 0 R -1.97)
+ (KRN O 0 R -1.98)
+ (KRN O 0 R -1.99)
+ (KRN O 0 R -2.0)
+ (KRN O 0 R -2.01)
+ (KRN O 0 R -2.02)
+ (KRN O 0 R -2.03)
+ (KRN O 0 R -2.04)
+ (KRN O 0 R -2.05)
+ (KRN O 0 R -2.06)
+ (KRN O 0 R -2.07)
+ (KRN O 0 R -2.08)
+ (KRN O 0 R -2.09)
+ (KRN O 0 R -2.1)
+ (KRN O 0 R -2.11)
+ (KRN O 0 R -2.12)
+ (KRN O 0 R -2.13)
+ (KRN O 0 R -2.14)
+ (KRN O 0 R -2.15)
+ (KRN O 0 R -2.16)
+ (KRN O 0 R -2.17)
+ (KRN O 0 R -2.18)
+ (KRN O 0 R -2.19)
+ (KRN O 0 R -2.2)
+ (KRN O 0 R -2.21)
+ (KRN O 0 R -2.22)
+ (KRN O 0 R -2.23)
+ (KRN O 0 R -2.24)
+ (KRN O 0 R -2.25)
+ (KRN O 0 R -2.26)
+ (KRN O 0 R -2.27)
+ (KRN O 0 R -2.28)
+ (KRN O 0 R -2.29)
+ (KRN O 0 R -2.3)
+ (KRN O 0 R -2.31)
+ (KRN O 0 R -2.32)
+ (KRN O 0 R -2.33)
+ (KRN O 0 R -2.34)
+ (KRN O 0 R -2.35)
+ (KRN O 0 R -2.36)
+ (KRN O 0 R -2.37)
+ (KRN O 0 R -2.38)
+ (KRN O 0 R -2.39)
+ (KRN O 0 R -2.4)
+ (KRN O 0 R -2.41)
+ (KRN O 0 R -2.42)
+ (KRN O 0 R -2.43)
+ (KRN O 0 R -2.44)
+ (KRN O 0 R -2.45)
+ (KRN O 0 R -2.46)
+ (KRN O 0 R -2.47)
+ (KRN O 0 R -2.48)
+ (KRN O 0 R -2.49)
+ (KRN O 0 R -2.5)
+ (KRN O 0 R -2.51)
+ (KRN O 0 R -2.52)
+ (KRN O 0 R -2.53)
+ (KRN O 0 R -2.54)
+ (KRN O 0 R -2.55)
+ (KRN O 0 R -2.56)
+ (KRN O 0 R -2.57)
+ (/LIG/>> C r C s)
+ (/LIG/ C p C s)
+ (KRN C s R 0.3)
+ )
+ )
+(CHARACTER C u
+ (CHARWD R 0.0)
+ (COMMENT
+ (/LIG C Z C p)
+ (LIG C p C r)
+ )
+ )
+(CHARACTER O 202
+ (CHARWD R 0.400001)
+ )
diff --git a/Master/texmf-doc/doc/english/knuth/trip.tex b/Master/texmf-doc/doc/english/knuth/trip.tex
new file mode 100644
index 00000000000..a9205e52d5e
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/trip.tex
@@ -0,0 +1,448 @@
+% This is a diabolical test file for TeX82. Watch your step.
+\immediate\catcode `{ = 1 \endlinechar=13
+\catcode `} = 2
+\catcode `$ = 3 {\catcode`$13\gdef\dol{$}}
+\catcode `& = 4
+\let\paR=\par
+\let\%=\relax
+\outer\xdef\par{\catcode `\% 14}
+ % this line should change % from type 5 to type 14
+\let\par=\paR \defaulthyphenchar=`- \defaultskewchar=256
+\ifx\initex\undefined \def\initex{} % next lines are skipped if format loaded
+ \catcode `# = 6 \catcode `U=\catcode`# % # for parameters
+ \catcode `^ = 7 \catcode `| = 8 % ^ for superscripts and | for subscripts
+ \catcode `~ = 9 % ~ will be ignored
+ \catcode `* = 10 % * will be like a space
+ \catcode `E = 12 % E is not a letter
+ \catcode`\@ = 15 % @ will be invalid
+ \catcode `^^A = 0008 % this is another way to get a subscript
+ \catcode `\^^@ = 11 % a strange letter will be allowed
+ \catcode `\^^? = \badness % and so will a strange escape delimiter
+ \fontdimen12\nullfont=13pt % give the null font more parameters
+ \font\trip = trip\relax % see TRIP.PL for details of this font
+ ^^?trip \font\smalltrip=trip scaled 500 % this will be our symbols font
+ \global\fontdimen22\smalltrip 7pt % the axis height
+ \textfont2=\smalltrip \scriptfont2 \smalltrip \scriptscriptfont2 \smalltrip
+ \nonstopmode\lccode256-0\mathchardef\a="8000\def\a{ SCALED 3~2769}
+ \font\rip=trip\a % font \rip will be the same as \trip
+ \skewchar\rip=`B \countdef\countz % \countz will be \count0
+ \def\on{1} \toksdef\tokens=256 \show\errorstopmode
+ \showthe\font \showthe\pageshrink \showthe\pagegoal
+ \font\bigtr^^@p=trip at20pt\textfont3=\bigtr^^@p % this will be extension font
+ \skip200 = 10pt plUs5fil\ifdim\hsize<\hsize\fi lllminus 0 fill
+ \setbox200=\vbox{\hrule\vskip\skip200} \wd200-2pt \setbox100=\hbox{A}
+ \skipdef\shkip100\shkip -18pt plus\catcode`\}fil minus 10fil
+ \advance\shkip by \skip200 \dimen33=3pt \count33=-\dimen33
+ \divide\shkip by \count33
+ \multiply\shkip by \count33 % so \skip100=-6pt plus 3filll minus 9fil
+ \count200 -5 \multiply\count200 by -100 % \count200 is 500
+ \count100=1000000 \divide\count100 by \count200 % \count100 is 2000
+ \dimen100=,00152587890625in % (100/65536)in = 7227sp
+ \multiply\dimen100 by 65536 \divide\dimen100 by 9 % \dimen100 is 803pt
+ \lineskip 0pt plus 40pt
+ \baselineskip=10pt plus 41pt
+ \parskip -0pt plus 42pt minus 8pt
+ \splittopskip 1pt plus 43pt
+ \splitmaxdepth -2pt \boxmaxdepth 1000pt
+ \belowdisplayskip 3pt plus 44pt minus\baselineskip \abovedisplayskip3pt
+ \abovedisplayshortskip 1pt plus 45pt minus\dimen100
+ \belowdisplayshortskip -\count33sp plus 46pt
+ \global\mathchardef\minus"232D % mathbin, family 3, character "2D (-)
+ \thinmuskip 1mu plus 2fill minus 3mu
+ \medmuskip 2mu minus 3mu
+ \thickmuskip -4mu
+ \def\gobble#1{} \floatingpenalty 100 \holdinginserts1
+ \everypar{A\insert200{\baselineskip400pt\splittopskip\count15pt\hbox{\vadjust
+ {\penalty999}}\hbox to -10pt{}}\showthe\pagetotal\showthe\pagegoal
+ \advance\count15by1\mark{\the\count15}\splitmaxdepth-1pt
+ \paR\gobble} % this aborts every paragraph abruptly
+ \def\weird#1{\csname\expandafter\gobble\string#1 \string\csname\endcsname}
+ \message{\the\output\weird\one on line \the\inputlineno}
+ \hyphenpenalty 88 \exhyphenpenalty 89 \badness
+ \clubpenalty 125 \widowpenalty 125 \displaywidowpenalty -125
+ \brokenpenalty 37
+ \interlinepenalty -125
+ \doublehyphendemerits 1000
+ \finalhyphendemerits 100000
+ \mag 2000 \righthyphenmin=1000000000
+ \delimiterfactor 10 \delimitershortfall 190pt
+ \showboxbreadth 55 \showboxdepth 9999 \chardef\nul0\def\0{\nul}
+ \tracingstats=4 \tracinglostchars=2 \tracingparagraphs\day \tracingpages\year
+ \chardef\?=`b \lccode`A=1 \let\^^bbb \hyphenchar\trip=1
+ \language-1\hyphenation\relax{b-\?-\char`b -\^^bb-^^62-^^" -t- }\lccode`149
+ {\everypar{\parindent\\\looseness-1}\skipdef\\8\language\?\\.01014pt\patterns
+ {0111}\emergencystretch9pt\language255\patterns{\the\\} % \patterns{.01015pt}
+ {\language256\patterns{0111 \?50AA1b3 *1AcA. bb bb1 0B2B0 b1c}} % *==space
+ \pretolerance-1\setbox0=\hbox{11}\setbox0=\hbox{\hbadness100\valign{#\cr
+ \hskip-9pt7A\righthyphenmin0\setlanguage\?\unhbox0{*\language`b11\noboundary}
+ 1Z1pts\patterns{q9q} -\0qq \showlists{\language\?\noboundary111}%
+ \hyphenchar\rip=`-\cr}}\patterns{toolate}\showbox0}
+ \showboxbreadth 9999\lefthyphenmin=2\righthyphenmin=3
+ \nulldelimiterspace --+.1pt \mathcode`q="3171
+ \scriptspace\if00-0.\fi\ifnum'\ifnum10=10 12="\fi
+ A 01p\ifdim1,0pt<`^^Abpt\fi\fi % this boils down to -0.01pt
+ \overfullrule 5pt \voffset-2pt
+ \def\sh{\ifnum\count4>10\else\dimen5=\count4pt
+ \advance\dimen5 by 10pt
+ \xdef\a{\a\the\count4pt \the\dimen5}
+ \advance\count4 by 1 \sh\fi}
+ \count4=1 \def\a{} \sh % \def\a{1pt 11pt 2pt 12pt ... 10pt 20pt}
+ \let\next=\dump \everyjob{\message{#}}
+\else\let\next=\relax\fi
+\next % if no format was preloaded, this will dump the trip.fmt file and halt
+\tracingcommands2\tracingrestores+2\write-1{log file only\the\prevgraf}
+\openout-'78terminal \openout10=tr\romannumeral1 \gobble\newcs pos
+\write10{} % writing three lines on tripos.tex (the first line is empty)
+\write10{\uppercase{\number{\outputpenalty}}} % 0{\outputpenalty} + error
+\write10{[\uppercase{\romannumeral-\the\outputpenalty}[} % "mmmmmmmmmm" (-10000)
+\vsize 2000pt
+\vbadness=1
+\topskip 20pt plus 1fil
+\penalty -12345 % this will be ignored since the page is still empty
+\maxdepth=2pt
+\tracingoutput\on
+\moveleft20pt\copy200
+\moveright20pt\hbox{\vrule depth20pt height-19pt width1pt}
+\penalty-10000 % now we'll compute silently for awhile, after default output
+\batchmode\output={\tracingcommands0\showthe\outputpenalty
+ \showboxbreadth 9999 \showboxdepth 9999 \hoffset1sp
+ {\setbox 254=\box255\shipout\ifvbox2\ifhbox254 \error\fi54\copy25\fi4}
+ \ifvoid 254\relax\else\error\fi
+ }
+\setbox255\vbox{}
+\dimen200=10000pt
+{\output{\dimen 9=\ht200\count5=\dimen9\global\countz=\outputpenalty
+ \ifnum\holdinginserts>0\global\holdinginserts0\unvbox255\penalty\countz
+ \else\setbox255\copy255 % at end of group, \box255 reverts to former value
+ \shipout\hbox{\box100\box200\vsplit 255 to 55pt}
+ \unvcopy255\showlists\showthe\insertpenalties\showthe\pageshrink
+ \globaldefs1\halign{#\tabskip\lineskip\cr}
+ \showboxdepth1\showboxbreadth2\fi
+ \message{\topmark:\firstmark:\botmark:\splitfirstmark:\splitbotmark}}
+ \insert100{\def\box{\vbox to 267.7pt{}} \vskip0pt plus 1fil
+ \baselineskip 0pt \lineskip 0pt minus .4pt
+ \box \penalty-101 \box \penalty-100 \box \penalty-1000
+ } % since \dimen100=803pt<3*267.7pt, the insertion splits;
+ % and the natural height+depth of the split-off part is 267.7pt;
+ % now since \count100=2000,
+ % this insertion adds about 535.4pt to the current page
+ \topskip1pt plus 44pt
+ \vbox spread 1000pt{} % beginning of new page
+ \insertpenalties=-50\penalty12345
+ \cleaders\hbox{\lower2pt\vbox to 17pt{}
+ \leaders\hrule\hskip10pt
+ \cleaders\hbox{A}\hskip 9pt % the A is 2pt wide
+ \leaders\hbox{A}\hskip 9pt
+ \xleaders\hbox{A}\hskip 9pt
+ \write111{\help} % \write will be ignored in leaders
+ }\vskip50pt minus 10pt
+ \mark{alpha}
+ AAA\everypar=\errhelp % because of previous \everypar, this makes 3 paragraphs
+ % and each paragraph consists of A\insert 200{400pt of stuff}\mark{n}
+ % but \count200=500 so the inserts are rated 200pt each
+ % so the third insertion will be split
+ \kern-50pt
+ A\hfill\vadjust{\newlinechar128\special{^^80\the\prevdepth}\penalty-5000}%
+ \penalty-1000000000 % forces line break in paragraph
+ % this is not the end of paragraph
+ A\par\insert200{\vskip10000pt\floatingpenalty3}% this insert will be held over
+ \pagefilstretch-1pt\showthe\insertpenalties\penalty99999999\showlists
+ \showthe\pagefilllstretch\vskip 1000pt\penalty-333\hbox to 23pt{} % output now
+ \vsize.pt\global\vsize=16383.99999237060546875pt % page size \approx infinity
+ } % now we revert to the former output routine
+{\tracingoutput-2\tracingstats1\shipout\hbox{\closeout10\closeout-10}}
+\showthe\everypar
+\everypar{}\showthe\everypar
+\def\showlonglists{{\tracingcommands0\pagefillstretch-1\dimen100
+ \showboxbreadth 9999 \showboxdepth 9999 \showlists \pagegoal=10000pt}}
+\tracingmacros=1
+\def\t12#101001#{-.#1pt} \let\T=\t
+\dimendef\varunit=222\varunit=+1,001\ifdim.5\mag>0cc0\fi1pt
+\ifdim -0.01001\varunit=\t120100101001001{\relax}\else\error\fi
+\countz=-1
+\ifodd\count0\advance\countz by -1\fi
+\penalty -12345 % output the remaining stuff
+\tracingmacros\tracingstats % the next part tests line-break computations
+% the two competing ways to set the paragraph have respective demerits
+% (30+l)^2+(30+l)^2+a and (51+l)^2+l^2, where a=adjdemerits, l=linepenalty
+\adjdemerits=782
+\linepenalty=1
+\def\1#1{\hbox to#1pt{}}
+\valign{\baselineskip20ptplus1pt\global\parfillskip0pt
+ \global\global\leftskip4pt
+ \rightskip-1pt
+ \global\hsize13pt
+ \setbox2\12
+ \noindent\copy2\hskip2pt plus5pt minus1pt
+ \copy2\hskip5pt minus2pt
+ \lower2pt\11\hskip3pt % this affects depth of the second line
+ \copy2 \hskip2pt plus.5pc
+ \box2#\cr
+ \noalign{\spacefactor=2000\global\xspaceskip=-1pt}
+ \noalign{ \vrule width0pt{ }}
+ \cr % set that paragraph with a=782, l=1 (demerits 2704 vs 2705)
+ \adjdemerits=784 \cr % increase a, so the second alternative is better
+ \linepenalty=2\hbadness=51\cr % increase l by 1, suppress diagnostic typeout
+ \noalign{ \spacefactor=1}}\message{\the\spacefactor}
+{\hsize1000pt\par\parindent1pt\indent}\leftskip3pt\def\?{\vrule width-2pt
+ \hbox spread2pt{}}\noindent\indent\hbox spread2pt{\hskip0pt plus-1bp}%
+\discretionary{\?AAAB}{\?B-}{\?/A\kern2pt}\unkern % the widths are 7pt, 4pt, 6pt
+\showthe\lastkern\vbox{\hrule width 6pt} \par % should set with nothing overfull
+\penalty-22222 % end of demerits test, hyphenation is next
+\looseness-10
+\uchyph=1
+\hsize 100pt
+A /A\char`A BBBBCACAC//% that becomes /k[AA]k[BB]k[BB][CA][CA][C/]/,
+ % where [] means a ligature and k means a kern.
+ % the word "aabbbbcaca" should be hyphenated to "aa1b3b2b2b1c1aca",
+ % which becomes {[AA]k-||[AA]k}{B-|[BB]kBk|[BB][BB]}{-||}{C-|A|[CA]}[CA]
+ % if I use the notation {x|y|z} for \discretionary{x}{y}{z}.
+\vadjust{\uchyph=0\ BBBBBB}% underfull box will show no hyphens
+\vadjust{\ \closeout1BBBBBB}{\hyphenchar\trip`C}% this time we get hyphens
+\hyphenation{BbB-BbB}\vadjust{\ BBBBBB\kern0ptB}% different hyphens
+\hyphenchar\rip`-\vadjust{\def\B{B}\ \pretolerance10000 B\B BBBB} % no hyphens
+
+\hbox{\sfcode`B=1234AB aB }\noindent \scriptscriptfont3 \smalltrip
+$$\eqno^{}$\scriptfont3=\rip\fontdimen2\smalltrip=0pt
+{\rightskip0pt plus 104pt minus 100fil
+ \looseness 5 \spaceskip 4pt plus 2pt minus 1fil
+ A\spacefactor32767\discretionary{}{\kern2pt-}{B\kern2pt} C$ \scriptfont2=\trip
+ \mathsurround143pt$ C $\mathsurround40pt$$\mathsurround60pt\hbox{$$}$\par}
+\uccode`m=`A\font\mumble=mumble\input tripos % "AAAAAAAAAA"+errors
+\par\penalty-33333 % end hyphenation, math is next
+{\catcode`?=13 \font?xyzzy at0pt\font ? xyzzy scaled1?} % nonexistent
+\font\enorm=trip at 2047.999992370605468749999 pt
+\font\ip trip at -10pt % through the looking glass
+\showthe$
+\showthe\font
+\message{\fontname\ip}
+\rip
+\textfont1=\font \scriptfont1=\smalltrip \scriptscriptfont1=\bigtr^^@p % [sick]
+\def\symbolpar #1*#2*#3*{\global\fontdimen#1\smalltrip = #3 pt}
+{\tracingmacros-1
+ \symbolpar8 num1 9.1
+ \symbolpar9 num2 9.2
+ \symbolpar10 num3 9.3
+ \symbolpar11 denom1 3.1
+ \symbolpar12 denom2 3.2
+ \symbolpar13 sup1 8.1
+ \symbolpar"E sup2 8.2
+ \symbolpar15 sup3 8.3
+ \symbolpar16 sub1 4.1
+ \symbolpar17 sub2 4.2
+ \symbolpar18 supdrop 0.3
+ \symbolpar19 subdrop 0.4
+ \symbolpar20 delim1 10
+ \symbolpar21 delim2 20
+ }
+\mathcode`+='20457 % mathbin, family 1, character '57 (/)
+\mathcode`=="322D % mathrel, family 2, character "2D (-)
+\delcode`["161361 % small (family 1, character "61 (a)), large (3,"61)
+\catcode`(=13 \catcode`(=13 \mathcode`y"7320\mathcode`z"8000
+\def({\delimiter"4162362 }{\catcode`z=13\global\let z=(}
+\parshape 10 \a \chardef\x200
+\hangindent- \parshape pt\hangafter-12% \parshape will take precedence
+\begingroup
+\looseness 2
+\rightskip 0pt plus 10fil minus 1sp
+\--\--\char-0-A\- % this makes lines 1 to 3
+$$\number\the\delcode`\relax\over{{{}}}}\pagestretch=-1\pagetotal\showlists
+\begingroup\halign to\the\displaywidth{#&#\crcr\crcr\cr} % makes lines 4--6
+\global\count6=\displayindent
+\predisplaypenalty=101
+\global\postdisplaypenalty-\predisplaysize* \global\setbox=
+\eqno % another error (actually causes two error messages and inserts $$)
+\looseness-2
+$\right\relax\mathchardef\minus="322D % locally \minus is the same as =
+\left.A\over A\abovewithdelims.?\right(+\mskip1A\minus=A+\penalty+1000A
+\relpenalty-2222
+\binoppenalty-3333
+\mathsurround.11em$\x % this formula goes on line 7
+$$ % here we begin a hairy display that covers lines 8 to 10
+\vadjust{\penalty7}\mkern-9mu\the\prevgraf \prevgraf=8 \insert255{\penalty999}
+\x\vcenter spread-2pt{} {\mathaccent"32D {A}}|-
+^{\raise 2pt\hbox{a}\displaystyle\char`+\textstyle}
+\overline{^A A|\minus\mathinner{}^
+ {A \mathchar"141 \char`B^^A{\mathaccent"7161
+ {\mathop A \mathbin A \mathopen A \mathpunct A\mathclose A \mathrel A
+ \global\scriptscriptfont0=\trip
+ \mathaccent"161 {\fam13A9\the\scriptscriptfont-1}}}}}
+\mathop\char`B^\mathchar"143
+\mathop b\nolimits\limits|C
+\mathord \radical"161 % missing { will be inserted
+ {\textstyle\radical"282382{\left(\scriptscriptstyle\mathop{\underline{
+ A\atop\displaystyle A|{A\hfil\over B\nonscript\kern1pt}^=}}
+ \nolimits|{\mathop y\nonscript\textstyle\nonscript\mskip9mu minus1fil
+ \showthe\lastskip B\abovewithdelims(.2pt\displaylimits}^z
+ \discretionary{\showthe\spacefactor-}{\smalltrip A\hss}{\smalltrip A}
+ \right[A}}}
+\let\penalty=\minus \aftergroup\expandafter
+\eqno\aftergroup\relax\scriptstyle\penalty % reader, be alert
+(\mathpunct{AA}
+|{B\fam1-}^{\hbox{A}}{\above9pt{v\overwithdelims..
+ \displaystyle{pq\atopwithdelims((\vrule height 9pt}}
+ \show\penalty \showlonglists
+ $\expandafter$\csname!\endcsname % end of hairy display, missing } inserted
+\parshape=-1 % now the hanging indentation is relevant
+\leftskip \parshape pt plus -10fil
+\spacefactor1\raise1pt\hbox{\special{\the\hangafter} } \penalty-10000
+\showbox0\spacefactor=0
+\write10{\the\spacefactor}\par % it's illegal to \write the space factor
+} % this fails to match \begingroup
+\aftergroup\lccode\aftergroup`\endgroup A`a % this restores \parshape
+\mark{\the\spacefactor} % \spacefactor: not in vertical mode
+$$\global\count7=\predisplaysize
+\mskip18mu minus 18mu \catcode`J=13 \catcode`j=\the\catcode`J \def j{\relax}
+\vtop to\displaywidth{\everydisplay{\global}\vbox to -1sp{}\noindent$$
+ \count9=\predisplaysize\lowercase{AaJ}$\ifvmode$\fi}\hss
+\leqno\mathchardef A\/\left(\over\left(\global\errorcontextlines5$$
+
+\hangindent1pt\par\showthe\hangindent\hangindent 254cm
+\parfillskip 0pt plus 100pt \fontdimen6\the\scriptfont2=-19sp
+\the\fam % begins a paragraph, but there's no 0 in the font
+A \char'202$$\global\count8=\predisplaysize\leqno\kern1009pt$\par
+\showlists {\catcode`!13\global\everyhbox{\def!{}}}
+\count5=\lastskip % \lastskip=3pt (\belowdisplayskip)
+\baselineskip 10pt
+{\sfcode`A=500\vfuzz18pt\everyvbox{ }% overfull \vbox won't be shown: 37-8=11+18
+ \vbox to 11pt{\hsize 10pt\tolerance 1 A A A A A\clubpenalty10000\par
+ \hbadness100\hfuzz 3pt A A A A A\leaders\vrule\hskip5pt\par}
+ \message{\the\badness}}
+\vbox to 10pt{\hbadness 99\hfuzz1pt\hbox to 0pt{\hskip 10pt minus 9pt}
+ \hbadness100\hbox to 10bp{\hskip 0pt plus 10pt}\tracingcommands1
+ \if\the\badness\fi\message{\the\badness}}\lineskiplimit-1pt\everyhbox{}
+\def\space{ } \dimendef\df=188 \dimen188=1pt
+\vbox to 11pt{\tracinglostchars-9 A\/\space\space\ignorespaces\space\space J
+ \vskip2pt\moveleft1pt\vbox to10pt{\boxmaxdepth=-1pt\mark{vii}}\vskip3pt
+ \unskip\setbox22=\lastbox\showthe\lastskip % \lastskip=-1pt (\baselineskip)
+ \unskip\vskip-\lastskip\kern\lastkern\penalty\lastkern\showbox22}
+\showbox22\kern3pt\message{\the\lastkern}\unkern
+\show\botmark \catcode`;13\def;{\setbox`; }
+\lineskiplimit-0.9999 \space\df\space\count9 0
+\vbox\space to 11pt{\accent\x\space\accent\space"42 \def\^^M{\ } ; \char'101
+ A\ \fontdimen 4 \trip = 88 pt\ \spaceskip 2 pt \
+ \vskip 10pt minus 10pt}
+\penalty-2147483647 % that's the largest value TeX will scan
+\penalty-2147483648 % see?
+\tabskip 1009.9sp minus .25cc % and now for alignment tests
+\let\A=\relax\count1=2{\errhelp{all is lost}\errmessage{}}
+\def\d#1\d{#1#1} \looseness-1
+\setbox3=\vtop{\vskip-3mm} % this box has a depth of -3mm
+\halign spread-12.truedd{&#\span\iftrue\A\span\else\span\fi\span&
+ \vbox{\halign to 0pt{\t2\dp3\A\crcr}#A}
+ &\hss\tabskip1ex plus7200bp minus 4\wd4\d#\d\cr % \d#\d becomes (erroneous) ##
+ \global\let\t=\tabskip \spaceskip=4pt minus 1sp
+ \def\A{B}\def\xx{\global\gdef\A{\global\count\count1=####\cr
+ \omit\cr\tabskip}}\expandafter\xx\span % please don't ask what this does
+ A&\omit\valign to -5pt{#&#\cr A\char`}\span\cr{ }\span\cr}\cr
+ \global\edef\A{\uppercase{
+ \message{\fontname\smalltrip\the\font\romannumeral1009}\lowercase{vq}} }
+ \lccode`Q=`b \span\omit$$\span\A&\show\cr\omit\cr
+ \noalign{\global\prevdepth20pt\errmessage{\count2=\the\count2}}
+ \omit\mark{a}&\omit\mark{b}\cr} % \count2 was set to -6mm=-1118806sp
+\errmessage{\prevdepth=\the\prevdepth}
+\penalty-88888 % end alignment test, now miscellaneous error messages
+\newlinechar`Y\global\unskip\show^^Y\newlinechar\lastpenalty\unpenalty\unkern
+\lastbox\penalty5\message{\the\lastpenalty\the\newlinechar}\textfont16=\relax
+\outer\def{}?
+\dimen5=-'7777777777sp\showthe\dimen5 % this should be OK
+\dimen6=-'40000pt\showthe\dimen6 % this should overflow
+\dimen7=.51\dimen5\showthe\dimen7 \multiply\dimen7 2\showthe\dimen7
+\a^^@^^@a@ % an undefined control sequence followed by invalid character
+{\aftergroup\gobble\aftergroup\c\gdef\b{\c} \def\c{} \b} % \c undefined
+\def\b#1\par{}
+\outer\gdef\a^^@^^@a#1\par#2{}\tokens{\a^^@^^@a\par!
+\long\gdef\l#1{}
+\outer\global\long\edef\lo#1#2U3#4#5#6#7#8#8#9#{\relax}
+\ifcase 1 \undefined\or\l\par\b{\par % occurrence of \par aborts \b
+\b{\l\undefined}\par\else\b{\par}\fi % but not there!
+\ifcase\iftrue-1a\else\fi \ifcase0\fi\else\ifcase5\fi\fi
+\catcode`^^C = 6 % another parameter symbol
+\let\^^C=\halign
+\def\^^@^^C{}
+\^^C{{\span\ifcase3 \lo#\cr............89{}\cr} % runaway preamble?
+\def\a^^C1{\d#1\d\l{#2}\l#1\par\a^^@^^@a#1\par# % runaway in definition; #2 bad
+\xdef\a^^C1{\d#1\d\l{#2}\l#1\par\a^^@^^@a#1\par# % runaway in definition; #2 OK!
+\T^^?a^^@^^@a\par{\lo\par % runaway in use
+\lo\par\par\par P \par\par\par\par\par\par89{} \muskip3=-\thickmuskip
+\muskipdef\shmip=3 \shmip=5mu plus \muskip3minus.5\shmip \showthe\shmip
+{\advance\shmip by \shkip\endlinechar-1
+\divide\shmip by \shkip\endlinechar`}
+\global\multiply\shmip by 2
+\showthe\shmip
+\div^^)de\count88
+By ^^p \toks1={\a\test}
+^\leaders\vrule\mskip\shmip M\leaders\hrule\nonscript\hskip\thinmuskip
+
+{\setbox3\hbox{\vfill\vsplit 3 0pt}
+\def\a#2{}
+\show A
+\show\a^^@^^@a
+\show (
+\message{\meaning\lo\noexpand\lo}
+\show\^^C
+\show\batchmode
+\show\error
+\showthe\output
+\showthe\thinmuskip
+\showthe\fontdimen1\enorm
+\ifx T\span\else\par\if\span\else\else\else\fi\fi
+\ifdim72p\iftrue t1i\fi n\fi\fi \message{\jobname\ifx\lo\lo OK}\fi
+\hangindent 2pt
+{\if 11 \prevgraf=-1\if 0123\error\else\relax\fi\else\error\fi
+ \prevgraf1\global\hangafter=2}\showthe\hangafter\showthe\prevgraf
+\char'203\showthe\prevgraf$\indent\mark{twain}
+\setbox3\hbox{\vrule}&\moveleft\lastbox % can't do that in math mode
+\unhbox234\unhcopy3\accent\x\vfill\vfil\vfilneg\vss % \vfill exits, \vss bad
+\def\a}{\let\a\xyzzy\csname a\endcsname}
+\def\a{ab
+
+ \c}\def\b{ab*\par\c}\let\c\b \def\b{\a\c} \ifx\a\ifx \.
+\else\expandafter\ifx\b \ifinner\error\else\relax\fi\else\error\fi\fi
+\ifvmode$\ifmmode\hbox tt\ifhmode\hfilneg\else\error\fi}$\fi\fi % missing {
+\noalign\omit\endcsname % these are extra
+\fontdimen 1000=20\varunit\showthe\fontdimen1000\trip\let\PAR=\par
+\gdef\par{\relax\PAR}\expandafter\ifx\csname xyzzy\endcsname\relax \mag=1999
+
+\fi\noindent{\halign to 1truemm\expandafter{\csname#\endcsname#&#&\l{#}\cr
+ \global\futurelet\endt\foo&\show\endt&$&&&.}
+
+\hbox{\/\hrule\textfont3=\enorm\prevdepth\advance\xspaceskip by-\xspaceskip
+ \spacefactor2000{ }\everymath{\radical"3}\fontdimen2\rip=0pt
+ $62{}\delimiterfactor1600\left(Aa\right\delimiter"300$AA\/}
+\openin 15 tripos\closein 15\iftrue{\ifeof 15\openin 100 tripos
+ \def\loop{\ifeof 0\let\loop=\relax\else{\global\read0to \a}\show\a\fi\loop}
+ \catcode`015\catcode`[1\outer\def\uppercase{}\loop}\else\fi
+}\def\test#1{\let\test= }\test. \show\test
+\def\a#1{\ifcat#1 \message\ifx#1 {\iffalse\fi\the\tokens\fi\fi}}
+\pretolerance-1\tokens\toks1\unhbox16\par\everycr{\noalign{\penalty97}}
+\the\tokens\ifcase1\or\ifeof\fi\def\stopinput{\error\let\input\die}
+\let\lb={\let\rb=}\halign\relax{\span\iffalse}\fi\cr#&\ifnum0=`{\fi\cr\cr}
+\let\e\expandafter\def\trap#1{}\def\unbalanced{\halign\lb}\unbalanced#\cr
+ \relax\e\e\e\err\e\e\e\endt\e\trap\cr\noexpand\cr}
+
+\expandafter\stopinput\input tripos\endinput\input % one line of tripos
+\setbox10=\vbox to8192pt{\hbox{\hbox{\vadjust{A}}}}\vrule\unhbox10\hrule
+\output{\showthe\deadcycles\global\advance\countz by1\global\globaldefs-1
+ \gdef\local{}\unvbox255\end\rb}\futurelet\dump\maxdeadcycles=3\show\dump
+\catcode`q=7 \catcode`\qqM=0 \expandafter\let\csname^^Mendcsname=\^^@\relax
+\relax\catcode`\qq1qM=13 \defqqM{\relax}#\begingroup{\showboxdepth=4\showbox10}
+
+\long\def\l#1\l{#1}\immediate\write10{\string\caution \l} % living dangerously
+\escapechar`|\tracingoutput0\shipout\vbox{\copy10qq5e^5cbox10}
+\setbox9\hbox{\fontdimen8\rip 0pt % \over becomes \atop in \scriptstyle
+ \afterassignment\relax\advance\prevdepth\afterassignment\relax\futurelet\x
+ \message{\noexpand\l\meaning\l\the\skewchar\ip}\vbox{\hyphenchar\ip-1%
+ \-\ BBBBBB\par\hyphenchar\ip`?\-\ BBBBBB}\if$\expandafter\noexpand\dol\fi%
+ \expandafter\expandafter\noexpand\undefined\noexpand\expandafter%
+ $\begingroup\mathop{\vbox{\vss}}\limits^\mathchoice{}a}{A|{}}{\mathchoice}
+ {}{\relax{}{B\over}\endgroup\showlonglists$}\showboxbreadth9\showboxdepth9
+\showbox9\PAR{\output{}\penalty-10001\deadcycles=2}\scrollmode%
+\hbox{\write-100000{\if01{\else unbal}\fi}\showlists\tracingonline1%
+\escapechar127\global\tracingoutput1\global\escapechar256\end
+% things not tested:
+% interaction (error insertion/deletion, interrupts, \pausing, files not there)
+% system-dependent parsing of file names, areas, extensions
+% certain error messages, especially fatal ones
+% things that can't happen in INITEX
+% unusual cases of fixed-point arithmetic
diff --git a/Master/texmf-doc/doc/english/knuth/tripman.tex b/Master/texmf-doc/doc/english/knuth/tripman.tex
new file mode 100644
index 00000000000..7634c8c9e78
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/tripman.tex
@@ -0,0 +1,413 @@
+% The TRIP manual: How to validate TeX --- last updated by D E Knuth on 4 Dec 89
+\font\eighttt= cmtt8
+\font\eightrm= cmr8
+\font\titlefont= cmr7 scaled\magstep5
+\let\mc=\eightrm
+\rm
+\let\mainfont=\tenrm
+
+\def\.#1{\hbox{\tt#1}}
+\def\\#1{\hbox{\it#1\/\hskip.05em}} % italic type for identifiers
+
+\parskip 2pt plus 1pt
+\baselineskip 12pt plus .25pt
+
+\def\verbatim#1{\begingroup \frenchspacing
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =\active \catcode`\^^M=\active
+ \tt \def\par{\ \endgraf} \obeylines \obeyspaces
+ \input #1 \endgroup}
+% a blank line will be typeset at the end of the file;
+% if you're unlucky it will appear on a page by itself!
+{\obeyspaces\global\let =\ }
+
+\output{\shipout\box255\global\advance\pageno by 1} % for the title page only
+\null
+\vfill
+\centerline{\titlefont A torture test for \TeX}
+\vskip 18pt
+\centerline{by Donald E. Knuth}
+\centerline{Stanford University}
+\vskip 6pt
+\centerline{({\sl Version 3, January 1990\/})}
+\vfill
+\centerline{\vbox{\hsize 4in
+\noindent Programs that claim to be implementations of \TeX82 are
+supposed to be able to process the test routine contained in this
+report, producing the outputs contained in this report.}}
+\vskip 24pt
+{\baselineskip 9pt
+\eightrm\noindent
+The preparation of this report was supported in part by the National Science
+Foundation under grants IST-8201926 and MCS-8300984,
+and by the System Development Foundation.
+`\TeX' is a trademark of the American Mathematical Society.
+
+}\pageno=0\eject
+
+\output{\shipout\vbox{ % for subsequent pages
+ \baselineskip0pt\lineskip0pt
+ \hbox to\hsize{\strut
+ \ifodd\pageno \hfil\eightrm\firstmark\hfil
+ \mainfont\the\pageno
+ \else\mainfont\the\pageno\hfil
+ \eightrm\firstmark\hfil\fi}
+ \vskip 10pt
+ \box255}
+ \global\advance\pageno by 1}
+\let\runninghead=\mark
+\outer\def\section#1.{\noindent{\bf#1.}\quad
+ \runninghead{\uppercase{#1} }\ignorespaces}
+
+\section Introduction.
+People often think that their programs are ``debugged'' when large applications
+have been run successfully. But system programmers know that a typical large
+application tends to use at most about 50 per cent of the instructions
+in a typical compiler. Although the other half of the code---which tends
+to be the ``harder half''---might be riddled with errors, the system seems
+to be working quite impressively until an unusual case shows up on the
+next day. And on the following day another error manifests itself, and so on;
+months or years go by before certain parts of the compiler are even
+activated, much less tested in combination with other portions of the system,
+if user applications provide the only tests.
+
+How then shall we go about testing a compiler? Ideally we would like to
+have a formal proof of correctness, certified by a computer.
+This would give us a lot of confidence,
+although of course the formal verification program might itself be incorrect.
+A more serious drawback of automatic verification is that the formal
+specifications of the compiler are likely to be wrong, since they aren't
+much easier to write than the compiler itself. Alternatively, we can
+substitute an informal proof of correctness: The programmer writes his or
+her code in a structured manner and checks that appropriate relations
+remain invariant, etc. This helps greatly to reduce errors, but it cannot
+be expected to remove them completely; the task of checking a large
+system is sufficiently formidable that human beings cannot do it without
+making at least a few slips here and there.
+
+Thus, we have seen that test programs are unsatisfactory if they are simply
+large user applications; yet some sort of test program is needed because
+proofs of correctness aren't adequate either. People have proposed schemes
+for constructing test data automatically from a program text, but such
+approaches run the risk of circularity, since they cannot assume that a
+given program has the right structure.
+
+I have been having good luck with a somewhat different approach,
+first used in 1960 to debug an {\mc ALGOL} compiler. The idea is to
+construct a test file that is about as different from a typical user
+application as could be imagined. Instead of testing things that people
+normally want to do, the file tests complicated things that people would
+never dare to think of, and it embeds these complexities in still
+more arcane constructions. Instead of trying to make the compiler do the
+right thing, the goal is to make it fail (until the bugs have all been found).
+
+To write such a fiendish test routine, one simply gets into a nasty frame
+of mind and tries to do everything in the unexpected way. Parameters
+that are normally positive are set negative or zero; borderline cases
+are pushed to the limit; deliberate errors are made in hopes that the
+compiler will not be able to recover properly from them.
+
+A user's application tends to exercise 50\%\ of a compiler's logic,
+but my first fiendish tests tend to improve this to about 90\%. As the
+next step I generally make use of frequency-counting software to identify
+the instructions that have still not been called upon. Then I add ever more
+fiendishness to the test routine, until more than 99\%\ of the code
+has been used at least once. (The remaining bits are things that
+can occur only if the source program is really huge, or if certain
+fatal errors are detected; or they are cases so similar to other well-tested
+things that there can be little doubt of their validity.)
+
+Of course, this is not guaranteed to work. But my experience in 1960 was
+that only two bugs were ever found in that {\mc ALGOL} compiler after it
+correctly translated that original fiendish test. And one of those bugs
+was actually present in the results of the test; I simply had failed to
+notice that the output was incorrect. Similar experiences occurred later
+during the 60s and 70s, with respect to a few assemblers, compilers,
+and simulators that I wrote.
+
+This method of debugging, combined with the methodology of structured
+programming and informal proofs (otherwise known as careful desk checking),
+leads to greater reliability of production software than any other
+method I know. Therefore I have used it in developing \TeX82, and the
+main bulk of this report is simply a presentation of the test program
+that was used to get the bugs out of \TeX.
+
+Such a test file is useful also after a program has been debugged, since
+it can be used to give some assurance that subsequent modifications don't
+mess things up.
+
+The test file is called \.{TRIP.TEX}, because of my warped sense of humor:
+\TeX\ is pronounced ``techhh'', so the name reminded me of a
+triptych (and besides, I wanted to take a trip through the program while
+tripping it up, etc.).
+
+The contents of this test file are so remote from what people actually
+do with \TeX, I feel apologetic if I have to explain the correct
+translation of \.{TRIP.TEX}; nobody really cares about most of the
+nitty-gritty rules that are involved. Yet I believe \.{TRIP} exemplifies
+the sort of test program that has outstanding diagnostic ability, as
+explained above.
+
+If somebody claims to have a correct implementation of \TeX, I will not
+believe it until I see that \.{TRIP.TEX} is translated properly.
+I propose, in fact, that a program must meet two criteria before it
+can justifiably be called \TeX: (1)~The person who wrote it must be
+happy with the way it works at his or her installation; and (2)~the
+program must produce the correct results from \.{TRIP.TEX}.
+
+\TeX\ is in the public domain, and its algorithms are published;
+I've done this since I do not want to discourage its use by placing
+proprietary restrictions on the software. However, I don't want
+faulty imitations to masquerade as \TeX\ processors, since users
+want \TeX\ to produce identical results on different machines.
+Hence I am planning to do whatever I can to suppress any systems that
+call themselves \TeX\ without meeting conditions (1) and~(2).
+I have copyrighted the programs so that I have some chance to forbid
+unauthorized copies; I explicitly authorize copying of correct
+\TeX\ implementations, and not of incorrect ones!
+
+The remainder of this report consists of appendices, whose contents ought
+to be described briefly here:
+
+Appendix A explains in detail how to carry out a test of \TeX, given
+a tape that contains copies of the other appendices.
+
+Appendix B is \.{TRIP.TEX}, the fiendish test file that has already
+been mentioned. People who think that they understand \TeX\ are challenged
+to see if they know what \TeX\ is supposed to do with this file.
+People who know only a little about \TeX\ might still find it
+interesting to study Appendix~B, just to get some insights into the
+methodology advocated here.
+
+Appendix C is \.{TRIP.PL}, the property-list description of a
+special font called \.{trip}. This is the only font used by \.{TRIP.TEX}.
+There are no graphic characters associated with \.{trip} that could
+possibly be printed; indeed, \.{TRIP.PL} describes the properties of a font
+that is as weird as the ``document'' described by \.{TRIP.TEX}.
+
+Appendix D is \.{TRIPIN.LOG}, a correct transcript file \.{TRIP.LOG}
+that results if \.{INITEX} is applied to \.{TRIP.TEX}. (\.{INITEX} is
+the name of a version of \TeX\ that does certain initializations;
+this run of \.{INITEX} also creates a binary format file called \.{TRIP.FMT}.)
+
+Appendix E is a correct transcript file \.{TRIP.LOG} that results if
+\.{INITEX} or any other version of \TeX\ is applied to \.{TRIP.TEX}
+with format \.{TRIP.FMT}.
+
+Appendix F is \.{TRIP.TYP}, the symbolic version of a correct output
+file \.{TRIP.DVI} that was produced at the same time as the \.{TRIP.LOG}
+file of Appendix~E.
+
+Appendix G is \.{TRIPOS.TEX}, a short file written out and read in
+by \TeX\ when it processes \.{TRIP.TEX}.
+
+Appendix H is \.{TRIP.FOT}, an abbreviated version of Appendix E that
+appears on the user's terminal during the run that produces \.{TRIP.LOG}
+and \.{TRIP.DVI}.
+
+The debugging of \TeX\ and the testing of the adequacy of \.{TRIP.TEX}
+could not have been done nearly as well as reported here except for
+the magnificent software support provided by my colleague David R. Fuchs.
+In particular, he extended our local Pascal compiler so that
+frequency counting and a number of other important features were added
+to its online debugging abilities.
+
+The method of testing advocated here has one chief difficulty that deserves
+comment: I had to verify by hand that \TeX\ did the right things
+to \.{TRIP.TEX}. This took many hours, and perhaps I have missed
+something (as I did in 1960); I must confess that I have not checked
+every single number in Appendices E and~F. However, I'm willing to pay
+\$327.68 to the first finder of any remaining bug in \TeX, and I will
+be surprised if that bug doesn't show up also in Appendix~E. (I plan to
+write a technical report about all of the errors ultimately found in \TeX; that
+report will tell whether any bugs are discovered between now and~then!)
+
+\vfill\eject
+
+\section Appendix A: How to test \TeX.
+
+\item{0.} Let's assume that you have a tape containing \.{TRIP.TEX},
+\.{TRIP.PL}, \.{TRIPIN.LOG}, \.{TRIP.LOG}, \.{TRIP.TYP}, and \.{TRIP.FOT},
+as in Appendices B, C, D, E, F, and~G. Furthermore, let's suppose that you
+have a working \.{WEB} system, and that you have working programs \.{TFtoPL},
+\.{PLtoTF}, \.{DVItype}, as described in the \TeX ware report.
+
+\item{1.} Use \.{PLtoTF} to convert \.{TRIP.PL} into \.{TRIP.TFM}.
+Then use \.{TFtoPL} to convert \.{TRIP.TFM} into \.{TMP.PL}. Check that
+\.{TMP.PL} is identical to \.{TRIP.PL} (this is a partial test of \.{PLtoTF}
+and \.{TFtoPL}). Install \.{TRIP.TFM} in the standard file area for
+\TeX\ font metric files.
+
+\item{2.} Prepare a special version of \.{INITEX}. (This means that your \.{WEB}
+change file should have {\bf init} and {\bf tini} defined to be null.)
+The {\bf stat} and {\bf tats} macros should also be null, so that
+statistics are kept and other special features are enabled. Set
+\\{mem\_min} and \\{mem\_bot} equal to~1, and set \\{mem\_top} and
+\\{mem\_max} equal to~3000, for purposes of this test version. Also set
+$\\{error\_line}=64$, $\\{half\_error\_line}=32$, and
+$\\{max\_print\_line}=72$; these parameters affect many of the lines of
+the test output, so your job will be much easier if you use the same
+settings that were used to produce Appendix~E. You probably should also
+use the ``normal'' settings of other parameters found in \.{TEX.WEB}
+(e.g., $\\{stack\_size}=200$, $\\{font\_max}=75$, etc.), since these show
+up in a few lines of the test output. Your test version should not
+change the default definition of unprintable characters (\S49 of the program).
+
+\item{3.} Run the \.{INITEX} prepared in step 2. In response to the first
+`\.{**}' prompt, type carriage return (thus getting another `\.{**}').
+Then type `\.{\char`\\input trip}'. You should get an output that matches
+the file \.{TRIPIN.LOG} (Appendix~D). Don't be alarmed by the error
+messages that you see, unless they are different from those in Appendix~D.
+
+\def\sp{{\char'40}}
+\item{4.} Run \.{INITEX} again. This time type `\.{\sp\&trip\sp\sp trip\sp}'.
+(The spaces in this input help to check certain parts of \TeX\ that
+aren't otherwise used.) You should get outputs \.{TRIP.LOG}, \.{TRIP.DVI},
+and \.{TRIPOS.TEX}; there will also be an empty file \.{8TERMINAL.TEX}.
+Furthermore, your terminal should receive output that matches \.{TRIP.FOT}
+(Appendix~H). During the middle part of this test, however, the terminal
+will not be getting output, because \.{\char'134batchmode} is being
+tested; don't worry if nothing seems to be happening for a while---nothing
+is supposed to.
+
+\item{5.} Compare the \.{TRIP.LOG} file from step 4 with the ``master''
+\.{TRIP.LOG} file of step~0. (Let's hope you put that master file in a
+safe place so that it wouldn't be clobbered.) There should be perfect
+agreement between these files except in the following respects:
+
+\itemitem{a)} The dates and possibly the file names will
+naturally be different.
+
+\itemitem{b)} Glue settings in the displays of \TeX\ boxes are subject
+to system-dependent rounding, so slight deviations are permissible. However,
+such deviations apply only to the `\.{glue set}' values that appear at the
+end of an \.{\char'134hbox} or \.{\char'134vbox} line;
+all other numbers should agree exactly, since they are computed with
+integer arithmetic in a prescribed system-independent manner.
+
+\itemitem{c)} The amount of space in kerns that are marked ``for accent''
+are, similarly, subject to system-dependent rounding.
+
+\itemitem{d)} If you had different values for \\{stack\_size}, \\{buf\_size},
+etc., the corresponding capacity values will be different when they
+are printed out at the end.
+
+\itemitem{e)} Help messages may be different; indeed, the author encourages
+non-English help messages in versions of \TeX\ for people who don't
+understand English as well as some other language.
+
+\itemitem{f)} The total number and length of strings at the end may well
+be different.
+
+\itemitem{g)} If your \TeX\ uses a different memory allocation or
+packing scheme or \.{DVI} output logic, the memory usage statistics may change.
+
+\item{6.} Use \.{DVItype} to convert your file \.{TRIP.DVI} to a file
+\.{TRIP.TYP}. The following options should be set when using \.{DVItype}:
+$$\vbox{\halign{#\hfil&\hfil#\cr
+Output level = 2\cr
+Starting page = \.{*.*.*.*.*.*.*.*.*.*}\hskip-20pt\cr
+Number of pages = 1000000&(this is the default)\cr
+Resolution = 7227/100&(this is one point per pixel)\cr
+New magnification = 0&(this is the default)\cr}}$$
+The resulting file should agree with the master \.{TRIP.TYP} file of step~0,
+except that some of the values might be a little off due to floating-point
+rounding discrepancies. Furthermore there may be differences between
+`\\{right}' and `\\w' and `\\x' commands, and between `\\{down}' and `\\y'
+and `\\z'; the key thing is that all characters and rules and \\{xxx}'s should
+be in almost the same positions as specified in Appendix~F.
+(If your \.{DVI}-writing routines differ substantially from those in
+\.{TEX.WEB}, you may want to write a \.{DVIcompare} program that
+detects any substantive differences between two given \.{DVI} files. Such
+a routine would be of general use besides.
+On the other hand, if you have set \\{dvi\_buf\_size} to 800, then your
+\.{DVI} file should be virtually identical to the one supplied.)
+
+\item{7.} You might also wish to test \.{TRIP} with other versions of
+\TeX\ (i.e., \.{VIRTEX} or a production version with other fonts and
+macros preloaded). It should work unless \TeX's primitives have been
+redefined. However, this step isn't essential, since all the code of
+\.{VIRTEX} appears in \.{INITEX}; you probably won't catch any more errors
+this way, unless they would already become obvious from normal use of
+the~system.
+
+\vfill\eject
+
+\section Appendix B: The \.{TRIP.TEX} file.
+The contents of the test routine are prefixed here with line numbers, for
+ease in comparing this file with the error messages printed later; the
+line numbers aren't actually present.
+\runninghead{APPENDIX B: \.{TRIP.TEX} (CONTINUED)}
+
+\vskip 8pt
+\begingroup\count255=0
+\everypar{\global\advance\count255 by 1
+ \hbox to 20pt{\sevenrm\hfil\the\count255\ \ }}
+\verbatim{trip.tex}
+\endgroup
+\vfill\eject
+
+\section Appendix C: The \.{TRIP.PL} file.
+The ``font'' defined here has only a few characters, but they include all
+the complexities that \TeX\ must deal with: ligatures, kerns,
+lists of characters, and extensible characters. Some of the dimensions
+are negative, just to make things worse yet. (The format of property-list
+files like this is explained in the documentation to \.{PLtoTF}, in
+the \TeX ware report.)
+\runninghead{APPENDIX C: \.{TRIP.PL} (CONTINUED)}
+
+\vskip8pt
+\verbatim{trip.pl}
+\vfill\eject
+
+\section Appendix D: The \.{TRIPIN.LOG} file.
+When \.{INITEX} makes the \.{TRIP.FMT} file, it also creates a file called
+\.{TRIP.LOG} that looks like this.
+\runninghead{APPENDIX D: \.{TRIPIN.LOG} (CONTINUED)}
+
+\vskip8pt
+\verbatim{tripin.log}
+\vfill\eject
+
+\section Appendix E: The \.{TRIP.LOG} file.
+Here is the major output of the \.{TRIP} test; it is generated by running
+\.{INITEX} and loading \.{TRIP.FMT}, then reading \.{TRIP.TEX}.
+\runninghead{APPENDIX E: \.{TRIP.LOG} (CONTINUED)}
+
+{\let\tt=\eighttt\leftskip 1in\baselineskip 9pt plus .1pt minus .1pt
+\vskip8pt
+\verbatim{trip.log}
+}
+\vfill\eject
+
+\section Appendix F: The \.{TRIP.TYP} file.
+Here is another major component of the test. It shows the output of \.{DVItype}
+applied to the file \.{TRIP.DVI} that was created at the same time
+Appendix E was produced.
+\runninghead{APPENDIX F: \.{TRIP.TYP} (CONTINUED)}
+
+{\let\tt=\eighttt\leftskip 1in\baselineskip 9pt plus .1pt minus .1pt
+\vskip8pt
+\verbatim{trip.typ}
+}
+\vfill\eject
+
+\section Appendix G: The \.{TRIPOS.TEX} file.
+This short file was written out once and read in twice, during the time
+Appendix E was being produced. There are only three lines, the first of
+which is blank.
+\runninghead{APPENDIX G: \.{TRIPOS.TEX} (CONTINUED)}
+
+\vskip8pt
+\verbatim{tripos.tex}
+\vfill\eject
+
+\section Appendix H: The \.{TRIP.FOT} file.
+This shows what appeared on the terminal while Appendix E was being produced.
+\runninghead{APPENDIX H: \.{TRIP.FOT} (CONTINUED)}
+
+\vskip8pt
+\verbatim{trip.fot}
+
+\vfill\end
diff --git a/Master/texmf-doc/doc/english/knuth/web.tex b/Master/texmf-doc/doc/english/knuth/web.tex
new file mode 100644
index 00000000000..1920be4042b
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/web.tex
@@ -0,0 +1,1477 @@
+% Page layout
+\input webmac
+\output{\setbox0=\box255}\eject % get rid of spurious WEBMAC page
+
+\font\man=manfnt scaled \magstep3 %manfnt
+\font\CompJtitle=cmbx10 scaled\magstep4 %ambx10
+\font\CompJabstract=cmb10 %amb10
+\font\tenssb=cmssdc10 %amssmc10
+\font\tenss=cmss10 %amss10
+\font\tenssi=cmssi10 %amssi10
+\font\eightss=cmss8 %helvetica at 8truebp
+\font\eightssi=cmssi8 %helveticai at 8truebp
+\font\eightssb=cmssq8 %helveticab at 8truebp
+\font\eighttt=cmtt8 %amtt8
+\font\ninerm=cmr9 %amr9
+\let\mc=\ninerm % medium caps for names like PASCAL
+
+\newdimen\pagewidth \newdimen\pageheight \newdimen\ruleht
+\hsize=177mm \vsize=249mm
+\parindent=1em % this is needed for WEB output
+\pagewidth=\hsize \pageheight=\vsize \ruleht=1pt
+\abovedisplayskip=11pt plus 3pt minus 8pt
+\abovedisplayshortskip=0pt plus 3pt
+\belowdisplayskip=11pt plus 3pt minus 8pt
+\belowdisplayshortskip=6pt plus 3pt minus 3pt
+
+\newif\iftitle
+\def\titlepage{\global\titletrue} % for pages without headlines
+
+\def\leftheadline{\hbox to \pagewidth{%
+ \vbox to 8pt{}\hss \eightrm D. E. KNUTH\hss}}
+\def\rightheadline{\hbox to \pagewidth{%
+ \vbox to 8pt{}\hss \eightrm LITERATE PROGRAMMING\hss}}
+\hoffset=-.25in \voffset=-.6in
+
+\newinsert\lefttop \newinsert\righttop
+\count\lefttop=1000 \count\righttop=1000
+\dimen\lefttop=\maxdimen \dimen\righttop=\maxdimen
+\skip\lefttop=25pt plus 3pt minus 3pt
+\skip\righttop=\skip\lefttop
+\def\leftfloat{\insert\lefttop\bgroup
+ \floatingpenalty=0
+ \penalty0
+ \vbox\bgroup}
+\def\rightfloat{\insert\righttop\bgroup
+ \floatingpenalty=0
+ \penalty0
+ \vbox\bgroup}
+\def\endfloat{\egroup\egroup}
+
+\def\onepageout#1{\shipout\vbox{ % here we define one page of output
+ \offinterlineskip % butt the boxes together
+ \vbox to 9mm{ % this part goes on top of the regular pages
+ \iftitle % the next is used for title pages
+ \global\titlefalse % reset the titlepage switch
+ \hbox to\pagewidth{\leaders\CJrule\hfill}
+ \else\ifodd\pageno \rightheadline\else\leftheadline\fi\fi
+ \vfill} % this completes the \vbox to 9mm
+ \vbox to \pageheight{
+ #1 % now insert the main information
+ \boxmaxdepth=\maxdepth
+ } % this completes the \vbox to \pageheight
+ \baselineskip=7mm \lineskiplimit=0pt
+ \hbox to\pagewidth{%
+ \ifodd\pageno\hfil\tenss submitted to THE COMPUTER JOURNAL%
+ \tenssb\quad\folio
+ \else\tenssb\folio\quad
+ \tenss submitted to THE COMPUTER JOURNAL\hfil\fi}
+ }
+ \advancepageno}
+
+\output{\onepageout{\unvbox255}}
+
+\newbox\partialpage
+\def\begindoublecolumns{\begingroup
+ \output={\global\setbox\partialpage=\vbox{\unvbox255}}\eject
+ \output={\doublecolumnout} \hsize=84mm \vsize=510mm}
+\def\enddoublecolumns{\output={\balancecolumns}\eject
+ \endgroup \pagegoal=\vsize}
+
+\def\doublecolumnout{\dimen0=\pageheight
+ \advance\dimen0 by-\ht\partialpage \splittopskip=\topskip
+ \ifdim\ht\lefttop>0pt \setbox255=\vbox{\unvbox\lefttop
+ \setbox0=\lastbox\unvbox0\vskip\skip\lefttop\unvbox255}\fi
+ \setbox0=\vsplit255 to\dimen0
+ \ifdim\ht\righttop>0pt \setbox255=\vbox{\unvbox\righttop
+ \setbox0=\lastbox\unvbox0\vskip\skip\righttop\unvbox255}\fi
+ \setbox2=\vsplit255 to\dimen0
+ \onepageout\pagesofar
+ \unvbox255 \penalty\outputpenalty}
+\def\pagesofar{\unvbox\partialpage
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
+\def\balancecolumns{\setbox0=\vbox{\unvbox255} \dimen0=\ht0
+ \advance\dimen0 by\topskip \advance\dimen0 by-\baselineskip
+ \divide\dimen0 by2 \splittopskip=\topskip
+ {\vbadness=10000 \loop \global\setbox3=\copy0
+ \global\setbox1=\vsplit3 to\dimen0
+ \ifdim\ht3>\dimen0 \global\advance\dimen0 by1pt \repeat}
+ \setbox0=\vbox to\dimen0{\unvbox1}
+ \setbox2=\vbox to\dimen0{\unvbox3}
+ \pagesofar}
+
+\def\CJrule{\hrule height\ruleht}
+\baselineskip=11pt
+\parskip=0pt plus 1pt
+\def\beginsection #1\par{\goodbreak\vskip9mm plus4mm minus 2mm
+ \vbox{\CJrule width \hsize \kern5pt}
+ \kern-3pt
+ \nointerlineskip
+ \leftline{\strut\bf#1}
+ \CJrule
+ \kern12pt\nobreak\noindent\ignorespaces}
+\def\caption #1. #2.{\leftline{\def\TeX{T\kern-.2em\lower.5ex\hbox{E}X}%
+ \tenssb Figure #1.\enspace\tenss#2.}}
+
+\def\WEB{{\tt WEB}}
+\def\PASCAL{{\mc PASCAL}}
+\def\sec{{\tensy x}}
+\def\<{$\langle\,$}
+\def\>{$\,\rangle$}
+\newbox\circlebox
+\setbox\circlebox=\hbox{\man Y}
+\def\encircle#1{\kern6pt\hbox to\wd\circlebox{\hss\tt#1\hss}\kern-\wd\circlebox
+ \raise10pt\copy\circlebox\kern6pt}
+
+\def\ttverbatim{\begingroup \tt \parindent=0pt \obeylines
+ \uncatcodespecials \catcode`/=0 \obeyspaces}
+\let\endverbatim=\endgroup
+{\obeyspaces\global\let =\ } % let active space = control space
+\def\uncatcodespecials{\def\do##1{\catcode`##1=12 }\dospecials}
+\def\cvdots{\kern3pt\qquad\smash\vdots}
+
+\newcount\refno \newif\ifshowit
+\def\ref{\showittrue\makeref}
+\def\silentref{\showitfalse\makeref}
+\def\references{} % this will grow until it holds all the references
+\def\makeref#1#2{\advance\refno by1 \edef#1{{\the\refno}}%
+ \toks0=\expandafter{\references}%
+ {\def\rm{\eightss}\def\sl{\eightssi}\def\bf{\eightssb}\def\tt{\eighttt}%
+ \def\TeX{T\kern-.2em\lower.5ex\hbox{E}\kern-.000em X}%
+ \xdef\references{\the\toks0 \noexpand\item{\the\refno.}#2\par}}%
+ \ifshowit\edef\next{\spacefactor=\the\spacefactor\space}%
+ $^{\the\refno}$\next\fi}
+\hyphenation{Dijk-stra}
+\hyphenchar\tentt=-1 % no hyphenation in the typewriter font
+
+\titlepage
+\leftline{\kern13mm\CompJtitle Literate Programming}
+\kern6mm
+\CJrule
+\kern4.5mm
+\leftline{\kern13mm\bf Donald E. Knuth}
+\kern2pt
+\leftline{\kern13mm\eightrm Computer Science Department, Stanford University,
+ Stanford, CA 94305, USA}
+\kern4mm
+\CJrule
+\kern6mm
+\leftline{\kern13mm\vbox{\hsize=151mm\CompJabstract\noindent
+The author and his associates have been experimenting for the past several
+years with a programming language and documentation system called \WEB.
+This paper presents \WEB\ by example, and discusses why the new
+system appears to be an improvement over previous ones.}}
+\bigskip\bigskip
+\begindoublecolumns
+
+\beginsection A. INTRODUCTION
+
+The past ten years have witnessed substantial improvements in programming
+methodology. This advance, carried out under the banner of ``structured
+programming,'' has led to programs that are more reliable and easier to
+comprehend; yet the results are not entirely satisfactory. My purpose
+in the present paper is to propose another motto that may be appropriate
+for the next decade, as we attempt to make further progress in the
+state of the art. I believe that the time is ripe for significantly
+better documentation of programs, and that we can best achieve this by
+considering programs to be {\it works of literature}. Hence, my title:
+``Literate Programming.''
+
+Let us change our traditional attitude to the construction of programs:
+Instead of imagining that our main task is to instruct a {\it computer\/}
+what to do, let us concentrate rather on explaining to {\it human beings\/}
+what we want a computer to do.
+
+The practitioner of literate programming can be regarded as an essayist, whose
+main concern is with exposition and excellence of style. Such an author,
+with thesaurus in hand, chooses the names of variables carefully and explains
+what each variable means. He or she strives for a program that is
+comprehensible because its concepts have been introduced in an order that
+is best for human understanding, using a mixture of formal and informal
+methods that re\"\i nforce each other.
+
+I dare to suggest that such advances in documentation are possible because
+of the experiences I've had during the past several years while working
+intensively on software development. By making use of several ideas that
+have existed for a long time, and by applying them systematically in a
+slightly new way, I've stumbled across a method of composing programs
+that excites me very much. In fact, my enthusiasm is so great that I must warn
+the reader to discount much of what I shall say as the ravings of a fanatic
+who thinks he has just seen a great light.
+
+Programming is a very personal activity, so I can't be certain that what has
+worked for me will work for everybody. Yet the impact of this new approach on
+my own style has been profound, and my excitement has continued unabated
+for more than two years. I~enjoy the new methodology so much that it is hard
+for me to refrain from going back to every program that I've ever written
+and recasting it in ``literate'' form. I~find myself unable to resist working
+on programming tasks that I would ordinarily have assigned to student
+research assistants; and why? Because it seems to me that at last I'm able
+to write programs as they should be written. My programs are not only
+explained better than ever before; they also are better programs,
+because the new methodology encourages me to do a better job. For these
+reasons I am compelled to write this paper, in hopes that my experiences
+will prove to be relevant to others.
+
+I must confess that there may also be a bit of malice in my choice of
+a title. During the 1970s I was coerced like everybody else into adopting
+the ideas of structured programming, because I couldn't bear to be found
+guilty of writing {\it unstructured\/} programs. Now I have a chance
+to get even. By coining the phrase ``literate programming,'' I am imposing
+a moral commitment on everyone who hears the term; surely nobody wants
+to admit writing an {\it il{}literate\/} program.
+
+\beginsection B. THE \WEB\ SYSTEM
+
+I hope, however, to demonstrate in this paper that the title is not merely
+wordplay. The ideas of literate programming have been embodied in a language
+and a suite of computer programs that have been developed at Stanford
+University during the past few years as part of my research on algorithms
+and on digital typography. This language and its associated programs
+have come to be known as the \WEB\ system. My goal in what follows is
+to describe the philosophy that underlies \WEB, to present examples
+of programs in the \WEB\ language, and to discuss what may be the future
+implications of this work.
+
+I chose the name \WEB\ partly because it was one of the few three-letter
+words of English that hadn't already been applied to computers. But as time
+went on, I've become extremely pleased with the name, because I~think
+that a complex piece of software is, indeed, best regarded as a {\it web\/}
+that has been delicately pieced together from simple materials. We
+understand a complicated system by understanding its simple parts, and by
+understanding the simple relations between those parts and their immediate
+neighbors. If we express a program as a web of ideas, we can emphasize
+its structural properties in a natural and satisfying way.
+
+\WEB\ itself is chiefly a combination of two other languages:
+(1)~a document formatting language and (2)~a programming language.
+My prototype \WEB\ system uses \TeX\ as the document formatting
+language and \PASCAL\ as the programming language, but the same
+principles would apply equally well if other languages were
+substituted. Instead of \TeX, one could use a language like Scribe
+or Troff; instead of \PASCAL, one could use {\mc ADA}, {\mc ALGOL},
+{\mc LISP}, {\mc COBOL}, {\mc FORTRAN}, {\mc APL}, {\mc C}, etc., or
+even assembly language. The main point is that \WEB\ is inherently
+bilingual, and that such a combination of languages proves to be much
+more powerful than either single language by itself. \WEB\ does not
+make the other languages obsolete; on the contrary, it enhances them.
+
+I naturally chose \TeX\ to be the document formatting language, in the
+first \WEB\ system, because \TeX\ is my own creation;\ref\TeXbook{D. E. Knuth,
+{\sl The \TeX book}. Addison-Wesley, Reading, Mass., U.S.A. (1983).}
+I wanted to acquire a lot of experience in harnessing \TeX\ to a variety
+of different tasks. I~chose \PASCAL\ as the programming language because
+it has received such widespread support from educational institutions all
+over the world; it is not my favorite language for system programming, but
+it has become a ``second language'' for so many programmers that it
+provides an exceptionally effective medium of communication. Furthermore
+\WEB\ itself has a macro-processing ability that makes \PASCAL's
+limitations largely irrelevant.
+
+Document formatting languages are newcomers to the computing scene, but
+their use is spreading rapidly. Therefore I'm confident that we will be
+able to expect each member of the next generation of programmers to be
+familiar with a document language as well as a programming language,
+as part of their basic education. Once a person knows both of the
+underlying languages, there's no trick at all to learning \WEB, because
+the \WEB\ user's manual is fewer than ten pages long.
+
+A \WEB\ user writes a program that serves
+as the source language for two different system routines. (See Figure~1.)
+One line of processing is called {\it weaving\/} the web; it produces
+a document that describes the program clearly and that facilitates program
+maintenance. The other line of processing is called {\it tangling\/} the
+web; it produces a machine-executable program. The program and its
+documentation are both generated from the same source, so they are
+consistent with each other.
+
+\bigskip
+\centerline{\vbox{
+ \halign{&\hss#\hss\cr
+ &&&\TeX\cr
+ \noalign{\vskip-4pt}
+ &&\encircle{TEX}&\enspace\rightarrowfill\enspace&\encircle{DVI}\cr
+ \multispan2\hfil\smash{\raise4pt\hbox{\tt WEAVE}\kern-1pt}$\nearrow$ \cr
+ \noalign{\vskip6pt}
+ \encircle{WEB}\cr
+ \noalign{\vskip6pt}
+ \multispan2\hfil\smash{\lower6pt\hbox{\tt TANGLE}\kern-1pt}$\searrow$ \cr
+ &&\encircle{PAS}&\enspace\rightarrowfill\enspace&\encircle{REL}\cr
+ \noalign{\vskip-2pt}
+ &&&\mc\ PASCAL\ \cr}
+ }}
+\nobreak\medskip
+\caption 1. Dual usage of a {\tt WEB} file.
+\bigbreak
+
+Let's look at this process in slightly more detail. Suppose you have
+written a \WEB\ program and put it into a computer text file called
+{\tt COB.WEB} (say). To generate hardcopy documentation for your program,
+you can run the {\tt WEAVE} processor; this is a system program that takes
+the file {\tt COB.WEB} as input and produces another file {\tt COB.TEX}
+as output. Then you run the \TeX\ processor, which takes {\tt COB.TEX}
+as input and produces {\tt COB.DVI} as output. The latter file,
+{\tt COB.DVI}, is a ``device-independent'' binary description of how
+to typeset the documentation, so you can get printed output by applying
+one more system routine to this file.
+
+You can also follow the other branch of Figure~1, by running the
+{\tt TANGLE} processor; this is a system program that takes the file
+{\tt COB.WEB} as input and produces a new file {\tt COB.PAS} as output.
+Then you run the \PASCAL\ compiler, which converts {\tt COB.PAS} to
+a binary file {\tt COB.REL} (say). Finally, you can run your program
+by loading and executing {\tt COB.REL}. The process of ``compile, load,
+and go'' has been slightly lengthened to ``tangle, compile, load, and go.''
+
+\beginsection C. A COMPLETE EXAMPLE
+
+Now it's time for me to stop presenting general platitudes and to move on
+to something tangible. Let us look at a real program that has been written
+in \WEB. The numbered paragraphs that follow are the actual output of a
+\WEB\ file that has been ``woven'' into a document; a computer has also
+generated the indexes that appear at the program's end. If my claims for
+the advantages of literate programming have any merit, you should be able
+to understand the following description more easily than you could
+have understood the same program when presented in a more conventional
+way. However, I am trying here to explain the format of \WEB\ documentation
+at the same time as I am discussing the details of a nontrivial algorithm,
+so the description below is slightly longer than it would be if it were
+written for people who already have been introduced to \WEB.
+
+\silentref\Dijk{O.-J.~Dahl, E.~W. Dijkstra, and C.~A.~R. Hoare,
+{\sl Structured Programming}. Academic Press, London and New York (1972).}
+\silentref\goto{D. E. Knuth, Structured programming with {\bf go to}
+statements. {\sl Computing Surveys\/ \bf6}, 261--301 (1974).}
+
+Here, then, is the computer-generated output:
+
+\bigskip
+\CJrule
+\medskip
+\begingroup
+\def\prune\input webmac{\input primes.contents}
+\def\Z#1#2#3{\line{\ignorespaces#1\ \dotfill\ {\tensy x}#2}}
+\def\M#1.{\MN#1.\iftrue\medbreak\startsection\ignorespaces}
+\def\firstmod{1}
+\def\N#1.#2.{\MN#1.\iftrue\nobreak
+ \ifx\modno\firstmod\medskip\else\bigskip\fi
+ \CJrule\medbreak\startsection
+ {\bf\ignorespaces#2.\quad}\ignorespaces}
+\def\inx{\par\medbreak
+ \def\:##1, {\par\hangindent2em\noindent##1:\kern1em}
+ \def\[##1]{$\underline{##1}$}
+ \rm \rightskip0pt plus2.5em \tolerance10000 \let\*=\lapstar
+ \hyphenpenalty10000 \parindent0pt}
+\def\fin{\par\bigskip\CJrule\medbreak
+ \parfillskip0pt plus1fil
+ \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}}
+ \def\U{\note{Used in}}
+ \def\:{\par\hangindent 2em}\let\*=*}
+\let\con=\par
+\parskip=0pt
+\expandafter\prune\input primes
+\endgroup
+
+\beginsection D. HOW THE EXAMPLE WAS SPECIFIED
+
+Everything reproduced above, from the table of contents preceding the
+program to the indexes of identifiers and section names at the end,
+was generated by applying the program {\tt WEAVE} to a source file
+{\tt PRIMES.WEB} written in the \WEB\ language. Let us now look at that
+file {\tt PRIMES.WEB}, in order to get an idea of what a \WEB\ user
+actually types.
+
+There's no need to show very much of {\tt PRIMES.WEB}, however, because
+that file is reflected quite faithfully by the formatted output. Figure~2
+contains enough of the \WEB\ source to indicate the general flavor;
+a reader who is familiar with the rudiments of \TeX\ will be able to
+reconstruct all of {\tt PRIMES.WEB} by looking only at the formatted
+output and Figure~2.
+
+\leftfloat
+\ttverbatim
+/hrule
+/medskip
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\WEB{{\tt WEB}}
+\def\PASCAL{{\mc PASCAL}}
+\def\[{\ifhmode\ \fi$[\mkern-2mu[$}
+\def\]{$]\mkern-2mu]$\ }
+/cvdots
+\hyphenation{Dijk-stra}
+/medskip
+@* Printing primes: An example of \WEB.
+The following program is essentially the same
+as Edsger Dijkstra's @^Dijkstra, Edsger@>
+``first example of step-wise program
+composition,'' found on pages 26--39
+of his {\sl Notes on Structured
+Programming},$^\Dijk$ but it has been
+translated into the \WEB\ language. @.WEB@>
+/medskip
+\[Double brackets will be used in what
+follows to enclose comments relating to \WEB\
+/cvdots
+an informal top-level description.\]
+/medskip
+@p @<Program to print the first thousand
+prime numbers@>
+/endverbatim
+\medskip
+\caption 2a. The beginning of {\tt PRIMES.WEB}.
+\medskip
+\hrule
+\endfloat
+
+Figure 2a starts with \TeX\ commands (not shown in full) that make it
+convenient to typeset double brackets $[\mkern-2mu[\ldots]\mkern-2mu]$
+and to give special typographic treatment to names like `\WEB' and `\PASCAL'.
+A \WEB\ user generally begins by declaring such special aspects of the
+document format; for example, if nonstandard fonts of type are needed,
+they are usually stated first. It may also be necessary to specify the
+correct hyphenation of non-English words that appear in the document.
+
+Then comes `{\tt@*}', which starts the program proper. \WEB\ uses the
+symbol `{\tt@}' as an escape character for special instructions to the
+{\tt WEAVE} and {\tt TANGLE} processors. Everything between such special
+commands is either expressed in \TeX\ language or in \PASCAL\ language,
+depending on the context.
+
+Each section of the program begins either with `{\tt@ }' (i.e., at-sign
+and space) or `{\tt@*}' (i.e., at-sign and asterisk); \WEB\ supplies the
+section numbers automatically. The latter case, `{\tt@*}', denotes a
+{\it major section\/} of the program, for which a special title is given.
+This title will appear in boldface type, and it will also appear in the
+table of contents, and as a running headline on all pages of the
+woven documentation until another major section begins. Each major section
+starts at the top of a page. (Such page beginnings have been indicated
+by horizontal lines in our example, because \WEB's normal output format
+has been adapted to the format of this journal. The output of {\tt WEAVE}
+usually has a lot more white space, and the individual lines of text
+are usually quite a bit wider.)
+
+The lines that follow in Figure~2a show a few more \WEB\ instructions:
+`{\tt@\char`^}' marks the beginning of an index entry to be set in roman
+type; `{\tt@>}' marks the end of an argument to a \WEB\ command;
+`{\tt@.}'\ marks the beginning of an index entry to be set in typewriter
+type; `{\tt@p}' marks the beginning of the \PASCAL\ program; and `{\tt@<}'
+marks the beginning of a top-level description, i.e., of a section
+name in the \WEB\ program.
+
+\rightfloat
+\ttverbatim
+/hrule
+/medskip
+@ This program has no input, because we want
+to keep it rather simple. The result of the
+program will be to produce a list of the
+first thousand prime numbers, and this list
+will appear on the |output| file.
+/medskip
+Since there is no input, we declare the value
+|m=1000| as a compile-time constant. The
+program itself is capable of generating the
+first |m| prime numbers for any positive |m|,
+as long as the computer's finite limitations
+are not exceeded.
+/medskip
+\[The program text below specifies the
+``expanded meaning'' of `\X2:Program to print
+$\ldots$ numbers\X'; notice that it involves
+the top-level descriptions of three other
+sections. When those top-level descriptions
+are replaced by their expanded meanings, a
+syntactically correct \PASCAL\ program will
+be obtained.\]
+/medskip
+@<Program to print...@>=
+program print_primes(output);
+const @!m=1000;
+@<Other constants of the program@>@;
+var @<Variables of the program@>@;
+begin @<Print the first |m| prime numbers@>;
+end.
+/endverbatim
+\medskip
+\caption 2b. The \WEB\ code that generated \sec2.
+\ttverbatim
+/bigskip
+/hrule
+/medskip
+@ In order to keep this program reasonably
+free of notations that are uniquely
+\PASCAL esque, \[and in order to illustrate
+/cvdots
+The first three macro definitions here are
+parametric; the other two are simple.\]
+/medskip
+@d print_string(#)==write(#)
+ {put a given string into the |output| file}
+@d print_integer(#)==write(#:1)
+ {put a given integer into the |output|
+ file, in decimal notation, using only as
+ many digit positions as necessary}
+@d print_entry(#)==write(#:ww)
+ {like |print_integer|, but
+ |ww| character positions are filled,
+ inserting blanks at the left}
+@d new_line==write_ln
+ {advance to a new line in the |output| file}
+@d new_page==page
+ {advance to a new page in the |output| file}
+/endverbatim
+\medskip
+\caption 2c. The \WEB\ code that generated \sec6.
+\medskip
+\hrule
+\endfloat
+
+Figure 2b immediately follows Figure~2a in the \WEB\ file. This material
+is what generated \sec2 of the documentation, and it illustrates the
+bilingual nature of \WEB: The commentary at the beginning of each section
+is typed in \TeX\ language, and the program text at the end is typed
+in \PASCAL\ language.
+
+Language-switching between \TeX\ and \PASCAL\ is occasionally desirable.
+For example, when you refer to technical details about the program, you
+usually want to describe them in \PASCAL, hence you want {\tt WEAVE} to format
+them with the typographic conventions it uses for \PASCAL\ programs.
+Conversely, when you put comments in a \PASCAL\ program, you want
+the text of those comments to be formatted by \TeX\ in the normal way.
+\WEB\ files use vertical bars to introduce \PASCAL\ formatting in the
+midst of \TeX\ formatting; for example, Figure~2b says `{\tt the
+|output| file}' in order to typeset `the \\{output} file'.
+
+The program text in Figure~2b begins with `{\tt@<}' instead of with the
+`{\tt@p}' command used in Figure~2a, because the program text in~\sec2
+is the expansion of a specific top-level description. Notice that the
+top-level description has been abbreviated to `{\tt@<Program to print...@>}'.
+Since the names of sections tend to be rather long, it is a nuisance to
+type them in full each time; \WEB\ allows you to type `{\tt...}'\ after you
+have given enough text to identify the remainder uniquely.
+
+The `{\tt@!}'\ operation in the program text of Figure~2b governs the
+underlining of index entries. The `{\tt@;}'\ specifies an invisible symbol
+that has the effect of a semicolon in \PASCAL\ syntax. Commands such as these
+are comparatively unimportant, but they are available for polishing up
+the final documentation when you want to maintain fine control.
+
+Figure 2c shows key portions of the \WEB\ text that generated \sec6.
+Notice that the command `{\tt@d}' introduces a macro definition.
+All features of \WEB\ that appear in our example program are illustrated
+in Figures 2a, 2b, and~2c; the remainder of {\tt PRIMES.WEB} simply
+uses the same conventions again and again. In fact, most of the \WEB\
+file is much simpler than the examples shown here; Figure~2 has
+illustrated only the difficult parts.
+
+\beginsection E. THE TANGLED OUTPUT
+
+Figure 3 shows the \PASCAL\ program {\tt PRIMES.PAS} that results when
+{\tt TANGLE} is applied to {\tt PRIMES.WEB}. This program is not intended
+for human consumption---it's only supposed to be readable by a \PASCAL\
+compiler---so {\tt TANGLE} does not go to great pains to produce a
+beautiful format. Notice that underlines have been removed from the
+identifier names, and that all of the letters have been converted to
+uppercase (except in strings); {\tt TANGLE} tries to produce a format
+that will be acceptable to a standard \PASCAL\ compiler.
+
+{\tt TANGLE} removes all of the commentary in the \WEB\ file, but it
+inserts new comments of its own. If for some reason you need
+to correlate the tangled \PASCAL\ code with the woven documentation,
+you can find the program text for, say, \sec8 by looking between
+the comments `{\tt\char`\{8:\char`\}}' and `{\tt\char`\{:8\char`\}}'.
+
+A comparison of Figure~3 to Figure~2 should make it clear why the
+{\tt TANGLE} processor has acquired its name.
+
+\rightfloat
+\ttverbatim
+/hrule
+/medskip
+{1:}{2:}PROGRAM PRINTPRIMES(OUTPUT);
+CONST M=1000;{5:}RR=50;CC=4;WW=10;{:5}{19:}
+ORDMAX=30;{:19}VAR{4:}
+P:ARRAY[1..M]OF INTEGER;{:4}{7:}
+PAGENUMBER:INTEGER;PAGEOFFSET:INTEGER;
+ROWOFFSET:INTEGER;C:0..CC;{:7}{12:}J:INTEGER;
+K:0..M;{:12}{15:}JPRIME:BOOLEAN;{:15}{17:}
+ORD:2..ORDMAX;SQUARE:INTEGER;{:17}{23:}
+N:2..ORDMAX;{:23}{24:}
+MULT:ARRAY[2..ORDMAX]OF INTEGER;{:24}
+BEGIN{3:}{11:}{16:}J:=1;K:=1;P[1]:=2;{:16}
+{18:}ORD:=2;SQUARE:=9;{:18};
+WHILE K<M DO BEGIN{14:}REPEAT J:=J+2;{20:}
+IF J=SQUARE THEN BEGIN ORD:=ORD+1;{21:}
+SQUARE:=P[ORD]*P[ORD];{:21}{25:}
+MULT[ORD-1]:=J;{:25};END{:20};{22:}N:=2;
+JPRIME:=TRUE;
+WHILE(N<ORD)AND JPRIME DO BEGIN{26:}
+WHILE MULT[N]<J DO MULT[N]:=MULT[N]+P[N]+P[N]
+;IF MULT[N]=J THEN JPRIME:=FALSE{:26};N:=N+1;
+END{:22};UNTIL JPRIME{:14};K:=K+1;P[K]:=J;
+END{:11};{8:}BEGIN PAGENUMBER:=1;
+PAGEOFFSET:=1;
+WHILE PAGEOFFSET<=M DO BEGIN{9:}
+BEGIN WRITE('The First ');WRITE(M:1);
+WRITE(' Prime Numbers --- Page ');
+WRITE(PAGENUMBER:1);WRITELN;WRITELN;
+FOR ROWOFFSET:=PAGEOFFSET TO PAGEOFFSET+RR-1
+DO{10:}
+BEGIN FOR C:=0 TO CC-1 DO IF ROWOFFSET+C*RR<=
+M THEN WRITE(P[ROWOFFSET+C*RR]:WW);WRITELN;
+END{:10};PAGE;END{:9};
+PAGENUMBER:=PAGENUMBER+1;
+PAGEOFFSET:=PAGEOFFSET+RR*CC;END;END{:8}{:3};
+END.{:2}{:1}
+/endverbatim
+\medskip
+\caption 3. PASCAL program generated from the \WEB\ file.
+\medskip
+\hrule
+\endfloat
+
+\beginsection F. THE WOVEN OUTPUT
+
+I mentioned earlier that {\tt WEAVE} is a program that converts a file
+like {\tt PRIMES.WEB} into a file {\tt PRIMES.TEX} that is a syntactically
+correct source file for \TeX. Figure~4 gives a sampling of {\tt PRIMES.TEX},
+which is even more unreadable than {\tt PRIMES.PAS}. The instructions that
+cause \TeX\ to produce formatted \PASCAL\ programs, with appropriate
+typefaces and indentation, etc., are somewhat complex because they are
+supposed to give decent results regardless of the page size.
+
+There is no need to discuss Figure~4 further in the present paper, because
+the details of ``pretty printing'' are not relevant to my main theme.
+I have shown this much of {\tt PRIMES.TEX} only to make the point that
+it is nice to have a program like {\tt WEAVE} to do all the formatting;
+computer programs are not easy to typeset.
+
+\leftfloat
+\ttverbatim
+/hrule
+/medskip
+\input webmac
+\font\ninerm=cmr9
+/cvdots
+syntactically correct \PASCAL\ program will
+be obtained.\]
+/medskip
+\Y\P$\4\X2:Program to print the first
+thousand prime numbers\X\S$\6
+\4\&{program}\1\ \37$\\{print\_primes}(%
+\\{output})$;\6
+\4\&{const} \37$\|m=1000$;\5
+\X5:Other constants of the program\X\6
+\4\&{var} \37\X4:Variables of the program\X\6
+\&{begin} \37\X3:Print the first \|m prime
+numbers\X;\6
+\&{end}.\par
+\U section~1.\fi
+/cvdots
+The first three macro definitions here are
+parametric; the other two are simple.\]
+/medskip
+\Y\P\D \37$\\{print\_string}(\#)\S\\{write}(%
+\#)$\C{put a given string into the %
+\\{output} file}\par
+/cvdots
+\inx
+\:{Bertrand, Joseph, postulate}, 21.
+\:\\{boolean}, 15.
+/cvdots
+\:\.{WEB}, 1.
+\:\\{write}, 6.
+\:\\{write\_ln}, 6.
+\:\\{ww}, \[5], 6.
+\fin
+/cvdots
+\:\X4, 7, 12, 15, 17, 23, 24:Variables of
+the program\X
+\U section~2.
+\con
+/endverbatim
+\medskip
+\caption 4. \TeX\ program generated from the \WEB\ file.
+\medskip
+\hrule
+\endfloat
+
+\beginsection G. ADDITIONAL BELLS AND WHISTLES
+
+A system like \WEB\ can be successful only if it is capable of handling
+large programs as well as small ones, and only if it is complete enough
+to take care of all the practical requirements that arise when many
+different kinds of programs are considered. A small example like
+{\tt PRIMES.WEB} is a satisfactory vehicle for illustrating the general
+ideas, but it cannot be convincing as a demonstration of \WEB's ability
+to produce quality software in the ``real world.'' My original design
+of \WEB\ in September, 1981, was followed by a year of extensive
+experiments, so that by the time Version~1 was released in
+September, 1982, I could be fairly confident that the language was
+reasonably complete. Since then only one or two small extensions
+have proved to be necessary; and although numerous enhancements can
+easily be imagined, I believe that a useful stopping point for a
+working system called {\tt WEB83} has been reached.
+
+A full description of {\tt WEB83} appears in a Stanford report,\ref\WEBman%
+{D. E. Knuth, {\sl The \WEB\kern-2pt\ System of Structured Documentation}.
+Stanford Computer Science Report CS980 (September 1983).}
+which also contains the complete \WEB\ programs for {\tt WEAVE} and
+{\tt TANGLE}. The full language contains only a few features that
+do not show up in the {\tt PRIMES} example considered above:
+
+\def\nindent#1{\noindent\hbox to\parindent{#1)\hfil}\ignorespaces}
+\smallskip
+\nindent1 There are facilities to override {\tt WEAVE}'s
+automatic formatting of \PASCAL\ programs. For example, it is
+possible to force a statement to begin on a new line, or to force
+several statements to appear on the same line, or to suggest
+a desirable breakpoint in the middle of a long expression. In
+unusual cases, {\tt WEAVE} must parse program fragments that
+are not syntactically complete---for example, there may be a
+{\bf begin} without a matching {\bf end}---so a \WEB\ user must
+be given a chance to control the results. Furthermore there is a
+facility for changing {\tt WEAVE}'s formatting rules by declaring
+that a certain identifier should be treated as a certain \PASCAL\
+reserved word, or by declaring that a certain reserved word
+should be treated as an ordinary identifier.
+
+\smallskip
+\nindent2 There is a way to force {\tt TANGLE} to omit a
+space between two adjacent pieces of text, so that a name
+like `\\{x3}' can be manufactured from `\|x' and `\\3'. Similarly,
+there is a way to pass an arbitrary sequence of characters through
+{\tt TANGLE} so that the same sequence will appear ``verbatim'' in
+the \PASCAL\ file; and there is a way to force beginning-of-line
+in that file. The latter extensions have proved to be necessary
+to deal with various nonstandard conventions of different \PASCAL\ compilers.
+When a comment in braces is sent to the \PASCAL\ file, {\tt TANGLE}
+is careful not to introduce further braces inside the comment.
+
+\smallskip
+\nindent3 There are facilities for octal and hexadecimal constants in \WEB\
+thees. {\tt TANGLE} converts such constants to decimal form; {\tt WEAVE} gives
+them an appropriate typographic treatment.
+
+\smallskip
+\nindent4 There is a facility for dealing with alphabetic constants.
+When a program contains a double-quoted character like {\tt"A"},
+{\tt TANGLE} converts this to an integer between 0 and~127 that
+equals the corresponding {\mc ASCII} code (in this case 65).
+The use of {\mc ASCII} code facilitates the construction of software
+that is readily portable from one machine to another, independent of
+the actual character set in use.
+
+\smallskip
+\nindent5 Furthermore, if a double-quoted constant is a string
+of several characters, like {\tt"cat"}, {\tt TANGLE} converts it
+into a unique integer that is 128 or more. A special {\it string pool
+file\/} is written, containing all of the strings that have been
+specially encoded in this way. I have used this general mechanism only
+in large programs, but experience has shown that it makes quite a
+nice substitute for the string-processing capabilities that \PASCAL\
+lacks. (Incidentally, I noticed after several months that a program
+needs to have some indication that the string-pool file it is reading
+contains the same strings that {\tt TANGLE} generated when the program
+itself was tangled. Therefore a ``check sum'' is included in the
+string pool file; each program is able to refer to its own check sum
+and to compare it with the value in the file. This check-sum extension
+was one of the last features to be added to \WEB.)
+
+\smallskip
+\nindent6 The {\tt PRIMES} example illustrates macros with
+parameters and macros without parameters. \WEB\ also allows ``numeric''
+macros, which are small integer constants; {\tt TANGLE} is capable of
+doing simple arithmetic on such constants. This feature of \WEB\ was
+introduced specifically to overcome \PASCAL's unfortunate inability to
+do compile-time arithmetic. For example, it is impossible to have a
+\PASCAL\ array whose bounds are `$0\to n-1$', or to write
+`$20+3:$' as the label of one of the cases in `{\bf case} $x+y$';
+\WEB's numeric macros make it possible for {\tt TANGLE} to
+preprocess such constants.
+
+\beginsection H. OCCAM'S RAZOR
+
+I would also like to mention several things that were intentionally left
+out of \WEB, since I have tried to keep the language as simple as I could.
+
+There are no ``conditional macros,'' nor does {\tt TANGLE}
+evaluate Boolean expressions that might influence the
+output. I~found that everything I needed could be done
+satisfactorily by commenting out the optional code.
+
+For example, a system program is often designed to gather statistics about
+its own operation, but such statistics-gathering is pointless unless someone
+is actually going to use the results. In order to make the instrumentation
+code optional, I include the word `{\bf stat}' just before any special
+code for statistics, and `{\bf tats}' just after such code; and I tell
+{\tt WEAVE} to regard {\bf stat} and {\bf tats} as if they were {\bf begin}
+and {\bf end}. But {\bf stat} and {\bf tats} are actually simple macros.
+When I do want to gather the statistics, I define {\bf stat} and {\bf tats} to
+be null; but in a production version of the software, I make {\bf stat}
+expand to~`{\tt@\char`\{}' and {\bf tats} expand to~`{\tt@\char`\}}',
+where {\tt@\char`\{} and {\tt@\char`\}} are special braces that {\tt TANGLE}
+does not remove. Thus the optional code appears as a harmless comment in
+the \PASCAL\ program.
+
+\WEB's macros are allowed to have at most one parameter. Again, I did this
+in the interests of simplicity, because I noticed that most applications
+of multiple parameters could in fact be reduced to the one-parameter case.
+For example, suppose that you want to define something like
+$$\hbox{\tt mac(\#1,\#2) == m[\#1*r+\#2]}$$
+which \WEB\ doesn't permit. You can get essentially the same result
+with two one-parameter macros
+$$\vbox{\halign{\tt#\hfil\cr
+mac\char`\_tail(\#) == \#]\cr
+mac(\#) == m[\#*r+mac\char`\_tail\cr}}$$
+since, e.g., `{\tt mac(a)(b)}' will expand into `{\tt m[a*r+b]}'.
+
+Here is another example that indicates some of the surprising generality
+of one-parameter macros: Consider the two definitions
+$$\vbox{\halign{\tt#\hfil\cr
+define two\char`\_cases(\#)==case j of\cr
+\ \ \ \ \ \ \ \ \ \ \ \ \ 1:\#(1); 2:\#(2); end\cr
+define reset\char`\_file(\#)==reset(file@\&\#)\cr}}$$
+where `{\tt@\char`\&}' in the second definition is the concatenation operation
+that pastes two texts together. You can now say
+$$\hbox{\tt two\char`\_cases(reset\char`\_file)}$$
+and the resulting \PASCAL\ output will be
+$$\vbox{\halign{\tt#\hfil\cr
+case j of\cr
+1:reset(file1);\cr
+2:reset(file2);\cr
+end\cr}}$$
+In other words, the name of one macro can usefully be a parameter to
+another macro. This particular trick makes it possible to live with
+\PASCAL\ compilers that do not allow arrays of files.
+
+\beginsection I. PORTABILITY
+
+One of the goals of my \TeX\ research has been to produce portable
+software, and the {\tt WEB} system has been extremely helpful in this
+respect. Although my own work is done on a DEC-10 computer with
+Stanford's one-of-a-kind operating system, the software developed
+with \WEB\ has already been transported successfully to a wide
+variety of computers made by other manufacturers (including IBM,
+Control Data, XEROX, Hewlett-Packard), and to a variety
+of different operating systems for those machines. To my knowledge,
+no other software of such complexity has ever been transported to
+so many different machines. It seems likely that \TeX\ will soon be
+operating on all but the smallest of the world's computer systems.
+
+To my surprise, the main bottleneck to portability of the \TeX ware
+has been the lack of suitable \PASCAL\ compilers, because \PASCAL\ has
+often been implemented without system programming in mind. Anybody
+who has a decent \PASCAL\ compiler can install \WEB\ (and all programs
+written in \WEB) without great difficulty, essentially as follows:
+
+\smallskip
+\item{1)} Start with the three files {\tt WEAVE.WEB}, {\tt TANGLE.WEB}, and
+{\tt TANGLE.PAS}. (The programs have not been copyrighted, so
+these files are not difficult to obtain.)
+
+\item{2)} Run {\tt TANGLE.PAS} through your \PASCAL\ compiler to
+get a working {\tt TANGLE} program.
+
+\item{3)} Check your {\tt TANGLE} by applying it to {\tt TANGLE.WEB};
+your output file should match {\tt TANGLE.PAS}.
+
+\item{4)} Apply your {\tt TANGLE} to the file {\tt WEAVE.WEB}, obtaining
+{\tt WEAVE.PAS}; then apply \PASCAL\ to {\tt WEAVE.PAS} and you'll
+have a working {\tt WEAVE} system.
+
+\item{5)} The same process applies to any software written in \WEB,
+notably to \TeX\ itself. (However, you need fonts and suitable output
+equipment in order to make proper use of \TeX; that may be another
+bottleneck.) Once you have \TeX\ working, you can apply {\tt WEAVE}
+and \TeX\ to your \WEB\ files, thereby getting program documents
+as illustrated above.
+
+\smallskip\noindent
+Notice that a {\tt TANGLE.PAS} file is needed in order to get this
+``bootstrapping'' process started. If you have just {\tt WEAVE.WEB}
+and {\tt TANGLE.WEB}, you can't do the first step.
+
+However, anybody who has looked seriously into the question of software
+portability will realize that my comments in the preceding paragraphs
+have been oversimplified. I have glossed over some serious
+problems that arise: Character sets are different; file naming conventions
+are different; special conventions are needed to interact with a user's
+terminal; data is packed differently on different machines; floating-point
+arithmetic is always nonstandard and sometimes nonexistent; users want
+``friendly'' interaction with existing programs for editing and spooling;
+etc., etc. Furthermore, many of the world's \PASCAL\ compilers are incredibly
+bizarre. Therefore it is quite na\"\i ve to believe that a single program
+{\tt TANGLE.PAS} could actually work on very many different machines, or
+even that one single source file {\tt TANGLE.WEB} could be adequate; some
+system-dependent\kern-.5pt\kern.5pt\ changes are inevitable.
+
+The \WEB\ system caters to system-dependent changes in a simple but surprisingly
+effective way that I neglected to mention when I listed its other features.
+Both {\tt TANGLE} and {\tt WEAVE} are designed to work with
+{\it two\/} input files, not just one: In addition to a \WEB\ source file
+like {\tt TEX.WEB}, there is also a ``change file'' {\tt TEX.CH} that
+contains whatever changes are needed to customize \TeX\ for a particular
+system. (Similarly, the source files {\tt WEAVE.WEB} and {\tt TANGLE.WEB}
+are accompanied by {\tt WEAVE.CH} and {\tt TANGLE.CH}.)
+
+Here's how change files work: Each change has the form ``replace
+$x_1\ldots x_m$ by $y_1\ldots y_n$,'' for some $m\ge 1$ and $n\ge0$;
+here $x_i$ and~$y_j$ represent lines in the change file.
+The {\tt WEAVE} and {\tt TANGLE} programs
+read data from the \WEB\ input file until finding a line that matches
+$x_1$; this line, and the $m-1$ following lines, are replaced by
+$y_1\ldots y_n$. An error message is given if the $m$ lines replaced did
+not match $x_1\ldots x_m$ perfectly.
+
+For example, the program {\tt PRIMES.WEB} invokes a \\{page} procedure to
+begin a new page; but \\{page} was not pres\-ent in Wirth's original \PASCAL\
+and it is defined rather vaguely in the \PASCAL\ standard. Therefore
+a system-dependent change may be needed here. A change file {\tt
+PRIMES.CH} could be made by copying the line
+$$\hbox{\tt @d new\char`\_page==page}$$ from
+Figure~2c and specifying one or more appropriate replacement lines.
+
+The program {\tt TANGLE} itself contains about 190 sections, and a
+typical installation will have to change about 15 of these. If you
+want to transport {\tt TANGLE} to a new environment, you therefore
+need to create a suitable file {\tt TANGLE.CH} that modifies 15~or~so parts
+of {\tt TANGLE.WEB}. (Examples of {\tt TANGLE.CH} are provided to
+all people who receive {\tt TANGLE.WEB}, so that each implementor has
+a model of what to do.) You need to insert your changes by hand into
+{\tt TANGLE.PAS}, until you have a {\tt TANGLE} program that works
+sufficiently well to support further bootstrapping. But you never
+actually change the master file {\tt TANGLE.WEB}.
+
+This approach has two important advantages. First, the same
+master file {\tt TANGLE.WEB} is used by everybody, and it
+contains the basic logic of {\tt TANGLE} that really defines the
+essence of tangling. The system-dependent changes do not affect
+any of the subtle parts of {\tt TANGLE}'s control structures or
+data structures. Second, when the official {\tt TANGLE} has been
+upgraded to a newer version, a brand new {\tt TANGLE.WEB} will
+almost always work with the old {\tt TANGLE.CH}, since changes
+are rarely made to the system-dependent parts. In other words,
+this dual-input-file scheme works when the \WEB\ file is constant
+and the {\tt CH} file is modified, and it also works when the
+{\tt CH} file is constant but the \WEB\ file is modified.
+
+Change files were added to \WEB\ about three months after the system was
+initially designed, based on our initial experiences with people who had
+volunteered to participate in portability experiments. We realized
+about a year later that {\tt WEAVE} could be modified so that
+only the changed parts of a program would (optionally) be printed; thus,
+it's now possible to document the changes by listing only the sections
+that are actually affected by the {\tt CH} file that {\tt WEAVE} has
+processed. We also generalized the original format of {\tt CH} files,
+which permitted only changes that extended to the end of a section. These
+two important ideas were among the final enhancements incorporated into
+{\tt WEB83}.
+
+\beginsection J. PROGRAMS AS WEBS
+
+When I first began to work with the ideas that eventually became the
+\WEB\ system, I thought that I would be designing a language for ``top-down''
+programming, where a top-level description is given first and successively
+refined. On the other hand I knew that I often created major parts
+of programs in a ``bottom-up'' fashion, starting with the definitions of
+basic procedures and data structures and gradually building more and
+more powerful subroutines. I had the feeling that top-down and bottom-up
+were opposing methodologies: one more suitable for program exposition
+and the other more suitable for program creation.
+
+But after gaining experience with \WEB, I have come to realize that there is
+no need to choose once and for all between top-down and bottom-up, because
+a program is best thought of as a web instead of a tree. A hierarchical
+structure is present, but the most important thing about a program is
+its structural relationships. A complex piece of software consists of
+simple parts and simple relations between those parts; the programmer's
+task is to state those parts and those relationships, in whatever order
+is best for human comprehension---not in some rigidly determined
+order like top-down or bottom-up.
+
+When I'm writing a longish program like {\tt TANGLE.WEB} or {\tt WEAVE.WEB}
+or {\tt TEX.WEB}, I invariably have strong feelings about what part of the
+whole should be tackled next. For example, I'll come to a point where I need
+to define a major data structure and its conventions, before I'll feel
+happy about going further. My experiences have led me to believe that a
+person reading a program is, likewise, ready to comprehend it by
+learning its various parts in approximately the order in which it
+was written. The {\tt PRIMES.WEB} example illustrates this principle on
+a small scale; the decisions that Dijkstra made as he composed the original
+program$^\Dijk$ appear in the \WEB\ documentation in the same order.
+
+Top-down programming gives you a strong idea of where you are going, but
+it forces you to keep a lot of plans in your head; suspense builds up
+because nothing is really nailed down until the end. Bottom-up programming
+has the advantage that you continually wield a more and more powerful
+pencil, as more and more subroutines have been constructed; but it forces
+you to postpone the overall program organization until the last minute,
+so you might flounder aimlessly.
+
+When I tear up the first draft of a program and start over, my second draft
+usually considers things in almost the same order as the first one did.
+Sometimes the ``correct'' order is top-down, sometimes it is bottom-up,
+and sometimes it's a mixture; but always it's an order that makes sense on
+expository grounds.
+
+Thus the \WEB\ language allows a person to express programs
+in a ``stream of consciousness'' order. {\tt TANGLE} is able to scramble
+everything up into the arrangement that a \PASCAL\ compiler demands. This
+feature of \WEB\ is perhaps its greatest asset; it makes a \WEB-written
+program much more readable than the same program written purely in
+\PASCAL, even if the latter program is well commented. And the fact that there's
+no need to be hung up on the question of top-down versus bottom-up---since
+a programmer can now view a large program as a web, to be explored in
+a psychologically correct order---is perhaps the greatest lesson I have
+learned from my recent experiences.
+
+Another surprising thing that I learned while using \WEB\ was that
+traditional programming languages had been causing me to write inferior
+programs, although I hadn't realized what I was doing. My original idea was that
+\WEB\ would be merely a tool for documentation, but I actually found that
+my \WEB\ programs were better than the programs I had been writing
+in other languages. How could this be?
+
+Well, imagine that you are writing a small subroutine that updates part
+of a data structure, and suppose that the updating takes only
+one or two lines of code. In practical programs, there's often something
+that can go wrong, if the user's input is incorrect, so the subroutine
+has to check that the input is correct before doing the update.
+Thus, the subroutine has the general form
+$$\vbox{\halign{#\hfil\cr
+\&{procedure} \\{update};\cr
+\&{begin if} \<input data is invalid\> \&{then}\cr
+\quad \<Issue an error message and try to recover\>;\cr
+\<Update the data structure\>;\cr
+\&{end}.\cr}}$$
+A subtle phenomenon occurs in traditional programming languages: While
+writing the program for `\<Issue an error message and try to recover\>',
+a programmer subconsciously tries to get by with the fewest possible
+lines of code, since the program for `\<Update the data structure\>' is
+quite short. If an extensive error recovery is actually programmed, the
+subroutine will appear to have error-message printing as its main purpose.
+But the programmer knows that the error is really an exceptional case that
+arises only rarely; therefore a lengthy error recovery doesn't look right,
+and most programmers will minimize it (without realizing that they are doing
+so) in order to make the subroutine's appearance match its intended behavior.
+On the other hand when the same task is programmed with \WEB, the purpose
+of \\{update} can be shown quite clearly, and the possibility of error
+recovery can be reduced to a mere mention when \\{update} is defined.
+When another section entitled `\<Issue an error message and try to
+recover\>' is subsequently written, the whole point of that section is to do
+the best error recovery, and it becomes quite natural to write a better program
+as a result.
+
+This fact---that \WEB\ allows you to let each part of the program have
+its appropriate size, without distorting the readability of other parts---means
+that good programmers find their \WEB\ programs better than their \PASCAL\
+programs, even though their \PASCAL\ programs once looked like the work
+of an expert.
+
+\beginsection K. STYLISTIC ISSUES
+
+I found that my style of using \WEB\ evolved quite a bit during the first
+year. The general format, in which each section beings with commentary and
+ends with a formal program fragment, is extremely versatile; you have the
+freedom to say anything you want, yet you must make a decision about how
+you'll do it. I imagine that different programmers will converge to
+quite different styles, but I would like to note down some of the things
+that have seemed to work best for me.
+
+Consider first the question of macros versus section names. A named section,
+like `\<Issue an error message and try to recover\>', is essentially the
+same as a parameterless macro; \WEB\ provides both. I prefer to use
+parameterless macros for ``small'' things that can be embodied in a word
+or two, but named sections for longer portions of the program that
+merit a fuller description.
+
+I usually start the name of a section with an imperative verb, but I give
+a declarative commentary at the beginning of a section. Thus,
+{\tt PRIMES.WEB} says `{\bf 8.}~Now that appropriate $\ldots$
+\X8:Print table $p$\X$\;\S\;$\dots\thinspace'; I wouldn't do the opposite
+and say `{\bf8.}~Print the table. \X8:Code for printing\X$\;\S\;$\dots'.
+
+The name of a section (enclosed in angle brackets) should be long enough
+to encapsulate the essential characteristics of the code in that section,
+but it should not be too verbose. I found very early that it would be a
+mistake to include all of the assumptions about local and global variables
+in the name of each section, even though such information would strictly
+be necessary to isolate that section as an independent module. The trick is
+to find a balance between formal and informal exposition so that a reader
+can grasp what is happening without being overwhelmed with detail.\ref\Naur%
+{P. Naur, Formalization in program development. {\sl BIT\/ \bf22},
+437--453 (1982).}
+
+Another lesson I learned early in the game was that the name of a section
+should explicitly mention any nonstandard control structures, even though
+its data structures can often be left implied. Furthermore, if the control
+flow is properly explained, you can avoid the usual errors associated
+with \&{goto} statements; such statements can safely be introduced in
+a restrained but natural manner.
+
+For example, \sec14 of the prime-printing example could be reprogrammed as
+follows, using `\&{loop}' as a macro abbreviation for `\&{while} \\{true}
+\&{do}':
+$$\vbox{\halign{\hbox to\hsize{#\hfil}\cr
+\X14:Increase $j$ until it is the next prime number\X$\;\S$\cr
+\quad\&{loop begin} $j\K j+2$;\cr
+\qquad\X20:Update variables that depend on $j$\X;\cr
+\qquad\X22:If $j$ is prime, \&{goto} \\{found}\X;\cr
+\qquad\&{end};\cr
+\\{found}:\cr}}$$
+With this change, \sec22 could become
+$$\vbox{\halign{\hbox to\hsize{#\hfil}\cr
+\X22:If $j$ is prime, \&{goto} \\{found}\X$\;\S$\cr
+\quad$n\K2$;\cr
+\quad\&{while} $n<\\{ord}$ \&{do}\cr
+\qquad\&{begin} \X26:If $p[n]$ is a factor of $j$, \&{goto} \\{not\_found}\X;\cr
+\qquad$n\K n+1$;\cr
+\qquad\&{end};\cr
+\quad\&{goto} \\{found};\cr
+\\{not\_found}:\cr}}$$
+if \sec26 changes in the obvious way. The resulting program will be more
+efficient on most machines; and I believe that it is actually easier to
+read and to write, in spite of the fact that two \&{goto} statements
+appear, because the labels have been used with appropriate interpretations
+of their abstract significance.
+
+Of course, \PASCAL\ makes it difficult to use \&{goto} statements,
+because Wirth decided that labels should be numeric, and that they
+should be declared in advance. If I were to introduce the \&{goto}
+statements as suggested, I would have to define numeric macros
+\\{found} and \\{not\_found}, and I would have to insert
+`\&{label} \\{found}, \\{not\_found}' into the program at the right place.
+Such extra work is a bit of a nuisance, but it can be done in \WEB\ without
+spoiling the exposition.
+
+\PASCAL\ has a few other misfeatures that prove to be inconvenient with
+respect to \WEB\ exposition. The worst of these is the inability to
+declare local variables in the midst of a program or procedure. For
+example, a programmer often finds it most natural to define an integer
+variable when a \&{for} loop is introduced, but the rules of \PASCAL\
+insist that such a variable be declared rather far away from
+that \&{for} loop. My \WEB\ programs overcome this problem by having
+sections like `\<Local variables for \\{xyzzy}\>' whenever there's a
+rather lengthy procedure `\\{xyzzy}' whose local variables should not
+be declared all at once. But when a procedure is short, say only half
+a dozen sections long, there's usually no harm in declaring its local
+variables in \PASCAL\ style, because the entire text of the procedure will
+tend to appear on one or two adjacent pages of the documentation.
+
+Another slightly awkward aspect of \PASCAL\ is its treatment of semicolons.
+If you look closely at the prime-number example, you'll see that I had to
+be a bit careful about where I put semicolons; sometimes they occur at the
+end of the expanded text of a section, but usually they don't. With
+a little self discipline, a person can learn to do this quite satisfactorily,
+but it is a nuisance until you get used to it.
+
+\beginsection L. ECONOMIC ISSUES
+
+What does it cost to use \WEB? Let's look first at the lowest level, where
+computer costs are considered, because it is easy to make quantitative
+statements at this level. The running time to {\tt TANGLE} a \WEB\ file is
+approximately the same as the time needed to compile the resulting
+\PASCAL\ program; hence the extra preprocessing does not cost much.
+Similarly, {\tt WEAVE} doesn't take long to produce a file for \TeX.
+However, \TeX\ needs a comparatively large amount of time to typeset the
+final document. For example, if we assume that each page requires four
+seconds, it will take four minutes to produce a 60-page document. The
+running time for {\tt WEAVE}-plus-\TeX\ is quite reasonable when you
+consider that your program is effectively being
+converted into a fairly substantial booklet; but the costs are sufficiently
+large to discourage remaking and reprinting such a booklet more than once or
+twice a day. When a new program is being developed, it is therefore customary
+to work with hardcopy documentation that is slightly obsolete, and to read
+the \WEB\ source file itself when up-to-date information is required;
+the source file is sufficiently easy to read for such purposes.
+
+The costs of \WEB\ are more difficult to estimate at higher levels, but I have
+found to my surprise that the total time of writing and debugging a \WEB\
+program is no greater than the total time of writing and debugging an
+{\mc ALGOL} or {\mc PASCAL} program, even though my \WEB\ programs are
+much better, and even though I am putting substantially more documentation
+into the programs. Therefore I have lately been using \WEB\ for all of my
+programming, even for one-off jobs that I write ``for my eyes only'' just
+to explore occasional problems. The extra time I spend in preparing additional
+commentary is regained because the debugging time is reduced.
+
+In retrospect, the fact that a ``literate'' program takes much less time to
+debug is not surprising, because the \WEB\ language encourages a discipline
+that I was previously unwilling to impose on myself. I had known for a long
+time that the programs I construct for publication in a book, or the programs
+that I construct in front of a class, have tended to be comparatively free
+of errors, because I am forced to clarify my thoughts as I do the programming.
+By contrast, when writing for myself alone, I have often taken shortcuts that
+proved later to be dreadful mistakes. It's harder for me to fool myself in
+such ways when I'm writing a \WEB\ program, because I'm in ``expository
+mode'' (analogous to classroom lecturing) whenever a \WEB\ is being spun.
+Ergo, less debugging time.
+
+Now that I am writing all my programs in \WEB, an unforeseen problem has,
+however, arisen: I suddenly have a collection of programs that seem quite
+beautiful in my own eyes, and I have a compelling urge to publish all of
+them so that everybody can admire these works of art. A nice little 10-page
+program can easily be written and debugged in an afternoon and evening;
+if I keep accumulating such gems, I'll soon run out of storage space,
+and my office will be encrusted with webs of my own making. There is no
+telling what will happen if lots of other people catch \WEB\ fever and
+start foisting their creations on each other. I can already envision the
+appearance of a new journal, to be entitled {\sl Webs}, for the publication
+of literate programs; I imagine that it will have a large backlog and
+a large group of dedicated editors and referees.
+
+\beginsection M. RELATED WORK
+
+Nothing about \WEB\ is really new; I have simply combined a bunch of
+ideas that have been in the air for a long time. I would like to
+summarize in the next few paragraphs the things that had the greatest
+influence on my thinking as I put those pieces together.
+
+George Forsythe wrote in 1966 that ``A useful algorithm is a substantial
+contribution to knowledge. Its publication constitutes an important
+piece of schol\-ar\-ship.''\ref\GEF{G. E. Forsythe, Algorithms for
+scientific computation. {\sl Communications of the ACM\/ \bf9}, 255--256
+(1966).} His comments have always inspired me to strive for excellence
+in programming, and they have played a major r\^^Dole in shaping my present
+view that it is worthwhile to consider {\it every\/} program as a
+work of literature.
+
+The design of \WEB\ was influenced primarily by the pioneering work
+of Pierre-Arnoul de Marneffe,\ref\deM{P. A. de Marneffe, {\sl Holon
+Programming}. Univ.~de Liege, Service D'Informatique (December, 1973).}$^,$%
+\ref\deMR{P. A. de Marneffe and D. Ribbens, Holon Programming, in
+A. G\"unther et al.\ (eds.), {\sl International Computing Symposium 1973\/},
+Amsterdam, North-Holland (1974).} whose research on what he called
+``Holon Programming'' has not received the attention it deserves. His
+work was, in turn, inspired by Arthur Koestler's excellent treatise
+on the structure of complex systems and organisms;\ref\Koest{A.
+Koestler, {\sl The Ghost in the Machine}. New York, Macmillan (1968).}
+thus we have another connection between programming and literature.
+A somewhat similar system was independently created by Edwin Towster.\ref\Tow%
+{E. Towster, A convention for explicit declaration of environments
+and top-down refinement of data. {\sl IEEE Transactions on Software
+Engineering\/ \bf SE--5}, 374--386 (1979).}
+
+I owe a great debt to Edsger Dijkstra, Tony Hoare, Ole-Johan Dahl, and
+Niklaus Wirth for opening my eyes to the importance of abstraction in the
+reading and writing of programs, and to Peter Naur for stressing the
+importance of a balance between formal and informal methods.
+
+Tony Hoare provided a special impetus for \WEB\ when he suggested in 1978
+that I should publish my program for \TeX. Since very few large-scale
+software systems were available in the literature, he had been trying to
+promote the publication of well-written programs. Hoare's suggestion was
+actually rather terrifying to me, and I'm sure he knew that he was posing
+quite a challenge. As a professor of computer science, I was quite
+comfortable publishing papers about toy problems that could be polished up
+nicely and presented in an elegant manner; but I had no idea how to take a
+piece of real software, with all the compromises necessary to make it
+useful to a large class of people on a wide variety of systems, and to open
+it up to public scrutiny. How could a supposedly respectable academic, like
+me, reveal the way he actually writes large programs? And could a large
+program be made intelligible? My previous attempts along these
+lines\ref\CF{D. E. Knuth, Computer-drawn flow charts. {\sl
+Communications of the ACM\/ \bf 6}, 555--563 (1963).} were by now
+hopelessly out of date. I decided that this would be a good time to try
+out de Marneffe's ideas; furthermore, the \TeX\ system itself provided me
+with new tools for printing and format control, so I suspected that it
+would be possible to obtain state-of-the-art documentation by making
+proper use of typography.
+
+It is interesting to reread some of the comments that Tony made ten years
+ago in his keynote address to the first ACM symposium on Principles
+of Programming Languages:\ref\Hoare{C. A. R. Hoare, {\sl Hints on
+Programming Language Design}. Stanford Computer Science Report CS403
+(October 1973).}
+\smallskip
+{\narrower\noindent
+Documentation must be regarded as an integral part of the process of
+design and coding. A good programming language will encourage and
+assist the programmer to write clear, self-documenting code, and even
+perhaps to develop and display a pleasant style of writing.
+\smallskip}
+\noindent He foresaw many future trends, but not the impending improvements in
+typesetting quality:
+\smallskip
+{\narrower\noindent
+It is of course possible for a compiler or service program to expand the
+abbreviations, fill in the defaults, and make explicit the assumptions.
+But in practice, experience shows that it is very unlikely that the
+output of a computer will ever be more readable than its input, except
+in such trivial but important aspects as improved indentation.
+\smallskip}
+
+Typographic formatting of computer programs has a long tradition, originating
+with {\mc ALGOL} and its immediate precursors. I'm not sure who made the
+first experiments, but I believe that the lion's share of the credit
+for developing excellent programming-language typography belongs to two
+people: Peter Naur, who edited the {\mc ALGOL~60} report\ref\Alg{P. Naur
+(ed.)~et al., Report on the algorithmic language ALGOL 60.
+{\sl Communications of the ACM\/ \bf3}, 299--314.} and gave special
+care to its presentation; and Myrtle Kellington, who served for many years
+as executive editor of ACM publications and set the standards that have
+been adopted by other journals. The computing profession owes much to
+these people, who made published programs so much more readable than they
+would otherwise have been; the magnitude of their contribution can only
+be appreciated by people who submit computer programs to journals
+like {\sl Acta Arithmetica\/} whose editors are unfamiliar with computer
+science. Bill McKeeman called attention to formatting issues when he
+published Algorithm~268, ``{\mc ALGOL~60} reference language editor,''
+in 1965.\ref\McK{W. M. McKeeman, Algorithm 268. {\sl Communications
+of the ACM\/ \bf8}, 667--668 (1965).} There has been a flowering of
+such algorithms in recent years; the papers by Oppen\ref\DO{D. Oppen,
+Prettyprinting. {\sl ACM Transactions on Programming Languages and
+Systems\/ \bf2}, 465--483 (1980).} and by Rose and Welsh\ref\RW{G. A.
+Rose and J. Welsh, Formatted programming languages. {\sl Software---%
+Practice \char'46\ Experience\/ \bf11}, 651--669 (1981).} are particularly
+noteworthy.
+
+I began to design \WEB\ in the spring of 1979, when I constructed a prototype
+system that was called {\tt DOC}. Luis Trabb~Pardo helped me to develop
+a suitable style of exposition at that time; then Ignacio Zabala~Salelles
+gave a {\tt DOC} a thorough test when he prepared a full implementation
+of \TeX\ in \PASCAL. Zabala's implementation was successfully transported
+to many different computers,\ref\Z{I. Zabala and L. Trabb Pardo,
+The status of the PASCAL implementation of \TeX. {\sl TUGboat\/ \bf1},
+16--17 (1980).}\silentref\ZZ{I. Zabala, \TeX-PASCAL and PASCAL compilers.
+{\sl TUGboat\/ \bf2} (1), 11--12 (1981).}\silentref\ZZZ{I. Zabala,
+Some feedback from PTEX installations. {\sl TUGboat\/ \bf2} (2), 16--19
+(1981).}$^-$\ref\ZZZZ{I. A. Zabala, How
+portable is PASCAL? Draft of paper in preparation (1982).}
+and this experience was of immense value to me when I cast \WEB\ into its
+present form in 1981. Since then many significant improvements have been
+suggested by my colleague David R. Fuchs, and I have also benefited from
+the experiences of a large number of outstanding people who volunteered to
+be guinea pigs for pre-released versions of \TeX. It's impossible for me
+to name everyone who has helped, but I would like to give special thanks
+to Arthur Samuel, Howard Trickey, Joe Weening, and Pierre MacKay for
+important contributions. I'm fortunate indeed to share a working
+environment with such stimulating people.
+
+When I originally designed the \WEB\ system, I spent about six
+weeks preparing the files {\tt TANGLE.WEB} and {\tt WEAVE.WEB},
+during which time I was continually changing the language and
+trying different styles of exposition. (The programs were neither
+long nor complicated, but this was rather intensive work, so I
+didn't get much else done during those six weeks. The first two
+weeks were actually spent drafting the first ten per cent of what
+is now {\tt TEX.WEB}.) Then I spent about six tedious hours with
+a text editor, hand-simulating the behavior of {\tt TANGLE} on
+{\tt TANGLE.WEB}, so that I had a program {\tt TANGLE.PAS} that
+was ripe for debugging. At first I had to correct errors both in
+{\tt TANGLE.WEB} and {\tt TANGLE.PAS}, but soon {\tt TANGLE} was
+working well enough that I needed only {\tt TANGLE.WEB} as a
+source file. Then {\tt WEAVE.WEB} could be tangled and debugged
+too. The total time to create ``Version~0'' of the \WEB\ system,
+including the language design and the time to debug the programs
+and write a brief manual for users, was about eight weeks; then
+enhancements were added at the rate of about one per month for
+the next 18 months. As a result of this experience I think it's
+reasonable to state that a {\tt WEB}-like system can be created
+from scratch in a fairly short time, for some other pair of
+languages besides \TeX\ and \PASCAL, by an expert system
+programmer who is conversant with both languages. Indeed, I spoke
+about \WEB\ on a recent visit to London and one of the people in
+the audience decided to test this hypothesis; shortly afterwards I
+received an elegant report from Harold Thimbleby, who had just constructed
+an excellent system called {\tt Cweb}, based on Troff/Nroff and {\mc
+C} instead of \TeX\ and \PASCAL.\ref\Thim{H. Thimbleby, {\sl Cweb}.
+Preprint, University of York (August 1983).}
+
+\beginsection N. RETROSPECT AND PROSPECTS
+
+Enthusiastic reports about new computer languages, by the authors of those
+languages, are commonplace. Hence I'm well aware of the fact that my own
+experiences cannot be extrapolated too far. I also realize that, whenever I have
+encountered a problem with \WEB, I've simply changed
+the system; other users of \WEB\ cannot operate under the same ground rules.
+
+However, I believe that I have stumbled on a way of programming that produces
+better programs that are more port\-able and more easily understood and
+maintained; furthermore, the system seems to work with large programs as
+well as with small ones. I'm pleased that my work on typography, which
+began as an application of computers to another field, has come full circle
+and become an application of typography to the heart of
+computer science; I like to think of \WEB\ as a neat ``spinoff'' of my
+research on \TeX. However, all of my experiences with this system have
+been highly colored by my own tastes, and only time will tell if a large
+number of other people will find \WEB\ to be equally attractive and useful.
+
+I made a conscious decision not to design a language that would be
+suitable for everybody. My goal was to provide a tool for system
+programmers, not for high school students or for hobbyists. I don't have
+anything against high school students and hobbyists, but I don't believe
+every computer language should attempt to offer all things to all people.
+A user of \WEB\ needs to be good enough at computer science that he or she
+is comfortable dealing with several languages simultaneously. Since
+\WEB\ combines \TeX\ and \PASCAL\ with a few rules of its own, \WEB\ programs
+can contain \WEB\ syntax errors, \TeX\ syntax errors, \PASCAL\ syntax errors,
+and algorithmic errors; in practice, all four types of errors occur, and
+a bit of sophistication is needed to sort out which is which. Computer
+scientists tend to be better at such things than other people. I have found
+that \WEB\ programs can be debugged rapidly in spite of the profusion
+of languages, but I'm sure that many other intelligent people will find
+such a task difficult.
+
+In other words, \WEB\ seems to be specifically for the peculiar breed of
+people who are called computer scientists. And I'm pretty sure that there
+are also a lot of computer scientists who will not enjoy using \WEB; some
+of us are glad that traditional programming languages have comparatively
+primitive capabilities for inserted comments, because such difficulties provide
+a good excuse for not documenting programs well. Thus, \WEB\ may be only for the
+subset of computer scientists who like to write and to explain what they
+are doing. My hope is that the ability to make explanations more natural will
+cause more programmers to discover the joys of literate programming,
+because I believe it's quite a pleasure to combine verbal and mathematical
+skills; but perhaps I'm hoping for too much. The fact that at least one
+paper has been written that is a syntactically correct {\mc ALGOL 68}
+program\ref\ft{C. H. Lindsey, ALGOL 68 with fewer tears. {\sl The
+Computer Journal\/ \bf15}, 176--188 (1972).} encourages me to persevere
+in my hopes for the future. Perhaps we will even one day find Pulitzer
+prizes awarded to computer programs.
+
+And what about the future of \WEB? If the next year or so of trial use
+shows that a lot of other people besides myself become ``hooked'' on this
+method of programming, there will be many ways to incorporate the \WEB\
+philosophy into a really effective programming environment. For example,
+it will be worthwhile to produce a unified system that does both
+tangling and compiling, instead of using separate programs as in Figure~1;
+and it will also be worthwhile to carry the unification one step further,
+so that run-time debugging as well as syntactic debugging can be done
+entirely in terms of the \WEB\ source language. Furthermore, a \WEB-like
+system could be designed to incorporate additional modularization,
+so that it would be easier to compile different parts of a program
+independently. The new generation of graphic workstations makes it
+desirable to display selected program sections on demand, by using \TeX\
+only on the sections that are of current interest, instead of producing
+hardcopy for an entire document. And so on; a considerable amount of
+additional research and development will be appropriate if the idea
+of literate programming catches on.
+
+\bigskip\leftline{\bf Acknowledgements}
+\smallskip
+{\eightrm\baselineskip9pt
+\noindent The preparation of this paper was supported in part by
+the National Science Foundation under grants IST-8201926 and MCS-8300984,
+and by the System Development Foundation. `\TeX' is a trademark of the
+American Mathematical Society.\par}
+
+\enddoublecolumns % prepare for the references
+\bigskip\bigskip
+\hbox to\pagewidth{\hss\bf REFERENCES\hss\strut}
+\CJrule width\pagewidth
+\bigskip
+\begindoublecolumns
+\let\rm=\eightss \let\sl=\eightssi \let\bf=\eightssb \rm
+\baselineskip=9pt
+\tolerance=1000
+\references
+\bigskip
+\noindent
+Received September 1983
+\enddoublecolumns
+\kern6mm
+\CJrule width\pagewidth
+\bye
diff --git a/Master/texmf-doc/doc/english/knuth/webman.tex b/Master/texmf-doc/doc/english/knuth/webman.tex
new file mode 100644
index 00000000000..61e12a28789
--- /dev/null
+++ b/Master/texmf-doc/doc/english/knuth/webman.tex
@@ -0,0 +1,1672 @@
+% WEB user manual -- last updated by D E Knuth on 4 Dec 89
+\input webmac
+\parskip 0pt plus 1pt
+\def\RA{\char'31 } % right arrow
+\def\hang{\hangindent 4em\ignorespaces}
+\font\ninerm=cmr9
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\let\mc=\ninerm % medium caps for names like SAIL
+\def\PASCAL{Pascal}
+\font\quoterm=cmssq8
+\font\quoteit=cmssqi8
+\def\pb{\.{|...|}}
+\def\lpile{\def\cr{\hfill\endline}\matrix} % I only use \lpile by itself
+
+\outer\def\section #1.{\penalty-50\vskip 12pt plus 3pt minus 3pt
+ \noindent{\bf #1.}\quad\ignorespaces}
+
+\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
+\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
+\def\runninghead{{\tentt WEB} USER MANUAL}
+
+% This verbatim mode assumes that no ? appears in the text being copied.
+\def\verbatim{\begingroup
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =13 \catcode`\^^M=13
+ \tt \catcode`\?=0 \verbatimdefs \verbatimgobble}
+{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }} %
+ \gdef\verbatimgobble#1^^M{}}
+ \centerline{\titlefont The {\ttitlefont WEB} System
+ of Structured Documentation}
+
+\vskip 15pt plus 3pt minus 3pt
+\noindent This memo describes how to write programs in the
+\.{WEB} language; and it also includes the full \.{WEB} documentation for
+\.{WEAVE} and \.{TANGLE}, the programs that read \.{WEB} input and produce
+\TeX\ and \PASCAL\ output, respectively. The philosophy behind \.{WEB} is
+that an experienced system programmer, who wants to provide the best
+possible documentation of software products, needs two things
+simultaneously: a language like \TeX\ for formatting, and a language like
+\PASCAL\ for programming. Neither type of language can provide the best
+documentation by itself. But when both are appropriately combined, we
+obtain a system that is much more useful than either language separately.
+
+The structure of a software program may be thought of as a ``web'' that is
+made up of many interconnected pieces. To document such a program, we want
+to explain each individual part of the web and how it relates to its
+neighbors. The typographic tools provided by \TeX\ give us an opportunity
+to explain the local structure of each part by making that structure
+visible, and the programming tools provided by \PASCAL\ make it possible
+for us to specify the algorithms formally and unambiguously. By combining
+the two, we can develop a style of programming that maximizes our ability
+to perceive the structure of a complex piece of software, and at the same
+time the documented programs can be mechanically translated into a working
+software system that matches the documentation.
+
+Since \.{WEB} is an experimental system developed for internal use within
+the \TeX\ project at Stanford, this report is rather terse, and it assumes
+that the reader is an experienced programmer who is highly motivated to
+read a detailed description of \.{WEB}'s rules. Furthermore, even if a
+less terse manual were to be written, the reader would have to be warned
+in advance that \.{WEB} is not for beginners and it never will be: The
+user of \.{WEB} must be familiar with both \TeX\ and \PASCAL. When one
+writes a \.{WEB} description of a software system, it is possible to make
+mistakes by breaking the rules of \.{WEB} and/or the rules of \TeX\ and/or
+the rules of \PASCAL. In practice, all three types of errors will occur,
+and you will get different error messages from the different language
+processors. In compensation for the sophisticated expertise needed to cope
+with such a variety of languages, however, experience has shown that
+reliable software can be created quite rapidly by working entirely in
+\.{WEB} from the beginning; and the documentation of such programs seems
+to be better than the documentation obtained by any other known method.
+Thus, \.{WEB} users need to be highly qualified, but they can get some
+satisfaction and perhaps even a special feeling of accomplishment when
+they have successfully created a software system with this method.
+
+To use \.{WEB}, you prepare a file called \.{COB.WEB} (say), and then you
+apply a system program called \.{WEAVE} to this file, obtaining an output
+file called \.{COB.TEX}. When \TeX\ processes \.{COB.TEX}, your output
+will be a ``pretty printed'' version of \.{COB.WEB} that takes appropriate
+care of typographic details like page layout and the use of indentation,
+italics, boldface, etc.; this output will contain extensive cross-index
+information that is gathered automatically. You can also submit the same
+file \.{COB.WEB} to another system program called \.{TANGLE}, which will
+produce a file \.{COB.PAS} that contains the \PASCAL\ code of your \.{COB}
+program. The \PASCAL\ compiler will convert \.{COB.PAS} into
+machine-language instructions corresponding to the algorithms that were so
+nicely formatted by \.{WEAVE} and \TeX. Finally, you can (and should)
+delete the files \.{COB.TEX} and \.{COB.PAS}, because \.{COB.WEB} contains
+the definitive source code. Examples of the behavior of \.{WEAVE} and
+\.{TANGLE} are appended to this manual.
+
+Besides providing a documentation tool, \.{WEB} enhances the \PASCAL\
+language by providing a rudimentary macro capability together with the
+ability to permute pieces of the program text, so that a large system can
+be understood entirely in terms of small modules and their local
+interrelationships. The \.{TANGLE} program is so named because it takes a
+given web and moves the modules from their web structure into the order
+required by \PASCAL; the advantage of programming in \.{WEB} is that the
+algorithms can be expressed in ``untangled'' form, with each module
+explained separately. The \.{WEAVE} program is so named because it takes
+a given web and intertwines the \TeX\ and \PASCAL\ portions contained in
+each module, then it knits the whole fabric into a structured document.
+(Get it? Wow.) Perhaps there is some deep connection here with the fact
+that the German word for ``weave'' is ``{\it web\/}'', and the
+corresponding Latin imperative is ``{\it texe\/}''!
+
+It is impossible to list all of the related work that has influenced the
+design of \.{WEB}, but the key contributions should be mentioned
+here.\quad (1)~Myrtle Kellington, as executive editor for ACM
+publications, developed excellent typographic standards for the
+typesetting of Algol programs during the 1960s, based on the original
+designs of Peter Naur; the subtlety and quality of this influential work
+can be appreciated only by people who have seen what happens when other
+printers try to typeset Algol without the advice of ACM's copy
+editors.\quad(2)~Bill McKeeman introduced a program intended to automate
+some of this task [Algorithm 268, ``Algol~60 reference language editor,''
+{\sl CACM \bf8} (1965), 667--668]; and a considerable flowering of such
+programs has occurred in recent years [see especially Derek Oppen,
+``Prettyprinting,'' {\sl ACM TOPLAS \bf2} (1980), 465--483; G.~A. Rose and
+J. Welsh, ``Formatted programming languages,'' {\sl SOFTWARE Practice
+\char`\&\ Exper.\ \bf11} (1981), 651--669].\quad(3)~The top-down style of
+exposition encouraged by \.{WEB} was of course chiefly influenced by Edsger
+Dijkstra's essays on structured programming in the late 1960s. The less
+well known work of Pierre-Arnoul de Marneffe [``Holon programming: A
+survey,'' Univ.\ de Liege, Service Informatique, Liege, Belgium, 1973; 135
+pp.\null] also had a significant influence on the author as \.{WEB} was
+being formulated.\quad(4)~Edwin Towster has proposed a similar style of
+documentation in which the programmer is supposed to specify the relevant
+data structure environment in the name of each submodule [``A convention
+for explicit declaration of environments and top-down refinement of
+data,'' {\sl IEEE Trans.\ on Software Eng.\ \bf SE--5} (1979), 374--386];
+this requirement seems to make the documentation a bit too verbose,
+although experience with \.{WEB} has shown that any unusual control
+structure or data structure should definitely be incorporated into the
+module names on psychological grounds.\quad(5)~Discussions with Luis
+Trabb~Pardo in the spring of 1979 were extremely helpful for setting up a
+prototype version of \.{WEB} that was called \.{DOC}.\quad (6)~Ignacio
+Zabala's extensive experience with \.{DOC}, in which he created a full
+implementation of \TeX\ in \PASCAL\ that was successfully transported to
+many different computers, was of immense value while \.{WEB} was taking
+its present form.\quad(7)~David~R. Fuchs made several crucial suggestions
+about how to make \.{WEB} more portable; he and Arthur~L. Samuel
+coordinated the initial installations of \.{WEB} on dozens of computer
+systems, making changes to the code so that it would be acceptable to
+a wide variety of \PASCAL\ compilers.\quad(8)~The name \.{WEB} itself
+was chosen in honor of my wife's mother, Wilda Ernestine Bates.
+
+The appendices to this report contain complete \.{WEB} programs for the
+\.{WEAVE} and \.{TANGLE} processors. A study of these examples, together
+with an attempt to write \.{WEB} programs by yourself, is the best way
+to understand why \.{WEB} has come to be like it is.
+ \section General rules.
+A \.{WEB} file is a long string of text that has been divided into
+individual lines. The exact line boundaries are not terribly crucial, and
+a programmer can pretty much chop up the \.{WEB} file in whatever way seems
+to look best as the file is being edited; but string constants and control
+texts must end on the same line on which they begin, since this convention
+helps to keep errors from propagating. The end of a line means
+the same thing as a blank space.
+
+Two kinds of material go into \.{WEB} files: \TeX\ text and \PASCAL\ text.
+A programmer writing in \.{WEB} should be thinking both of the
+documentation and of the \PASCAL\ program that he or she is creating;
+i.e., the programmer should be instinctively aware of the different
+actions that \.{WEAVE} and \.{TANGLE} will perform on the \.{WEB} file.
+\TeX\ text is essentially copied without change by \.{WEAVE}, and it is
+entirely deleted by \.{TANGLE}, since the \TeX\ text is ``pure
+documentation.'' \PASCAL\ text, on the other hand, is formatted by
+\.{WEAVE} and it is shuffled around by \.{TANGLE}, according to rules that
+will become clear later. For now the important point to keep in mind is
+that there are two kinds of text. Writing \.{WEB} programs is something
+like writing \TeX\ documents, but with an additional ``\PASCAL\ mode''
+that is added to \TeX's horizontal mode, vertical mode, and math mode.
+
+A \.{WEB} file is built up from units called {\sl modules\/} that are more
+or less self-contained. Each module has three parts:
+
+\yskip\item{1)} A \TeX\ part, containing explanatory material about what
+is going on in the module.
+
+\item{2)} A definition part, containing macro definitions that serve as
+abbreviations for \PASCAL\ constructions that would be less comprehensible
+if written out in full each time.
+
+\item{3)} A \PASCAL\ part, containing a piece of the program that
+\.{TANGLE} will produce. This \PASCAL\ code should ideally be about a
+dozen lines long, so that it is easily comprehensible as a unit and so
+that its structure is readily perceived.
+
+\yskip\noindent The three parts of each module must appear in this order;
+i.e., the \TeX\ commentary must come first, then the definitions, and
+finally the \PASCAL\ code. Any of the parts may be empty.
+
+\eject % page break inserted Dec 88
+
+A module begins with the pair of symbols `\.{@\ }' or `\.{@*}', where
+`\.{\ }' denotes a blank space. A module ends
+at the beginning of the next module (i.e., at the next
+`\.{@\ }' or `\.{@*}'), or at the end of the file, whichever comes first.
+The \.{WEB} file may also contain material that is not part of any module
+at all, namely the text (if any) that occurs before the first module.
+Such text is said to be ``in limbo''; it is ignored by \.{TANGLE}
+and copied essentially verbatim by \.{WEAVE}, so its function is to
+provide any additional formatting instructions that may be desired in the
+\TeX\ output. Indeed, it is customary to begin a \.{WEB} file with
+\TeX\ code in limbo that loads special fonts, defines special macros,
+changes the page sizes, and/or produces a title page.
+
+Modules are numbered consecutively, starting with 1; these numbers appear
+at the beginning of each module of the \TeX\ documentation, and they appear
+as bracketed comments at the beginning of the code generated by that
+module in the \PASCAL\ program.
+
+Fortunately, you never mention these numbers yourself when you are writing
+in \.{WEB}. You just say `\.{@\ }' or `\.{@*}' at the beginning of each
+new module, and the numbers are supplied automatically by \.{WEAVE} and
+\.{TANGLE}. As far as you are concerned, a module has a
+{\sl name\/} instead of a number; such a name is specified by writing
+`\.{@<}' followed by \TeX\ text followed by `\.{@>}'. When \.{WEAVE}
+outputs a module name, it replaces the `\.{@<}' and `\.{@>}' by
+angle brackets and inserts the module number in small type. Thus, when you
+read the output of \.{WEAVE} it is easy to locate any module that is
+referred to in another module.
+
+For expository purposes, a module name should be a good description of the
+contents of that module; i.e., it should stand for the abstraction
+represented by the module. Then the module can be ``plugged into'' one or
+more other modules in such a way
+that unimportant details of its inner workings
+are suppressed. A module name therefore ought to be long enough to convey
+the necessary meaning. Unfortunately, however, it is laborious to type
+such long names over and over again, and it is also difficult to specify a
+long name twice in exactly the same way so that \.{WEAVE} and \.{TANGLE}
+will be able to match the names to the modules. To ameliorate this difficulty,
+\.{WEAVE} and \.{TANGLE} let you abbreviate a module name
+after its first appearance in the \.{WEB} file; you can type simply
+`\.{@<$\alpha$...@>}', where $\alpha$ is any string that is a prefix of
+exactly one module name appearing in the file. For example, `\.{@<Clear
+the arrays@>}' can be abbreviated to `\.{@<Clear...@>}' if no other module
+name begins with the five letters `\.{Clear}'. Module names must otherwise
+match character for character, except that consecutive blank spaces and/or
+tab marks are treated as equivalent to single spaces, and such spaces are
+deleted at the beginning and end of the name. Thus, `\.{@< Clear { }the
+arrays @>}' will also match the name in the previous example.
+
+We have said that a module begins with `\.{@\ }' or `\.{@*}', but we
+didn't say how it gets divided up into a \TeX\ part, a definition part,
+and a \PASCAL\ part. The definition part begins with the first appearance
+of `\.{@d}' or `\.{@f}' in the module, and the \PASCAL\ part begins with
+the first appearance of `\.{@p}' or `\.{@<}'. The latter option `\.{@<}'
+stands for the beginning of a module name, which is the name of the module
+itself. An equals sign (\.=) must follow the `\.{@>}' at the end of this
+module name; you are saying, in effect, that the module name stands for
+the \PASCAL\ text that follows, so you say `$\langle\,$module
+name$\,\rangle=\null$\PASCAL\ text'. Alternatively, if the \PASCAL\ part
+begins with `\.{@p}' instead of a module name, the current module is said
+to be {\sl unnamed}. Note that module names cannot appear in the
+definition part of a module, because the first `\.{@<}' in a module
+signals the beginning of its \PASCAL\ part. But any number of module names
+might appear in the \PASCAL\ part, once it has started.
+
+The general idea of \.{TANGLE} is to make a \PASCAL\ program out of these
+modules in the following way: First all the \PASCAL\ parts of unnamed
+modules are copied down, in order; this constitutes the initial
+approximation $T_0$ to the text of the program. (There should be at least
+one unnamed module, otherwise there will be no program.) Then all module
+names that appear in the initial text $T_0$ are replaced by the \PASCAL\
+parts of the corresponding modules, and this substitution process
+continues until no module names remain. Then all defined macros are
+replaced by their equivalents, according to certain rules that are
+explained later. The resulting \PASCAL\ code is ``sanitized'' so that it
+will be acceptable to an average garden-variety \PASCAL\ compiler; i.e.,
+lowercase letters are converted to uppercase, long identifiers are
+chopped, and the lines of the output file are constrained to be at most 72
+characters long. All comments will have been removed from this \PASCAL\
+program except for the meta-comments delimited by `\.{@\{}' and
+`\.{@\}}', as explained below, and except for the module-number comments
+that point to the source location where each piece of the program text
+originated in the \.{WEB} file.
+
+If the same name has been given to more than one module, the \PASCAL\ text
+for that name is obtained by putting together all of the \PASCAL\ parts in
+the corresponding modules. This feature is useful, for example, in a
+module named `Global variables in the outer block', since one can then
+declare global variables in whatever modules those variables are
+introduced. When several modules have the same name, \.{WEAVE} assigns the
+first module number as the number corresponding to that name, and it
+inserts a note at the bottom of that module telling the reader to `See
+also sections so-and-so'; this footnote gives the numbers of all the other
+modules having the same name as the present one. The \PASCAL\ text
+corresponding to a module is usually formatted by \.{WEAVE} so that the
+output has an equivalence sign in place of the equals sign in the \.{WEB}
+file; i.e., the output says `$\langle\,$module
+name$\,\rangle\equiv\null$\PASCAL\ text'. However, in the case of the second
+and subsequent appearances of a module with the same name, this `$\equiv$'
+sign is replaced by `$\mathrel+\equiv$', as an indication that the \PASCAL\
+text that follows is being appended to the \PASCAL\ text of another
+module.
+
+The general idea of \.{WEAVE} is to make a \.{TEX} file from the \.{WEB}
+file in the following way: The first line of the \.{TEX} file will be
+`\.{\\input webmac}'; this will cause \TeX\ to read in the macros that
+define \.{WEB}'s documentation conventions. The next lines of the file
+will be copied from whatever \TeX\ text is in limbo before the first
+module. Then comes the output for each module in turn, possibly
+interspersed with end-of-page marks. Finally, \.{WEAVE} will generate a
+cross-reference index that lists each module number in which each \PASCAL\
+identifier appears, and it will also generate an alphabetized list
+of the module names, as well as a table of contents that
+shows the page and module numbers for each ``starred'' module.
+
+What is a ``starred'' module, you ask? A module that begins with `\.{@*}'
+instead of `\.{@\ }' is slightly special in that it denotes a new major
+group of modules. The `\.{@*}' should be followed by the title of this
+group, followed by a period. Such modules will always start on a new page
+in the \TeX\ output, and the group title will appear as a running headline
+on all subsequent pages until the next starred module. The title will also
+appear in the table of contents, and in boldface type at the beginning of
+its module. Caution: Do not use \TeX\ control sequences in such titles,
+unless you know that the \.{webmac} macros will do the right thing with
+them. The reason is that these titles are converted to uppercase when
+they appear as running heads, and they are converted to boldface when they
+appear at the beginning of their modules, and they are also written out to
+a table-of-contents file used for temporary storage while \TeX\ is
+working; whatever control sequences you use must be meaningful in all
+three of these modes.
+
+The \TeX\ output produced by \.{WEAVE} for each module consists of
+the following: First comes the module number (e.g., `\.{\\M123.}'
+at the beginning of module 123, except that `\.{\\N}' appears in place of
+`\.{\\M}' at the beginning of a starred module). Then comes the
+\TeX\ part of the module, copied almost verbatim except as noted
+below. Then comes the definition part and the \PASCAL\ part, formatted
+so that there will be a little extra space between them if both are
+nonempty. The definition and \PASCAL\ parts are obtained by inserting
+a bunch of funny looking \TeX\ macros into the \PASCAL\ program; these
+macros handle typographic details about fonts and proper math spacing,
+as well as line breaks and indentation.
+
+When you are typing \TeX\ text, you will probably want to make frequent
+reference to variables and other quantities in your \PASCAL\ code, and you
+will want those variables to have the same typographic treatment
+when they appear in your text as when they appear in your
+program. Therefore the \.{WEB} language allows you to get the effect of
+\PASCAL\ editing within \TeX\ text, if you place `\.|' marks before and
+after the \PASCAL\ material. For example, suppose you want to say something
+like this:
+$$\hbox{The characters are placed into \\{buffer}, which is a
+\&{packed} \&{array} $[1\to\|n]$ \&{of} \\{char}.}$$
+The \TeX\ text would look like this in your \.{WEB} file:
+$$\.{The characters are placed into |buffer|, which is a |packed
+array [1..n] of char|.}$$
+And \.{WEAVE} translates this into something you are glad you didn't have
+to type:
+$$\lpile{\.{The characters are placed into \\\\\{buffer\},}\cr
+ \.{which is a \\\&\{packed\}{ }\\\&\{array\}{ }\$
+ [1\\to\\|n]\${ }\\\&\{of\}{ }\\\\\{char\}.}\cr}$$
+Incidentally, the cross-reference index that \.{WEAVE} would make, in
+the presence of a comment like this, would include
+the current module number as one of the index entries for \\{buffer}
+\vadjust{\eject}% page break inserted Dec 88
+and \\{char}, even though \\{buffer} and \\{char}
+might not appear in the \PASCAL\ part of
+this module. Thus, the index covers references to identifiers in
+the explanatory comments as well as in the program itself; you will
+soon learn to appreciate this feature. However, the identifiers
+\&{packed} and \&{array} and \|n\ and \&{of\/} would not be indexed,
+because \.{WEAVE} does not make index entries for reserved words or
+single-letter identifiers. Such identifiers are felt to be so ubiquitous
+that it would be pointless to mention every place where they occur.
+
+Speaking of identifiers, the author of \.{WEB} thinks that
+\\{IdentifiersSeveralWordsLong} look terribly ugly when they mix
+uppercase and lowercase letters. He recommends that
+\\{identifiers\_several\_words\_long} be written with underline characters
+to get a much better effect. The actual identifiers sent to the \PASCAL\
+compiler by \.{TANGLE} will have such underlines removed, and \.{TANGLE}
+will check to make sure that two different identifiers do not become
+identical when this happens. (In fact, \.{TANGLE} even checks that
+the first seven characters of identifiers are unique, when lowercase
+letters have been converted to uppercase; the number seven in this
+constraint is more strict than \PASCAL's eight, and it can
+be changed if desired.) The \.{WEAVE} processor will properly
+alphabetize identifiers that have embedded underlines
+when it makes the index.
+
+Although a module begins with \TeX\ text and ends with \PASCAL\ text, we
+have noted that the dividing line isn't sharp, since \PASCAL\ text can be
+included in \TeX\ text if it is enclosed in `\pb'. Conversely, \TeX\ text
+also appears frequently within \PASCAL\ text, because everything in
+comments (i.e., between left and right braces) is treated as \TeX\ text.
+Furthermore, a module name consists of \TeX\ text; thus, a \.{WEB} file
+typically involves constructions like `\.{if} \.x \.= \.0 \.{then}
+\.{@<Empty} \.{the} \.{|buffer|} \.{array@>}' where we go back and forth
+between \PASCAL\ and \TeX\ conventions in a natural way.
+ \section Macros.
+A \.{WEB} programmer can define three kinds of macros to make the programs
+shorter and more readable:
+
+\yskip\hang`\.{@d} \\{identifier} \.= \\{constant}' defines a {\sl numeric\/}
+macro, allowing \.{TANGLE} to do rudimentary arithmetic.
+
+\yskip\hang`\.{@d} \\{identifier} \.{==} \PASCAL\ text' defines a {\sl
+simple\/} macro, where the identifier will be replaced by the \PASCAL\ text
+when \.{TANGLE} produces its output.
+
+\yskip\hang`\.{@d} \\{identifier}\.{(\#) ==} \PASCAL\ text' defines a
+{\sl parametric\/} macro, where the identifier will be replaced by the \PASCAL\
+text and where occurrences of \.{\#} in that \PASCAL\ text will be
+replaced by an argument.
+
+\yskip\noindent In all three cases, the identifier must have length greater
+than one; it must not be a single letter.
+
+Numeric macros are subject to the following restrictions:\quad
+(1)~The identifier must
+be making its first appearance in the \.{WEB} file;
+a numeric macro must be defined before it is used.\quad
+(2)~The right-hand side of the numeric definition must be made entirely from
+integer constants, numeric macros, preprocessed strings (see below), and
+plus~signs or minus signs. No other operations or symbols are allowed,
+not even parentheses, except that \PASCAL-like comments (enclosed in
+braces) can appear. Indeed, comments are recommended, since it is usually
+wise to give a brief explanation of the significance of each identifier as
+it is defined.\quad
+(3)~The numeric value must be less than $2^{15}=32768$ in absolute value.
+(For larger values, you can use `\.{==}' in place of~`\.=', thus making use
+of a simple macro instead of a numeric one. Note, however, that simple
+macros sometimes have a different effect. For example, consider the three
+definitions `\.{@d n1=2 @d n2=2+n1 @d n3==2+n1}'; then `\.{x-n2}' will
+expand into `\.{x-4}', while `\.{x-n3}' will expand into `\.{x-2+2}' which
+is quite different! It is wise to include parentheses in non-numeric
+macros, e.g., `\.{@d n3==(2+n1)}', to avoid such errors.)
+
+When constants are connected by plus signs or minus
+signs in a \PASCAL\ program, \.{TANGLE} does the arithmetic before putting
+the constant into the output file. Therefore it is permissible to say, for
+example, `\&{array} $[0\,.\,.\,\\{size}-1]$' if \\{size} has been declared
+as a macro; note that \PASCAL\ doesn't allow this kind of compile-time
+arithmetic if \\{size} is a \&{constant} quantity in the program. Another
+use of \.{TANGLE}'s arithmetic is to make \&{case} statement labels such
+as `$\\{flag}+1$' legitimate. Of course, it is improper to change \.{2+2}
+into \.4 without looking at the surrounding context; many counterexamples
+exist, such as the phrases `\.{-2+2}', `\.{x/2+2}', and `\.{2+2E5}'. The
+program for \.{TANGLE}, in the appendix, gives precise details about this
+conversion, which \.{TANGLE} does only when it is safe.
+
+The right-hand sides of simple and parametric macros
+are required to have balanced parentheses, and the \PASCAL\ texts of
+modules must have balanced parentheses too. Therefore when the argument
+to a para\-metric macro appears in parentheses, both parentheses
+will belong to the same \PASCAL\ text.
+
+The appendices to this report contain hundreds of typical examples of the
+usefulness of \.{WEB} macros, so it is not necessary to dwell on the
+subject here. However, the reader should know that \.{WEB}'s apparently
+primitive macro capabilities can actually do a lot of rather surprising
+things. Here is a construction that sheds further light on what is
+possible: After making the definitions
+$$\catcode`\#=12
+\lpile{\.{@d two\_cases(#)==case j of 1:#(1); 2:#(2); end}\cr
+\.{@d reset\_file(#)==reset(input\_file@\&#)}\cr}$$
+one can write `\.{two\_cases(reset\_file)}' and the resulting \PASCAL\
+output will be
+$$\.{case j of 1:reset(input\_file1); 2:reset(input\_file2); end}$$
+(but in uppercase letters and with \.\_'s removed).
+The `\.{@\&}' operation used here joins together two adjacent tokens
+into a single token, as explained later; otherwise the \PASCAL\ file would
+contain a space between \.{input\_file} and the digit that followed it.
+This trick can be used to provide the effect of an array of files, if you
+are unfortunate enough to have a \PASCAL\ compiler that doesn't allow such
+arrays. Incidentally, the cross-reference index made by \.{WEAVE} from
+this example would contain the identifier \\{input\_file} but it would not
+contain \\{input\_file1} or \\{input\_file2}. Furthermore, \.{TANGLE}
+would not catch the error that \.{INPUTFILE1} and \.{INPUTFILE2} both
+begin with the same nine letters; one should be more careful when using
+`\.{@\&}'! But such aspects of the construction in this trick are
+peripheral to our main point, which is that a parametric macro name without
+arguments can be used as an argument to another parametric macro.
+
+Although \.{WEB}'s macros are allowed to have at most one parameter, the
+following example shows that this is not as much of a restriction as it
+may seem at first. Let \\{amac} and \\{bmac} be any parametric macros, and
+suppose that we want to get the effect of
+$$\catcode`\#=12
+\.{@d cmac(#1,#2) == amac(#1) bmac(#2)}$$
+which \.{WEB} doesn't permit. The solution is to make the definitions
+$$\catcode`\#=12
+\lpile{\.{@d cmac(#) == amac(#) dmac}\cr
+\.{@d dmac(#) == bmac(#)}\cr}$$
+and then to say `\.{cmac(x)(y)}'.
+
+There is one restriction in the generality of \.{WEB}'s parametric
+macros, however: the argument to a para\-metric macro must not come from
+the expansion of a macro that has not already been ``started.'' For
+example, here is one of the things \.{WEB} cannot handle:
+$$\catcode`\#=12
+\lpile{\.{@d arg == (p)}\cr
+\.{@d identity(#) == #}\cr
+\.{@p identity arg}\cr}$$
+In this case \.{TANGLE} will complain that the \.{identity} macro is not
+followed by an argument in parentheses.
+
+The \.{WEB} language has another feature that is somewhat similar to a
+numeric macro. A {\sl preprocessed string\/} is a string that is like
+a \PASCAL\ string but delimited by double-quote marks (\.") instead of
+single-quotes. Double-quote marks inside of such strings are indicated by
+giving two double-quotes in a row. If a preprocessed string is
+of length one (e.g., \.{"A"} or \.{""""}), it will be treated by \.{TANGLE}
+as equivalent to the corresponding ASCII-code integer (e.g., \.{65} or
+\.{34}). And if a preprocessed string is not of length one, it will be
+converted into an integer equal to 256 or more. A {\sl string pool\/}
+containing all such strings will be written out by the \.{TANGLE}
+processor; this string pool file consists of string 256, then string 257,
+etc., where each string is followed by an end-of-line and prefixed by two
+decimal digits that define its length. Thus, for example, the empty string
+\.{""} would be represented in the string pool file by a line containing
+the two characters `\.{00}', while the string \.{"""String"""} would be
+represented by `\.{08"String"}'. A given string appears at most once in
+the string pool; the use of such a pool makes it easier to cope with
+\PASCAL's restrictions on string manipulation. The string pool ends with
+`\.{*nnnnnnnnn}', where \.{nnnnnnnnn} is a decimal number
+called the {\sl string pool check sum}. If any string changes, the check
+sum almost surely changes too; thus, the `\.{@\$}' feature
+described below makes it possible for a program to assure itself that it
+is reading its own string pool.
+
+Here is a simple example that combines numeric macros with preprocessed
+strings of length one:
+$$\lpile{\.{@d upper\_case\_Y = "Y"}\cr
+\.{@d case\_difference = -"y"+upper\_case\_Y}\cr}$$
+The result is to define
+$\\{upper\_case\_Y}=89$, $\\{case\_difference}=-32$.
+ \section Control codes.
+We have seen several magic uses of `\.{@}' signs in \.{WEB} files, and it
+is time to make a systematic study of
+these special features. A \.{WEB} {\sl control code\/}
+is a two-character combination of which the first is `\.@'.
+
+Here is a complete list of the legal control codes. The letters $L$, $T$,
+$P$, $M$, $C$, and/or $S$ following each code indicate whether or not that
+code is allowable in limbo, in \TeX\ text, in \PASCAL\ text, in module
+names, in comments, and/or in strings. A bar over such a letter means
+that the control code terminates the present part of the \.{WEB} file; for
+example, $\overline L$ means that this control code ends the limbo material
+before the first module.
+
+\def\@#1[#2] {\yskip\hangindent 2em\noindent\.{@#1\unskip
+ \spacefactor1000{ }}$[#2]$\quad}
+\def\oP{\overline P}
+\def\oT{\overline T\mskip1mu}
+
+\@@ [C,L,M,P,S,T] A double \.@ denotes the single character `\.@'. This is
+the only control code that is legal in limbo, in comments, and in strings.
+
+\@\ [\overline L,\oP,\oT] This denotes the beginning of a new
+(unstarred) module. A tab mark or end-of-line (carriage return)
+is equivalent to a space when it follows an \.@ sign.
+
+\@* [\overline L,\oP,\oT] This denotes the beginning of a new starred
+module, i.e., a module that begins a new major group. The title of the new
+group should appear after the \.{@*}, followed by a period. As explained
+above, \TeX\ control sequences should be avoided in such titles unless
+they are quite simple. When \.{WEAVE} and \.{TANGLE} read a \.{@*}, they
+print an asterisk on the terminal
+followed by the current module number, so that the user
+can see some indication of progress. The very first module should be starred.
+
+\@d [\oP,\oT] Macro definitions begin with \.{@d} (or \.{@D}), followed by
+the \PASCAL\ text for one of the three kinds of macros, as explained
+earlier.
+
+\@f [\oP,\oT] Format definitions begin with \.{@f} (or \.{@F}); they cause
+\.{WEAVE} to treat identifiers in a special way when they appear in
+\PASCAL\ text. The general form of a format definition is `\.{@f} \|l \.{==}
+\|r', followed by an optional comment enclosed in braces, where \|l and \|r
+are identifiers; \.{WEAVE} will subsequently treat identifier \|l as it
+currently treats \|r. This feature allows a \.{WEB} programmer to invent
+new reserved words and/or to unreserve some of \PASCAL's reserved
+identifiers. The definition part of each module consists of any number of
+macro definitions (beginning with \.{@d}) and format definitions (beginning
+with \.{@f}), intermixed in any order.
+
+\@p [\oP,\oT] The \PASCAL\ part of an unnamed module begins with \.{@p}
+(or \.{@P}). This causes \.{TANGLE} to append the following \PASCAL\ code
+to the initial program text $T_0$ as explained above. The \.{WEAVE}
+processor does not cause a `\.{@p}' to appear explicitly in the \TeX\
+output, so if you are creating a \.{WEB} file based on a \TeX-printed
+\.{WEB} documentation you have to remember to insert \.{@p} in the
+appropriate places of the unnamed modules.
+
+\@< [P,\oT] A module name begins with \.{@<} followed by \TeX\ text followed
+by \.{@>}; the \TeX\ text should not contain any \.{WEB} control codes
+except \.{@@}, unless these control codes appear in \PASCAL\ text that
+is delimited by \pb. The module name may be abbreviated, after its first
+appearance in a \.{WEB} file, by giving any unique prefix followed by \.{...},
+where the three dots immediately precede the closing \.{@>}. No module name
+should be a prefix of another. Module names may not appear in \PASCAL\
+text that is enclosed in \pb, nor may they appear in the definition part
+of a module (since the appearance of a module name ends the definition
+part and begins the \PASCAL\ part).
+
+\@\' [P,T] This denotes an octal constant, to be formed from the
+succeeding digits. For example, if the \.{WEB} file contains `\.{@\'100}',
+the \.{TANGLE} processor will treat this an equivalent to `\.{64}';
+the constant will be formatted as ``\O{100}'' in the \TeX\ output
+produced via \.{WEAVE}. You should use octal notation only for positive
+constants; don't try to get, e.g., $-1$ by saying `\.{@\'777777777777}'.
+
+\@" [P,T] A hexadecimal constant; `\.{@"D0D0}' tangles to \.{53456} and
+weaves to `\H{D0D0}'.
+
+\@\$ [P] This denotes the string pool check sum.
+
+\@\{ [P] The beginning of a ``meta comment,'' i.e., a comment
+that is supposed to appear in the \PASCAL\ code, is indicated by
+\.{@\{} in the \.{WEB} file. Such delimiters can be used as
+isolated symbols in macros or modules, but they should be properly nested
+in the final \PASCAL\ program. The \.{TANGLE} processor will convert
+`\.{@\{}' into `\.\{' in the \PASCAL\ output file, unless
+the output is already part of a meta-comment; in the latter case
+`\.{@\{}' is converted into `\.[', since \PASCAL\ does not allow
+nested comments. Incidentally, module numbers are automatically inserted
+as meta-comments into the \PASCAL\ program, in order to help correlate the
+outputs of \.{WEAVE} and \.{TANGLE} (see Appendix~C\null). Meta-comments
+can be used to put conditional text into a \PASCAL\ program; this helps to
+overcome one of the limitations of \.{WEB}, since the simple macro
+processing routines of \.{TANGLE} do not include the dynamic evaluation of
+boolean expressions.
+
+\@\} [P] The end of a ``meta comment'' is indicated by `\.{@\}}'; this is
+converted either into `\.\}' or `\.{]}' in the \PASCAL\ output, according
+to the conventions explained for \.{@\{} above.
+
+\@\& [P] The \.{@\&} operation causes whatever is on its left to be
+adjacent to whatever is on its right, in the \PASCAL\ output. No spaces or
+line breaks will separate these two items. However, the thing on the left
+should not be a semicolon, since a line break might occur after a semicolon.
+
+\@\^ [P,T] The ``control text'' that follows, up to the next
+`\.{@>}', will be entered into the index together with the identifiers of
+the \PASCAL\ program; this text will appear in roman type. For example, to
+put the phrase ``system dependencies'' into the index, you can type
+`\.{@\^system dependencies@>}' in each module
+that you want to index as system dependent. A control text, like a string,
+must end on the same line of the \.{WEB} file as it began. Furthermore,
+no \.{WEB} control codes are allowed in a control text, not even
+\.{@@}. (If you need an \.{@} sign you can get around this restriction by
+typing `\.{\\AT!}'.)
+
+\@. [P,T] The ``control text'' that follows will be entered into the index
+in \.{typewriter} \.{type}; see the rules for `\.{@\^}', which is analogous.
+
+\@: [P,T] The ``control text'' that follows will be entered into the index
+in a format controlled by the \TeX\ macro `\.{\\9}', which the user
+should define as desired; see the rules for `\.{@\^}', which is analogous.
+
+\@t [P] The ``control text'' that follows, up to the next `\.{@>}', will
+be put into a \TeX\ \.{\\hbox} and formatted along with the neighboring
+\PASCAL\ program. This text is ignored by \.{TANGLE}, but it can be used
+for various purposes within \.{WEAVE}. For example, you can make comments
+that mix \PASCAL\ and classical mathematics, as in `$\\{size}<2^{15}$', by
+typing `\.{|size < @t\$2\^\{15\}\$@>|}'. A control text must end on the
+same line of the \.{WEB} file as it began, and it may not contain any
+\.{WEB} control codes.
+
+\@= [P] The ``control text'' that follows, up to the next `\.{@>}', will
+be passed verbatim to the \PASCAL\ program.
+
+\@\\ [P] Force end-of-line here in the \PASCAL\ program file.
+
+\@! [P,T] The module number in an index entry will be underlined if `\.{@!}'
+immediately precedes the identifier or control text being indexed. This
+convention is used to distinguish the modules where an identifier is
+defined, or where it is explained in some special way, from the modules
+where it is used. A~reserved word or an identifier of length one will not
+be indexed except for underlined entries. An `\.{@!}' is implicitly inserted
+by \.{WEAVE} just after the reserved words \&{function}, \&{procedure},
+\&{program}, and \&{var}, and just after \.{@d} and \.{@f}. But you should
+insert your own `\.{@!}' before the definitions of types, constants,
+variables, parameters, and components of records and enumerated types that
+are not covered by this implicit convention, if you want to improve the
+quality of the index that you get.
+
+\@? [P,T] This cancels an implicit (or explicit) `\.{@!}', so that the next
+index entry will not be underlined.
+
+\@, [P] This control code inserts a thin space in \.{WEAVE}'s output; it is
+ignored by \.{TANGLE}. Sometimes you need this extra space if you are using
+macros in an unusual way, e.g., if two identifiers are adjacent.
+
+\@/ [P] This control code causes a line break to occur within a \PASCAL\
+program formatted by \.{WEAVE}; it is ignored by \.{TANGLE}. Line breaks
+are chosen automatically by \TeX\ according to a scheme that works 99\%\
+of the time, but sometimes you will prefer to force a line break so that
+the program is segmented according to logical rather than visual criteria.
+Caution: `\.{@/}' should be used only after statements or clauses, not in
+the middle of an expression; use \.{@|} in the middle of expressions, in
+order to keep \.{WEAVE}'s parser happy.
+
+\@| [P] This control code specifies an optional line break in the midst of
+an expression. For example, if you have a long condition between \&{if} and
+\&{then}, or a long expression on the right-hand side of an assignment
+statement, you can use `\.{@|}' to specify breakpoints more logical than
+the ones that \TeX\ might choose on visual grounds.
+
+\@\# [P] This control code forces a line break, like \.{@/} does,
+and it also causes a little extra white space to appear between the lines at
+this break. You might use it, for example, between procedure definitions or
+between groups of macro definitions that are logically separate but within
+the same module.
+
+\@+ [P] This control code cancels a line break that might otherwise be
+inserted by \.{WEAVE}, e.g., before the word `\&{else}', if you want to
+put a short if-then-else construction on a single line. It is ignored by
+\.{TANGLE}.
+
+\@; [P] This control code is treated like a semicolon, for formatting
+purposes, except that it is invisible. You can use it, for example, after
+a module name when the \PASCAL\ text represented by that module name ends
+with a semicolon.
+
+\yskip\noindent
+The last six control codes (namely `\.{@,}', `\.{@/}', `\.{@|}',
+`\.{@\#}', `\.{@+}', and `\.{@;}') have no effect on the \PASCAL\
+program output by \.{TANGLE}; they merely help to improve the readability
+of the \TeX-formatted \PASCAL\ that is output by \.{WEAVE}, in unusual
+circumstances. \.{WEAVE}'s built-in formatting method is fairly good, but
+it is incapable of handling all possible cases, because it must deal with
+fragments of text involving macros and module names; these fragments do
+not necessarily obey \PASCAL's syntax. Although \.{WEB} allows you to
+override the automatic formatting, your best strategy is not to worry
+about such things until you have seen what \.{WEAVE} produces automatically,
+since you will probably need to make only a few corrections when you are
+touching up your documentation.
+
+Because of the rules by which every module is broken into three parts,
+the control codes `\.{@d}', `\.{@f}', and `\.{@p}' are not allowed to occur
+once the \PASCAL\ part of a module has begun.
+ \section Additional features and caveats.
+
+1. The character pairs `\.{(*}', `\.{*)}', `\.{(.}', and `\.{.)}' are
+converted automatically in \PASCAL\ text as though they were
+`\.{@\{}', `\.{@\}}', `\.[', and `\.]', respectively, except
+of course in strings. Furthermore in certain installations of \.{WEB} that
+{\def\\#1#2{`{\tentex\char'#1#2}'}%
+have an extended character set, the characters \\32, \\34, \\35, \\30,
+\\36, \\04, \\37, \\05, and \\06}
+can be typed as abbreviations for
+`\.{<>}', `\.{<=}', `\.{>=}', `\.{:=}', `\.{==}', `\.{and}', `\.{or}',
+`\.{not}', and `\.{in}', respectively. However, the latter abbreviations
+are not used in the standard versions of \.{WEAVE.WEB} and \.{TANGLE.WEB}
+that are distributed to people who are installing \.{WEB} on other
+computers, and the programs are designed to produce only standard ASCII
+characters as output if the input consists entirely of ASCII characters.
+
+2. If you have an extended character set, all of the characters listed
+in Appendix C of {\sl The \TeX book\/} can be used in strings. But you should
+stick to standard ASCII characters if you want to write programs that will
+be useful to all the poor souls out there who don't have extended
+character sets.
+
+3. The \TeX\ file output by \.{WEAVE} is broken into lines having at most
+80 characters each. The algorithm that does this line breaking is unaware
+of \TeX's convention about comments following `\.\%' signs on a line. When
+\TeX\ text is being copied, the existing line breaks are copied as well,
+so there is no problem with `\.\%' signs unless the original \.{WEB} file
+contains a line more than eighty characters long or a line with \PASCAL\
+text in \pb\ that expands to more than eighty characters long. Such lines
+should not have `\.\%' signs.
+
+4. \PASCAL\ text is translated by a ``bottom up'' procedure that
+identifies each token as a ``part of speech'' and combines parts of speech
+into larger and larger phrases as much as possible according to a special
+grammar that is explained in the documentation of \.{WEAVE}. It is easy to
+learn the translation scheme for simple constructions like single
+identifiers and short expressions, just by looking at a few examples of
+what \.{WEAVE} does, but the general mechanism is somewhat complex because
+it must handle much more than \PASCAL\ itself. Furthermore the output
+contains embedded codes that cause \TeX\ to indent and break lines as
+necessary, depending on the fonts used and the desired page width. For
+best results it is wise to adhere to the following restrictions:
+
+\yskip\itemitem{a)}Comments in \PASCAL\ text should appear only after
+statements or clauses; i.e., after semicolons, after reserved words like
+\&{then} and \&{do}, or before reserved words like \&{end} and \&{else}.
+Otherwise \.{WEAVE}'s parsing method may well get mixed up.
+
+\itemitem{b)}Don't enclose long \PASCAL\ texts in \pb, since the
+indentation and line breaking codes are omitted when the \pb\ text is
+translated from \PASCAL\ to \TeX. Stick to simple expressions or
+statements.
+
+\yskip
+5. Comments and module names are not permitted in \pb\ text. After a `\.|'
+signals the change from \TeX\ text to \PASCAL\ text, the next `\.|' that is
+not part of a string or control text ends the \PASCAL\ text.
+
+6. A comment must have properly nested occurrences of left and right
+braces, otherwise \.{WEAVE} and \.{TANGLE} will not know where the comment
+ends. However, the character pairs `\.{\\\{}' and `\.{\\\}}' do not count
+as left and right braces in comments, and the character pair `\.{\\|}'
+does not count as a delimiter that begins \PASCAL\ text. (The actual rule
+is that a character after `\.\\' is ignored; hence in `\.{\\\\\{}' the
+left brace {\sl does\/} count.) At present, \.{TANGLE} and \.{WEAVE} treat
+comments in slightly different ways, and it is necessary to satisfy both
+conventions: \.{TANGLE} ignores `\.|' characters entirely, while \.{WEAVE}
+uses them to switch between \TeX\ text and \PASCAL\ text. Therefore, a
+comment that includes a brace in a string in \pb---e.g., `\.{\{{ }look at
+this |"\{"| \}}'---will be handled correctly by \.{WEAVE}, but \.{TANGLE}
+will think there is an unmatched left brace. In order to satisfy both
+processors, one can write `\.{\{{ }look at this \\leftbrace\\{ }\}}', after
+setting up`\.{\\def\\leftbrace\{|"\{"|\}}'.
+
+7. Reserved words of \PASCAL\ must appear entirely in lowercase letters
+in the \.{WEB} file; otherwise their special nature will not be recognized
+by \.{WEAVE}. You could, for example, have a macro named \\{END} and it
+would not be confused with \PASCAL's \&{end}.
+
+However, you may not want to capitalize macro names just to distinguish them
+from other identifiers. Here is a way to unreserve \PASCAL's reserved word
+`\&{type}' and to substitute another word `\&{mtype}' in the \.{WEB} file.
+$$\vbox{\halign{\tt #\hfil\cr
+@d type(\char'43) == mem[\char'43].t\cr
+@d mtype == t \char'100\char'46{} y \char'100\char'46{} p
+ \char'100\char'46{} e\cr
+@f mtype == type\cr
+@f type == true\cr}}$$
+In the output of \.{TANGLE}, the macro \.{mtype} now produces `\.{TYPE}'
+and the macro \.{type(x)} now produces `\.{MEM[X].T}'. In the output of
+\.{WEAVE}, these same inputs produce \&{mtype} and \\{type}(\|x),
+respectively.
+
+8. The \.{@f} feature allows you to define one identifier to act like
+another, and these format definitions are carried out sequentially, as the
+example above indicates. However, a given identifier has only one printed format
+throughout the entire document (and this format will even be used before
+the \.{@f} that defines it). The reason is that \.{WEAVE} operates in two
+passes; it processes \.{@f}'s and cross-references on the first pass and
+it does the output on the second.
+
+9. You may want some \.{@f} formatting that doesn't correspond to any
+existing reserved word. In that case, \.{WEAVE} could be extended in a
+fairly obvious way to include new ``reserved words'' in its vocabulary.
+The identifier `\&{xclause}' has in fact been included already as a
+reserved word, so that it can be used to format the `\&{loop}' macro,
+where `\&{loop}' is defined to be equivalent to `\&{while \\{true} do}'.
+
+10. Sometimes it is desirable to insert spacing into \PASCAL\ code that is
+more general than the thin space provided by `\.{@,}'. The \.{@t} feature
+can be used for this purpose; e.g., `\.{@t\\hskip 1in@>}' will
+leave one inch of blank space. Furthermore, `\.{@t\\4@>}' can be
+used to backspace by one unit of indentation, since the control sequence
+\.{\\4} is defined in \.{webmac} to be such a backspace. (This
+control sequence is used, for example, at the beginning of lines that
+contain labeled statements, so that the label will stick out a little at
+the left.)
+
+11. \.{WEAVE} and \.{TANGLE} are designed to work with two input files,
+called \\{web\_file} and \\{change\_file}, where \\{change\_file} contains
+data that overrides selected portions of \\{web\_file}. The resulting merged
+text is actually what has been called the \.{WEB} file elsewhere in this
+report.
+
+Here's how it works: The change file consists of zero or more ``changes,''
+where a change has the form `\.{@x}$\langle$old lines$\rangle$\.{@y}$\langle$%
+new lines$\rangle$\.{@z}'. The special control codes \.{@x}, \.{@y}, \.{@z},
+which are allowed only in change files, must appear at the beginning of a line;
+the remainder of such a line is ignored.
+The $\langle$old lines$\rangle$ represent material that exactly matches
+consecutive lines of the \\{web\_file}; the $\langle$new lines$\rangle$
+represent zero or more lines that are supposed to replace the old. Whenever
+the first ``old line'' of a change is found to match a line in the
+\\{web\_file}, all the other lines in that change must match too.
+
+Between changes, before the first change, and after the last change,
+the change file can have any number of lines that do not begin with
+`\.{@x}', `\.{@y}', or~`\.{@z}'. Such lines are bypassed and not used for
+matching purposes.
+
+This dual-input feature is useful when working with a master \.{WEB} file
+that has been received from elsewhere (e.g., \.{TANGLE.WEB} or
+\.{WEAVE.WEB} or \.{TEX.WEB}), when changes are desirable to customize the
+program for your local computer system. You will be able to debug your
+system-dependent changes without clobbering the master web file; and once
+your changes are working, you will be able to incorporate them readily
+into new releases of the master web file that you might receive from time
+to time.
+ \section Appendices.
+The basic ideas of \.{WEB} can be understood most easily by looking at
+examples of ``real'' programs. Appendix~A shows the \.{WEB} input that
+generated modules 55--59 of the \.{WEAVE} program; Appendix~B shows the
+corresponding \TeX\ code output by \.{WEAVE}; and Appendix~C shows excerpts
+from the corresponding \PASCAL\ code output by \.{TANGLE}.
+
+The complete webs for \.{WEAVE} and \.{TANGLE} appear as the bulk of this
+report, in Appendices D and~E. The reader should first compare Appendix~A
+to the corresponding portion of Appendix~D; then the same material should
+be compared to Appendices B and~C. Finally, if time permits, the reader may
+enjoy studying the complete programs in Appendices D and~E, since \.{WEAVE}
+and \.{TANGLE} contain several interesting aspects, and since an attempt
+has been made in these appendices to evolve a style of programming that
+makes good use of the \.{WEB} language.
+
+Finally, Appendix F is the `\.{webmac}' file that sets \TeX\ up to accept
+the output of \.{WEAVE}; Appendix~G discusses how to use some of its macros
+to vary the output formats; and Appendix~H discusses what needs to be done
+when \.{WEAVE} and \.{TANGLE} are installed in a new operating environment.
+ \section Performance statistics.
+The programs in Appendices D and E will optionally keep statistics on
+how much memory they require. Here is what they once printed out when
+processing themselves:
+
+\def\pstat#1#2#3
+#4{\yskip\noindent\.{#1} applied to \.{#2} (cpu time #3 sec)\par
+\halign{\quad\tt##\hfil\cr#4}}
+
+\pstat{TANGLE}{TANGLE}{15}
+{Memory usage statistics:\cr
+456 names, 215 replacement texts;\cr
+3396+3361 bytes, 6685+7329+5805 tokens.\cr}
+
+\pstat{TANGLE}{WEAVE}{30}
+{Memory usage statistics:\cr
+692 names, 339 replacement texts;\cr
+4576+4294 bytes, 10184+9875+9150 tokens.\cr}
+
+\pstat{WEAVE}{TANGLE}{45}
+{Memory usage statistics: 478 names, 2045 cross references, 4159+3729 bytes;\cr
+parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
+sorting required 34 levels.\cr}
+
+\pstat{WEAVE}{WEAVE}{65}
+{Memory usage statistics: 737 names, 3306 cross references, 4896+4962 bytes;\cr
+parsing required 684 scraps, 1300 texts, 3766 tokens, 119 levels;\cr
+sorting required 73 levels.\cr}
+
+\yskip\noindent The cpu time for \PASCAL\ to process \.{TANGLE.PAS} was
+approximately 13 seconds, and \.{WEAVE.PAS} took approximately 26 seconds;
+thus the tangling time was slightly more than the compiling time. The cpu
+time for \TeX\ to process \.{TANGLE.TEX} was approximately 500 seconds,
+and \.{WEAVE.TEX} took approximately 750 seconds (i.e., about 7
+seconds per printed page, where these pages are substantially larger than
+the pages in a normal book). All cpu times quoted are for a DECsystem-10.
+
+\def\K{{\mc K}}
+The file \.{TANGLE.WEB} is about 125\K\ characters long; \.{TANGLE}
+reduces it to a file \.{TANGLE.PAS} whose size is about 42\K\ characters,
+while \.{WEAVE} expands it to a file \.{TANGLE.TEX} of about 185\K\null.
+The corresponding file sizes for \.{WEAVE.WEB}, \.{WEAVE.PAS}, and
+\.{WEAVE.TEX} are 180\K, 89\K, and 265\K.
+
+The much larger file \.{TEX.WEB} led to the following numbers:
+
+\pstat{TANGLE}{TEX}{110}
+{Memory usage statistics:\cr
+3750 names, 1768 replacement texts;\cr
+41895+41053 bytes, 42378+45074+41091 tokens.\cr}
+
+\pstat{WEAVE}{TEX}{270}
+{Memory usage statistics: 3412 names, 19699 cross references,
+ 37900+40232 bytes;\cr
+parsing required 685 scraps, 1303 texts, 3784 tokens, 104 levels;\cr
+sorting required 52 levels.\cr}
+
+\yskip\noindent
+\PASCAL\ did \.{TEX.PAS} in about 75 seconds; \TeX\ did \.{TEX.TEX}
+in about 3600.
+ % Here is a quotation that could not really be omitted
+
+\vfill
+
+{\baselineskip9pt
+\halign to\hsize{\hfil\quoteit#\tabskip 0pt plus 100pt&
+ \hfil\quoteit#\tabskip 0pt\cr
+O, what a tangled web we weave&
+ O, what a tangled WEB we weave\cr
+When first we practise to deceive!&
+ When \TeX\ we practise to conceive!\cr
+\noalign{\vskip 2pt}
+\quoterm ---SIR WALTER SCOTT, {\quoteit Marmion} 6:17 (1808)&
+ \quoterm ---RICHARD PALAIS (1982)\cr
+}}
+\eject
+ \def\runninghead{APPENDIX A --- {\tentt WEB} FILE FORMAT}
+\section Appendix A.
+This excerpt from \.{WEAVE.WEB} produced modules 55--59 in Appendix~D.
+Note that some of the lines are indented to show the program structure.
+The indentation is ignored by \.{WEAVE} and \.{TANGLE}, but users find
+that \.{WEB} files are quite readable if they have some such indentation.
+
+\vskip 6pt
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+% Note to myself: I had to remove SAIL characters from the file here!
+% Also tabs replaced by double-space. The changes were made in WEAVE source.
+\verbatim
+@* Searching for identifiers.
+The hash table described above is updated by the |id_lookup| procedure,
+which finds a given identifier and returns a pointer to its index in
+|byte_start|. The identifier is supposed to match character by character
+and it is also supposed to have a given |ilk| code; the same name may be
+present more than once if it is supposed to appear in the index with
+different typesetting conventions.
+If the identifier was not already present, it is inserted into the table.
+
+Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
+to let |id_lookup| search for an identifier that is present in the |buffer|
+array. Two other global variables specify its position in the buffer: the
+first character is |buffer[id_first]|, and the last is |buffer[id_loc-1]|.
+
+@<Glob...@>=
+@!id_first:0..long_buf_size; {where the current identifier begins in the buffer}
+@!id_loc:0..long_buf_size; {just after the current identifier in the buffer}
+@#
+@!hash:array [0..hash_size] of sixteen_bits; {heads of hash lists}
+
+@ Initially all the hash lists are empty.
+
+@<Local variables for init...@>=
+@!h:0..hash_size; {index into hash-head array}
+
+@ @<Set init...@>=
+for h:=0 to hash_size-1 do hash[h]:=0;
+
+@ Here now is the main procedure for finding identifiers (and index
+entries). The parameter |t| is set to the desired |ilk| code. The
+identifier must either have |ilk=t|, or we must have
+|t=normal| and the identifier must be a reserved word.
+
+@p function id_lookup(@!t:eight_bits):name_pointer; {finds current identifier}
+label found;
+var i:0..long_buf_size; {index into |buffer|}
+@!h:0..hash_size; {hash code}
+@!k:0..max_bytes; {index into |byte_mem|}
+@!w:0..ww-1; {row of |byte_mem|}
+@!l:0..long_buf_size; {length of the given identifier}
+@!p:name_pointer; {where the identifier is being sought}
+begin l:=id_loc-id_first; {compute the length}
+@<Compute the hash code |h|@>;
+@<Compute the name location |p|@>;
+if p=name_ptr then @<Enter a new name into the table at position |p|@>;
+id_lookup:=p;
+end;
+
+@ A simple hash code is used: If the sequence of
+ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
+$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
+
+@<Compute the hash...@>=
+h:=buffer[id_first]; i:=id_first+1;
+while i<id_loc do
+ begin h:=(h+h+buffer[i]) mod hash_size; incr(i);
+ end
+?endgroup % end of verbatim mode
+\endgroup
+\vfill\eject
+ \def\runninghead{APPENDIX B --- TRANSLATION BY {\tentt WEAVE}}
+\section Appendix B.
+This excerpt from \.{WEAVE.TEX} corresponds to Appendix A.
+
+% I've inserted \vfill's here at the blank lines, to squeeze this on one page!
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\verbatim
+?vfill?verbatimgobble
+\N55. Searching for identifiers.
+The hash table described above is updated by the \\{id\_lookup} procedure,
+which finds a given identifier and returns a pointer to its index in
+\\{byte\_start}. The identifier is supposed to match character by character
+and it is also supposed to have a given \\{ilk} code; the same name may be
+present more than once if it is supposed to appear in the index with
+different typesetting conventions.
+If the identifier was not already present, it is inserted into the table.
+?vfill?verbatimgobble
+Because of the way \.{WEAVE}'s scanning mechanism works, it is most convenient
+to let \\{id\_lookup} search for an identifier that is present in the %
+\\{buffer}
+array. Two other global variables specify its position in the buffer: the
+first character is $\\{buffer}[\\{id\_first}]$, and the last is $\\{buffer}[%
+\\{id\_loc}-1]$.
+?vfill?verbatimgobble
+\Y\P$\4\X9:Globals in the outer block\X\mathrel{+}\S$\6
+\4\\{id\_first}: \37$0\to\\{long\_buf\_size}$;\C{where the current identifier
+begins in the buffer}\6
+\4\\{id\_loc}: \37$0\to\\{long\_buf\_size}$;\C{just after the current
+identifier in the buffer}\7
+\4\\{hash}: \37\&{array} $[0\to\\{hash\_size}]$ \1\&{of}\5
+\\{sixteen\_bits};\C{heads of hash lists}\2\par
+\fi
+?vfill?verbatimgobble
+\M56. Initially all the hash lists are empty.
+?vfill?verbatimgobble
+\Y\P$\4\X16:Local variables for initialization\X\mathrel{+}\S$\6
+\4\|h: \37$0\to\\{hash\_size}$;\C{index into hash-head array}\par
+\fi
+?vfill?verbatimgobble
+\M57. \P$\X10:Set initial values\X\mathrel{+}\S$\6
+\&{for} $\|h\K0\mathrel{\&{to}}\\{hash\_size}-1$ \1\&{do}\5
+$\\{hash}[\|h]\K0$;\2\par
+\fi
+?vfill?verbatimgobble
+\M58. Here now is the main procedure for finding identifiers (and index
+entries). The parameter \|t is set to the desired \\{ilk} code. The
+identifier must either have $\\{ilk}=\|t$, or we must have
+$\|t=\\{normal}$ and the identifier must be a reserved word.
+?vfill?verbatimgobble
+\Y\P\4\&{function}\1\ \37$\\{id\_lookup}(\|t:\\{eight\_bits})$: \37\\{name%
+\_pointer};\C{finds current identifier}\6
+\4\&{label} \37\\{found};\6
+\4\&{var} \37\|i: \37$0\to\\{long\_buf\_size}$;\C{index into \\{buffer}}\6
+\|h: \37$0\to\\{hash\_size}$;\C{hash code}\6
+\|k: \37$0\to\\{max\_bytes}$;\C{index into \\{byte\_mem}}\6
+\|w: \37$0\to\\{ww}-1$;\C{row of \\{byte\_mem}}\6
+\|l: \37$0\to\\{long\_buf\_size}$;\C{length of the given identifier}\6
+\|p: \37\\{name\_pointer};\C{where the identifier is being sought}\2\6
+\&{begin} \37$\|l\K\\{id\_loc}-\\{id\_first}$;\C{compute the length}\6
+\X59:Compute the hash code \|h\X;\6
+\X60:Compute the name location \|p\X;\6
+\&{if} $\|p=\\{name\_ptr}$ \1\&{then}\5
+\X62:Enter a new name into the table at position \|p\X;\2\6
+$\\{id\_lookup}\K\|p$;\6
+\&{end};\par
+\fi
+?vfill?verbatimgobble
+\M59. A simple hash code is used: If the sequence of
+ASCII codes is $c_1c_2\ldots c_m$, its hash value will be
+$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,\\{hash\_size}.$$
+?vfill?verbatimgobble
+\Y\P$\4\X59:Compute the hash code \|h\X\S$\6
+$\|h\K\\{buffer}[\\{id\_first}]$;\5
+$\|i\K\\{id\_first}+1$;\6
+\&{while} $\|i<\\{id\_loc}$ \1\&{do}\6
+\&{begin} \37$\|h\K(\|h+\|h+\\{buffer}[\|i])\mathbin{\&{mod}}\\{hash\_size}$;\5
+$\\{incr}(\|i)$;\6
+\&{end}\2\par
+\U section~58.\fi
+?endgroup
+\endgroup
+\eject
+ \def\runninghead{APPENDIX C --- TRANSLATION BY {\tentt TANGLE}}
+\section Appendix C.
+The \.{TANGLE} processor converts \.{WEAVE.WEB} into a syntactically
+correct (but not very pretty) \PASCAL\ program \.{WEAVE.PAS}.
+The first three and last two lines of output are shown here, together with the
+lines of code generated by modules 55--62 and the environments of
+those lines. There are 1559 lines in all; the notation
+`\.. \\. \\.' stands for portions that are not shown.
+
+Note that, for example, the code corresponding to
+module 55 begins with `\.{\{55:\}}' and ends with `\.{\{:55\}}';
+the code from modules 59--62 has been tangled into the code from module 58.
+
+\vskip6pt
+\verbatim
+{2:}{4:}{$C-,A+,D-}{[$C+,D+]}{:4}
+PROGRAM WEAVE(WEBFILE,CHANGEFILE,TEXFILE);LABEL 9999;CONST{8:}
+MAXBYTES=45000;MAXNAMES=5000;MAXMODULES=2000;HASHSIZE=353;BUFSIZE=100;
+ . . .
+TOKPTR:0..MAXTOKS;{MAXTOKPTR,MAXTXTPTR:0..MAXTOKS;}{:53}{55:}
+IDFIRST:0..LONGBUFSIZE;IDLOC:0..LONGBUFSIZE;
+HASH:ARRAY[0..HASHSIZE]OF SIXTEENBITS;{:55}{63:}CURNAME:NAMEPOINTER;
+ . . .
+PROCEDURE INITIALIZE;VAR{16:}I:0..127;{:16}{40:}WI:0..1;{:40}{56:}
+H:0..HASHSIZE;{:56}{247:}C:ASCIICODE;{:247}BEGIN{10:}HISTORY:=0;{:10}
+ . . .
+TOKPTR:=1;TEXTPTR:=1;TOKSTART[0]:=1;TOKSTART[1]:=1;{MAXTOKPTR:=1;
+MAXTXTPTR:=1;}{:54}{57:}FOR H:=0 TO HASHSIZE-1 DO HASH[H]:=0;{:57}{94:}
+SCANNINGHEX:=FALSE;{:94}{102:}MODTEXT[0]:=32;{:102}{124:}OUTPTR:=1;
+ . . .
+IF R=0 THEN XREF[P]:=XREFPTR ELSE XMEM[R].XLINKFIELD:=XREFPTR;END;{:51}
+{58:}FUNCTION IDLOOKUP(T:EIGHTBITS):NAMEPOINTER;LABEL 31;
+VAR I:0..LONGBUFSIZE;H:0..HASHSIZE;K:0..MAXBYTES;W:0..1;
+L:0..LONGBUFSIZE;P:NAMEPOINTER;BEGIN L:=IDLOC-IDFIRST;{59:}
+H:=BUFFER[IDFIRST];I:=IDFIRST+1;
+WHILE I<IDLOC DO BEGIN H:=(H+H+BUFFER[I])MOD HASHSIZE;I:=I+1;END{:59};
+{60:}P:=HASH[H];
+WHILE P<>0 DO BEGIN IF(BYTESTART[P+2]-BYTESTART[P]=L)AND((ILK[P]=T)OR((T
+=0)AND(ILK[P]>3)))THEN{61:}BEGIN I:=IDFIRST;K:=BYTESTART[P];W:=P MOD 2;
+WHILE(I<IDLOC)AND(BUFFER[I]=BYTEMEM[W,K])DO BEGIN I:=I+1;K:=K+1;END;
+IF I=IDLOC THEN GOTO 31;END{:61};P:=LINK[P];END;P:=NAMEPTR;
+LINK[P]:=HASH[H];HASH[H]:=P;31:{:60};IF P=NAMEPTR THEN{62:}
+BEGIN W:=NAMEPTR MOD 2;
+IF BYTEPTR[W]+L>MAXBYTES THEN BEGIN WRITELN(TERMOUT);
+WRITE(TERMOUT,'! Sorry, ','byte memory',' capacity exceeded');ERROR;
+HISTORY:=3;JUMPOUT;END;
+IF NAMEPTR+2>MAXNAMES THEN BEGIN WRITELN(TERMOUT);
+WRITE(TERMOUT,'! Sorry, ','name',' capacity exceeded');ERROR;HISTORY:=3;
+JUMPOUT;END;I:=IDFIRST;K:=BYTEPTR[W];
+WHILE I<IDLOC DO BEGIN BYTEMEM[W,K]:=BUFFER[I];K:=K+1;I:=I+1;END;
+BYTEPTR[W]:=K;BYTESTART[NAMEPTR+2]:=K;NAMEPTR:=NAMEPTR+1;ILK[P]:=T;
+XREF[P]:=0;END{:62};IDLOOKUP:=P;END;{:58}{66:}
+FUNCTION MODLOOKUP(L:SIXTEENBITS):NAMEPOINTER;LABEL 31;VAR C:0..4;
+ . . .
+WRITE(TERMOUT,'(That was a fatal error, my friend.)');END;END{:263};
+END.{:261}
+?endgroup
+\vfill\eject
+ \pageno=197 % take account of the page numbers for App's D and E.
+ \def\runninghead{APPENDIX F --- MACROS FOR FORMATTING}
+\section Appendix F: The \.{webmac.tex} file.
+This is the file that extends ``plain \TeX'' format in order to support the
+features needed by the output of \.{WEAVE}.
+
+\vskip6pt
+\verbatim
+% standard macros for WEB listings (in addition to PLAIN.TEX)
+\xdef\fmtversion{\fmtversion+WEBMAC4.0} % identifies current set of macros
+\parskip 0pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of Pascal text
+
+\font\eightrm=cmr8 \let\sc=\eightrm % NOT a caps-and-small-caps font!
+\let\mainfont=\tenrm
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+\font\tentex=cmtex10 % TeX extended character set (used in strings)
+
+\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\hbox{$#1$}} % one-letter identifiers look a bit better this way
+\def\&#1{\hbox{\bf#1\/}} % boldface type for reserved words
+\def\.#1{\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\'=\RQ % right quote in a string
+ \let\`=\LQ % left quote in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ #1}}
+\def\#{\hbox{\tt\char`\#}} % parameter sign
+\def\${\hbox{\tt\char`\$}} % dollar sign
+\def\%{\hbox{\tt\char`\%}} % percent sign
+\def\^{\ifmmode\mathchar"222 \else\char`^ \fi} % pointer or hat
+% circumflex accents can be obtained from \^^D instead of \^
+\def\AT!{@} % at sign for control text
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\def\LQ{{\tt\char'22}} % left quote in a string
+\chardef\RB=`\} % right brace in a string
+\def\RQ{{\tt\char'23}} % right quote in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+
+\let\yskip=\smallskip
+\def\to{\mathrel{.\,.}} % double dot, used only in math mode
+\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}}
+\def\lapstar{\rlap{*}}
+\def\startsection{\Q\noindent{\let\*=\lapstar\bf\modstar.\quad}}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 }} % begin `define' or `format'
+\def\A{\note{See also section}} % crossref for doubly defined section name
+\def\As{\note{See also sections}} % crossref for multiply defined section name
+\def\B{\mathopen{\.{@\{}}} % begin controlled comment
+\def\C#1{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % Pascal comments
+ \XX\hfil\penalty-1\hfilneg\quad$\{\,$#1$\,\}$\XX}
+\def\D{\defin{define}} % macro definition
+\def\E{\cdot10^} % exponent in floating point constant
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+\def\H#1{\hbox{\rm\char"7D\tt#1}} % hexadecimal constant
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K=\gets % left arrow
+\let\L=\le % less than or equal sign
+\outer\def\M#1.{\MN#1.\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip12ptminus3pt\startsection\ignorespaces}
+\outer\def\N#1.#2.{\MN#1.\vfil\eject % beginning of starred section
+ \def\rhead{\uppercase{\ignorespaces#2}} % define running headline
+ \message{*\modno} % progress report
+ \edef\next{\write\cont{\Z{#2}{\modno}{\the\pageno}}}\next % to contents file
+ \ifon\startsection{\bf\ignorespaces#2.\quad}\ignorespaces}
+\def\MN#1.{\par % common code for \M, \N
+ {\xdef\modstar{#1}\let\*=\empty\xdef\modno{#1}}
+ \ifx\modno\modstar \onmaybe \else\ontrue \fi \mark{\modno}}
+\def\O#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant
+\def\P{\rightskip=0pt plus 100pt minus 10pt % go into Pascal mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\Q{\rightskip=0pt % get out of Pascal mode
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50 }
+\let\R=\lnot % logical not
+\let\S=\equiv % equivalence sign
+\def\T{\mathclose{\.{@\}}}} % terminate controlled comment
+\def\U{\note{This code is used in section}} % crossref for use of a section
+\def\Us{\note{This code is used in sections}} % crossref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,$#2{\eightrm\kern.5em#1}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\let % now you can \send the control sequence \Z
+\def\){\hbox{\.{@\$}}} % sign for string pool check sum
+\def\]{\hbox{\.{@\\}}} % sign for forced line break
+\def\=#1{\kern2pt\hbox{\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule}\kern2pt} % verbatim string
+\let\~=\ignorespaces
+\let\*=*
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
+\def\lheader{\mainfont\the\pageno\eightrm\qquad\rhead\hfill\title\qquad
+ \tensy x\mainfont\topmark} % top line on left-hand pages
+\def\rheader{\tensy x\mainfont\topmark\eightrm\qquad\title\hfill\rhead
+ \qquad\mainfont\the\pageno} % top line on right-hand pages
+\def\page{\box255 }
+\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+ \shipout\vbox{
+ \vbox to\fullpageheight{
+ \iftitle\global\titlefalse
+ \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+ \vfill#1}} % parameter #1 is the page itself
+ \global\advance\pageno by1}
+
+\def\rhead{\.{WEB} OUTPUT} % this running head is reset by starred sections
+\def\title{} % an optional title can be set by the user
+\def\topofcontents{\centerline{\titlefont\title}
+ \vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill} % this material will end the table of contents page
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.7in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+ \fullpageheight=9truein\setpage}
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+\def\contentsfile{CONTENTS} % file that gets table of contents info
+\def\readcontents{\input CONTENTS}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \global\output{\normaloutput\page\lheader\rheader}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \write\cont{} % ensure that the contents file isn't empty
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\:##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \let\ttentry=\. \def\.##1{\ttentry{##1\kern.2em}} % give \tt a little room
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
+ \def\rhead{NAMES OF THE SECTIONS}
+ \message{Section names:}
+ \output{\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\hfil\penalty-1\hfilneg\quad{\eightrm##1 ##2.}}
+ \linepenalty=10 % try to conserve lines
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\:{\par\hangindent 2em}\let\*=*\let\.=\ttentry}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage
+ \output{\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber \def\rhead{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \def\Z##1##2##3{\line{\ignorespaces##1
+ \leaders\hbox to .5em{.\hfil}\hfil\ ##2\hbox to3em{\hss##3}}}
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+?endgroup
+\vfill\eject
+ \def\runninghead{APPENDIX G --- NOTES ON FORMATTING}
+\section Appendix G: How to use \.{WEB} macros.
+The macros in \.{webmac} make it possible to produce a variety of formats
+without editing the output of \.{WEAVE}, and the purpose of this appendix
+is to explain some of the possibilities.
+
+\def\point#1.{\yskip\indent#1.\quad\ignorespaces}
+
+\point 1. Three fonts have been declared in addition to the standard fonts of
+\.{PLAIN} format: You can say `\.{\{\\sc STUFF\}}' to get {\sc STUFF}
+in small caps; and you can select the largish fonts \.{\\titlefont}
+and \.{\\ttitlefont} in the title of your document, where \.{\\ttitlefont}
+is a typewriter style of type.
+
+\point 2. When you mention an identifier in \TeX\ text, you normally call
+it `\.{|identifier|}'. But you can also say `\.{\\\\\{identifier\}}'. The
+output will look the same in both cases, but the second alternative
+doesn't put \\{identifier} into the index, since
+it bypasses \.{WEAVE}'s translation from \PASCAL\ mode.
+
+\point 3. To get typewriter-like type, as when referring to `\.{WEB}', you
+can use the `\.{\\.}' macro (e.g., `\.{\\.\{WEB\}}'). In the argument to
+this macro you should insert an additional backslash before the symbols
+listed as `special string characters' in the index to \.{WEAVE}, i.e.,
+before backslashes and dollar signs and the like.
+A `\.{\\\ }' here will result in the visible space symbol; to get an
+invisible space following a control sequence you can say `\.{\{\ \}}'.
+
+\point 4. The three control sequences \.{\\pagewidth}, \.{\\pageheight},
+and \.{\\fullpageheight} can be redefined in the limbo section at the
+beginning of your \.{WEB} file, to change the dimensions of each page.
+The standard settings
+$$\lpile{\.{\\pagewidth=6.5in}\cr
+ \.{\\pageheight=8.7in}\cr
+ \.{\\fullpageheight=9in}\cr}$$
+were used to prepare the present report; \.{\\fullpageheight} is
+\.{\\pageheight} plus room for the additional heading and page numbers at
+the top of each page. If you change any of these quantities, you should
+call the macro \.{\\setpage} immediately after making the change.
+
+\point 5. The \.{\\pageshift} macro defines an amount by which right-hand
+pages (i.e., odd-numbered pages) are shifted right with respect to
+left-hand (even-numbered) ones. By adjusting this amount you may be
+able to get two-sided output in which the page numbers line up on
+opposite sides of each sheet.
+
+\point 6. The \.{\\title} macro will appear at the top of each page
+in small caps. For example, Appendix~D was produced after saying
+`\.{\\def\\title\{WEAVE\}}'.
+
+\point 7. The first page usually is assigned page number 1.
+To start on page 16, with contents
+on page 15, say this: `\.{\\def\\contentspagenumber\{15\}}
+\.{\\pageno=\\contentspagenumber} \.{\\advance\\pageno by 1}'. (Appendix~D
+was generated that way.)
+
+\point 8. The macro \.{\\iftitle} will suppress the header line if it is
+defined by `\.{\\titletrue}'. The normal value is \.{\\titlefalse}
+except for the table of contents; thus, the contents
+page is usually unnumbered.
+
+Two macros are provided to give flexibility to the table of
+contents: \.{\\topofcontents} is invoked just before the contents
+info is read, and \.{\\botofcontents} is invoked just after.
+For example, Appendix~D was produced with the following definitions:
+$$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
+ \.{ { }\\titlefalse \% include headline on the contents page}\cr
+ \.{ { }\\def\\rheader\{\\mainfont Appendix D\\hfil 15\}}\cr
+ \.{ { }\\centerline\{\\titlefont The \{\\ttitlefont WEAVE\}{ }processor\}}\cr
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4)\}{ }\\vfill\}}\cr}$$
+Redefining \.{\\rheader}, which is the headline for right-hand pages,
+suffices in this case to put the desired information at the top of the
+contents page.
+
+\point 9. Data for the table of contents is written to a file that
+is read after the indexes have been \TeX ed; there's one line of data
+for every starred module. For example, when Appendix~D was being generated,
+a file \.{CONTENTS.TEX} containing
+$$\lpile{\.{\\Z \{{ }Introduction\}\{1\}\{16\}}\cr
+ \.{\\Z \{{ }The character set\}\{11\}\{19\}}\cr}$$
+and similar lines was created. The \.{\\topofcontents} macro could
+redefine \.{\\Z} so that the information appears in another format.
+
+\point 10. Sometimes it is necessary or desirable to divide the output of
+\.{WEAVE} into subfiles that can be processed separately. For example,
+the listing of \TeX\ runs to more than 500 pages, and that is enough to
+exceed the capacity of many printing devices and/or their software.
+When an extremely large job isn't cut into smaller pieces, the entire
+process might be spoiled by a single error of some sort, making it
+necessary to start everything over.
+
+Here's a safe way to break a woven file into three parts:
+Say the pieces are $\alpha$,
+$\beta$, and $\gamma$, where each piece begins with a starred module.
+All macros should be defined in the opening limbo section of $\alpha$,
+and copies of this \TeX\ code should be placed at the
+beginning of $\beta$ and of $\gamma$. In order to process the parts
+separately, we need to take care of two things: The starting page
+numbers of $\beta$ and $\gamma$ need to be set up properly, and
+the table of contents data from all three runs needs to be
+accumulated.
+
+The \.{webmac} macros include two control sequences \.{\\contentsfile} and
+\.{\\readcontents} that facilitate the necessary processing. We include
+`\.{\\def\\contentsfile\{CONT1\}}' in the limbo section of $\alpha$, and
+we include `\.{\\def\\contentsfile\{CONT2\}}' in the limbo section of
+$\beta$; this causes \TeX\ to write the contents data for $\alpha$ and $\beta$
+into \.{CONT1.TEX} and \.{CONT2.TEX}. Now in $\gamma$ we say
+$$\.{\\def\\readcontents\{\\input CONT1 \\input CONT2 \\input CONTENTS\}};$$
+this brings in the data from all three pieces, in the proper order.
+
+However, we still need to solve the page-numbering problem. One way to
+do it is to include the following in the limbo material for $\beta$:
+$$\lpile{\.{\\message\{Please type the last page number of part 1: \}}\cr
+ \.{\\read -1 to \\temp \\pageno=\\temp \\advance\\pageno by 1}\cr}$$
+Then you simply provide the necessary data when \TeX\ requests
+it; a similar construction is used at the beginning of $\gamma$.
+
+This method can, of course, be used to divide a woven file into
+any number of pieces.
+
+\point 11. Sometimes it is nice to include things in the index that are
+typeset in a special way. For example, we might want to have an
+index entry for `\TeX'. \.{WEAVE} provides two simple ways to
+typeset an index entry (unless the entry is an identifier or a reserved word):
+`\.{@\^}' gives roman type, and `\.{@.}' gives typewriter type.
+But if we try to typeset `\TeX' in roman type by saying, e.g.,
+`\.{@\^\\TeX@>}', the backslash character gets in the way,
+and this entry wouldn't appear in the index with the T's.
+
+The solution is to use the `\.{@:}' feature, declaring a macro that
+simply removes a sort key as follows:
+$$\.{\\def\\9\#1\{\}}$$
+Now you can say, e.g., `\.{@:TeX\}\{\\TeX@>}' in your \.{WEB} file; \.{WEAVE}
+puts it into the index alphabetically, based on the sort key, and
+produces the macro call `\.{\\9\{TeX\}\{\\TeX\}}' which will ensure that
+the sort key isn't printed.
+
+A similar idea can be used to insert hidden material into module
+names so that they are alphabetized in whatever way you might wish.
+Some people call these tricks ``special refinements''; others call
+them ``kludges''.
+
+\point 12. The control sequence \.{\\modno} is set to the number of the
+module being typeset.
+
+\point 13. If you want to list only the modules that have changed,
+together with the index, put the command `\.{\\let\\maybe=\\iffalse}' in
+the limbo section before the first module of your \.{WEB} file. It's
+customary to make this the first change in your change file.
+
+\point 14. To get output in languages other than English, redefine the
+macros \.{\\A}, \.{\\As}, \.{\\ET}, \.{\\ETs}, \.{\\U}, \.{\\Us},
+\.{\\ch}, \.{\\fin}, and \.{\\con}. \.{WEAVE} itself need not be changed.
+
+\vfill\eject
+ \def\runninghead{APPENDIX H --- GETTING STARTED}
+\section Appendix H: Installing the \.{WEB} system.
+Suppose you want to use the \.{WEB} programs on your computer, and suppose
+that you can't simply borrow them from somebody else who has the same
+kind of machine. Here's what to do:
+
+\yskip
+\def\step(#1){\par\hangindent 2em\noindent\hbox to 2em{\hfil(#1) }\ignorespaces}
+\step(1) Get a tape that contains the files \.{WEAVE.WEB}, \.{TANGLE.WEB},
+\.{TANGLE.PAS}, and \.{WEBMAC.TEX}. The tape will probably also contain an
+example change file \.{TANGLE.CH}.
+\step(2) Look at the sections of \.{TANGLE} that are listed under ``system
+dependencies'' in the index of Appendix~E above, and figure out what changes
+(if any) will be needed for your system.
+\step(3) Make a change file \.{TANGLE.CH} that contains the changes of~(2);
+do not change your copy of \.{TANGLE.WEB}, leave it intact. (The
+rules for change files are explained at the end of the manual just before
+the appendices; you may want to look at the example change file that
+arrived with your copy of \.{TANGLE.WEB}. It's also a good idea to
+define all the ``switches'' like \&{debug} and \&{gubed} to be null in your
+first change files; then you can sure that your compiler will handle
+all of the code.)
+\step(4) Make the changes of (2) in your copy of \.{TANGLE.PAS}. (If these
+changes are extensive, you might be better off finding some computer that
+that already has \.{TANGLE} running, and making the new \.{TANGLE.PAS}
+from \.{TANGLE.WEB} and your \.{TANGLE.CH}.)
+\step(5) Use your \PASCAL\ compiler to convert your copy of \.{TANGLE.PAS}
+to a running program \.{TANGLE}.
+\step(6) Check your changes as follows: Run \.{TANGLE} on \.{TANGLE.WEB}
+and your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}'$; make a running
+program $\.{TANGLE}'$ by applying \PASCAL\ to
+$\.{TANGLE.PAS}'$; run $\.{TANGLE}'$ on \.{TANGLE.WEB} and
+your \.{TANGLE.CH}, yielding $\.{TANGLE.PAS}''$; and check
+that $\.{TANGLE.PAS}''$ is identical to
+$\.{TANGLE.PAS}'$. Once this test has been passed, you have got a
+working \.{TANGLE} program.
+\step(7) Make a change file \.{WEAVE.CH} analogous to (3), but this time
+consider the system-dependent parts of \.{WEAVE} that are listed in
+the index to Appendix~D.
+\step(8) Run \.{TANGLE} on \.{WEAVE.WEB} and your \.{WEAVE.CH}, obtaining
+\.{WEAVE.PAS}.
+\step(9) Use \PASCAL\ on \.{WEAVE.PAS} to make a running \.{WEAVE} program.
+\step(10) Run \.{WEAVE} on \.{TANGLE.WEB} and \.{TANGLE.CH} to produce
+\.{TANGLE.TEX}.
+\step(11) Run \TeX\ on \.{TANGLE.TEX}, obtaining a listing analogous to
+Appendix~E. This listing will incorporate your changes.
+\step(12) Run \.{WEAVE} on \.{WEAVE.WEB} and your \.{WEAVE.CH} to produce
+\.{WEAVE.TEX}.
+\step(13) Run \TeX\ on \.{WEAVE.TEX}, obtaining a listing analogous to
+Appendix~D that incorporates your changes.
+
+\yskip\noindent
+This description assumes that you already have a working \TeX82 system.
+But what if you don't have \TeX82? Then you start with a tape that also
+contains \.{TEX.WEB} and \.{plain.tex}, and you refer to a hardcopy
+listing of the \TeX82 program corresponding to \.{TEX.WEB}. Between steps
+(10) and (11) you do the following:
+
+\yskip
+\def\substep(10.#1){\par\hangindent 4em\noindent
+ \hbox to 4em{\hfil(10.#1) }\ignorespaces}
+\substep(10.1) Make a change file \.{TEX.CH} to fix the system dependent
+portions of \.{TEX.WEB}, in a manner analogous to step~(2). Since \TeX\ is
+a much more complex program than \.{WEAVE} or \.{TANGLE}, there are more
+system-dependent features to think about, but by now you will be good at
+making such modifications. Do not make any changes to \.{TEX.WEB}.
+\substep(10.2) Make an almost-copy of your \.{TEX.CH} called \.{INITEX.CH};
+this one will have the `\&{init}' and `\&{tini}' macros redefined in order
+to make the initialization version of \TeX. It also might have smaller
+font memory and dynamic memory areas, since \.{INITEX} doesn't need as
+much memory for such things; by setting the memory smaller in \.{INITEX},
+you guarantee that the production system will have a ``cushion.''
+\substep(10.3) Run \.{TANGLE} on \.{TEX.WEB} and \.{INITEX.CH}, obtaining
+\.{INITEX.PAS} and \.{TEX.POOL}.
+\substep(10.4) Run \PASCAL\ on \.{INITEX.PAS}, obtaining \.{INITEX}.
+\substep(10.5) Run \.{INITEX} on \.{TEX.POOL}, during which run you type
+`\.{plain}' and `\.{\\dump}'. This will produce a file \.{plain.fmt}
+containing the data needed to initialize \TeX's memory.
+\substep(10.6) Run \.{TANGLE} on \.{TEX.WEB} and the \.{TEX.CH} of (10.1),
+obtaining \.{TEX.PAS}.
+\substep(10.7) Run \PASCAL\ on \.{TEX.PAS}, obtaining \.{VIRTEX}.
+\substep(10.8) If your operating system supports programs whose core images
+have been saved, run \.{VIRTEX}, type `\.{\&plain}', then save the core image
+and call it \TeX. Otherwise, \.{VIRTEX} will be your \TeX, and it will
+read `\.{plain.fmt}' (or some other \.{fmt} file) each time you run.
+
+\yskip
+This 21-step process may seem long, but it is actually an oversimplification,
+since you also need fonts and a way to print the device-independent files
+that \TeX\ spews out. On the other hand, the total number of steps is not
+quite so large when you consider that \.{TANGLE}-followed-by-\PASCAL\ and
+\.{WEAVE}-followed-by-\TeX\ may be regarded as single operations.
+
+If you have only the present report, not a tape, you will have to prepare
+files \.{WEAVE.WEB} and \.{TANGLE.WEB} by hand, typing them into the
+computer by following Appendices D and E. Then you have to simulate the
+behavior of \.{TANGLE} by converting \.{TANGLE.WEB} manually into
+\.{TANGLE.PAS}; with a good text editor this takes about six hours. Then
+you have to correct errors that were made in all this hand work; but still
+the whole project is not impossibly difficult, because in fact the entire
+development of \.{WEAVE} and \.{TANGLE} (including the writing of the
+programs and this manual) took less than two months of work.
+ \vfill\end