%%% MACKAY.TXH Date: Fri, 30 Oct 87 23:44:09 PST From: mackay@june.cs.washington.edu (Pierre MacKay) Subject: TeXhax Digest V87 #86 RE: FTPing Unix-TeX [ for text of message, see TeXhax8790 ] ========================TeX2.1 to TeX2.3 ========================== *** /src/tex/tex82/tex.web Sat Mar 7 12:38:15 1987 --- ../TEX.WEB/TEX.WEB Tue Sep 22 20:42:16 1987 *************** *** 5,10 **** --- 5,13 ---- % See Appendix H of the WEB manual for hints on how to install this program. % And see Appendix A of the TRIP manual for details about how to validate it. + % TeX is a trademark of the American Mathematical Society. + % METAFONT is a tradement of Addison-Wesley Publishing Company. + % Version 0 was released in September 1982 after it passed a variety of tests. % Version 1 was released in November 1983 after thorough testing. % Version 1.1 fixed ``disappearing font identifiers'' et alia (July 1984). *************** *** 14,19 **** --- 17,24 ---- % Version 1.5 fixed \the\toks after other expansion in \edefs (August 1985). % Version 2.0 (almost identical to 1.5) corresponds to "Volume B" (April 1986). % Version 2.1 corrects anomalies in discretionary breaks (January 1987). + % Version 2.2 corrects "(Please type...)" with null \endlinechar (April 1987). + % Version 2.3 avoids incomplete page in premature termination (August 1987). % A reward of $40.96 will be paid to the first finder of any remaining bug. % (This amount will double again in 1988.) *************** *** 36,41 **** --- 41,47 ---- \def\MF{{\logo META}\-{\logo FONT}} \def\<#1>{$\langle#1\rangle$} \def\section{\mathhexbox278} + \chardef\%=`\% \def\(#1){} % this is used to make section names sort themselves better \def\9#1{} % this is used for sort keys in the index via @@:sort key}{entry@@> *************** *** 153,159 **** known as `\TeX' [cf.~Stanford Computer Science report CS1027, November 1984]. ! @d banner=='This is TeX, Version 2.1' {printed when \TeX\ starts} @ Different \PASCAL s have slightly different conventions, and the present @!@:PASCAL H}{\ph@> --- 159,165 ---- known as `\TeX' [cf.~Stanford Computer Science report CS1027, November 1984]. ! @d banner=='This is TeX, Version 2.3' {printed when \TeX\ starts} @ Different \PASCAL s have slightly different conventions, and the present @!@:PASCAL H}{\ph@> *************** *** 766,773 **** $$\vbox{\halign{#\hfil\qquad&#\hfil\cr |reset(f,@t\\{name}@>,'/O')|&for input;\cr |rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ ! The `\\{name}' parameter, which is of type `\ignorespaces|packed ! array[@t\<\\{any}>@>] of text_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. --- 772,779 ---- $$\vbox{\halign{#\hfil\qquad&#\hfil\cr |reset(f,@t\\{name}@>,'/O')|&for input;\cr |rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ ! 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. *************** *** 860,866 **** @!max_buf_stack:0..buf_size; {largest index used in |buffer|} @ The |input_ln| function brings the next line of input from the specified ! field into available positions of the buffer array and returns the value |true|, unless the file has already been entirely read, in which case it returns |false| and sets |last:=first|. In general, the |ASCII_code| numbers that represent the next line of the file are input into --- 866,872 ---- @!max_buf_stack:0..buf_size; {largest index used in |buffer|} @ The |input_ln| function brings the next line of input from the specified ! file into available positions of the buffer array and returns the value |true|, unless the file has already been entirely read, in which case it returns |false| and sets |last:=first|. In general, the |ASCII_code| numbers that represent the next line of the file are input into *************** *** 1721,1730 **** before we get to |error| itself. It is possible for |error| to be called recursively if some error arises ! when |get_token| is being used to delete a token, or if some fatal error occurs while \TeX\ is trying to fix a non-fatal one. But such recursion @^recursion@> ! is never more than one level deep. @= procedure@?normalize_selector; forward;@t\2@>@/ --- 1727,1736 ---- before we get to |error| itself. It is possible for |error| to be called recursively if some error arises ! when |get_token| is being used to delete a token, and/or if some fatal error occurs while \TeX\ is trying to fix a non-fatal one. But such recursion @^recursion@> ! is never more than two levels deep. @= procedure@?normalize_selector; forward;@t\2@>@/ *************** *** 2661,2667 **** end; r:=q-s; if r>p+1 then @; ! if r=p then if ((rlink(p)<>rover) or (llink(p)<>rover)) then @; node_size(p):=q-p {reset the size in case it grew} --- 2667,2673 ---- end; r:=q-s; if r>p+1 then @; ! if r=p then if rlink(p)<>p then @; node_size(p):=q-p {reset the size in case it grew} *************** *** 2764,2775 **** @^oriental characters@>@^Chinese characters@>@^Japanese characters@> and styles of type. It is suggested that Chinese and Japanese fonts be handled by representing such characters in two consecutive |char_node| ! entries: The first of these would identify the font and the character ! dimensions, and it would also link to the second, where the full halfword ! |info| field would address the desired character. Such an extension of ! \TeX\ would not be difficult; further details are left to the reader. The saving feature about oriental characters is that most of them have ! the same box dimensions. In order to make sure that the |character| code fits in a quarterword, \TeX\ adds the quantity |min_quarterword| to the actual code. --- 2770,2784 ---- @^oriental characters@>@^Chinese characters@>@^Japanese characters@> and styles of type. It is suggested that Chinese and Japanese fonts be handled by representing such characters in two consecutive |char_node| ! entries: 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. In order to make sure that the |character| code fits in a quarterword, \TeX\ adds the quantity |min_quarterword| to the actual code. *************** *** 3197,3204 **** 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}} @d fil_glue==zero_glue+glue_spec_size {\.{0pt plus 1fil minus 0pt}} --- 3206,3212 ---- 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|. @d zero_glue==mem_bot {specification for \.{0pt plus 0pt minus 0pt}} @d fil_glue==zero_glue+glue_spec_size {\.{0pt plus 1fil minus 0pt}} *************** *** 3275,3281 **** @t\hskip1em@>@!was_free: packed array [mem_min..mem_max] of boolean; {previously free cells} @t\hskip1em@>@!was_mem_end,@!was_lo_max,@!was_hi_min: pointer; ! {previous |mem_end|, |lo_mem_max|,and |hi_mem_min|} @t\hskip1em@>@!panicking:boolean; {do we want to check memory constantly?} gubed --- 3283,3289 ---- @t\hskip1em@>@!was_free: packed array [mem_min..mem_max] of boolean; {previously free cells} @t\hskip1em@>@!was_mem_end,@!was_lo_max,@!was_hi_min: pointer; ! {previous |mem_end|, |lo_mem_max|, and |hi_mem_min|} @t\hskip1em@>@!panicking:boolean; {do we want to check memory constantly?} gubed *************** *** 3426,3432 **** @p procedure short_display(@!p:integer); {prints highlights of list |p|} var n:integer; {for replacement counts} ! begin while p>null do begin if is_char_node(p) then begin if p<=mem_end then begin if font(p)<>font_in_short_display then --- 3434,3440 ---- @p procedure short_display(@!p:integer); {prints highlights of list |p|} var n:integer; {for replacement counts} ! begin while p>mem_min do begin if is_char_node(p) then begin if p<=mem_end then begin if font(p)<>font_in_short_display then *************** *** 3562,3568 **** contains a scaled integer, if |p| is a pointer that has been clobbered or chosen at random. ! @p procedure show_node_list(@!p:pointer); {prints a node list symbolically} label exit; var n:integer; {the number of items already printed at this level} @!g:real; {a glue ratio, as a floating point number} --- 3570,3576 ---- contains a scaled integer, if |p| is a pointer that has been clobbered or chosen at random. ! @p procedure show_node_list(@!p:integer); {prints a node list symbolically} label exit; var n:integer; {the number of items already printed at this level} @!g:real; {a glue ratio, as a floating point number} *************** *** 3572,3578 **** return; end; n:=0; ! while p>null do begin print_ln; print_current_string; {display the nesting history} if p>mem_end then {pointer out of range} begin print("Bad link, display aborted."); return; --- 3580,3586 ---- return; end; n:=0; ! while p>mem_min do begin print_ln; print_current_string; {display the nesting history} if p>mem_end then {pointer out of range} begin print("Bad link, display aborted."); return; *************** *** 6389,6395 **** are declared to be \.{\\outer}. A variable called |scanner_status| tells \TeX\ whether or not to complain ! when a subfile ends. This variable has five possible values: \yskip\hang|normal|, means that a subfile can safely end here without incident. --- 6397,6403 ---- are declared to be \.{\\outer}. A variable called |scanner_status| tells \TeX\ whether or not to complain ! when a subfile ends. This variable has six possible values: \yskip\hang|normal|, means that a subfile can safely end here without incident. *************** *** 7311,7317 **** end; if selectornonstop_mode then ! begin if limit=start then {previous line was empty} print_nl("(Please type a command or say `\end')"); @.Please type...@> print_ln; first:=start; --- 7319,7326 ---- end; if selectornonstop_mode then ! begin if (end_line_char<0)or(end_line_char>127) then incr(limit); ! if limit=start then {previous line was empty} print_nl("(Please type a command or say `\end')"); @.Please type...@> print_ln; first:=start; *************** *** 9415,9421 **** end; @ When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then ! if \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if} condition has been evaluated, \.{\\relax} will be inserted. For example, a sequence of commands like `\.{\\ifvoid1\\else...\\fi}' would otherwise require something after the `\.1'. --- 9424,9430 ---- end; @ When we begin to process a new \.{\\if}, we set |if_limit:=if_code|; then ! if\/ \.{\\or} or \.{\\else} or \.{\\fi} occurs before the current \.{\\if} condition has been evaluated, \.{\\relax} will be inserted. For example, a sequence of commands like `\.{\\ifvoid1\\else...\\fi}' would otherwise require something after the `\.1'. *************** *** 10208,10217 **** last gives the ``face byte.'' The program that converts \.{DVI} files to Xerox printing format gets this information by looking at the \.{TFM} file, which it needs to read anyway because of other information that ! is not explicitly repeated in \.{DVI} format. Extensions of \TeX\ for ! oriental languages should be able to identify oriental fonts by means ! of this additional header information. ! @^oriental characters@>@^Chinese characters@>@^Japanese characters@> \yskip\hang|header[0]| is a 32-bit check sum that \TeX\ will copy into the \.{DVI} output file. Later on when the \.{DVI} file is printed, --- 10217,10223 ---- last gives the ``face byte.'' The program that converts \.{DVI} files to Xerox printing format gets this information by looking at the \.{TFM} file, which it needs to read anyway because of other information that ! is not explicitly repeated in \.{DVI} format. \yskip\hang|header[0]| is a 32-bit check sum that \TeX\ will copy into the \.{DVI} output file. Later on when the \.{DVI} file is printed, *************** *** 10594,10600 **** malformed; if there's no room for this font, say so and |goto done|; otherwise |incr(font_ptr)| and |goto done|@>; bad_tfm: @; ! done: b_close(tfm_file); read_font_info:=g; end; @ There are programs called \.{TFtoPL} and \.{PLtoTF} that convert --- 10600,10607 ---- malformed; if there's no room for this font, say so and |goto done|; otherwise |incr(font_ptr)| and |goto done|@>; bad_tfm: @; ! done: if file_opened then b_close(tfm_file); ! read_font_info:=g; end; @ There are programs called \.{TFtoPL} and \.{PLtoTF} that convert *************** *** 10875,10881 **** begin m:=cur_chr; scan_four_bit_int; f:=equiv(m+cur_val); end else begin print_err("Missing font identifier"); ! @.Undefined font code@> help2("I was looking for a control sequence whose")@/ ("current meaning has been defined by \font."); back_error; f:=null_font; --- 10882,10888 ---- begin m:=cur_chr; scan_four_bit_int; f:=equiv(m+cur_val); end else begin print_err("Missing font identifier"); ! @.Missing font identifier@> help2("I was looking for a control sequence whose")@/ ("current meaning has been defined by \font."); back_error; f:=null_font; *************** *** 11497,11503 **** @ @= total_pages:=0; max_v:=0; max_h:=0; max_push:=0; last_bop:=-1; ! doing_leaders:=false; dead_cycles:=0; @ The \.{DVI} bytes are output to a buffer instead of being written directly to the output file. This makes it possible to reduce the overhead of --- 11504,11510 ---- @ @= total_pages:=0; max_v:=0; max_h:=0; max_push:=0; last_bop:=-1; ! doing_leaders:=false; dead_cycles:=0; cur_s:=-1; @ The \.{DVI} bytes are output to a buffer instead of being written directly to the output file. This makes it possible to reduce the overhead of *************** *** 11921,11931 **** @!dvi_h,@!dvi_v:scaled; {a \.{DVI} reader program thinks we are here} @!cur_h,@!cur_v:scaled; {\TeX\ thinks we are here} @!dvi_f:internal_font_number; {the current font} ! @!cur_s:integer; {current depth of output box nesting} @ @= dvi_h:=0; dvi_v:=0; cur_h:=h_offset; dvi_f:=null_font; ! cur_s:=-1; ensure_dvi_open; if total_pages=0 then begin dvi_out(pre); dvi_out(id_byte); {output the preamble} @^preamble of \.{DVI} file@> --- 11928,11938 ---- @!dvi_h,@!dvi_v:scaled; {a \.{DVI} reader program thinks we are here} @!cur_h,@!cur_v:scaled; {\TeX\ thinks we are here} @!dvi_f:internal_font_number; {the current font} ! @!cur_s:integer; {current depth of output box nesting, initially $-1$} @ @= dvi_h:=0; dvi_v:=0; cur_h:=h_offset; dvi_f:=null_font; ! ensure_dvi_open; if total_pages=0 then begin dvi_out(pre); dvi_out(id_byte); {output the preamble} @^preamble of \.{DVI} file@> *************** *** 12003,12011 **** begin synch_h; synch_v; repeat f:=font(p); c:=character(p); if f<>dvi_f then @; ! if cdvi_f then @; ! if c>=qi(128) then dvi_out(set1); ! dvi_out(qo(c));@/ cur_h:=cur_h+char_width(f)(char_info(f)(c)); p:=link(p); until not is_char_node(p); *************** *** 12108,12114 **** results for the |div| operation when |cur_h| is less than |left_edge|. 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 case of |x_leaders| (expanded leaders) we increase |cur_h| by $1/(q+1)$ of this excess space, where $q$ is the number of times the leader box will be replicated. Slight inaccuracies in the division might --- 12114,12120 ---- results for the |div| operation when |cur_h| is less than |left_edge|. 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 |cur_h| by $1/(q+1)$ of this excess space, where $q$ is the number of times the leader box will be replicated. Slight inaccuracies in the division might *************** *** 12345,12351 **** dvi_four(last_bop); last_bop:=page_loc; cur_v:=height(p)+v_offset; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; ! dvi_out(eop); incr(total_pages); done: @ Sometimes the user will generate a huge page because other error messages --- 12351,12357 ---- dvi_four(last_bop); last_bop:=page_loc; cur_v:=height(p)+v_offset; temp_ptr:=p; if type(p)=vlist_node then vlist_out@+else hlist_out; ! dvi_out(eop); incr(total_pages); cur_s:=-1; done: @ Sometimes the user will generate a huge page because other error messages *************** *** 12379,12384 **** --- 12385,12396 ---- An integer variable |k| will be declared for use by this routine. @= + 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.") @.No pages of output@> else begin dvi_out(post); {beginning of the postamble} *************** *** 13195,13203 **** subsidiary to the |nucleus| field of some noad; the dot is replaced by `\.[' or `\.(' or `\./' or `\.\\' if |p| is descended from the |subscr| or |supscr| or |denominator| or |numerator| fields of noads. For example, ! the current string would be `\.{.(.[/}' if |p| points to the |ord_noad| for ! |x| in the (ridiculous) formula `\.{\$\\sqrt\{a\^\{\{b\_\{c\\over x+y\} ! \}\}\}\$}'. @= style_node:print_style(subtype(p)); --- 13207,13215 ---- subsidiary to the |nucleus| field of some noad; the dot is replaced by `\.[' or `\.(' or `\./' or `\.\\' if |p| is descended from the |subscr| or |supscr| or |denominator| or |numerator| fields of noads. For example, ! the current string would be `\.{.\^.\_/}' if |p| points to the |ord_noad| for ! |x| in the (ridiculous) formula ! `\.{\$\\sqrt\{a\^\{\\mathinner\{b\_\{c\\over x+y\}\}\}\}\$}'. @= style_node:print_style(subtype(p)); *************** *** 13645,13652 **** @ The next subroutine is much simpler; it is used for numerators and denominators of fractions as well as for displayed operators and ! their limits above and below. It takes a given hlist box |b| and ! changes it so that the new box is centered in a box of width |w|. The centering is done by putting \.{\\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 --- 13657,13664 ---- @ The next subroutine is much simpler; it is used for numerators and denominators of fractions as well as for displayed operators and ! their limits above and below. It takes a given box~|b| and ! changes it so that the new box is centered in a box of width~|w|. The centering is done by putting \.{\\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 *************** *** 15702,15708 **** @= @!passive:pointer; {most recent node on passive list} @!printed_node:pointer; {most recent node that has been printed} ! @!pass_number:pointer; {the number of passive nodes allocated on this pass} @ The active list also contains ``delta'' nodes that help the algorithm compute the badness of individual lines. Such nodes appear only between two --- 15714,15720 ---- @= @!passive:pointer; {most recent node on passive list} @!printed_node:pointer; {most recent node that has been printed} ! @!pass_number:halfword; {the number of passive nodes allocated on this pass} @ The active list also contains ``delta'' nodes that help the algorithm compute the badness of individual lines. Such nodes appear only between two *************** *** 17148,17154 **** \.{abcdef} is a word in a font for which the only ligatures are \.{b\!c}, \.{c\!d}, \.{d\!e}, and \.{e\!f}. If this word is to permit hyphenation between \.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 insertion of a hyphen might cause effects to ripple arbitrarily far into the rest of the word. A further complication arises if additional hyphens appear together with such rippling, e.g., if the word in the --- 17160,17166 ---- \.{abcdef} is a word in a font for which the only ligatures are \.{b\!c}, \.{c\!d}, \.{d\!e}, and \.{e\!f}. If this word is to permit hyphenation between \.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 insertion of a hyphen might cause effects to ripple arbitrarily far into the rest of the word. A further complication arises if additional hyphens appear together with such rippling, e.g., if the word in the *************** *** 17351,17357 **** When a word |hc[1..hn]| has been set up to contain a candidate for 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. @^Liang, Franklin Mark@> Let's consider Liang's method first, since it is much more interesting than the --- 17363,17369 ---- When a word |hc[1..hn]| has been set up to contain a candidate for 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. @^Liang, Franklin Mark@> Let's consider Liang's method first, since it is much more interesting than the *************** *** 17874,17880 **** end; @ By making sure that |trie_max| is at least |h+128|, we can be sure that ! |trie_max>z|, since |h=z+c|. It follows that location |trie_max| will never be occupied in |trie|, and we will have |trie_max>=trie_link(z)|. @=h+128|@>= --- 17886,17892 ---- end; @ By making sure that |trie_max| is at least |h+128|, we can be sure that ! |trie_max>z|, since |h=z-c|. It follows that location |trie_max| will never be occupied in |trie|, and we will have |trie_max>=trie_link(z)|. @=h+128|@>= *************** *** 18640,18646 **** label exit,done,done1,continue,contribute,update_heights; var p:pointer; {the node being appended} @!q,@!r:pointer; {nodes being examined} ! @!b,c:integer; {badness and cost of current page} @!pi:integer; {penalty to be added to the badness} @!n:min_quarterword..255; {insertion box number} @!delta,@!h,@!w:scaled; {sizes used for insertion calculations} --- 18652,18658 ---- label exit,done,done1,continue,contribute,update_heights; var p:pointer; {the node being appended} @!q,@!r:pointer; {nodes being examined} ! @!b,@!c:integer; {badness and cost of current page} @!pi:integer; {penalty to be added to the badness} @!n:min_quarterword..255; {insertion box number} @!delta,@!h,@!w:scaled; {sizes used for insertion calculations} *************** *** 23606,23612 **** @d close_node=2 {|subtype| in whatsits that represent streams to \.{\\closeout}} @d special_node=3 {|subtype| in whatsits that represent \.{\\special} things} @d write_tokens(#) == link(#+1) {reference count of token list to write} ! @d write_stream(#) == info(#+1) {stream number (0 to 16)} @d open_name(#) == link(#+1) {string number of file name to open} @d open_area(#) == info(#+2) {string number of file area for |open_name|} @d open_ext(#) == link(#+2) {string number of file extension for |open_name|} --- 23618,23624 ---- @d close_node=2 {|subtype| in whatsits that represent streams to \.{\\closeout}} @d special_node=3 {|subtype| in whatsits that represent \.{\\special} things} @d write_tokens(#) == link(#+1) {reference count of token list to write} ! @d write_stream(#) == info(#+1) {stream number (0 to 17)} @d open_name(#) == link(#+1) {string number of file name to open} @d open_area(#) == info(#+2) {string number of file area for |open_name|} @d open_ext(#) == link(#+2) {string number of file extension for |open_name|} ==============================TeX2.3 to TeX2.5======================== *** TEX2.3.WEB Tue Sep 22 20:42:16 1987 --- TEX.WEB Wed Oct 14 07:03:19 1987 *************** *** 19,24 **** --- 19,26 ---- % Version 2.1 corrects anomalies in discretionary breaks (January 1987). % Version 2.2 corrects "(Please type...)" with null \endlinechar (April 1987). % Version 2.3 avoids incomplete page in premature termination (August 1987). + % Version 2.4 fixes \noaligned rules in indented displays (August 1987). + % Version 2.5 saves cur_order when expanding tokens (September 1987). % A reward of $40.96 will be paid to the first finder of any remaining bug. % (This amount will double again in 1988.) *************** *** 159,165 **** known as `\TeX' [cf.~Stanford Computer Science report CS1027, November 1984]. ! @d banner=='This is TeX, Version 2.3' {printed when \TeX\ starts} @ Different \PASCAL s have slightly different conventions, and the present @!@:PASCAL H}{\ph@> --- 161,167 ---- known as `\TeX' [cf.~Stanford Computer Science report CS1027, November 1984]. ! @d banner=='This is TeX, Version 2.5' {printed when \TeX\ starts} @ Different \PASCAL s have slightly different conventions, and the present @!@:PASCAL H}{\ph@> *************** *** 2517,2523 **** If the available-space list is empty, i.e., if |avail=null|, we try first to increase |mem_end|. If that cannot be done, i.e., if |mem_end=mem_max|, we try to decrease |hi_mem_min|. If that cannot be ! done, i.e., if |hi_mem_min=low_mem_max+1|, we have to quit. @p function get_avail : pointer; {single-word node allocation} var p:pointer; {the new node being got} --- 2519,2525 ---- If the available-space list is empty, i.e., if |avail=null|, we try first to increase |mem_end|. If that cannot be done, i.e., if |mem_end=mem_max|, we try to decrease |hi_mem_min|. If that cannot be ! done, i.e., if |hi_mem_min=lo_mem_max+1|, we have to quit. @p function get_avail : pointer; {single-word node allocation} var p:pointer; {the new node being got} *************** *** 7450,7465 **** @!p,@!q,@!r:pointer; {for list manipulation} @!j:0..buf_size; {index into |buffer|} @!cv_backup:integer; {to save the global quantity |cur_val|} ! @!cvl_backup,@!radix_backup:small_number; {to save |cur_val_level| and |radix|} @!backup_backup:pointer; {to save |link(backup_head)|} @!save_scanner_status:small_number; {temporary storage of |scanner_status|} begin cv_backup:=cur_val; cvl_backup:=cur_val_level; radix_backup:=radix; ! backup_backup:=link(backup_head); if cur_cmd else if cur_cmd; cur_val:=cv_backup; cur_val_level:=cvl_backup; radix:=radix_backup; ! link(backup_head):=backup_backup; end; @ @= --- 7452,7468 ---- @!p,@!q,@!r:pointer; {for list manipulation} @!j:0..buf_size; {index into |buffer|} @!cv_backup:integer; {to save the global quantity |cur_val|} ! @!cvl_backup,@!radix_backup,@!co_backup:small_number; ! {to save |cur_val_level|, etc.} @!backup_backup:pointer; {to save |link(backup_head)|} @!save_scanner_status:small_number; {temporary storage of |scanner_status|} begin cv_backup:=cur_val; cvl_backup:=cur_val_level; radix_backup:=radix; ! co_backup:=cur_order; backup_backup:=link(backup_head); if cur_cmd else if cur_cmd; cur_val:=cv_backup; cur_val_level:=cvl_backup; radix:=radix_backup; ! cur_order:=co_backup; link(backup_head):=backup_backup; end; @ @= *************** *** 15395,15401 **** pack_begin_line:=0 @ @= ! q:=link(head); while q<>null do begin if type(q)=unset_node then @ --- 15398,15404 ---- pack_begin_line:=0 @ @= ! q:=link(head); s:=head; while q<>null do begin if type(q)=unset_node then @ *************** *** 15402,15408 **** else if type(q)=rule_node then @; ! q:=link(q); end @ @= --- 15405,15411 ---- else if type(q)=rule_node then @; ! s:=q; q:=link(q); end @ @= *************** *** 15409,15414 **** --- 15412,15421 ---- begin if is_running(width(q)) then width(q):=width(p); if is_running(height(q)) then height(q):=height(p); 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; end @ The unset box |q| represents a row that contains one or more unset boxes, =============================end of diffs =========================== Pierre A. MacKay TUG Site Coordinator for Unix-flavored TeX -------