diff options
author | Karl Berry <karl@freefriends.org> | 2021-03-08 18:32:57 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-03-08 18:32:57 +0000 |
commit | b8bbb5c4096ec141403ff5e06e55c25eb7f3c805 (patch) | |
tree | 64c2b4b1b84765421aba98966cb8a4d9a297015c /Master | |
parent | a4aa2281f58a777d7188ff716f0b38e78098e480 (diff) |
knuth-errata sources their own package, following CTAN
git-svn-id: svn://tug.org/texlive/trunk@58225 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
22 files changed, 29295 insertions, 11 deletions
diff --git a/Master/texmf-dist/doc/generic/knuth-errata/cm85.bug b/Master/texmf-dist/doc/generic/knuth-errata/cm85.bug new file mode 100644 index 00000000000..d8cbea6442d --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/cm85.bug @@ -0,0 +1,1906 @@ +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 + +@x in CALU, I decided in July 2005 that I really wanted a less swashy F +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 +@y +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+(0,.15asc_height){up}...{right}(z1-(2u,0)) + ---z6...{down}z7; % upper bar +@z + +@x in SYMBOL, two points of Hardy's asymptotic equivalence sign were unlabeled +labels(1,2,3,4); endchar; +@y +labels(1,2,3,4,5,6); endchar; +@z + +@x in GREEKL, correct a tiny notch that can show up at hires (Charles Duan) +filldraw z1l--z2l--z--z1r--cycle; % stem +@y +filldraw z1l--z2l...(x3,y2l)...z--z1r--cycle; % stem +@z + +@x in GREEKL, make almost-invisible semantic corrections to beta +x0=x1=x9; lft x0l=hround(1.5u-.5hair); x2=x4=x6=x8=.5w-.25u; +@y +x0=x1=x9; lft x0r=hround(1.5u-.5hair); x2=x4=x6=x8=.5w-.25u; +@z +@x +y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8=-oo; y7=y9=.55[y6,y8]; +@y +y5=.5[y4,y6]; top y6r-bot y4r=vstem+eps; bot y8r=-oo; y7=y9=.55[y6,y8]; +@z +@x and also to delta +y5+.1x_height=y7=.5[y6,y8]; bot y6=-oo; +@y +y5+.1x_height=y7=.5[y6,y8]; bot y6r=-oo; +@z +@x and also to phi +top y1=x_height+oo; y2=y4=.5[y1,y3]; bot y3=-oo; +@y +top y1r=x_height+oo; y2=y4=.5[y1,y3]; bot y3r=-oo; +@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-dist/doc/generic/knuth-errata/errata.eight b/Master/texmf-dist/doc/generic/knuth-errata/errata.eight new file mode 100644 index 00000000000..f7ceafd9f69 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.eleven b/Master/texmf-dist/doc/generic/knuth-errata/errata.eleven new file mode 100644 index 00000000000..64d9f8ab457 --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/errata.eleven @@ -0,0 +1,317 @@ +% 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, 2001}} +\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\/} between the first ``Millennium edition'' of 2000 and the +second such edition, which appeared late in 2001. +(More precisely, it lists errors to the 16th, 7th, 6th, 4th, and 5th +printings of Volumes A, B, C, D, and E, respectively, that were corrected +in the 17th, 8th, 7th, 5th, and 6th printings.) +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 A16, line 7 from the bottom (06/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 (06/30/01) + +\ninepoint\indent +fications that grow in geometric ratios---something like equal-tempered +tuning\cutpar + +\bugonpage A51, lines 18--20 (06/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 (06/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 (06/30/01) + +\tenpoint\indent +One of the interesting things that can happen when glue stretches and\cutpar + +\bugonpage A180, line 20 (06/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 (04/09/01) + +\ninepoint\noindent +\begintt +\output={\unvbox255 + \ifnum\outputpenalty<10000 \penalty\outputpenalty\fi} +\endtt + +\bugonpage A292, lines 13--16 (06/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 (06/30/01) + +\ninepoint\noindent +instead of a shelf{\kern0pt}ful. +In fact, the latter idea---to +insert an italic correction---is prefer-\cutpar + +\bugonpage A323, line 12 from the bottom (06/30/01) + +\ninepoint\noindent +\hbox to\parindent{\bf\hss18.31.\enspace}% +|$k=1.38065\times10^{-16}\rm\,erg\,K^{-1}$|. + +\bugonpage A451, line 15 (01/30/01) + +\tenpoint\noindent +{\sl Connecticut Yankee\/} come out with only nine or +ten bad hyphens: + +\bugonpage A451, line 23 (01/30/01) + +\tenpoint\noindent\begintt + mo-er-der-mohren-mut-ter-mar-mor-mon-u-menten-macher. +\endtt + +\bugonpage A454, lines 23--30 (06/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 (07/08/01) + +\eightpoint\noindent +\llap{*}|\char|, {\it 43--45}, 76, 86, 155, 283, $\underline{286}$, + +\bugonpage A466, left column (07/09/01) + +\eightpoint\noindent +\llap{*}|\floatingpenalty|, $\underline{123}$--$\underline{124}$, + 272, 281, {\it 363}. + +\bugonpage A473, left column (06/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 + +\hsize=35pc + +\bugonpage B8, line 2 (05/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$ (05/04/01) + +\ninepoint\noindent +\quad{\bf begin} \\{update\_terminal};\quad$\{\,$now the user sees + the prompt for sure$\,\}$ + +\bugonpage B84, lines 22 and 27 (05/04/01) + +\ninepoint\noindent +\quad$\\{ignore}=9$\quad$\{\,$characters to ignore ( |^^@| )$\,\}$\par +\noindent +\quad$\\{active\_char}=13$\quad$\{\,$characters that invoke + macros ( |~| )$\,\}$ + +\bugonpage B280, lines 23 and 24 (04/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 B382, line 6 (01/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 (04/08/01) + +\ninepoint\noindent +\quad$\\{qi}(2),\\{qi}(6)$: {\bf begin} $\\{cur\_r}\gets\\{rem\_byte}(q)$;% + \quad$\{\,$\||=:|, \||=:>|$\,\}$ + +\bugonpage B475, line 12 (07/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 +\def\ddashto{\mathrel{\hbox{-\thinspace-\thinspace-\kern-.05em}}} +\def\tension{\mathop{\rm tension}} +\def\controls{\mathop{\rm controls}} +\def\and{\,{\rm and}\,} + +\bugonpage C204, line 3 from the bottom (07/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 (07/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 C313, bottom line (06/30/01) + +\rightline{\eightss--- LA ROCHEFOUCAULD, {\eightssi Maximes\/}\enspace(1665)} + +\bugonpage C352, left column (06/30/01) + +\eightpoint\noindent +La Rochefoucauld, Fran\c cois VI, 313. + +\bugonpage C357, right column (07/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 + +\hsize=35pc + +\bugonpage D8, line 2 (05/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$ (05/04/01) + +\ninepoint\noindent +\quad{\bf begin} \\{update\_terminal};\quad$\{\,$now the user sees + the prompt for sure$\,\}$ + +\bugonpage D101, line 21 (07/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 (01/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 D196, lines 7 and 8 (01/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 (07/03/01) + +\tenpoint\noindent +from appearing again. + +% volume E +\hsize=29pc + +\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 `--' + +\bugonpage E9, line 9 (07/03/01) + +\tenpoint\indent +|[92] [123] [124]) ) )| + +\bye + + diff --git a/Master/texmf-dist/doc/generic/knuth-errata/errata.five b/Master/texmf-dist/doc/generic/knuth-errata/errata.five new file mode 100644 index 00000000000..4e2982f109a --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.four b/Master/texmf-dist/doc/generic/knuth-errata/errata.four new file mode 100644 index 00000000000..11d0435e749 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.nine b/Master/texmf-dist/doc/generic/knuth-errata/errata.nine new file mode 100644 index 00000000000..f562cb0bd8a --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/errata.nine @@ -0,0 +1,235 @@ +% 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 A49, top (9/1/96) + +\eightpoint\noindent +[The copy on pages 45 and 46 was significantly shortened +in the seventeenth printing (October 1989 --- see {\tt errata.five}), +and exercise 8.7 moved back to page 48 as a result. But the printer +was not asked to change page 49; hence exercise 8.7 appeared twice, +on pages 48 {\it and\/}~49, during a six-year period.] + +\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/96) + +\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-dist/doc/generic/knuth-errata/errata.one b/Master/texmf-dist/doc/generic/knuth-errata/errata.one new file mode 100644 index 00000000000..471971958c3 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.seven b/Master/texmf-dist/doc/generic/knuth-errata/errata.seven new file mode 100644 index 00000000000..0866189da51 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.six b/Master/texmf-dist/doc/generic/knuth-errata/errata.six new file mode 100644 index 00000000000..ad7444d8600 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errata.ten b/Master/texmf-dist/doc/generic/knuth-errata/errata.ten new file mode 100644 index 00000000000..9efa2a3e503 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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 first ``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-dist/doc/generic/knuth-errata/errata.tex b/Master/texmf-dist/doc/generic/knuth-errata/errata.tex new file mode 100644 index 00000000000..3a0d367f0ca --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/errata.tex @@ -0,0 +1,1802 @@ +% Bugs (sigh) in Computers \& Typesetting --- the most recent errata + +\tracingpages=1 +\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\endgraf}} + +\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 beginning of 2014. +(More precisely, it lists errors corrected +since the 19th printing of Volume~A, the 9th printing +of Volume~B, the 8th printing of Volume~C, the 6th printing of Volume~D, +and the 7th printing of Volume~E. % 2012 for A-D, 2013 for E +But it omits changes that are ``purely cosmetic.'') +Corrections made to the softcover version of {\sl The \TeX book\/}, +beginning with its 32nd printing, are +the same as corrections to Volume~A\null. Corrections to the softcover +version of {\sl The \slMF\kern1ptbook}, beginning with its 11th printing, +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 A34, line 3 from the bottom (01/09/20) + +\ninepoint\noindent +not, you can say +`\.{I\char`\\errorcontextlines=100} \.{\char`\\oops}' and try again. \ (That +will usually\cutpar + +\bugonpage A43, line 6 (07/24/14) + +\tenpoint\noindent +keyboard, or that have been +pre\"empted for formatting? + +\bugonpage A49, cummings quote (08/03/19) + +(delete the period at the end of the line) + +\bugonpage A66, line 3 from the bottom (08/26/17) + +\ninepoint +Such displays of box contents will be discussed further in +Chapters 12 and~27.\cutpar + +\bugonpage A105, lines 9--16 (01/16/21) + +\ddanger If you say \.{\char`\\vadjust\char`\{}$\langle\,$vertical +mode material$\,\rangle$\.{\char`\}} within a +paragraph, \TeX\ will use internal vertical mode to insert the specified +material into the vertical +list that encloses the paragraph, immediately after whatever line +contained the position of the \.{\char`\\vadjust}. For example, you can say +`\.{\char`\\vadjust\char`\{\char`\\kern1pt\char`\}}' +to increase the amount of space between lines of a +paragraph if those lines would otherwise come out too close together. \ (The +\vadjust{\kern1pt}author +did that in the current line, just to illustrate what happens.) \ Also, +if you want to make sure that a page break will occur immediately after a +certain line, you can say `\.{\char`\\vadjust\char`\{\char`\\eject\char`\}}' +anywhere in that line. + +\bugonpage A122, lines 3--8 (11/24/19) + +\ninepoint\noindent +\.{\char`\\count255}, \.{\char`\\dimen255}, \.{\char`\\skip255}, +\.{\char`\\muskip255}, and \.{\char`\\toks255} are +traditionally kept available for such purposes. Furthermore, plain \TeX\ +reserves \.{\char`\\dimen0} to \.{\char`\\dimen9}, +\.{\char`\\skip0} to \.{\char`\\skip9}, \.{\char`\\muskip0} to +\.{\char`\\muskip9}, and \.{\char`\\box0} to \.{\char`\\box9} +for ``scratchwork''; these registers +are never allocated by the \.{\char`\\new...}\null\ operations. We have seen that +\.{\char`\\count0} through \.{\char`\\count9} are special, +and \.{\char`\\box255} also turns out to +be special; so those registers should be avoided unless you know what you +are doing. + +\bugonpage A155, line 8 from the bottom (01/17/21) + +\ninepoint\indent +\.{\char`\\mathopen\char`\{\char`\\hbox\char`\{\char`\$\char`\\left\char`\#1}% +$\langle\,$strut$\,\rangle$\.{\char`\\right.\char`\$\char`\}\char`\}} + +\bugonpage A155, the bottom six lines (12/10/18) + +\ninepoint\noindent +dividual symbols; \.{\char`\\left}$\,\ldots\,$\.{\char`\\right} +constructions are treated as ``inner'' subformulas, which means that +they will be surrounded by additional space in certain circumstances. +All other subformulas are generally treated as ordinary symbols, +whether they are formed by \.{\char`\\overline} or +\.{\char`\\hbox} or \.{\char`\\vcenter} or +by simply being enclosed in braces. Thus, \.{\char`\\mathord} isn't really +a necessary part of the \TeX\ language; instead of typing +`\.{\char`\$1\char`\\mathord,234\char`\$}' you can get the same +effect from `\.{\char`\$1\char`\{,\char`\}234\char`\$}'. + +\bugonpage A158, line 19 (12/10/18) + +\ninepoint\indent +Inner\quad is an inner atom produced by + `\.{\char`\\left}$\,\ldots\,$\.{\char`\\right}'; + +\bugonpage A170, lines 18 and 19 (12/10/18) + +\ninepoint\noindent +subformulas delimited by \.{\char`\\left} and \.{\char`\\right} +are treated as type~Inner. The following table is +used to determine the spacing between pairs of adjacent atoms: + +\bugonpage A171, line 19 from the bottom (06/15/19) + +\ninepoint\noindent +formula produces a result essentially equivalent to +`\.{\char`\\left(}$\langle\,$subformula$\,\rangle$\.{\char`\\right)}', +when\cutpar + +\bugonpage A215, line 16 from the bottom becomes two lines (10/13/20) + +\ninepoint +\item\bull Just after a token such as \.{\char`\$}$_3$ +that begins math mode, to see if +another token of category 3 follows. + +\bugonpage A222, lines 21--23 (01/16/21) + +\ninepoint +\halign{\indent#\hfil&\quad(see Chapter #)\hfil\cr +\.{\char`\\hbox}$\langle\,$box specification$\,\rangle$% + \.{\char`\{}$\langle\,$horizontal mode material$\,\rangle$\.{\char`\}}&12\cr +\.{\char`\\vbox}$\langle\,$box specification$\,\rangle$% + \.{\char`\{}$\langle\,$vertical mode material$\,\rangle$\.{\char`\}}&12\cr +\.{\char`\\vtop}$\langle\,$box specification$\,\rangle$% + \.{\char`\{}$\langle\,$vertical mode material$\,\rangle$\.{\char`\}}&12\cr +} + +\bugonpage A222, lines 11--13 from the bottom (01/16/21) + +\ninepoint\noindent +ter~15. The \.{\char`\\vsplit} operation +is also explained in Chapter~15. In math modes an additional +type of box is available: +\.{\char`\\vcenter}$\langle\,$box specification$\,\rangle$% + \.{\char`\{}$\langle\,$vertical mode material$\,\rangle$\.{\char`\}} +(see Chapter~17). + +\bugonpage A232, line 14 (01/10/21) + +\ninepoint\noindent +tabs outside; `\.{\char`\\global\char`\\settabs}' will not do what +you might think it should. + +\bugonpage A233, lines 3--5 (04/27/15) + +\tenpoint\noindent +Only two tabs are set in this case, because only two \.{\char`\&}'s +appear in the sample line. \ (A sample line usually +ends with~\.{\char`\&\char`\\cr}, as it does here, +because text material between the last tab and \.{\char`\\cr} +isn't used for anything.) + +\bugonpage A252, lines 5--7 (12/25/20) + +\ninepoint\noindent +blank, and +the footline is normally a centered page number, but you can specify any +headline and footline that you want by changing the token lists +\.{\char`\\headline} and \.{\char`\\footline}. For example, + +\bugonpage A253, lines 7--9 from the bottom (10/27/20) + +\ninepoint\indent +\.{\char`\\everypar} or \.{\char`\\errhelp}, except that \TeX\ +retains the begin-group symbol~`\.{\char`\{}' at the beginning +and the end-group symbol~`\.{\char`\}}' at the end. These +grouping characters +help to keep the output routine from interfering with what +\TeX\ was doing\cutpar + +\bugonpage A256, line 19 (08/28/15) + +\ninepoint\indent +\tt \char`\\baselineskip=24pt \char`\\lineskiplimit=0pt + +\bugonpage A277, lines 9 and 10 from the bottom (08/26/17) + +\ninepoint\indent +$\langle\,$hyphenation assignment$\,\rangle$\is + \.{\char`\\hyphenation}$\langle\,$filler$\,\rangle$% + \.{\char`\{}$\langle\,$hyphenations$\,\rangle$\.{\char`\}}\par +\qquad \alt \.{\char`\\patterns}$\langle\,$filler$\,\rangle$% + \.{\char`\{}$\langle\,$patterns$\,\rangle$\.{\char`\}} + +\bugonpage A286, bottom two lines {(and affecting the top lines +of page 287)} (08/26/17) + +\ninepoint\noindent +stands for zero or more \<assignment> +commands other than \.{\char`\\setbox}, possibly with \<filler>. +If the assignments are not followed by a \<character>, where +\<character> stands\cutpar + +\bugonpage A287, lines 11--17 (04/22/20) + +\ninepoint +\textindent{$\bull$} \.{\char`\\discretionary}% + \<disc text>\<disc text>\<disc text>.\enskip +A \<disc text> has the form +`\<filler>\.{\char`\{}\<horizontal mode material>\.{\char`\}}', +where the material is processed in restricted horizontal mode and +should contain only fixed-width things. +More precisely, the horizontal list formed by each +\<disc text> must consist only of characters, ligatures, +kerns, boxes, and rules; there should be no glue or penalty items, etc. +This command appends a discretionary item to the current list; see +Chapter~14 for the meaning of a discretionary item. The space factor is +not changed. + +\bugonpage A292, lines 8--10 (04/22/20) + +\ninepoint +\textindent{$\bull$} \.{\char`\\discretionary}% + \<disc text>\<disc text>\<disc text>.\enskip +This command has the same effect as in horizontal mode (see Chapter~25), but the +third \<disc text> must produce an empty list. + +\bugonpage A299, line 11 from the bottom (11/01/20) + +\ninepoint\noindent +is corrupted or was prepared for a different version of \TeX. + +\bugonpage A305, bottom line (06/30/20) + +\ninepoint\indent +\tt \char`\\setbox0=\char`\\hbox\char`\{\char`\#1\char`\}% +\char`\\advance\char`\\dimen0 by -\char`\\wd0 \char`\}\rm. + +\bugonpage A309, line 2 becomes two lines (12/06/20) + +\ninepoint\noindent +represent text entered from the user's terminal, or with +`\.{<insert>}', when they +represent text inserted during error recovery). + +\bugonpage A316, lines 17 and 18 from the bottom (09/03/15) + +\ninepoint\noindent +(The next line must also not be too tall.) +Here \.{\char`\\specialstar} is a box of height zero and depth +\.{\char`\\strutdepth}, +and it puts an asterisk in the left margin: + +\bugonpage A320, lines 5--9 from the bottom (06/27/15) + +\ninepoint\noindent +{\bf 17.21.}\enspace Assigning \.{\char`\\delcode\char`\`\char`\{} +would not work to allow `\.{\char`\\left\char`\{}', because +the brace has category~1 and isn't a legal \<delim>. +Allowing brace delimiters would be a bad idea because it would +mess up other constructions, such as arguments to macros, and +components of alignments. Moreover, a user who +gets away with `\.{\char`\\left\char`\{}' +is likely to try also `\.{\char`\\bigl\char`\{}', which +fails miserably. + +\bugonpage A326, line 12 (08/26/17) + +\ninepoint\noindent +its natural width. The \.{\char`\\hbox} version also invokes +\.{\char`\\everyhbox} and \.{\char`\\everymath}. + +\bugonpage A329, line 3 of answer 20.7 (05/15/19) + +\ninepoint\noindent +the three tokens \.{!1}, \.{\char`\#2}, \.{[}$_1$; the +\<replacement text> consists of the six tokens +\.{\char`\{}$_1$, \.{\char`\#}$_6$,\cutpar + +\bugonpage A329, line 6 of answer 20.7 (05/15/19) + +\ninepoint\noindent +is otherwise irrelevant. Thus, `\.{\char`\\def\char`\\!!1\char`\#2\char + `\#[\char`\{\char`\#\char`\#]!!\char`\#2]}' +would produce an essentially\cutpar + +\bugonpage A329, line 5 from the bottom of answer 20.7 (05/15/19) + +\ninepoint\indent +\.{!1<-x} + +\bugonpage A329, bottom line of answer 20.7 (05/15/19) + +\ninepoint\noindent +final parameter in the parameter text; +`\.{!1}' would have been rendered `\.{\char`\#1}'. + +\bugonpage A332, lines 13 and 14 (08/26/17) + +\ninepoint\noindent +{\bf 21.10.}\enspace If you say +`\.{\char`\{\char`\\let}\stretch +\.{\char`\\the=0\char`\\edef}\stretch +\.{\char`\\next}\stretch +\.{\char`\{\char`\\write}\stretch +\.{\char`\\cont}\stretch +\.{\char`\{}\<token list>\.{\char`\}\char`\}\char`\\next}\stretch +\.{\char`\}}', +the \.{\char`\\write} will be exercuted after +\.{\char`\\edef} expands everything except \.{\char`\\the}. + +\bugonpage A332, bottom line (11/15/19) + +\ninepoint\indent\quad +\tt \char`\\+\char`\&\char`\{\char`\\bf end\char`\};\char`\\cr \ + \char`\%\ note that the semicolon isn't bold + +\bugonpage A342, lines 12 and 13 (08/14/20) + +\tenpoint\noindent +of plain \TeX\ format; but some of them are primitive (built in), +such as `\.{\char`\\par}' (end of +paragraph), `\.{\char`\\noindent}' (beginning of +non-indented paragraph), and `\.{\char`\/}' (italic\cutpar + +\bugonpage A345, lines 10--13 from the bottom (06/27/15) + +\ninepoint\noindent +Braces are used for grouping, when supplying +arguments to macros; so they cannot also be used as math delimiters, or as +arguments to macros such as \.{\char`\\big}. (One could change their catcodes +to~12, and use some other pair of characters for grouping; but that +would not be plain \TeX.) + +\bugonpage A346, lines 10--22 (11/24/19) + +\ninepoint\noindent +number identification.) \ (2)~The registers +\.{\char`\\count255}, \.{\char`\\dimen255}, \.{\char`\\skip255}, +\.{\char`\\toks255}, and \.{\char`\\muskip255} +are freely available in the same way. +\ (3)~All assignments to the scratch registers whose numbers are +1,~3, 5, 7, and~9 should be \.{\char`\\global}; all assignments to the +other scratch registers (0,~2, 4, 6, 8,~255) should be non-\.{\char`\\global}. +\ (This prevents the phenomenon of ``save stack buildup'' discussed +in Chapter~27.) +\ (4)~Furthermore, it's possible to +use any register in a group, if you ensure that \TeX's grouping +mechanism will restore the register when you're done with the group, and +if you are certain that other macros will not make global assignments +to that register when you need it. \ (5)~But when a register is used +by several macros, or over long spans of time, it should be allocated +by \.{\char`\\newcount}, \.{\char`\\newdimen}, \.{\char`\\newbox}, +etc. \ (6)~Similar remarks +apply to input/output streams used by \.{\char`\\read} and \.{\char`\\write}, +to math families used by \.{\char`\\fam}, to sets of hyphenation rules used by +\.{\char`\\language}, and to insertions (which require +\.{\char`\\box}, \.{\char`\\count}, \.{\char`\\dimen}, +and \.{\char`\\skip} registers all having the +same number).\looseness=-1 + +\bugonpage A347, line 6 (06/30/20) + +\ninepoint\noindent +\tt \char`\\def\char`\\wlog\char`\{\char`\\immediate\char`\\write-1 \char`\} +\ \char`\%\ this will write on log file (only) + +\bugonpage A347, line 10 (11/24/19) + +\ninepoint\noindent +\tt \char`\\outer\char`\\def\char`\\newmuskip\char`\{\char`\\alloc@3% +\char`\\muskip\char`\\muskipdef\char`\\@cclv\char`\} + +\bugonpage A347, line 14 (11/24/19) + +\ninepoint\noindent +\tt \char`\\outer\char`\\def\char`\\newtoks\char`\{\char`\\alloc@5% +\char`\\toks\char`\\toksdef\char`\\@cclv\char`\} + +\bugonpage A350, lines 15 and 16 from the bottom (01/17/21) + +\ninepoint\noindent +format; it shouldn't cost much for people to acquire all the +fonts of plain \TeX\ in addition to the ones that they really want. Second, it +is desirable on many computer systems to\cutpar + +\bugonpage A364, line 5 from the bottom (01/14/21) + +\ninepoint\noindent +\tt \char`\\def\char`\\fmtversion\char`\{3.1415926535\char`\} +\ \char`\%\ identifies the current format + +\bugonpage A370, lines 11 and 12 (08/26/17) + +\ninepoint\noindent +close as possible to the ASCII conventions. +\ (b)~Make sure that codes \oct{041}--\oct{046}, \oct{060}--\oct{071}, +\oct{136}, \oct{141}--\oct{146}, and \oct{160}--\oct{171} are present and that +each unrepresentable in-\cutpar + +\bugonpage A373, lines 21 and 22 (01/17/21) + +\ninepoint\noindent +and \.{\char`\\if...\char`\\fi} +tests, as well as special operations like \.{\char`\\the} +and \.{\char`\\input}, while the +latter category includes the primitive commands listed in Chapters~24--26. +The expansion of\cutpar + +\bugonpage A375, bottom three lines (06/30/20) + +\ninepoint\noindent +|$$\generaldisplay$$| to be invoked, with |\eq| defined to be $\alpha$. +Furthermore, when an equation number~$\beta$ is present, it should be stored +in |\eqn|, and the test |\ifeqno| should be true. +In such cases |\ifleqno| should distinguish |\leqno| from |\eqno|. +Here\cutpar + +\bugonpage A398, lines 4 and 5 (08/26/17) + +\ninepoint\indent +|\setbox2=\lastbox \setbox\footins=\vbox{\box2}|\par +\smallskip\noindent +since |\lastbox| will be the result of\/ |\rigidbalance|, which is an hbox. + +\bugonpage A407, line 5 from the bottom (06/30/20) + +\ninepoint\noindent\quad +| \interlinepenalty5000\def\par{\endgraf\penalty5000 }}| + +\bugonpage A413, line 11 from the bottom (05/14/19) + +\ninepoint\indent +The computer file |texbook.tex| that generated {\sl The \TeX book\/} begins +with a\cutpar + +\bugonpage A418, line 4 (05/14/19) + +\ninepoint\noindent +\TeX\ commands +that look like this in the file |texbook.tex|: + +\bugonpage A420, line 11 (06/30/20) + +\ninepoint\noindent +|\def\bull{\vrule height.9ex width.8ex depth-.1ex \relax} % square bullet| + +\bugonpage A423, line 16 (06/30/20) + +\ninepoint\noindent +| \vrule height6pt depth2pt width0pt \relax} % a strut for \insert\margin| + +\bugonpage A445, lines 10--14 (12/10/18) + +\ninepoint +\textindent{\bf 15e.} Enclose the vbox that was constructed in Rule 15c or 15d by +delimiters $(\lambda,\rho)$ +whose height plus depth is at least $\sigma_{20}$, if $C>T$, and at +least $\sigma_{21}$ otherwise. Shift the delimiters up or down so that they are +vertically centered with respect to the axis. Replace the generalized +fraction by an Ord atom whose nucleus is the resulting sequence of three boxes +($\lambda$, vbox, $\rho$). Go to rule~19. + +\bugonpage A446, the bottom three lines of Rule 19 become four lines (01/10/21) + +\ninepoint\noindent +atom and the right boundary item to +a Close atom. The entire resulting list now becomes the nucleus of an +Inner atom. \ (All of the calculations in this step are done with +$C$ equal to the starting style of the math list; style items in the +middle of the list do not affect the style of the right boundary item.) + +\bugonpage A454, lines 17 and 18 from the bottom (04/13/20) + +\ninepoint\noindent +of the process; the trial word consists of all the letters found in admissible +items, up to a maximum of~63. Notice that all of these letters are in font~$f$. + +\bugonpage A458 and following, selected amendments to the index (01/18/21) + +\eightpoint +|[1]| (progress report), 23, $\underline{119}$.\par +|\aa| ( \aa\ ), {\it52}, $\underline{356}$.\par +|\AA| ( \AA\ ), {\it52}, $\underline{356}$.\par +\<disc text>, $\underline{287}$, 292.\par +\<general text>, $\underline{276}$, 279, 280.\par +\<horizontal mode material>, 278, 285, 287.\par +integral signs, {\sl see\/} |\int|, |\oint|, |\smallint|.\par +\<math mode material>, 287, 289--293.\par +|\null|, 311, {\it312}, {\it316}, {\it332}, {\it335}, $\underline{351}$, {\it354}, {\it360}--{\it362}, {\it419}.\par +|\o| ( \o\ ), {\it52}, $\underline{356}$.\par +|\O| ( \O\ ), {\it52}, $\underline{356}$.\par +programs, for computers, 38, 165, {\it234}.\par +repeating templates, {\sl see\/} periodic preambles.\par +replacement text, {\it200}--{\it204}, 212, 280, 300, 329.\par +right delimiters, {\sl see\/} closings.\par +struts, $\underline{82}$, 125, 131, 142, 155, 178, 245--247, 255, 329, 416, 422, 423.\par +\<vertical mode material>, 278, 280--282, 290. + + +% volume B +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\dts{\mathrel{.\,.}} % double dot, used only in math mode + +\bugonpage Bv {(formerly Bvii)}, bottom two lines (01/15/21) + +\eightpoint\noindent +all of those changes. +I~now believe that the final bug was discovered on 22 October 2020 +and removed in version 3.141592653. % on 12 January 2021 +The finder's fee has converged to \$327.68. + +\hsize=35pc + +\bugonpage B2, line 10 from the bottom (01/15/21) + +\ninepoint\noindent\hskip10pt +{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$% +{\tt This\]is\]TeX,\]Version\]3.141592653\char'23}\quad +$\{\,$printed when \TeX\ starts$\,\}$ + +\bugonpage B4, line 8 of \S7 (04/02/17) + +\tenpoint\noindent +diagnostic information for \.{\char`\\tracingparagraphs}, +\.{\char`\\tracingpages}, and \.{\char`\\tracingrestores}. + +\bugonpage B21, lines 33 and 34 (04/02/17) + +\def\Oct#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant +\tenpoint\noindent +$[\Oct{41}\to\Oct{46},\Oct{60}% +\to\Oct{71},\Oct{136},\Oct{141}\to\Oct{146},\Oct{160}\to\Oct{171}]$ must be printable. +Thus, at least 80 printable characters are needed. + +\bugonpage B28, lines 3 and 4 (04/02/17) + +\tenpoint\noindent +not serious since we assume that this +part of the program is system dependent. + +\bugonpage B28, line 2 from the bottom (04/02/17) + +\ninepoint\noindent\quad +{\bf var} $k$: $0\dts23$;\quad$\{\,$index to current digit; we assume + that $\vert n\vert<10^{23}\,\}$ + +\bugonpage B35, line 2 of \S83 becomes two lines (06/27/20) + +\ninepoint\noindent\quad +{\bf loop begin} \\{continue}: {\bf if} $\\{interaction}\ne\\{error\_stop\_mode}$ + {\bf then return};\par +\noindent\qquad +\\{clear\_for\_error\_prompt}; \ \\{prompt\_input}(\.{"?\]"}); + +\bugonpage B36, line 11 of \S84 (07/03/20) + +\ninepoint\noindent\quad +\.{"E"}: {\bf if} $\\{base\_ptr}>0$ {\bf then if} + $\\{input\_stack}[\\{base\_ptr}].\\{name\_field}\ge256$ {\bf then} + +\bugonpage B36, line 5 of \S85 becomes two lines (07/03/20) + +\ninepoint\noindent\quad +{\bf if} $\\{base\_ptr}>0$ {\bf then}\par +\noindent\qquad +{\bf if} $\\{input\_stack}[\\{base\_ptr}].\\{name\_field}\ge256$ {\bf then} +\\{print}(\.{"E\]to\]edit\]your\]file."} + +\bugonpage B40, line 5 from the bottom (08/07/20) + +\ninepoint\noindent\qquad +(\.{"Try\]to\]insert\]an\]instruction\]for\]me\](e.g.,\]% + \char`\`I\char`\\showlists\char`\'),"}) + +\bugonpage B58, lines 2 and 3 of \S136 (10/11/20) + +\tenpoint\noindent +the values corresponding to `\.{\char`\\hbox\char`\{\char`\}}'. +The \\{sub\_type} +field is set to \\{min\_quarterword}, for historic reasons that are no +longer relevant. + +\bugonpage B88, line 16 (10/22/20) + +\tenpoint\noindent +The mode is temporarily set to zero while processing \.{\char`\\write} texts. + +\bugonpage B102, lines 3 and following of \S241 (12/11/20) + +\tenpoint\noindent +information, something special +is needed. The program here simply assumes that suitable values appear in +the global variables \\{sys\_time}, \\{sys\_day}, \\{sys\_month}, and +\\{sys\_year} (which are initialized to noon on 4 July 1776, +in case the implementor is careless). +\smallskip +\ninepoint\noindent +{\bf procedure} \\{fix\_date\_and\_time};\par +\noindent\quad{\bf begin} +$\\{sys\_time}\gets12\ast60$; \ +$\\{sys\_day}\gets4$; \ +$\\{sys\_month}\gets7$; \ +$\\{sys\_year}\gets1776$;\quad +$\{\,$self-evident truths$\,\}$\par +\noindent\quad$\\{time}\gets\\{sys\_time}$;\quad + $\{\,$minutes since midnight$\,\}$\par +\noindent\quad$\\{day}\gets\\{sys\_day}$;\quad$\{\,$day of the month$\,\}$\par +\noindent\quad$\\{month}\gets\\{sys\_month}$;\quad$\{\,$month of the year$\,\}$\par +\noindent\quad$\\{year}\gets\\{sys\_year}$;\quad$\{\,$Anno Domini$\,\}$\par +\noindent\quad{\bf end}; + +\bugonpage B103, replacement for \S246 (12/11/20) + +\tenpoint\noindent +{\bf 246.}\quad Of course we had better declare a few more global variables, +if the previous routines are going to work. +\smallskip +\ninepoint\noindent +$\langle\,$Global variables {\sevenrm\kern.5em13}$\,\rangle+\equiv$\par +\noindent\\{old\_setting}: $0\dts\\{max\_selector}$;\par +\noindent\\{sys\_time}, \\{sys\_day}, \\{sys\_month}, \\{sys\_year}: \\{integer}; +\quad$\{\,$date and time supplied by external system$\,\}$ + +\goodbreak +\bugonpage B122, lines 9 and 10 of \S291 (10/12/20) + +\tenpoint\noindent\quad +The enclosing \.{\char'173} and \.{\char'175} characters of a macro +definition are omitted, but an output routine +will be enclosed in braces. + +\bugonpage B143, lines 2, 3, 4 become four lines (01/15/17) + +\tenpoint\noindent +routines that should be aborted, but we can sketch the +ideas here: For a runaway definition or a runaway balanced text, +we will insert a right brace; for a +runaway preamble, we will insert a special \.{\char`\\cr} token and a right +brace; and for a runaway argument, we will set \\{long\_state} to +\\{outer\_call} and insert \.{\char`\\par}. + +\bugonpage B188, line 8 (04/02/17) + +\ninepoint\noindent +{\bf function} \\{str\_toks}$(b:\\{pool\_pointer})$: \\{pointer};\quad + $\{\,$converts \\{str\_pool}$[b\dts\\{pool\_ptr}-1]$ to a token list$\,\}$ + +\bugonpage B192, line 17 (10/22/20) + +\ninepoint\noindent\quad +{\bf label} \\{found}, \\{continue}, \\{done}, \\{done1}, \\{done2}; + +\bugonpage B192, line 3 of \S474 (10/22/20) + +\ninepoint\noindent\qquad +{\bf begin} \\{continue}: \\{get\_token};\quad$\{\,$set \\{cur\_cmd}, + \\{cur\_chr}, \\{cur\_tok}$\,\}$ + +\bugonpage B193, line 4 of \S476 (05/20/20) + +\ninepoint\noindent\quad +{\bf if} $\\{cur\_tok}<\\{left\_brace\_limit}$ {\bf then} + +\bugonpage B193, line 10 of \S476 becomes two lines (10/22/20) + +\ninepoint\noindent\qquad +\\{help2}(\.{"I\char`\'m\]going\]to\]ignore\]the\]\#\]sign\]you\]just\]used,"})\par +\noindent\qquad +(\.{"as\]well\]as\]the\]token\]that\]followed\]it."}); +\\{error}; {\bf goto} \\{continue}; + +\bugonpage B196, line 5 from the bottom (02/17/18) + +\ninepoint\noindent\qquad\quad +\\{help1}(\.{"This\]\char`\\read\]has\]unbalanced\]braces."}); +$\\{align\_state}\gets1000000$; +$\\{limit}\gets0$; +\\{error}; + +\bugonpage B199, lines 1--3 of \S494 (10/25/20) + +\tenpoint\noindent +{\bf 494.} \ \ Here is a procedure that ignores text until coming to an \.{\char`\\or}, +\.{\char`\\else}, or \.{\char`\\fi} at the current level +of $\.{\char`\\if}\ldots\.{\char`\\fi}$ +nesting. After it has acted, \\{cur\_chr} will indicate the token that +was found, but \\{cur\_tok} will not be set (because this makes the +procedure run faster). + + +\bugonpage B214, lines 2--6 of \S536 (12/11/20) + +\ninepoint\noindent\quad +{\bf begin} \\{wlog}(\\{banner}); +\\{slow\_print}(\\{format\_ident}); +\\{print}(\.{"\]\]"}); +\\{print\_int}(\\{sys\_day}); +\\{print\_char}(\.{"\]"});\par +\noindent\quad +$\\{months}\gets\.{\char`\'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC\char`\'}$;\par +\noindent\quad +{\bf for} $k\gets3\ast\\{sys\_month}-2$ {\bf to} $3\ast\\{sys\_month}$ +{\bf do} \\{wlog}(\\{months}[$k$]);\par +\noindent\quad +\\{print\_char}(\.{"\]"}); +\\{print\_int}(\\{sys\_year}); +\\{print\_char}(\.{"\]"}); +\\{print\_two}(\\{sys\_time} {\bf div} 60); +\\{print\_char}(\.{":"});\par +\noindent\quad +\\{print\_two}(\\{sys\_time} {\bf mod} 60); + +\bugonpage B214, line 2 of \S537 becomes two lines (10/29/20) + +\tenpoint\noindent +command is being processed. +Beware: For historic reasons, this code foolishly conserves a tiny bit +of string pool space; but that can confuse the interactive `\.E' option. + +\bugonpage B214, bottom line (10/29/20) + +\ninepoint\noindent +{\bf if} $\\{name}=\\{str\_ptr}-1$ {\bf then} +\ $\{\,$conserve string pool space (but see note above)$\,\}$ + +\bugonpage B219, lines 18--20 of \S545 (09/19/19) + +\tenpoint\noindent +so-called 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 boundary character at the +left, beginning at location $256\ast\\{op\_byte}+$\cutpar + +\bugonpage B282, line 1 {(and change lines 20--23 accordingly)} (04/02/17) + +\tenpoint\noindent +{\bf 682.} Each portion of a formula is classified as Ord, Op, Bin, Rel, Open, +Close, Punct, or Inner, for\cutpar + +\bugonpage B299, line 4 from the bottom of \S722 (10/06/20) + +\ninepoint\noindent\qquad\quad +{\bf begin} \\{char\_warning}(\\{cur\_f}, \\{qo}(\\{cur\_c})); +$\\{math\_type}(a)\gets\\{empty}$; +$\\{cur\_i}\gets\\{null\_character}$; + +\bugonpage B318, lines 16 and 17 of \S761 become one (03/25/19) + +\ninepoint\noindent +\\{fraction\_noad}: $s\gets\\{fraction\_noad\_size}$; + +\bugonpage B333, line 5 of \S793 becomes two lines (01/10/20) + +\ninepoint\noindent\quad +$\\{cur\_loop}\gets\\{link}(\\{cur\_loop})$; +$\\{link}(p)\gets\\{new\_glue}(\\{glue\_ptr}(\\{cur\_loop}))$;\par +\noindent\quad +$\\{subtype}(\\{link}(p))\gets\\{tab\_skip\_code}+1$; + +\bugonpage B348, insert a new line after line 5 of \S826 (01/15/17) + +\ninepoint\noindent\qquad +{\bf stat if} $\\{tracing\_paragraphs}>0$ {\bf then} +\\{end\_diagnostic}(\\{true}); \ {\bf tats} + +\bugonpage B348, insert a new line to be the seventh line after the previous change (01/15/17) + +\ninepoint\noindent\qquad +{\bf stat if} $\\{tracing\_paragraphs}>0$ {\bf then} +\\{begin\_diagnostic}; \ {\bf tats} + +\bugonpage B377, line 6 (10/31/20) + +\ninepoint\noindent +\\{hn}: $0\dts64$; \ $\{\,$the number of positions occupied in \\{hc}; + not always a \\{small\_number}$\,\}$ + +\bugonpage B417, mini-index (04/02/17) + +\eightpoint\noindent +The entry `\\{height}, \S981.' here and on many later +odd-numbered pages should be `$\\{height}=\rm macro$, \S135.' + +\bugonpage B522, line 3 of \S1306. (10/25/20) + +\tenpoint\noindent +to be in the range $a\le x\le b$. +System error messages should be suppressed when undumping. + +\bugonpage B533, lines 5--8 of \S1333. (10/15/20) + +\tenpoint\noindent +loop. +(Actually there's one way to get error messages, via \\{prepare\_mag}; +but that can't cause infinite recursion.)\par +\noindent\quad +If \\{final\_cleanup} is bypassed, this program doesn't bother to +close the input files that may still be open. + +\bugonpage B533, line 12 of \S1333. (11/29/20) + +\ninepoint\noindent\quad +{\bf begin} $\langle\,$Finish the extensions{\sevenrm\kern.5em1378}$\,\rangle$; +$\\{new\_line\_char}\gets-1$; + +\bugonpage B534, line 6 of \S1335. (11/29/20) + +\ninepoint\noindent\quad +{\bf begin} $c\gets\\{cur\_chr}$; +{\bf if} $c\ne1$ {\bf then} $\\{new\_line\_char}\gets-1$; + +\bugonpage B537, line 18 of \S1338 becomes two lines (10/05/20) + +\ninepoint\noindent\quad +{\bf begin} \\{clear\_terminal};\par +\noindent\quad +{\bf loop} + +\bugonpage B537, lines 11 and 12 from the bottom of \S1338 + become three lines (04/02/17) + +\ninepoint\noindent\qquad\qquad +{\bf begin goto} \\{breakpoint};\par +\noindent\qquad\qquad\quad$\{\,$go to every declared label at least once$\,\}$\par +\noindent\qquad\quad\\{breakpoint}: $m\gets0$; + \.{@\char`\{\char`\'BREAKPOINT\char`\'@\char`\}} + +\bugonpage B600, the bottom five lines (05/14/19) + +\tenpoint\noindent +they occupy in a typical production system +(executable code size for dark blocks, global data size for light blocks). +In this way the chart indicates a total of about +$12\times22=264${\ninerm K} bytes of memory, plus +$12\times10=120${\ninerm K} for the +dynamic memory region not shown explicitly. The dynamic memory +is often considerably larger in practice, because it is desirable to +accommodate large macro packages and large pages. + + +% volume C +\hsize=29pc +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\dashto{\mathrel{\hbox{-\thinspace-\kern-.05em}}} +\def\ddashto{\mathrel{\hbox{-\thinspace-\thinspace-\kern-.05em}}} +\def\tension{\mathop{\rm tension}} +\def\controls{\mathop{\rm controls}} +\def\and{\,{\rm and}\,} + +\bugonpage Cx, line 4 from the bottom (06/14/20) + +\count255=1 +\def\diamondleaders{\global\advance\count255 by 1 + \ifodd\count255 \kern-10pt \fi + \leaders\hbox to 20pt{\ifodd\count255 \kern13pt \else\kern3pt \fi + .\hss}} +\line{\strut + \hbox to\parindent{\bf\hbox to 1em{\hss20}\hss}% + \rm More About Macros\diamondleaders\hfil\hbox to 2em{\hss175}} + +\bugonpage C39, lines 10 and 11 become three lines (07/04/20) + +\tenpoint\noindent +that has already been designed. All you'll see is +`|(io.mf| |The| |letter| |O| |[79])|' or possibly only `|(io.mf| |[79])|', +followed by~`|*|'. Now the fun starts: You should type + +\bugonpage C68, lines 9, 28, 35, 36, 38 (11/11/17) + +\ninepoint +\halign{\indent\hbox to 160pt{\tt#\hfil}&\tt#\hfil\cr +uniformdeviate -100&-36.1628\cr +z slanted 1/6&(0.16667y+x,y)\cr +(a,b)zscaled(3,4)&(-4b+3a,3b+4a)\cr +(a,b)zscaled dir 30&(-0.5b+0.86603a,0.86603b+0.5a)\cr +(a,b)dotprod(3,4)&4b+3a\cr +} + +\bugonpage C72, lines 4--18 (07/16/20) + +\ninepoint\noindent +\beginsyntax +<numeric atom>\is<numeric variable> + \alt<numeric token primary> + \alt[(]<numeric expression>[)] + \alt[normaldeviate] + \alt[length]<string primary> + \alt[length]<path primary> + \alt[length]<pair primary> + \alt[angle]<pair primary> + \alt[xpart]<pair primary> + \alt[ypart]<pair primary> + \alt<numeric operator><numeric primary> +<numeric token primary>\is<numeric token>[/]<numeric token> + \alt<numeric token not followed by % + `{\tt/}$\thinspace\langle$numeric token$\rangle$'\thinspace> +<numeric primary>\is<numeric atom not followed by {[\char'133]<expression>[,]}> + \alt<numeric atom>[\char'133]<numeric expression>% + [,]<numeric expression>[\char'135] +\endsyntax + +\bugonpage C76, lines 8--16 from the bottom (11/11/17) + +\newdimen\longesteq +\setbox0=\hbox{\indent$z_{12}-z_{11}=z_{14}-z_{13}$\quad} +\longesteq=\wd0 +\tenpoint\noindent \hangindent\longesteq \hangafter0 +tom edge of the type. +\ (With plain \MF's {\bf beginchar} each +character has a ``bounding box'' that runs from $(0,h)$ +at the upper left and $(w,h)$ at the upper right to $(0,-d)$ and~$(w,-d)$ +at the lower left and lower right; variable $d$ represents the depth of +the type. The values of $w$, $h$, and~$d$ might change from character to +character, since the individual pieces of type need not have the same size +in a computer-produced font.) + +\bugonpage C80, line 14 (06/13/20) + +\tenpoint\indent +\\{penpos}\<suffix>(\<unknown>,\thinspace\<known>). + +\bugonpage C83, line 16 (06/13/20) + +\ninepoint\indent +|### 0.5a=-c-0.5b+1.5| + +\bugonpage C83, line 19 (06/13/20) + +\ninepoint\noindent +the only +dependent variable is now $d$, which equals $0.5c+0.75b+0.75$. \ (This is\cutpar + +\bugonpage C96, line 13 from the bottom (10/31/20) + +\tenpoint\noindent +illustrates the +use of $u\0$, $s\0$, $\\{ht}\0$, \\{logo\_pen}, \\{leftstemloc}, $o$, +\\{xgap}, and \\{barheight}: + +\bugonpage C106, lines 19--21 (07/03/20) + +\ninepoint\noindent +pixels. \ (Some typesetting +systems use both of these device-dependent amounts to alter their current +position on a page, just after typesetting each character. Other systems, +like typical |dvi| software associated with \TeX, assume that $\\{chardy}=0$ +but use \\{chardx}\cutpar + +\bugonpage C113, lines 5--11 from the bottom (07/20/20) + +\def\cycle{\hbox{\rm cycle}} +\ninepoint\noindent +\begindisplay +$s\0:=5\\{pt}\0$; \ {\bf define\_pixels}$(s)$; \ \% side of the square\cr +$z_1=(0,0)$; \ $z_2=(s,0)$; \ $z_3=(0,s)$; \ $z_4=(s,s)$;\cr +{\bf for} $k=1$ {\bf upto} 4: + $z[k+4]=z[k]+({2\over3}s,{1\over3}s)$; \ {\bf endfor}\cr +{\bf pickup pencircle} scaled $.4\\{pt}$; \ +{\bf draw} $z_5\dashto z_6\dashto z_8\dashto z_7\dashto \cycle$;\cr +{\bf pickup pencircle} scaled $1.6\\{pt}$; \ +{\bf erase draw} $z_2\dashto z_4\dashto z_3$;\cr +{\bf pickup pencircle} scaled $.4\\{pt}$; \ +{\bf draw} $z_1\dashto z_2\dashto z_4\dashto z_3\dashto \cycle$;\cr +{\bf for} $k=1$ {\bf upto} 4: + {\bf draw} $z[k]\dashto z[k+4]$; \ {\bf endfor}.\cr +\enddisplay + +\bugonpage C114, line 7 (07/20/20) + +\ninepoint\indent +{\bf for} $k=0$ {\bf upto} 4: \ $z[k]=\\{center}+(\\{radius},0)$ + rotated$(90+{360\over5}k)$; \ {\bf endfor} + +\bugonpage C128, lines 13 and 14 (06/13/20) + +\ninepoint\noindent +changed. Plain \MF\ has a {\bf tensepath} operation +that does this. For example, {\bf tensepath}~\\{unitsquare}~$=$ +$(0,0)\ddashto(1,0)\ddashto(1,1)\ddashto(0,1)\ddashto\cycle$. + +\bugonpage C136, lines 18 and 19 (07/17/20) + +\ninepoint\noindent +only +about 0.28 with respect to the initial and final directions; since \MF\ insists +that tensions be at least~0.75, this anomalous path could never have arisen +if the control\cutpar + +\bugonpage C155, line 7 (10/07/20) + +\tenpoint\indent +\<program>\is\<statement list>\<statement>\thinspace|end| + +\bugonpage C160, lines 7--9 (06/25/20) + +\ninepoint\noindent +might produce a transcript +that includes the following diagnostic information: +\begintt +rotatedaround(EXPR0)(EXPR1)-> + shifted-(EXPR0)rotated(EXPR1)shifted(EXPR0) +\endtt + +\bugonpage C165, lines 5--7 from the bottom (11/11/17) + +\ninepoint\noindent +(i.e., parameters in parentheses), +then we name zero or one or two undelimited parameters. +Then comes an `$=$'~sign, +followed by the replacement text, and {\bf enddef}. The `$=$'~sign might also +be~`$:=$'\thinspace; both mean the same thing. + +\bugonpage C171, lines 18--20 (08/16/20) + +\ninepoint\indent +Chapter~14's syntax rules for +\<path primary>, via \<pair primary>. +A pair expression is not considered to be +of type {\bf path} unless the path interpretation is the only~possibility. + +\bugonpage C176, line 7 from the bottom (07/09/20) + +\ninepoint\indent +\quad {\bf if} |@#|$(\\{x\_})\colon\ \\{tx\_} \ \hbox{\bf else}\colon\ + \\{fx\_}\ \hbox{\bf fi}$ + :=\ \\{x\_}\thinspace; {\bf endfor} + +\bugonpage C180, line 3 from the bottom (06/24/20) + +\ninepoint\indent +`$=$' or `$:=$' following {\bf let}. + +\bugonpage C187, line11 from the bottom (07/12/20) + +\ninepoint\indent\qquad +\alt|substring|\thinspace\<pair expression>\thinspace|of|\thinspace + \<string primary> + +\bugonpage C189, line 14 (06/13/20) + +\ninepoint\noindent +`|! |' and followed +by~`|.|', followed by lines of context as in \MF's normal error\cutpar + +\bugonpage C200, line 12 from the bottom (08/27/20) + +\ninepoint\indent +$y_1=y_2=\\{good.y}(.5[-d,h]+1.1\\{pt})$; + +\bugonpage C202, line 17 from the bottom (06/13/20) + +\ninepoint\noindent +command, +and it works only when the \\{penpos} angle is~0. If the \\{penpos} command +is\cutpar + +\bugonpage C210, bottom eight lines, and top ten lines of page C211 (07/16/20) + +\ninepoint\noindent +\beginsyntax +<numeric atom>\is<numeric variable>\alt<numeric argument> + \alt<numeric token primary> + \alt<internal quantity> + \alt[normaldeviate] + \alt[(]<numeric expression>[)] + \alt[begingroup]<statement list><numeric expression>[endgroup] + \alt[length]<numeric primary>\alt[length]<pair primary> + \alt[length]<path primary>\alt[length]<string primary> + \alt[ASCII]<string primary>\alt[oct]<string primary>\alt[hex]<string primary> + \alt<pair part><pair primary>\alt<transform part><transform primary> + \alt[angle]<pair primary> + \alt[turningnumber]<path primary>\alt[totalweight]<picture primary> + \alt<numeric operator><numeric primary> + \alt[directiontime]<pair expression>[of]<path primary> +<numeric token primary>\is<numeric token>[/]<numeric token> + \alt<numeric token not followed by % + `{\tt/}$\thinspace\langle$numeric token$\rangle$'\thinspace> +<numeric primary>\is<numeric atom not followed by {[\char'133]<expression>[,]}> + \alt<numeric atom>[\char'133]<numeric expression>% + [,]<numeric expression>[\char'135] +\endsyntax + +\bugonpage C214, line 6 becomes two lines (07/17/20) + +\ninepoint\noindent +\beginsyntax +<future pen primary>\is<future pen argument> + \alt[pencircle] +\endsyntax + +\bugonpage C214, line 6 from the bottom (07/12/20) + +\ninepoint\noindent +\beginsyntax + \alt[substring]<pair expression>[of]<string primary> +\endsyntax + +\bugonpage C217, lines 20--25 (10/07/20) + +\ninepoint\noindent +\beginsyntax +<program>\is<statement list><non-title statement>[end] + \alt<statement list><non-title statement>[dump] +<statement list>\is<empty>\alt<statement>[;]<statement list> +<statement>\is<empty>\alt<title> + \alt<equation>\alt<assignment>\alt<declaration> + \alt<definition>\alt<compound>\alt<command> +\endsyntax + +\bugonpage C219, line 25 (05/25/20) + +\ninepoint\noindent +to see which of its subscripts and suffixes have occurred. +For example, if you're\cutpar + +\bugonpage C224, lines 7--9 from the bottom (12/21/18) + +\tenpoint\indent +|y4r=-0.9848thinn+259.00049|\par +|x4r=-0.08682thinn+144|\par +|y4=-0.4924thinn+259.00049| + +\bugonpage C226, lines 9 and 10 (11/01/20) + +\ninepoint\noindent +This means that the preloaded base you have specified cannot be used, +because it is corrupted or was prepared for a different version of +\MF\kern-.03em. + +\bugonpage C228, line 27 (06/19/20) + +\ninepoint\indent +|l.94 endfor| + +\bugonpage C228, line 4 from the bottom (07/12/20) + +\ninepoint\noindent +might want to review now.) \ +You probably also have a |proof| mode diagram: + +\bugonpage C234, line 4 of answer 4.6 (07/20/20) + +\ninepoint\indent +{\bf for} $k=1$ {\bf upto} 6: $z[k]'=.2[z[k],z_0]$; {\bf endfor} + +\bugonpage C241, line 2 (11/11/17) + +\ninepoint\indent +|\mode=cheapo; input cheaplogo10| + +\bugonpage C242, line 11 of answer 13.7 (07/20/20) + +\ninepoint\indent +{\bf for} $k=1$ {\bf upto} 4: + $z[k+4]=z[k]+({2\over3}s,{1\over3}s)$; \ {\bf endfor} + +\bugonpage C243, lines 7 and 8 (11/08/15) + +\ninepoint\indent +\indent {\bf draw} subpath$(k,k+1)$ of \\{star}; {\bf cullit};\par\indent +\indent {\bf undraw} subpath$(k+2,k+3)$ of \\{star} {\bf withpen} + \\{eraser}; {\bf cullit}; + +\bugonpage C243, line 3 of answer 13.11 (06/17/20) + +\ninepoint\indent +{\bf def overdraw expr} $c$ = {\bf begingroup save} \\{region}; + +\bugonpage C243, lines 12--16 of answer 13.11 (05/24/20) + +\ninepoint\noindent +\begindisplay +{\bf beginchar}$(\hbox{\tt"M"},1.25\\{in}\0,.5\\{in}\0,0)$; \ + {\bf pickup pencircle} scaled .4\\{pt};\cr +$z_1=(20,-13)$; \ $z_2=(30,-6)$; \ $z_3=(20,1)$; \ $z_4=(4,-7)$;\cr +\indent $z_5=(-12,-13)$; \ $z_6=(-24,-4)$; \ $z_7=(-15,6)$;\cr +{\bf path} $M$; $M=(\\{origin}\dts + z_1\dts z_2\dts z_3\dts z_4\dts z_5\dts z_6\dts z_7\dts$\cr +\indent$\\{origin}\dts -z_7\dts -z_6\dts -z_5\dts -z_4\dts + -z_3\dts -z_2\dts -z_1\dts\cycle)$\cr +\enddisplay + +\bugonpage C246, line 2 of answer 14.13 (08/16/20) + +\ninepoint\noindent +path $z_0\dashto z_1$ is equivalent to `$z_0\dts +\controls1/3[z_0,z_1]\and2/3[z_0,z_1]\dts z_1$', and the\cutpar + +\bugonpage C247, line 1 of answer 15.5 (06/13/20) + +\ninepoint\noindent +\quad{\bf 15.5.}\enspace +{\bf beginchar}$(126,25u\0,\\{h\_height}\0+\\{border}\0,0)$; \ +|"Dangerous left bend"|; + +\bugonpage C247, replacement for answer 15.7 (07/21/20) + +\ninepoint\noindent +\quad{\bf 15.7.}\enspace +Replace lines 10 and 11 by +\begindisplay +{\bf pickup pencircle} scaled 3/4\\{pt} yscaled 1/3 rotated $-60$;\cr +{\bf draw} ($z_1\ldots p$) transformed $t$;\cr +{\bf addto} \\{currentpicture} {\bf also} \\{currentpicture}\cr +\qquad rotatedaround$\bigl((.5w,.5h)$ yscaled \\{aspect\_ratio}$,-180\bigr)$;\cr +\enddisplay + +\bugonpage C249, line 1 of answer 18.9 (08/02/20) + +\ninepoint\noindent +\quad{\bf 18.9.}\enspace +{\bf beginchar}\kern1pt(|"H"|$,13u\0,"ht"\0,0)$; \ + {\bf pickup} \\{broad\_pen}; + +\bugonpage C249, line 11 of answer 18.9 (08/02/20) + +\ninepoint\indent +{\bf filldraw} $\\{bot\_serif\_edge}_4$ + +\bugonpage C250, line 4 of answer 19.1 (04/19/20) + +\ninepoint\noindent +because it saves a wee bit of time and because +`;'\ often belongs before {\bf endfor}. + +\bugonpage C250, replacement for answer 19.3 (07/12/20) + +\ninepoint\noindent +\quad{\bf 19.3.}\enspace +Yes, if and only if $n-{1\over2}$ is an even integer. +\ (Because ambiguous values are rounded upwards.) + +\bugonpage C251, replacement for answer 22.1 (07/12/20) + +\ninepoint\noindent +\quad{\bf 22.1}\enspace +(a) If and only if $n$ is an integer between 0 and 255. +(b) If and only if $s$ is a string of length~1. + +\bugonpage C254, lines 10--13 from the bottom become five lines (06/26/20) + +\ninepoint\noindent +\begintt +? H +I found no right delimiter to match a left one. So I've +put one in, behind the scenes; this may fix the problem. +|null +? +\endtt + +\bugonpage C260, the ``line'' after line 3 (06/14/20) + +\def\bb{$\,\left\{\vcenter\bgroup\halign\bgroup\hfil##\hfil\cr} +\def\ee{\crcr\egroup\egroup\right\}\,$} +\tenpoint\noindent +\bb|font_size|\cr|font_slant|\cr|font_normal_space|\cr + |font_normal_stretch|\cr|font_normal_shrink|\cr|font_x_height|\cr + |font_quad|\cr|font_extra_space|\ee +\bb|=|\cr\noalign{\kern-2pt}|:=|\cr\noalign{\kern-2pt}\<empty>\ee +\<numeric$\0$>; \ +\bb|ligtable|\<ligs/kerns>\cr|charlist|\<codes>\cr|extensible|\<codes>\cr + |fontdimen|\<info>\cr|headerbyte|\<info>\ee;\kern-10pt + +\bugonpage C261, lines 16 and 17 from the bottom (06/14/20) + +\tenpoint\noindent +\bb|proofrule|\cr|screenrule|\ee|(|\<pair>|,|\<pair>|)|; \ +|makegrid(|\<numerics>|)(|\<numerics>|)|;\smallskip\noindent +|proofrulethickness| \<numeric$\0$>; \ |proofoffset| \<pair>. + +\bugonpage C266, lines 19 and 20 (07/04/20) + +\ninepoint\noindent +You can say either `|incr|~|x|' or `|incr|~|(x)|', within +an expression; but neither of them are valid statements by themselves. + +\bugonpage C269, line 11 (01/10/21) + +\ninepoint\indent +|\smode="specmode"; mag=|\<magnification>|; input |\<font file name> + +\bugonpage C277, lines 15--19 (03/06/17) + +\ninepoint\noindent +|def openit = openwindow currentwindow from origen % and please correct|\par +\noindent +| to (screen_rows,screen_cols) at (-50,300) enddef; % "(-50,300)" too|\par +\noindent +|def showit_ = display currentpicture inwindow currentwindow enddef;|\par +\noindent +|def showit = openit; let showit=showit_; showit enddef; % first time only|\par +\kern3pt\hrule\medskip\noindent +Plain \MF\ has several other terse commands +similar to `{\bf openit}' and `{\bf showit}': + +\bugonpage C279, line 1 (11/11/17) + +\ninepoint\noindent +| blacker:=.1; % make pens a teeny bit blacker| + +\bugonpage C289, line 20 (10/07/20) + +\ninepoint\indent +|if {{(pair x) cand x>(0,0)}}: A else: B fi.| + +\bugonpage C291, line 18 (07/24/20) + +\ninepoint\indent +| save u_; setu_ u; let switch_ = if; if false: enddef.| + +\bugonpage C292, line 10 from the bottom (10/23/20) + +\ninepoint\noindent +be known by saying `{\bf if} known $(p-q)$: $p=q$ {\bf else}:~{\bf false fi}'; +transforms could be handled\cutpar + +\bugonpage C293, lines 13 and 14 from the bottom (10/27/20) + +\ninepoint\noindent +$f(-1)$ is false! When $c\rightarrow0$, the quantity $a^3+b^3$ +approaches $-\infty$ when $c$~is positive, $+\infty$ when $c$~is +negative. An attempt to `\\{solve} $f(1,-1)$' will divide by zero and +come\cutpar + +\bugonpage C295, line 2 (07/04/20) + +\ninepoint\noindent +`interpolate $(1,1)\dts(3,2)\dts(15,4)$ of~7' the approximate value 3.37. + +\bugonpage C299, bottom four lines of code become five (08/06/20) + +\ninepoint\noindent +\begintt +primarydef t Bernshtein nn = begingroup save r; r = + begingroup for n=nn downto 2: + for k=1 upto n-1: u_[[[k]]]:=t[[[u_[[[k]]],u_[[[k+1]]] ]]]; + endfor endfor u_[[[1]]] endgroup; numeric u_[[[]]]; + r endgroup enddef; +\endtt + +\bugonpage C299, line 5 after the code becomes two lines (08/06/20) + +\ninepoint\noindent +brackets are nested inside of brackets. +However, the auxiliary variables `|u_[[[|$k$|]]]|' must not remain +independent at the end. + +\bugonpage C305, lines 14--18 (07/08/20) + +\ninepoint\noindent +|width_adj#:=0pt#; % width adjustment for certain characters|\par +\noindent +|serif_fit#:=0pt#; % extra sidebar near lowercase serifs| +\vskip-3pt\noindent\qquad\vdots\par\noindent +|low_asterisk:=false; % should the asterisk be centered at the axis?|\par +\noindent +|math_fitting:=false; % should math-mode spacing be used?| + +\bugonpage C317, line 21 becomes two lines (11/11/17) + +\ninepoint\noindent +\beginsyntax +<label>\is<code label>\alt<code>[::]\alt[\\\\:] +<code label>\is\<code>[:] +\endsyntax + +\bugonpage C318, lines 10--16 from the bottom (11/11/17) + +\ninepoint\noindent +\beginsyntax + \alt<code label><labeled code> +<extensible command>\is[extensible]<code label><four codes> +<four codes>\is<code>[,]<code>[,]<code>[,]<code> +\endsyntax +Notice that a \<code label> can appear in a {\bf ligtable}, {\bf charlist}, or +{\bf extensible} command. + These appearances are mutually exclusive: No code may be +used more than once as a label. Thus, for example, a character with a +ligature/kerning program cannot also be {\bf extensible}, nor can it be +in a {\bf charlist} (except as the final item). + +\bugonpage C333, line 29 (10/25/19) + +\ninepoint\noindent +| "if charcode>0:currentpicture:=currentpicture scaled mg;fi;"| + +\bugonpage C333, bottom two lines become one (11/11/17) + +\ninepoint\noindent +| if unknown scale: scale := max(1,round(pixels_per_inch/300)); fi| + +\bugonpage C339, line 3 (05/21/20) + +\ninepoint\noindent +ing `\char'31', `\char'32', +`\char'33', and~`\char'34') and the uppercase letters (including +`\char'35', `\char'36', and~`\char'37') are\cutpar + +\bugonpage C341, line 14 from the bottom (11/11/17) + +\ninepoint\noindent +prints the |\table| and the |\text|; ^|\bigtest| gives +you the works, plus a mysterious word\cutpar + +\bugonpage C345 and following, selected amendments to the index (01/20/21) + +\eightpoint +*|,| (comma), 57, 72, 73, 129, 155, 165--167, 171, 211--213, 218, 317, 318.\par +`A', 10--11, 163, 164, 248, 302--303.\par +\<addto command>, 118, $\underline{220}$.\par +bell-shaped distribution, $\underline{183}$, 251.\par +|black|, 270, 332--333.\par +\<code> and \<code label>, $\underline{317}$.\par +concatenation, of paths, {\it70}--{\it71}, {\it123}, 127--129, $\underline{130}$, 137, {\it245}, {\it266}.\par +\quad of strings, {\it69}, 73, 84--85, $\underline{187}$, {\it278}, {\it286}, {\it312}.\par +*|directiontime|, {\it135}, $\underline{\it136}$, 211, 245, 265, {\it298}.\par +distance, 76, 84, {\sl see also\/} |length|.\par +|dotprod|, {\it68}--{\it69}, 178, {\it238}, 265.\par +efficiency, 39, 99, 116, 141, 144, 147, 228, 230, 234, 244, 264, 265, 277, 291, 297, 298.\par +empty option in {\bf for\/} list, 171, $\underline{172}$, {\it299}.\par +forbidden tokens, 173, $\underline{218}$--$\underline{219}$, 286.\par +*|from|, $\underline{191}$, 220, {\it252}, {\it277}, {\it312}.\par +Giotto di Bondone, 139.\par +independent variables, $\underline{81}$--$\underline{83}$, 88, 224, 226, 299.\par +|\init|, $\underline{337}$, 342.\par +internal quantities, 54--55, 88, 218, 262, 265--266.\par +*|inwindow|, $\underline{191}$, 220, {\it277}.\par +\<keep or drop>, $\underline{118}$, 220.\par +|labels|, {\it107}, $\underline{274}$, 327--328.\par +*|length|, {\it66}, {\it69}, 72, 210, 238.\par +*|ligtable|, {\it97}, {\it305}--{\it306}, $\underline{316}$--$\underline{317}$.\par +loops, 169, 171--173, 179, 226--227, 259, 290--291, 299.\par +`N', 184--185, 302--303.\par +\<numeric token primary>, 72, $\underline{211}$.\par +|o|, {\it23}, {\it34}, $\underline{93}$, 197, 200, 204, 240, 302.\par +`O', 32--37, 161, 199, 302--303.\par +overshoot, 23, 34, 93, 197, 200, 204, 302.\par +|penpos|, {\it26}--{\it29}, 37, 80, {\it103}, {\it162}, $\underline{273}$, 310.\par +pens, 21--29, 147--152, 297--298.\par +*|rotated|, {\it21}--{\it22}, {\it25}, 27, 44, {\it68}, 73, {\it107}, {\it114}, {\it117}, $\underline{141}$, 213, {\it238}.\par +|rule|, 274, 328.\par +*|scaled|, {\it21}--{\it23}, {\it68}, 73, $\underline{141}$, 213, 244, 291.\par +*|showstopping|, 211, 219, {\it227}, 230, {\it262}.\par +string expressions, {\it69}, 187--189, 258, 286.\par +\<suffix list>, $\underline{171}$, 236.\par +sum, of vectors, 9, {\it68}.\par +|test.mf|, 311--313.\par +\TeX, 1, 34, 40, 91, 96, 98, 101--103, 315, 336--343, 361.\par +text arguments, 219, 288--291, 299.\par +|.tfm|, 39, 315--321, 333, 335.\par +*|to|, $\underline{191}$, 220, {\it252}, {\it277}, {\it312}.\par +undelimited suffix parameters, $\underline{167}$, 176, 266, 270.\par +|undraw|, 113, 118, 120, {\it242}, $\underline{271}$.\par +|unitsquare|, {\it116}, 123--124, 128, 132, 136, $\underline{263}$.\par +*|unknown|, $\underline{170}$, 210.\par +unknown quantities, nonnumeric, 84--85, 143.\par +values, disappearance of, 56, 83, 88, 156--157, 177--178, 218, 239, 299.\par +\<vardef heading>, 165, $\underline{178}$.\par +*|xscaled|, {\it21}--{\it22}, {\it68}, 73, $\underline{141}$, 213, 244, 291.\par + + + +% Volume D +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\to{\mathrel{.\,.}} % double dot, used only in math mode + +\bugonpage Dv, line 16 (01/16/21) + +\tenpoint\noindent +\kern12.5mm I believe that the final bug in \MF\ was discovered on January\cutpar + +\bugonpage Dv, bottom two lines (01/16/21) + +\eightpoint\noindent +corporates all of those changes. +I~now believe that the final bug was discovered on 03 July 2020 +and removed in version 2.71828182. % on 16 January 2021 +The finder's fee has converged to \$327.68. + +\hsize=35pc + +\bugonpage D2, last line of \S2 (01/15/21) + +\ninepoint\noindent +$$\hbox{{\bf define} $\\{banner}\equiv\.{\char`\'This\]is\]METAFONT,\]Version\]2.71828182\char`\'}$\quad +$\{\,$printed when \MF\ starts$\,\}$}$$ + +\bugonpage D14, line 1 of \S30 (05/05/14) + +\tenpoint\noindent +{\bf 20.} \quad The \\{input\_ln} function brings the next line of input from the specified +file into available\cutpar + +\bugonpage D21, line 8 of \S47 (10/11/20) + +\ninepoint\noindent\quad +$g$: \\{str\_number};\quad$\{\,$the string just created$\,\}$ + +\bugonpage D27, lines 3 and 4 of \S61 (04/02/17) + +\tenpoint\noindent +is not serious since we assume that this +part of the program is system dependent. + +\bugonpage D28, line 7 (04/02/17) + +\ninepoint\noindent\quad +{\bf var} $k$: $0\dts23$;\quad$\{\,$index to current digit; we assume + that $\vert n\vert<10^{23}\,\}$ + +\bugonpage D32, line 2 of \S78 becomes two lines (06/27/20) + +\ninepoint\noindent\quad +{\bf loop begin} \\{continue}: {\bf if} $\\{interaction}\ne\\{error\_stop\_mode}$ + {\bf then return};\par +\noindent\qquad +\\{clear\_for\_error\_prompt}; \ \\{prompt\_input}(\.{"?\]"}); + +\bugonpage D32, line 11 of \S79 (07/03/20) + +\ninepoint\noindent\quad +\.{"E"}: {\bf if} $\\{file\_ptr}>0$ {\bf then if} + $\\{input\_stack}[\\{file\_ptr}].\\{name\_field}\ge256$ {\bf then} + +\bugonpage D33, line 5 of \S80 (07/03/20) + +\ninepoint\noindent\quad +{\bf if} $\\{file\_ptr}>0$ {\bf then}\par +\noindent\qquad +{\bf if} $\\{input\_stack}[\\{file\_ptr}].\\{name\_field}\ge256$ {\bf then} +\\{print}(\.{"E\]to\]edit\]your\]file."} + +\bugonpage D37, line 9 of \S93 (08/07/20) + +\ninepoint\noindent\qquad +(\.{"Try\]to\]insert\]an\]instruction\]for\]me\](e.g.,\]% + \char`\`I\]show\]x;\char`\'),"}) + +\bugonpage D82, line 2 from the bottom (09/19/19) + +\ninepoint\noindent\quad +{\bf define} $\\{boundary\_char}=41$\quad$\{\,$the boundary character for ligatures$\,\}$ + +\bugonpage D85, lines 3 and 4 of \S194 {(and \S194 actually moves to page D86)} (12/11/20) + +\tenpoint\noindent +information, something special +is needed. The program here simply assumes that suitable values appear in +the global variables \\{sys\_time}, \\{sys\_day}, \\{sys\_month}, and +\\{sys\_year} (which are initialized to noon on 4 July 1776, +in case the implementor is careless). + +\bugonpage D85, the final six lines of \S194 {(and \S194 actually moves to page D86)} (12/11/20) + +\ninepoint\noindent +{\bf procedure} \\{fix\_date\_and\_time};\par +\noindent\quad{\bf begin} +$\\{sys\_time}\gets12\ast60$; \ +$\\{sys\_day}\gets4$; \ +$\\{sys\_month}\gets7$; \ +$\\{sys\_year}\gets1776$;\quad +$\{\,$self-evident truths$\,\}$\par +\noindent\quad$\\{internal}[\\{time}]\gets\\{sys\_time}\ast\\{unity}$;\quad + $\{\,$minutes since midnight$\,\}$\par +\noindent\quad$\\{internal}[\\{day}]\gets\\{sys\_day}\ast\\{unity}$;\quad$\{\,$day of the month$\,\}$\par +\noindent\quad$\\{internal}[\\{month}]\gets\\{sys\_month}\ast\\{unity}$;\quad$\{\,$month of the year$\,\}$\par +\noindent\quad$\\{internal}[\\{year}]\gets\\{sys\_year}\ast\\{unity}$;\quad$\{\,$Anno Domini$\,\}$\par +\noindent\quad{\bf end}; + +\bugonpage D86, replacement for \S196 (12/11/20) + +\tenpoint\noindent +{\bf 196.}\quad Of course we had better declare a few more global variables, +if the previous routines are going to work. +\smallskip +\ninepoint\noindent +$\langle\,$Global variables {\sevenrm\kern.5em13}$\,\rangle+\equiv$\par +\noindent\\{old\_setting}: $0\dts\\{max\_selector}$;\par +\noindent\\{sys\_time}, \\{sys\_day}, \\{sys\_month}, \\{sys\_year}: \\{integer}; +\quad$\{\,$date and time supplied by external system$\,\}$ + +\bugonpage D97, line 2 of \S221 (05/26/17) + +\tenpoint\noindent +the definition of attribute nodes) that +it is convenient to let $\\{info}(p)=0$ stand for `\.{[]}'. + +\goodbreak +\bugonpage D148, line 7 (06/12/18) + +\tenpoint\noindent +but the $\log n$ factor is buried in our +implicit restriction on the maximum raster size.) The\cutpar + +\bugonpage D237, line 5 of \S513 (05/26/17) + +\ninepoint\noindent\quad +{\bf for} $n\gets0$ {\bf to} $\\{n1}-\\{n0}-1$ {\bf do} $\\{env\_move}[n]\gets\\{mm0}$; + +\bugonpage D250, line 2 of \S534 (05/26/17) + +\tenpoint\noindent +direction $\bigl(\\{right\_u}(p),\\{left\_v}(q)\bigr)$; +and there's a line of length $\ge\\{delta}$ from vertex~$q$ to vertex~$r$,\cutpar + +\bugonpage D296, line 11 (06/23/20) + +\tenpoint\noindent +\\{name} points to the \\{eqtb} address of the macro +being expanded, if the current token list\cutpar + +\bugonpage D324, line 13 of \S713 (12/20/20) + +\ninepoint\noindent\qquad\quad +\\{help2}(\.{"After\]\char`\`exitif\]<boolean\]expr>\char`\'\]I\]expect\]to\]see\]a\]% +semicolon."}) + +\bugonpage D326, line 5 from the bottom (06/23/20) + +\ninepoint\noindent\qquad\qquad +$\{\,$invokes a user-defined sequence of commands$\,\}$ + +\bugonpage D334, lines 1 and 2 of \S742 (10/25/20) + +\tenpoint\noindent +{\bf 742.} \ Here is a procedure that ignores text until coming to an {\bf elseif}, +{\bf else}, or {\bf fi} at the current level of {\bf if}$\,\ldots\,${\bf fi} +nesting. After it has acted, \\{cur\_mod} will indicate the token that +was found. + +\bugonpage D339, line 4 of \S757 (06/16/20) + +\tenpoint\noindent\quad +(A user who tries some shenanigan like `{\bf for} $\ldots$ {\bf let} {\bf endfor}' +will be foiled by the \\{get\_symbol}\cutpar + +\bugonpage D351, lines 2--7 of \S536 become five lines (12/11/20) + +\ninepoint\noindent\quad +{\bf begin} \\{wlog}(\\{banner}); +\\{slow\_print}(\\{format\_ident}); +\\{print}(\.{"\]\]"}); +\\{print\_int}(\\{sys\_day}); +\\{print\_char}(\.{"\]"});\par +\noindent\quad +$\\{months}\gets\.{\char`\'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC\char`\'}$;\par +\noindent\quad +{\bf for} $k\gets3\ast\\{sys\_month}-2$ {\bf to} $3\ast\\{sys\_month}$ +{\bf do} \\{wlog}(\\{months}[$k$]);\par +\noindent\quad +\\{print\_char}(\.{"\]"}); +\\{print\_int}(\\{sys\_year}); +\\{print\_char}(\.{"\]"}); +\\{print\_two}(\\{sys\_time} {\bf div} 60); +\\{print\_char}(\.{":"});\par +\noindent\quad +\\{print\_two}(\\{sys\_time} {\bf mod} 60); + +\bugonpage D352, line 2 of \S793 becomes two lines (10/29/20) + +\tenpoint\noindent +command is being processed. +Beware: For historic reasons, this code foolishly conserves a tiny bit +of string pool space; but that can confuse the interactive `\.E' option. + +\bugonpage D352, line 5 from the bottom (10/29/20) + +\ninepoint\noindent +{\bf if} $\\{name}=\\{str\_ptr}-1$ {\bf then} +\ $\{\,$conserve string pool space (but see note above)$\,\}$ + +\bugonpage D354, line 2 from the bottom (07/29/20) + +\tenpoint\noindent +$\\{cur\_type}=\\{path\_type}$ means that \\{cur\_exp} points to the first +node of +a path; nobody else points\cutpar + +\bugonpage D469, lines 18--20 of \S1093 (09/19/19) + +\tenpoint\noindent +so-called 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 boundary character at the +left, beginning at location $256\ast\\{op\_byte}+$\cutpar + +\bugonpage D469, line 30 of \S1093 (01/15/21) + +\tenpoint\noindent +tional halt; no ligature or kerning command is performed. + +\bugonpage D471, lines 20 and 21 (08/07/20) + +\ninepoint\noindent +\\{param}: {\bf array} $[1\dts\\{max\_font\_dimen}]$ {\bf of} +\\{scaled};\quad$\{\,${\bf fontdimen} parameters$\,\}$\par\noindent +\\{np}: $0\dts\\{max\_font\_dimen}$;\quad$\{\,$the largest {\bf fontdimen} parameter +specified so far$\,\}$ + +\bugonpage D474, line 2 from the bottom (08/07/20) + +\ninepoint\noindent\quad\qquad +\\{help1}(\.{"A\]colon\]should\]follow\]a\]headerbyte\]or\]fontdimen\]location."}); +\\{back\_error}; + +\bugonpage D508, line 3 of \S1189. (10/05/20) + +\tenpoint\noindent +to be in the range $a\le x\le b$. +System error messages should be suppressed when undumping. + +\bugonpage D516, line 6 (10/15/20) + +\tenpoint\noindent\quad +If \\{final\_cleanup} is bypassed, this program doesn't bother to +close the input files that may still be open. + +\bugonpage D519, line 17 (01/15/21) + +\ninepoint\noindent\quad +\\{fix\_date\_and\_time}; +$\\{init\_randoms}(\\{sys\_time}+\\{sys\_day}*\\{unity})$; + +\bugonpage D520, line 18 of \S1212 becomes two lines (10/05/20) + +\ninepoint\noindent\quad +{\bf begin} \\{clear\_terminal};\par +\noindent\quad +{\bf loop} + +\bugonpage D520, lines 11 and 12 from the bottom of \S1212 + become three lines (04/02/17) + +\ninepoint\noindent\qquad\qquad +{\bf begin goto} \\{breakpoint};\par +\noindent\qquad\qquad\quad$\{\,$go to every declared label at least once$\,\}$\par +\noindent\qquad\quad\\{breakpoint}: $m\gets0$; + \.{@\char`\{\char`\'BREAKPOINT\char`\'@\char`\}} + +\bugonpage D566, the bottom five lines (05/14/19) + +\tenpoint\noindent +they occupy in a typical production system +(executable code size for dark blocks, global data size for light blocks). +In this way the chart indicates a total of about +$8\times22=176${\ninerm K} bytes of memory, plus +$8\times15=120${\ninerm K} for the +dynamic memory region not shown explicitly. The dynamic memory +is often considerably larger in practice, because it is desirable to +accommodate large macro packages and large pictures. + + +% volume E +\hsize=29pc + +\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 `--' + + +\bye diff --git a/Master/texmf-dist/doc/generic/knuth-errata/errata.three b/Master/texmf-dist/doc/generic/knuth-errata/errata.three new file mode 100644 index 00000000000..d4a0afaccd8 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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\{\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`\$\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\{\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-dist/doc/generic/knuth-errata/errata.twelve b/Master/texmf-dist/doc/generic/knuth-errata/errata.twelve new file mode 100644 index 00000000000..8a7c291b490 --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/errata.twelve @@ -0,0 +1,1709 @@ +% Bugs (sigh) in Computers \& Typesetting + +\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\endgraf}} + +\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\/} between the publication of the second ``Millennium Edition'' +at the close of the year 2001 and the beginning of the year 2014. +(More precisely, it lists errors corrected +in 16th to 19th printings of Volume~A, the 7th and 8th printings +of Volume~B, the 6th and 7th printings of Volume~C, the 4th and 5th printings +of Volume~D, and the 5th and 6th printings of Volume~E.) +Corrections made to the softcover version of {\sl The \TeX book\/}, +beginning with its 32nd printing, are +the same as corrections to Volume~A\null. Corrections to the softcover +version of {\sl The \slMF\kern1ptbook}, beginning with its 11th printing, +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. All of these +errors have supposedly been corrected in more recent printings, unless +they were subsequently found to be wrong. +\looseness=-1 + +% volume A + +\bugonpage A7, line 4 from the bottom (01/15/04) + +\noindent +since control sequences of the second kind always have exactly one +symbol after\cutpar + +\bugonpage A123, line 7 from the bottom (02/27/08) + +\ninepoint\noindent +that it won't make the natural height-plus-depth +of\/ |\box|$\,n$ surpass |\dimen|$\,n$, when it~is\cutpar + +\bugonpage A124, lines 12 and 13 (02/27/08) + +\ninepoint\noindent +means that \TeX\ has tried to split an |\insert254| to height $180.2\pt$; +the natural height-plus-depth of the best such split is $175.3\pt$, +and the penalty for breaking there is~100.) + +\bugonpage A153, line 7 (01/03/14) + +\ninepoint\noindent +of three fonts: one for text size, one for +script size, and one for scriptscript size. The\cutpar + +\bugonpage A206, lines 12--17 (05/21/07) + +\ninepoint\noindent +or alignment template +is also considered to be |\outer| in this sense; for example, a +file shouldn't end in the middle of a definition. If you are designing a +format for others to use, you can help them detect errors before too much +harm is done, by using |\outer| with all control sequences that should +appear only at ``quiet times'' within a document. For example, Appendix~B +defines |\proclaim| to be |\outer|, since a user shouldn't be stating a +theorem as part of a definition or argument or preamble. + + +\bugonpage A216, line 3 from the bottom (12/20/07) + +\ninepoint\indent|\openin|\<number>|=|\<file name> + +\bugonpage A290, lines 25--26 (02/24/08) + +\ninepoint\textindent{$\bull$} +\<leaders>\<box or rule>\<horizontal skip>.\enskip +Here \<horizontal skip> refers to one of the first five glue-appending +commands just mentioned; the formal syntax for \<leaders>\cutpar + +\bugonpage A292, line 15 (12/02/02) + +\ninepoint\noindent +are defined as in the +second alternative of a \<math field>, are +recorded in a ``choice\cutpar + +\bugonpage A308, lines 25 and 26 (06/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/02/02) + +\ninepoint\indent +|\def\\{\if\space\next\ % assume that \next is unexpandable| + +\bugonpage A311, line 17 (12/29/07) + +\ninepoint\indent +| \leavevmode\copy0\kern-\wd0\makelightbox}| + +\bugonpage A318, lines 24 and 25 (10/01/03) + +\ninepoint\noindent +\hbox to\parindent{\bf\hss15.13.\enspace}% +Yes, in severe circumstances. (1)~Previous footnotes might + have left no room for any more footnotes on the page. +(2)~If |\vadjust{\eject}| occurs on the same line\cutpar + +\bugonpage A364, lines 12--15 from the bottom (02/29/08) + +\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}|\par +\noindent +|\def\tracingall{\tracingonline=1 \loggingall}| + +\bugonpage A364, line 5 from the bottom (02/29/08) + +\ninepoint\noindent +|\def\fmtversion{3.141592653} % identifies the current format| + +\bugonpage A373, lines 4 and 5 from the bottom (01/02/14) + +\ninepoint\noindent +And here's another solution (which may be faster, because +token list registers can be expanded more quickly than macros +on some implementations, using |\the|): + +\bugonpage A373, line 2 from the bottom (01/02/14) + +\ninepoint\indent +|\loop \ifnum\m>0 \t=\expandafter{\the\t*}\advance\m-1 \repeat| + +\bugonpage A399, line 18, through what used to be page A400, line 14 (02/26/08) + +\ninepoint +Finally, the reformatting of\/ |\box\footins| can be achieved easily with +an elegant technique suggested by David Kastrup, using the following +\TeX\ code within the |\output| routine: +\begindisplay +|\def\makefootnoteparagraph{\unvbox\footins|\cr +| \baselineskip=\footnotebaselineskip \removehboxes}|\cr +|\def\removehboxes{\unskip\setbox0=\lastbox|\cr +| \ifhbox0{\removehboxes}\unhbox0 \else\noindent \fi}|\cr +\enddisplay +The key idea here is |\removehboxes|, a macro that has the magical ability to +take a vertical box such as `|\vbox{\box1\box2\box3\removehboxes}|' and +transform it into +`|\vbox{\noindent\unhbox1\unhbox2\unhbox3}|'\kern-1pt, +if\/ |\box1|, \kern-2pt|\box2|, and +|\box3| are hboxes. Notice how |\removehboxes| introduces braces so that +\TeX's {save stack} will hold all of the hboxes before they are unboxed. Each +level of recursion in this routine uses one cell of input stack space and +three cells of save stack space; thus, it is generally safe to do more than +100 footnotes without exceeding \TeX's capacity. + +In our application there is no interline glue within |\box\footins|, +so the |\unskip| command could be deleted from |\removehboxes|. + +Incidentally, the |\unskip| and |\lastbox| operations have running +times of the approximate form +$a+mb$, where $m$~is the number of items on the +list preceding the glue or box that is removed. Hence |\removehboxes| has a +running time of order $n^2$ when it removes $n$~boxes. +But the constant~$b$ is so small that +for practical purposes it's possible to think of\/ |\unskip| and +|\lastbox| as almost instantaneous. + +\bugonpage A416, lines 18--22 (06/08/07) + +\ninepoint\noindent\beginlines +|\def\leftheadline{\hbox to \pagewidth{\spaceskip=0pt| +| \vbox to 10pt{}% strut to position the baseline| +| \llap{\tenbf\folio\kern1pc}% folio to left of text| +| \tenit\rhead\hfil}} % running head flush left| +|\def\rightheadline{\hbox to \pagewidth{\spaceskip=0pt\vbox to 10pt{}%| +\endlines + +\bugonpage A418, line 8 from the bottom (12/13/11) + +\ninepoint\noindent\beginlines +| \def\\{#3} \advance\hsize by -18mm| +\endlines + +\bugonpage A418, line 3 from the bottom (12/13/11) + +\ninepoint\noindent\beginlines +| \halign{\line{\titlefont\hss##}\\#4\unskip\\}| +\endlines + +\bugonpage A442, lines 7 and 8 from the bottom (01/03/14) + +\def\rule#1.{\smallskip\textindent{\bf#1.}\ignorespaces} +\ninepoint\textindent{\bf 3.}% +If the current item is a style change, set $C$ to the specified +style and move on to the next item. + +\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 A458, left column (01/11/07) + +\eightpoint\noindent +|\\|, 38, {\it356}, {\it378}, {\it418}. + +\bugonpage A459, left column (03/17/06) + +\eightpoint\noindent +angle brackets ( $\langle\,\rangle$ ), 59, {\it146--147}, 150,~156,\par +\noindent\qquad $\underline{268}$, 420, 437; + {\sl see also\/} |\langle|, |\rangle|. + +\bugonpage A461, left column (02/24/08) + +\eightpoint\noindent +|\boxit|, 223, 331. + +\bugonpage A468, right column (02/26/08) + +\eightpoint\noindent +interline glue, 78--79, $\underline{80}$, 104, 105, 125, 221,\par +\noindent\qquad 245, 263, 281--282, 335, 352, 399, 409. + +\bugonpage A469, left column (02/26/08) + +\eightpoint\noindent +Kastrup, David Friedrich, 399. + +\bugonpage A470, left column (01/21/03) + +\eightpoint\noindent +|\loggingall|, $\underline{364}$. + +\bugonpage A477, right column (06/08/07) + +\eightpoint\noindent +\llap{*}|\spaceskip|, 76, 274, {\it317}, {\it356}, {\it416}, 429. + +\bugonpage A479, right column (09/11/07) + +\eightpoint\noindent +|\undefined|, 350, 384. + +\bugonpage A483, line 5 from the bottom (11/18/03) + +\eightpoint +\rightline{\eightss--- HIERONYMUS HORNSCHUCH, % + {\eightrm'}$O\mkern-1mu\rho\mkern1mu\vartheta o\mkern1mu % + \tau\upsilon\pi o\gamma\mkern-1mu % + \rho\alpha\phi\acute\iota\alpha\varsigma$\enspace(1608)} + +% volume B +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\to{\mathrel{.\,.}} % double dot, used only in math mode + +\bugonpage Bv, page number change (12/27/11) + +\eightpoint\noindent[For consistency with Volumes A, C, and E, the +preface now begins on page v instead of page~vii. This change was first +made in the ninth printing.] + +\bugonpage Bv {(formerly Bvii)}, bottom two lines (01/06/14) + +\eightpoint\noindent +all of those changes. +I~now believe that the final bug was discovered on 14 September 2008 +and removed in version 3.14159265. +The finder's fee has converged to \$327.68. + +\bugonpage Bxiii {(formerly Bxv)}, line $-7$ (12/27/11) + +\ninepoint\noindent +Format specs have no effect on the corresponding Pascal program, but they +do influence\cutpar + +\hsize=35pc + +\bugonpage B2, line 10 from the bottom (01/02/14) + +\ninepoint\noindent\hskip10pt +{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$% +{\tt This\]is\]TeX,\]Version\]3.14159265\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 B21, lines 33 and 34 (09/11/07) + +\def\Oct#1{\hbox{\rm\char'23\kern-.2em\it#1\/\kern.05em}} % octal constant +\tenpoint\noindent +$[\Oct{41}\to\Oct{46},\Oct{60}% +\to\Oct{71},\Oct{136},\Oct{141}\to\Oct{146},\Oct{160}\to\Oct{171}]$ must be printable. +Thus, at least 81 printable characters are needed. + +\bugonpage B109, line 16 (01/06/14) + +\ninepoint\noindent +\qquad\qquad{\bf begin} $\\{print\_esc}(\.{"csname"})$; +$\\{print\_esc}(\.{"endcsname"})$; +$\\{print\_char}(\.{"\ "})$; +{\bf end} + +\bugonpage B114, line 25 (09/11/07) + +\def\#{\hbox{\tt\char`\#}} % parameter sign +\ninepoint\noindent +{\bf define} $\\{save\_index}(\#)\equiv\\{save\_stack}[\#].\\{hh}.\\{rh}$\quad + $\{\,$\\{eqtb} location or token or \\{save\_stack} location$\,\}$ + +\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 B144, line 14 (09/11/07) + +\ninepoint\noindent +\quad\\{cat}: $0\to\\{max\_char\_code}$;\quad$\{\,$\\{cat\_code}(\\{cur\_char}), usually$\,\}$ + +\bugonpage B153, lines 2 and 3 (09/11/07) + +\tenpoint\noindent +In fact, these three procedures account for almost every use of \\{get\_next}. + +\bugonpage B161, line 19 (12/19/02) + +\ninepoint\noindent +\quad{\bf 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 B163, line 29 (12/19/02) + +\ninepoint\noindent +\quad$\\{long\_state}\gets\\{call}$; +$\\{cur\_tok}\gets\\{par\_token}$; +$\\{ins\_error}$; +{\bf goto} \\{continue}; + +\bugonpage B172, lines 2--6 from the bottom (09/11/07) + +\ninepoint\noindent +{\bf else if\/} $m=\\{vmode}$ {\bf then} \\{scanned\_result}(\\{prev\_depth})(\\{dimen\_val})\par\noindent +\quad{\bf else} \\{scanned\_result}(\\{space\_factor})(\\{int\_val}) + +\bugonpage B178, line 4 (09/11/07) + +\ninepoint\noindent +\quad$\\{cur\_val}\gets0$; +$\\{cur\_val\_level}\gets\\{int\_val}$; +$\\{radix}\gets0$; +$\\{cur\_order}\gets\\{normal}$; + +\bugonpage B184, line 9 from the bottom (04/18/07) + +\tenpoint\noindent +and denominator sum to 32768 or less. +According to the definitions here, $\rm2660\,dd\approx1000.33297\,mm$;\kern-6.6pt\cutpar + +\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 B227, new line to precede line 23 (09/11/07) + +\ninepoint\noindent +{\bf if} $(\\{nw}=0)\lor(\\{nh}=0)\lor(\\{nd}=0)\lor(\\{ni}=0)$ + {\bf then} \\{abort}; + +\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 B266, line 29 (09/11/07) + +\tenpoint\noindent +$\\{total\_pages}\ge65536$, the \.{DVI} file will lie. And if +$\\{max\_push}\ge65536$, the user deserves whatever chaos might ensue. + +\bugonpage B279, line 19 (09/11/07) + +\ninepoint\noindent +\qquad\\{p}: \\{pointer};\quad$\{\,$a new glue node$\,\}$ + +\bugonpage B288, lines 18--20 (09/11/07) + +\ninepoint\noindent +\\{left\_noad}: {\bf begin} \\{print\_esc}(\.{"left"}); + \\{print\_delimiter}(\\{delimiter}($p$));\par\noindent +\quad{\bf end};\par\noindent +\\{right\_noad}: {\bf begin} \\{print\_esc}(\.{"right"}); + \\{print\_delimiter}(\\{delimiter}($p$)); + +\bugonpage B290, line 12 (09/11/07) + +\ninepoint\noindent +\quad{\bf begin if\/} $s=\\{text\_size}$ {\bf then} + \\{print\_esc}(\.{"textfont"}); + +\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 B336, line 11 from the bottom (10/13/03) + +\tenpoint\noindent +$j-i+\\{min\_quarterword}$ in their +\\{link} fields. The values of $w_{ii}$ were initialized to +\\{null\_flag},\cutpar + +\bugonpage B342, lines 5 and 6 (09/11/07) + +\tenpoint +In restricted horizontal mode, the \\{clang} part of \\{aux} is undefined; +an over-cautious Pascal runtime system may complain about this. + +\bugonpage B343, line 25 (01/02/13) + +\noindent +should begin in the +sequence of line numbers, in case hanging indentation or \.{\char`\\parshape} +is in\cutpar + +\bugonpage B416, line 22 (02/29/08) + +\ninepoint\noindent +\qquad\qquad{\bf if\/} $\\{count}(t)=1000$ {\bf then} $t\gets\\{height}(r)$ +\par\noindent +\qquad\qquad{\bf else} $t\gets\\{x\_over\_n}(\\{height}(r),1000)*\\{count}(t)$; +\par\noindent +\qquad\qquad\\{print\_scaled}$(t)$ + +\bugonpage B438, lines 1--3 (09/11/07) + +\tenpoint\noindent +{\bf1035.\quad}If \\{link}(\\{cur\_q}) is nonnull when \\{wrapup} is invoked, +\\{cur\_q} points to +the list of characters that were consumed while building the ligature +character~\\{cur\_l}. + +\bugonpage B438, lines 19 and 20 (09/11/07) + +\ninepoint\noindent +\qquad\qquad\qquad{\bf begin if\/} $\\{link}(\\{cur\_q})>\\{null}$ {\bf then} +\par\noindent +\qquad\qquad\qquad\quad{\bf if\/} $\\{character}(\\{tail})=\\{qi}( + \\{hyphen\_char}[\\{main\_f}])$ {\bf then} $\\{ins\_disc}\gets\\{true}$; + +\bugonpage B438, line 4 from the bottom (09/11/07) + +\ninepoint\noindent +\quad$\\{link}(\\{tail})\gets\\{lig\_stack}$; +$\\{tail}\gets\\{lig\_stack}$\quad$\{\,$\\{main\_loop\_lookahead} is next$\,\}$ + +\bugonpage B439, line 3 (09/11/07) + +\ninepoint\noindent +\quad{\bf if\/} $\\{main\_p}>\\{null}$ {\bf then} + \\{tail\_append}(\\{main\_p});\quad$\{\,$append a single character$\,\}$ + +\bugonpage B440, new line to follow line 9 (09/11/07) + +\ninepoint\noindent +\quad{\bf if\/} $\\{cur\_r}=\\{non\_char}$ {\bf then goto} + \\{main\_loop\_wrapup}; + +\bugonpage B452, line 18 (28/03/11) + +\noindent\\{hmode}, where the latter two are used to denote + \.{\char`\\vbox} and \.{\char`\\hbox}, respectively. + +\bugonpage B455, lines 3 and 4 (09/11/07) + +\ninepoint\noindent +\quad{\bf if\/} $((\\{cur\_cmd}=\\{hskip})\land(\\{abs}(\\{mode})\ne\\{vmode})) + \lor ((\\{cur\_cmd}=\\{vskip})\land(\\{abs}(\\{mode})=\\{vmode}))$ {\bf then} + +\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 B505, line 19 (09/11/07) + +\ninepoint\noindent +\qquad(\.{"since\]the\]result\]is\]out\]of\]range."});\par\noindent +\qquad{\bf if\/} $p\ge\\{glue\_val}$ {\bf then} + \\{delete\_glue\_ref}(\\{cur\_val});\par\noindent +\qquad\\{error}; {\bf return}; + +\bugonpage B506, line 1 (10/13/03) + +\tenpoint\noindent +{\bf 1237.\quad}Here we use the fact that the consecutive codes +$\\{int\_val}\to\\{mu\_val}$ and +$\\{assign\_int}\to$\cutpar + +\bugonpage B520, line 8 (06/25/04) + +\tenpoint\noindent +says, +for example, `\.{(preloaded format=plain 1982.11.19)}', showing the year, +month, and day\cutpar + +\bugonpage B535, new line to follow line 11 (09/11/07) + +\ninepoint\noindent +\qquad{\bf if\/} $\\{last\_glue}\ne\\{max\_halfword}$ {\bf then} + \\{delete\_glue\_ref}(\\{last\_glue}); + +\bugonpage B578, new entry (06/04/06) + +\eightpoint\noindent +Trabb Pardo, Luis Isidoro, 2. + +% volume C +\hsize=29pc +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\ddashto{\mathrel{\hbox{-\thinspace-\thinspace-\kern-.05em}}} +\def\tension{\mathop{\rm tension}} +\def\controls{\mathop{\rm controls}} +\def\and{\,{\rm and}\,} + +\bugonpage Cxi, line 4 (05/20/07) + +\line{\hbox to\parindent{\bf\hbox to 1em{\hss27}\hss}% + \rm Recovery from Errors\leaders\hbox to 20pt{\kern13pt.\hss}\hfil + \hbox to 2em{\hss223}} + +\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 (09/09/01) + +\noindent +[points 2 and 5 should not be labeled twice] + +\bugonpage C32, line 5 from the bottom (01/04/14) + +\noindent +\hbox to\parindent{\hfil\sevenrm20\ \ }% +| penpos1(stem,15); penpos2(.9stem,12); penpos3(stem,10);| + +\bugonpage C36, line 5 from the bottom (01/05/14) + +\noindent +line~12, where it +says `|x1l|', not `|x11|' or~`|xll|'); be sure to distinguish between\cutpar + +\bugonpage C55, lines 5 and 6 (01/05/14) + +\ninepoint\noindent +suffixed or subscripted. +Thus, the syntax rule for \<variable> +should actually be replaced by a slightly more complicated pair of rules: + + +\bugonpage C129, line 16 (02/21/08) + +\ninepoint\beginsyntax +<path subexpression>\is<path expression not ending with direction specifier>\kern-5pt\null +\endsyntax + +\bugonpage C130, lines 13--15 from the bottom (09/13/03) + +\ninepoint\noindent +point but not after it, the +nonempty one is duplicated in a similar way. A~basic path join +`$\to\controls u\and v\to$' specifies explicit control points that +override any direction specifiers that may immediately surround it. + +\bugonpage C137, lines 5--7 from the bottom (02/21/08) + +\danger Let's conclude this chapter by applying what we've learned about +paths to a real-life example. The {\sl Journal of Algorithms\/} was +published for many years by Academic Press, and its cover page carried the +following logo, which was designed\cutpar +\enddanger + +\bugonpage C137, bottom two lines (02/21/08) + +\ninepoint\noindent +A \MF\ program to produce this logo made it possible for the editors +of the journal to use it on letterheads in their correspondence. +Here is one way to do that job,\cutpar +% actually the MS now says "to write that program," and the +% correction therefore extends to page C138 + +\bugonpage C156, line 15 from the bottom (09/09/01) + +\ninepoint\noindent +be the values they had upon entry to the group.) + +\bugonpage C159, lines 12--15 (12/01/06) + +\begintt +def --- = ..tension infinity.. enddef; +\endtt +it makes `$z_1\ddashto z_2$' become +`$z_1\to\tension\\{infinity}\to z_2$'. +The {replacement text} can be any sequence of tokens not including +`{\bf enddef}\kern1pt'; or it can include entire subdefinitions like +`{\bf def}~$\ldots$~{\bf enddef}\kern1pt', according to certain rules +that we shall explain later. + +\bugonpage C171, line 16 from the bottom (06/18/02) + +\tenpoint +\<loop>\is\<loop header>|:|\<loop text> {\tt endfor} + +\bugonpage C179, line 7 from the bottom (09/09/01) + +\ninepoint\noindent +next time \MF\ gets to the end of an input line, it will stop reading +from the\cutpar + +\bugonpage C180, lines 14--16 (04/25/03) + +\ninepoint\noindent +digits should be a +file name that works in essentially the same way on all installations of +\MF\kern-.03em\null. Uppercase letters are considered to be distinct from their +lowercase counterparts, on many systems. + +\bugonpage C180, new line to be inserted 4 from the bottom (06/25/04) + +\ninepoint\item\bull +When \MF\ is reading the symbolic tokens to be saved by {\bf save}. + +\bugonpage C203, line 12 from the bottom (04/25/03) + +\ninepoint\hbox to 237pt{point~3 at the right of the triangle +might digitize into a} + +\bugonpage C213, line 26 (02/21/08) + +\ninepoint\beginsyntax +<path subexpression>\is<path expression not ending with direction specifier>\kern-5pt\null +\endsyntax + +\bugonpage C226, line 23 (02/21/08) + +\ninepoint\noindent following nineteen things will be mentioned: + +\bugonpage C226, new line to be second from the bottom (02/21/08) + +\ninepoint\indent|independent variables|\qquad(distinct numeric variables) + +\bugonpage C236, line 7 from the bottom (01/05/14) + +\ninepoint\noindent +\hbox to\parindent{\hss\bf 7.4.\enspace}False. +After `|newinternal x;|' you can't say `|x|\<tag>' in a \<suffix list>. + +\bugonpage C246, line 12 (02/21/08) + +\ninepoint\noindent +is performed whenever \MF\ uses the last two alternatives +in the definition\cutpar + +\bugonpage C250, lines 13 and 14 (02/19/08) + +\ninepoint\noindent\hbox to\parindent{\bf\hss19.3.\enspace}% +Yes, if and only if $n-{1\over2}$ is a nonnegative even integer. +\ (Because ambiguous values are rounded upwards.) + +\bugonpage C250, line 12 from the bottom (04/25/03) + +\ninepoint\noindent +following \<boolean primary>.) + +\bugonpage C286, line 25 (09/09/01) + +\ninepoint\noindent +problem; it would simply have put |ENDFOR| into the +replacement text of |asts|, because\cutpar + +\bugonpage C289, line 7 (09/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 (09/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 C293, line 5 from the bottom (04/25/03) + +\ninepoint\noindent +given angle~$\phi$. We can consider +the common angle~$\theta$ of $z_{1r}-z_{1l}$ and $z_{0r}-z_{0l}$ to be\cutpar + +\bugonpage C315, line 15 from the bottom (04/25/03) + +\ninepoint\noindent +`b' was shipped out.) \ The second letter,~`o', is placed +in a second little box adjacent\cutpar + +\bugonpage C325, bottom line (02/29/08) + +\rightline{\eightss--- CAROLUS LINN\AE US, + {\eightssi Philosophia Botanica\/}\enspace(1751)} + +\bugonpage C332, line 4 from the bottom (04/25/03) + +\ninepoint\noindent +(The proofsheet resolution will be 50 pixels per inch, because {\it cheapo\/} +has 200 pixels per\cutpar + +\bugonpage C346, left column (06/18/02) + +\eightpoint\noindent +\llap{*}|:|, 169, 171, 317--319. + +\bugonpage C346, right column (07/09/01) + +\eightpoint\noindent +\llap{*}|angle|, {\it29}, {\it67}, $\underline{72}$, {\it107}, +{\it135}, 211, {\it238}. + +\bugonpage C346, right column (10/04/04) + +\eightpoint\noindent +arccosine, arcsine, arctangent, {\sl see\/} |angle|. + +\bugonpage C351, right column (02/21/08) + +\eightpoint\noindent +independent variables, $\underline{81}$--$\underline{83}$, 88, 224, 226. + +\bugonpage C352, right column (02/29/08) + +\eightpoint\noindent +Linn\'e, Carl von (= Linn\ae us, Carolus), 325. + +\bugonpage C355, right column (02/29/08) + +\eightpoint\noindent +\llap{*}|save|, $\underline{155}$--$\underline{156}$, {\it160}, 173, + {\it178}, 180, 218,\par +\noindent\qquad{\it236}, {\it244}, {\it296}, 299. + +% Volume D +\def\\#1{\hbox{\it#1\/\kern.05em}} % italic type for identifiers +\def\to{\mathrel{.\,.}} % double dot, used only in math mode + +\bugonpage Dv, page number change (12/27/11) + +\eightpoint\noindent[For consistency with Volumes A, C, and E, the +preface now begins on page v instead of page~vii. This change was first +made in the sixth printing.] + +\bugonpage Dv {(formerly Dvii)}, bottom two lines (01/06/14) + +\eightpoint\noindent +corporates all of those changes. +I~now believe that the final bug was discovered on 03~June 2008, +and removed in version 2.7182818. +The finder's fee has converged to \$327.68. + +\bugonpage Dxiii {(formerly Dxv)}, line $-7$ (12/27/11) + +\ninepoint\noindent +Format specs have no effect on the corresponding Pascal program, but they +do influence\cutpar + +\hsize=35pc +\parindent=1em + +\bugonpage D2, line $-17$ (01/03/14) + +\ninepoint\noindent +{\bf define} $\\{banner}\equiv\hbox{\tt\char'23}$% +{\tt This\]is\]METAFONT,\]Version\]2.7182818\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 D16, new paragraph to follow line 26 (06/25/04) + +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. +(If the Pascal compiler does not support non-local {\bf goto}, the +statement `{\bf goto} \\{final\_end}' should be replaced by something that +quietly terminates the program.) + +\bugonpage D22, line 26 (09/11/07) + +\noindent +ASCII codes $[\Oct{60}\to\Oct{71},% +\Oct{136},\Oct{141}\to\Oct{146}]$ +must be printable. + +\bugonpage D31, line 29 (06/25/04) + +\noindent +This is the only nontrivial {\bf goto} statement in the +whole program. It is used when there is no\cutpar + +\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 D58, line 16 from the bottom (06/25/04) + +\ninepoint\noindent +\hskip5em{\bf if\/} $\\{j\_random}=0$ {\bf then} \\{new\_randoms} + {\bf else} \\{decr}(\\{j\_random}) + +\bugonpage D63, line 21 (06/25/04) + +Locations of \\{mem} between \\{mem\_min} and \\{mem\_top} may be dumped as +part +of preloaded base\cutpar + +\bugonpage D75, line 13 (06/25/04) + +\ninepoint\noindent +\quad{\bf define} $\\{fi\_or\_else}=2$\quad$\{\,$delimiters for conditionals + ({\bf elseif\/}, {\bf else}, {\bf fi})$\,\}$ + +\bugonpage D76, line 5 (06/25/04) + +\ninepoint\noindent +\quad{\bf define} $\\{type\_name}=30$\quad$\{\,$declare a type + ({\bf numeric}, {\bf pair}, etc.)$\,\}$ + +\bugonpage D77, line 16 (06/25/04) + +\ninepoint\noindent +\quad{\bf define} $\\{lig\_kern\_token}=76$\quad$\{\,$the operators + `{\bf kern}' and `\.{=:}' and `\.{=:\char'174}', etc.$\,\}$ + +\bugonpage D98, bottom two lines (06/25/04) + +\noindent +They consist of zero or more parameter tokens followed +by a code for the type of macro. + +\bugonpage D101, line 3 (06/25/04) + +\noindent +\MF\ user assigns a type to a variable like \.{x20a.b} by saying, for +example, `\.{boolean} \.{x[]a.b}'. + +\bugonpage D102, lines 10--16 (06/25/04) + +\noindent +variable that is relevant +when no attributes are attached to the parent. The \\{attr\_head} node +has the fields of either +a value node, a subscript node, or an attribute node, depending on what +the parent would be if it were not structured; but the subscript and +attribute fields are ignored, so it effectively contains only the data of +a value node. The \\{link} field in this special node points to an attribute +node whose \\{attr\_loc} field is zero; the latter node represents a collective +subscript `\.{[]}' attached to the parent, and its \\{link} field points to +the first non-special attribute node (or to \\{end\_attr} if there are none). + +\bugonpage D102, lines 7 and 8 from the bottom (06/25/04) + +\noindent +$\\{subscr\_head}(\\{q1})=\\{qq1}$; +\\{qq} is a three-word ``attribute-as-value'' node with +$\\{type}(\\{qq})=\break\\{numeric\_type}$ +(assuming that \.{x5} is numeric, because \\{qq} represents `\.{x[]}' +with no further\break + attributes), $\\{name\_type}(\\{qq})=\\{structured\_root}$, +$\\{attr\_loc}(\\{qq})=0$, $\\{parent}(\\{qq})=p$,\cutpar + +\bugonpage D103, line 6 (06/25/04) + +\noindent +The value of variable \.{x20b} +appears in node~$\\{qqq2}=\\{link}(\\{qqq1})$, as you can well imagine. +Similarly, the value of `\.{x.a}' appears in node $\\{q2}=\\{link}(\\{q1})$, +where $\\{attr\_loc}(\\{q2})=h(a)$ and $\\{parent}(\\{q2})=p$. + +\bugonpage D114, line 12 (06/25/04) + +\noindent +\qquad Such save stack entries are generated by {\bf save} commands. + +\bugonpage D120, line 3 (06/25/04) + +\ninepoint\noindent +[delete the line `The code here \dots', since the + code {\it doesn't\/} use the stated fact] + +\bugonpage D126, line 10 (06/25/04) + +\tenpoint\noindent +If $\theta_0$ is supposed to have a given value $E_0$, we simply +define $C_0=1$, $D_0=0$, and $R_0=E_0$.\cutpar + +\bugonpage D138, line 11 from the bottom (10/26/06) + +\tenpoint\noindent +for the bisected interval are $z'_0=z_0$ +and $z''_0=z_0+(Z'_1+Z'_2+\cdots+Z'_n)/2^{l+1}$. + +\bugonpage D142, line 3 (06/25/04) + +\tenpoint\noindent +out to hold if and only if $x_0\le x_1$ and $x_2\le x_3$, and either +$x_1\le x_2$ or $(x_1-x_2)^2\le(x_1-x_0)(x_3-x_2)$.\cutpar + +\bugonpage D142, line 8 (10/26/06) + +\tenpoint\noindent\quad +For example, if we start with $(x_1-x_0,x_2-x_1,x_3-x_2)= +(X_1,X_2,X_3)=(7,-16,39)$, the\cutpar + +\bugonpage D142, lines 21--23 (06/25/04) + +\tenpoint\noindent +monotonic +cubic, then $B(x_0,x_1,x_2,x_3;{1\over2})$ is always between +$.06[x_0,x_3]$ and $.94[x_0,x_3]$; and it is impossible for $\bar x$ +to be within~$\epsilon$ of such a number. Contradiction! +(The constant .06 is actually $(2-\sqrt3\,)/4$; the worst case +occurs for polynomials like $B(0,2-\sqrt3,1-\sqrt3,3;t)$.) + +\bugonpage D177, line 18 (06/25/04) + +\ninepoint\noindent +$\\{cur\_x},\\{cur\_y}$: \\{scaled};\quad$\{\,$outputs of \\{skew}, + \\{unskew}, and a few other routines$\,\}$ + +\bugonpage D182, lines 27--29 (06/25/04) + +\noindent +{\bf399.\quad}If + the segment numbers on the cycle are $t_1$, $t_2$, \dots, $t_m$, +and if $m\le\\{max\_quarterword}$, +we have $t_{k-1}\le t_k$ except for at most one value of~$k$. If there are +no exceptions, $f$ will point to $t_1$; otherwise it will point to the +exceptional~$t_k$. + +\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 3--8 (06/25/04) + +The first job is to fix things so that $x(t)$ plus the horizontal +pen offset is an integer multiple of the +current ``granularity'' when the derivative $x'(t)$ crosses through zero. +The given cyclic path contains regions where $x'(t)\ge0$ and regions +where $x'(t)\le0$. The \\{quadrant\_subdivide} routine is called into action +before any of the path coordinates have been skewed, but some of them +may have been negated. In regions 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 D196, lines 15 and 16 (06/25/04) + +\noindent +current pen might be unsymmetric in such a way that $x$ coordinates +should round dif-\break ferently in different parts of the curve. +These considerations imply that round$(x_0)$\cutpar + +\bugonpage D200, line 4 (06/25/04) + +\noindent +and that there are similar ways to address other important offsets.\par +\smallskip\ninepoint +[Also delete the definitions of \\{north\_south\_edge}, etc., +on lines 11--15; those definitions are never used.] + +\bugonpage D212, line 18 (06/25/04) + +\noindent +at $(x_0,y_0)$ and ends at $(x_1,y_1)$, it's possible to +prove (by induction on the length of the truncated\cutpar + +\bugonpage D216, bottom line (06/25/04) + +\noindent +we list it twice (with coordinates +interchanged, so as to make the second octant look like\cutpar + +\bugonpage D217, lines 2--10 (06/25/04) + +\noindent +$$\tabskip\centering +\halign to\hsize{$\hfil#\;\mapsto\;{}$\tabskip=0pt& +$#\hfil$&\quad in the #\hfil\tabskip\centering\cr +w_2\;w_2\;w_2&(-5,6)\;(-5,6)\;(-5,6)\cr +\noalign{\vskip\belowdisplayskip +\vbox{\noindent\strut as the list of transformed and skewed offsets to use +when curves that travel in the second octant. Similarly, we will have\strut} +\vskip\abovedisplayskip} +w_2\;w_2\;w_2&(7,-6)\;(7,-6)\;(7,-6)&third;\cr +w_2\;w_2\;w_3\;w_3&(-7,1)\;(-7,1)\;(-3,2)\;(-3,2)&fourth;\cr +w_3\;w_3\;w_3&(3,-2)\;(3,-2)\;(3,-2)&fifth;\cr +w_3\;w_3\;w_0\;w_0&(-3,1)\;(-3,1)\;(1,0)\;(1,0)&sixth;\cr +w_0\;w_0\;w_0&(1,0)\;(1,0)\;(1,0)&seventh;\cr +w_0\;w_0\;w_0&(-1,1)\;(-1,1)\;(-1,1)&eighth.\cr}$$ + +\bugonpage D218, lines 2 and 3 (06/25/04) + +\noindent +count followed by pointers to the eight offset lists, followed +by an indication of the pen's range of values. + +\bugonpage D218, line 15 (06/25/04) + +The \\{link} field of a pen header node should be \\{null} if and only if +the pen is a single point. + +\bugonpage D227, line 11 (06/25/04) + +\noindent +\\{endpoint}. The cubics all have +monotone-nondecreasing $x(t)$ and $y(t)$. + +\bugonpage D228, lines 4--7 from the bottom (06/25/04) + +\noindent +In odd-numbered octants, the numerator and denominator of this fraction +will be nonnegative; in even-numbered octants they will both be nonpositive. +Furthermore we always have $0=s_0\le s_1\le\cdots\le s_n=\infty$. The goal of +\\{offset\_prep} is to find an offset index~$k$ to associate with +each cubic, such that the slope $s(t)$ of the cubic satisfies + +\bugonpage D231, line 7 (06/25/04) + +\ninepoint\noindent +\quad{\bf if\/} $\\{abs}(\\{du})\ge\\{abs}(\\{dv})$ {\bf then}\quad $\{\, + s_{k-1}\le1$ or $s_k\le1\,\}$ + +\bugonpage D231, line 16 (06/25/04) + +\noindent +and return towards $s_{k-1}$ or $s_k$, +respectively, yielding another solution of $(*)$. + +\bugonpage D246, line 4 from the bottom (06/25/04) + +\noindent +dinate fields. Hence, for example, +the point $\bigl($$\\{x\_coord}(p)-\\{left\_v}(q),\\{y\_coord}(p)+% +\\{right\_u}(p)$$\bigr)$ +also\cutpar + +\bugonpage D248, lines 14 and 15 (01/06/14) + +\noindent +the $x$-axis at the point +$\bigl((a^2-b^2)\sin\theta\cos\theta/\rho\bigr)+i\rho$, where +\vadjust{\vskip1pt}% +$\rho=\sqrt{(a\sin\theta)^2+(b\cos\theta)^2}$. It reaches +furthest to the right of~the $y$-axis at the point +$\sigma+i(a^2-b^2)\sin\theta\cos\theta/\sigma$, where +$\sigma=$\cutpar + +\bugonpage D248, line 24 (06/25/04) + +\ninepoint\noindent +\qquad{\bf else begin} $\\{beta}\gets\\{minor\_axis}$; + $\\{gamma}\gets\\{major\_axis}$; + $\\{theta}\gets0$; + +\bugonpage D251, line 1 (01/06/14) + +\noindent +{\bf536.\quad}Only the coordinates need to be copied, not the class numbers +and other stuff. At this point either $\\{link}(p)$ or +$\\{link}(\\{link}(p))$ is \\{null}. + +\bugonpage D251, line 10 (01/06/14) + +\ninepoint\noindent +\\{done1}: {\bf if\/} $(\\{link}(p)\ne\\{null})$ {\bf then} +$\\{free\_node}(\\{link}(p),\\{knot\_node\_size})$;\hfil\break +\null\quad$\\{link}(p)\gets s$; +$\\{beta}\gets-\\{y\_coord}(h)$; + +\bugonpage D256, line 2 from the bottom (06/25/04) + +\noindent +we have $2^lu_{\min}=2^lu_0+U_{\min}$, etc.; the condition for overlap +reduces to + +\bugonpage D261, line 5 (06/25/04) + +\ninepoint\noindent +\\{tol}: \\{integer};\quad$\{\,$bound on the uncertainty in the overlap test$\,\}$ + +\bugonpage D262, lines 26 and 27 (06/25/04) + +\ninepoint\noindent +\qquad\quad$\\{uv}\gets\\{uv}+\\{int\_packets}$;\quad$\{\,$switch + from \\{l\_packets} to \\{r\_packets}$\,\}$\par\noindent +\qquad\quad$\\{decr}(\\{cur\_tt})$; + $\\{xy}\gets\\{xy}-\\{int\_packets}$;\quad$\{\,$switch + from \\{r\_packets} to \\{l\_packets}$\,\}$ + +\bugonpage D262, line 11 from the bottom (06/25/04) + +\ninepoint\noindent +\qquad$\\{xy}\gets\\{xy}+\\{int\_packets}$;\quad$\{\,$switch + from \\{l\_packets} to \\{r\_packets}$\,\}$ + +\bugonpage D274, line 15 from the bottom (06/25/04) + +\ninepoint\noindent +\qquad\qquad{\bf begin if\/} $\\{serial\_no}>\\{el\_gordo}-\\{s\_scale}$ + {\bf then}\par\noindent +\qquad\qquad\quad$\\{overflow}(\.{"independent\]variables"}, + \\{serial\_no}\mathbin{\hbox{\bf div}}\\{s\_scale})$;\par\noindent +\qquad\qquad$\\{type}(\#)\gets\\{independent}$; + $\\{serial\_no}\gets\\{serial\_no}+\\{s\_scale}$; + $\\{value}(\#)\gets\\{serial\_no}$; + +\bugonpage D309, line 21 (06/25/04) + +\noindent +{\bf670.\quad}We go to \\{restart} instead of to \\{switch}, +because we might enter \\{token\_state} after the error\cutpar + +\bugonpage D314, line 6 from the bottom (06/25/04) + +\noindent +\\{macro\_def} or \\{iteration}). + +\bugonpage D330, line 1 (06/25/04) + +\noindent +{\bf728.\quad}A {\bf suffix} or {\bf text} parameter will have been scanned as +a token list pointed to by \\{cur\_exp},\cutpar + +\bugonpage D354, lines 15 and 16 from the bottom (06/25/04) + +\noindent\hangindent 3em +$\\{cur\_type}=\\{unknown\_boolean}$ means that \\{cur\_exp} points to a +capsule node that is in +a ring of equivalent booleans whose value has not yet been defined. + +\bugonpage D354, lines 11 and 12 from the bottom (06/25/04) + +\noindent\hangindent 3em +$\\{cur\_type}=\\{unknown\_string}$ means that \\{cur\_exp} points to a +capsule node that is in +a ring of equivalent strings whose value has not yet been defined. + +\bugonpage D354, lines 7 and 8 from the bottom (06/25/04) + +\noindent\hangindent 3em +$\\{cur\_type}=\\{unknown\_pen}$ means that \\{cur\_exp} points to a +capsule node that is in +a ring of equivalent pens whose value has not yet been defined. + +\bugonpage D355, lines 1 and 2 (06/25/04) + +\noindent\hangindent 3em +$\\{cur\_type}=\\{unknown\_path}$ means that \\{cur\_exp} points to a +capsule node that is in +a ring of equivalent paths whose value has not yet been defined. + +\bugonpage D355, lines 5 and 6 (06/25/04) + +\noindent\hangindent 3em +$\\{cur\_type}=\\{unknown\_picture}$ means that \\{cur\_exp} points to a +capsule node that is in +a ring of equivalent pictures whose value has not yet been defined. + +\bugonpage D355, lines 21 and 22 (06/25/04) + +\noindent +$\\{cur\_type}=\\{token\_list}$ means that \\{cur\_exp} points to a linked list +of tokens. + +\bugonpage D356, lines 2--3 (06/25/04) + +\noindent +nodes have $\\{name\_type}=\\{capsule}$, +and their \\{type} field is one of the possibilities for \\{cur\_type} +listed above. +Also $\\{link}\le\\{void}$ in capsules that aren't part of a token list. + +\bugonpage D368, line 13 (06/25/04) + +\ninepoint\noindent +\qquad\\{my\_var\_flag}: $0\to\\{max\_command\_code}$;\quad$\{\,$initial + value of \\{var\_flag}$\,\}$ + +\bugonpage D378, line 9 from the bottom (06/25/04) + +\ninepoint\noindent +\qquad\quad{\bf begin} $\\{cur\_type}\gets\\{known}$; + $\\{cur\_exp}\gets0$; + $\\{free\_node}(q,\\{dep\_node\_size})$; + +\bugonpage D380, line 12 (06/25/04) + +\ninepoint\noindent +\qquad\qquad{\bf begin} $\\{type}(r)\gets\\{known}$; + $\\{value}(r)\gets0$; + $\\{free\_node}(p,\\{dep\_node\_size})$; + +\bugonpage D390, lines 2 and 3 (06/25/04) + +\noindent +by a previous operation. We must maintain +the value of $\\{right\_type}(q)$ in cases such as\break +`|..{curl2}z{0,0\}..|'. + +\bugonpage D437, line 1 (06/25/04) + +\noindent +{\bf996.\quad}And \\{do\_assignment} is similar to \\{do\_equation}: + +\bugonpage D439, line 10 becomes two lines (06/25/04) + +\ninepoint\noindent +\qquad{\bf begin} $\\{nonlinear\_eq}(v,\\{cur\_exp},\\{false})$; + $\\{cur\_type}\gets t$; + {\bf goto} \\{done}; + +\bugonpage D443, line 11 (06/25/04) + +\ninepoint\noindent +\\{done}: {\bf if\/} $\\{eq\_type}(x)\mathbin{\hbox{\bf mod}}\\{outer\_tag} + \ne\\{tag\_token}$ {\bf then} + $\\{clear\_symbol}(x,\\{false})$; + +\bugonpage D452, line 9 (06/25/04) + +\noindent +though they don't necessarily correspond to primitive tokens. + +\bugonpage D476, line 12 from the bottom (06/25/04) + +\ninepoint\noindent +\quad{\bf if\/} $\\{nl}-\\{skip\_table}[c]>128$ {\bf then} + +\bugonpage D483, line 7 (06/25/04) + +\ninepoint\noindent +\quad$\\{max\_tfm\_dimen}\gets16\ast\\{internal}[\\{design\_size}]-1 + -\\{internal}[\\{design\_size}]\mathbin{\hbox{\bf div}}\Oct{10000000}$; + +\bugonpage D483, lines 15--17 (06/25/04) + +\ninepoint\noindent +\qquad{\bf if\/} $x>0$ {\bf then} + $x\gets\\{max\_tfm\_dimen}$ {\bf else} + $x\gets-\\{max\_tfm\_dimen}$;\par\noindent +\qquad{\bf end};\par\noindent +\quad$x\gets\\{make\_scaled}(x\ast16,\\{internal}[\\{design\_size}])$; + +\bugonpage D496, line 2 (06/25/04) + +\noindent +a pointer to +an edge structure. Its mission is to describe the positive pixels +in \.{GF} form,\cutpar + +\bugonpage D500, line 16 (06/25/04) + +\ninepoint\noindent +\quad$\\{selector}\gets\\{old\_setting}$; + $\\{gf\_out}(\\{cur\_length})$; + $\\{gf\_string}(0,\\{make\_string})$; + $\\{decr}(\\{str\_ptr})$; + +\bugonpage D506, lines 8--10 (06/25/04) + +\noindent +\MF\ it says, +for example, `\.{(preloaded base=plain 1984.2.29)}', showing the year, +month, and day that the base file was created. We have $\\{base\_ident}=0$ +before \MF's tables are loaded. + +\bugonpage D514, line 14 from the bottom (06/25/04) + +\noindent +\.{CMMF}, should also be provided for commonly used bases such as \.{cmbase}. + +% volume E +\hsize=29pc + +\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 `--' + +\bugonpage E1, line 3 (01/06/06) + +\tenpoint\noindent +Zillions of alphabets can be generated by the programs in this book. +All\cutpar + +\bugonpage E6, lines 16--19 (12/29/04) + +\textindent\bull + {\it square\_dots\/} tells whether dots should be square, not rounded;\smallskip +\textindent\bull + {\it hefty\/} tells whether weight-reducing strategies should be used;\smallskip +\textindent\bull\hangindent\parindent + {\it monospace\/} tells whether the characters should all be forced to + have the same width; + +\bugonpage E7, line 11 (12/21/02) + +\ninepoint\indent +\\{hair}, \\{vair}, \\{stem}, \\{curve}, \\{ess}, \\{flare}, \\{dot\_size}, + \\{bar}, \\{slab}, + +\bugonpage E7, line 14 (12/21/02) + +\ninepoint\indent +\\{crisp}, \\{tiny}, \\{fine}; +\medskip\noindent +and \\{thin\_join} should not be less than \\{fine}. + +\bugonpage E19, line 19 (11/07/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\char`\_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 E125, line 6 from the bottom (07/10/05) + +\ninepoint\noindent +$\\{top}\,y_1=\\{top}\,y_6=h$; $z_2=.5[z_3,z_1]+\\{bend}$; + +\bugonpage E125, line 3 from the bottom (07/10/05) + +\ninepoint\noindent +{\bf draw} $z_1-\\{flourish\_change}\{\\{up}\}+(0,.15\\{asc\_height}) + \{\\{up}\}$\par +\line{\quad$\8{...}\{\\{right}\}(z_1+(2u,0))\8{---}z_6\8{...}\{\\{down}\}z_7$; + \hfil\% upper bar} + +\bugonpage E146, also pages 164 and 540 (02/08/03) + +\eightpoint\noindent +[The labels on the new illustrations of beta, omega, and spadesuit +are too large, and the resolution of the shapes is too small.] + +\bugonpage E147, line 11 from the bottom (04/23/04) + +\ninepoint\noindent +$x_0=x_1=x_9$; $\\{lft}\,x_{0r}={\rm hround}(1.5u-.5\\{hair})$; +$x_2=x_4=x_6=x_8=.5w-.25u$; + +\bugonpage E147, line 8 from the bottom (04/23/04) + +\ninepoint\noindent +$y_5=.5[y_4,y_6]$; $\\{top}\,y_{6r}-\\{bot}\,y_{4r}=\\{vstem}+\\{eps}$; + $\\{bot}\,y_{8r}=-\\{oo}$; $y_7=y_9=.55[y_6,y_8]$; + +\bugonpage E149, line 8 from the bottom (04/23/04) + +\ninepoint\noindent +$y_5+.1\\{x\_height}=y_7=.5[y_6,y_8]$; $\\{bot}\,y_{6r}=-\\{oo}$; + +\bugonpage E157, line 11 (02/29/08) + +\ninepoint\noindent +\line{{\bf filldraw} $z_{1l}\8{--}z_{2l}\8{...}(x_3,y_{2l})\8{...}z\8{--} + z_{1r}\8{--}\rm cycle$;\hfil\% stem} + +\bugonpage E161, line 7 from the bottom (04/23/04) + +\ninepoint\noindent +$\\{top}\,y_{1r}=\\{x\_height}+\\{oo}$; $y_2=y_4=.5[y_1,y_3]$; + $\\{bot}\,y_{3r}=-\\{oo}$; + +\bugonpage E209, line 3 (12/29/04) + +\ninepoint +\rightline{\% This lowercase italic alphabet was prepared by D. E. Knuth + in December, 1979,} + +\bugonpage E377, lines 3 and 4 from the bottom (12/22/02) + +\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 E379, lines 17 and 18 become one line (01/06/14) + +\ninepoint\noindent +{\bf else}: $\\{rt}\,x_{6r}={\rm hround}(w-1.5u)$; +$y_{6}=y_{5l}+\\{eps};$ {\bf fi} + +\bugonpage E379, bottom line of the program (01/06/14) + +\def\SH{\raise.7ex\hbox{$\scriptstyle\#$}} % sharp sign for sharped units +\ninepoint\noindent +{\bf math\_fit}$(0,\\{ic}\SH-2.5u\SH)$; +{\bf penlabels}$(0,1,2,3,4,5,6,7)$; +{\bf endchar}; + +\bugonpage E489, bottom line (06/25/04) + +\ninepoint\noindent +{\bf labels}$(1,2,3,4,5,6)$; {\bf endchar};\hfil\break +[Labels `\.5' and `\.6' should also be added to + the lower illustration on page E488.] + +\bugonpage E545, line 11 from the bottom (12/29/04) + +\parindent=36pt +The most important general routine in |cmbase| is probably the {\it pos}\cutpar + +\bugonpage E551, line 3 from the bottom (12/29/04) + +\noindent quantities needed in the |calu| +programs are also established at this time. + + +\bugonpage E577, right column (12/23/02) + +\eightpoint\noindent +\\{p\_}\kern1pt, 305, 377.\par\noindent +{\bf padded}, 103--111, 117--121, $\underline{549}$. + +\bugonpage E578, left column (12/23/02) + +\eightpoint\noindent +{\bf postcontrol}, 347, 377.\par\noindent +{\bf precontrol}, 347, 377. + +\bye diff --git a/Master/texmf-dist/doc/generic/knuth-errata/errata.two b/Master/texmf-dist/doc/generic/knuth-errata/errata.two new file mode 100644 index 00000000000..74dde877267 --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/errorlog.tex b/Master/texmf-dist/doc/generic/knuth-errata/errorlog.tex new file mode 100644 index 00000000000..dfb201b7377 --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/errorlog.tex @@ -0,0 +1,2946 @@ +% 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 Guntermann). @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 +R936. Don't allow a million unbalanced braces followed by |\cr| + outside of any alignment (Ralf Roth). @789 +R937. Don't allow end-template except at end of template (Roth). @325,1131 +* 30 September 2002 +Q938. Improve rounding of glue during output (M. F. Bridgland). @625,634 +* 18 March 2008 +F939. Forgot to goto the proper error recovery (DRF). @395 +E940. Avoid a case of dirty Pascal and speed up inner loop. @1035 +R941. Forget reference to \\{last_glue} in format file (DRF). @1335 +R942. Glue reference not updated after overflow error (DRF). @1236 +B943. Muglue in |\leaders| had wrong units; now disallowed (DRF). @1078 +E944. Speedup of ligatures and kerns at end of a word (DRF). @1039 +R945. Another sanity check of TFM files for security (DRF). @565 +I946. Give better size data for unmagnified insertions. @986 +* 6 January 2014 +C947. Space after |\csname\endcsname| to match other spaces. (Oleg Bulatov) @262 +* 15 January 2021 +I948. Don't pause on errors when tracing paragraphs (Udo Wermuth). @826 +S949. Don't try to interact when in |\batchmode| (Xiaosa Zhang). @83 +S950. Don't try to edit when no file is active (Xiaosa Zhang). @84 +R951. Take date and time sometimes from system, not user (Udo Wermuth). @241,536 +B952. Don't allow implicit left brace after |#| (Udo Wermuth). @476 +R953. After nine parameters, must delete offending tokens (Bruno Le Floch). @476 +D954. Garbage visible in buffer after file ends prematurely (DRF). @486 +R955. Force nonexistent characters to have null specs (DRF). @722 +C956. Don't mark fraction noads as temporarily Inner (DRF). @761 +Q957. Reset |\newlinechar| before logging the stats (Udo Wermuth). @1333,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-dist/doc/generic/knuth-errata/logmac.tex b/Master/texmf-dist/doc/generic/knuth-errata/logmac.tex new file mode 100644 index 00000000000..8719efc497d --- /dev/null +++ b/Master/texmf-dist/doc/generic/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-dist/doc/generic/knuth-errata/mf84.bug b/Master/texmf-dist/doc/generic/knuth-errata/mf84.bug new file mode 100644 index 00000000000..c6349b896da --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/mf84.bug @@ -0,0 +1,2443 @@ +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 hackles 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. I forgot to update curtype in e.g. boolean b[]; b1=true=b2; + (Thorsten Dahlheimer, June 2004) +@x 1003 + begin nonlinear_eq(v,cur_exp,false); goto done; +@y + begin nonlinear_eq(v,cur_exp,false); unstash_cur_exp(cur_exp); goto done; +@z + +568. Wrong handling of extreme TFM values (T. Dahlheimer, June 2004) +@x 1128 +max_tfm_dimen:=16*internal[design_size]-internal[design_size] div @'10000000; +@y +max_tfm_dimen:=16*internal[design_size]-1-internal[design_size] div @'10000000; +@z +@x 1129 + if x>0 then x:=three_bytes-1@+else x:=1-three_bytes; + end +else x:=make_scaled(x*16,internal[design_size]); +@y + if x>0 then x:=max_tfm_param@+else x:=-max_tfm_param; + end; +x:=make_scaled(x*16,internal[design_size]); +@z + +569. Bug in make_ellipse when theta=180 (T. Dahlheimer, June 2004) +@x 530 + else begin beta:=minor_axis; gamma:=major_axis; +@y + else begin beta:=minor_axis; gamma:=major_axis; theta:=0; +@z + +570. Forgot outer_tag in scan_declared variable (T. Dahlheimer, June 2004) +@x 1011 +done: if eq_type(x)<>tag_token then clear_symbol(x,false); +@y +done: if eq_type(x) mod outer_tag<>tag_token then clear_symbol(x,false); +@z + +571. Apparent bug if init_gf called at incredibly unlikely time (T. Dahlheimer, +June 2004); not REALLY a bug, because str_ptr cannot equal max_strings here +(because this was checked by end_name, and area_delimiter=0 there because +cur_area="" in the output file name); but anyway I'll make a patch to be clean +@x 1163 +str_start[str_ptr+1]:=pool_ptr; gf_string(0,str_ptr); +@y +gf_string(0,make_string); decr(str_ptr); +@z + +572. Memory leak in make_ellipse on symmetric pens that don't have +a point on the x-axis (Eberhard Mattes, 03 June 2008) +@x module 536 +done1: link(p):=s; beta:=-y_coord(h); +@y +done1: if (link(p)<>null) then free_node(link(p),knot_node_size); +link(p):=s; beta:=-y_coord(h); +@z + +573. Don't restrict the length of the banner line, leave it system-dependent code +(Udo Wermuth, 02 April 2017) +@x module 61 +incorrect, but the discrepancy is not serious since we assume that the banner +and base identifier together will occupy at most |max_print_line| +character positions. +@y +incorrect, but the discrepancy is not serious since we assume that this +part of the program is system dependent. +@^system dependencies@> +@z + +574. Defeat interactions during batch mode (Xiaosa Zhang, 27 June 2020) +@x module 78 +@ @<Get user's advice...@>= +loop@+begin continue: clear_for_error_prompt; prompt_input("? "); +@y +@ @<Get user's advice...@>= +loop@+begin continue: if interaction<>error_stop_mode then return; + clear_for_error_prompt; prompt_input("? "); +@z + +575. Don't exit to editor if no input file is at the bottom line +(Xiaosa Zhang, 03 July 2020) +@x module 79 +"E": if file_ptr>0 then +@y +"E": if file_ptr>0 then if input_stack[file_ptr].name_field>=256 then +@z +@x module 80 +if file_ptr>0 then print("E to edit your file,"); +@y +if file_ptr>0 then if input_stack[file_ptr].name_field>=256 then + print("E to edit your file,"); +@z + +576. Keep date and time in system variables, use them in opening banner +(Udo Wermuth, 11 December 2020) +@x module 194 +Since standard \PASCAL\ cannot provide such information, something special +is needed. The program here simply specifies July 4, 1776, at noon; but +users probably want a better approximation to the truth. + +Note that the values are |scaled| integers. Hence \MF\ can no longer +be used after the year 32767. + +@p procedure fix_date_and_time; +begin internal[time]:=12*60*unity; {minutes since midnight} +internal[day]:=4*unity; {fourth day of the month} +internal[month]:=7*unity; {seventh month of the year} +internal[year]:=1776*unity; {Anno Domini} +end; +@y +Since standard \PASCAL\ cannot provide such information, something special +is needed. The program here simply assumes that suitable values appear in +the global variables \\{sys\_time}, \\{sys\_day}, \\{sys\_month}, and +\\{sys\_year} (which are initialized to noon on 4 July 1776, +in case the implementor is careless). + +Note that the values are |scaled| integers. Hence \MF\ can no longer +be used after the year 32767. + +@p procedure fix_date_and_time; +begin sys_time:=12*60; +sys_day:=4; sys_month:=7; sys_year:=1776; {self-evident truths} +internal[time]:=sys_time*unity; {minutes since midnight} +internal[day]:=sys_day*unity; {day of the month} +internal[month]:=sys_month*unity; {month of the year} +internal[year]:=sys_year*unity; {Anno Domini} +end; +@z +@x module 196 +@ Of course we had better declare another global variable, if the previous +routines are going to work. + +@<Glob...@>= +@!old_setting:0..max_selector; +@y +@ Of course we had better declare a few more global variables, if the previous +routines are going to work. + +@<Glob...@>= +@!old_setting:0..max_selector; +@!sys_time,@!sys_day,@!sys_month,@!sys_year:integer; + {date and time supplied by external system} +@z +@x module 790 +print_int(round_unscaled(internal[day])); print_char(" "); +months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +m:=round_unscaled(internal[month]); +for k:=3*m-2 to 3*m do wlog(months[k]); +print_char(" "); print_int(round_unscaled(internal[year])); print_char(" "); +m:=round_unscaled(internal[time]); +print_dd(m div 60); print_char(":"); print_dd(m mod 60); +@y +print_int(sys_day); print_char(" "); +months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +for k:=3*sys_month-2 to 3*sys_month do wlog(months[k]); +print_char(" "); print_int(sys_year); print_char(" "); +print_dd(sys_time div 60); print_char(":"); print_dd(sys_time mod 60); +@z +@x module 1211 +fix_date_and_time; init_randoms((internal[time] div unity)+internal[day]);@/ +@y +fix_date_and_time; init_randoms(sys_time+sys_day*unity);@/ +@z + +------------- +999. The absolutely final change (to be made after my death) +@x module 2 +@d banner=='This is METAFONT, Version 2.71828182' {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-dist/doc/generic/knuth-errata/tex82.bug b/Master/texmf-dist/doc/generic/knuth-errata/tex82.bug new file mode 100644 index 00000000000..12de105bae8 --- /dev/null +++ b/Master/texmf-dist/doc/generic/knuth-errata/tex82.bug @@ -0,0 +1,9279 @@ +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 one 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. Error recovery hindered by missing goto statement (reported by +David Fuchs, September 2007) + +@x module 395 +incr(align_state); long_state:=call; cur_tok:=par_token; ins_error; +@y +incr(align_state); long_state:=call; cur_tok:=par_token; ins_error; +goto continue; +@z + +421. Slight improvement to inner loop speed also eliminates a case +of "dirty Pascal" + +@x module 1035 + begin if character(tail)=qi(hyphen_char[main_f]) then if link(cur_q)>null then +@y + begin if link(cur_q)>null then + if character(tail)=qi(hyphen_char[main_f]) then ins_disc:=true; +@z + +422. Amendment to bugfix 414 (reported by David Fuchs, September 2007) + +@x module 1335 + store_fmt_file; return;@+tini@/ +@y + if last_glue<>max_halfword then delete_glue_ref(last_glue); + store_fmt_file; return;@+tini@/ +@z + +423. Remove leaking glue reference after error (DRF, September 2007) + +@x module 1236 + help2("I can't carry out that multiplication or division,")@/ + ("since the result is out of range."); +@y + help2("I can't carry out that multiplication or division,")@/ + ("since the result is out of range."); + if p>=glue_val then delete_glue_ref(cur_val); +@z + +424. Leaders with muglue is henceforth disallowed (indeed, David Fuchs +observed that it has never worked, except in 180pt fonts!) + +@x module 1078 +if ((cur_cmd=hskip)and(abs(mode)<>vmode))or@| + ((cur_cmd=vskip)and(abs(mode)=vmode))or@| + ((cur_cmd=mskip)and(abs(mode)=mmode)) then +@y +if ((cur_cmd=hskip)and(abs(mode)<>vmode))or@| + ((cur_cmd=vskip)and(abs(mode)=vmode)) then +@z + +425. An optimization suggested by Fuchs that I couldn't resist, because +it improves the inner loop whenever the last letter of a word +has a lig/kern program. Also another twiddle for the inner loop. + +@x module 1039 +if char_tag(main_i)<>lig_tag then goto main_loop_wrapup; +@y +if char_tag(main_i)<>lig_tag then goto main_loop_wrapup; +if cur_r=non_char then goto main_loop_wrapup; +@z +@x module 1036 +tail_append(lig_stack) {|main_loop_lookahead| is next} +@y +link(tail):=lig_stack; tail:=lig_stack {|main_loop_lookahead| is next} +@z + +426. For robustness, enforce a restriction checked by TFtoPL (suggested +by DRF) + +@x module 365 +if lf<>6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np then abort; +@y +if lf<>6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+nk+ne+np then abort; +if (nw=0)or(nh=0)or(nd=0)or(ni=0) then abort; +@z + +427. Tell more precisely the effective size of 1:1 insertions (DEK, 27 Feb 08) + +@x module 986 + t:=x_over_n(height(r),1000)*count(t); print_scaled(t); +@y + if count(t)=1000 then t:=height(r) + else t:=x_over_n(height(r),1000)*count(t); + print_scaled(t); +@z + +428. \csname\endcsname should be followed by space in print_cs, just as all +other multiletter control sequences are (found by Oleg Bulatov, 14 Sep 2008) + +@x module 262 + begin print_esc("csname"); print_esc("endcsname"); +@y + begin print_esc("csname"); print_esc("endcsname"); print_char(" "); +@z + +429. Don't echo error message to terminal when tracing paragraphs +(Udo Wermuth, 15 January 2017) +@x module 826 + begin no_shrink_error_yet:=false; +@y + begin no_shrink_error_yet:=false; + @!stat if tracing_paragraphs>0 then end_diagnostic(true);@+tats@; +@z +@x + error; +@y + error; + @!stat if tracing_paragraphs>0 then begin_diagnostic;@+tats@; +@z + +430. Defeat interactions during batch mode (Xiaosa Zhang, 27 June 2020) +@x module 83 +@ @<Get user's advice...@>= +loop@+begin continue: clear_for_error_prompt; prompt_input("? "); +@y +@ @<Get user's advice...@>= +loop@+begin continue: if interaction<>error_stop_mode then return; + clear_for_error_prompt; prompt_input("? "); +@z + +431. Don't exit to editor if no input file is at the bottom line +(Xiaosa Zhang, 03 July 2020) +@x module 84 +"E": if base_ptr>0 then +@y +"E": if base_ptr>0 then if input_stack[base_ptr].name_field>=256 then +@z +@x module 85 +if base_ptr>0 then print("E to edit your file,"); +@y +if base_ptr>0 then if input_stack[base_ptr].name_field>=256 then + print("E to edit your file,"); +@z + +432. Keep date and time in system variables, use them in opening banner +(Udo Wermuth, 11 December 2020) +@x module 241 +Since standard \PASCAL\ cannot provide such information, something special +is needed. The program here simply specifies July 4, 1776, at noon; but +users probably want a better approximation to the truth. + +@p procedure fix_date_and_time; +begin time:=12*60; {minutes since midnight} +day:=4; {fourth day of the month} +month:=7; {seventh month of the year} +year:=1776; {Anno Domini} +@y +Since standard \PASCAL\ cannot provide such information, something special +is needed. The program here simply assumes that suitable values appear in +the global variables \\{sys\_time}, \\{sys\_day}, \\{sys\_month}, and +\\{sys\_year} (which are initialized to noon on 4 July 1776, +in case the implementor is careless). + +@p procedure fix_date_and_time; +begin sys_time:=12*60; +sys_day:=4; sys_month:=7; sys_year:=1776; {self-evident truths} +time:=sys_time; {minutes since midnight} +day:=sys_day; {day of the month} +month:=sys_month; {month of the year} +year:=sys_year; {Anno Domini} +@z +@x module 246 +@ Of course we had better declare another global variable, if the previous +routines are going to work. + +@<Glob...@>= +@!old_setting:0..max_selector; +@y +@ Of course we had better declare a few more global variables, if the previous +routines are going to work. + +@<Glob...@>= +@!old_setting:0..max_selector; +@!sys_time,@!sys_day,@!sys_month,@!sys_year:integer; + {date and time supplied by external system} +@z +@x module 536 +print_int(day); print_char(" "); +months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +for k:=3*month-2 to 3*month do wlog(months[k]); +print_char(" "); print_int(year); print_char(" "); +print_two(time div 60); print_char(":"); print_two(time mod 60); +@y +print_int(sys_day); print_char(" "); +months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +for k:=3*sys_month-2 to 3*sys_month do wlog(months[k]); +print_char(" "); print_int(sys_year); print_char(" "); +print_two(sys_time div 60); print_char(":"); print_two(sys_time mod 60); +@z + +433. After nine parameters, delete both # and the token that follows +(Bruno Le Floch, 22 October 2020) +@x module 473 +label found,done,done1,done2; +@y +label found,continue,done,done1,done2; +@z +@x module 474 +begin loop begin get_token; {set |cur_cmd|, |cur_chr|, |cur_tok|} +@y +begin loop begin continue: get_token; {set |cur_cmd|, |cur_chr|, |cur_tok|} +@z +@x module 476 + help1("I'm going to ignore the # sign you just used."); error; +@y + help2("I'm going to ignore the # sign you just used,")@/ + ("as well as the token that followed it."); error; goto continue; +@z + +434. Don't accept an implicit left brace after # in macro head +(Udo Wermuth, 20 May 2020) +@x module 476 +if cur_cmd=left_brace then +@y +if cur_tok<left_brace_limit then +@z + +435. Keep garbage out of the buffer if a |\read| end unexpectedly +(DRF, 17 February 2018) +@x module 486 + align_state:=1000000; error; +@y + align_state:=1000000; limit:=0; error; +@z + +436. Zero out nonexistent chars, to prevent rogue TFM files +(DRF, 06 October 2020) +@x module 722 + math_type(a):=empty; +@y + math_type(a):=empty; cur_i:=null_character; +@z + +437. Don't classify fraction noads as inner noads (DRF, 25 March 2019) +@x module 761 +fraction_noad: begin t:=inner_noad; s:=fraction_noad_size; + end; +@y +fraction_noad: s:=fraction_noad_size; +@z + +438. Properly identify tabskip glue when tracing repeated templates +(Igor Liferenko, 10 January 2020) +@x module 793 +link(p):=new_glue(glue_ptr(cur_loop)); +@y +link(p):=new_glue(glue_ptr(cur_loop)); +subtype(link(p)):=tab_skip_code+1; +@z + +439. Use the correct range for local variable hn (DRF, 31 October 2020) +@x module 892 +@!hn:small_number; {the number of positions occupied in |hc|} +@y +@!hn:0..64; {the number of positions occupied in |hc|; + not always a |small_number|} +@z + +440. Normalize newlinechar when printing the final stats +(Udo Wermuth, 29 November 2020) +@x module 1333 +begin @<Finish the extensions@>; +@y +begin @<Finish the extensions@>; new_line_char:=-1; +@z +@x module 1335 +begin c:=cur_chr; +@y +begin c:=cur_chr; if c<>1 then new_line_char:=-1; +@z + +----------- +999. The absolutely final change (to be made after my death) +@x module 2 +@d banner=='This is TeX, Version 3.141592653' {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/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check index 2ca7d79fd45..5ec3946c43f 100755 --- a/Master/tlpkg/bin/tlpkg-ctan-check +++ b/Master/tlpkg/bin/tlpkg-ctan-check @@ -415,7 +415,7 @@ my @TLP_working = qw( kblocks kdgdocs kerkis kerntest ketcindy keycommand keyfloat keyindex keyreader keystroke keyval2e keyvaltable kix kixfont - knitting knittingpattern knowledge knuth knuth-lib knuth-local + knitting knittingpattern knowledge knuth knuth-errata knuth-lib knuth-local koma-moderncvclassic koma-script koma-script-examples koma-script-sfs komacv komacv-rg kotex-oblivoir kotex-plain kotex-utf kotex-utils kpfonts kpfonts-otf ksfh_nat ksp-thesis @@ -433,7 +433,7 @@ my @TLP_working = qw( latex-git-log latex-graphics-companion latex-graphics-dev latex-make latex-mr latex-notes-zh-cn latex-papersize latex-refsheet - latex-tds latex-tools-dev latex-uni8 + latex-tools-dev latex-uni8 latex-veryshortguide latex-via-exemplos latex-web-companion latex2e-help-texinfo latex2e-help-texinfo-fr latex2e-help-texinfo-spanish latex2man latex2nemeth diff --git a/Master/tlpkg/bin/tlpkginfo b/Master/tlpkg/bin/tlpkginfo index 7ab4ba42658..15955427bf7 100755 --- a/Master/tlpkg/bin/tlpkginfo +++ b/Master/tlpkg/bin/tlpkginfo @@ -78,12 +78,6 @@ sub ctaninfo { hacm inriafonts imtekda mathdesign sdaps tufte-latex xassoccnt), ); - # special packages from latex-tds project; used by prepare() - $latex_tds_pkgs = "latex-tds"; -# $latex_tds_pkgs .= "|psnfss"; # amsmath|cyrillic|graphics|latex|tools on own - $latex_tds_pkgs .= "|knuth"; # other - $latex_tds_dir = "$CTAN/macros/latex/contrib/latex-tds"; - # the CJK material is split into several packages. $cjk_pkgs = "bin-(cjk|ttf)utils|dnp|(|garuda-|norasi-)c90"; @@ -432,9 +426,6 @@ sub prepare { } elsif ($pkg eq "latex") { $tds_path = "$CTAN/install/macros/latex/latex-base.tds.zip"; - # ...and except for files in latex-tds... - } elsif ($pkg =~ /^($latex_tds_pkgs)$/) { - $tds_path = "$latex_tds_dir/$pkg.tds.zip"; } my $tds_path_ok = -s $tds_path ? 1 : 0; diff --git a/Master/tlpkg/tlpsrc/collection-langenglish.tlpsrc b/Master/tlpkg/tlpsrc/collection-langenglish.tlpsrc index 62c29b88d83..55eb18ecabe 100644 --- a/Master/tlpkg/tlpsrc/collection-langenglish.tlpsrc +++ b/Master/tlpkg/tlpsrc/collection-langenglish.tlpsrc @@ -27,6 +27,7 @@ depend happy4th depend impatient depend intro-scientific depend knuth +depend knuth-errata depend l2tabu-english depend latex-brochure depend latex-course diff --git a/Master/tlpkg/tlpsrc/knuth-errata.tlpsrc b/Master/tlpkg/tlpsrc/knuth-errata.tlpsrc new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/Master/tlpkg/tlpsrc/knuth-errata.tlpsrc |