diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /systems/tex-extensions/clasen/math/fraction.ch |
Initial commit
Diffstat (limited to 'systems/tex-extensions/clasen/math/fraction.ch')
-rw-r--r-- | systems/tex-extensions/clasen/math/fraction.ch | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/systems/tex-extensions/clasen/math/fraction.ch b/systems/tex-extensions/clasen/math/fraction.ch new file mode 100644 index 0000000000..ab27046166 --- /dev/null +++ b/systems/tex-extensions/clasen/math/fraction.ch @@ -0,0 +1,355 @@ +% idea: keep track of math style in integer parameter +% \mathstyle *while scanning the formula*. To be able +% to do this, we need to keep track of +% +% \overline +% ^ +% _ +% \mathaccent +% style atoms +% \fraction{...\over...} +% +% Change necessary: \mathstyle is *not* an ordinary +% integer parameter, since math style doesn't obey +% grouping. Try ${\scriptscriptstyle 1}2$. +% Therefore it should be a special readonly parameter and +% a \cramp primitive should be separately added. + +@x l.8392 +@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}} +@d badness_code=glue_val+2 {code for \.{\\badness}} +@y +@d input_line_no_code=glue_val+1 {code for \.{\\inputlineno}} +@d badness_code=glue_val+2 {code for \.{\\badness}} +@d math_style_code=glue_val+3 {code for \.{\\mathstyle}} +@z + +@x l.8420 +primitive("badness",last_item,badness_code); +@!@:badness_}{\.{\\badness} primitive@> +@y +primitive("badness",last_item,badness_code); +@!@:badness_}{\.{\\badness} primitive@> +primitive("mathstyle",last_item,math_style_code); +@!@:mathstyle_}{\.{\\mathstyle} primitive@> +@z + +@x l.8435 + input_line_no_code: print_esc("inputlineno"); + othercases print_esc("badness") +@y + input_line_no_code: print_esc("inputlineno"); + badness_code: print_esc("badness"); + math_style_code: print_esc("mathstyle"); + othercases confusion("last_item") +@:this can't happen last_item}{\quad last_item@> +@z + +% +% \mathstyle returns -1 if used outside math mode. +% + +@x l.8504 +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|} + cur_val_level:=int_val; + end +@y +if cur_chr>glue_val then + begin if cur_chr=input_line_no_code then cur_val:=line + else if cur_chr=math_style_code then begin + if abs(mode)=mmode then cur_val:=mathstyle + else cur_val:=-1; + end else cur_val:=last_badness; + cur_val_level:=int_val; + end +@z + +@x l.14108 +@!cur_style:small_number; {style code at current place in the list} +@y +@!cur_style,mathstyle:small_number; {style code at current place in the list} +@z + +@x l.21649 +begin push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1); +if every_math<>null then begin_token_list(every_math,every_math_text); +@y +begin mathstyle:=text_style; +push_math(math_shift_group); eq_word_define(int_base+cur_fam_code,-1); +if every_math<>null then begin_token_list(every_math,every_math_text); +@z + +@x l.21700 +push_math(math_shift_group); mode:=mmode; +eq_word_define(int_base+cur_fam_code,-1);@/ +@y +mathstyle:=display_style; +push_math(math_shift_group); mode:=mmode; +eq_word_define(int_base+cur_fam_code,-1);@/ +@z + +@x l.21798 +mmode+left_brace: begin tail_append(new_noad); + back_input; scan_math(nucleus(tail)); +@y +mmode+left_brace: begin tail_append(new_noad); + back_input; scan_math(nucleus(tail),mathstyle); +@z + +% +% we change scan_math to expect one additional parameter, +% the mathstyle for the next math atom. There are two +% cases here: +% - simple atom: use local var stack to hold old style +% and restore it from there +% - subformula: use save stack to hold old style and +% restore it when reading `}' +% + +@x l.21810 +procedure scan_math(@!p:pointer); +label restart,reswitch,exit; +var c:integer; {math character code} +begin restart:@<Get the next non-blank non-relax...@>; +reswitch:case cur_cmd of +letter,other_char,char_given: begin c:=ho(math_code(cur_chr)); + if c=@'100000 then + begin @<Treat |cur_chr| as an active character@>; + goto restart; + end; + end; +char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given; + goto reswitch; + end; +math_char_num: begin scan_fifteen_bit_int; c:=cur_val; + end; +math_given: c:=cur_chr; +delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000; + end; +othercases @<Scan a subformula enclosed in braces and |return|@> +endcases;@/ +math_type(p):=math_char; character(p):=qi(c mod 256); +if (c>=var_code)and fam_in_range then fam(p):=cur_fam +else fam(p):=(c div 256) mod 16; +exit:end; +@y +procedure scan_math(@!p:pointer;s:small_number); +label restart,reswitch,exit; +var c:integer; {math character code} + savedstyle:small_number; +begin +savedstyle:=mathstyle; mathstyle:=s; +restart:@<Get the next non-blank non-relax...@>; +reswitch:case cur_cmd of +letter,other_char,char_given: begin c:=ho(math_code(cur_chr)); + if c=@'100000 then + begin @<Treat |cur_chr| as an active character@>; + goto restart; + end; + end; +char_num: begin scan_char_num; cur_chr:=cur_val; cur_cmd:=char_given; + goto reswitch; + end; +math_char_num: begin scan_fifteen_bit_int; c:=cur_val; + end; +math_given: c:=cur_chr; +delim_num: begin scan_twenty_seven_bit_int; c:=cur_val div @'10000; + end; +othercases @<Scan a subformula enclosed in braces and |return|@> +endcases;@/ +math_type(p):=math_char; character(p):=qi(c mod 256); +if (c>=var_code)and fam_in_range then fam(p):=cur_fam +else fam(p):=(c div 256) mod 16; +mathstyle:=savedstyle; +exit: +end; +@z + +@x l.21848 +begin back_input; scan_left_brace;@/ +saved(0):=p; incr(save_ptr); push_math(math_group); return; +@y +begin back_input; scan_left_brace;@/ +saved(0):=p; incr(save_ptr); saved(0):=savedstyle; incr(save_ptr); +push_math(math_group); return; +@z + +@x l.21944 +mmode+math_comp: begin tail_append(new_noad); + type(tail):=cur_chr; scan_math(nucleus(tail)); +@y +mmode+math_comp: begin tail_append(new_noad); + type(tail):=cur_chr; + case type(tail) of + over_noad: scan_math(nucleus(tail),cramped_style(mathstyle)); + othercases scan_math(nucleus(tail),mathstyle); + endcases; +@z + +%@x l.21999 +%scan_delimiter(left_delimiter(tail),true); +%if t=1 then scan_delimiter(right_delimiter(tail),true) +%else mem[right_delimiter(tail)].qqqq:=null_delimiter; +%scan_math(nucleus(tail)); +%end; +%@y +%scan_delimiter(left_delimiter(tail),true); +%if t=1 then scan_delimiter(right_delimiter(tail),true) +%else mem[right_delimiter(tail)].qqqq:=null_delimiter; +%scan_math(nucleus(tail),cramped_style(mathstyle)); +%end; +%@z + +@x +{before |scan_math| in |math_radical|} +scan_math(nucleus(tail)); +@y +{before |scan_math| in |math_radical|} +scan_math(nucleus(tail),cramped_style(mathstyle)); +@z + +@x l.22012 +if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam +else fam(accent_chr(tail)):=(cur_val div 256) mod 16; +scan_math(nucleus(tail)); +end; +@y +if (cur_val>=var_code)and fam_in_range then fam(accent_chr(tail)):=cur_fam +else fam(accent_chr(tail)):=(cur_val div 256) mod 16; +scan_math(nucleus(tail),cramped_style(mathstyle)); +end; +@z + +@x l.22066 +mmode+math_style: tail_append(new_style(cur_chr)); +@y +mmode+math_style: begin tail_append(new_style(cur_chr)); + mathstyle:=cur_chr; +end; +@z + +@x l.22076 +procedure append_choices; +begin tail_append(new_choice); incr(save_ptr); saved(-1):=0; +push_math(math_choice_group); scan_left_brace; +@y +procedure append_choices; +begin tail_append(new_choice); +incr(save_ptr); saved(-1):=mathstyle; +incr(save_ptr); saved(-1):=0; +push_math(math_choice_group); scan_left_brace; +mathstyle:=display_style; +@z + +@x l.22094 +3:begin script_script_mlist(tail):=p; decr(save_ptr); return; + end; +end; {there are no other cases} +incr(saved(-1)); push_math(math_choice_group); scan_left_brace; +@y +3:begin script_script_mlist(tail):=p; decr(save_ptr); + mathstyle:=saved(-1); decr(save_ptr); + return; + end; +end; {there are no other cases} +incr(saved(-1)); push_math(math_choice_group); scan_left_brace; +mathstyle:=2*saved(-1); +@z + +@x l.22109 +procedure sub_sup; +var t:small_number; {type of previous sub/superscript} +@!p:pointer; {field to be filled by |scan_math|} +begin t:=empty; p:=null; +if tail<>head then if scripts_allowed(tail) then + begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|} + t:=math_type(p); + end; +if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>; +scan_math(p); +end; +@y +procedure sub_sup; +var t:small_number; {type of previous sub/superscript} +@!p:pointer; {field to be filled by |scan_math|} +begin t:=empty; p:=null; +if tail<>head then if scripts_allowed(tail) then + begin p:=supscr(tail)+cur_cmd-sup_mark; {|supscr| or |subscr|} + t:=math_type(p); + end; +if (p=null)or(t<>empty) then @<Insert a dummy noad to be sub/superscripted@>; +if cur_cmd=sup_mark then scan_math(p,sup_style(mathstyle)) +else scan_math(p,sub_style(mathstyle)); +end; +@z + +@x l.22149 +@d delimited_code=3 { `\.{\\abovewithdelims}', etc.} +@y +@d delimited_code=3 { `\.{\\abovewithdelims}', etc.} +@d fraction_code=6 { `\.{\\fraction}', etc.} +@z + +@x l.22162 +primitive("atopwithdelims",above,delimited_code+atop_code); +@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@> +@y +primitive("atopwithdelims",above,delimited_code+atop_code); +@!@:atop_with_delims_}{\.{\\atopwithdelims} primitive@> +primitive("fraction",above,fraction_code); +@!@:fraction_}{\.{\\fraction} primitive@> +@z + +@x l.22171 + delimited_code+atop_code:print_esc("atopwithdelims"); + othercases print_esc("above") +@y + delimited_code+atop_code:print_esc("atopwithdelims"); + fraction_code:print_esc("fraction"); + othercases print_esc("above") +@z + +% We handle \fraction{...\over...} here, by scanning away +% the left brace and then doing the same as for +% mmode+left_brace +% The point is that we have a handle to update the +% math_style variable properly here. +% We do scan_left_brace followed by back_input to +% force the left brace to be there + +@x l.22176 +mmode+above: math_fraction; +@y +mmode+above: if cur_chr=fraction_code then begin + scan_left_brace; tail_append(new_noad); + back_input; + scan_math(nucleus(tail),num_style(mathstyle)); +end else begin + math_fraction; +end; +@z + +@x +procedure math_fraction; +var c:small_number; {the type of generalized fraction we are scanning} +begin c:=cur_chr; +@y +procedure math_fraction; +var c:small_number; {the type of generalized fraction we are scanning} +begin c:=cur_chr; +mathstyle:=denom_style(save_stack[cur_boundary-1].int); +@z + +@x l.22258 +math_group: begin unsave; decr(save_ptr);@/ + math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p; +@y +math_group: begin unsave; decr(save_ptr);@/ + mathstyle:=saved(0); decr(save_ptr); + math_type(saved(0)):=sub_mlist; p:=fin_mlist(null); info(saved(0)):=p; +@z + + + |