summaryrefslogtreecommitdiff
path: root/systems/tex-extensions/clasen/math/fraction.ch
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 /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.ch355
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
+
+
+