% vim: ft=change % TODO: sparse arrays % This is the first of the set of % WEB change file containing code for various features extending Omega; % these files define the Aleph program, and are designed to be applied % to omega.web compiled without XML support. % This change-file is heavily based on etex.ch, % defining version 2.1 of e-TeX. % ATTENTION: The software is currently in pre-alpha stage. % The TeX program is copyright (C) 1982 by D. E. Knuth. % TeX is a trademark of the American Mathematical Society. % e-TeX and NTS are trademarks of the NTS group. % All line numbers refer to TEX.WEB 3.14159 as of March 21, 1995. % TODO: double line number reference, having them for both TEX.WEB % and (X)OMEGA.WEB @x limbo l.1 - this is Aleph % (C) 1994--2000 by John Plaice and Yannis Haralambous. @y % (C) 2002--2004 by Giuseppe Bilotta and the Aleph task force; % all rights are reserved. % % Aleph is directly derived from e-TeX, an extension of % Donald E. Knuth's TeX developed by Peter Breitenlohner and % the NTS team, and Omega, another extension of TeX, developed by % John Plaice and Yannis Haralambous. % Aleph is designed in the form of a set of WEB changefiles % to be applied to Omega % compiled without XML support. The changefiles are heavily based % on the e-TeX 2.1 changefiles. % Omega is copyright (C) 1994--2000 by John Plaice and Yannis Haralambous. @z %--------------------------------------- @x limbo l.1 - this is e-TeX % % 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 % 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. % TeX is a trademark of the American Mathematical Society. % METAFONT is a trademark of Addison-Wesley Publishing Company. @y % e-TeX is copyright (C) 1994,98 by the NTS team; all rights are reserved. % e-TeX and NTS are trademarks of the NTS group. % TeX is a trademark of the American Mathematical Society. % METAFONT is a trademark of Addison-Wesley Publishing Company. % e-TeX is directly derived from Donald E. Knuth's TeX; % the change history which follows and the reward offered for finders of % bugs refer specifically to TeX; they should not be taken as referring % to e-TeX, although the change history is relevant in that it % demonstrates the evolutionary path followed. This program is not TeX; % that name is reserved strictly for the program which is the creation % and sole responsibility of Professor Knuth. @z %--------------------------------------- @x limbo l.50 - e-TeX history % Although considerable effort has been expended to make the TeX program % correct and reliable, no warranty is implied; the author disclaims any % obligation or liability for damages, including but not limited to % special, indirect, or consequential damages arising out of or in % connection with the use or performance of this software. This work has % been a ``labor of love'' and the author hopes that users enjoy it. @y % A preliminary version of TeX--XeT was released in April 1992. % TeX--XeT version 1.0 was released in June 1992, % version 1.1 prevented arith overflow in glue computation (Oct 1992). % A preliminary e-TeX version 0.95 was operational in March 1994. % Version 1.0beta was released in May 1995. % Version 1.01beta fixed bugs in just_copy and every_eof (December 1995). % Version 1.02beta allowed 256 mark classes (March 1996). % Version 1.1 changed \group{type,level} -> \currentgroup{type,level}, % first public release (October 1996). % Version 2.0 development was started in March 1997; % fixed a ligature-\beginR bug in January 1998; % was released in March 1998. % Version 2.1 fixed a marks bug (when min_halfword<>0) (January 1999). % Aleph includes all the e-TeX extensions, except for TeX--XeT and % some optimizations. % Release Candidate 0 was released in Janurary 2003. % Release Candidate 1 was released in June 2003. % fixed Omega overfull box bug % Release Candidate 2 has to be released % fixed Omega overfull rule bug % fixed Omega leader tripping bug % reorganized source code % Although considerable effort has been expended to make the Aleph program % correct and reliable, no warranty is implied; the authors disclaim any % obligation or liability for damages, including but not limited to % special, indirect, or consequential damages arising out of or in % connection with the use or performance of this software. This work has % been a ``labor of love'' and the authors hope that users enjoy it. @z %--------------------------------------- @x limbo l.61 - e-TeX logo, TeXXeT \let\mc=\ninerm % medium caps for names like SAIL @y \let\mc=\ninerm % medium caps for names like SAIL \def\eTeX{$\varepsilon$-\TeX} \def\Aleph{$\aleph$} % \font\revrm=xbmc10 % for right-to-left text % % to generate xbmc10 (i.e., reflected cmbx10) use a file % % xbmc10.mf containing: % %+++++++++++++++++++++++++++++++++++++++++++++++++ % % if unknown cmbase: input cmbase fi % % extra_endchar := extra_endchar & % % "currentpicture:=currentpicture " & % % "reflectedabout((.5[l,r],0),(.5[l,r],1));"; % % input cmbx10 % %+++++++++++++++++++++++++++++++++++++++++++++++++ % \ifx\beginL\undefined % this is TeX \def\XeT{X\kern-.125em\lower.5ex\hbox{E}\kern-.1667emT} \def\TeXeT{\TeX-\hbox{\revrm \XeT}} % for TeX-XeT \def\TeXXeT{\TeX-\hbox{\revrm -\XeT}} % for TeX--XeT % \else % \ifx\eTeXversion\undefined % this is \TeXeT % \def\TeXeT{\TeX-{\revrm\beginR\TeX\endR}} % for TeX-XeT % \def\TeXXeT{\TeX-{\revrm\beginR\TeX-\endR}} % for TeX--XeT % \else % this is \eTeX % \def\TeXeT{\TeX-{\TeXXeTstate=1\revrm\beginR\TeX\endR}} % for TeX-XeT % \def\TeXXeT{\TeX-{\TeXXeTstate=1\revrm\beginR\TeX-\endR}} % for TeX--XeT % \fi % \fi @z %--------------------------------------- @x limbo l.64 - bug fix (print only changed modules) \def\pct!{{\char`\%}} % percent sign in ordinary text @y \def\pct!{{\char`\%}} % percent sign in ordinary text \def\grp{\.{\char'173...\char'175}} @z %--------------------------------------- @x limbo l.80 - e-TeX basic \def\title{$\Omega$ (OMEGA)} @y \def\title{\Aleph\ (ALEPH)} % system dependent redefinitions of \title should come later % and should use: % \toks0=\expandafter{\title} % \edef\title{...\the\toks0...} \let\maybe=\iffalse % print only changed modules \let\maybe=\iftrue % print everything @z %--------------------------------------- @x [1] m.1 l.91 - this is e-TeX This is $\Omega$, a document compiler intended to simplify high-quality @y This is \Aleph, an extension of $\Omega$. $\Omega$ is a document compiler intended to simplify high-quality @z %--------------------------------------- @x [1] m.2 l.179 - e-TeX basic If this program is changed, the resulting system should not be called @y This program contains code from both the $\Omega$ (developed by John Plaice and Yannis Haralambous) and \eTeX\ (developed by Peter Breitenlohner and the NTS team) extensions to \TeX, therefore this program is called `\Aleph' and not @z %--------------------------------------- @x [1] m.2 l.185 - e-TeX basic November 1984]. @y November 1984]. A similar test suite called the ``\.{e-BUMP} test'' is (or will be made) available for helping to determine whether a particular implementation deserves to be known as `\Aleph'. @z %--------------------------------------- @x [1] m.2 l.187 - e-TeX basic @d banner=='This is Omega, Version 3.1415926--1.15' {printed when \TeX\ starts} @y @d banner=='This is Aleph, Version 3.1415926--1.15--2.1' {printed when \TeX\ starts} @# @d eTeX_version_string=='3.1415926--1.15--2.1' {current \eTeX\ version} @d eTeX_version=2 { \.{\\eTeXversion} } @d eTeX_revision==".1" { \.{\\eTeXrevision} } @# @d eTeX_banner=='This is Aleph, Version ',eTeX_version_string {printed when \eTeX\ starts} @# @d OMEGA==ALEPH {change program name into |ALEPH|} @# @d eTeX_states=1 {number of \eTeX\ state variables in |eqtb|} @z %--------------------------------------- @x [1] m.15 l.493 - e-TeX basic @d not_found=45 {go here when you've found nothing} @y @d not_found=45 {go here when you've found nothing} @d not_found1=46 {like |not_found|, when there's more than one} @d not_found2=47 {like |not_found|, when there's more than two} @d not_found3=48 {like |not_found|, when there's more than three} @d not_found4=49 {like |not_found|, when there's more than four} @z %--------------------------------------- @x [5] m.61 l.1556 - e-TeX basic wterm(banner); @y wterm(eTeX_banner); @z %--------------------------------------- @x [10] m.141 l.2965 - e-TeX marks This field occupies a full word instead of a halfword, because there's nothing to put in the other halfword; it is easier in \PASCAL\ to use the full word than to risk leaving garbage in the unused half. @y In addition there is a |mark_class| field that contains the mark class. @z %--------------------------------------- @x [10] m.141 l.2971 - e-TeX marks @d mark_ptr(#)==mem[#+1].int {head of the token list for a mark} @y @d mark_ptr(#)==link(#+1) {head of the token list for a mark} @d mark_class(#)==info(#+1) {the mark class} @z %--------------------------------------- @x [10] m.142 l.2980 - e-TeX marks @d adjust_ptr==mark_ptr {vertical list to be moved out of horizontal list} @y @d adjust_ptr(#)==mem[#+1].int {vertical list to be moved out of horizontal list} @z %--------------------------------------- % @x [10] m.147 l.3069 - e-TeX TeXXeT % the amount of surrounding space inserted by \.{\\mathsurround}. % @y % the amount of surrounding space inserted by \.{\\mathsurround}. % % In addition a |math_node| with |subtype>after| and |width=0| will be % (ab)used to record a regular |math_node| reinserted after being % discarded at a line break or one of the text direction primitives ( % \.{\\beginL}, \.{\\endL}, \.{\\beginR}, and \.{\\endR} ). % @z %--------------------------------------- % @x [10] m.147 l.3073 - e-TeX TeXXeT % @d after=1 {|subtype| for math node that winds up a formula} % @y % @d after=1 {|subtype| for math node that winds up a formula} % @# % @d M_code=2 % @d begin_M_code=M_code+before {|subtype| for \.{\\beginM} node} % @d end_M_code=M_code+after {|subtype| for \.{\\endM} node} % @d L_code=4 % @d begin_L_code=L_code+begin_M_code {|subtype| for \.{\\beginL} node} % @d end_L_code=L_code+end_M_code {|subtype| for \.{\\endL} node} % @d R_code=L_code+L_code % @d begin_R_code=R_code+begin_M_code {|subtype| for \.{\\beginR} node} % @d end_R_code=R_code+end_M_code {|subtype| for \.{\\endR} node} % @# % @d end_LR(#)==odd(subtype(#)) % @d end_LR_type(#)==(L_code*(subtype(#) div L_code)+end_M_code) % @d begin_LR_type(#)==(#-after+before) % @z %--------------------------------------- % @x [12] m.175 l.3546 - e-TeX TeXXeT % math_node: print_char("$"); % @y % math_node: if subtype(p)>=L_code then print("[]") % else print_char("$"); % @z %--------------------------------------- % @x [12] m.184 l.3713 - e-TeX TeXXeT % begin print(", shifted "); print_scaled(shift_amount(p)); % end; % @y % begin print(", shifted "); print_scaled(shift_amount(p)); % end; % if eTeX_ex then @; % @z %--------------------------------------- % @x [12] m.192 l.3811 - e-TeX TeXXeT % begin print_esc("math"); % @y % if subtype(p)>after then % begin if end_LR(p) then print_esc("end") % else print_esc("begin"); % if subtype(p)>R_code then print_char("R") % else if subtype(p)>L_code then print_char("L") % else print_char("M"); % end else % begin print_esc("math"); % @z %--------------------------------------- @x [12] m.196 l.3844 - e-TeX marks begin print_esc("mark"); print_mark(mark_ptr(p)); @y begin print_esc("mark"); if mark_class(p)<>0 then begin print_char("s"); print_int(mark_class(p)); end; print_mark(mark_ptr(p)); @z %--------------------------------------- @x [15] m.208 l.4081 - e-TeX saved_items @d un_vbox=24 {unglue a box ( \.{\\unvbox}, \.{\\unvcopy} )} @y @d un_vbox=24 {unglue a box ( \.{\\unvbox}, \.{\\unvcopy} )} {( or \.{\\pagediscards}, \.{\\splitdiscards} )} @z %--------------------------------------- % @x [15] m.208 l.4091 - e-TeX TeXXeT % @d valign=33 {vertical table alignment ( \.{\\valign} )} % @y % @d valign=33 {vertical table alignment ( \.{\\valign} )} % {or text direction directives ( \.{\\beginL}, etc.~)} % @z %--------------------------------------- @x [15] m.208 l.4107 - e-TeX middle @d left_right=49 {variable delimiter ( \.{\\left}, \.{\\right} )} @y @d left_right=49 {variable delimiter ( \.{\\left}, \.{\\right} )} {( or \.{\\middle} )} @z %--------------------------------------- @x [15] m.209 l.4151 - e-TeX basic \.{\\insertpenalties} )} @y \.{\\insertpenalties} )} {( or \.{\\interactionmode} )} @z %--------------------------------------- @x [15] m.209 l.4153 - e-TeX penalties @d set_shape=set_box_dimen+1 {specify fancy paragraph shape ( \.{\\parshape} )} @y @d set_shape=set_box_dimen+1 {specify fancy paragraph shape ( \.{\\parshape} )} {(or \.{\\interlinepenalties}, etc.~)} @z %--------------------------------------- @x [15] m.209 l.4163 - e-TeX protected @d prefix=divide+1 {qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )} @y @d prefix=divide+1 {qualify a definition ( \.{\\global}, \.{\\long}, \.{\\outer} )} {( or \.{\\protected} )} @z %--------------------------------------- @x [15] m.209 l.4166 - e-TeX read_line @d read_to_cs=shorthand_def+1 {read into a control sequence ( \.{\\read} )} @y @d read_to_cs=shorthand_def+1 {read into a control sequence ( \.{\\read} )} {( or \.{\\readline} )} @z %--------------------------------------- @x [15] m.210 l.4181 - e-TeX scan_tokens @d input=max_command+4 {input a source file ( \.{\\input}, \.{\\endinput} )} @y @d input=max_command+4 {input a source file ( \.{\\input}, \.{\\endinput} )} {( or \.{\\scantokens} )} @z %--------------------------------------- @x [15] m.210 l.4186 - e-TeX unexpanded @d the=max_command+9 {expand an internal quantity ( \.{\\the} )} @y @d the=max_command+9 {expand an internal quantity ( \.{\\the} )} {( or \.{\\unexpanded}, \.{\\detokenize} )} @z %--------------------------------------- @x [16] m.212 l.4289 - e-TeX basic user's output routine. @y user's output routine. A seventh quantity, |eTeX_aux|, is used by the extended features \eTeX. In vertical modes it is known as |LR_save| and holds the LR stack when a paragraph is interrupted by a displayed formula. In display math mode it is known as |LR_box| and holds a pointer to a prototype box for the display. In math mode it is known as |delim_ptr| and points to the most recent |left_noad| or |middle_noad| of a |math_left_group|. In \Aleph it is only used in this last sense. @z %--------------------------------------- @x [16] m.212 l.4304 - e-TeX basic @!head_field,@!tail_field: pointer; @y @!head_field,@!tail_field: pointer; @!eTeX_aux_field: pointer; @z %--------------------------------------- @x [16] m.213 l.4311 - e-TeX basic @d tail==cur_list.tail_field {final node on current list} @y @d tail==cur_list.tail_field {final node on current list} @d eTeX_aux==cur_list.eTeX_aux_field {auxiliary data for \eTeX} @d delim_ptr==eTeX_aux {most recent left or right noad of a math left group} @z %--------------------------------------- @x [16] m.215 l.4342 - e-TeX basic mode:=vmode; head:=contrib_head; tail:=contrib_head; @y mode:=vmode; head:=contrib_head; tail:=contrib_head; eTeX_aux:=null; @z %--------------------------------------- @x [16] m.216 l.4358 push_nest - e-TeX basic incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line; @y incr(nest_ptr); head:=get_avail; tail:=head; prev_graf:=0; mode_line:=line; eTeX_aux:=null; @z %--------------------------------------- @x [17] m.230 l.4712 - e-TeX basic, penalties @d output_routine_loc=local_base+1 {points to token list for \.{\\output}} @d every_par_loc=local_base+2 {points to token list for \.{\\everypar}} @d every_math_loc=local_base+3 {points to token list for \.{\\everymath}} @d every_display_loc=local_base+4 {points to token list for \.{\\everydisplay}} @d every_hbox_loc=local_base+5 {points to token list for \.{\\everyhbox}} @d every_vbox_loc=local_base+6 {points to token list for \.{\\everyvbox}} @d every_job_loc=local_base+7 {points to token list for \.{\\everyjob}} @d every_cr_loc=local_base+8 {points to token list for \.{\\everycr}} @d err_help_loc=local_base+9 {points to token list for \.{\\errhelp}} @d ocp_trace_level_base=local_base+10 @y @d inter_line_penalties_loc=local_base+1 {additional penalties between lines} @d club_penalties_loc=local_base+2 {penalties for creating club lines} @d widow_penalties_loc=local_base+3 {penalties for creating widow lines} @d display_widow_penalties_loc=local_base+4 {ditto, just before a display} @d token_base=local_base+5 {table of token list parameters} @d output_routine_loc=token_base {points to token list for \.{\\output}} @d every_par_loc=token_base+1 {points to token list for \.{\\everypar}} @d every_math_loc=token_base+2 {points to token list for \.{\\everymath}} @d every_display_loc=token_base+3 {points to token list for \.{\\everydisplay}} @d every_hbox_loc=token_base+4 {points to token list for \.{\\everyhbox}} @d every_vbox_loc=token_base+5 {points to token list for \.{\\everyvbox}} @d every_job_loc=token_base+6 {points to token list for \.{\\everyjob}} @d every_cr_loc=token_base+7 {points to token list for \.{\\everycr}} @d every_eof_loc=token_base+8 {points to token list for \.{\\everyeof}} @d err_help_loc=token_base+9 {points to token list for \.{\\errhelp}} @d ocp_trace_level_base=token_base+10 @z %--------------------------------------- @x [17] m.231 l.4787 - e-TeX basic othercases print_esc("errhelp") @y @/@@/ othercases print_esc("errhelp") @z %--------------------------------------- % FIXME moved to init_eqtb_entry --see later % @x [17] m.232 l.4805 - e-TeX penalties % eq_level(par_shape_loc):=level_one;@/ % @y % eq_level(par_shape_loc):=level_one;@/ % for k:=par_shape_loc+1 to token_base-1 do % eqtb[k]:=eqtb[par_shape_loc]; % @z %--------------------------------------- @x [17] m.233 l.4833 - e-TeX penalties if n=par_shape_loc then begin print_esc("parshape"); print_char("="); if par_shape_ptr=null then print_char("0") else print_int(info(par_shape_ptr)); @y if npar_shape_loc then begin print_int(penalty(equiv(n))); print_char(" "); print_int(penalty(equiv(n)+1)); if penalty(equiv(n))>1 then print_esc("ETC."); end else print_int(info(par_shape_ptr)); @z %--------------------------------------- % FIXME: in this section and in the next % we should remove pre_display_direction[_code] % stuff, both here and down below @x [17] m.236 l.4955 - e-TeX basic @d dir_base=int_base+int_pars @y @d tracing_assigns_code=int_pars {show assignments} @d tracing_groups_code=int_pars+1 {show save/restore groups} @d tracing_ifs_code=int_pars+2 {show conditionals} @d tracing_scan_tokens_code=int_pars+3 {show pseudo file open and close} @d tracing_nesting_code=int_pars+4 {show incomplete groups and ifs within files} @d pre_display_direction_code=int_pars+5 {text direction preceding a display} @d last_line_fit_code=int_pars+6 {adjustment for last line of paragraph} @d saving_vdiscards_code=int_pars+7 {save items discarded from vlists} @d saving_hyph_codes_code=int_pars+8 {save hyphenation codes for languages} @d eTeX_state_code=int_pars+9 {\eTeX\ state variables} @d dir_base=int_base+eTeX_state_code+eTeX_states @z %--------------------------------------- @x [17] m.236 l.5016 - e-TeX basic @d error_context_lines==int_par(error_context_lines_code) @y @d error_context_lines==int_par(error_context_lines_code) @d tracing_assigns==int_par(tracing_assigns_code) @d tracing_groups==int_par(tracing_groups_code) @d tracing_ifs==int_par(tracing_ifs_code) @d tracing_scan_tokens==int_par(tracing_scan_tokens_code) @d tracing_nesting==int_par(tracing_nesting_code) @d pre_display_direction==int_par(pre_display_direction_code) @d last_line_fit==int_par(last_line_fit_code) @d saving_vdiscards==int_par(saving_vdiscards_code) @d saving_hyph_codes==int_par(saving_hyph_codes_code) @z %--------------------------------------- @x [17] m.237 l.5081 print_param - e-TeX basic othercases print("[unknown integer parameter!]") @y @/@@/ othercases print("[unknown integer parameter!]") @z %--------------------------------------- % FIXED(?): moved to init_eqtb_entry in % omega.web at l.5813 @x [17] m.232 l.4805 - e-TeX penalties { Region 4 } else if (p>=par_shape_loc) and (p<=toks_base+biggest_reg) then begin equiv_field(mw):=null; eq_type_field(mw):=undefined_cs; eq_level_field(mw):=level_zero; end @y { Region 4 } else if (p>=par_shape_loc) and (p< token_base) then begin equiv_field(mw):=null; eq_type_field(mw):=shape_ref; eq_level_field(mw):=level_one; end else if (p>=token_base) and (p<=toks_base+biggest_reg) then begin equiv_field(mw):=null; eq_type_field(mw):=undefined_cs; eq_level_field(mw):=level_zero; end @z %--------------------------------------- @x [18] m.264 l.5612 primitive - e-TeX basic @!j:small_number; {index into |buffer|} @y @!j:0..buf_size; {index into |buffer|} @z %--------------------------------------- @x [18] m.264 l.5616 primitive - e-TeX basic {we will move |s| into the (empty) |buffer|} for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]); cur_val:=id_lookup(0,l); {|no_new_control_sequence| is |false|} @y {we will move |s| into the (possibly non-empty) |buffer|} if first+l>buf_size+1 then overflow("buffer size",buf_size); @:TeX capacity exceeded buffer size}{\quad buffer size@> for j:=0 to l-1 do buffer[first+j]:=so(str_pool[k+j]); cur_val:=id_lookup(first,l); {|no_new_control_sequence| is |false|} @z %--------------------------------------- @x [18] m.265 l.5691 - e-TeX penalties primitive("parshape",set_shape,0);@/ @y primitive("parshape",set_shape,par_shape_loc);@/ @z %--------------------------------------- @x [18] m.265 l.5708 - e-TeX sparse arrays primitive("toks",toks_register,0);@/ @y primitive("toks",toks_register,mem_bot);@/ @z %--------------------------------------- @x [18] m.266 l.5741 - e-TeX cond expand_after: print_esc("expandafter"); @y expand_after: if chr_code=0 then print_esc("expandafter") @; @z %--------------------------------------- @x [18] m.266 l.5747 - e-TeX marks mark: print_esc("mark"); @y mark: begin print_esc("mark"); if chr_code>0 then print_char("s"); end; @z %--------------------------------------- @x [18] m.266 l.5758 - e-TeX read_line read_to_cs: print_esc("read"); @y read_to_cs: if chr_code=0 then print_esc("read") @; @z %--------------------------------------- @x [18] m.266 l.5762 - e-TeX penalties set_shape: print_esc("parshape"); @y set_shape: case chr_code of par_shape_loc: print_esc("parshape"); @@;@/ end; {there are no other cases} @z %--------------------------------------- @x [18] m.266 l.5763 - e-TeX unexpanded the: print_esc("the"); @y the: if chr_code=0 then print_esc("the") @; @z %--------------------------------------- @x [18] m.266 l.5764 - e-TeX sparse arrays toks_register: print_esc("toks"); @y toks_register: @; @z %--------------------------------------- % @x [18] m.266 l.5766 - e-TeX TeXXeT % valign: print_esc("valign"); % @y % valign: if chr_code=0 then print_esc("valign")@/ % @; % @z %--------------------------------------- @x [19] m.268 l.5800 - e-TeX sparse arrays interpreted in one of four ways: @y interpreted in one of five ways: @z %--------------------------------------- @x [19] m.268 l.5820 - e-TeX tracing the entries for that group. @y the entries for that group. Furthermore, in extended \eTeX\ mode, |save_stack[p-1]| contains the source line number at which the current level of grouping was entered. \yskip\hang 5) If |save_type(p)=restore_sa|, then |sa_chain| points to a chain of sparse array entries to be restored at the end of the current group. Furthermore |save_index(p)| and |save_level(p)| should replace the values of |sa_chain| and |sa_level| respectively. @z %--------------------------------------- % FIXME restore_sa safe? (sparse arrays) @x [19] m.268 l.5830 - e-TeX basic @d level_boundary=3 {|save_type| corresponding to beginning of group} @y @d level_boundary=3 {|save_type| corresponding to beginning of group} @d restore_sa=4 {|save_type| when sparse array entries should be restored} @p@t\4@>@ @z %--------------------------------------- @x [19] m.273 l.5888 - e-TeX tracing @ The following macro is used to test if there is room for up to six more @y @ The following macro is used to test if there is room for up to seven more @z %--------------------------------------- @x [19] m.273 l.5894 check_full_save_stack - e-TeX tracing if max_save_stack>save_size-6 then overflow("save size",save_size); @y if max_save_stack>save_size-7 then overflow("save size",save_size); @z %--------------------------------------- @x [19] m.274 l.5916 new_save_level - e-TeX tracing begin check_full_save_stack; @y begin check_full_save_stack; if eTeX_ex then begin saved(0):=line; incr(save_ptr); end; @z %--------------------------------------- @x [19] m.274 l.5923 new_save_level - e-TeX tracing cur_boundary:=save_ptr; incr(cur_level); incr(save_ptr); cur_group:=c; @y cur_boundary:=save_ptr; cur_group:=c; @!stat if tracing_groups>0 then group_trace(false);@+tats@;@/ incr(cur_level); incr(save_ptr); @z %--------------------------------------- @x [19] m.275 l.5941 eq_destroy - e-TeX sparse arrays othercases do_nothing @y @/@@/ othercases do_nothing @z %--------------------------------------- @x [19] m.277 l.5963 - e-TeX tracing the call, since |eq_save| makes the necessary test. @y the call, since |eq_save| makes the necessary test. @d assign_trace(#)==@!stat if tracing_assigns>0 then restore_trace(#); tats @z %--------------------------------------- @x [19] m.277 l.5967 eq_define - e-TeX tracing begin if eq_level(p)=cur_level then eq_destroy(new_eqtb(p)) @y label exit; begin if eTeX_ex and(eq_type(p)=t)and(equiv(p)=e) then begin assign_trace(p,"reassigning")@;@/ eq_destroy(new_eqtb(p)); return; end; assign_trace(p,"changing")@;@/ if eq_level(p)=cur_level then eq_destroy(new_eqtb(p)) @z %--------------------------------------- @x [19] m.277 l.5970 eq_define - e-TeX tracing end; @y assign_trace(p,"into")@;@/ exit:end; @z %--------------------------------------- @x [19] m.278 l.5977 eq_word_define - e-TeX tracing begin if xeq_level(p)<>cur_level then @y label exit; begin if eTeX_ex and(eqtb[p].int=w) then begin assign_trace(p,"reassigning")@;@/ return; end; assign_trace(p,"changing")@;@/ if xeq_level(p)<>cur_level then @z %--------------------------------------- @x [19] m.278 l.5981 eq_word_define - e-TeX tracing end; @y assign_trace(p,"into")@;@/ exit:end; @z %--------------------------------------- @x [19] m.279 l.5990 geq_define - e-TeX tracing begin eq_destroy(new_eqtb(p)); set_eq_level(p,level_one); set_eq_type(p,t); set_equiv(p,e); @y begin assign_trace(p,"globally changing")@;@/ begin eq_destroy(new_eqtb(p)); set_eq_level(p,level_one); set_eq_type(p,t); set_equiv(p,e); end; assign_trace(p,"into")@;@/ @z %--------------------------------------- @x [19] m.279 l.5995 geq_word_define - e-TeX tracing begin set_new_eqtb_int(p,w); set_xeq_level(p,level_one); @y begin assign_trace(p,"globally changing")@;@/ begin set_new_eqtb_int(p,w); set_xeq_level(p,level_one); end; assign_trace(p,"into")@;@/ @z %--------------------------------------- @x [19] m.281 l.6012 - e-TeX tracing @p@t\4@>@@;@/ @y @p @z %--------------------------------------- @x [19] m.281 l.6019 unsave - e-TeX optimized \aftergroup begin if cur_level>level_one then @y @!a:boolean; {have we already processed an \.{\\aftergroup} ?} begin a:=false; if cur_level>level_one then @z %--------------------------------------- % FIXME restore_sa usage @x [19] m.282 l.6033 - e-TeX sparse arrays else begin if save_type(save_ptr)=restore_old_value then @y else if save_type(save_ptr)=restore_sa then begin sa_restore; sa_chain:=p; sa_level:=save_level(save_ptr); end else begin if save_type(save_ptr)=restore_old_value then @z %--------------------------------------- @x [19] m.282 l.6041 - e-TeX tracing done: cur_group:=save_level(save_ptr); cur_boundary:=save_index(save_ptr) @y done: @!stat if tracing_groups>0 then group_trace(true);@+tats@;@/ if grp_stack[in_open]=cur_boundary then group_warning; {groups possibly not properly nested with files} cur_group:=save_level(save_ptr); cur_boundary:=save_index(save_ptr); if eTeX_ex then decr(save_ptr) @z %--------------------------------------- @x [19] m.284 l.6067 - e-TeX tracing @ @= @y @ @= @z %--------------------------------------- @x [20] m.289 l.6155 - e-TeX protected @d end_match_token=@"E0000 {$2^16\cdot|end_match|$} @y @d end_match_token=@"E0000 {$2^16\cdot|end_match|$} @d protected_token=@"E0001 {$2^16\cdot|end_match|+1$} @z %--------------------------------------- @x [20] m.294 l.6280 - e-TeX protected end_match: print("->"); @y end_match: if c=0 then print("->"); @z %--------------------------------------- @x [20] m.296 l.6301 print_meaning - e-TeX marks else if cur_cmd=top_bot_mark then @y else if (cur_cmd=top_bot_mark)and(cur_chr0 then if cur_cmd>=if_test then if cur_cmd<=fi_or_else then begin print(": "); if cur_cmd=fi_or_else then begin print_cmd_chr(if_test,cur_if); print_char(" "); n:=0; l:=if_line; end else begin n:=1; l:=line; end; p:=cond_ptr; while p<>null do begin incr(n); p:=link(p); end; print("(level "); print_int(n); print_char(")"); print_if_line(l); end; print_char("}"); @z %--------------------------------------- % FIXME: What about \write18 compatibility? @x [22] m.303 l.6475 show_context - e-TeX scan_tokens the terminal, under control of the procedure |read_toks|.) @y the terminal, under control of the procedure |read_toks|.) Finally |18<=name<=19| indicates that we are reading a pseudo file created by the \.{\\scantokens} command. @z %--------------------------------------- @x [22] m.307 l.6692 - e-TeX basic @d mark_text=14 {|token_type| code for \.{\\topmark}, etc.} @d write_text=15 {|token_type| code for \.{\\write}} @y @d every_eof_text=14 {|token_type| code for \.{\\everyeof}} @d mark_text=15 {|token_type| code for \.{\\topmark}, etc.} @d write_text=16 {|token_type| code for \.{\\write}} @z %--------------------------------------- @x [22] m.311 l.6749 show_context - e-TeX scan_tokens if (name>17) or (base_ptr=0) then bottom_line:=true; @y if (name>19) or (base_ptr=0) then bottom_line:=true; @z %--------------------------------------- @x [22] m.313 l.6794 - e-TeX scan_tokens else begin print_nl("l."); print_int(line); @y else if index<>in_open then {input from a pseudo file} begin print_nl("l."); print_int(line_stack[index+1]); end else begin print_nl("l."); print_int(line); @z %--------------------------------------- @x [22] m.314 l.6814 - e-TeX basic every_cr_text: print_nl(" "); @y every_cr_text: print_nl(" "); every_eof_text: print_nl(" "); @z %--------------------------------------- @x [23] m.326 l.7009 - e-TeX optimized \aftergroup begin t:=cur_tok; cur_tok:=p; back_input; cur_tok:=t; @y begin t:=cur_tok; cur_tok:=p; if a then begin p:=get_avail; info(p):=cur_tok; link(p):=loc; loc:=p; start:=p; if cur_tok17 then a_close(cur_file); {forget it} @y if (name=18)or(name=19) then pseudo_close else if name>17 then a_close(cur_file); {forget it} @z %--------------------------------------- @x [23] m.331 l.7066 - e-TeX tracing_nesting in_open:=0; open_parens:=0; max_buf_stack:=0; @y in_open:=0; open_parens:=0; max_buf_stack:=0; grp_stack[0]:=0; if_stack[0]:=null; @z %--------------------------------------- @x [24] m.362 l.7538 - e-TeX scan_tokens, every_eof if not force_eof then @y if not force_eof then if name<=19 then begin if pseudo_input then {not end of file} firm_up_the_line {this sets |limit|} else if (every_eof<>null)and not eof_seen[index] then begin limit:=first-1; eof_seen[index]:=true; {fake one empty line} begin_token_list(every_eof,every_eof_text); goto restart; end else force_eof:=true; end else @z %--------------------------------------- @x [24] m.362 l.7541 - e-TeX every_eof else force_eof:=true; @y else if (every_eof<>null)and not eof_seen[index] then begin limit:=first-1; eof_seen[index]:=true; {fake one empty line} begin_token_list(every_eof,every_eof_text); goto restart; end else force_eof:=true; @z %--------------------------------------- @x [24] m.362 l.7544 - e-TeX scan_tokens begin print_char(")"); decr(open_parens); update_terminal; {show user that file has been read} @y begin if tracing_nesting>0 then if (grp_stack[in_open]<>cur_boundary)or@| (if_stack[in_open]<>cond_ptr) then file_warning; {give warning for some unfinished groups and/or conditionals} if name>=19 then begin print_char(")"); decr(open_parens); update_terminal; {show user that file has been read} end; @z %--------------------------------------- @x [25] m.366 l.7630 - e-TeX basic @t\4@>@@;@/ @y @t\4@>@@;@/ @t\4@>@@;@/ @z %--------------------------------------- @x [25] m.366 l.7637 expand - e-TeX cond procedure expand; @y procedure expand; label reswitch; @z %--------------------------------------- @x [25] m.366 l.7648 expand - e-TeX cond if cur_cmd @y reswitch: if cur_cmd @z %--------------------------------------- @x [25] m.367 l.7659 - e-TeX cond expand_after:@; @y expand_after:if cur_chr=0 then @ else @; @z %--------------------------------------- @x [25] m.377 l.7779 - e-TeX scan_tokens input: if chr_code=0 then print_esc("input")@+else print_esc("endinput"); @y input: if chr_code=0 then print_esc("input") @/@@/ else print_esc("endinput"); @z %--------------------------------------- @x [25] m.378 l.7782 - e-TeX scan_tokens if cur_chr>0 then force_eof:=true @y if cur_chr=1 then force_eof:=true @/@@/ @z %--------------------------------------- @x [25] m.382 l.7838 - e-TeX marks @d top_mark_code=0 {the mark in effect at the previous page break} @y @d marks_code==5 {add this for \.{\\topmarks} etc.} @# @d top_mark_code=0 {the mark in effect at the previous page break} @z %--------------------------------------- @x [25] m.385 l.7870 - e-TeX marks top_bot_mark: case chr_code of @y top_bot_mark: begin case (chr_code mod marks_code) of @z %--------------------------------------- @x [25] m.385 l.7876 - e-TeX marks endcases; @y endcases; if chr_code>=marks_code then print_char("s"); end; @z %--------------------------------------- @x [25] m.386 l.7882 - e-TeX marks begin if cur_mark[cur_chr]<>null then begin_token_list(cur_mark[cur_chr],mark_text); @y begin t:=cur_chr mod marks_code; if cur_chr>=marks_code then scan_register_num@+else cur_val:=0; if cur_val=0 then cur_ptr:=cur_mark[t] else @; if cur_ptr<>null then begin_token_list(cur_ptr,mark_text); @z %--------------------------------------- @x [25] m.389 l.7945 macro_call - e-TeX protected if info(r)<>end_match_token then @y if info(r)=protected_token then r:=link(r); if info(r)<>end_match_token then @z %--------------------------------------- @x [26] m.409 l.8255 - e-TeX basic @t\4\4@>@ @y @t\4\4@>@@; @t\4\4@>@ @z %--------------------------------------- @x [26] m.411 l.8299 - e-TeX sparse arrays |glue_val|, or |mu_val|. @y |glue_val|, or |mu_val| more than |mem_bot| (dynamic variable-size nodes cannot have these values) @z %--------------------------------------- @x [26] m.411 l.8302 - e-TeX sparse arrays primitive("count",register,int_val); @!@:count_}{\.{\\count} primitive@> primitive("dimen",register,dimen_val); @!@:dimen_}{\.{\\dimen} primitive@> primitive("skip",register,glue_val); @!@:skip_}{\.{\\skip} primitive@> primitive("muskip",register,mu_val); @y primitive("count",register,mem_bot+int_val); @!@:count_}{\.{\\count} primitive@> primitive("dimen",register,mem_bot+dimen_val); @!@:dimen_}{\.{\\dimen} primitive@> primitive("skip",register,mem_bot+glue_val); @!@:skip_}{\.{\\skip} primitive@> primitive("muskip",register,mem_bot+mu_val); @z %--------------------------------------- @x [26] m.412 l.8312 - e-TeX sparse arrays register: if chr_code=int_val then print_esc("count") else if chr_code=dimen_val then print_esc("dimen") else if chr_code=glue_val then print_esc("skip") else print_esc("muskip"); @y register: @; @z %--------------------------------------- @x [26] m.413 l.8328 scan_something_internal - e-TeX basic var m:halfword; {|chr_code| part of the operand token} @y label exit; var m:halfword; {|chr_code| part of the operand token} @!q:halfword; {general purpose index} @!i:four_quarters; {character info} @z %--------------------------------------- @x [26] m.413 l.8354 scan_something_internal - e-TeX basic end; @y exit:end; @z %--------------------------------------- @x [26] m.415 l.8375 - e-TeX sparse arrays begin scan_eight_bit_int; m:=toks_base+cur_val; end; scanned_result(equiv(m))(tok_val); @y if m=mem_bot then begin scan_register_num; if cur_val<256 then cur_val:=equiv(toks_base+cur_val) else begin find_sa_element(tok_val,cur_val,false); if cur_ptr=null then cur_val:=null else cur_val:=sa_ptr(cur_ptr); end; end else cur_val:=sa_ptr(m) else cur_val:=equiv(m); cur_val_level:=tok_val; @z %--------------------------------------- @x [26] m.416 l.8390 - e-TeX basic |glue_val|, |input_line_no_code|, or |badness_code|. @d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}} @d badness_code=glue_val+2 {code for \.{\\badness}} @y |glue_val|, |last_node_type_code|, |input_line_no_code|, |badness_code|, |eTeX_version_code|, or one of the other codes for \eTeX\ extensions. @d last_node_type_code=glue_val+1 {code for \.{\\lastnodetype}} @d input_line_no_code=glue_val+2 {code for \.{\\inputlineno}} @d badness_code=glue_val+3 {code for \.{\\badness}} @d eTeX_int=glue_val+4 {first of \eTeX\ codes for integers} @d eTeX_dim=eTeX_int+8 {first of \eTeX\ codes for dimensions} @d eTeX_glue=eTeX_dim+9 {first of \eTeX\ codes for glue} @d eTeX_mu=eTeX_glue+1 {first of \eTeX\ codes for muglue} @d eTeX_expr=eTeX_mu+1 {first of \eTeX\ codes for expressions} @z %--------------------------------------- @x [26] m.417 l.8425 - e-TeX interaction_mode @+else print_esc("insertpenalties"); @y @/@@/ @+else print_esc("insertpenalties"); @z %--------------------------------------- @x [26] m.417 l.8434 - e-TeX basic othercases print_esc("badness") @y @/@@/ othercases print_esc("badness") @z %--------------------------------------- @x [26] m.419 l.8457 - e-TeX interaction_mode begin if m=0 then cur_val:=dead_cycles@+else cur_val:=insert_penalties; @y begin if m=0 then cur_val:=dead_cycles @/@@/ else cur_val:=insert_penalties; @z %--------------------------------------- @x [26] m.420 l.8462 - e-TeX sparse arrays begin scan_eight_bit_int; if box(cur_val)=null then cur_val:=0 @+else cur_val:=mem[box(cur_val)+m].sc; @y begin scan_register_num; fetch_box(q); if q=null then cur_val:=0 @+else cur_val:=mem[q+m].sc; @z %--------------------------------------- @x [26] m.423 l.8487 - e-TeX penalties begin if par_shape_ptr=null then cur_val:=0 @y begin if m>par_shape_loc then @ else if par_shape_ptr=null then cur_val:=0 @z %--------------------------------------- % @x [26] m.424 l.8493 - e-TeX TeXXeT % implemented. The reference count for \.{\\lastskip} will be updated later. % @y % implemented. The reference count for \.{\\lastskip} will be updated later. % A final \.{\\endM} node is temporarily removed. % @z %--------------------------------------- @x [26] m.424 l.8499 - e-TeX basic if cur_chr>glue_val then begin if cur_chr=input_line_no_code then cur_val:=line else cur_val:=last_badness; {|cur_chr=badness_code|} @y if m>last_node_type_code then if m>=eTeX_glue then @@; else if m>=eTeX_dim then begin case m of @/@@/ end; {there are no other cases} cur_val_level:=dimen_val; end else begin case m of input_line_no_code: cur_val:=line; badness_code: cur_val:=last_badness; @/@@/ end; {there are no other cases} @z %--------------------------------------- @x [26] m.424 l.8505 - e-TeX last_node_type cur_val_level:=cur_chr; @y if cur_chr=last_node_type_code then begin cur_val:=int_val; if (tail=head)or(mode=0) then cur_val:=-1; end else cur_val_level:=cur_chr; @z %--------------------------------------- % @x [26] m.424 l.8507 - e-TeX TeXXeT % case cur_chr of % @y % begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then % remove_end_M; % case cur_chr of % @z %--------------------------------------- @x [26] m.424 l.8513 - e-TeX last_node_type end; @y end; last_node_type_code: if (type(tail)<>math_node)or(subtype(tail)<>end_M_code) then if type(tail)<=unset_node then cur_val:=type(tail)+1 else cur_val:=unset_node+2; @z %--------------------------------------- % @x [26] m.424 l.8514 - e-TeX TeXXeT % end {there are no other cases} % @y % end; {there are no other cases} % if LR_temp<>null then insert_end_M; % end % @z %--------------------------------------- @x [26] m.424 l.8519 - e-TeX last_node_type glue_val: if last_glue<>max_halfword then cur_val:=last_glue; @y glue_val: if last_glue<>max_halfword then cur_val:=last_glue; last_node_type_code: cur_val:=last_node_type; @z %--------------------------------------- % FIXME might need work @x [26] m.427 l.8535 - e-TeX sparse arrays begin scan_eight_bit_int; case m of @y begin if (mlo_mem_stat_max) then begin cur_val_level:=sa_type(m); if cur_val_level255 then begin find_sa_element(cur_val_level,cur_val,false); if cur_ptr=null then if cur_val_level@; @z %--------------------------------------- @x [27] m.464 l.9129 - e-TeX basic @p function str_toks(@!b:pool_pointer):pointer; @y @p @t\4@>@@;@/ function str_toks(@!b:pool_pointer):pointer; @z %--------------------------------------- @x [27] m.465 l.9154 the_toks - e-TeX unexpanded @p function the_toks:pointer; @y @p function the_toks:pointer; label exit; @z %--------------------------------------- @x [27] m.465 l.9158 the_toks - e-TeX unexpanded begin get_x_token; scan_something_internal(tok_val,false); @y @!c:small_number; {value of |cur_chr|} begin @;@/ get_x_token; scan_something_internal(tok_val,false); @z %--------------------------------------- @x [27] m.465 l.9172 the_toks - e-TeX unexpanded end; @y exit:end; @z %--------------------------------------- @x [27] m.469 l.9223 - e-TeX basic othercases print_esc("jobname") @y @/@@/ othercases print_esc("jobname") @z %--------------------------------------- @x [27] m.470 l.9232 conv_toks - e-TeX basic @!c:number_code..job_name_code; {desired type of conversion} @y @!c:small_number; {desired type of conversion} @z %--------------------------------------- @x [27] m.471 l.9249 - e-TeX basic end {there are no other cases} @y @/@@/ end {there are no other cases} @z %--------------------------------------- @x [27] m.472 l.9265 - e-TeX basic end {there are no other cases} @y @/@@/ end {there are no other cases} @z %--------------------------------------- @x [27] m.478 l.9374 - e-TeX protected if cur_cmd<=max_command then goto done2; @y if cur_cmd>=call then if info(link(cur_chr))=protected_token then begin cur_cmd:=relax; cur_chr:=no_expand_flag; end; if cur_cmd<=max_command then goto done2; @z %--------------------------------------- @x [27] m.482 l.9422 read_toks - e-TeX read_line @p procedure read_toks(@!n:integer;@!r:pointer); @y @p procedure read_toks(@!n:integer;@!r:pointer;@!j:halfword); @z %--------------------------------------- @x [27] m.483 l.9448 - e-TeX read_line loop@+ begin get_token; @y @;@/ loop@+ begin get_token; @z %--------------------------------------- @x [28] m.487 l.9500 - e-TeX cond @d if_char_code=0 { `\.{\\if}' } @y @d unless_code=32 {amount added for `\.{\\unless}' prefix} @# @d if_char_code=0 { `\.{\\if}' } @z %--------------------------------------- @x [28] m.488 l.9555 - e-TeX cond if_test: case chr_code of @y if_test: begin if chr_code>=unless_code then print_esc("unless"); case chr_code mod unless_code of @z %--------------------------------------- @x [28] m.488 l.9572 - e-TeX cond othercases print_esc("if") endcases; @y @/@@/ othercases print_esc("if") endcases; end; @z %--------------------------------------- @x [28] m.494 l.9646 pass_text - e-TeX tracing done: scanner_status:=save_scanner_status; @y done: scanner_status:=save_scanner_status; if tracing_ifs>0 then show_cur_cmd_chr; @z %--------------------------------------- @x [28] m.496 l.9662 - e-TeX tracing_nesting begin p:=cond_ptr; if_line:=if_line_field(p); @y begin if if_stack[in_open]=cond_ptr then if_warning; {conditionals possibly not properly nested with files} p:=cond_ptr; if_line:=if_line_field(p); @z %--------------------------------------- @x [28] m.498 l.9699 conditional - e-TeX cond begin @;@+save_cond_ptr:=cond_ptr;this_if:=cur_chr;@/ @; @y @!is_unless:boolean; {was this if preceded by `\.{\\unless}' ?} begin if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr; @;@+save_cond_ptr:=cond_ptr; is_unless:=(cur_chr>=unless_code); this_if:=cur_chr mod unless_code;@/ @; if is_unless then b:=not b; @z %--------------------------------------- @x [28] m.501 l.9742 - e-TeX cond if_false_code: b:=false; @y if_false_code: b:=false; @/@@/ @z %--------------------------------------- @x [28] m.505 l.9781 - e-TeX sparse arrays begin scan_eight_bit_int; p:=box(cur_val); @y begin scan_register_num; fetch_box(p); @z %--------------------------------------- @x [28] m.510 l.9871 - e-TeX cond if cur_chr>if_limit then @y begin if tracing_ifs>0 then if tracing_commands<=1 then show_cur_cmd_chr; if cur_chr>if_limit then @z %--------------------------------------- @x [28] m.510 l.9882 - e-TeX cond end @y end; end @z %--------------------------------------- @x [29] m.536 l.10324 - e-TeX basic begin wlog(banner); @y begin wlog(eTeX_banner); @z %--------------------------------------- @x [29] m.536 l.10331 - e-TeX basic end @y if eTeX_ex then begin; wlog_cr; wlog('entering extended mode'); end; end @z %--------------------------------------- @x [30] m.581 l.11263 char_warning - e-TeX tracing begin if tracing_lost_chars>0 then @y var old_setting: integer; {saved value of |tracing_online|} begin if tracing_lost_chars>0 then begin old_setting:=tracing_online; if eTeX_ex and(tracing_lost_chars>1) then tracing_online:=1; @z %--------------------------------------- @x [30] m.581 l.11270 char_warning - e-TeX tracing end; @y tracing_online:=old_setting; end; end; @z %--------------------------------------- % @x [32] m.616 l.12238 - e-TeX TeXXeT % this is essentially the depth of |push| commands in the \.{DVI} output. % @y % this is essentially the depth of |push| commands in the \.{DVI} output. % % For mixed direction text (\TeXXeT) the current text direction is called % |cur_dir|. As the box being shipped out will never be used again and % soon be recycled, we can simply reverse any R-text (i.e., right-to-left) % segments of hlist nodes as well as complete hlist nodes embedded in such % segments. Moreover this can be done iteratively rather than recursively. % There are, however, two complications related to leaders that require % some additional bookkeeping: (1)~One and the same hlist node might be % used more than once (but never inside both L- and R-text); and % (2)~leader boxes inside hlists must be aligned with respect to the left % edge of the original hlist. % % A math node is changed into a kern node whenever the text direction % remains the same, it is replaced by an |edge_node| if the text direction % changes; the subtype of an an |hlist_node| inside R-text is changed to % |reversed| once its hlist has been reversed. % @!@^data structure assumptions@> % @z %--------------------------------------- % @x [32] m.616 l.12240 - e-TeX TeXXeT % @d synch_h==if cur_h<>dvi_h then % @y % @d reversed=min_quarterword+1 {subtype for an |hlist_node| whose hlist % has been reversed} % @d dlist=min_quarterword+2 {subtype for an |hlist_node| from display math mode} % @d left_to_right=0 % @d right_to_left=1 % @d reflected==1-cur_dir {the opposite of |cur_dir|} % @# % @d synch_h==if cur_h<>dvi_h then % @z %--------------------------------------- % @x [32] m.619 l.12300 hlist_out - e-TeX add_glue % @!g_order: glue_ord; {applicable order of infinity for glue} % @y % @z %--------------------------------------- % @x [32] m.619 l.12308 hlist_out - e-TeX TeXXeT % @!edge:scaled; {left edge of sub-box, or right edge of leader space} % @y % @!edge:scaled; {right edge of sub-box or leader space} % @!prev_p:pointer; {one step behind |p|} % @z %--------------------------------------- % @x [32] m.619 l.12309 hlist_out - e-TeX add_glue % @!glue_temp:real; {glue value before rounding} % begin this_box:=temp_ptr; g_order:=glue_order(this_box); % @y % begin this_box:=temp_ptr; % @z %--------------------------------------- % @x [32] m.619 l.12315 hlist_out - e-TeX TeXXeT % save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; left_edge:=cur_h; % @y % save_loc:=dvi_offset+dvi_ptr; base_line:=cur_v; % prev_p:=this_box+list_offset; % if eTeX_ex then % begin @; % if subtype(this_box)=dlist then % if cur_dir=right_to_left then % begin cur_dir:=left_to_right; cur_h:=cur_h-width(this_box); % end % else subtype(this_box):=min_quarterword; % if (cur_dir=right_to_left)and(subtype(this_box)<>reversed) then % @; % end; % left_edge:=cur_h; % @z %--------------------------------------- % @x [32] m.619 l.12318 hlist_out - e-TeX TeXXeT % prune_movements(save_loc); % @y % if eTeX_ex then % begin @; % if subtype(this_box)=dlist then cur_dir:=right_to_left; % end; % prune_movements(save_loc); % @z %--------------------------------------- % @x [32] m.620 l.12337 - e-TeX TeXXeT % p:=link(p); % @y % prev_p:=link(prev_p); {N.B.: not |prev_p:=p|, |p| might be |lig_trick|} % p:=link(p); % @z %--------------------------------------- % @x [32] m.622 l.12362 - e-TeX TeXXeT % kern_node,math_node:cur_h:=cur_h+width(p); % @y % kern_node:cur_h:=cur_h+width(p); % math_node:begin if eTeX_ex then % @; % cur_h:=cur_h+width(p); % end; % @z %--------------------------------------- % @x [32] m.622 l.12364 - e-TeX TeXXeT % othercases do_nothing % @y % @/@@; % othercases do_nothing % @z %--------------------------------------- % @x [32] m.622 l.12369 - e-TeX TeXXeT % next_p:p:=link(p); % @y % next_p:prev_p:=p; p:=link(p); % @z %--------------------------------------- % @x [32] m.623 l.12376 - e-TeX TeXXeT % temp_ptr:=p; edge:=cur_h; % @y % temp_ptr:=p; edge:=cur_h+width(p); % if cur_dir=right_to_left then cur_h:=edge; % @z %--------------------------------------- % @x [32] m.623 l.12379 - e-TeX TeXXeT % cur_h:=edge+width(p); cur_v:=base_line; % @y % cur_h:=edge; cur_v:=base_line; % @z %--------------------------------------- % @x [32] m.625 l.12401 - e-TeX add_glue % begin if g_sign=stretching then % begin if stretch_order(g)=g_order then % begin vet_glue(float(glue_set(this_box))*stretch(g)); % @^real multiplication@> % rule_wd:=rule_wd+round(glue_temp); % end; % end % else if shrink_order(g)=g_order then % begin vet_glue(float(glue_set(this_box))*shrink(g)); % rule_wd:=rule_wd-round(glue_temp); % end; % end; % @y % add_glue(rule_wd); % @z %--------------------------------------- % @x [32] m.626 l.12428 - e-TeX TeXXeT % edge:=cur_h+rule_wd; lx:=0; % @y % if cur_dir=right_to_left then cur_h:=cur_h-10; % edge:=cur_h+rule_wd; lx:=0; % @z %--------------------------------------- % @x [32] m.626 l.12434 - e-TeX TeXXeT % cur_h:=edge-10; goto next_p; % @y % if cur_dir=right_to_left then cur_h:=edge % else cur_h:=edge-10; % goto next_p; % @z %--------------------------------------- % @x [32] m.628 l.12473 - e-TeX TeXXeT % synch_h; save_h:=dvi_h; temp_ptr:=leader_box; % @y % synch_h; save_h:=dvi_h; temp_ptr:=leader_box; % if cur_dir=right_to_left then cur_h:=cur_h+leader_wd; % @z %--------------------------------------- % @x [32] m.629 l.12489 vlist_out - e-TeX add_glue % @!g_order: glue_ord; {applicable order of infinity for glue} % @y % @z %--------------------------------------- % @x [32] m.629 l.12498 vlist_out - e-TeX add_glue % @!glue_temp:real; {glue value before rounding} % begin this_box:=temp_ptr; g_order:=glue_order(this_box); % @y % begin this_box:=temp_ptr; % @z %--------------------------------------- % @x [32] m.632 l.12544 - e-TeX TeXXeT % cur_h:=left_edge+shift_amount(p); {shift the box right} % @y % if cur_dir=right_to_left then cur_h:=left_edge-shift_amount(p) % else cur_h:=left_edge+shift_amount(p); {shift the box right} % @z %--------------------------------------- % @x [32] m.633 l.12556 - e-TeX TeXXeT % begin synch_h; synch_v; % dvi_out(put_rule); dvi_four(rule_ht); dvi_four(rule_wd); % @y % begin if cur_dir=right_to_left then cur_h:=cur_h-rule_wd; % synch_h; synch_v; % dvi_out(put_rule); dvi_four(rule_ht); dvi_four(rule_wd); % cur_h:=left_edge; % @z %--------------------------------------- % @x [32] m.634 l.12564 - e-TeX add_glue % begin if g_sign=stretching then % begin if stretch_order(g)=g_order then % begin vet_glue(float(glue_set(this_box))*stretch(g)); % @^real multiplication@> % rule_ht:=rule_ht+round(glue_temp); % end; % end % else if shrink_order(g)=g_order then % begin vet_glue(float(glue_set(this_box))*shrink(g)); % rule_ht:=rule_ht-round(glue_temp); % end; % end; % @y % add_glue(rule_ht); % @z %--------------------------------------- % @x [32] m.637 l.12619 - e-TeX TeXXeT % begin cur_h:=left_edge+shift_amount(leader_box); synch_h; save_h:=dvi_h;@/ % @y % begin if cur_dir=right_to_left then % cur_h:=left_edge-shift_amount(leader_box) % else cur_h:=left_edge+shift_amount(leader_box); % synch_h; save_h:=dvi_h;@/ % @z %--------------------------------------- % @x [32] m.638 l.12656 ship_out - e-TeX TeXXeT % @; % @y % @; % if eTeX_ex then @; % @z %--------------------------------------- % @x [33] m.649 l.12876 hpack - e-TeX TeXXeT % h:=0; @; % @y % h:=0; @; % if TeXXeT_en then @; % @z %--------------------------------------- % @x [33] m.649 l.12886 hpack - e-TeX TeXXeT % exit: hpack:=r; % @y % exit: if TeXXeT_en then @; % hpack:=r; % @z %--------------------------------------- % @x [33] m.651 l.12910 - e-TeX TeXXeT % kern_node,math_node: x:=x+width(p); % @y % kern_node: x:=x+width(p); % math_node: begin x:=x+width(p); % if TeXXeT_en then @; % end; % @z %--------------------------------------- @x [34] m.687 l.13480 - e-TeX middle \TeX's \.{\\left} and \.{\\right}. The |nucleus| of such noads is @y \TeX's \.{\\left} and \.{\\right} as well as \eTeX's \.{\\middle}. The |nucleus| of such noads is @z %--------------------------------------- @x [34] m.687 l.13497 - e-TeX middle @d delimiter==nucleus {|delimiter| field in left and right noads} @y @d delimiter==nucleus {|delimiter| field in left and right noads} @d middle_noad==1 {|subtype| of right noad representing \.{\\middle}} @z %--------------------------------------- @x [34] m.696 l.13670 - e-TeX middle right_noad: begin print_esc("right"); print_delimiter(delimiter(p)); end; end; if subtype(p)<>normal then if subtype(p)=limits then print_esc("limits") else print_esc("nolimits"); if type(p)normal then if subtype(p)=limits then print_esc("limits") else print_esc("nolimits"); print_subsidiary_data(nucleus(p),"."); end; @z %--------------------------------------- @x [36] m.727 l.14268 - e-TeX middle done_with_noad: r:=q; r_type:=type(r); @y done_with_noad: r:=q; r_type:=type(r); if r_type=right_noad then begin r_type:=left_noad; cur_style:=style; @; end; @z %--------------------------------------- @x [36] m.760 l.14929 - e-TeX middle r_type:=t; @y if type(q)=right_noad then t:=open_noad; r_type:=t; @z %--------------------------------------- @x [36] m.762 l.14970 make_left_right - e-TeX middle begin if style; @z %--------------------------------------- @x [37] m.785 l.15461 align_peek - e-TeX protected begin restart: align_state:=1000000; @; @y begin restart: align_state:=1000000; repeat get_x_or_protected; until cur_cmd<>spacer; @z %--------------------------------------- @x [37] m.791 l.15572 fin_col - e-TeX protected align_state:=1000000; @; @y align_state:=1000000; repeat get_x_or_protected; until cur_cmd<>spacer; @z %--------------------------------------- % @x [37] m.807 l.15834 - e-TeX TeXXeT % begin type(q):=hlist_node; width(q):=width(p); % @y % begin type(q):=hlist_node; width(q):=width(p); % if nest[nest_ptr-1].mode_field=mmode then subtype(q):=dlist; {for |ship_out|} % @z %--------------------------------------- % @x [37] m.808 l.15852 - e-TeX TeXXeT % n:=span_count(r); t:=width(s); w:=t; u:=hold_head; % @y % n:=span_count(r); t:=width(s); w:=t; u:=hold_head; % subtype(r):=min_quarterword; {for |ship_out|} % @z %--------------------------------------- @x [38] m.814 l.15975 - e-TeX penalties There is one explicit parameter: |final_widow_penalty| is the amount of additional penalty to be inserted before the final line of the paragraph. @y There is one explicit parameter: |d| is true for partial paragraphs preceding display math mode; in this case the amount of additional penalty inserted before the final line is |display_widow_penalty| instead of |widow_penalty|. @z %--------------------------------------- @x [38] m.815 l.16002 line_break - e-TeX penalties procedure line_break(@!final_widow_penalty:integer); @y procedure line_break(@!d:boolean); @z %--------------------------------------- @x [38] m.815 l.16012 - e-TeX basic end; @y end; @# @t\4@>@ @z %--------------------------------------- @x [38] m.816 l.16032 - e-TeX last_line_fit final_par_glue:=new_param_glue(par_fill_skip_code); link(tail):=final_par_glue; @y final_par_glue:=new_param_glue(par_fill_skip_code); link(tail):=final_par_glue; last_line_fill:=link(tail); @z %--------------------------------------- @x [38] m.819 l.16097 - e-TeX last_line_fit @d active_node_size=3 {number of words in active nodes} @y @d active_node_size_normal=3 {number of words in normal active nodes} @z %--------------------------------------- % FIXME might need fixes; TeX has 6 backgrounds % Omega has 7. Why the difference? @x [38] m.827 l.16260 - e-TeX last_line_fit background[7]:=shrink(q)+shrink(r); @y background[7]:=shrink(q)+shrink(r); @; @z %--------------------------------------- @x [38] m.829 l.16311 try_break - e-TeX last_line_fit label exit,done,done1,continue,deactivate; @y label exit,done,done1,continue,deactivate,found,not_found; @z %--------------------------------------- @x [38] m.845 l.16603 - e-TeX last_line_fit total_demerits(q):=minimal_demerits[fit_class]; @y total_demerits(q):=minimal_demerits[fit_class]; if do_last_line_fit then @; @z %--------------------------------------- @x [38] m.846 l.16616 - e-TeX last_line_fit print(" t="); print_int(total_demerits(q)); @y print(" t="); print_int(total_demerits(q)); if do_last_line_fit then @; @z %--------------------------------------- @x [38] m.851 l.16715 - e-TeX last_line_fit if (b>inf_bad)or(pi=eject_penalty) then @y if do_last_line_fit then @; found: if (b>inf_bad)or(pi=eject_penalty) then @z %--------------------------------------- @x [38] m.852 l.16739 - e-TeX last_line_fit begin b:=0; fit_class:=decent_fit; {infinite stretch} @y begin if do_last_line_fit then begin if cur_p=null then {the last line of a paragraph} @; shortfall:=0; end; b:=0; fit_class:=decent_fit; {infinite stretch} @z %--------------------------------------- @x [38] m.855 l.16796 - e-TeX last_line_fit best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l; @y best_place[fit_class]:=break_node(r); best_pl_line[fit_class]:=l; if do_last_line_fit then @; @z %--------------------------------------- @x [39] m.863 l.16969 - e-TeX last_line_fit end;@+tats@/ @y end;@+tats@/ if do_last_line_fit then @; @z %--------------------------------------- @x [39] m.864 l.16980 - e-TeX last_line_fit line_number(q):=prev_graf+1; total_demerits(q):=0; link(active):=q; @y line_number(q):=prev_graf+1; total_demerits(q):=0; link(active):=q; if do_last_line_fit then @; @z %--------------------------------------- % @x [39] m.866 l.17030 - e-TeX TeXXeT % math_node: begin auto_breaking:=(subtype(cur_p)=after); kern_break; % @y % math_node: begin if subtype(cur_p); % @z %--------------------------------------- % @x [39] m.880 l.17276 - e-TeX TeXXeT % @; % @y % if TeXXeT_en then % @; % @; % if TeXXeT_en then @; % @z %--------------------------------------- % @x [39] m.881 l.17299 - e-TeX TeXXeT % else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0; % @y % else if type(q)=kern_node then width(q):=0 % else if type(q)=math_node then % begin width(q):=0; % if TeXXeT_en then @; % end; % @z %--------------------------------------- % FIXME possible conflict @x [39] m.890 l.17395 - e-TeX penalties if passive_pen_inter(cur_p)<>0 then pen:=passive_pen_inter(cur_p) else pen:=inter_line_penalty; if cur_line=prev_graf+1 then pen:=pen+club_penalty; if cur_line+2=best_line then pen:=pen+final_widow_penalty; @y q:=inter_line_penalties_ptr; if q<>null then begin r:=cur_line; if r>penalty(q) then r:=penalty(q); pen:=penalty(q+r); end else begin if passive_pen_inter(cur_p)<>0 then pen:=passive_pen_inter(cur_p) else pen:=inter_line_penalty; end; q:=club_penalties_ptr; if q<>null then begin r:=cur_line-prev_graf; if r>penalty(q) then r:=penalty(q); pen:=pen+penalty(q+r); end else if cur_line=prev_graf+1 then pen:=pen+club_penalty; if d then q:=display_widow_penalties_ptr else q:=widow_penalties_ptr; if q<>null then begin r:=best_line-cur_line-1; if r>penalty(q) then r:=penalty(q); pen:=pen+penalty(q+r); end else if cur_line+2=best_line then if d then pen:=pen+display_widow_penalty else pen:=pen+widow_penalty; @z %--------------------------------------- @x [40] m.891 l.17460 - e-TeX hyph_codes cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf; @y cur_lang:=init_cur_lang; l_hyf:=init_l_hyf; r_hyf:=init_r_hyf; set_hyph_index; @z %--------------------------------------- @x [40] m.896 l.17529 - e-TeX hyph_codes if lc_code(c)<>0 then if (lc_code(c)=c)or(uc_hyph>0) then goto done2 @y set_lc_code(c); if hc[0]<>0 then if (hc[0]=c)or(uc_hyph>0) then goto done2 @z %--------------------------------------- @x [40] m.897 l.17546 - e-TeX hyph_codes if lc_code(c)=0 then goto done3; if lc_code(c)>max_hyph_char then goto done3; if hn=63 then goto done3; hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c); hyf_bchar:=non_char; @y set_lc_code(c); if hc[0]=0 then goto done3; if lc_code(c)>max_hyph_char then goto done3; if hn=63 then goto done3; hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=hc[0]; hyf_bchar:=non_char; @z %--------------------------------------- @x [40] m.898 l.17572 - e-TeX hyph_codes if lc_code(c)=0 then goto done3; if lc_code(c)>max_hyph_char then goto done3; if j=63 then goto done3; incr(j); hu[j]:=c; hc[j]:=lc_code(c);@/ @y set_lc_code(c); if hc[0]=0 then goto done3; if lc_code(c)>max_hyph_char then goto done3; if j=63 then goto done3; incr(j); hu[j]:=c; hc[j]:=hc[0];@/ @z %--------------------------------------- @x [42] m.934 l.18211 new_hyph_exceptions - e-TeX hyph_codes label reswitch, exit, found, not_found; @y label reswitch, exit, found, not_found, not_found1; @z %--------------------------------------- @x [42] m.934 l.18221 new_hyph_exceptions - e-TeX hyph_codes set_cur_lang; @y set_cur_lang; @!init if trie_not_ready then begin hyph_index:=0; goto not_found1; end; tini@/ set_hyph_index; not_found1: @z %--------------------------------------- @x [42] m.937 l.18253 - e-TeX hyph_codes else begin if lc_code(cur_chr)=0 then @y else begin set_lc_code(cur_chr); if hc[0]=0 then @z %--------------------------------------- @x [42] m.937 l.18261 - e-TeX hyph_codes begin incr(n); hc[n]:=lc_code(cur_chr); @y begin incr(n); hc[n]:=hc[0]; @z %--------------------------------------- @x [43] m.952 l.18549 - e-TeX hyph_codes trie_root:=compress_trie(trie_root); {identify equivalent subtries} @y hyph_root:=compress_trie(hyph_root); trie_root:=compress_trie(trie_root); {identify equivalent subtries} @z %--------------------------------------- @x [43] m.958 l.18637 - e-TeX hyph_codes if trie_root=0 then {no patterns were given} @y if trie_max=0 then {no patterns were given} @z %--------------------------------------- @x [43] m.958 l.18641 - e-TeX hyph_codes else begin trie_fix(trie_root); {this fixes the non-holes in |trie|} @y else begin if hyph_root>0 then trie_fix(hyph_root); if trie_root>0 then trie_fix(trie_root); {this fixes the non-holes in |trie|} @z %--------------------------------------- @x [43] m.960 l.18684 new_patterns - e-TeX hyph_codes brace@>; @y brace@>; if saving_hyph_codes>0 then @; @z %--------------------------------------- @x [43] m.966 l.18791 init_trie - e-TeX hyph_codes @; @y if hyph_root<>0 then @; @; @z %--------------------------------------- @x [44] m.968 l.18807 - e-TeX saved_items whenever this is possible without backspacing. @y whenever this is possible without backspacing. When the second argument |s| is |false| the deleted nodes are destroyed, otherwise they are collected in a list starting at |split_disc|. @z %--------------------------------------- @x [44] m.968 l.18814 prune_page_top - e-TeX saved_items @p function prune_page_top(@!p:pointer):pointer; {adjust top after page break} var prev_p:pointer; {lags one step behind |p|} @!q:pointer; {temporary variable for list manipulation} @y @p function prune_page_top(@!p:pointer;@!s:boolean):pointer; {adjust top after page break} var prev_p:pointer; {lags one step behind |p|} @!q,@!r:pointer; {temporary variables for list manipulation} @z %--------------------------------------- @x [44] m.968 l.18825 prune_page_top - e-TeX saved_items link(prev_p):=p; flush_node_list(q); @y link(prev_p):=p; if s then begin if split_disc=null then split_disc:=q@+else link(r):=q; r:=q; end else flush_node_list(q); @z %--------------------------------------- @x [44] m.977 l.18992 vsplit - e-TeX marks, sparse arrays @p function vsplit(@!n:eight_bits; @!h:scaled):pointer; @y @p @t\4@>@@; function vsplit(@!n:halfword; @!h:scaled):pointer; @z %--------------------------------------- % FIXME incompatible? @x [44] m.977 l.18998 vsplit - e-TeX sparse arrays begin v:=box(n); vdir:=box_dir(v); @y begin cur_val:=n; fetch_box(v); vdir:=box_dir(v); @z %--------------------------------------- % FIXME: how to detach this from sparse arrays? @x [44] m.977 l.18999 vsplit - e-TeX marks, saved_items if split_first_mark<>null then @y flush_node_list(split_disc); split_disc:=null; if sa_mark<>null then if do_marks(vsplit_init,0,sa_mark) then sa_mark:=null; if split_first_mark<>null then @z %--------------------------------------- @x [44] m.977 l.19007 vsplit - e-TeX saved_items q:=prune_page_top(q); p:=list_ptr(v); free_node(v,box_node_size); @y q:=prune_page_top(q,saving_vdiscards>0); p:=list_ptr(v); free_node(v,box_node_size); @z %--------------------------------------- % FIXME might be incompatible? @x [44] m.977 l.19008 vsplit - e-TeX sparse arrays if q=null then set_equiv(box_base+n,null) {the |eq_level| of the box stays the same} else set_equiv(box_base+n,vpack(q,natural)); @y if q<>null then q:=vpack(q,natural); change_box(q); {the |eq_level| of the box stays the same} @z %--------------------------------------- @x [44] m.979 l.19033 - e-TeX marks if split_first_mark=null then @y if mark_class(p)<>0 then @ else if split_first_mark=null then @z %--------------------------------------- @x [45] m.982 l.19167 - e-TeX last_node_type The variables |last_penalty| and |last_kern| are similar. And @y The variables |last_penalty|, |last_kern|, and |last_node_type| are similar. And @z %--------------------------------------- @x [45] m.982 l.19180 - e-TeX last_node_type @!last_kern:scaled; {used to implement \.{\\lastkern}} @y @!last_kern:scaled; {used to implement \.{\\lastkern}} @!last_node_type:integer; {used to implement \.{\\lastnodetype}} @z %--------------------------------------- @x [45] m.991 l.19317 - e-TeX last_node_type last_glue:=max_halfword; last_penalty:=0; last_kern:=0; @y last_glue:=max_halfword; last_penalty:=0; last_kern:=0; last_node_type:=-1; @z %--------------------------------------- @x [45] m.996 l.19384 - e-TeX last_node_type last_penalty:=0; last_kern:=0; @y last_penalty:=0; last_kern:=0; last_node_type:=type(p)+1; @z %--------------------------------------- @x [45] m.999 l.19421 - e-TeX saved_items link(contrib_head):=link(p); link(p):=null; flush_node_list(p) @y link(contrib_head):=link(p); link(p):=null; if saving_vdiscards>0 then begin if page_disc=null then page_disc:=p@+else link(tail_page_disc):=p; tail_page_disc:=p; end else flush_node_list(p) @z %--------------------------------------- % FIXME: sparse arrays? @x [45] m.1012 l.19661 fire_up - e-TeX marks if bot_mark<>null then @y if sa_mark<>null then if do_marks(fire_up_init,0,sa_mark) then sa_mark:=null; if bot_mark<>null then @z %--------------------------------------- @x [45] m.1012 l.19669 fire_up - e-TeX marks if (top_mark<>null)and(first_mark=null) then @y if sa_mark<>null then if do_marks(fire_up_done,0,sa_mark) then sa_mark:=null; if (top_mark<>null)and(first_mark=null) then @z %--------------------------------------- @x [45] m.1014 l.19706 - e-TeX marks else if type(p)=mark_node then @0 then @ else @null then eq_define(par_shape_loc,shape_ref,null); @y if par_shape_ptr<>null then eq_define(par_shape_loc,shape_ref,null); if inter_line_penalties_ptr<>null then eq_define(inter_line_penalties_loc,shape_ref,null); @z %--------------------------------------- % FIXME incompatible? % @x [47] m.1071 l.20718 - e-TeX sparse arrays % |box_flag+255| represent `\.{\\setbox0}' through `\.{\\setbox255}'; % codes |box_flag+256| through |box_flag+511| represent `\.{\\global\\setbox0}' % through `\.{\\global\\setbox255}'; % code |box_flag+512| represents `\.{\\shipout}'; and codes |box_flag+513| % through |box_flag+515| represent `\.{\\leaders}', `\.{\\cleaders}', % @y % |global_box_flag-1| represent `\.{\\setbox0}' through `\.{\\setbox32767}'; % codes |global_box_flag| through |ship_out_flag-1| represent % `\.{\\global\\setbox0}' through `\.{\\global\\setbox32767}'; % code |ship_out_flag| represents `\.{\\shipout}'; and codes |leader_flag| % through |leader_flag+2| represent `\.{\\leaders}', `\.{\\cleaders}', % @z %--------------------------------------- @x [47] m.1071 l.20732 - e-TeX sparse arrays @d ship_out_flag==box_flag+(number_regs+number_regs) {context code for `\.{\\shipout}'} @y @d global_box_flag==box_flag+(number_regs+number_regs) {context code for `\.{\\global\\setbox0}'} @d ship_out_flag==global_box_flag+1 {context code for `\.{\\shipout}'} @z %--------------------------------------- @x [47] m.1075 l.20815 box_end - e-TeX sparse arrays var p:pointer; {|ord_noad| for new box in math mode} @y var p:pointer; {|ord_noad| for new box in math mode} @!a:small_number; {global prefix} @z %--------------------------------------- % FIXME: might not work this way @x [47] m.1077 l.20853 - e-TeX sparse arrays if box_context; % @y % begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then % remove_end_M; % if (type(tail)=hlist_node)or(type(tail)=vlist_node) then % @; % if LR_temp<>null then insert_end_M; % end; % @z %--------------------------------------- @x [47] m.1082 l.20935 - e-TeX sparse arrays begin scan_eight_bit_int; n:=cur_val; @y begin scan_register_num; n:=cur_val; @z %--------------------------------------- % @x [47] m.1096 l.21119 - e-TeX penalties, TeXXeT % else line_break(widow_penalty); % @y % else line_break(false); % if LR_save<>null then % begin flush_list(LR_save); LR_save:=null; % end; % @z %--------------------------------------- @x [47] m.1101 l.21175 make_mark - e-TeX marks begin p:=scan_toks(false,true); p:=get_node(small_node_size); @y @!c:halfword; {the mark class} begin if cur_chr=0 then c:=0 else begin scan_register_num; c:=cur_val; end; p:=scan_toks(false,true); p:=get_node(small_node_size); mark_class(p):=c; @z %--------------------------------------- % @x [47] m.1105 l.21203 - e-TeX TeXXeT % will be deleted, if present. % @y % will be deleted, if present. % A final \.{\\endM} node is temporarily removed. % @z %--------------------------------------- % @x [47] m.1105 l.21213 delete_last - e-TeX TeXXeT % else begin if not is_char_node(tail) then if type(tail)=cur_chr then % @y % else begin if not is_char_node(tail) then % begin if (type(tail)=math_node)and(subtype(tail)=end_M_code) then % remove_end_M; % if type(tail)=cur_chr then % @z %--------------------------------------- % @x [47] m.1105 l.21224 delete_last - e-TeX TeXXeT % end; % @y % if LR_temp<>null then insert_end_M; % end; % end; % @z %--------------------------------------- @x [47] m.1108 l.21262 - e-TeX saved_items un_vbox: if chr_code=copy_code then print_esc("unvcopy") @y un_vbox: if chr_code=copy_code then print_esc("unvcopy") @@/ @z %--------------------------------------- @x [47] m.1110 l.21272 unpackage - e-TeX saved_items label exit; @y label done, exit; @z %--------------------------------------- @x [47] m.1110 l.21275 unpackage - e-TeX saved_items, sparse arrays begin c:=cur_chr; scan_eight_bit_int; p:=box(cur_val); @y begin if cur_chr>copy_code then @; c:=cur_chr; scan_register_num; fetch_box(p); @z %--------------------------------------- % FIXME: might be incompatible @x [47] m.1110 l.21287 unpackage - e-TeX sparse arrays else begin link(tail):=list_ptr(p); set_equiv(box_base+cur_val,null); @y else begin link(tail):=list_ptr(p); change_box(null); @z %--------------------------------------- @x [47] m.1110 l.21290 unpackage - e-TeX saved_items while link(tail)<>null do tail:=link(tail); @y done: while link(tail)<>null do tail:=link(tail); @z %--------------------------------------- % @x [47] m.1130 l.21562 - e-TeX TeXXeT % vmode+halign,hmode+valign:init_align; % @y % vmode+halign:init_align; % hmode+valign:@@; init_align; % @z %--------------------------------------- % @x [48] m.1138 l.21629 init_math - e-TeX TeXXeT % procedure init_math; % label reswitch,found,not_found,done; % var w:scaled; {new or partial |pre_display_size|} % @y % @t\4@>@@; % procedure init_math; % label reswitch,found,not_found,done; % var w:scaled; {new or partial |pre_display_size|} % @!j:pointer; {prototype box for display} % @!x:integer; {new |pre_display_direction|} % @z %--------------------------------------- % @x [48] m.1145 l.21687 - e-TeX TeXXeT, penalties % begin if head=tail then {`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'} % begin pop_nest; w:=-max_dimen; % end % else begin line_break(display_widow_penalty);@/ % @y % begin j:=null; w:=-max_dimen; % if head=tail then {`\.{\\noindent\$\$}' or `\.{\$\${ }\$\$}'} % @ % else begin line_break(true);@/ % @z %--------------------------------------- % @x [48] m.1145 l.21700 - e-TeX TeXXeT % eq_word_define(dimen_base+pre_display_size_code,w); % @y % eq_word_define(dimen_base+pre_display_size_code,w); % LR_box:=j; % if eTeX_ex then eq_word_define(int_base+pre_display_direction_code,x); % @z %--------------------------------------- % @x [48] m.1146 l.21708 - e-TeX TeXXeT % v:=shift_amount(just_box)+2*quad(cur_font); w:=-max_dimen; % p:=list_ptr(just_box); % @y % @; % @z %--------------------------------------- % @x [48] m.1146 l.21723 - e-TeX TeXXeT % done: % @y % done: % @ % @z %--------------------------------------- % @x [48] m.1147 l.21734 - e-TeX TeXXeT % kern_node,math_node: d:=width(p); % @y % kern_node: d:=width(p); % @t\4@>@@; % @z %--------------------------------------- @x [48] m.1185 l.22243 - e-TeX middle if type(q)<>left_noad then confusion("right"); @:this can't happen right}{\quad right@> info(numerator(incompleat_noad)):=link(q); link(q):=incompleat_noad; link(incompleat_noad):=p; @y if (type(q)<>left_noad)or(delim_ptr=null) then confusion("right"); @:this can't happen right}{\quad right@> info(numerator(incompleat_noad)):=link(delim_ptr); link(delim_ptr):=incompleat_noad; link(incompleat_noad):=p; @z %--------------------------------------- @x [48] m.1189 l.22288 - e-TeX middle else print_esc("right"); @y @/@@/ else print_esc("right"); @z %--------------------------------------- @x [48] m.1191 l.22297 math_left_right - e-TeX middle begin t:=cur_chr; if (t=right_noad)and(cur_group<>math_left_group) then @y @!q:pointer; {resulting mlist} begin t:=cur_chr; if (t<>left_noad)and(cur_group<>math_left_group) then @z %--------------------------------------- % FIXME: might be incompatible? @x [48] m.1191 l.22302 math_left_right - e-TeX middle if t=left_noad then begin push_math(math_left_group); link(head):=p; tail:=p; end else begin p:=fin_mlist(p); @; {end of |math_left_group|} @y if t=middle_noad then begin type(p):=right_noad; subtype(p):=middle_noad; end; if t=left_noad then q:=p else begin q:=fin_mlist(p); @; {end of |math_left_group|} end; if t<>right_noad then begin push_math(math_left_group); link(head):=q; tail:=p; delim_ptr:=p; end else begin @z %--------------------------------------- @x [48] m.1191 l.22308 math_left_right - e-TeX middle info(nucleus(tail)):=p; @y info(nucleus(tail)):=q; @z %--------------------------------------- @x [48] m.1192 l.22316 - e-TeX middle print_err("Extra "); print_esc("right"); @.Extra \\right.@> help1("I'm ignoring a \right that had no matching \left."); @y print_err("Extra "); if t=middle_noad then begin print_esc("middle"); @.Extra \\middle.@> help1("I'm ignoring a \middle that had no matching \left."); end else begin print_esc("right"); @.Extra \\right.@> help1("I'm ignoring a \right that had no matching \left."); end; @z %--------------------------------------- % @x [48] m.1194 l.22331 after_math - e-TeX TeXXeT % procedure after_math; % @y % @t\4@>@@; % procedure after_math; % @z %--------------------------------------- % @x [48] m.1194 l.22338 after_math - e-TeX TeXXeT % begin danger:=false; % @y % begin danger:=false; % @; % @z %--------------------------------------- % @x [48] m.1194 l.22345 after_math - e-TeX TeXXeT % mlist_to_hlist; a:=hpack(link(temp_head),natural); % @y % mlist_to_hlist; a:=hpack(link(temp_head),natural); % subtype(a):=dlist; % @z %--------------------------------------- % @x [48] m.1194 l.22348 after_math - e-TeX TeXXeT % danger:=false; % @y % danger:=false; % @; % @z %--------------------------------------- % @x [48] m.1199 l.22435 - e-TeX TeXXeT % w:=width(b); z:=display_width; s:=display_indent; % @y % w:=width(b); z:=display_width; s:=display_indent; % if pre_display_direction<0 then s:=-s-z; % @z %--------------------------------------- % @x [48] m.1199 l.22450 - e-TeX TeXXeT % resume_after_display % @y % @; % resume_after_display % @z %--------------------------------------- % @x [48] m.1202 l.22492 - e-TeX TeXXeT % d:=half(z-w); % @y % subtype(b):=dlist; % d:=half(z-w); % @z %--------------------------------------- % @x [48] m.1203 l.22513 - e-TeX TeXXeT % begin shift_amount(a):=s; append_to_vlist(a); % @y % begin app_display(j,a,0); % @z %--------------------------------------- % @x [48] m.1204 l.22528 - e-TeX TeXXeT % shift_amount(b):=s+d; append_to_vlist(b) % @y % app_display(j,b,d) % @z %--------------------------------------- % @x [48] m.1205 l.22533 - e-TeX TeXXeT % shift_amount(a):=s+z-width(a); % append_to_vlist(a); % @y % app_display(j,a,z-width(a)); % @z %--------------------------------------- % @x [48] m.1206 l.22552 - e-TeX TeXXeT % pop_nest; % @y % flush_node_list(LR_box); % pop_nest; % @z %--------------------------------------- @x [49] m.1208 l.22577 - e-TeX protected control sequence can be defined to be `\.{\\long}' or `\.{\\outer}', and it might or might not be expanded. The prefixes `\.{\\global}', `\.{\\long}', @y control sequence can be defined to be `\.{\\long}', `\.{\\protected}', or `\.{\\outer}', and it might or might not be expanded. The prefixes `\.{\\global}', `\.{\\long}', `\.{\\protected}', @z %--------------------------------------- @x [49] m.1209 l.22603 - e-TeX protected else print_esc("global"); @y @/@@/ else print_esc("global"); @z %--------------------------------------- @x [49] m.1211 l.22665 prefixed_command - e-TeX tracing @; @y @; if tracing_commands>2 then if eTeX_ex then show_cur_cmd_chr; @z %--------------------------------------- @x [49] m.1213 l.22686 - e-TeX protected if (cur_cmd<>def)and(a mod 4<>0) then @y if a>=8 then begin j:=protected_token; a:=a-8; end else j:=0; if (cur_cmd<>def)and((a mod 4<>0)or(j<>0)) then @z %--------------------------------------- @x [49] m.1218 l.22749 - e-TeX protected q:=scan_toks(true,e); define(p,call+(a mod 4),def_ref); @y q:=scan_toks(true,e); if j<>0 then begin q:=get_avail; info(q):=j; link(q):=link(def_ref); link(def_ref):=q; end; define(p,call+(a mod 4),def_ref); @z %--------------------------------------- @x [49] m.1224 l.22840 - e-TeX sparse arrays othercases begin scan_eight_bit_int; @y othercases begin scan_register_num; if cur_val>255 then begin j:=n-count_def_code; {|int_val..box_val|} if j>mu_val then j:=tok_val; {|int_val..mu_val| or |tok_val|} find_sa_element(j,cur_val,true); add_sa_ref(cur_ptr); if j=tok_val then j:=toks_register@+else j:=register; define(p,j,cur_ptr); end else @z %--------------------------------------- @x [49] m.1225 l.22853 - e-TeX read_line read_to_cs: begin scan_int; n:=cur_val; @y read_to_cs: begin j:=cur_chr; scan_int; n:=cur_val; @z %--------------------------------------- @x [49] m.1225 l.22861 - e-TeX read_line p:=cur_cs; read_toks(n,p); define(p,call,cur_val); @y p:=cur_cs; read_toks(n,p,j); define(p,call,cur_val); @z %--------------------------------------- @x [49] m.1226 l.22870 - e-TeX sparse arrays if cur_cmd=toks_register then begin scan_eight_bit_int; p:=toks_base+cur_val; end else p:=cur_chr; {|p=every_par_loc| or |output_routine_loc| or \dots} @y e:=false; {just in case, will be set |true| for sparse array elements} if cur_cmd=toks_register then if cur_chr=mem_bot then begin scan_register_num; if cur_val>255 then begin find_sa_element(tok_val,cur_val,true); cur_chr:=cur_ptr; e:=true; end else cur_chr:=toks_base+cur_val; end else e:=true; p:=cur_chr; {|p=every_par_loc| or |output_routine_loc| or \dots} @z %--------------------------------------- @x [49] m.1226 l.22880 - e-TeX sparse arrays begin define(p,undefined_cs,null); free_avail(def_ref); end else begin if p=output_routine_loc then {enclose in curlies} @y begin sa_define(p,null)(p,undefined_cs,null); free_avail(def_ref); end else begin if (p=output_routine_loc)and not e then {enclose in curlies} @z %--------------------------------------- @x [49] m.1226 l.22888 - e-TeX sparse arrays define(p,call,def_ref); @y sa_define(p,def_ref)(p,call,def_ref); @z %--------------------------------------- @x [49] m.1227 l.22893 - e-TeX sparse arrays begin if cur_cmd=toks_register then begin scan_eight_bit_int; cur_cmd:=assign_toks; cur_chr:=toks_base+cur_val; end; if cur_cmd=assign_toks then begin q:=equiv(cur_chr); if q=null then define(p,undefined_cs,null) else begin add_token_ref(q); define(p,call,q); end; goto done; end; end @y if (cur_cmd=toks_register)or(cur_cmd=assign_toks) then begin if cur_cmd=toks_register then if cur_chr=mem_bot then begin scan_register_num; if cur_val<256 then q:=equiv(toks_base+cur_val) else begin find_sa_element(tok_val,cur_val,false); if cur_ptr=null then q:=null else q:=sa_ptr(cur_ptr); end; end else q:=sa_ptr(cur_ptr) else q:=equiv(cur_chr); if q=null then sa_define(p,null)(p,undefined_cs,null) else begin add_token_ref(q); sa_define(p,q)(p,call,q); end; goto done; end @z %--------------------------------------- @x [49] m.1236 l.23009 do_register_command - e-TeX sparse arrays begin q:=cur_cmd; @y @!e:boolean; {does |l| refer to a sparse array element?} @!w:integer; {integer or dimen value of |l|} begin q:=cur_cmd; e:=false; {just in case, will be set |true| for sparse array elements} @z %--------------------------------------- @x [49] m.1236 l.23024 do_register_command - e-TeX sparse arrays if plo_mem_stat_max) then begin l:=cur_chr; p:=sa_type(l); e:=true; end else begin p:=cur_chr-mem_bot; scan_register_num; if cur_val>255 then begin find_sa_element(p,cur_val,true); l:=cur_ptr; e:=true; end else @z %--------------------------------------- @x [49] m.1237 l.23053 - e-TeX sparse arrays end; found: @y end; end; found: if p@/ @z %--------------------------------------- @x [49] m.1247 l.23188 alter_box_dimen - e-TeX sparse arrays @!b:eight_bits; {box number} begin c:=cur_chr; scan_eight_bit_int; b:=cur_val; scan_optional_equals; scan_normal_dimen; if box(b)<>null then mem[box(b)+c].sc:=cur_val; @y @!b:pointer; {box register} begin c:=cur_chr; scan_register_num; fetch_box(b); scan_optional_equals; scan_normal_dimen; if b<>null then mem[b+c].sc:=cur_val; @z %--------------------------------------- @x [49] m.1248 l.23197 - e-TeX penalties set_shape: begin scan_optional_equals; scan_int; n:=cur_val; if n<=0 then p:=null @y set_shape: begin q:=cur_chr; scan_optional_equals; scan_int; n:=cur_val; if n<=0 then p:=null else if q>par_shape_loc then begin n:=(cur_val div 2)+1; p:=get_node(2*n+1); info(p):=n; n:=cur_val; mem[p+1].int:=n; {number of penalties} for j:=p+2 to p+n+1 do begin scan_int; mem[j].int:=cur_val; {penalty values} end; if not odd(n) then mem[p+n+2].int:=0; {unused} end @z %--------------------------------------- @x [49] m.1248 l.23207 - e-TeX penalties define(par_shape_loc,shape_ref,p); @y define(q,shape_ref,p); @z %--------------------------------------- @x [49] m.1292 l.23581 - e-TeX show_groups show_lists:print_esc("showlists"); @y show_lists:print_esc("showlists"); @@;@/ @z %--------------------------------------- @x [49] m.1293 l.23588 show_whatever - e-TeX show_ifs var p:pointer; {tail of a token list to show} @y var p:pointer; {tail of a token list to show} @!t:small_number; {type of conditional being shown} @!m:normal..or_code; {upper bound on |fi_or_else| codes} @!l:integer; {line where that conditional began} @!n:integer; {level of \.{\\if...\\fi} nesting} @z %--------------------------------------- @x [49] m.1293 l.23594 show_whatever - e-TeX show_groups othercases @@;@/ othercases @0 then print_char(" "); print("macro"); @z %--------------------------------------- @x [49] m.1296 l.23637 - e-TeX sparse arrays begin scan_eight_bit_int; begin_diagnostic; print_nl("> \box"); print_int(cur_val); print_char("="); if box(cur_val)=null then print("void") else show_box(box(cur_val)); @y begin scan_register_num; fetch_box(p); begin_diagnostic; print_nl("> \box"); print_int(cur_val); print_char("="); if p=null then print("void")@+else show_box(p); @z %--------------------------------------- @x [50] m.1307 l.23779 - e-TeX basic dump_int(@$);@/ @y dump_int(@$);@/ @@/ @z %--------------------------------------- @x [50] m.1308 l.23794 - e-TeX basic if x<>@$ then goto bad_fmt; {check that strings are the same} @y if x<>@$ then goto bad_fmt; {check that strings are the same} @/@@/ @z %--------------------------------------- @x [50] m.1311 l.23848 - e-TeX sparse arrays dump_int(lo_mem_max); dump_int(rover); @y dump_int(lo_mem_max); dump_int(rover); if eTeX_ex then for k:=int_val to tok_val do dump_int(sa_root[k]); @z %--------------------------------------- @x [50] m.1312 l.23871 - e-TeX sparse arrays undump(lo_mem_stat_max+1)(lo_mem_max)(rover); @y undump(lo_mem_stat_max+1)(lo_mem_max)(rover); if eTeX_ex then for k:=int_val to tok_val do undump(null)(lo_mem_max)(sa_root[k]); @z %--------------------------------------- @x [50] m.1324 l.24065 - e-TeX hyph_codes dump_int(trie_max); @y dump_int(trie_max); dump_int(hyph_start); @z %--------------------------------------- @x [50] m.1325 l.24093 - e-TeX hyph_codes undump_size(0)(trie_size)('trie size')(j); @+init trie_max:=j;@+tini @y undump_size(0)(trie_size)('trie size')(j); @+init trie_max:=j;@+tini undump(0)(j)(hyph_start); @z %--------------------------------------- @x [51] m.1335 l.24313 final_cleanup - tracing print_int(cur_level-level_one); print_char(")"); @y print_int(cur_level-level_one); print_char(")"); if eTeX_ex then show_save_groups; @z %--------------------------------------- @x [51] m.1335 l.24336 final_cleanup - e-TeX marks, saved_items if cur_mark[c]<>null then delete_token_ref(cur_mark[c]); @y if cur_mark[c]<>null then delete_token_ref(cur_mark[c]); if sa_mark<>null then if do_marks(destroy_marks,0,sa_mark) then sa_mark:=null; for c:=last_box_code to vsplit_code do flush_node_list(disc_ptr[c]); @z %--------------------------------------- @x [51] m.1336 l.24345 ] m.1336 l.24340 init_prim - e-TeX basic begin no_new_control_sequence:=false; @y begin no_new_control_sequence:=false; first:=0; @z %--------------------------------------- @x [51] m.1337 l.24360 - e-TeX basic if (format_ident=0)or(buffer[loc]="&") then @y @@;@/ if (format_ident=0)or(buffer[loc]="&") then @z %--------------------------------------- @x [51] m.1337 l.24368 - e-TeX basic end; @y end; if eTeX_ex then wterm_ln('entering extended mode'); @z %--------------------------------------- @x [53] m.1363 l.24715 - e-TeX hyph_codes adv_past(s) @y if subtype(s)=language_node then begin cur_lang:=what_lang(s); l_hyf:=what_lhm(s); r_hyf:=what_rhm(s); set_hyph_index; end @z %--------------------------------------- @x [54] m.1379 l.24903 - e-TeX additions @* \[54] System-dependent changes. @y @* \[53a] The extended features of \eTeX. The program has two modes of operation: (1)~In \TeX\ compatibility mode it fully deserves the name \TeX\ and there are neither extended features nor additional primitive commands. There are, however, a few modifications that would be legitimate in any implementation of \TeX\ such as, e.g., preventing inadequate results of the glue to \.{DVI} unit conversion during |ship_out|. (2)~In extended mode there are additional primitive commands and the extended features of \eTeX\ are available. The distinction between these two modes of operation initially takes place when a `virgin' \.{eINITEX} starts without reading a format file. Later on the values of all \eTeX\ state variables are inherited when \.{eVIRTEX} (or \.{eINITEX}) reads a format file. The code below is designed to work for cases where `$|init|\ldots|tini|$' is a run-time switch. @= @!init if (buffer[loc]="*")and(format_ident=" (INITEX)") then begin no_new_control_sequence:=false; @@; incr(loc); eTeX_mode:=1; {enter extended mode} @@; end; tini@;@/ if not no_new_control_sequence then {just entered extended mode ?} no_new_control_sequence:=true@+else @ The \eTeX\ features available in extended mode are grouped into two categories: (1)~Some of them are permanently enabled and have no semantic effect as long as none of the additional primitives are executed. (2)~The remaining \eTeX\ features are optional and can be individually enabled and disabled. For each optional feature there is an \eTeX\ state variable named \.{\\...state}; the feature is enabled, resp.\ disabled by assigning a positive, resp.\ non-positive value to that integer. @d eTeX_state_base=int_base+eTeX_state_code @d eTeX_state(#)==eqtb[eTeX_state_base+#].int {an \eTeX\ state variable} @# @d eTeX_version_code=eTeX_int {code for \.{\\eTeXversion}} @d eTeX_revision_code=6 {command code for \.{\\eTeXrevision}} @= primitive("lastnodetype",last_item,last_node_type_code); @!@:last_node_type_}{\.{\\lastnodetype} primitive@> primitive("eTeXversion",last_item,eTeX_version_code); @!@:eTeX_version_}{\.{\\eTeXversion} primitive@> primitive("eTeXrevision",convert,eTeX_revision_code);@/ @!@:eTeX_revision_}{\.{\\eTeXrevision} primitive@> @ @= last_node_type_code: print_esc("lastnodetype"); eTeX_version_code: print_esc("eTeXversion"); @ @= eTeX_version_code: cur_val:=eTeX_version; @ @= eTeX_revision_code: print_esc("eTeXrevision"); @ @= eTeX_revision_code: do_nothing; @ @= eTeX_revision_code: print(eTeX_revision); @ @d eTeX_ex==(eTeX_mode=1) {is this extended mode?} @= @!eTeX_mode: 0..1; {identifies compatibility and extended mode} @ @= eTeX_mode:=0; {initially we are in compatibility mode} @@; @ @= dump_int(eTeX_mode); for j:=0 to eTeX_states-1 do eTeX_state(j):=0; {disable all enhancements} @ @= undump(0)(1)(eTeX_mode); if eTeX_ex then begin @@; end else begin @@; end; @ The |eTeX_enabled| function simply returns its first argument as result. This argument is |true| if an optional \eTeX\ feature is currently enabled; otherwise, if the argument is |false|, the function gives an error message. @= function eTeX_enabled(@!b:boolean;@!j:quarterword;@!k:halfword):boolean; begin if not b then begin print_err("Improper "); print_cmd_chr(j,k); help1("Sorry, this optional e-TeX feature has been disabled."); error; end; eTeX_enabled:=b; end; @ First we implement the additional \eTeX\ parameters in the table of equivalents. @= primitive("everyeof",assign_toks,every_eof_loc); @!@:every_eof_}{\.{\\everyeof} primitive@> primitive("tracingassigns",assign_int,int_base+tracing_assigns_code);@/ @!@:tracing_assigns_}{\.{\\tracingassigns} primitive@> primitive("tracinggroups",assign_int,int_base+tracing_groups_code);@/ @!@:tracing_groups_}{\.{\\tracinggroups} primitive@> primitive("tracingifs",assign_int,int_base+tracing_ifs_code);@/ @!@:tracing_ifs_}{\.{\\tracingifs} primitive@> primitive("tracingscantokens",assign_int,int_base+tracing_scan_tokens_code);@/ @!@:tracing_scan_tokens_}{\.{\\tracingscantokens} primitive@> primitive("tracingnesting",assign_int,int_base+tracing_nesting_code);@/ @!@:tracing_nesting_}{\.{\\tracingnesting} primitive@> { FIXME: the next two should be commented } primitive("predisplaydirection", assign_int,int_base+pre_display_direction_code);@/ @!@:pre_display_direction_}{\.{\\predisplaydirection} primitive@> primitive("lastlinefit",assign_int,int_base+last_line_fit_code);@/ @!@:last_line_fit_}{\.{\\lastlinefit} primitive@> primitive("savingvdiscards",assign_int,int_base+saving_vdiscards_code);@/ @!@:saving_vdiscards_}{\.{\\savingvdiscards} primitive@> primitive("savinghyphcodes",assign_int,int_base+saving_hyph_codes_code);@/ @!@:saving_hyph_codes_}{\.{\\savinghyphcodes} primitive@> @ @d every_eof==equiv(every_eof_loc) @= every_eof_loc: print_esc("everyeof"); @ @= tracing_assigns_code:print_esc("tracingassigns"); tracing_groups_code:print_esc("tracinggroups"); tracing_ifs_code:print_esc("tracingifs"); tracing_scan_tokens_code:print_esc("tracingscantokens"); tracing_nesting_code:print_esc("tracingnesting"); { FIXME: the next one should be commented } pre_display_direction_code:print_esc("predisplaydirection"); last_line_fit_code:print_esc("lastlinefit"); saving_vdiscards_code:print_esc("savingvdiscards"); saving_hyph_codes_code:print_esc("savinghyphcodes"); @ In order to handle \.{\\everyeof} we need an array |eof_seen| of boolean variables. @= @!eof_seen : array[1..max_in_open] of boolean; {has eof been seen?} @ The |print_group| procedure prints the current level of grouping and the name corresponding to |cur_group|. @= procedure print_group(@!e:boolean); label exit; begin case cur_group of bottom_level: begin print("bottom level"); return; end; simple_group,semi_simple_group: begin if cur_group=semi_simple_group then print("semi "); print("simple"); end; hbox_group,adjusted_hbox_group: begin if cur_group=adjusted_hbox_group then print("adjusted "); print("hbox"); end; vbox_group: print("vbox"); vtop_group: print("vtop"); align_group,no_align_group: begin if cur_group=no_align_group then print("no "); print("align"); end; output_group: print("output"); disc_group: print("disc"); insert_group: print("insert"); vcenter_group: print("vcenter"); math_group,math_choice_group,math_shift_group,math_left_group: begin print("math"); if cur_group=math_choice_group then print(" choice") else if cur_group=math_shift_group then print(" shift") else if cur_group=math_left_group then print(" left"); end; end; {there are no other cases} print(" group (level "); print_int(qo(cur_level)); print_char(")"); if saved(-1)<>0 then begin if e then print(" entered at line ") else print(" at line "); print_int(saved(-1)); end; exit:end; @ The |group_trace| procedure is called when a new level of grouping begins (|e=false|) or ends (|e=true|) with |saved(-1)| containing the line number. @= @!stat procedure group_trace(@!e:boolean); begin begin_diagnostic; print_char("{"); if e then print("leaving ") else print("entering "); print_group(e); print_char("}"); end_diagnostic(false); end; tats @ The \.{\\currentgrouplevel} and \.{\\currentgrouptype} commands return the current level of grouping and the type of the current group respectively. @d current_group_level_code=eTeX_int+1 {code for \.{\\currentgrouplevel}} @d current_group_type_code=eTeX_int+2 {code for \.{\\currentgrouptype}} @= primitive("currentgrouplevel",last_item,current_group_level_code); @!@:current_group_level_}{\.{\\currentgrouplevel} primitive@> primitive("currentgrouptype",last_item,current_group_type_code); @!@:current_group_type_}{\.{\\currentgrouptype} primitive@> @ @= current_group_level_code: print_esc("currentgrouplevel"); current_group_type_code: print_esc("currentgrouptype"); @ @= current_group_level_code: cur_val:=cur_level-level_one; current_group_type_code: cur_val:=cur_group; @ The \.{\\currentiflevel}, \.{\\currentiftype}, and \.{\\currentifbranch} commands return the current level of conditionals and the type and branch of the current conditional. @d current_if_level_code=eTeX_int+3 {code for \.{\\currentiflevel}} @d current_if_type_code=eTeX_int+4 {code for \.{\\currentiftype}} @d current_if_branch_code=eTeX_int+5 {code for \.{\\currentifbranch}} @= primitive("currentiflevel",last_item,current_if_level_code); @!@:current_if_level_}{\.{\\currentiflevel} primitive@> primitive("currentiftype",last_item,current_if_type_code); @!@:current_if_type_}{\.{\\currentiftype} primitive@> primitive("currentifbranch",last_item,current_if_branch_code); @!@:current_if_branch_}{\.{\\currentifbranch} primitive@> @ @= current_if_level_code: print_esc("currentiflevel"); current_if_type_code: print_esc("currentiftype"); current_if_branch_code: print_esc("currentifbranch"); @ @= current_if_level_code: begin q:=cond_ptr; cur_val:=0; while q<>null do begin incr(cur_val); q:=link(q); end; end; current_if_type_code: if cond_ptr=null then cur_val:=0 else if cur_if= primitive("fontcharwd",last_item,font_char_wd_code); @!@:font_char_wd_}{\.{\\fontcharwd} primitive@> primitive("fontcharht",last_item,font_char_ht_code); @!@:font_char_ht_}{\.{\\fontcharht} primitive@> primitive("fontchardp",last_item,font_char_dp_code); @!@:font_char_dp_}{\.{\\fontchardp} primitive@> primitive("fontcharic",last_item,font_char_ic_code); @!@:font_char_ic_}{\.{\\fontcharic} primitive@> @ @= font_char_wd_code: print_esc("fontcharwd"); font_char_ht_code: print_esc("fontcharht"); font_char_dp_code: print_esc("fontchardp"); font_char_ic_code: print_esc("fontcharic"); @ @= font_char_wd_code, font_char_ht_code, font_char_dp_code, font_char_ic_code: begin scan_font_ident; q:=cur_val; scan_char_num; if (font_bc(q)<=cur_val)and(font_ec(q)>=cur_val) then begin i:=char_info(q)(qi(cur_val)); case m of font_char_wd_code: cur_val:=char_width(q)(i); font_char_ht_code: cur_val:=char_height(q)(height_depth(i)); font_char_dp_code: cur_val:=char_depth(q)(height_depth(i)); font_char_ic_code: cur_val:=char_italic(q)(i); end; {there are no other cases} end else cur_val:=0; end; @ The \.{\\parshapedimen}, \.{\\parshapeindent}, and \.{\\parshapelength} commands return the indent and length parameters of the current \.{\\parshape} specification. @d par_shape_length_code=eTeX_dim+4 {code for \.{\\parshapelength}} @d par_shape_indent_code=eTeX_dim+5 {code for \.{\\parshapeindent}} @d par_shape_dimen_code=eTeX_dim+6 {code for \.{\\parshapedimen}} @= primitive("parshapelength",last_item,par_shape_length_code); @!@:par_shape_length_}{\.{\\parshapelength} primitive@> primitive("parshapeindent",last_item,par_shape_indent_code); @!@:par_shape_indent_}{\.{\\parshapeindent} primitive@> primitive("parshapedimen",last_item,par_shape_dimen_code); @!@:par_shape_dimen_}{\.{\\parshapedimen} primitive@> @ @= par_shape_length_code: print_esc("parshapelength"); par_shape_indent_code: print_esc("parshapeindent"); par_shape_dimen_code: print_esc("parshapedimen"); @ @= par_shape_length_code, par_shape_indent_code, par_shape_dimen_code: begin q:=cur_chr-par_shape_length_code; scan_int; if (par_shape_ptr=null)or(cur_val<=0) then cur_val:=0 else begin if q=2 then begin q:=cur_val mod 2; cur_val:=(cur_val+q)div 2; end; if cur_val>info(par_shape_ptr) then cur_val:=info(par_shape_ptr); cur_val:=mem[par_shape_ptr+2*cur_val-q].sc; end; cur_val_level:=dimen_val; end; @ The \.{\\showgroups} command displays all currently active grouping levels. @d show_groups=4 { \.{\\showgroups} } @= primitive("showgroups",xray,show_groups); @!@:show_groups_}{\.{\\showgroups} primitive@> @ @= show_groups:print_esc("showgroups"); @ @= show_groups: begin begin_diagnostic; show_save_groups; end; @ @= @!save_pointer=0..save_size; {index into |save_stack|} @ The modifications of \TeX\ required for the display produced by the |show_save_groups| procedure were first discussed by Donald~E. Knuth in {\sl TUGboat\/} {\bf 11}, 165--170 and 499--511, 1990. @^Knuth, Donald Ervin@> In order to understand a group type we also have to know its mode. Since unrestricted horizontal modes are not associated with grouping, they are skipped when traversing the semantic nest. @= procedure show_save_groups; label found1,found2,found,done; var p:0..nest_size; {index into |nest|} @!m:-mmode..mmode; {mode} @!v:save_pointer; {saved value of |save_ptr|} @!l:quarterword; {saved value of |cur_level|} @!c:group_code; {saved value of |cur_group|} @!a:-1..1; {to keep track of alignments} @!i:integer; @!j:quarterword; @!s:str_number; begin p:=nest_ptr; nest[p]:=cur_list; {put the top level into the array} v:=save_ptr; l:=cur_level; c:=cur_group; save_ptr:=cur_boundary; decr(cur_level);@/ a:=1; print_nl(""); print_ln; loop@+begin print_nl("### "); print_group(true); if cur_group=bottom_level then goto done; repeat m:=nest[p].mode_field; if p>0 then decr(p) else m:=vmode; until m<>hmode; print(" ("); case cur_group of simple_group: begin incr(p); goto found2; end; hbox_group,adjusted_hbox_group: s:="hbox"; vbox_group: s:="vbox"; vtop_group: s:="vtop"; align_group: if a=0 then begin if m=-vmode then s:="halign" else s:="valign"; a:=1; goto found1; end else begin if a=1 then print("align entry") else print_esc("cr"); if p>=a then p:=p-a; a:=0; goto found; end; no_align_group: begin incr(p); a:=-1; print_esc("noalign"); goto found2; end; output_group: begin print_esc("output"); goto found; end; math_group: goto found2; disc_group,math_choice_group: begin if cur_group=disc_group then print_esc("discretionary") else print_esc("mathchoice"); for i:=1 to 3 do if i<=saved(-2) then print("{}"); goto found2; end; insert_group: begin if saved(-2)=255 then print_esc("vadjust") else begin print_esc("insert"); print_int(saved(-2)); end; goto found2; end; vcenter_group: begin s:="vcenter"; goto found1; end; semi_simple_group: begin incr(p); print_esc("begingroup"); goto found; end; math_shift_group: begin if m=mmode then print_char("$") else if nest[p].mode_field=mmode then begin print_cmd_chr(eq_no,saved(-2)); goto found; end; print_char("$"); goto found; end; math_left_group: begin if type(nest[p+1].eTeX_aux_field)=left_noad then print_esc("left") else print_esc("middle"); goto found; end; end; {there are no other cases} @; found1: print_esc(s); @; found2: print_char("{"); found: print_char(")"); decr(cur_level); cur_group:=save_level(save_ptr); save_ptr:=save_index(save_ptr) end; done: save_ptr:=v; cur_level:=l; cur_group:=c; end; @ @= if saved(-2)<>0 then begin print_char(" "); if saved(-3)=exactly then print("to") else print("spread"); print_scaled(saved(-2)); print("pt"); end @ @= i:=saved(-4); if i<>0 then if i0 then print_cmd_chr(j,0) else print_cmd_chr(j,1); print_scaled(abs(i)); print("pt"); end else if i=global_box_flag then begin print_esc("global"); i:=i-(global_box_flag-box_flag); end; print_esc("setbox"); print_int(i-box_flag); print_char("="); end else print_cmd_chr(leader_ship,i-(leader_flag-a_leaders)) @ The |scan_general_text| procedure is much like |scan_toks(false,false)|, but will be invoked via |expand|, i.e., recursively. @^recursion@> @= procedure@?scan_general_text; forward;@t\2@> @ The token list (balanced text) created by |scan_general_text| begins at |link(temp_head)| and ends at |cur_val|. (If |cur_val=temp_head|, the list is empty.) @= procedure scan_general_text; label found; var s:normal..absorbing; {to save |scanner_status|} @!w:pointer; {to save |warning_index|} @!d:pointer; {to save |def_ref|} @!p:pointer; {tail of the token list being built} @!q:pointer; {new node being added to the token list via |store_new_token|} @!unbalance:halfword; {number of unmatched left braces} begin s:=scanner_status; w:=warning_index; d:=def_ref; scanner_status:=absorbing; warning_index:=cur_cs; def_ref:=get_avail; token_ref_count(def_ref):=null; p:=def_ref; scan_left_brace; {remove the compulsory left brace} unbalance:=1; loop@+ begin get_token; if cur_tok= primitive("showtokens",xray,show_tokens); @!@:show_tokens_}{\.{\\showtokens} primitive@> @ @= show_tokens:print_esc("showtokens"); @ The \.{\\unexpanded} primitive prevents expansion of tokens much as the result from \.{\\the} applied to a token variable. The \.{\\detokenize} primitive converts a token list into a list of character tokens much as if the token list were written to a file. We use the fact that the command modifiers for \.{\\unexpanded} and \.{\\detokenize} are odd whereas those for \.{\\the} and \.{\\showthe} are even. @= primitive("unexpanded",the,1);@/ @!@:unexpanded_}{\.{\\unexpanded} primitive@> primitive("detokenize",the,show_tokens);@/ @!@:detokenize_}{\.{\\detokenize} primitive@> @ @= else if chr_code=1 then print_esc("unexpanded") else print_esc("detokenize") @ @= if odd(cur_chr) then begin c:=cur_chr; scan_general_text; if c=1 then the_toks:=cur_val else begin old_setting:=selector; selector:=new_string; b:=pool_ptr; p:=get_avail; link(p):=link(temp_head); token_show(p); flush_list(p); selector:=old_setting; the_toks:=str_toks(b); end; return; end @ The \.{\\showifs} command displays all currently active conditionals. @d show_ifs=6 { \.{\\showifs} } @= primitive("showifs",xray,show_ifs); @!@:show_ifs_}{\.{\\showifs} primitive@> @ @= show_ifs:print_esc("showifs"); @ @d print_if_line(#)==if #<>0 then begin print(" entered on line "); print_int(#); end @= show_ifs: begin begin_diagnostic; print_nl(""); print_ln; if cond_ptr=null then begin print_nl("### "); print("no active conditionals"); end else begin p:=cond_ptr; n:=0; repeat incr(n); p:=link(p);@+until p=null; p:=cond_ptr; t:=cur_if; l:=if_line; m:=if_limit; repeat print_nl("### level "); print_int(n); print(": "); print_cmd_chr(if_test,t); if m=fi_code then print_esc("else"); print_if_line(l); decr(n); t:=subtype(p); l:=if_line_field(p); m:=type(p); p:=link(p); until p=null; end; end; @ The \.{\\interactionmode} primitive allows to query and set the interaction mode. @= primitive("interactionmode",set_page_int,2); @!@:interaction_mode_}{\.{\\interactionmode} primitive@> @ @= else if chr_code=2 then print_esc("interactionmode") @ @= else if m=2 then cur_val:=interaction @ @= procedure@?new_interaction; forward;@t\2@> @ @= else if c=2 then begin if (cur_valerror_stop_mode) then begin print_err("Bad interaction mode"); @.Bad interaction mode@> help2("Modes are 0=batch, 1=nonstop, 2=scroll, and")@/ ("3=errorstop. Proceed, and I'll ignore this case."); int_error(cur_val); end else begin cur_chr:=cur_val; new_interaction; end; end @ The |middle| feature of \eTeX\ allows one ore several \.{\\middle} delimiters to appear between \.{\\left} and \.{\\right}. @= primitive("middle",left_right,middle_noad); @!@:middle_}{\.{\\middle} primitive@> @ @= else if chr_code=middle_noad then print_esc("middle") @ The |scan_tokens| feature of \eTeX\ defines the \.{\\scantokens} primitive. @= primitive("scantokens",input,2); @!@:scan_tokens_}{\.{\\scantokens} primitive@> @ @= else if chr_code=2 then print_esc("scantokens") @ @= else if cur_chr=2 then pseudo_start @ The global variable |pseudo_files| is used to maintain a stack of pseudo files. The |info| field of each pseudo file points to a linked list of variable size nodes representing lines not yet processed: the |info| field of the first word contains the size of this node, all the following words contain ASCII codes. @= @!pseudo_files:pointer; {stack of pseudo files} @ @= pseudo_files:=null; @ The |pseudo_start| procedure initiates reading from a pseudo file. @= procedure@?pseudo_start; forward;@t\2@> @ @= procedure pseudo_start; var old_setting:0..max_selector; {holds |selector| setting} @!s:str_number; {string to be converted into a pseudo file} @!l,@!m:pool_pointer; {indices into |str_pool|} @!p,@!q,@!r:pointer; {for list construction} @!w: four_quarters; {four ASCII codes} @!nl,@!sz:integer; begin scan_general_text; old_setting:=selector; selector:=new_string; token_show(temp_head); selector:=old_setting; flush_list(link(temp_head)); str_room(1); s:=make_string; @; flush_string; @; end; @ @= str_pool[pool_ptr]:=si(" "); l:=str_start(s); nl:=si(new_line_char); p:=get_avail; q:=p; while lnl) do incr(l); sz:=(l-m+7)div 4; if sz=1 then sz:=2; r:=get_node(sz); link(q):=r; q:=r; info(q):=hi(sz); while sz>2 do begin decr(sz); incr(r); w.b0:=qi(so(str_pool[m])); w.b1:=qi(so(str_pool[m+1])); w.b2:=qi(so(str_pool[m+2])); w.b3:=qi(so(str_pool[m+3])); mem[r].qqqq:=w; m:=m+4; end; w.b0:=qi(" "); w.b1:=qi(" "); w.b2:=qi(" "); w.b3:=qi(" "); if l>m then begin w.b0:=qi(so(str_pool[m])); if l>m+1 then begin w.b1:=qi(so(str_pool[m+1])); if l>m+2 then begin w.b2:=qi(so(str_pool[m+2])); if l>m+3 then w.b3:=qi(so(str_pool[m+3])); end; end; end; mem[r+1].qqqq:=w; if str_pool[l]=nl then incr(l); end; info(p):=link(p); link(p):=pseudo_files; pseudo_files:=p @ @= begin_file_reading; {set up |cur_file| and new level of input} line:=0; limit:=start; loc:=limit+1; {force line read} if tracing_scan_tokens>0 then begin if term_offset>max_print_line-3 then print_ln else if (term_offset>0)or(file_offset>0) then print_char(" "); name:=19; print("( "); incr(open_parens); update_terminal; end else name:=18 @ Here we read a line from the current pseudo file into |buffer|. @= function pseudo_input: boolean; {inputs the next line or returns |false|} var p:pointer; {current line from pseudo file} @!sz:integer; {size of node |p|} @!w:four_quarters; {four ASCII codes} @!r:pointer; {loop index} begin last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} p:=info(pseudo_files); if p=null then pseudo_input:=false else begin info(pseudo_files):=link(p); sz:=