summaryrefslogtreecommitdiff
path: root/info/digests/texhax/txh/mackay.txh
diff options
context:
space:
mode:
Diffstat (limited to 'info/digests/texhax/txh/mackay.txh')
-rw-r--r--info/digests/texhax/txh/mackay.txh753
1 files changed, 753 insertions, 0 deletions
diff --git a/info/digests/texhax/txh/mackay.txh b/info/digests/texhax/txh/mackay.txh
new file mode 100644
index 0000000000..d66dd31fc1
--- /dev/null
+++ b/info/digests/texhax/txh/mackay.txh
@@ -0,0 +1,753 @@
+%%% 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.
+
+ @<Error handling...@>=
+ 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.
+
+ @<Error handling...@>=
+ procedure@?normalize_selector; forward;@t\2@>@/
+***************
+*** 2661,2667 ****
+ 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}
+
+--- 2667,2673 ----
+ 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)<>p then
+ @<Allocate entire node |p| and |goto found|@>;
+ 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 selector<log_only then open_log_file;
+ if interaction>nonstop_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 selector<log_only then open_log_file;
+ if interaction>nonstop_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: @<Report that the font won't be loaded@>;
+! 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: @<Report that the font won't be loaded@>;
+! 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 ****
+
+ @ @<Set init...@>=
+ 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 ----
+
+ @ @<Set init...@>=
+ 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}
+
+ @ @<Initialize variables as |ship_out| begins@>=
+ 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$}
+
+ @ @<Initialize variables as |ship_out| begins@>=
+ 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 @<Change font |dvi_f| to |f|@>;
+! if c<qi(128) then dvi_out(qo(c))
+! else begin dvi_out(set1); dvi_out(qo(c));
+! end;
+ cur_h:=cur_h+char_width(f)(char_info(f)(c));
+ p:=link(p);
+ until not is_char_node(p);
+--- 12010,12017 ----
+ begin synch_h; synch_v;
+ repeat f:=font(p); c:=character(p);
+ if f<>dvi_f then @<Change font |dvi_f| to |f|@>;
+! 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.
+
+ @<Finish the \.{DVI} file@>=
++ 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\}
+! \}\}\}\$}'.
+
+ @<Cases of |show_node_list| that arise...@>=
+ 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\}\}\}\}\$}'.
+
+ @<Cases of |show_node_list| that arise...@>=
+ 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 ****
+ @<Glob...@>=
+ @!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 ----
+ @<Glob...@>=
+ @!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)|.
+
+ @<Ensure that |trie_max>=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)|.
+
+ @<Ensure that |trie_max>=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<call then @<Expand a nonmacro@>
+ else if cur_cmd<end_template then macro_call
+ else @<Insert a |frozen_endv| token@>;
+ cur_val:=cv_backup; cur_val_level:=cvl_backup; radix:=radix_backup;
+! link(backup_head):=backup_backup;
+ end;
+
+ @ @<Expand a nonmacro@>=
+--- 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<call then @<Expand a nonmacro@>
+ else if cur_cmd<end_template then macro_call
+ else @<Insert a |frozen_endv| token@>;
+ cur_val:=cv_backup; cur_val_level:=cvl_backup; radix:=radix_backup;
+! cur_order:=co_backup; link(backup_head):=backup_backup;
+ end;
+
+ @ @<Expand a nonmacro@>=
+***************
+*** 15395,15401 ****
+ pack_begin_line:=0
+
+ @ @<Set the glue in all the unset...@>=
+! q:=link(head);
+ while q<>null do
+ begin if type(q)=unset_node then
+ @<Set the unset box |q| and the unset boxes in it@>
+--- 15398,15404 ----
+ pack_begin_line:=0
+
+ @ @<Set the glue in all the unset...@>=
+! q:=link(head); s:=head;
+ while q<>null do
+ begin if type(q)=unset_node then
+ @<Set the unset box |q| and the unset boxes in it@>
+***************
+*** 15402,15408 ****
+ else if type(q)=rule_node then
+ @<Make the running dimensions in rule |q| extend to the
+ boundaries of the alignment@>;
+! q:=link(q);
+ end
+
+ @ @<Make the running dimensions in rule |q| extend...@>=
+--- 15405,15411 ----
+ else if type(q)=rule_node then
+ @<Make the running dimensions in rule |q| extend to the
+ boundaries of the alignment@>;
+! s:=q; q:=link(q);
+ end
+
+ @ @<Make the running dimensions in rule |q| extend...@>=
+***************
+*** 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
+
+-------