From e0c6872cf40896c7be36b11dcc744620f10adf1d Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 2 Sep 2019 13:46:59 +0900 Subject: Initial commit --- obsolete/systems/knuth/tex--xet/tex--xet.change | 917 ++++++++++++++++++++++++ obsolete/systems/knuth/tex--xet/tex--xet.doc | 34 + 2 files changed, 951 insertions(+) create mode 100644 obsolete/systems/knuth/tex--xet/tex--xet.change create mode 100644 obsolete/systems/knuth/tex--xet/tex--xet.doc (limited to 'obsolete/systems/knuth/tex--xet') 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 + @; +@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:@; +@y +hlist_node,vlist_node,R_node:@; +@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 @; + cur_h:=cur_h+width(p); + end; +@z +%--------------------------------------- +@x [32] m.622 l.12363 - TeX--XeT +othercases do_nothing +@y +@@; +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:@; +@y +hlist_node,vlist_node,R_node:@; +@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 +@; +@y +cur_dir:=left_to_right; {L-text at the outer level} +LR_ptr:=get_avail; info(LR_ptr):=before; {this will never match} +@; +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: @; +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); + @; + 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 @; +@z +%--------------------------------------- +@x [39] m.880 l.17257 - TeX--XeT +@; +@y +@; +@; +@; +@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; @; + 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 + +@= +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 @; + q:=link(q); + end + +@ @= +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. + +@= +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 + +@ @= +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) + +@ @= +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 + +@ @= +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'} + +@= +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 @; + 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)} + +@= +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; + +@ @= +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. + +@= +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. + +@= +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 + +@= +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)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. + +@= +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 @; +if (t<>null)or(m<>min_halfword)or(n<>min_halfword) then LR_confusion; +done:reverse:=l; +end; + +@ @= +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 @ + +@ @= +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@>@@; +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. + +@= +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. + +@= +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. + +@= +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 @; + 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. + +@= +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 --- -- cgit v1.2.3