summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/tex.web
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/tex.web')
-rw-r--r--Build/source/texk/web2c/tex.web222
1 files changed, 123 insertions, 99 deletions
diff --git a/Build/source/texk/web2c/tex.web b/Build/source/texk/web2c/tex.web
index 92b0cc53b9c..65d0279f827 100644
--- a/Build/source/texk/web2c/tex.web
+++ b/Build/source/texk/web2c/tex.web
@@ -1,6 +1,7 @@
% This program is copyright (C) 1982 by D. E. Knuth; all rights are reserved.
-% Copying of this file is authorized only if (1) you are D. E. Knuth, or if
-% (2) you make absolutely no changes to your copy. (The WEB system provides
+% Unlimited copying and redistribution of this file are permitted as long
+% as this file is not modified. Modifications are permitted, but only if
+% the resulting file is not named tex.web. (The WEB system provides
% for alterations via an auxiliary file; the master file should stay intact.)
% 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.
@@ -46,6 +47,7 @@
% Version 3.141592 fixed \xleaders, glueset, weird alignments (December 2002).
% Version 3.1415926 was a general cleanup with minor fixes (February 2008).
% Version 3.14159265 was similar (January 2014).
+% Version 3.141592653 was similar but more extensive (January 2021).
% A reward of $327.68 will be paid to the first finder of any remaining bug.
@@ -188,7 +190,7 @@ helping to determine whether a particular implementation deserves to be
known as `\TeX' [cf.~Stanford Computer Science report CS1027,
November 1984].
-@d banner=='This is TeX, Version 3.14159265' {printed when \TeX\ starts}
+@d banner=='This is TeX, Version 3.141592653' {printed when \TeX\ starts}
@ Different \PASCAL s have slightly different conventions, and the present
@!@:PASCAL H}{\ph@>
@@ -199,7 +201,7 @@ reader see how to make an appropriate interface for other systems
if necessary. (\ph\ is Charles Hedrick's modification of a compiler
@^Hedrick, Charles Locke@>
for the DECsystem-10 that was originally developed at the University of
-Hamburg; cf.\ {\sl SOFTWARE---Practice \AM\ Experience \bf6} (1976),
+Hamburg; cf.\ {\sl Software---Practice and Experience \bf6} (1976),
29--42. The \TeX\ program below is intended to be adaptable, without
extensive changes, to most other versions of \PASCAL, so it does not fully
use the admirable features of \ph. Indeed, a conscious effort has been
@@ -295,8 +297,8 @@ to people who wish to preserve the purity of English.
Similarly, there is some conditional code delimited by
`$|stat|\ldots|tats|$' that is intended for use when statistics are to be
kept about \TeX's memory usage. The |stat| $\ldots$ |tats| code also
-implements diagnostic information for \.{\\tracingparagraphs} and
-\.{\\tracingpages}.
+implements diagnostic information for \.{\\tracingparagraphs},
+\.{\\tracingpages}, and \.{\\tracingrestores}.
@^debugging@>
@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging}
@@ -1303,7 +1305,7 @@ example, be `|k in [0,@'10..@'12,@'14,@'15,@'33,@'177..@'377]|'.
If character |k| cannot be printed, and |k<@'200|, then character |k+@'100| or
|k-@'100| must be printable; moreover, ASCII codes |[@'41..@'46,
@'60..@'71, @'136, @'141..@'146, @'160..@'171]| must be printable.
-Thus, at least 81 printable characters are needed.
+Thus, at least 80 printable characters are needed.
@:TeXbook}{\sl The \TeX book@>
@^character set dependencies@>
@^system dependencies@>
@@ -1564,9 +1566,9 @@ end;
@ Here is the very first thing that \TeX\ prints: a headline that identifies
the version number and format package. The |term_offset| variable is temporarily
-incorrect, but the discrepancy is not serious since we assume that the banner
-and format identifier together will occupy at most |max_print_line|
-character positions.
+incorrect, but the discrepancy is not serious since we assume that this
+part of the program is system dependent.
+@^system dependencies@>
@<Initialize the output...@>=
wterm(banner);
@@ -1616,7 +1618,7 @@ by all \PASCAL\ compilers.
@<Basic print...@>=
procedure print_int(@!n:integer); {prints an integer in decimal form}
-var k:0..23; {index to current digit; we assume that $|n|<10^{23}$}
+var k:0..23; {index to current digit; we assume that $\vert n\vert<10^{23}$}
@!m:integer; {used to negate |n| in possibly dangerous cases}
begin k:=0;
if n<0 then
@@ -1764,7 +1766,8 @@ error messages are
\hang|term_only| (when |interaction>batch_mode| and |log_file| not yet open);
-\hang|log_only| (when |interaction=batch_mode| and |log_file| is open);
+\hang|log_only| (when |interaction=batch_mode| and |log_file| is open,
+ or when tracing paragraphs);
\hang|term_and_log| (when |interaction>batch_mode| and |log_file| is open).
@@ -1880,7 +1883,8 @@ var c:ASCII_code; {what the user types}
{used to save global variables when deleting tokens}
begin if history<error_message_issued then history:=error_message_issued;
print_char("."); show_context;
-if interaction=error_stop_mode then @<Get user's advice and |return|@>;
+if interaction=error_stop_mode then if selector<>log_only then
+ @<Get user's advice and |return|@>;
incr(error_count);
if error_count=100 then
begin print_nl("(That makes 100 errors; please try again.)");
@@ -1891,7 +1895,8 @@ if error_count=100 then
exit:end;
@ @<Get user's advice...@>=
-loop@+begin continue: clear_for_error_prompt; prompt_input("? ");
+loop@+begin continue: if interaction<>error_stop_mode then return;
+ clear_for_error_prompt; prompt_input("? ");
@.?\relax@>
if last=first then return;
c:=buffer[first];
@@ -1916,7 +1921,7 @@ case c of
"0","1","2","3","4","5","6","7","8","9": if deletions_allowed then
@<Delete \(c)|c-"0"| tokens and |goto continue|@>;
@t\4\4@>@;@+@!debug "D": begin debug_help; goto continue;@+end;@+gubed@/
-"E": if base_ptr>0 then
+"E": if base_ptr>0 then if input_stack[base_ptr].name_field>=256 then
begin print_nl("You want to edit file ");
@.You want to edit file x@>
slow_print(input_stack[base_ptr].name_field);
@@ -1937,7 +1942,8 @@ begin print("Type <return> to proceed, S to scroll future error messages,");@/
@.Type <return> to proceed...@>
print_nl("R to run without stopping, Q to run quietly,");@/
print_nl("I to insert something, ");
-if base_ptr>0 then print("E to edit your file,");
+if base_ptr>0 then if input_stack[base_ptr].name_field>=256 then
+ print("E to edit your file,");
if deletions_allowed then
print_nl("1 or ... or 9 to ignore the next 1 to 9 tokens of input,");
print_nl("H for help, X to quit.");
@@ -2129,7 +2135,7 @@ begin if OK_to_interrupt then
print_err("Interruption");
@.Interruption@>
help3("You rang?")@/
- ("Try to insert some instructions for me (e.g.,`I\showlists'),")@/
+ ("Try to insert an instruction for me (e.g., `I\showlists'),")@/
("unless you just want to quit by typing `X'.");
deletions_allowed:=false; error; deletions_allowed:=true;
interrupt:=0;
@@ -2917,8 +2923,8 @@ specifies the order of infinity to which glue setting applies (|normal|,
@ The |new_null_box| function returns a pointer to an |hlist_node| in
which all subfields have the values corresponding to `\.{\\hbox\{\}}'.
-The |subtype| field is set to |min_quarterword|, since that's the desired
-|span_count| value if this |hlist_node| is changed to an |unset_node|.
+(The |subtype| field is set to |min_quarterword|, for historic reasons
+that are no longer relevant.)
@p function new_null_box:pointer; {creates a new box node}
var p:pointer; {the new node}
@@ -4100,7 +4106,7 @@ expanded by `\.{\\the}'.
@d hskip=26 {horizontal glue ( \.{\\hskip}, \.{\\hfil}, etc.~)}
@d vskip=27 {vertical glue ( \.{\\vskip}, \.{\\vfil}, etc.~)}
@d mskip=28 {math glue ( \.{\\mskip} )}
-@d kern=29 {fixed space ( \.{\\kern})}
+@d kern=29 {fixed space ( \.{\\kern} )}
@d mkern=30 {math kern ( \.{\\mkern} )}
@d leader_ship=31 {use a box ( \.{\\shipout}, \.{\\leaders}, etc.~)}
@d halign=32 {horizontal table alignment ( \.{\\halign} )}
@@ -4239,7 +4245,7 @@ At each level of processing we are in one of six modes:
\hang|-mmode| stands for math formula mode (not displayed).
\yskip\noindent The mode is temporarily set to zero while processing \.{\\write}
-texts in the |ship_out| routine.
+texts.
Numeric values are assigned to |vmode|, |hmode|, and |mmode| so that
\TeX's ``big semantic switch'' can select the appropriate thing to
@@ -4432,7 +4438,7 @@ case abs(m) div (max_command+1) of
end;
end;
2: if a.int<>null then
- begin print("this will be denominator of:"); show_box(a.int);@+
+ begin print("this will begin denominator of:"); show_box(a.int);@+
end;
end {there are no other cases}
@@ -4954,7 +4960,7 @@ that will be defined later.
@d output_penalty_code=39 {penalty found at current page break}
@d max_dead_cycles_code=40 {bound on consecutive dead cycles of output}
@d hang_after_code=41 {hanging indentation changes after this many lines}
-@d floating_penalty_code=42 {penalty for insertions heldover after a split}
+@d floating_penalty_code=42 {penalty for insertions held over after a split}
@d global_defs_code=43 {override \.{\\global} specifications}
@d cur_fam_code=44 {current family}
@d escape_char_code=45 {escape character for token output}
@@ -5236,14 +5242,18 @@ del_code("."):=0; {this null delimiter is used in error recovery}
input and output, establishes the initial values of the date and time.
@^system dependencies@>
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.
+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 time:=12*60; {minutes since midnight}
-day:=4; {fourth day of the month}
-month:=7; {seventh month of the year}
-year:=1776; {Anno Domini}
+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}
end;
@ @<Show equivalent |n|, in region 5@>=
@@ -5279,11 +5289,13 @@ if blank_line then print_ln;
selector:=old_setting;
end;
-@ Of course we had better declare another global variable, if the previous
+@ 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}
@ The final region of |eqtb| contains the dimension parameters defined
here, and the 256 \.{\\dimen} registers.
@@ -5824,7 +5836,7 @@ should replace the corresponding entry in |xeq_level|.
\yskip\hangg 2) If |save_type(p)=restore_zero|, then |save_index(p)|
is a location in |eqtb| whose current value should be destroyed at the end
of the current group, when it should be
-replaced by the current value of |eqtb[undefined_control_sequence]|.
+replaced by the value of |eqtb[undefined_control_sequence]|.
\yskip\hangg 3) If |save_type(p)=insert_token|, then |save_index(p)|
is a token that should be inserted into \TeX's input when the current
@@ -6189,8 +6201,8 @@ when |m=out_param|, it means that \TeX\ should insert parameter
number |c| into the text at this point.
The enclosing \.{\char'173} and \.{\char'175} characters of a macro
-definition are omitted, but the final right brace of an output routine
-is included at the end of its token list.
+definition are omitted, but an output routine
+will be enclosed in braces.
Here is an example macro definition that illustrates these conventions.
After \TeX\ processes the text
@@ -6654,7 +6666,7 @@ template is being scanned;
template is being scanned;
\hang|backed_up|, if the token list being scanned has been inserted as
-`to be read again'.
+`to be read again';
\hang|inserted|, if the token list being scanned has been inserted as
the text expansion of a \.{\\count} or similar variable;
@@ -7190,7 +7202,8 @@ end
@ The recovery procedure can't be fully understood without knowing more
about the \TeX\ routines that should be aborted, but we can sketch the
-ideas here: For a runaway definition we will insert a right brace; for a
+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 \.{\\cr} token and a right
brace; and for a runaway argument, we will set |long_state| to
|outer_call| and insert \.{\\par}.
@@ -7357,7 +7370,7 @@ if cur_cmd>=outer_call then check_outer_validity;
end
@ 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;
@@ -7367,7 +7380,7 @@ end
@<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;
+ 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;
@@ -7827,7 +7840,7 @@ done: if cur_cs=0 then cur_tok:=(cur_cmd*@'400)+cur_chr
else cur_tok:=cs_token_flag+cur_cs;
end;
-@ The |get_x_token| procedure is equivalent to two consecutive
+@ The |get_x_token| procedure is essentially equivalent to two consecutive
procedure calls: |get_next; x_token|.
@p procedure x_token; {|get_x_token| without the initial |get_next|}
@@ -8148,7 +8161,7 @@ end
strip off the enclosing braces. That's why |rbrace_ptr| was introduced.
@<Tidy up the parameter just scanned, and tuck it away@>=
-begin if (m=1)and(info(p)<right_brace_limit)and(p<>temp_head) then
+begin if (m=1)and(info(p)<right_brace_limit) then
begin link(rbrace_ptr):=null; free_avail(p);
p:=link(temp_head); pstack[n]:=link(p); free_avail(p);
end
@@ -9140,7 +9153,7 @@ The token list created by |str_toks| begins at |link(temp_head)| and ends
at the value |p| that is returned. (If |p=temp_head|, the list is empty.)
@p function str_toks(@!b:pool_pointer):pointer;
- {changes the string |str_pool[b..pool_ptr]| to a token list}
+ {converts |str_pool[b..pool_ptr-1]| to a token list}
var p:pointer; {tail of the token list}
@!q:pointer; {new node being added to the token list via |store_new_token|}
@!t:halfword; {token being appended}
@@ -9302,7 +9315,7 @@ address of the control sequence to display in ``runaway'' error
messages.
@p function scan_toks(@!macro_def,@!xpand:boolean):pointer;
-label found,done,done1,done2;
+label found,continue,done,done1,done2;
var t:halfword; {token representing the highest parameter number}
@!s:halfword; {saved token}
@!p:pointer; {tail of the token list being built}
@@ -9322,7 +9335,7 @@ scan_toks:=p;
end;
@ @<Scan and build the parameter part...@>=
-begin loop begin get_token; {set |cur_cmd|, |cur_chr|, |cur_tok|}
+begin loop begin continue: get_token; {set |cur_cmd|, |cur_chr|, |cur_tok|}
if cur_tok<right_brace_limit then goto done1;
if cur_cmd=mac_param then
@<If the next character is a parameter number, make |cur_tok|
@@ -9344,7 +9357,7 @@ end
@ @<If the next character is a parameter number...@>=
begin s:=match_token+cur_chr; get_token;
-if cur_cmd=left_brace then
+if cur_tok<left_brace_limit then
begin hash_brace:=cur_tok;
store_new_token(cur_tok); store_new_token(end_match_token);
goto done;
@@ -9352,7 +9365,8 @@ if cur_cmd=left_brace then
if t=zero_token+9 then
begin print_err("You already have nine parameters");
@.You already have nine...@>
- help1("I'm going to ignore the # sign you just used."); error;
+ help2("I'm going to ignore the # sign you just used,")@/
+ ("as well as the token that followed it."); error; goto continue;
end
else begin incr(t);
if cur_tok<>t then
@@ -9502,7 +9516,7 @@ begin if not input_ln(read_file[m],true) then
print_err("File ended within "); print_esc("read");
@.File ended within \\read@>
help1("This \read has unbalanced braces.");
- align_state:=1000000; error;
+ align_state:=1000000; limit:=0; error;
end;
end;
end
@@ -9638,7 +9652,7 @@ where skipping began, for use in error messages.
@!skip_line:integer; {skipping began here}
@ Here is a procedure that ignores text until coming to an \.{\\or},
-\.{\\else}, or \.{\\fi} at level zero of $\.{\\if}\ldots\.{\\fi}$
+\.{\\else}, or \.{\\fi} at the current level of $\.{\\if}\ldots\.{\\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).
@@ -10342,15 +10356,18 @@ end
@ @<Print the banner...@>=
begin wlog(banner);
slow_print(format_ident); print(" ");
-print_int(day); print_char(" ");
+print_int(sys_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);
+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);
end
@ Let's turn now to the procedure that is used to initiate file reading
when an `\.{\\input}' 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.
+@^system dependencies@>
@p procedure start_input; {\TeX\ will \.{\\input} something}
label done;
@@ -10375,7 +10392,7 @@ if term_offset+length(name)>max_print_line-2 then print_ln
else if (term_offset>0)or(file_offset>0) then print_char(" ");
print_char("("); incr(open_parens); slow_print(name); update_terminal;
state:=new_line;
-if name=str_ptr-1 then {we can conserve string pool space now}
+if name=str_ptr-1 then {conserve string pool space (but see note above)}
begin flush_string; name:=cur_name;
end;
@<Read the first line of the new file@>;
@@ -10589,11 +10606,11 @@ 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 |next_char| byte is the 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 left boundary character,
-beginning at location |256*op_byte+remainder|.
+there is a special ligature/kerning program for a boundary character at the
+left, 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
@@ -10725,7 +10742,7 @@ the font.
{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}
+ {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|}
@@ -10904,7 +10921,7 @@ var k:font_index; {index into |font_info|}
@!a,@!b,@!c,@!d:eight_bits; {byte variables}
@!qw:four_quarters;@!sw:scaled; {accumulators}
@!bch_label:integer; {left boundary start location, or infinity}
-@!bchar:0..256; {right boundary character, or 256}
+@!bchar:0..256; {boundary character, or 256}
@!z:scaled; {the design size or the ``at'' size}
@!alpha:integer;@!beta:1..16;
{auxiliary quantities used in fixed-point multiplication}
@@ -11472,13 +11489,13 @@ stack were empty at the time of a |pop| command.
The parameter is a signed number in two's complement notation, |-128<=b<128|;
if |b<0|, the reference point moves left.
-\yskip\hang|right2| 144 |b[2]|. Same as |right1|, except that |b| is a
+\yskip\hang|@!right2| 144 |b[2]|. Same as |right1|, except that |b| is a
two-byte quantity in the range |-32768<=b<32768|.
-\yskip\hang|right3| 145 |b[3]|. Same as |right1|, except that |b| is a
+\yskip\hang|@!right3| 145 |b[3]|. Same as |right1|, except that |b| is a
three-byte quantity in the range |@t$-2^{23}$@><=b<@t$2^{23}$@>|.
-\yskip\hang|right4| 146 |b[4]|. Same as |right1|, except that |b| is a
+\yskip\hang|@!right4| 146 |b[4]|. Same as |right1|, except that |b| is a
four-byte quantity in the range |@t$-2^{31}$@><=b<@t$2^{31}$@>|.
\yskip\hang|w0| 147. Set |h:=h+w|; i.e., move right |w| units. With luck,
@@ -12886,7 +12903,7 @@ also removes all occurrences of |ins_node|, |mark_node|, and |adjust_node|
items and appends the resulting material onto the list that ends at
location |adjust_tail|.
-@< Glob...@>=
+@<Glob...@>=
@!adjust_tail:pointer; {tail of adjustment list}
@ @<Set init...@>=adjust_tail:=null; last_badness:=0;
@@ -13408,8 +13425,8 @@ programming.
@d sub_mlist=3 {|math_type| when the attribute is a formula}
@d math_text_char=4 {|math_type| when italic correction is dubious}
-@ Each portion of a formula is classified as Ord, Op, Bin, Rel, Ope,
-Clo, Pun, or Inn, for purposes of spacing and line breaking. An
+@ Each portion of a formula is classified as Ord, Op, Bin, Rel, Open,
+Close, Punct, or Inner, for purposes of spacing and line breaking. An
|ord_noad|, |op_noad|, |bin_noad|, |rel_noad|, |open_noad|, |close_noad|,
|punct_noad|, or |inner_noad| is used to represent portions of the various
types. For example, an `\.=' sign in a formula leads to the creation of a
@@ -13431,10 +13448,10 @@ limits has been overridden for this operator.
@d op_noad=ord_noad+1 {|type| of a noad classified Op}
@d bin_noad=ord_noad+2 {|type| of a noad classified Bin}
@d rel_noad=ord_noad+3 {|type| of a noad classified Rel}
-@d open_noad=ord_noad+4 {|type| of a noad classified Ope}
-@d close_noad=ord_noad+5 {|type| of a noad classified Clo}
-@d punct_noad=ord_noad+6 {|type| of a noad classified Pun}
-@d inner_noad=ord_noad+7 {|type| of a noad classified Inn}
+@d open_noad=ord_noad+4 {|type| of a noad classified Open}
+@d close_noad=ord_noad+5 {|type| of a noad classified Close}
+@d punct_noad=ord_noad+6 {|type| of a noad classified Punct}
+@d inner_noad=ord_noad+7 {|type| of a noad classified Inner}
@d limits=1 {|subtype| of |op_noad| whose scripts are to be above, below}
@d no_limits=2 {|subtype| of |op_noad| whose scripts are to be normal}
@@ -14209,7 +14226,7 @@ else begin if (qo(cur_c)>=font_bc[cur_f])and(qo(cur_c)<=font_ec[cur_f]) then
else cur_i:=null_character;
if not(char_exists(cur_i)) then
begin char_warning(cur_f,qo(cur_c));
- math_type(a):=empty;
+ math_type(a):=empty; cur_i:=null_character;
end;
end;
end;
@@ -14596,7 +14613,7 @@ else begin shift_down:=denom2(cur_size);
@ The numerator and denominator must be separated by a certain minimum
clearance, called |clr| in the following program. The difference between
-|clr| and the actual clearance is |2delta|.
+|clr| and the actual clearance is twice |delta|.
@<Adjust \(s)|shift_up| and |shift_down| for the case of no fraction line@>=
begin if cur_style<text_style then clr:=7*default_rule_thickness
@@ -14979,8 +14996,7 @@ rel_noad: begin t:=rel_noad; pen:=rel_penalty;
ord_noad,vcenter_noad,over_noad,under_noad: do_nothing;
radical_noad: s:=radical_noad_size;
accent_noad: s:=accent_noad_size;
-fraction_noad: begin t:=inner_noad; s:=fraction_noad_size;
- end;
+fraction_noad: s:=fraction_noad_size;
left_noad,right_noad: t:=make_left_right(q,style,max_d,max_h);
style_node: @<Change the current style and |goto delete_q|@>;
whatsit_node,penalty_node,rule_node,disc_node,adjust_node,ins_node,mark_node,
@@ -15020,7 +15036,7 @@ begin cur_style:=subtype(q); s:=style_node_size;
goto delete_q;
end
-@ The inter-element spacing in math formulas depends on a $8\times8$ table that
+@ The inter-element spacing in math formulas depends on an $8\times8$ table that
\TeX\ preloads as a 64-digit string. The elements of this string have the
following significance:
$$\vbox{\halign{#\hfil\cr
@@ -15400,6 +15416,7 @@ text(frozen_cr):="cr"; eqtb[frozen_cr]:=eqtb[cur_val];@/
primitive("crcr",car_ret,cr_cr_code);
@!@:cr_cr_}{\.{\\crcr} primitive@>
text(frozen_end_template):="endtemplate"; text(frozen_endv):="endtemplate";
+@.endtemplate@>
eq_type(frozen_endv):=endv; equiv(frozen_endv):=null_list;
eq_level(frozen_endv):=level_one;@/
eqtb[frozen_end_template]:=eqtb[frozen_endv];
@@ -15627,6 +15644,7 @@ info(p):=end_span; width(p):=null_flag; cur_loop:=link(cur_loop);
@<Copy the templates from node |cur_loop| into node |p|@>;
cur_loop:=link(cur_loop);
link(p):=new_glue(glue_ptr(cur_loop));
+subtype(link(p)):=tab_skip_code+1;
end
@ @<Copy the templates from node |cur_loop| into node |p|@>=
@@ -15992,8 +16010,8 @@ The method used here is based on an approach devised by Michael F. Plass and
@^Plass, Michael Frederick@>
@^Knuth, Donald Ervin@>
the author in 1977, subsequently generalized and improved by the same two
-people in 1980. A detailed discussion appears in {\sl SOFTWARE---Practice
-\AM\ Experience \bf11} (1981), 1119--1184, where it is shown that the
+people in 1980. A detailed discussion appears in {\sl Software---Practice
+and Experience \bf11} (1981), 1119--1184, where it is shown that the
line-breaking problem can be regarded as a special case of the problem of
computing the shortest path in an acyclic network. The cited paper includes
numerous examples and describes the history of line breaking as it has been
@@ -17291,7 +17309,7 @@ loop@+ begin q:=link(r);
if is_char_node(q) then goto done1;
if non_discardable(q) then goto done1;
if type(q)=kern_node then if subtype(q)<>explicit then goto done1;
- r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node| or |penalty_node|}
+ r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node|, or |penalty_node|}
end;
done1: if r<>temp_head then
begin link(r):=null; flush_node_list(link(temp_head));
@@ -17502,7 +17520,8 @@ nodes $p_{a-1}$ and~$p_b$ in the description above are placed into variables
@<Glob...@>=
@!hc:array[0..65] of 0..256; {word to be hyphenated}
-@!hn:small_number; {the number of positions occupied in |hc|}
+@!hn:0..64; {the number of positions occupied in |hc|;
+ not always a |small_number|}
@!ha,@!hb:pointer; {nodes |ha..hb| should be replaced by the hyphenated result}
@!hf:internal_font_number; {font number of the letters in |hc|}
@!hu:array[0..63] of 0..256; {like |hc|, before conversion to lowercase}
@@ -17644,7 +17663,7 @@ forgetting what |ha| and |hb|, etc., are all about.
@ @<Local variables for hyphenation@>=
@!i,@!j,@!l:0..65; {indices into |hc| or |hu|}
@!q,@!r,@!s:pointer; {temporary registers for list manipulation}
-@!bchar:halfword; {right boundary character of hyphenated word, or |non_char|}
+@!bchar:halfword; {boundary character of hyphenated word, or |non_char|}
@ \TeX\ will never insert a hyphen that has fewer than
\.{\\lefthyphenmin} letters before it or fewer than
@@ -17766,7 +17785,7 @@ affect the translation of the beginning of the word.
function reconstitute(@!j,@!n:small_number;@!bchar,@!hchar:halfword):
small_number;
label continue,done;
-var @!p:pointer; {temporary register for list manipulation}
+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}
@@ -18378,7 +18397,7 @@ The hash table is called |trie_op_hash|, and the number of entries it contains
is |trie_op_ptr|.
@<Glob...@>=
-@!init@! trie_op_hash:array[-trie_op_size..trie_op_size] of 0..trie_op_size;
+@!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}
@@ -18556,7 +18575,7 @@ entries.
@d trie_back(#)==trie[#].lh {backward links in |trie| holes}
@<Glob...@>=
-@!init@!trie_taken:packed array[1..trie_size] of boolean;
+@!init @!trie_taken:packed array[1..trie_size] of boolean;
{does a family start here?}
@t\hskip10pt@>@!trie_min:array[ASCII_code] of trie_pointer;
{the first possible slot for each character}
@@ -19213,7 +19232,8 @@ all split and floating insertions.
@!last_glue:pointer; {used to implement \.{\\lastskip}}
@!last_penalty:integer; {used to implement \.{\\lastpenalty}}
@!last_kern:scaled; {used to implement \.{\\lastkern}}
-@!insert_penalties:integer; {sum of the penalties for held-over insertions}
+@!insert_penalties:integer; {sum of the penalties for insertions
+ that were held over}
@ @<Put each...@>=
primitive("pagegoal",set_page_dimen,0);
@@ -19914,7 +19934,7 @@ end
in internal vertical mode, and \TeX\ will do the following:
@<Resume the page builder after an output routine has come to an end@>=
-begin if (loc<>null) or
+begin if (loc<>null) or
((token_type<>output_text)and(token_type<>backed_up)) then
@<Recover from an unbalanced output routine@>;
end_token_list; {conserve stack space in case more outputs are triggered}
@@ -20077,7 +20097,7 @@ Several additional global variables are needed.
@!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|}
+@!bchar:halfword; {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?}
@@ -20599,7 +20619,7 @@ end;
@ Many of the actions related to box-making are triggered by the appearance
of braces in the input. For example, when the user says `\.{\\hbox}
-\.{to} \.{100pt\{$\langle\,\hbox{hlist}\,\rangle$\}}' in vertical mode,
+\.{to} \.{100pt\{$\langle\,\hbox{\rm hlist}\,\rangle$\}}' in vertical mode,
the information about the box size (100pt, |exactly|) is put onto |save_stack|
with a level boundary word just above it, and |cur_group:=adjusted_hbox_group|;
\TeX\ enters restricted horizontal mode to process the hlist. The right
@@ -22785,6 +22805,7 @@ end;
@ @<Initialize table entries...@>=
text(frozen_protection):="inaccessible";
+@.inaccessible@>
@ Here's an example of the way many of the following routines operate.
(Unfortunately, they aren't all as simple as this.)
@@ -23618,7 +23639,7 @@ any_mode(xray): show_whatever;
@ @d show_code=0 { \.{\\show} }
@d show_box_code=1 { \.{\\showbox} }
@d show_the_code=2 { \.{\\showthe} }
-@d show_lists=3 { \.{\\showlists} }
+@d show_lists_code=3 { \.{\\showlists} }
@<Put each...@>=
primitive("show",xray,show_code);
@@ -23627,14 +23648,14 @@ primitive("showbox",xray,show_box_code);
@!@:show_box_}{\.{\\showbox} primitive@>
primitive("showthe",xray,show_the_code);
@!@:show_the_}{\.{\\showthe} primitive@>
-primitive("showlists",xray,show_lists);
-@!@:show_lists_}{\.{\\showlists} primitive@>
+primitive("showlists",xray,show_lists_code);
+@!@:show_lists_code_}{\.{\\showlists} primitive@>
@ @<Cases of |print_cmd_chr|...@>=
xray: case chr_code of
show_box_code:print_esc("showbox");
show_the_code:print_esc("showthe");
- show_lists:print_esc("showlists");
+ show_lists_code:print_esc("showlists");
othercases print_esc("show")
endcases;
@@ -23643,7 +23664,7 @@ 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;
+show_lists_code: 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|@>;
@@ -23723,8 +23744,8 @@ so that the inverse relation between them is clear.
The global variable |format_ident| is a string that is printed right
after the |banner| line when \TeX\ is ready to start. For \.{INITEX} this
-string says simply `\.{(INITEX)}'; for other versions of \TeX\ it says,
-for example, `\.{(preloaded format=plain 1982.11.19)}', showing the year,
+string says simply `\.{ (INITEX)}'; for other versions of \TeX\ it says,
+for example, `\.{ (preloaded format=plain 1982.11.19)}', showing the year,
month, and day that the format file was created. We have |format_ident=0|
before \TeX's tables are loaded.
@@ -23815,6 +23836,8 @@ macros to dump words of different types:
@ The inverse macros are slightly more complicated, since we need to check
the range of the values we are reading in. We say `|undump(a)(b)(x)|' to
read an integer value |x| that is supposed to be in the range |a<=x<=b|.
+System error messages should be suppressed when undumping.
+@^system dependencies@>
@d undump_wd(#)==begin get(fmt_file); #:=fmt_file^;@+end
@d undump_int(#)==begin get(fmt_file); #:=fmt_file^.int;@+end
@@ -24289,17 +24312,17 @@ cannot produce error messages. For example, it would be a mistake to call
|str_room| or |make_string| at this time, because a call on |overflow|
might lead to an infinite loop.
@^system dependencies@>
-
-Actually there's one way to get error messages, via |prepare_mag|;
-but that can't cause infinite recursion.
+(Actually there's one way to get error messages, via |prepare_mag|;
+but that can't cause infinite recursion.)
@^recursion@>
-This program doesn't bother to close the input files that may still be open.
+If |final_cleanup| is bypassed, this program doesn't bother to close
+the input files that may still be open.
@<Last-minute...@>=
procedure close_files_and_terminate;
var k:integer; {all-purpose index}
-begin @<Finish the extensions@>;
+begin @<Finish the extensions@>; new_line_char:=-1;
@!stat if tracing_stats>0 then @<Output statistics about this job@>;@;@+tats@/
wake_up_terminal; @<Finish the \.{DVI} file@>;
if log_opened then
@@ -24355,7 +24378,7 @@ been scanned and |its_all_over|\kern-2pt.
procedure final_cleanup;
label exit;
var c:small_number; {0 for \.{\\end}, 1 for \.{\\dump}}
-begin c:=cur_chr;
+begin c:=cur_chr; if c<>1 then new_line_char:=-1;
if job_name=0 then open_log_file;
while input_ptr>0 do
if state=token_list then end_token_list@+else end_file_reading;
@@ -24459,14 +24482,15 @@ program below. (If |m=13|, there is an additional argument, |l|.)
@!debug procedure debug_help; {routine to display various things}
label breakpoint,exit;
var k,@!l,@!m,@!n:integer;
-begin loop begin wake_up_terminal;
+begin clear_terminal;
+ loop begin wake_up_terminal;
print_nl("debug # (-1 to exit):"); update_terminal;
@.debug \#@>
read(term_in,m);
if m<0 then return
else if m=0 then
- begin goto breakpoint;@\ {go to every label at least once}
- breakpoint: m:=0; @{'BREAKPOINT'@}@\
+ begin goto breakpoint;@/ {go to every declared label at least once}
+ breakpoint: m:=0; @{'BREAKPOINT'@}@/
end
else begin read(term_in,n);
case m of