summaryrefslogtreecommitdiff
path: root/obsolete/systems/knuth/tex--xet
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /obsolete/systems/knuth/tex--xet
Initial commit
Diffstat (limited to 'obsolete/systems/knuth/tex--xet')
-rw-r--r--obsolete/systems/knuth/tex--xet/tex--xet.change917
-rw-r--r--obsolete/systems/knuth/tex--xet/tex--xet.doc34
2 files changed, 951 insertions, 0 deletions
diff --git a/obsolete/systems/knuth/tex--xet/tex--xet.change b/obsolete/systems/knuth/tex--xet/tex--xet.change
new file mode 100644
index 0000000000..5fe23d99fa
--- /dev/null
+++ b/obsolete/systems/knuth/tex--xet/tex--xet.change
@@ -0,0 +1,917 @@
+% This is TEX--XET.CHANGE in text format, as of October 9, 1992.
+TEX--XET.CHANGE - WEB change file for TEX 3.141
+TeX--XeT Copyright (C) 1992 by Dante e.V.
+Contains code for mixed direction text (please note that the name is
+ TeX--XeT and not TeX-XeT).
+
+% A preliminary version was released in April 1992.
+% Version 1.0 was released in June 1992.
+% Version 1.1 prevents arith overflow in glue computation (October 1992).
+
+This change file is free software; you can redistribute and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In order to implement TeX--XeT for a particular system these generic,
+ i.e., system-independent changes for TeX--XeT must be merged into
+ the system-dependent changes for TeX. For that purpose the GNU
+ General Public License is to be interpreted as follows:
+
+1. In the banner line (displayed on the terminal and written to the
+ transcript file) 'TeX' must be replaced by 'TeX--XeT' and the
+ TeX--XeT version (currently '--1.1') be appended to the TeX version
+ (currently '3.141').
+
+2. If the implementation is distributed under the terms of the GNU
+ General Public License or similar (in particular if the source is
+ available) then the change file must include the TeX--XeT copyright
+ notice above. Moreover if the program displays its own copyright
+ message then the TeX--XeT copyright message must be displayed as well.
+
+3. If the source of the implementation is not available then the program
+ must display the TeX--XeT copyright message. Moreover the distribution
+ of the implementation must make clear that it uses this change file
+ and that this change file is available under the terms of the GNU
+ General Public License.
+
+4. The distributor of the implementation is obliged to make this change
+ file available on request (paragraph 3 of the GNU General Public
+ License).
+
+% All line numbers refer to TEX.WEB 3.141 as of March 16, 1992.
+
+@x limbo l.59 - TeX--XeT
+\let\mc=\ninerm % medium caps for names like SAIL
+@y
+\let\mc=\ninerm % medium caps for names like SAIL
+\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 % this is TeX--XeT (or TeX-XeT)
+ \def\TeXeT{\TeX-{\revrm\beginR\TeX\endR}} % for TeX-XeT
+ \def\TeXXeT{\TeX-{\revrm\beginR\TeX-\endR}} % for TeX--XeT
+\fi
+@z
+%---------------------------------------
+@x [1] m.1 l.122 - TeX--XeT
+@:TeXbook}{\sl The \TeX book@>
+@y
+@:TeXbook}{\sl The \TeX book@>
+
+@d TeX_XeT_version=='--1.1' {identifies the current TeX--XeT version}
+@d TeX_XeT_copyright=='TeX--XeT Copyright (C) 1992 by Dante e.V.'
+@z
+%---------------------------------------
+@x [1] m.2 l.177 - TeX--XeT
+If this program is changed, the resulting system should not be called
+`\TeX'; the official name `\TeX' by itself is reserved
+for software systems that are fully compatible with each other.
+A special test suite called the ``\.{TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\TeX' [cf.~Stanford Computer Science report CS1027,
+November 1984].
+@y
+This program contains code for mixed left-to-right and right-to-left
+typesetting. This code is inspired by but different from \TeXeT\ as
+presented by Donald~E. Knuth and Pierre MacKay in {\sl TUGboat\/}
+@^Knuth, Donald Ervin@>
+@^MacKay, Pierre@>
+{\bf 8}, 14--25, 1987. Since the original program is changed, the
+resulting system is not called `\TeX'; the official name `\TeX' by
+itself is reserved for software systems that are fully compatible with
+each other.
+
+In order to avoid confusion with \TeXeT\ the present implementation of
+mixed direction typesetting is called \TeXXeT. It differs from \TeXeT\
+in several important aspects:
+(1)~Right-to-left text is reversed explicitely by the |ship_out| routine
+and is written to a normal \.{DVI} file without any |begin_reflect| or
+|end_reflect| commands; (2)~a |math_node| is (ab)used instead of a
+|whatsit_node| to record the \.{\\beginL}, \.{\\endL}, \.{\\beginR}, and
+\.{\\endR} text direction primitives in order not to influence the line
+breaking algorithm for pure left-to-right text; (3)~therefore \TeXXeT\
+is designed to be used instead of and not in addition to \TeX\ and
+consequently the pool file name is not changed; (4)~right-to-left text
+interrupted by a displayed equation is automatically resumed after that
+equation; and (5)~the |valign| command code with a non-zero command
+modifier is (ab)used for the text direction primitives.
+
+(6) \TeXXeT\ includes code to prevent arithmetic overflow during
+|ship_out| caused by constructions such as
+$$\vbox{\halign{\.{#}\hfil\cr
+{}\\vbox to \\vsize\{\cr
+\hskip 25pt \\vskip 0pt plus 0.0001fil\cr
+\hskip 25pt ...\cr
+\hskip 25pt \\vfil\\penalty-200\\vfilneg\cr
+\hskip 25pt ...\}\cr}}$$
+The relevant stretch or shrink components of consecutive glue nodes are
+added before they are converted to \.{DVI} units; during this process
+glue nodes are converted into kern nodes and glue specifications may be
+discarded.
+
+A special test suite called the ``\.{TRIP} test'' is available for
+helping to determine whether a particular implementation deserves to be
+known as `\TeX' [cf.~Stanford Computer Science report CS1027, November
+1984]. As a consequence of points~(1), (2), and~(6) above \TeXXeT\
+passes the \.{TRIP} test with the following modifications: there are
+four additional `multiletter control sequences' (one line in both
+\.{tripin.log} and \.{trip.log}), one \.{\\mathon} discarded by the line
+breaking algorithm is reinserted at the beginning of a line (four lines
+in \.{trip.log}), and the `Memory usage before' value for three pages is
+reduced because some glue nodes are discarded before the memory usage
+statistic is printed (three more lines in \.{trip.log}).
+@z
+%---------------------------------------
+@x [1] m.3 l.216 - TeX--XeT
+@!@^dirty \PASCAL@>
+@y
+@!@^dirty \PASCAL@>
+
+@d TeX_XeT_banner=='This is TeX--XeT',
+ ', Version 3.141' (here we should use a substring of banner)
+ ,TeX_XeT_version {printed when \TeX\ starts}
+@z
+%---------------------------------------
+@x [5] m.61 l.1554 - TeX--XeT
+wterm(banner);
+@y
+wterm(TeX_XeT_banner);
+@z
+%---------------------------------------
+@x [5] m.61 l.1558 - TeX--XeT
+update_terminal;
+@y
+wterm_ln(TeX_XeT_copyright); {may be omitted under certain circumstances}
+update_terminal;
+@z
+%---------------------------------------
+@x [10] m.147 l.3069 - TeX--XeT
+@d math_node=9 {|type| of a math node}
+@d before=0 {|subtype| for math node that introduces a formula}
+@d after=1 {|subtype| for math node that winds up a formula}
+@y
+In addition a |math_node| with |subtype>after| and |width=0| will be
+(ab)used to record one of the text direction primitives ( \.{\\beginL},
+\.{\\endL}, \.{\\beginR}, \.{\\endR} ).
+
+@d math_node=9 {|type| of a math node}
+@d before=0 {|subtype| for math node that introduces a formula}
+@d after=1 {|subtype| for math node that winds up a formula}
+@#
+@d L_code=2
+@d begin_L_code=L_code+before {|subtype| for \.{\\beginL} `math node'}
+@d end_L_code=L_code+after {|subtype| for \.{\\endL} `math node'}
+@d R_code=4
+@d begin_R_code=R_code+before {|subtype| for \.{\\beginR} `math node'}
+@d end_R_code=R_code+after {|subtype| for \.{\\endR} `math node'}
+@#
+@d end_LR(#)==odd(subtype(#))
+@d end_LR_type(#)==(subtype(#)+after-before)
+@d begin_LR_type(#)==(info(#)-after+before)
+@z
+%---------------------------------------
+@x [12] m.175 l.3544 - TeX--XeT
+math_node: print_char("$");
+@y
+math_node: if subtype(p)>after then print("[]")
+ else print_char("$");
+@z
+%---------------------------------------
+@x [12] m.192 l.3809 - TeX--XeT
+begin print_esc("math");
+@y
+if subtype(p)>after then
+ begin if odd(subtype(p)) then print_esc("end")
+ else print_esc("begin");
+ if subtype(p)<=end_L_code then print_char("L")
+ else print_char("R");
+ end
+else begin print_esc("math");
+@z
+%---------------------------------------
+@x [15] m.208 l.4089 - TeX--XeT
+@d valign=33 {vertical table alignment ( \.{\\valign} )}
+@y
+@d valign=33 {vertical table alignment ( \.{\\valign} ) or text
+ direction ( \.{\\beginL}, \.{\\endL}, \.{\\beginR}, \.{\\endR} )}
+@z
+%---------------------------------------
+@x [16] m.212 l.4289 - TeX--XeT
+Seventh and eighth quantities, |lhmin| and |rhmin|, affect hyphenation.
+@y
+Seventh and eighth quantities, |lhmin| and |rhmin|, affect hyphenation.
+A nineth quantity, |LR_save|, holds the LR stack when a paragraph is
+interrupted by a displayed formula.
+@z
+%---------------------------------------
+@x [16] m.212 l.4305 - TeX--XeT
+ @!lhm_field,@!rhm_field: quarterword;
+@y
+ @!lhm_field,@!rhm_field: quarterword;
+ @!LRs_field: halfword;
+@z
+%---------------------------------------
+@x [16] m.213 l.4319 - TeX--XeT
+@d rhmin==cur_list.rhm_field {\.{\\righthyphenmin} at start of paragraph}
+@y
+@d rhmin==cur_list.rhm_field {\.{\\righthyphenmin} at start of paragraph}
+@d LR_save==cur_list.LRs_field {LR stack when a paragraph is interrupted}
+@z
+%---------------------------------------
+@x [16] m.215 l.4345 - TeX--XeT
+lhmin:=0; rhmin:=0;
+@y
+lhmin:=0; rhmin:=0; LR_save:=null;
+@z
+%---------------------------------------
+@x [16] m.216 l.4360 push_nest - TeX--XeT
+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;
+LR_save:=null;
+@z
+%---------------------------------------
+@x [18] m.265 l.5712 - TeX--XeT
+primitive("valign",valign,0);@/
+@!@:valign_}{\.{\\valign} primitive@>
+@y
+primitive("valign",valign,0);@/
+@!@:valign_}{\.{\\valign} primitive@>
+primitive("beginL",valign,begin_L_code);@/
+@!@:beginL_}{\.{\\beginL} primitive@>
+primitive("endL",valign,end_L_code);@/
+@!@:endL_}{\.{\\endL} primitive@>
+primitive("beginR",valign,begin_R_code);@/
+@!@:beginR_}{\.{\\beginR} primitive@>
+primitive("endR",valign,end_R_code);@/
+@!@:endR_}{\.{\\endR} primitive@>
+@z
+%---------------------------------------
+@x [18] m.266 l.5766 - TeX--XeT
+valign: print_esc("valign");
+@y
+valign: if chr_code<>0 then case chr_code of
+ begin_L_code: print_esc("beginL");
+ end_L_code: print_esc("endL");
+ begin_R_code: print_esc("beginR");
+ othercases print_esc("endR")
+ endcases
+else print_esc("valign");
+@z
+%---------------------------------------
+@x [29] m.536 l.10324 - TeX--XeT
+begin wlog(banner);
+@y
+begin wlog(TeX_XeT_banner);
+@z
+%---------------------------------------
+@x [32] m.616 l.12238 - TeX--XeT
+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 which 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; an |hlist_node| inside R-text is changed to an |R_node| once
+its hlist has been reversed.
+@!@^data structure assumptions@>
+@z
+%---------------------------------------
+@x [32] m.616 l.12240 - TeX--XeT
+@d synch_h==if cur_h<>dvi_h then
+@y
+@d R_node=unset_node {an |unset_node| does not occur during |ship_out|}
+@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.616 l.12251 - TeX--XeT
+@!cur_s:integer; {current depth of output box nesting, initially $-1$}
+@y
+@!cur_s:integer; {current depth of output box nesting, initially $-1$}
+@!cur_dir:small_number; {current text direction}
+@!LR_ptr:pointer; {stack of LR codes}
+@z
+%---------------------------------------
+@x [32] m.619 l.12300 hlist_out - TeX--XeT
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@y
+@z
+%---------------------------------------
+@x [32] m.619 l.12308 hlist_out - TeX--XeT
+@!edge:scaled; {left edge of sub-box, or right edge of leader space}
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+@!edge:scaled; {right edge of sub-box or leader space}
+@!prev_p:pointer; {one step behind |p|}
+begin this_box:=temp_ptr;
+@z
+%---------------------------------------
+@x [32] m.619 l.12314 hlist_out - TeX--XeT
+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; left_edge:=cur_h;
+prev_p:=this_box+list_offset;
+if cur_dir=right_to_left then if type(this_box)=hlist_node then
+ @<Reverse the complete hlist and change this node into an |R_node|@>;
+@z
+%---------------------------------------
+@x [32] m.620 l.12336 - TeX--XeT
+ p:=link(p);
+@y
+ prev_p:=p; p:=link(p);
+@z
+%---------------------------------------
+@x [32] m.622 l.12355 - TeX--XeT
+hlist_node,vlist_node:@<Output a box in an hlist@>;
+@y
+hlist_node,vlist_node,R_node:@<Output a box in an hlist@>;
+@z
+%---------------------------------------
+@x [32] m.622 l.12361 - TeX--XeT
+kern_node,math_node:cur_h:=cur_h+width(p);
+@y
+kern_node:cur_h:=cur_h+width(p);
+math_node:
+ begin @<Adjust the LR stack for the |ship_out| routine; if necessary
+ reverse an hlist segment and |goto reswitch|@>;
+ cur_h:=cur_h+width(p);
+ end;
+@z
+%---------------------------------------
+@x [32] m.622 l.12363 - TeX--XeT
+othercases do_nothing
+@y
+@<Cases of |hlist_out| that arise in mixed direction text only@>@;
+othercases do_nothing
+@z
+%---------------------------------------
+@x [32] m.622 l.12368 - TeX--XeT
+next_p:p:=link(p);
+@y
+next_p:prev_p:=p; p:=link(p);
+@z
+%---------------------------------------
+@x [32] m.623 l.12375 - TeX--XeT
+ 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.12378 - TeX--XeT
+ cur_h:=edge+width(p); cur_v:=base_line;
+@y
+ cur_h:=edge; cur_v:=base_line;
+@z
+%---------------------------------------
+@x [32] m.625 l.12394 - TeX--XeT
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ rule_wd:=rule_wd+round(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ end
+ else begin if shrink_order(g)=g_order then
+ rule_wd:=rule_wd-round(float(glue_set(this_box))*shrink(g));
+ end;
+ end;
+@y
+ add_glue(rule_wd);
+@z
+%---------------------------------------
+@x [32] m.626 l.12418 - TeX--XeT
+ 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.12424 - TeX--XeT
+ 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.12463 - TeX--XeT
+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.12479 vlist_out - TeX--XeT
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@y
+@z
+%---------------------------------------
+@x [32] m.629 l.12488 vlist_out - TeX--XeT
+begin this_box:=temp_ptr; g_order:=glue_order(this_box);
+@y
+begin this_box:=temp_ptr;
+@z
+%---------------------------------------
+@x [32] m.631 l.12511 - TeX--XeT
+hlist_node,vlist_node:@<Output a box in a vlist@>;
+@y
+hlist_node,vlist_node,R_node:@<Output a box in a vlist@>;
+@z
+%---------------------------------------
+@x [32] m.632 l.12533 - TeX--XeT
+ 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.12545 - TeX--XeT
+ 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.12553 - TeX--XeT
+ begin if g_sign=stretching then
+ begin if stretch_order(g)=g_order then
+ rule_ht:=rule_ht+round(float(glue_set(this_box))*stretch(g));
+@^real multiplication@>
+ end
+ else begin if shrink_order(g)=g_order then
+ rule_ht:=rule_ht-round(float(glue_set(this_box))*shrink(g));
+ end;
+ end;
+@y
+ add_glue(rule_ht);
+@z
+%---------------------------------------
+@x [32] m.638 l.12642 ship_out - TeX--XeT
+@<Ship box |p| out@>;
+@y
+cur_dir:=left_to_right; {L-text at the outer level}
+LR_ptr:=get_avail; info(LR_ptr):=before; {this will never match}
+@<Ship box |p| out@>;
+if info(LR_ptr)<>before then LR_confusion;
+free_avail(LR_ptr); LR_ptr:=null;
+@z
+%---------------------------------------
+@x [33] m.649 l.12848 - TeX--XeT
+@p function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+@y
+@p function safe_info(@!p:pointer): halfword;
+begin if p=null then safe_info:=0@+else safe_info:=info(p);
+end;
+@#
+function hpack(@!p:pointer;@!w:scaled;@!m:small_number):pointer;
+@z
+%---------------------------------------
+@x [33] m.649 l.12859 hpack - TeX--XeT
+begin last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node;
+@y
+@!LR_ptr:pointer; {stack of LR codes}
+@!LR_problems:integer; {counts missing begins and ends}
+begin LR_ptr:=null; LR_problems:=0;
+last_badness:=0; r:=get_node(box_node_size); type(r):=hlist_node;
+@z
+%---------------------------------------
+@x [33] m.649 l.12872 hpack - TeX--XeT
+exit: hpack:=r;
+@y
+exit: @<Check for LR anomalies at the end of |hpack|@>;
+hpack:=r;
+@z
+%---------------------------------------
+@x [33] m.651 l.12896 - TeX--XeT
+ kern_node,math_node: x:=x+width(p);
+@y
+ kern_node,math_node:
+ begin x:=x+width(p);
+ @<Adjust the LR stack for the |hpack| routine@>;
+ end;
+@z
+%---------------------------------------
+@x [39] m.866 l.17013 - TeX--XeT
+math_node: begin auto_breaking:=(subtype(cur_p)=after); kern_break;
+@y
+math_node: begin auto_breaking:=(subtype(cur_p)<>before); kern_break;
+@z
+%---------------------------------------
+@x [39] m.877 l.17197 post_line_break - TeX--XeT
+begin @<Reverse the links of the relevant passive nodes, setting |cur_p| to the
+@y
+@!LR_ptr:pointer; {stack of LR codes}
+begin LR_ptr:=LR_save;
+@<Reverse the links of the relevant passive nodes, setting |cur_p| to the
+@z
+%---------------------------------------
+@x [39] m.877 l.17210 post_line_break - TeX--XeT
+prev_graf:=best_line-1;
+@y
+prev_graf:=best_line-1; LR_save:=LR_ptr;
+@z
+%---------------------------------------
+@x [39] m.879 l.17240 - TeX--XeT
+ r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node| or |penalty_node|}
+@y
+ r:=q; {now |type(q)=glue_node|, |kern_node|, |math_node| or |penalty_node|}
+ @<Adjust the LR stack for the |post_line_break| routine@>;
+@z
+%---------------------------------------
+@x [39] m.880 l.17257 - TeX--XeT
+@<Modify the end of the line to reflect the nature of the break and to include
+ \.{\\rightskip}; also set the proper value of |disc_break|@>;
+@y
+@<Insert LR nodes at the beginning of the current line and adjust
+ the LR stack based on LR nodes in this line@>;
+@<Modify the end of the line to reflect the nature of the break and to include
+ \.{\\rightskip}; also set the proper value of |disc_break|@>;
+@<Insert LR nodes at the end of the current line@>;
+@z
+%---------------------------------------
+@x [39] m.881 l.17280 - TeX--XeT
+ else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0;
+@y
+ else if (type(q)=math_node)or(type(q)=kern_node) then
+ begin width(q):=0; @<Adjust the LR stack for the |p...@>;
+ end;
+@z
+%---------------------------------------
+@x [47] m.1096 l.21095 - TeX--XeT
+ else line_break(widow_penalty);
+@y
+ else line_break(widow_penalty);
+ if LR_save<>null then
+ begin flush_list(LR_save); LR_save:=null;
+ end;
+@z
+%---------------------------------------
+@x [47] m.1130 l.21538 - TeX--XeT
+vmode+halign,hmode+valign:init_align;
+@y
+vmode+halign,hmode+valign:
+ if cur_chr>0 then tail_append(new_math(0,cur_chr))
+ else init_align;
+@z
+%---------------------------------------
+@x [54] m.1379 l.24872 additions - TeX--XeT
+This section should be replaced, if necessary, by any special
+modifications of the program
+that are necessary to make \TeX\ work at a particular installation.
+It is usually best to design your change file so that all changes to
+previous sections preserve the section numbering; then everybody's version
+will be consistent with the published program. More extensive changes,
+which introduce new sections, can be inserted here; then only the index
+itself will get a new section number.
+@^system dependencies@>
+@y
+The following sections, as recommended, contain the more extensive
+modifications of the program
+that are necessary to make \TeX\ work at a particular installation.
+@^system dependencies@>
+
+@ Insert system dependent changes here.
+
+@ Last not least we do the main work required for mixed-direction texts.
+A number of routines are based on a stack of one-word nodes whose |info|
+fields contain |after|, |end_L_code|, or |end_R_code|. The top of the
+stack is pointed to by |LR_ptr|.
+
+When the stack manipulation macros of this section are used below,
+variable |LR_ptr| might be the global variable declared for |ship_out|,
+or might be local to |hpack| or |post_line_break|.
+
+@d push_LR(#)==begin temp_ptr:=get_avail; info(temp_ptr):=end_LR_type(#);
+ link(temp_ptr):=LR_ptr; LR_ptr:=temp_ptr;
+ end
+@d pop_LR==begin temp_ptr:=LR_ptr; LR_ptr:=link(temp_ptr);
+ free_avail(temp_ptr);
+ end
+
+@<Insert LR nodes at the beg...@>=
+q:=link(temp_head);
+if LR_ptr<>null then
+ begin temp_ptr:=LR_ptr; r:=q;
+ repeat s:=new_math(0,begin_LR_type(temp_ptr)); link(s):=r; r:=s;
+ temp_ptr:=link(temp_ptr);
+ until temp_ptr=null;
+ link(temp_head):=r;
+ end;
+while q<>cur_break(cur_p) do
+ begin if not is_char_node(q) then @<Adjust the LR stack for the |p...@>;
+ q:=link(q);
+ end
+
+@ @<Adjust the LR stack for the |p...@>=
+if type(q)=math_node then
+ if end_LR(q) then
+ begin if LR_ptr<>null then if info(LR_ptr)=subtype(q) then pop_LR;
+ end
+ else push_LR(q)
+
+@ We use the fact that |q| now points to the node with \.{\\rightskip} glue.
+
+@<Insert LR nodes at the end...@>=
+if LR_ptr<>null then
+ begin s:=temp_head; r:=link(s);
+ while r<>q do
+ begin s:=r; r:=link(s);
+ end;
+ r:=LR_ptr;
+ while r<>null do
+ begin temp_ptr:=new_math(0,info(r));
+ link(s):=temp_ptr; s:=temp_ptr; r:=link(r);
+ end;
+ link(s):=q;
+ end
+
+@ @<Adjust the LR stack for the |h...@>=
+if type(p)=math_node then
+ if end_LR(p) then
+ if safe_info(LR_ptr)=subtype(p) then pop_LR
+ else begin incr(LR_problems);
+ while link(q)<>p do q:=link(q);
+ link(q):=link(p); free_node(p,small_node_size); p:=q;
+ end
+ else push_LR(p)
+
+@ @<Check for LR anomalies at the end of |h...@>=
+if LR_ptr<>null then
+ begin while link(q)<>null do q:=link(q);
+ repeat temp_ptr:=q; q:=new_math(0,info(LR_ptr)); link(temp_ptr):=q;
+ LR_problems:=LR_problems+10000; pop_LR;
+ until LR_ptr=null;
+ end;
+if LR_problems>0 then
+ begin print_ln; print_nl("\endL or \endR problem (");@/
+ print_int(LR_problems div 10000); print(" missing, ");@/
+ print_int(LR_problems mod 10000); print(" extra");@/
+ LR_problems:=0; goto common_ending;
+ end
+
+@ @<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+procedure LR_confusion;
+begin confusion("LR");
+@:this can't happen LR}{\quad LR@>
+end;
+
+@ @d LR_dir(#)==(subtype(#) div 4) {text direction of a `math node'}
+
+@<Adjust the LR stack for the |s...@>=
+if end_LR(p) then
+ begin if info(LR_ptr)<>subtype(p) then LR_confusion;
+ pop_LR; type(p):=kern_node;
+ end
+else begin push_LR(p); type(p):=kern_node;
+ if LR_dir(p)<>cur_dir then
+ begin @<Reverse an hlist segment containing right-to-left material@>;
+ goto reswitch;
+ end;
+ type(p):=kern_node;
+ end
+
+@ @d edge_node=style_node {a |style_node| does not occur during |ship_out|}
+@d edge_node_size=style_node_size {number of words in an edge node}
+@d edge_dist(#)==depth(#) {new |left_edge| position relative to |cur_h|
+ (after |width| has been taken into account)}
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function new_edge(@!s:small_number;@!w:scaled):pointer;
+ {create an edge node}
+var p:pointer; {the new node}
+begin p:=get_node(edge_node_size); type(p):=edge_node;
+subtype(p):=s; width(p):=w; {the |edge_dist| field will be set later}
+new_edge:=p;
+end;
+
+@ @<Cases of |hlist_out| that arise...@>=
+edge_node: begin cur_h:=cur_h+width(p);
+ left_edge:=cur_h+edge_dist(p); cur_dir:=subtype(p);
+ end;
+
+@ We detach the hlist, start a new one consisting of just one kern node,
+append the reversed list, and set the width of the kern node.
+
+@<Reverse the complete hlist...@>=
+begin save_h:=cur_h; temp_ptr:=p; p:=new_kern(0); link(prev_p):=p;
+cur_h:=0; link(p):=reverse(this_box,null); width(p):=-cur_h;
+cur_h:=save_h; type(this_box):=R_node;
+end
+
+@ We detach the remainder of the hlist, replace the math node by
+an edge node, and append the reversed hlist segment to it; the tail of
+the reversed segment is another edge node and the remainder of the
+original list is attached to it.
+
+@<Reverse an hlist segment...@>=
+begin save_h:=cur_h; temp_ptr:=link(p); rule_wd:=width(p);
+free_node(p,small_node_size);
+cur_dir:=reflected; p:=new_edge(cur_dir,rule_wd); link(prev_p):=p;
+cur_h:=cur_h-left_edge+rule_wd;
+link(p):=reverse(this_box,new_edge(reflected,0));
+edge_dist(p):=cur_h; cur_dir:=reflected; cur_h:=save_h;
+end
+
+@ In constructions such as
+$$\vbox{\halign{\.{#}\hfil\cr
+{}\\vbox to \\vsize\{\cr
+\hskip 25pt \\vskip 0pt plus 0.0001fil\cr
+\hskip 25pt ...\cr
+\hskip 25pt \\vfil\\penalty-200\\vfilneg\cr
+\hskip 25pt ...\}\cr}}$$
+the stretch components of \.{\\vfil} and \.{\\vfilneg} compensate;
+nevertheless they may cause arithmetic overflow during |ship_out| when
+each of them is multiplied by a large |glue_set| value.
+
+In order to avoid such unnecessary arithmetic overflow the |do_glue|
+function adds up the relevant stretch (or shrink) components of
+consecutive glue nodes and converts the glue nodes them into equivalent
+kern nodes; the accumulated stretch or shrink is then multiplied by
+|glue_set(this_box)| and returned as result. Since one and the same box
+may be used several times inside leaders the result is also added to the
+width of the first or only kern node; the subtype of the glue node(s)
+remains unchanged. The consecutive glue nodes may be separated by
+insert, mark, adjust, kern, and penalty nodes.
+
+@d add_glue(#)==#:=#+do_glue(this_box,p)
+@#
+@d add_stretch_shrink== {accumulate stretch or shrink amount}
+if g_sign=stretching then
+ begin if stretch_order(g)=g_order then s:=s+stretch(g);
+ end
+else begin if shrink_order(g)=g_order then s:=s-shrink(g);
+ end
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function do_glue(@!this_box,@!p:pointer):scaled;
+label continue, next_p, done;
+var q:pointer; {list traverser}
+@!g_order: glue_ord; {applicable order of infinity for glue}
+@!g_sign: normal..shrinking; {selects type of glue}
+@!s:scaled; {accumulated stretch or shrink}
+@!r:real; {|s| multiplied by |glue_set(this_box)|}
+begin g_order:=glue_order(this_box); g_sign:=glue_sign(this_box);
+s:=0; add_stretch_shrink;
+if subtype(p)>=a_leaders then goto done;
+q:=p;
+continue: type(q):=kern_node; width(q):=width(g);
+fast_delete_glue_ref(g);
+next_p: q:=link(q);
+if (q<>null) and not is_char_node(q) then case type(q) of
+ins_node,mark_node,adjust_node,kern_node,penalty_node: goto next_p;
+glue_node: if subtype(q)<a_leaders then
+ begin g:=glue_ptr(q); add_stretch_shrink; goto continue;
+ end;
+othercases do_nothing
+endcases;@/
+done: if s<>0 then
+ begin r:=float(glue_set(this_box))*s;
+@^real multiplication@>
+ if abs(r)>=max_dimen.5 then
+ begin print_err("Glue stretch or shrink too big");
+@.Glue stretch... too big@>
+ help2("I can't work with sizes bigger than about 19 feet.")@/
+ ("Continue and I'll use the largest value I can.");@/
+ error;
+ if r>0.0 then s:=max_dimen @+ else s:=-max_dimen;
+ end
+ else s:=round(r);
+ if type(p)=kern_node then width(p):=width(p)+s;
+ end;
+do_glue:=s;
+end;
+
+@ The |reverse| function defined here is responsible to reverse the
+nodes of an hlist (segment). The first parameter |this_box| is the
+enclosing hlist node, the second parameter |t| is to become the tail of
+the reversed list, and the global variable |temp_ptr| is the head of the
+list to be reversed. We remove nodes from the original list and add them
+to the head of the new one.
+
+@<Declare procedures needed in |hlist_out|, |vlist_out|@>=
+function reverse(@!this_box,@!t:pointer):pointer;
+label reswitch, next_p, done;
+var l:pointer; {the new list}
+@!p:pointer; {the current node}
+@!q:pointer; {the next node}
+@!g_sign: normal..shrinking; {selects type of glue}
+@!m,@!n:halfword; {number of unmatched math nodes}
+begin g_sign:=glue_sign(this_box);
+l:=t; p:=temp_ptr; m:=min_halfword; n:=min_halfword;
+while p<>null do @<Move node |p| to the new list and go to the next node;
+ or |goto done| if the end of the reflected segment has been reached@>;
+if (t<>null)or(m<>min_halfword)or(n<>min_halfword) then LR_confusion;
+done:reverse:=l;
+end;
+
+@ @<Move node |p| to the new list...@>=
+reswitch: if is_char_node(p) then
+ repeat f:=font(p); c:=character(p);
+ cur_h:=cur_h+char_width(f)(char_info(f)(c));
+ q:=link(p); link(p):=l; l:=p; p:=q;
+ until not is_char_node(p)
+else @<Move the non-|char_node| |p| to the new list@>
+
+@ @<Move the non-|char_node| |p| to the new list@>=
+begin q:=link(p); rule_wd:=width(p); {the width is needed in most cases}
+case type(p) of
+hlist_node,vlist_node,rule_node,kern_node: do_nothing;
+@t\4@>@<Cases of |reverse| that need special treatment@>@;
+R_node,edge_node: LR_confusion;
+othercases goto next_p
+endcases;@/
+cur_h:=cur_h+rule_wd;
+next_p: if (type(p)=kern_node)and((rule_wd=0)or(l=null)) then
+ free_node(p,small_node_size)
+else begin link(p):=l; l:=p;
+ end;
+p:=q;
+end
+
+@ Here we have to remember that |add_glue| may have converted the glue
+node into a kern node. If this is not the case we try to covert the
+glue node into a rule node.
+
+@<Cases of |reverse|...@>=
+glue_node: begin g:=glue_ptr(p); rule_wd:=width(g);
+if g_sign<>normal then add_glue(rule_wd);
+if subtype(p)>=a_leaders then
+ begin temp_ptr:=leader_ptr(p);
+ if type(temp_ptr)=rule_node then
+ begin delete_glue_ref(g); free_node(p,small_node_size);
+ p:=temp_ptr; width(p):=rule_wd;
+ end;
+ end;
+end;
+
+@ A ligature node is replaced by a char node.
+
+@<Cases of |reverse|...@>=
+ligature_node: begin flush_node_list(lig_ptr(p));
+temp_ptr:=p; p:=get_avail; mem[p]:=mem[lig_char(temp_ptr)]; link(p):=q;
+free_node(temp_ptr,small_node_size); goto reswitch;
+end;
+
+@ Math nodes in an inner reflected segment are modified, those at the
+outer level are changed into kern nodes.
+
+@<Cases of |reverse|...@>=
+math_node: if end_LR(p) then
+ if n>min_halfword then
+ begin decr(n); decr(subtype(p)); {change |after| into |before|}
+ end
+ else begin if info(LR_ptr)<>subtype(p) then LR_confusion;
+ pop_LR;
+ if m=min_halfword then @<Finish the reversed list and |goto done|@>;
+ decr(m); type(p):=kern_node;
+ end
+else if (n>min_halfword)or(LR_dir(p)<>cur_dir) then
+ begin incr(n); incr(subtype(p)); {change |before| into |after|}
+ end
+ else begin push_LR(p); incr(m); type(p):=kern_node;
+ end;
+
+@ Finally we have found the end of the hlist segment to be reversed; the
+terminating math node is released and the remaining list is attached to
+the edge node at the end of the reversed list.
+
+@<Finish the reversed list and |goto done|@>=
+begin if t=null then LR_confusion; free_node(p,small_node_size);
+link(t):=q; width(t):=rule_wd; edge_dist(t):=-cur_h-rule_wd;
+goto done;
+end
+@z
+%---------------------------------------
diff --git a/obsolete/systems/knuth/tex--xet/tex--xet.doc b/obsolete/systems/knuth/tex--xet/tex--xet.doc
new file mode 100644
index 0000000000..fff920c8e4
--- /dev/null
+++ b/obsolete/systems/knuth/tex--xet/tex--xet.doc
@@ -0,0 +1,34 @@
+TeX--XeT.DOC
+TeX--XeT Copyright (C) 1992 by Dante e.V.
+
+TeX--XeT contains the code necessary for mixed left-to-right and
+right-to-left typesetting. This code is inspired by but different from
+TeX-XeT as presented by Donald E. Knuth and Pierre MacKay in TUGboat 8,
+14--25, 1987.
+
+The TeX--XeT change file is distributed under the terms of the GNU
+General Public License and must be combined with the system-dependent
+TeX change file for a particular system. For that purpose the GNU
+General Public License is to be interpreted such that the use of
+TeX--XeT in a proprietary product or in a product with secret source
+code is possible under certain conditions (for details see the TeX-XeT
+change file).
+
+In order to avoid confusion with TeX-XeT the present implementation of
+mixed direction typesetting is called TeX--XeT. It differs from TeX-XeT
+in several important aspects:
+(1) Right-to-left text is reversed explicitely by the ship-out routine
+ and is written to a normal DVI file without any begin-reflect or
+ end-reflect commands;
+(2) TeX--XeT produces exactly the same line breaks as TeX when applied
+ to pure left-to-right text, in fact TeX--XeT passes the TRIP test
+ with very few and well understood modifications;
+(3) therefore TeX--XeT is designed to be used instead of and not in
+ addition to TeX and consequently the pool file name is not changed;
+(4) as an enhancement over TeX-XeT right-to-left text interrupted by a
+ displayed equation is automatically resumed after that equation.
+
+Files: TeX--XeT.CHANGE WEB change file for TeX 3.141
+ Version 1.1 was released in October 1992
+
+--- Peter Breitenlohner (peb@dm0mpi11.bitnet) -------- 09 Oct 92 ---