summaryrefslogtreecommitdiff
path: root/source/luametatex/source/tex/texmath.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/tex/texmath.c')
-rw-r--r--source/luametatex/source/tex/texmath.c156
1 files changed, 128 insertions, 28 deletions
diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c
index 00e67942c..a4ec71e5d 100644
--- a/source/luametatex/source/tex/texmath.c
+++ b/source/luametatex/source/tex/texmath.c
@@ -300,6 +300,16 @@ int tex_math_has_class_option(halfword cls, int option)
return (value & option) == option;
}
+int tex_math_has_class_parent(halfword cls)
+{
+ halfword value = count_parameter(first_math_options_code + cls);
+ if (value == no_class_options) {
+ unsigned parent = (unsigned) count_parameter(first_math_parent_code + cls);
+ return (parent >> 16) & 0xFF;
+ }
+ return 0;
+}
+
static void tex_aux_unsave_math(void)
{
tex_unsave();
@@ -2363,11 +2373,23 @@ static void tex_aux_math_math_component(halfword target, int append)
}
break;
case 's': case 'S':
- if (tex_scan_mandate_keyword("source", 1)) {
- noad_source(target) = tex_scan_int(0, NULL);
+ switch (tex_scan_character("ioIO", 0, 0, 0)) {
+ case 'i': case 'I':
+ if (tex_scan_mandate_keyword("single", 2)) {
+ noad_options(target) |= noad_option_single;
+ }
+ break;
+ case 'o': case 'O':
+ if (tex_scan_mandate_keyword("source", 2)) {
+ noad_source(target) = tex_scan_int(0, NULL);
+ }
+ break;
+ default:
+ tex_aux_show_keyword_error("single|source");
+ goto DONE;
}
break;
- case 't': case 'T':
+ case 't': case 'T':
if (tex_scan_mandate_keyword("textfont", 1)) {
usetextfont = math_atom_text_font_option;
}
@@ -2928,6 +2950,7 @@ void tex_run_math_accent(void)
halfword code = cur_chr;
halfword accent = tex_new_node(accent_noad, bothflexible_accent_subtype);
quarterword subtype = ordinary_noad_subtype;
+ halfword mathclass = accent_noad_subtype;
halfword attrlist = null;
if (cur_cmd == accent_cmd) {
tex_handle_error(
@@ -2945,15 +2968,48 @@ void tex_run_math_accent(void)
case math_uaccent_code:
/*tex |\Umathaccent| */
while (1) {
- switch (tex_scan_character("abcnsftokABCNSFTOK", 0, 1, 0)) {
+ switch (tex_scan_character("abcensftokABCENSFTOK", 0, 1, 0)) {
case 'a': case 'A':
- if (tex_scan_mandate_keyword("attr", 1)) {
- attrlist = tex_scan_attribute(attrlist);
+ switch (tex_scan_character("txTX", 0, 0, 0)) {
+ case 't': case 'T':
+ if (tex_scan_mandate_keyword("attr", 2)) {
+ attrlist = tex_scan_attribute(attrlist);
+ }
+ break;
+ // case 'x': case 'X':
+ // if (tex_scan_mandate_keyword("axis", 2)) {
+ // noad_options(accent) |= noad_option_axis;
+ // }
+ // break;
+ default:
+ // tex_aux_show_keyword_error("attr|axis");
+ tex_aux_show_keyword_error("attr");
+ goto DONE;
}
break;
case 'c': case 'C':
- if (tex_scan_mandate_keyword("center", 1)) {
- noad_options(accent) |= noad_option_center;
+ switch (tex_scan_character("elEL", 0, 0, 0)) {
+ case 'e': case 'E':
+ if (tex_scan_mandate_keyword("center", 2)) {
+ noad_options(accent) |= noad_option_center;
+ }
+ break;
+ case 'l': case 'L':
+ if (tex_scan_mandate_keyword("class", 2)) {
+ halfword c = (quarterword) tex_scan_math_class_number(0);
+ if (valid_math_class_code(c)) {
+ mathclass = c;
+ }
+ }
+ break;
+ default:
+ tex_aux_show_keyword_error("center|class");
+ goto DONE;
+ }
+ break;
+ case 'e': case 'E':
+ if (tex_scan_mandate_keyword("exact", 1)) {
+ noad_options(accent) |= noad_option_exact;
}
break;
case 's': case 'S':
@@ -3104,6 +3160,7 @@ void tex_run_math_accent(void)
noad_nucleus(accent) = n;
tex_aux_scan_math(n, tex_math_style_variant(cur_list.math_style, math_parameter_accent_variant), 0, 0, 0, 0, unset_noad_class, unset_noad_class);
}
+ set_noad_main_class(accent, mathclass);
}
/*tex
@@ -4704,6 +4761,34 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor
*/
+static inline int tex_aux_class_from_glyph(halfword n) {
+ return node_subtype(n) - (node_subtype(n) > glyph_math_extra_subtype ? glyph_math_extra_subtype : glyph_math_ordinary_subtype);
+}
+
+static int tex_aux_short_math(halfword m)
+{
+ // tex_show_node_list(m,10000,10000);
+ if (m) {
+ /* kern[] glyph[subtype -> class] vlist[scripts] kern[] */
+ if (node_type(m) == kern_node) {
+ m = node_next(m);
+ }
+ if (m && node_type(m) == glyph_node && tex_math_has_class_option(tex_aux_class_from_glyph(m), short_inline_class_option)) {
+ m = node_next(m);
+ } else {
+ return 0;
+ }
+ if (m && node_type(m) == vlist_node && node_subtype(m) == math_scripts_list) {
+ m = node_next(m);
+ }
+ if (m && node_type(m) == kern_node) {
+ m = node_next(m);
+ }
+ return ! m;
+ }
+ return 0;
+}
+
void tex_run_math_shift(void)
{
switch (cur_group) {
@@ -4719,7 +4804,7 @@ void tex_run_math_shift(void)
int mode = cur_list.mode;
int mathmode = cur_list.math_mode;
/*tex this pops the nest, the formula */
- halfword p = tex_aux_finish_math_list(null);
+ halfword mathlist = tex_aux_finish_math_list(null);
int mathleft = cur_list.math_begin;
int mathright = cur_list.math_end;
if (cur_cmd == math_shift_cs_cmd) {
@@ -4745,7 +4830,7 @@ void tex_run_math_shift(void)
tex_aux_check_display_math_end();
break;
}
- tex_run_mlist_to_hlist(p, 0, text_style, unset_noad_class, unset_noad_class);
+ tex_run_mlist_to_hlist(mathlist, 0, text_style, unset_noad_class, unset_noad_class);
eqnumber = tex_hpack(node_next(temp_head), 0, packing_additional, direction_unknown, holding_none_option);
attach_current_attribute_list(eqnumber);
tex_aux_unsave_math();
@@ -4754,7 +4839,7 @@ void tex_run_math_shift(void)
if (saved_type(saved_equation_number_item_location) == equation_number_location_save_type) {
atleft = saved_value(saved_equation_number_item_location) == left_location_code;
mode = cur_list.mode;
- p = tex_aux_finish_math_list(null);
+ mathlist = tex_aux_finish_math_list(null);
} else {
tex_confusion("after math");
}
@@ -4769,7 +4854,9 @@ void tex_run_math_shift(void)
the space above that display.
*/
- halfword math = tex_new_node(math_node, begin_inline_math);
+ halfword beginmath = tex_new_node(math_node, begin_inline_math);
+ halfword endmath = tex_new_node(math_node, end_inline_math);
+ halfword shortmath = 0;
if (mathmode) {
switch (cur_cmd) {
case math_shift_cs_cmd:
@@ -4784,68 +4871,81 @@ void tex_run_math_shift(void)
} else if (cur_cmd == math_shift_cs_cmd) {
tex_aux_check_inline_math_end();
}
- tex_tail_append(math);
- math_penalty(math) = pre_inline_penalty_par;
+ tex_tail_append(beginmath);
+ if (pre_inline_penalty_par != max_integer) {
+ math_penalty(beginmath) = pre_inline_penalty_par;
+ }
/*tex begin mathskip code */
switch (math_skip_mode_par) {
case math_skip_surround_when_zero:
if (! tex_glue_is_zero(math_skip_par)) {
- tex_copy_glue_values(math, math_skip_par);
+ tex_copy_glue_values(beginmath, math_skip_par);
} else {
- math_surround(math) = math_surround_par;
+ math_surround(beginmath) = math_surround_par;
}
break ;
case math_skip_always_left:
case math_skip_always_both:
case math_skip_only_when_skip:
- tex_copy_glue_values(math, math_skip_par);
+ tex_copy_glue_values(beginmath, math_skip_par);
break ;
case math_skip_always_right:
case math_skip_ignore:
break ;
case math_skip_always_surround:
default:
- math_surround(math) = math_surround_par;
+ math_surround(beginmath) = math_surround_par;
break;
}
/*tex end mathskip code */
if (cur_list.math_dir) {
tex_tail_append(tex_new_dir(normal_dir_subtype, math_direction_par));
}
- tex_run_mlist_to_hlist(p, cur_list.mode > nomode, is_valid_math_style(cur_list.math_main_style) ? cur_list.math_main_style : text_style, cur_list.math_begin, cur_list.math_end);
+ tex_run_mlist_to_hlist(mathlist, cur_list.mode > nomode, is_valid_math_style(cur_list.math_main_style) ? cur_list.math_main_style : text_style, cur_list.math_begin, cur_list.math_end);
+ shortmath = tex_aux_short_math(node_next(temp_head));
tex_try_couple_nodes(cur_list.tail, node_next(temp_head));
cur_list.tail = tex_tail_of_node_list(cur_list.tail);
if (cur_list.math_dir) {
tex_tail_append(tex_new_dir(cancel_dir_subtype, math_direction_par));
}
cur_list.math_dir = 0;
- math = tex_new_node(math_node, end_inline_math);
- tex_tail_append(math);
- math_penalty(math) = post_inline_penalty_par;
+ tex_tail_append(endmath);
+ /* */
+ if (post_inline_penalty_par != max_integer) {
+ math_penalty(endmath) = post_inline_penalty_par;
+ }
/*tex begin mathskip code */
switch (math_skip_mode_par) {
case math_skip_surround_when_zero :
if (! tex_glue_is_zero(math_skip_par)) {
- tex_copy_glue_values(math, math_skip_par);
- math_surround(math) = 0;
+ tex_copy_glue_values(endmath, math_skip_par);
+ math_surround(endmath) = 0;
} else {
- math_surround(math) = math_surround_par;
+ math_surround(endmath) = math_surround_par;
}
break;
case math_skip_always_right:
case math_skip_always_both:
case math_skip_only_when_skip:
- tex_copy_glue_values(math, math_skip_par);
+ tex_copy_glue_values(endmath, math_skip_par);
break;
case math_skip_always_left:
case math_skip_ignore:
break;
case math_skip_always_surround:
default:
- math_surround(math) = math_surround_par;
+ math_surround(endmath) = math_surround_par;
break;
}
/*tex end mathskip code */
+ if (shortmath) {
+ if (pre_short_inline_penalty_par != max_integer) {
+ math_penalty(beginmath) = pre_short_inline_penalty_par;
+ }
+ if (post_short_inline_penalty_par != max_integer) {
+ math_penalty(endmath) = post_short_inline_penalty_par;
+ }
+ }
cur_list.space_factor = default_space_factor;
mathleft = cur_list.math_begin;
mathright = cur_list.math_end;
@@ -4858,7 +4958,7 @@ void tex_run_math_shift(void)
tex_aux_check_display_math_end();
}
}
- tex_run_mlist_to_hlist(p, 0, display_style, cur_list.math_begin, cur_list.math_end);
+ tex_run_mlist_to_hlist(mathlist, 0, display_style, cur_list.math_begin, cur_list.math_end);
mathleft = cur_list.math_begin;
mathright = cur_list.math_end;
tex_aux_finish_displayed_math(atleft, eqnumber, node_next(temp_head));