diff options
author | Hans Hagen <pragma@wxs.nl> | 2023-01-15 14:50:04 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2023-01-15 14:50:04 +0100 |
commit | 0caec226a633182402b349c3ac5b3bf9e0bc76c2 (patch) | |
tree | 30524574e0b41eb771f5f9af8cadc60354652aa3 /source | |
parent | 659b8f28e591006b6d0669c05d809d6ccf60cec0 (diff) | |
download | context-0caec226a633182402b349c3ac5b3bf9e0bc76c2.tar.gz |
2023-01-15 13:55:00
Diffstat (limited to 'source')
32 files changed, 1093 insertions, 1014 deletions
diff --git a/source/luametatex/source/lua/lmtinterface.c b/source/luametatex/source/lua/lmtinterface.c index 641c22f8f..9156f0aaf 100644 --- a/source/luametatex/source/lua/lmtinterface.c +++ b/source/luametatex/source/lua/lmtinterface.c @@ -106,7 +106,9 @@ void lmt_initialize_interface(void) set_group_code_value(also_simple_group, alsosimple); set_group_code_value(semi_simple_group, semisimple); set_group_code_value(math_simple_group, mathsimple); - set_group_code_value(math_shift_group, mathshift); + set_group_code_value(math_inline_group, mathinline); + set_group_code_value(math_display_group, mathdisplay); + set_group_code_value(math_number_group, mathnumber); set_group_code_value(math_fence_group, mathfence); set_group_code_value(local_box_group, localbox); set_group_code_value(split_off_group, splitoff); diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h index 40cfbad29..f5fd10900 100644 --- a/source/luametatex/source/lua/lmtinterface.h +++ b/source/luametatex/source/lua/lmtinterface.h @@ -918,7 +918,9 @@ make_lua_key(L, mathpostpenalty);\ make_lua_key(L, mathprepenalty);\ make_lua_key(L, mathradical);\ make_lua_key(L, mathshapekern);\ -make_lua_key(L, mathshift);\ +make_lua_key(L, mathinline);\ +make_lua_key(L, mathdisplay);\ +make_lua_key(L, mathnumber);\ make_lua_key(L, mathsimple);\ make_lua_key(L, mathskip);\ make_lua_key(L, mathspec);\ diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index 5ad42124d..116860f85 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -1048,14 +1048,19 @@ static int nodelib_direct_getnucleus(lua_State *L) case accent_noad: case radical_noad: nodelib_push_direct_or_nil(L, noad_nucleus(n)); - break; - default: - lua_pushnil(L); - break; + if (lua_toboolean(L, 2)) { + nodelib_push_direct_or_nil(L, noad_prime(n)); + nodelib_push_direct_or_nil(L, noad_supscr(n)); + nodelib_push_direct_or_nil(L, noad_subscr(n)); + nodelib_push_direct_or_nil(L, noad_supprescr(n)); + nodelib_push_direct_or_nil(L, noad_subprescr(n)); + return 6; + } else { + return 1; + } } - } else { - lua_pushnil(L); - } + } + lua_pushnil(L); return 1; } @@ -8780,7 +8785,7 @@ static int nodelib_direct_effectiveglue(lua_State *L) if (n) { switch (node_type(n)) { case glue_node: - nodelib_direct_effect_done(L, glue_amount(n), glue_stretch(n), glue_shrink(n),glue_stretch_order(n), glue_shrink_order(n)); + nodelib_direct_effect_done(L, glue_amount(n), glue_stretch(n), glue_shrink(n), glue_stretch_order(n), glue_shrink_order(n)); break; case math_node: if (math_surround(n)) { diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index ccabddaf4..93abb0814 100644 --- a/source/luametatex/source/luametatex.h +++ b/source/luametatex/source/luametatex.h @@ -89,7 +89,7 @@ # define luametatex_version 210 # define luametatex_revision 05 # define luametatex_version_string "2.10.05" -# define luametatex_development_id 20230101 +# define luametatex_development_id 20230112 # define luametatex_name_camelcase "LuaMetaTeX" # define luametatex_name_lowercase "luametatex" diff --git a/source/luametatex/source/luarest/lmtstrlibext.c b/source/luametatex/source/luarest/lmtstrlibext.c index ffc687ff4..31dc53c86 100644 --- a/source/luametatex/source/luarest/lmtstrlibext.c +++ b/source/luametatex/source/luarest/lmtstrlibext.c @@ -777,6 +777,74 @@ static int strlib_pack_rows_columns(lua_State* L) return 1; } +/*tex + This converts a hex string to characters. Spacing is ignored and invalid characters result in + a false result. EMpty strings are okay. +*/ + +static int strlib_hextocharacters(lua_State *L) +{ + size_t ls = 0; + const char *s = lua_tolstring(L, 1, &ls); + if (ls > 0) { + luaL_Buffer b; + luaL_buffinitsize(L, &b, ls/2); + while (1) { + unsigned char first = *s++; + switch (first) { + case ' ': case '\n': case '\r': case '\t': + continue; + case '\0': + goto DONE; + default: + { + unsigned char second = *s++; + switch (second) { + case ' ': case '\n': case '\r': case '\t': + continue; + case '\0': + goto BAD; + default: + { + unsigned char chr; + if (first >= '0' && first <= '9') { + chr = 16 * (first - '0'); + } else if (first>= 'A' && first <= 'F') { + chr = 16 * (first - 'A' + 10); + } else if (first >= 'a' && first <= 'f') { + chr = 16 * (first - 'a' + 10); + } else { + goto BAD; + } + if (second >= '0' && second <= '9') { + chr += second - '0'; + } else if (second >= 'A' && second <= 'F') { + chr += second - 'A' + 10; + } else if (first >= 'a' && second <= 'f') { + chr += second - 'a' + 10; + } else { + goto BAD; + } + luaL_addchar(&b, chr); + break; + } + } + break; + } + } + } + DONE: + luaL_pushresult(&b); + return 1; + BAD: + lua_pushboolean(L, 0); + return 1; + } else { + lua_pushliteral(L, ""); + return 1; + } +} + static const luaL_Reg strlib_function_list[] = { { "characters", strlib_characters }, { "characterpairs", strlib_characterpairs }, @@ -797,6 +865,7 @@ static const luaL_Reg strlib_function_list[] = { /* { "toutf16", strlib_format_toutf16 }, */ /* untested */ { "toutf32", strlib_format_toutf32 }, { "packrowscolumns", strlib_pack_rows_columns }, + { "hextocharacters", strlib_hextocharacters }, { NULL, NULL }, }; diff --git a/source/luametatex/source/tex/texadjust.c b/source/luametatex/source/tex/texadjust.c index f57853caf..11d2da6ad 100644 --- a/source/luametatex/source/tex/texadjust.c +++ b/source/luametatex/source/tex/texadjust.c @@ -4,26 +4,35 @@ # include "luametatex.h" -static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *index, scaled *depthbefore, scaled *depthafter, halfword *attrlist) +typedef struct adjust_properties { + halfword options; + halfword code; + halfword index; + scaled depthbefore; + scaled depthafter; + halfword attrlist; +} adjust_properties; + +static void tex_scan_adjust_keys(adjust_properties *properties) { - *code = post_adjust_code; - *options = adjust_option_none; - *index = 0; - *depthbefore = 0; - *depthafter = 0; - *attrlist = null; + properties->code = post_adjust_code; + properties->options = adjust_option_none; + properties->index = 0; + properties->depthbefore = 0; + properties->depthafter = 0; + properties->attrlist = null; while (1) { switch (tex_scan_character("abdipABDIP", 0, 1, 0)) { case 'p': case 'P': switch (tex_scan_character("roRO", 0, 0, 0)) { case 'r': case 'R': if (tex_scan_mandate_keyword("pre", 2)) { - *code = pre_adjust_code; + properties->code = pre_adjust_code; } break; case 'o': case 'O': if (tex_scan_mandate_keyword("post", 2)) { - *code = post_adjust_code; + properties->code = post_adjust_code; } break; default: @@ -35,12 +44,12 @@ static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *in switch (tex_scan_character("aeAE", 0, 0, 0)) { case 'a': case 'A': if (tex_scan_mandate_keyword("baseline", 2)) { - *options |= adjust_option_baseline; + properties->options |= adjust_option_baseline; } break; case 'e': case 'E': if (tex_scan_mandate_keyword("before", 2)) { - *options |= adjust_option_before; + properties->options |= adjust_option_before; } break; default: @@ -50,9 +59,9 @@ static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *in break; case 'i': case 'I': if (tex_scan_mandate_keyword("index", 1)) { - *index = tex_scan_int(0, NULL); - if (! tex_valid_adjust_index(*index)) { - *index = 0; /* for now no error */ + properties->index = tex_scan_int(0, NULL); + if (! tex_valid_adjust_index(properties->index)) { + properties->index = 0; /* for now no error */ } } break; @@ -60,7 +69,7 @@ static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *in switch (tex_scan_character("ftFT", 0, 0, 0)) { case 'f': case 'F': if (tex_scan_mandate_keyword("after", 2)) { - *options &= ~(adjust_option_before | *options); + properties->options &= ~(adjust_option_before | properties->options); } break; case 't': case 'T': @@ -68,10 +77,10 @@ static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *in halfword i = tex_scan_attribute_register_number(); halfword v = tex_scan_int(1, NULL); if (eq_value(register_attribute_location(i)) != v) { - if (*attrlist) { - *attrlist = tex_patch_attribute_list(*attrlist, i, v); + if (properties->attrlist) { + properties->attrlist = tex_patch_attribute_list(properties->attrlist, i, v); } else { - *attrlist = tex_copy_attribute_list_set(tex_current_attribute_list(), i, v); + properties->attrlist = tex_copy_attribute_list_set(tex_current_attribute_list(), i, v); } } } @@ -86,24 +95,24 @@ static void tex_scan_adjust_keys(halfword *options, halfword *code, halfword *in switch (tex_scan_character("abclABCL", 0, 1, 0)) { /* so a space is permitted */ case 'a': case 'A': if (tex_scan_mandate_keyword("after", 1)) { - *options |= adjust_option_depth_after; - *depthafter = tex_scan_dimen(0, 0, 0, 0, NULL); + properties->options |= adjust_option_depth_after; + properties->depthafter = tex_scan_dimen(0, 0, 0, 0, NULL); } break; case 'b': case 'B': if (tex_scan_mandate_keyword("before", 1)) { - *options |= adjust_option_depth_before; - *depthbefore = tex_scan_dimen(0, 0, 0, 0, NULL); + properties->options |= adjust_option_depth_before; + properties->depthbefore = tex_scan_dimen(0, 0, 0, 0, NULL); } break; case 'c': case 'C': if (tex_scan_mandate_keyword("check", 1)) { - *options |= adjust_option_depth_check; + properties->options |= adjust_option_depth_check; } break; case 'l': case 'L': if (tex_scan_mandate_keyword("last", 1)) { - *options |= adjust_option_depth_last; + properties->options |= adjust_option_depth_last; } break; default: @@ -125,21 +134,17 @@ int tex_valid_adjust_index(halfword n) return n >= 0; } -void tex_run_vadjust(void) +void tex_set_vadjust(halfword target) { - halfword code = post_adjust_code; - halfword options = adjust_option_none; - halfword index = 0; - scaled depthbefore = 0; - scaled depthafter = 0; - halfword attrlist = null; - tex_scan_adjust_keys(&options, &code, &index, &depthbefore, &depthafter, &attrlist); - tex_set_saved_record(saved_adjust_item_location, adjust_location_save_type, 0, code); - tex_set_saved_record(saved_adjust_item_options, adjust_options_save_type, 0, options); - tex_set_saved_record(saved_adjust_item_index, adjust_index_save_type, 0, index); - tex_set_saved_record(saved_adjust_item_attr_list, adjust_attr_list_save_type, 0, attrlist); - tex_set_saved_record(saved_adjust_item_depth_before, adjust_depth_before_save_type, 0, depthbefore); - tex_set_saved_record(saved_adjust_item_depth_after, adjust_depth_after_save_type, 0, depthafter); + adjust_properties properties; + tex_scan_adjust_keys(&properties); + tex_set_saved_record(saved_adjust_item_location, adjust_location_save_type, 0, properties.code); + tex_set_saved_record(saved_adjust_item_options, adjust_options_save_type, 0, properties.options); + tex_set_saved_record(saved_adjust_item_index, adjust_index_save_type, 0, properties.index); + tex_set_saved_record(saved_adjust_item_attr_list, adjust_attr_list_save_type, 0, properties.attrlist); + tex_set_saved_record(saved_adjust_item_depth_before, adjust_depth_before_save_type, 0, properties.depthbefore); + tex_set_saved_record(saved_adjust_item_depth_after, adjust_depth_after_save_type, 0, properties.depthafter); + tex_set_saved_record(saved_adjust_item_target, adjust_target_save_type, 0, target); lmt_save_state.save_stack_data.ptr += saved_adjust_n_of_items; tex_new_save_level(vadjust_group); tex_scan_left_brace(); @@ -149,29 +154,37 @@ void tex_run_vadjust(void) cur_list.prev_depth = ignore_depth_criterium_par; } +void tex_run_vadjust(void) +{ + tex_set_vadjust(-1); +} + void tex_finish_vadjust_group(void) { if (! tex_wrapped_up_paragraph(vadjust_par_context)) { - halfword box, topskip, adjust; /*tex for short-term use */ + halfword box, adjust, target; /*tex for short-term use */ tex_end_paragraph(vadjust_group, vadjust_par_context); - topskip = tex_new_glue_node(split_top_skip_par, top_skip_code); /* cheat */ tex_unsave(); lmt_save_state.save_stack_data.ptr -= saved_adjust_n_of_items; box = tex_vpack(node_next(cur_list.head), 0, packing_additional, max_dimen, direction_unknown, holding_none_option); tex_pop_nest(); adjust = tex_new_node(adjust_node, (quarterword) saved_value(saved_adjust_item_location)); - tex_tail_append(adjust); + target = saved_value(saved_adjust_item_target); adjust_list(adjust) = box_list(box); adjust_options(adjust) = (halfword) saved_value(saved_adjust_item_options); adjust_index(adjust) = (halfword) saved_value(saved_adjust_item_index); adjust_depth_before(adjust) = (halfword) saved_value(saved_adjust_item_depth_before); adjust_depth_after(adjust) = (halfword) saved_value(saved_adjust_item_depth_after); tex_attach_attribute_list_attribute(adjust, (halfword) saved_value(saved_adjust_item_attr_list)); - tex_flush_node(topskip); + if (target < 1) { + tex_tail_append(adjust); + } else { + tex_adjust_attach(target, adjust); + } box_list(box) = null; tex_flush_node(box); /* we never do the callback ... maybe move it outside */ - if (lmt_nest_state.nest_data.ptr == 0) { + if (target < 0 && lmt_nest_state.nest_data.ptr == 0) { if (! lmt_page_builder_state.output_active) { lmt_page_filter_callback(vadjust_page_context, 0); } @@ -182,7 +195,7 @@ void tex_finish_vadjust_group(void) /*tex Append or prepend vadjust nodes. Here head is a temp node! */ -halfword tex_append_adjust_list(halfword head, halfword tail, halfword adjust) +halfword tex_append_adjust_list(halfword head, halfword tail, halfword adjust, const char *detail) { while (adjust && node_type(adjust) == adjust_node) { halfword next = node_next(adjust); @@ -193,7 +206,7 @@ halfword tex_append_adjust_list(halfword head, halfword tail, halfword adjust) } if (tracing_adjusts_par > 1) { tex_begin_diagnostic(); - tex_print_format("[adjust: index %i, location %s, append]", adjust_index(adjust), tex_aux_subtype_str(adjust)); + tex_print_format("[adjust: index %i, location %s, append, %s]", adjust_index(adjust), tex_aux_subtype_str(adjust), detail); tex_print_node_list(adjust_list(adjust), "adjust",show_box_depth_par, show_box_breadth_par); tex_end_diagnostic(); } @@ -203,7 +216,7 @@ halfword tex_append_adjust_list(halfword head, halfword tail, halfword adjust) return tail; } -halfword tex_prepend_adjust_list(halfword head, halfword tail, halfword adjust) +halfword tex_prepend_adjust_list(halfword head, halfword tail, halfword adjust, const char *detail) { while (adjust && node_type(adjust) == adjust_node) { halfword next = node_next(adjust); @@ -216,7 +229,7 @@ halfword tex_prepend_adjust_list(halfword head, halfword tail, halfword adjust) } if (tracing_adjusts_par > 1) { tex_begin_diagnostic(); - tex_print_format("[adjust: index %i, location %s, prepend]", adjust_index(adjust), tex_aux_subtype_str(adjust)); + tex_print_format("[adjust: index %i, location %s, prepend, %s]", adjust_index(adjust), tex_aux_subtype_str(adjust), detail); tex_print_node_list(adjust_list(adjust), "adjust", show_box_depth_par, show_box_breadth_par); tex_end_diagnostic(); } @@ -227,84 +240,86 @@ halfword tex_prepend_adjust_list(halfword head, halfword tail, halfword adjust) void tex_inject_adjust_list(halfword adjust, int obeyoptions, halfword nextnode, const line_break_properties *properties) { - adjust = node_next(adjust); - if (adjust) { - while (adjust && node_type(adjust) == adjust_node) { - halfword list = adjust_list(adjust); - halfword next = node_next(adjust); - if (list) { - halfword prevnode = cur_list.tail; - if (tracing_adjusts_par > 1) { - tex_begin_diagnostic(); - tex_print_format("[adjust: index %i, location %s, inject]", adjust_index(adjust), tex_aux_subtype_str(adjust)); - tex_print_node_list(adjust_list(adjust), "adjust", show_box_depth_par, show_box_breadth_par); - tex_end_diagnostic(); - } - if (obeyoptions && has_adjust_option(adjust, adjust_option_baseline)) { - /*tex - Here we attach data to a line. On the todo is to prepend and append to - the lines (nicer when we number lines). - */ - if (node_type(list) == hlist_node || node_type(list) == vlist_node) { - if (nextnode) { - /*tex - This is the |pre| case where |nextnode| is the line to be appended - after the adjust box |list|. - */ - if (node_type(nextnode) == hlist_node || node_type(nextnode) == vlist_node) { - if (box_height(nextnode) > box_height(list)) { - box_height(list) = box_height(nextnode); - } - if (box_depth(list) > box_depth(nextnode)) { - box_depth(nextnode) = box_depth(list); - } - /* not ok yet */ - box_y_offset(nextnode) += box_height(nextnode); - tex_check_box_geometry(nextnode); - /* till here */ - box_height(nextnode) = 0; - box_depth(list) = 0; + if (adjust && node_type(adjust) == temp_node) { + adjust = node_next(adjust); + } + while (adjust && node_type(adjust) == adjust_node) { + halfword next = node_next(adjust); + halfword list = adjust_list(adjust); + if (tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: index %i, location %s, inject]", adjust_index(adjust), tex_aux_subtype_str(adjust)); + tex_print_node_list(adjust_list(adjust), "adjust", show_box_depth_par, show_box_breadth_par); + tex_end_diagnostic(); + } + if (list) { + if (obeyoptions && has_adjust_option(adjust, adjust_option_baseline)) { + /*tex + Here we attach data to a line. On the todo is to prepend and append to + the lines (nicer when we number lines). + */ + if (node_type(list) == hlist_node || node_type(list) == vlist_node) { + if (nextnode) { + /*tex + This is the |pre| case where |nextnode| is the line to be appended + after the adjust box |list|. + */ + if (node_type(nextnode) == hlist_node || node_type(nextnode) == vlist_node) { + if (box_height(nextnode) > box_height(list)) { + box_height(list) = box_height(nextnode); } - } else { - /*tex - Here we have the |post| case where the line will end up before the - adjusted content. - */ - if (node_type(prevnode) == hlist_node || node_type(prevnode) == vlist_node) { - if (box_height(prevnode) < box_height(list)) { - box_height(prevnode) = box_height(list); - } - if (box_depth(list) < box_depth(prevnode)) { - box_depth(list) = box_depth(prevnode); - } - box_height(list) = 0; - box_depth(prevnode) = 0; + if (box_depth(list) > box_depth(nextnode)) { + box_depth(nextnode) = box_depth(list); + } + /* not ok yet */ + box_y_offset(nextnode) += box_height(nextnode); + tex_check_box_geometry(nextnode); + /* till here */ + box_height(nextnode) = 0; + box_depth(list) = 0; + } + } else { + /*tex + Here we have the |post| case where the line will end up before the + adjusted content. + */ + halfword prevnode = cur_list.tail; + if (node_type(prevnode) == hlist_node || node_type(prevnode) == vlist_node) { + if (box_height(prevnode) < box_height(list)) { + box_height(prevnode) = box_height(list); + } + if (box_depth(list) < box_depth(prevnode)) { + box_depth(list) = box_depth(prevnode); } + box_height(list) = 0; + box_depth(prevnode) = 0; } } } - if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_before)) { - cur_list.prev_depth = adjust_depth_before(adjust); - } - if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_check)) { - tex_append_to_vlist(list, -1, properties); - } else { - tex_couple_nodes(prevnode, list); - } - if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_after)) { - cur_list.prev_depth = adjust_depth_after(adjust); - } else if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_last)) { - cur_list.prev_depth = box_depth(list); - } - cur_list.tail = tex_tail_of_node_list(cur_list.tail); - if (! lmt_page_builder_state.output_active) { - lmt_append_line_filter_callback(post_adjust_append_line_context, adjust_index(adjust)); - } + } + if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_before)) { + cur_list.prev_depth = adjust_depth_before(adjust); + } + if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_check)) { + tex_append_to_vlist(list, -1, properties); + } else { + tex_tail_append_list(list); + // tex_couple_nodes(prevnode, list); + // cur_list.tail = tex_tail_of_node_list(list); + } + if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_after)) { + cur_list.prev_depth = adjust_depth_after(adjust); + } else if (obeyoptions && has_adjust_option(adjust, adjust_option_depth_last)) { + cur_list.prev_depth = box_depth(list); + } +// cur_list.tail = tex_tail_of_node_list(cur_list.tail); + if (! lmt_page_builder_state.output_active) { + lmt_append_line_filter_callback(post_adjust_append_line_context, adjust_index(adjust)); } adjust_list(adjust) = null; - tex_flush_node(adjust); - adjust = next; } + tex_flush_node(adjust); + adjust = next; } } @@ -313,6 +328,12 @@ void tex_adjust_attach(halfword box, halfword adjust) if (adjust_list(adjust)) { node_prev(adjust) = null; node_next(adjust) = null; + if (tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: index %i, location %s, attach]", adjust_index(adjust), tex_aux_subtype_str(adjust)); + tex_print_node_list(adjust_list(adjust), "attach",show_box_depth_par, show_box_breadth_par); + tex_end_diagnostic(); + } switch (node_subtype(adjust)) { case pre_adjust_code: if (! box_pre_adjusted(box)) { @@ -356,9 +377,9 @@ void tex_adjust_passon(halfword box, halfword adjust) case pre_adjust_code: if (lmt_packaging_state.pre_adjust_tail) { if (lmt_packaging_state.pre_adjust_tail != pre_adjust_head && has_adjust_option(adjust, adjust_option_before)) { - lmt_packaging_state.pre_adjust_tail = tex_prepend_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, adjust); + lmt_packaging_state.pre_adjust_tail = tex_prepend_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, adjust, "passon"); } else { - lmt_packaging_state.pre_adjust_tail = tex_append_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, adjust); + lmt_packaging_state.pre_adjust_tail = tex_append_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, adjust, "passon"); } } else { tex_normal_error("vadjust pre", "invalid list"); @@ -367,9 +388,9 @@ void tex_adjust_passon(halfword box, halfword adjust) case post_adjust_code: if (lmt_packaging_state.post_adjust_tail) { if (lmt_packaging_state.post_adjust_tail != post_adjust_head && has_adjust_option(adjust, adjust_option_before)) { - lmt_packaging_state.post_adjust_tail = tex_prepend_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, adjust); + lmt_packaging_state.post_adjust_tail = tex_prepend_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, adjust, "passon"); } else { - lmt_packaging_state.post_adjust_tail = tex_append_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, adjust); + lmt_packaging_state.post_adjust_tail = tex_append_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, adjust, "passon"); } } else { tex_normal_error("vadjust post", "invalid list"); @@ -384,6 +405,64 @@ void tex_adjust_passon(halfword box, halfword adjust) } } +static void tex_aux_show_flush_adjust(halfword adjust, const char *what, const char *detail) +{ + if (tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: index %i, location %s, flush, %s]", adjust_index(adjust), tex_aux_subtype_str(adjust), detail); + tex_print_node_list(adjust_list(adjust), what, show_box_depth_par, show_box_breadth_par); + tex_end_diagnostic(); + } +} + +halfword tex_flush_adjust_append(halfword adjust, halfword tail) +{ + while (adjust) { + halfword p = adjust; + halfword h = adjust_list(adjust); + if (h) { + int ishmode = is_h_mode(cur_list.mode); + tex_aux_show_flush_adjust(p, "append", ishmode ? "repack" : "direct"); + if (ishmode) { + halfword n = tex_new_node(adjust_node, post_adjust_code); + // tex_attach_attribute_list_copy(n, post_adjusted); + adjust_list(n) = h; + h = n; + } + tex_try_couple_nodes(tail, h); + tail = tex_tail_of_node_list(h); + adjust_list(p) = null; + } + adjust = node_next(p); + tex_flush_node(p); + } + return tail; +} + +halfword tex_flush_adjust_prepend(halfword adjust, halfword tail) +{ + while (adjust) { + halfword p = adjust; + halfword h = adjust_list(adjust); + if (h) { + int ishmode = is_h_mode(cur_list.mode); + tex_aux_show_flush_adjust(p, "prepend", ishmode ? "repack" : "direct"); + if (ishmode) { + halfword n = tex_new_node(adjust_node, pre_adjust_code); + // tex_attach_attribute_list_copy(n, pre_adjusted); + adjust_list(n) = h; + h = n; + } + tex_try_couple_nodes(tail, h); + tail = tex_tail_of_node_list(h); + adjust_list(p) = null; + } + adjust = node_next(p); + tex_flush_node(p); + } + return tail; +} + void tex_initialize_adjust(void) { } diff --git a/source/luametatex/source/tex/texadjust.h b/source/luametatex/source/tex/texadjust.h index 19c116f26..ea1c88f43 100644 --- a/source/luametatex/source/tex/texadjust.h +++ b/source/luametatex/source/tex/texadjust.h @@ -8,29 +8,34 @@ # define LMT_ADJUST_H typedef enum saved_adjust_items { - saved_adjust_item_location = 0, - saved_adjust_item_options = 1, - saved_adjust_item_index = 2, - saved_adjust_item_attr_list = 3, - saved_adjust_item_depth_before = 4, - saved_adjust_item_depth_after = 5, - saved_adjust_n_of_items = 6, + saved_adjust_item_location, + saved_adjust_item_options, + saved_adjust_item_index, + saved_adjust_item_attr_list, + saved_adjust_item_depth_before, + saved_adjust_item_depth_after, + saved_adjust_item_target, + saved_adjust_n_of_items, } saved_adjust_items; -extern void tex_initialize_adjust (void); -extern void tex_cleanup_adjust (void); - -extern void tex_run_vadjust (void); -extern void tex_finish_vadjust_group (void); - -extern int tex_valid_adjust_index (halfword n); - -extern void tex_inject_adjust_list (halfword list, int obeyoptions, halfword nextnode, const line_break_properties *properties); - -extern void tex_adjust_passon (halfword box, halfword adjust); -extern void tex_adjust_attach (halfword box, halfword adjust); - -extern halfword tex_prepend_adjust_list (halfword head, halfword tail, halfword adjust); -extern halfword tex_append_adjust_list (halfword head, halfword tail, halfword adjust); +extern void tex_initialize_adjust (void); +extern void tex_cleanup_adjust (void); + +extern void tex_run_vadjust (void); +extern void tex_set_vadjust (halfword target); +extern void tex_finish_vadjust_group (void); + +extern int tex_valid_adjust_index (halfword n); + +extern void tex_inject_adjust_list (halfword list, int obeyoptions, halfword nextnode, const line_break_properties *properties); + +extern void tex_adjust_passon (halfword box, halfword adjust); +extern void tex_adjust_attach (halfword box, halfword adjust); + +extern halfword tex_prepend_adjust_list (halfword head, halfword tail, halfword adjust, const char *detail); +extern halfword tex_append_adjust_list (halfword head, halfword tail, halfword adjust, const char *detail); + +extern halfword tex_flush_adjust_append (halfword adjust, halfword tail); +extern halfword tex_flush_adjust_prepend (halfword adjust, halfword tail); # endif
\ No newline at end of file diff --git a/source/luametatex/source/tex/texalign.c b/source/luametatex/source/tex/texalign.c index c8e4ed9dc..4ea4879c2 100644 --- a/source/luametatex/source/tex/texalign.c +++ b/source/luametatex/source/tex/texalign.c @@ -1066,7 +1066,7 @@ static void tex_aux_initialize_span(halfword p) { tex_push_nest(); if (cur_list.mode == restricted_hmode) { - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; } else { cur_list.prev_depth = ignore_depth_criterium_par; tex_normal_paragraph(span_par_context); @@ -1421,7 +1421,7 @@ static void tex_aux_finish_row(void) row = tex_filtered_vpack(node_next(cur_list.head), 0, packing_additional, max_depth_par, finish_row_group, direction_unknown, 0, null, 0, 0); tex_pop_nest(); tex_tail_append(row); - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; } /*tex Currently this one can be overloaded by the one set on the row via the noalign trickery @@ -1769,11 +1769,11 @@ static void tex_aux_finish_align(void) halfword preptr; halfword colptr; if (cur_list.mode == internal_vmode) { - /* tex_aux_change_list_type(rowptr, hlist_node); */ /* too much */ + /* tex_aux_change_list_type(rowptr, hlist_node); */ /* too much, needs checking */ node_type(rowptr) = hlist_node; box_width(rowptr) = box_width(preroll); } else { - /* tex_aux_change_list_type(rowptr, vlist_node); */ /* too much */ + /* tex_aux_change_list_type(rowptr, vlist_node); */ /* too much, needs checking */ node_type(rowptr) = vlist_node; box_height(rowptr) = box_height(preroll); } diff --git a/source/luametatex/source/tex/texbuildpage.c b/source/luametatex/source/tex/texbuildpage.c index 947ef1776..be75042eb 100644 --- a/source/luametatex/source/tex/texbuildpage.c +++ b/source/luametatex/source/tex/texbuildpage.c @@ -337,14 +337,32 @@ static halfword tex_aux_page_badness(scaled goal) } } +static halfword tex_aux_insert_topskip(halfword height, int contribution) +{ + if (lmt_page_builder_state.contents != contribute_nothing) { + lmt_page_builder_state.contents = contribution; + } else { + tex_aux_freeze_page_specs(contribution); + } + { + halfword glue = tex_new_param_glue_node(top_skip_code, top_skip_glue); + if (glue_amount(glue) > height) { + glue_amount(glue) -= height; + } else { + glue_amount(glue) = 0; + } + return glue; + } +} + void tex_build_page(void) { if (node_next(contribute_head) && ! lmt_page_builder_state.output_active) { /*tex The (upcoming) penalty to be added to the badness: */ - int pi = 0; + int penalty = 0; do { - halfword p = node_next(contribute_head); - halfword last_type = node_type(p); + halfword current = node_next(contribute_head); + halfword type = node_type(current); /*tex Update the values of |last_glue|, |last_penalty|, and |last_kern|. */ if (lmt_page_builder_state.last_glue != max_halfword) { tex_flush_node(lmt_page_builder_state.last_glue); @@ -353,21 +371,21 @@ void tex_build_page(void) lmt_page_builder_state.last_penalty = 0; lmt_page_builder_state.last_kern = 0; lmt_page_builder_state.last_boundary = 0; - lmt_page_builder_state.last_node_type = last_type; - lmt_page_builder_state.last_node_subtype = node_subtype(p); + lmt_page_builder_state.last_node_type = type; + lmt_page_builder_state.last_node_subtype = node_subtype(current); lmt_page_builder_state.last_extra_used = 0; - switch (last_type) { + switch (type) { case glue_node: - lmt_page_builder_state.last_glue = tex_new_glue_node(p, node_subtype(p)); + lmt_page_builder_state.last_glue = tex_new_glue_node(current, node_subtype(current)); break; case penalty_node: - lmt_page_builder_state.last_penalty = penalty_amount(p); + lmt_page_builder_state.last_penalty = penalty_amount(current); break; case kern_node: - lmt_page_builder_state.last_kern = kern_amount(p); + lmt_page_builder_state.last_kern = kern_amount(current); break; case boundary_node: - lmt_page_builder_state.last_boundary = boundary_data(p); + lmt_page_builder_state.last_boundary = boundary_data(current); break; } /*tex @@ -392,102 +410,96 @@ void tex_build_page(void) the contribution list will not be contributed until we know its successor. */ - switch (last_type) { + switch (type) { case hlist_node: case vlist_node: - if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_post)) { - halfword h = box_post_migrated(p); - if (h) { - halfword t = tex_tail_of_node_list(h); - if (node_next(p)) { - tex_couple_nodes(t, node_next(p)); - } else { - contribute_tail = t; + { + if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_post)) { + halfword head = box_post_migrated(current); + if (head) { + halfword tail = tex_tail_of_node_list(head); + if (tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: post, mvl]"); + tex_print_node_list(head,"post",show_box_depth_par, show_box_breadth_par); + tex_end_diagnostic(); + } + if (node_next(current)) { + tex_couple_nodes(tail, node_next(current)); + } else { + contribute_tail = tail; + } + tex_couple_nodes(current, head); + box_post_migrated(current) = null; } - tex_couple_nodes(p, h); - box_post_migrated(p) = null; } - } - if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_pre)) { - halfword h = box_pre_migrated(p); - if (h) { - halfword t = tex_tail_of_node_list(h); - tex_couple_nodes(t, p); - tex_couple_nodes(contribute_head, h); - box_pre_migrated(p) = null; - continue; - } - } - /* common with rule */ - if (lmt_page_builder_state.contents < contribute_box) { // nothing or insert - /*tex - Initialize the current page, insert the |\topskip| glue ahead of |p|, - and |goto continue|. - */ - halfword q; - if (lmt_page_builder_state.contents != contribute_nothing) { - lmt_page_builder_state.contents = contribute_box; - } else { - tex_aux_freeze_page_specs(contribute_box); + if (auto_migrating_mode_permitted(auto_migration_mode_par, auto_migrate_pre)) { + halfword head = box_pre_migrated(current); + if (head) { + halfword tail = tex_tail_of_node_list(head); + if (tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: pre, mvl]"); + tex_print_node_list(head,"pre",show_box_depth_par, show_box_breadth_par); + tex_end_diagnostic(); + } + tex_couple_nodes(tail, current); + tex_couple_nodes(contribute_head, current); + // if (contribute_head == contribute_tail) { + // contribute_tail = tail; + // } + box_pre_migrated(current) = null; + continue; + } } - q = tex_new_param_glue_node(top_skip_code, top_skip_glue); - if (glue_amount(q) > box_height(p)) { - glue_amount(q) -= box_height(p); + if (lmt_page_builder_state.contents < contribute_box) { + /*tex + Initialize the current page, insert the |\topskip| glue ahead of |p|, + and |goto continue|. + */ + halfword gluenode = tex_aux_insert_topskip(box_height(current), contribute_box); + tex_couple_nodes(gluenode, current); + tex_couple_nodes(contribute_head, gluenode); + continue; } else { - glue_amount(q) = 0; + /*tex Move a box to the current page, then |goto contribute|. */ + page_total += page_depth + box_height(current); + page_depth = box_depth(current); + goto CONTRIBUTE; } - tex_couple_nodes(q, p); - tex_couple_nodes(contribute_head, q); - continue; - } else { - /*tex Move a box to the current page, then |goto contribute|. */ - page_total += page_depth + box_height(p); - page_depth = box_depth(p); - goto CONTRIBUTE; } case rule_node: /* common with box */ if (lmt_page_builder_state.contents < contribute_box) { - halfword q; - if (lmt_page_builder_state.contents != contribute_nothing) { - lmt_page_builder_state.contents = contribute_rule; - } else { - tex_aux_freeze_page_specs(contribute_rule); - } - q = tex_new_param_glue_node(top_skip_code, top_skip_glue); - if (glue_amount(q) > rule_height(p)) { - glue_amount(q) -= rule_height(p); - } else { - glue_amount(q) = 0; - } - tex_couple_nodes(q, p); - tex_couple_nodes(contribute_head, q); + halfword gluenode = tex_aux_insert_topskip(rule_height(current), contribute_rule); + tex_couple_nodes(gluenode, current); + tex_couple_nodes(contribute_head, gluenode); continue; } else { - page_total += page_depth + rule_height(p); - page_depth = rule_depth(p); + page_total += page_depth + rule_height(current); + page_depth = rule_depth(current); goto CONTRIBUTE; } case boundary_node: if (lmt_page_builder_state.contents < contribute_box) { goto DISCARD; - } else if (node_subtype(p) == page_boundary) { + } else if (node_subtype(current) == page_boundary) { /*tex We just triggered the pagebuilder for which we needed a contribution. We fake a zero penalty so that all gets processed. The main rationale is that we get a better indication of what we do. Of course a callback can remove this node so that it is never seen. Triggering from the callback is not doable. */ - halfword n = tex_new_node(penalty_node, user_penalty_subtype); + halfword penaltynode = tex_new_node(penalty_node, user_penalty_subtype); /* todo: copy attributes */ tex_page_boundary_message("processed as penalty", 0); - tex_try_couple_nodes(node_prev(p), n); - tex_try_couple_nodes(n, node_next(p)); - tex_flush_node(p); - penalty_amount(n) = boundary_data(p); - p = n; - node_next(contribute_head) = p; - pi = 0; + tex_try_couple_nodes(node_prev(current), penaltynode); + tex_try_couple_nodes(penaltynode, node_next(current)); + tex_flush_node(current); + penalty_amount(penaltynode) = boundary_data(current); + current = penaltynode; + node_next(contribute_head) = current; + penalty = 0; break; } else { goto DISCARD; @@ -498,7 +510,7 @@ void tex_build_page(void) if (lmt_page_builder_state.contents < contribute_box) { goto DISCARD; } else if (precedes_break(lmt_page_builder_state.page_tail)) { - pi = 0; + penalty = 0; break; } else { goto UPDATEHEIGHTS; @@ -506,10 +518,10 @@ void tex_build_page(void) case kern_node: if (lmt_page_builder_state.contents < contribute_box) { goto DISCARD; - } else if (! node_next(p)) { + } else if (! node_next(current)) { return; - } else if (node_type(node_next(p)) == glue_node) { - pi = 0; + } else if (node_type(node_next(current)) == glue_node) { + penalty = 0; break; } else { goto UPDATEHEIGHTS; @@ -518,7 +530,7 @@ void tex_build_page(void) if (lmt_page_builder_state.contents < contribute_box) { goto DISCARD; } else { - pi = penalty_amount(p); + penalty = penalty_amount(current); break; } case mark_node: @@ -529,7 +541,7 @@ void tex_build_page(void) Append an insertion to the current page and |goto contribute|. The insertion number (index) is registered in the subtype (not any more for a while). */ - halfword index = insert_index(p); /* initially 65K */ + halfword index = insert_index(current); /* initially 65K */ halfword location = page_insert_head; halfword multiplier = tex_get_insert_multiplier(index); halfword content = tex_get_insert_content(index); @@ -568,13 +580,13 @@ void tex_build_page(void) general). */ - halfword q = tex_new_node(split_node, normal_split_subtype); + halfword splitnode = tex_new_node(split_node, normal_split_subtype); scaled advance = 0; halfword distance = lmt_get_insert_distance(index, slot); /*tex Callback: we get a copy! */ - split_insert_index(q) = index; - tex_try_couple_nodes(q, node_next(location)); - tex_couple_nodes(location, q); - location = q; + split_insert_index(splitnode) = index; + tex_try_couple_nodes(splitnode, node_next(location)); + tex_couple_nodes(location, splitnode); + location = splitnode; if (! tex_aux_valid_insert_content(content)) { content = tex_aux_delete_box_content(content); tex_set_insert_content(index, content); @@ -612,19 +624,19 @@ void tex_build_page(void) } /*tex I really need to check this logic with the original \LUATEX\ code. */ if (node_type(location) == split_node && node_subtype(location) == insert_split_subtype) { - lmt_page_builder_state.insert_penalties += insert_float_cost(p); + lmt_page_builder_state.insert_penalties += insert_float_cost(current); } else { scaled delta = page_goal - page_total - page_depth + page_shrink; - scaled needed = insert_total_height(p); - split_last_insert(location) = p; + scaled needed = insert_total_height(current); + split_last_insert(location) = current; /*tex This much room is left if we shrink the maximum. */ if (multiplier != 1000) { /*tex This much room is needed. */ needed = tex_x_over_n(needed, 1000) * multiplier; } - if ((needed <= 0 || needed <= delta) && (insert_total_height(p) + box_height(location) <= limit)) { - update_page_goal(index, insert_total_height(p), needed); - box_height(location) += insert_total_height(p); + if ((needed <= 0 || needed <= delta) && (insert_total_height(current) + box_height(location) <= limit)) { + update_page_goal(index, insert_total_height(current), needed); + box_height(location) += insert_total_height(current); } else { /*tex @@ -645,7 +657,7 @@ void tex_build_page(void) */ scaled height; - halfword brk, penalty; + halfword breaknode, penalty; if (multiplier <= 0) { height = max_dimen; } else { @@ -657,9 +669,9 @@ void tex_build_page(void) if (height > limit - box_height(location)) { height = limit - box_height(location); } - brk = tex_vert_break(insert_list(p), height, insert_max_depth(p)); + breaknode = tex_vert_break(insert_list(current), height, insert_max_depth(current)); box_height(location) += lmt_packaging_state.best_height_plus_depth; - penalty = brk ? (node_type(brk) == penalty_node ? penalty_amount(brk) : 0) : eject_penalty; + penalty = breaknode ? (node_type(breaknode) == penalty_node ? penalty_amount(breaknode) : 0) : eject_penalty; if (tracing_pages_par > 0) { tex_aux_display_insertion_split_cost(index, height, penalty); } @@ -668,15 +680,15 @@ void tex_build_page(void) } update_page_goal(index, lmt_packaging_state.best_height_plus_depth, lmt_packaging_state.best_height_plus_depth); node_subtype(location) = insert_split_subtype; - split_broken(location) = brk; - split_broken_insert(location) = p; + split_broken(location) = breaknode; + split_broken_insert(location) = current; lmt_page_builder_state.insert_penalties += penalty; } } goto CONTRIBUTE; } default: - tex_formatted_error("pagebuilder", "invalid node of type %d in vertical mode", node_type(p)); + tex_formatted_error("pagebuilder", "invalid node of type %d in vertical mode", node_type(current)); break; } /*tex @@ -684,7 +696,7 @@ void tex_build_page(void) prepare for output, and either fire up the users output routine and |return| or ship out the page and |goto done|. */ - if (pi < infinite_penalty) { + if (penalty < infinite_penalty) { /*tex Compute the badness, |b|, of the current page, using |awful_bad| if the box is too full. The |c| variable holds the costs. @@ -714,10 +726,10 @@ void tex_build_page(void) } if (badness >= awful_bad) { criterium = badness; - } else if (pi <= eject_penalty) { - criterium = pi; + } else if (penalty <= eject_penalty) { + criterium = penalty; } else if (badness < infinite_bad) { - criterium = badness + pi + lmt_page_builder_state.insert_penalties; + criterium = badness + penalty + lmt_page_builder_state.insert_penalties; } else { criterium = deplorable; } @@ -726,24 +738,24 @@ void tex_build_page(void) } { int moveon = criterium <= lmt_page_builder_state.least_cost; - int fireup = criterium == awful_bad || pi <= eject_penalty; + int fireup = criterium == awful_bad || penalty <= eject_penalty; if (tracing_pages_par > 0) { - tex_aux_display_page_break_cost(badness, pi, criterium, moveon, fireup); + tex_aux_display_page_break_cost(badness, penalty, criterium, moveon, fireup); } if (moveon) { - halfword r = node_next(page_insert_head); - lmt_page_builder_state.best_break = p; + halfword insert = node_next(page_insert_head); + lmt_page_builder_state.best_break = current; lmt_page_builder_state.best_size = page_goal; lmt_page_builder_state.insert_penalties = 0; lmt_page_builder_state.least_cost = criterium; - while (r != page_insert_head) { - split_best_insert(r) = split_last_insert(r); - r = node_next(r); + while (insert != page_insert_head) { + split_best_insert(insert) = split_last_insert(insert); + insert = node_next(insert); } } if (fireup) { /*tex Output the current page at the best place. */ - tex_aux_fire_up(p); + tex_aux_fire_up(current); if (lmt_page_builder_state.output_active) { /*tex User's output routine will act. */ return; @@ -759,19 +771,19 @@ void tex_build_page(void) Go here to record glue in the |active_height| table. Update the current page measurements with respect to the glue or kern specified by node~|p|. */ - switch(node_type(p)) { + switch(node_type(current)) { case kern_node: - page_total += page_depth + kern_amount(p); + page_total += page_depth + kern_amount(current); page_depth = 0; goto APPEND; case glue_node: - if (glue_stretch_order(p) > 1) { - page_stretch_1(glue_stretch_order(p)) += glue_stretch(p); + if (glue_stretch_order(current) > 1) { + page_stretch_1(glue_stretch_order(current)) += glue_stretch(current); } else { - page_stretch_2(glue_stretch_order(p)) += glue_stretch(p); + page_stretch_2(glue_stretch_order(current)) += glue_stretch(current); } - page_shrink += glue_shrink(p); - if (glue_shrink_order(p) != normal_glue_order && glue_shrink(p)) { + page_shrink += glue_shrink(current); + if (glue_shrink_order(current) != normal_glue_order && glue_shrink(current)) { tex_handle_error( normal_error_type, "Infinite glue shrinkage found on current page", @@ -779,10 +791,10 @@ void tex_build_page(void) "'\\vss' or '\\vskip 0pt minus 1fil'. Such glue doesn't belong there; but you can\n" "safely proceed, since the offensive shrinkability has been made finite." ); - tex_reset_glue_to_zero(p); - glue_shrink_order(p) = normal_glue_order; + tex_reset_glue_to_zero(current); + glue_shrink_order(current) = normal_glue_order; } - page_total += page_depth + glue_amount(p); + page_total += page_depth + glue_amount(current); page_depth = 0; goto APPEND; } @@ -796,25 +808,25 @@ void tex_build_page(void) page_depth = lmt_page_builder_state.max_depth; } APPEND: - /*tex Link node |p| into the current page and |goto done|. We assume a positive depth. */ - tex_couple_nodes(lmt_page_builder_state.page_tail, p); - lmt_page_builder_state.page_tail = p; - tex_try_couple_nodes(contribute_head, node_next(p)); - node_next(p) = null; - continue; + /*tex Link node |p| into the current page and |goto done|. We assume a positive depth. */ + tex_couple_nodes(lmt_page_builder_state.page_tail, current); + lmt_page_builder_state.page_tail = current; + tex_try_couple_nodes(contribute_head, node_next(current)); + node_next(current) = null; + continue; // or: break; DISCARD: /*tex Recycle node |p|. */ - tex_try_couple_nodes(contribute_head, node_next(p)); - node_next(p) = null; + tex_try_couple_nodes(contribute_head, node_next(current)); + node_next(current) = null; if (saving_vdiscards_par > 0) { if (lmt_packaging_state.page_discards_head) { - tex_couple_nodes(lmt_packaging_state.page_discards_tail, p); + tex_couple_nodes(lmt_packaging_state.page_discards_tail, current); } else { - lmt_packaging_state.page_discards_head = p; + lmt_packaging_state.page_discards_head = current; } - lmt_packaging_state.page_discards_tail = p; + lmt_packaging_state.page_discards_tail = current; } else { - tex_flush_node_list(p); + tex_flush_node_list(current); } } while (node_next(contribute_head)); /*tex Make the contribution list empty by setting its tail to |contribute_head|. */ diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 5c8328d52..03bcc34d1 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -559,6 +559,7 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "boxrepack", set_box_property_cmd, box_repack_code, 0); tex_primitive(luatex_command, "boxfreeze", set_box_property_cmd, box_freeze_code, 0); tex_primitive(luatex_command, "boxattribute", set_box_property_cmd, box_attribute_code, 0); + tex_primitive(luatex_command, "boxvadjust", set_box_property_cmd, box_vadjust_code, 0); tex_primitive(tex_command, "lastpenalty", some_item_cmd, lastpenalty_code, 0); tex_primitive(tex_command, "lastkern", some_item_cmd, lastkern_code, 0); @@ -707,7 +708,9 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "ifzeronum", if_test_cmd, if_zero_int_code, 0); tex_primitive(luatex_command, "ifzerodim", if_test_cmd, if_zero_dim_code, 0); tex_primitive(luatex_command, "ifchknum", if_test_cmd, if_chk_int_code, 0); + tex_primitive(luatex_command, "ifchknumber", if_test_cmd, if_chk_integer_code, 0); tex_primitive(luatex_command, "ifchkdim", if_test_cmd, if_chk_dim_code, 0); + tex_primitive(luatex_command, "ifchkdimension", if_test_cmd, if_chk_dimension_code, 0); tex_primitive(luatex_command, "ifcmpnum", if_test_cmd, if_cmp_int_code, 0); tex_primitive(luatex_command, "ifcmpdim", if_test_cmd, if_cmp_dim_code, 0); tex_primitive(luatex_command, "ifnumval", if_test_cmd, if_val_int_code, 0); @@ -896,6 +899,8 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "localrightboxbox", make_box_cmd, local_right_box_box_code, 0); tex_primitive(luatex_command, "localmiddleboxbox", make_box_cmd, local_middle_box_box_code, 0); + /*tex Begin compatibility. */ + tex_primitive(tex_command, "mathord", math_component_cmd, math_component_ordinary_code, 0); tex_primitive(tex_command, "mathop", math_component_cmd, math_component_operator_code, 0); tex_primitive(tex_command, "mathbin", math_component_cmd, math_component_binary_code, 0); @@ -904,13 +909,26 @@ void tex_initialize_commands(void) tex_primitive(tex_command, "mathclose", math_component_cmd, math_component_close_code, 0); tex_primitive(tex_command, "mathpunct", math_component_cmd, math_component_punctuation_code, 0); tex_primitive(tex_command, "mathinner", math_component_cmd, math_component_inner_code, 0); - tex_primitive(luatex_command, "mathfrac", math_component_cmd, math_component_fraction_code, 0); - tex_primitive(luatex_command, "mathrad", math_component_cmd, math_component_radical_code, 0); + tex_primitive(tex_command, "underline", math_component_cmd, math_component_under_code, 0); + tex_primitive(tex_command, "overline", math_component_cmd, math_component_over_code, 0); + + /*tex End compatibility. */ + + tex_primitive(luatex_command, "mathordinary", math_component_cmd, math_component_ordinary_code, 0); + tex_primitive(luatex_command, "mathoperator", math_component_cmd, math_component_operator_code, 0); + tex_primitive(luatex_command, "mathbinary", math_component_cmd, math_component_binary_code, 0); + tex_primitive(luatex_command, "mathrelation", math_component_cmd, math_component_relation_code, 0); + tex_primitive(luatex_command, "mathopen", math_component_cmd, math_component_open_code, 0); + tex_primitive(luatex_command, "mathclose", math_component_cmd, math_component_close_code, 0); + tex_primitive(luatex_command, "mathpunct", math_component_cmd, math_component_punctuation_code, 0); + tex_primitive(luatex_command, "mathinner", math_component_cmd, math_component_inner_code, 0); + tex_primitive(luatex_command, "mathfraction", math_component_cmd, math_component_fraction_code, 0); + tex_primitive(luatex_command, "mathradical", math_component_cmd, math_component_radical_code, 0); tex_primitive(luatex_command, "mathmiddle", math_component_cmd, math_component_middle_code, 0); tex_primitive(luatex_command, "mathaccent", math_component_cmd, math_component_accent_code, 0); tex_primitive(luatex_command, "mathfenced", math_component_cmd, math_component_fenced_code, 0); - tex_primitive(tex_command, "underline", math_component_cmd, math_component_under_code, 0); - tex_primitive(tex_command, "overline", math_component_cmd, math_component_over_code, 0); + tex_primitive(luatex_command, "mathunderline", math_component_cmd, math_component_under_code, 0); + tex_primitive(luatex_command, "mathoverline", math_component_cmd, math_component_over_code, 0); tex_primitive(luatex_command, "mathghost", math_component_cmd, math_component_ghost_code, 0); tex_primitive(luatex_command, "mathatom", math_component_cmd, math_component_atom_code, 0); @@ -929,8 +947,6 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "crampedtextstyle", math_style_cmd, cramped_text_style, 0); tex_primitive(luatex_command, "crampedscriptstyle", math_style_cmd, cramped_script_style, 0); tex_primitive(luatex_command, "crampedscriptscriptstyle", math_style_cmd, cramped_script_script_style, 0); - tex_primitive(luatex_command, "Ustyle", math_style_cmd, yet_unset_math_style, 0); - tex_primitive(luatex_command, "scaledmathstyle", math_style_cmd, scaled_math_style, 0); tex_primitive(luatex_command, "alldisplaystyles", math_style_cmd, all_display_styles, 0); tex_primitive(luatex_command, "alltextstyles", math_style_cmd, all_text_styles, 0); tex_primitive(luatex_command, "allscriptstyles", math_style_cmd, all_script_styles, 0); @@ -941,6 +957,8 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "allunsplitstyles", math_style_cmd, all_unsplit_styles, 0); tex_primitive(luatex_command, "alluncrampedstyles", math_style_cmd, all_uncramped_styles, 0); tex_primitive(luatex_command, "allcrampedstyles", math_style_cmd, all_cramped_styles, 0); + tex_primitive(luatex_command, "Ustyle", math_style_cmd, yet_unset_math_style, 0); + tex_primitive(luatex_command, "scaledmathstyle", math_style_cmd, scaled_math_style, 0); tex_primitive(tex_command, "message", message_cmd, message_code, 0); tex_primitive(tex_command, "errmessage", message_cmd, error_message_code, 0); @@ -1036,8 +1054,8 @@ void tex_initialize_commands(void) tex_primitive(tex_command, "unvcopy", un_vbox_cmd, copy_code, 0); tex_primitive(luatex_command, "unvpack", un_vbox_cmd, unpack_code, 0); - tex_primitive(etex_command, "pagediscards", un_vbox_cmd, last_box_code, 0); - tex_primitive(etex_command, "splitdiscards", un_vbox_cmd, vsplit_code, 0); + tex_primitive(etex_command, "pagediscards", un_vbox_cmd, page_discards_code, 0); + tex_primitive(etex_command, "splitdiscards", un_vbox_cmd, split_discards_code, 0); tex_primitive(luatex_command, "insertunbox", un_vbox_cmd, insert_box_code, 0); tex_primitive(luatex_command, "insertuncopy", un_vbox_cmd, insert_copy_code, 0); diff --git a/source/luametatex/source/tex/texcommands.h b/source/luametatex/source/tex/texcommands.h index 6495c93f0..57dc30f4f 100644 --- a/source/luametatex/source/tex/texcommands.h +++ b/source/luametatex/source/tex/texcommands.h @@ -621,9 +621,10 @@ typedef enum box_property_codes { box_freeze_code, /* we actually need set_box_int_cmd, or set_box_property */ box_attribute_code, + box_vadjust_code, } box_property_codes; -# define last_box_property_code box_attribute_code +# define last_box_property_code box_vadjust_code typedef enum hyphenation_codes { hyphenation_code, @@ -1075,11 +1076,7 @@ typedef enum math_styles { cramped_script_style, /*tex |\crampedscriptstyle| */ script_script_style, /*tex |\scriptscriptstyle| */ cramped_script_script_style, /*tex |\crampedscriptscriptstyle| */ - /* hidden */ - yet_unset_math_style, - former_choice_math_style, - scaled_math_style, - /* even more hidden */ /*tex These can be used to emulate the defaults. */ + /* hidden */ /*tex These can be used to emulate the defaults. */ all_display_styles, all_text_styles, all_script_styles, @@ -1090,13 +1087,18 @@ typedef enum math_styles { all_unsplit_styles, all_uncramped_styles, all_cramped_styles, + /* hidden */ + yet_unset_math_style, + scaled_math_style, + former_choice_math_style, } math_styles; # define first_math_style display_style -# define last_math_style all_cramped_styles +# define last_math_style former_choice_math_style # define is_valid_math_style(n) (n >= display_style && n <= cramped_script_script_style) # define are_valid_math_styles(n) (n >= all_display_styles && n <= all_cramped_styles) +# define visible_math_styles(n) (n >= display_style && n <= all_cramped_styles) inline static halfword tex_math_style_to_size(halfword s) { diff --git a/source/luametatex/source/tex/texconditional.c b/source/luametatex/source/tex/texconditional.c index 9cbdeed2b..22176f8b6 100644 --- a/source/luametatex/source/tex/texconditional.c +++ b/source/luametatex/source/tex/texconditional.c @@ -487,6 +487,21 @@ inline static halfword tex_aux_scan_comparison(int code) } } +inline static void tex_aux_check_strict(int *result) +{ + tex_get_x_token(); + switch (cur_cmd) { + case relax_cmd: + case spacer_cmd: + case if_test_cmd: + break; + default: + *result = 2; + break; + } + tex_back_input(cur_tok); +} + void tex_conditional_if(halfword code, int unless) { /*tex The result or case value. */ @@ -731,11 +746,15 @@ void tex_conditional_if(halfword code, int unless) result = 0; goto RESULT; case if_chk_int_code: + case if_chk_integer_code: { lmt_error_state.intercept = 1; /* maybe ++ and -- so that we can nest */ lmt_error_state.last_intercept = 0; lmt_condition_state.chk_num = tex_scan_int(0, NULL); /* value is ignored */ result = lmt_error_state.last_intercept ? 2 : 1; + if (result == 1 && code == if_chk_integer_code) { + tex_aux_check_strict(&result); + } lmt_error_state.intercept = 0; lmt_error_state.last_intercept = 0; goto CASE; @@ -758,11 +777,15 @@ void tex_conditional_if(halfword code, int unless) goto CASE; } case if_chk_dim_code: + case if_chk_dimension_code: { lmt_error_state.intercept = 1; lmt_error_state.last_intercept = 0; lmt_condition_state.chk_dim = tex_scan_dimen(0, 0, 0, 0, NULL); /* value is ignored */ result = lmt_error_state.last_intercept ? 2 : 1; + if (result == 1 && code == if_chk_dimension_code) { + tex_aux_check_strict(&result); + } lmt_error_state.intercept = 0; lmt_error_state.last_intercept = 0; goto CASE; diff --git a/source/luametatex/source/tex/texconditional.h b/source/luametatex/source/tex/texconditional.h index 47157556c..36f86f6a5 100644 --- a/source/luametatex/source/tex/texconditional.h +++ b/source/luametatex/source/tex/texconditional.h @@ -72,10 +72,12 @@ typedef enum if_test_codes { if_true_code, /*tex |\iftrue| */ if_false_code, /*tex |\iffalse| */ if_chk_int_code, /*tex |\ifchknum| */ - if_val_int_code, /*tex |\ifcmpnum| */ + if_chk_integer_code, /*tex |\ifchknumber| */ + if_val_int_code, /*tex |\ifnumval| */ if_cmp_int_code, /*tex |\ifcmpnum| */ if_chk_dim_code, /*tex |\ifchkdim| */ - if_val_dim_code, /*tex |\ifchkdim| */ + if_chk_dimension_code, /*tex |\ifchkdimension| */ + if_val_dim_code, /*tex |\ifdimval| */ if_cmp_dim_code, /*tex |\ifcmpdim| */ if_case_code, /*tex |\ifcase| */ if_def_code, /*tex |\ifdefined| */ diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h index a386ca3ba..87d987421 100644 --- a/source/luametatex/source/tex/texdumpdata.h +++ b/source/luametatex/source/tex/texdumpdata.h @@ -55,7 +55,7 @@ */ -# define luametatex_format_fingerprint 682 +# define luametatex_format_fingerprint 684 /* These end up in the string pool. */ diff --git a/source/luametatex/source/tex/texequivalents.c b/source/luametatex/source/tex/texequivalents.c index e61db3826..56d14a54f 100644 --- a/source/luametatex/source/tex/texequivalents.c +++ b/source/luametatex/source/tex/texequivalents.c @@ -664,14 +664,13 @@ void tex_show_save_groups(void) // ++pointer; // tex_print_str_esc("beginmathgroup"); // goto FOUND2; - case math_shift_group: - if (mode == mmode) { - tex_print_char('$'); - } else if (lmt_nest_state.nest[pointer].mode == mmode) { - tex_print_cmd_chr(equation_number_cmd, tex_aux_save_value(saved_equation_number_item_location)); - goto FOUND2; - } + case math_inline_group: tex_print_char('$'); + case math_display_group: + tex_print_char('$'); + goto FOUND2; + case math_number_group: + tex_print_cmd_chr(equation_number_cmd, tex_aux_save_value(saved_equation_number_item_location)); goto FOUND2; case math_fence_group: /* kind of ugly ... maybe also save that one */ /* todo: operator */ diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index 4a18c4d87..d64c78807 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -930,6 +930,7 @@ typedef enum save_types { adjust_attr_list_save_type, adjust_depth_before_save_type, adjust_depth_after_save_type, + adjust_target_save_type, } save_types; /*tex Nota bena: |equiv_value| is the same as |equiv| but sometimes we use that name instead. */ @@ -988,8 +989,10 @@ typedef enum tex_group_codes { also_simple_group, /*tex code for |\begingroup|\unknown|\egroup| */ semi_simple_group, /*tex code for |\begingroup|\unknown|\endgroup| */ math_simple_group, /*tex code for |\beginmathgroup|\unknown|\endmathgroup| */ - math_shift_group, /*tex code for |$|\unknown\|$| */ math_fence_group, /*tex code for fences |\left|\unknown|\right| */ + math_inline_group, + math_display_group, + math_number_group, local_box_group, /*tex code for |\localleftbox|\unknown|localrightbox| */ split_off_group, /*tex box code for the top part of a |\vsplit| */ split_keep_group, /*tex box code for the bottom part of a |\vsplit| */ diff --git a/source/luametatex/source/tex/texexpand.c b/source/luametatex/source/tex/texexpand.c index feb20c8d9..6cf887bea 100644 --- a/source/luametatex/source/tex/texexpand.c +++ b/source/luametatex/source/tex/texexpand.c @@ -419,7 +419,9 @@ void tex_expand_current_token(void) case the_cmd: { halfword h = tex_the_toks(cur_chr, NULL); - tex_begin_inserted_list(h); + if (h) { + tex_begin_inserted_list(h); + } break; } case lua_call_cmd: diff --git a/source/luametatex/source/tex/texlinebreak.c b/source/luametatex/source/tex/texlinebreak.c index 52e7f25d3..af60f1c40 100644 --- a/source/luametatex/source/tex/texlinebreak.c +++ b/source/luametatex/source/tex/texlinebreak.c @@ -3546,3 +3546,22 @@ static void tex_aux_post_line_break(const line_break_properties *properties, hal cur_list.direction_stack = lmt_linebreak_state.dir_ptr; lmt_linebreak_state.dir_ptr = null; } + +halfword tex_wipe_margin_kerns(halfword head) +{ + /*tex We assume that head is a temp node or at least can be skipped (for now). */ + halfword tail = head; + while (1) { + halfword next = node_next(tail); + if (next) { + if (node_type(next) == kern_node && (node_subtype(next) == left_margin_kern_subtype || node_subtype(next) == right_margin_kern_subtype)) { + tex_try_couple_nodes(tail, node_next(next)); + tex_flush_node(next); + } else { + tail = next; + } + } else { + return tail; + } + } +}
\ No newline at end of file diff --git a/source/luametatex/source/tex/texlinebreak.h b/source/luametatex/source/tex/texlinebreak.h index 27c8607e0..789101999 100644 --- a/source/luametatex/source/tex/texlinebreak.h +++ b/source/luametatex/source/tex/texlinebreak.h @@ -142,6 +142,9 @@ extern void tex_do_line_break ( line_break_properties *properties ); +extern halfword tex_wipe_margin_kerns( + halfword head +); /*tex diff --git a/source/luametatex/source/tex/texmainbody.c b/source/luametatex/source/tex/texmainbody.c index 4dd9c37a0..707882a6b 100644 --- a/source/luametatex/source/tex/texmainbody.c +++ b/source/luametatex/source/tex/texmainbody.c @@ -385,14 +385,15 @@ void tex_main_body(void) lmt_error_state.history = spotless; - { - int dump = tex_main_control(); - if (dump && lmt_main_state.run_state != initializing_state) { - /*tex Maybe we need to issue a warning here. For now we just ignore it. */ - dump = 0; - } - final_cleanup(dump); - } + // { + // int dump = tex_main_control(); + // if (dump && lmt_main_state.run_state != initializing_state) { + // /*tex Maybe we need to issue a warning here. For now we just ignore it. */ + // dump = 0; + // } + // final_cleanup(dump); + // } + final_cleanup(tex_main_control()); tex_close_files_and_terminate(0); diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c index 8b9250444..c15704129 100644 --- a/source/luametatex/source/tex/texmaincontrol.c +++ b/source/luametatex/source/tex/texmaincontrol.c @@ -64,6 +64,9 @@ main_control_state_info lmt_main_control_state = { .quit_loop = 0, }; +inline static void tex_aux_big_switch (int mode, int cmd); +static void tex_run_prefixed_command (void); + /*tex These two helpers, of which the second one is still experimental, actually belong in another file so then might be moved. Watch how the first one has the |unsave| call! @@ -150,16 +153,16 @@ static void tex_aux_out_of_range_error(halfword val, halfword max) static void tex_aux_adjust_space_factor(halfword chr) { halfword s = tex_get_sf_code(chr); - if (s == 1000) { - cur_list.space_factor = 1000; - } else if (s < 1000) { + if (s == default_space_factor) { + cur_list.space_factor = default_space_factor; + } else if (s < default_space_factor) { if (s > 0) { cur_list.space_factor = s; } else { /* s <= 0 */ } - } else if (cur_list.space_factor < 1000) { - cur_list.space_factor = 1000; + } else if (cur_list.space_factor < default_space_factor) { + cur_list.space_factor = default_space_factor; } else { cur_list.space_factor = s; } @@ -412,7 +415,7 @@ static void tex_aux_run_space(void) { */ { halfword p; - if (cur_mode == hmode && cur_cmd == spacer_cmd && cur_list.space_factor != 1000) { + if (cur_mode == hmode && cur_cmd == spacer_cmd && cur_list.space_factor != default_space_factor) { if ((cur_list.space_factor >= 2000) && (! tex_glue_is_zero(xspace_skip_par))) { p = tex_get_scaled_parameter_glue(xspace_skip_code, xspace_skip_glue); } else { @@ -796,7 +799,7 @@ static void tex_aux_scan_local_box(int code) { tex_scan_left_brace(); tex_push_nest(); cur_list.mode = restricted_hmode; - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; } static void tex_aux_finish_local_box(void) @@ -1294,12 +1297,14 @@ static void tex_aux_run_paragraph_end_hmode(void) { /* */ static void tex_aux_run_halign_mmode(void) { - if (tex_in_privileged_mode()) { - if (cur_group == math_shift_group) { + switch (cur_group) { + case math_inline_group: + case math_display_group: tex_run_alignment_initialize(); - } else { + break; + default: tex_off_save(); - } + break; } } @@ -1534,7 +1539,33 @@ static void tex_aux_run_lua_function_call(void) */ -inline static void tex_aux_big_switch (int mode, int cmd); +//int tex_main_control(void) +//{ +// lmt_main_control_state.control_state = goto_next_state; +// if (every_job_par) { +// tex_begin_token_list(every_job_par, every_job_text); +// } +// while (1) { +// if (lmt_main_control_state.control_state == goto_skip_token_state) { +// lmt_main_control_state.control_state = goto_next_state; +// } else { +// tex_get_x_token(); +// } +// /*tex +// Give diagnostic information, if requested When a new token has just been fetched at +// |big_switch|, we have an ideal place to monitor \TEX's activity. +// */ +// if (tracing_commands_par > 0) { +// tex_show_cmd_chr(cur_cmd, cur_chr); +// } +// /*tex Run the command: */ +// tex_aux_big_switch(cur_mode, cur_cmd); +// if (lmt_main_control_state.control_state == goto_return_state) { +// return cur_chr == dump_code; +// } +// } +// return 0; /* unreachable */ +//} int tex_main_control(void) { @@ -1543,10 +1574,15 @@ int tex_main_control(void) tex_begin_token_list(every_job_par, every_job_text); } while (1) { - if (lmt_main_control_state.control_state == goto_skip_token_state) { - lmt_main_control_state.control_state = goto_next_state; - } else { - tex_get_x_token(); + switch (lmt_main_control_state.control_state) { + case goto_next_state: + tex_get_x_token(); + break; + case goto_skip_token_state: + lmt_main_control_state.control_state = goto_next_state; + break; + case goto_return_state: + return lmt_main_state.run_state == initializing_state && cur_chr == dump_code; } /*tex Give diagnostic information, if requested When a new token has just been fetched at @@ -1557,9 +1593,6 @@ int tex_main_control(void) } /*tex Run the command: */ tex_aux_big_switch(cur_mode, cur_cmd); - if (lmt_main_control_state.control_state == goto_return_state) { - return cur_chr == dump_code; - } } return 0; /* unreachable */ } @@ -2008,18 +2041,6 @@ static const int glue_filler_codes[] = { static void tex_aux_run_glue(void) { switch (cur_chr) { - // case fil_code: - // tex_tail_append(tex_new_glue_node(fil_glue, user_skip_glue)); - // break; - // case fill_code: - // tex_tail_append(tex_new_glue_node(fill_glue, user_skip_glue)); - // break; - // case filll_code: /*tex aka |ss_code| */ - // tex_tail_append(tex_new_glue_node(filll_glue, user_skip_glue)); - // break; - // case fil_neg_code: - // tex_tail_append(tex_new_glue_node(fil_neg_glue, user_skip_glue)); - // break; case fil_code: case fill_code: case filll_code: @@ -2109,7 +2130,9 @@ void tex_off_save(void) ); break; } - case math_shift_group: + case math_inline_group: + case math_display_group: + case math_number_group: { set_token_info(h, math_shift_token + '$'); tex_handle_error( @@ -2278,8 +2301,8 @@ static void tex_aux_run_discretionary(void) static void tex_aux_finish_discretionary(void) { - halfword p, q, d; /* for link manipulation */ - int n = 0; /* length of discretionary list */ + halfword current, next; + int length = 0; tex_unsave(); /*tex Prune the current list, if necessary, until it contains only |char_node|, |kern_node|, @@ -2287,10 +2310,10 @@ static void tex_aux_finish_discretionary(void) set |q| to the lists tail. During this loop, |p = node_next(q)| and there are |n| items preceding |p|. */ - q = cur_list.head; - p = node_next(q); - while (p) { - switch (node_type(p)) { + current = cur_list.head; + next = node_next(current); + while (next) { + switch (node_type(next)) { case glyph_node: case hlist_node: case vlist_node: @@ -2299,13 +2322,13 @@ static void tex_aux_finish_discretionary(void) break; case glue_node: if (hyphenation_permitted(hyphenation_mode_par, permit_glue_hyphenation_mode)) { - if (glue_stretch_order(p)) { - glue_stretch(p) = 0; - glue_stretch_order(p) = 0; + if (glue_stretch_order(next)) { + glue_stretch(next) = 0; + glue_stretch_order(next) = 0; } - if (glue_shrink_order(p)) { - glue_shrink(p) = 0; - glue_shrink_order(p) = 0; + if (glue_shrink_order(next)) { + glue_shrink(next) = 0; + glue_shrink_order(next) = 0; } break; } else { @@ -2323,32 +2346,32 @@ static void tex_aux_finish_discretionary(void) tex_begin_diagnostic(); tex_print_str("The following discretionary sublist has been deleted:"); tex_print_levels(); - tex_show_box(p); + tex_show_box(next); tex_end_diagnostic(); - tex_flush_node_list(p); - node_next(q) = null; + tex_flush_node_list(next); + node_next(current) = null; goto DONE; } } - node_prev(p) = q; - q = p; - p = node_next(q); - ++n; + node_prev(next) = current; + current = next; + next = node_next(current); + ++length; } DONE: - p = node_next(cur_list.head); + next = node_next(cur_list.head); tex_pop_nest(); - d = cur_list.tail; if (saved_type(saved_discretionary_item_component - saved_discretionary_n_of_items) == discretionary_count_save_type) { + halfword discnode = cur_list.tail; switch (saved_value(saved_discretionary_item_component - saved_discretionary_n_of_items)) { case 0: - if (n > 0) { - tex_set_disc_field(d, pre_break_code, p); + if (length > 0) { + tex_set_disc_field(discnode, pre_break_code, next); } break; case 1: - if (n > 0) { - tex_set_disc_field(d, post_break_code, p); + if (length > 0) { + tex_set_disc_field(discnode, post_break_code, next); } break; case 2: @@ -2356,7 +2379,7 @@ static void tex_aux_finish_discretionary(void) Attach list |p| to the current list, and record its length; then finish up and |return|. */ - if (n > 0) { + if (length > 0) { if (cur_mode == mmode && ! hyphenation_permitted(hyphenation_mode_par, permit_math_replace_hyphenation_mode)) { tex_handle_error( normal_error_type, @@ -2364,29 +2387,29 @@ static void tex_aux_finish_discretionary(void) "Sorry: The third part of a discretionary break must be empty, in math formulas. I\n" "had to delete your third part." ); - tex_flush_node_list(p); + tex_flush_node_list(next); } else { - tex_set_disc_field(d, no_break_code, p); + tex_set_disc_field(discnode, no_break_code, next); } } if (! hyphenation_permitted(hyphenation_mode_par, normal_hyphenation_mode)) { - halfword n = disc_no_break_head(d); + halfword replace = disc_no_break_head(discnode); cur_list.tail = node_prev(cur_list.tail); node_next(cur_list.tail) = null; - if (n) { - tex_tail_append(n); - cur_list.tail = disc_no_break_tail(d); - tex_set_disc_field(d, no_break_code, null); - tex_set_discpart(d, n, disc_no_break_tail(d), glyph_discpart_replace); + if (replace) { + tex_tail_append(replace); + cur_list.tail = disc_no_break_tail(discnode); + tex_set_disc_field(discnode, no_break_code, null); + tex_set_discpart(discnode, replace, disc_no_break_tail(discnode), glyph_discpart_replace); } - tex_flush_node(d); - } else if (cur_mode == mmode && disc_class(d) != unset_disc_class) { - halfword n = null; - cur_list.tail = node_prev(d); - node_prev(d) = null; - node_next(d) = null; - n = tex_math_make_disc(d); - tex_tail_append(n); + tex_flush_node(discnode); + } else if (cur_mode == mmode && disc_class(discnode) != unset_disc_class) { + halfword noad = null; + cur_list.tail = node_prev(discnode); + node_prev(discnode ) = null; + node_next(discnode ) = null; + noad = tex_math_make_disc(discnode); + tex_tail_append(noad); } /*tex There are no other cases. */ lmt_save_state.save_stack_data.ptr -= saved_discretionary_n_of_items; @@ -2419,7 +2442,7 @@ static void tex_aux_finish_discretionary(void) static void tex_aux_extra_right_brace_error(void) { - const char * helpinfo = + const char *helpinfo = "I've deleted a group-closing symbol because it seems to be spurious, as in\n" "'$x}$'. But perhaps the } is legitimate and you forgot something else, as in\n" "'\\hbox{$x}'."; @@ -2439,7 +2462,9 @@ static void tex_aux_extra_right_brace_error(void) helpinfo ); break; - case math_shift_group: + case math_inline_group: + case math_display_group: + case math_number_group: tex_handle_error( normal_error_type, "Extra }, or forgotten $", @@ -2585,7 +2610,9 @@ static void tex_aux_run_right_brace(void) tex_aux_run_end_group(); break; case semi_simple_group: - case math_shift_group: + case math_inline_group: + case math_display_group: + case math_number_group: case math_fence_group: /*tex See above, let's see when we are supposed to end up here. */ tex_aux_extra_right_brace_error(); break; @@ -4121,7 +4148,7 @@ static void tex_aux_set_box_property(void) break; case box_attribute_code: { - halfword att = tex_scan_box_register_number(); + halfword att = tex_scan_attribute_register_number(); halfword val = tex_scan_int(1, NULL); if (b) { if (val == unused_attribute_value) { @@ -4132,6 +4159,13 @@ static void tex_aux_set_box_property(void) } } break; + case box_vadjust_code: + if (b) { + tex_set_vadjust(b); + } else { + tex_run_vadjust(); /* maybe error */ + } + break; default: break; } @@ -5426,7 +5460,7 @@ static void tex_aux_set_constant_register(halfword cmd, halfword cs, halfword fl tex_define(flags, cs, (singleword) cmd, v); } -void tex_run_prefixed_command(void) +static void tex_run_prefixed_command(void) { /*tex accumulated prefix codes so far */ int flags = 0; @@ -6047,7 +6081,7 @@ static void tex_aux_run_message(void) */ -static void tex_aux_run_shift_case(void) +static void tex_aux_run_case_shift(void) { int upper = cur_chr == upper_case_code; halfword l = tex_scan_toks_normal(0, NULL); @@ -6271,189 +6305,6 @@ static void tex_aux_run_show_whatever(void) */ -# if 0 - -# define register_runner(A,B,C,D) \ - case A: \ - switch (mode) { \ - case vmode: B(); break; \ - case hmode: C(); break; \ - case mmode: D(); break; \ - } \ - break - -# define register_simple(A,B) \ - case A: B(); break - -# define register_asmath(A,B,C) \ - case A: if (mode == mmode) { C(); } else { B(); } break - -inline static void tex_aux_big_switch(int mode, int cmd) -{ - - switch (cmd) { - /*tex These have the same handler for each mode: */ - - register_simple(arithmic_cmd, tex_run_prefixed_command); - register_simple(register_attribute_cmd, tex_run_prefixed_command); - register_simple(internal_attribute_cmd, tex_run_prefixed_command); - register_simple(register_dimen_cmd, tex_run_prefixed_command); - register_simple(internal_dimen_cmd, tex_run_prefixed_command); - register_simple(set_font_property_cmd, tex_run_prefixed_command); - register_simple(register_glue_cmd, tex_run_prefixed_command); - register_simple(internal_glue_cmd, tex_run_prefixed_command); - register_simple(register_int_cmd, tex_run_prefixed_command); - register_simple(internal_int_cmd, tex_run_prefixed_command); - register_simple(register_mu_glue_cmd, tex_run_prefixed_command); - register_simple(internal_mu_glue_cmd, tex_run_prefixed_command); - register_simple(register_toks_cmd, tex_run_prefixed_command); - register_simple(internal_toks_cmd, tex_run_prefixed_command); - register_simple(define_char_code_cmd, tex_run_prefixed_command); - register_simple(def_cmd, tex_run_prefixed_command); - register_simple(define_family_cmd, tex_run_prefixed_command); - register_simple(define_font_cmd, tex_run_prefixed_command); - register_simple(hyphenation_cmd, tex_run_prefixed_command); - register_simple(let_cmd, tex_run_prefixed_command); - register_simple(prefix_cmd, tex_run_prefixed_command); - register_simple(register_cmd, tex_run_prefixed_command); - register_simple(set_auxiliary_cmd, tex_run_prefixed_command); - register_simple(set_box_cmd, tex_run_prefixed_command); - register_simple(set_box_property_cmd, tex_run_prefixed_command); - register_simple(set_font_cmd, tex_run_prefixed_command); - register_simple(set_interaction_cmd, tex_run_prefixed_command); - register_simple(set_math_parameter_cmd, tex_run_prefixed_command); - register_simple(set_page_property_cmd, tex_run_prefixed_command); - register_simple(set_specification_cmd, tex_run_prefixed_command); - register_simple(shorthand_def_cmd, tex_run_prefixed_command); - register_simple(lua_value_cmd, tex_run_prefixed_command); - register_simple(integer_cmd, tex_run_prefixed_command); - register_simple(dimension_cmd, tex_run_prefixed_command); - register_simple(gluespec_cmd, tex_run_prefixed_command); - register_simple(mugluespec_cmd, tex_run_prefixed_command); - - register_simple(fontspec_cmd, tex_run_font_spec); - - // register_simple(some_item_cmd, tex_aux_run_illegal_case); - register_simple(some_item_cmd, tex_run_prefixed_command); - register_simple(iterator_value_cmd, tex_aux_run_illegal_case); - register_simple(parameter_cmd, tex_aux_run_illegal_case); - - register_simple(after_something_cmd, tex_aux_run_after_something); - register_simple(begin_group_cmd, tex_aux_run_begin_group); - register_simple(penalty_cmd, tex_aux_run_penalty); - register_simple(case_shift_cmd, tex_aux_run_shift_case); - register_simple(catcode_table_cmd, tex_aux_run_catcode_table); - register_simple(combine_toks_cmd, tex_run_prefixed_command); - // register_simple(combine_toks_cmd, tex_run_combine_the_toks); - register_simple(end_cs_name_cmd, tex_aux_run_cs_error); - register_simple(end_group_cmd, tex_aux_run_end_group); - register_simple(end_local_cmd, tex_aux_run_end_local); - register_simple(ignore_something_cmd, tex_aux_run_ignore_something); - register_simple(insert_cmd, tex_run_insert); - register_simple(kern_cmd, tex_aux_run_kern); - register_simple(leader_cmd, tex_aux_run_leader); - register_simple(legacy_cmd, tex_aux_run_legacy); - register_simple(local_box_cmd, tex_aux_run_local_box); - register_simple(lua_protected_call_cmd, tex_aux_run_lua_protected_call); - register_simple(lua_function_call_cmd, tex_aux_run_lua_function_call); - register_simple(make_box_cmd, tex_aux_run_make_box); - register_simple(set_mark_cmd, tex_run_mark); - register_simple(message_cmd, tex_aux_run_message); - register_simple(node_cmd, tex_aux_run_node); - register_simple(relax_cmd, tex_aux_run_relax); - register_simple(remove_item_cmd, tex_aux_run_remove_item); - register_simple(right_brace_cmd, tex_aux_run_right_brace); - register_simple(vcenter_cmd, tex_run_vcenter); - register_simple(xray_cmd, tex_aux_run_show_whatever); - - register_simple(alignment_cmd, tex_run_alignment_error); - register_simple(end_template_cmd, tex_run_alignment_end_template); - register_simple(alignment_tab_cmd, tex_run_alignment_error); - - /*tex These have different handlers but a common h/v mode: */ - - register_asmath(math_fraction_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_fraction); - register_asmath(delimiter_number_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_delimiter_number); - register_asmath(math_fence_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_fence); - register_asmath(math_modifier_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_modifier); - register_asmath(math_accent_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_accent); - register_asmath(math_choice_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_choice); - register_asmath(math_component_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_math_component); - register_asmath(math_style_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_style); - register_asmath(mkern_cmd, tex_aux_run_insert_dollar_sign, tex_aux_run_mkern); - register_asmath(mskip_cmd, tex_aux_run_insert_dollar_sign, tex_aux_run_mglue); - register_asmath(math_radical_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_radical); - register_asmath(subscript_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_script); - register_asmath(superscript_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_script); - register_asmath(math_script_cmd, tex_aux_run_insert_dollar_sign, tex_run_math_script); - - register_asmath(equation_number_cmd, tex_aux_run_illegal_case, tex_run_math_equation_number); - - register_asmath(left_brace_cmd, tex_aux_run_left_brace, tex_run_math_left_brace); - - /*tex These have different handlers: */ - - register_runner(italic_correction_cmd, tex_aux_run_illegal_case, tex_aux_run_text_italic_correction, tex_run_math_italic_correction); - register_runner(math_char_number_cmd, tex_aux_run_math_non_math, tex_run_text_math_char_number, tex_run_math_math_char_number); - register_runner(mathspec_cmd, tex_aux_run_math_non_math, tex_run_text_math_spec, tex_run_math_math_spec); - register_runner(vadjust_cmd, tex_aux_run_illegal_case, tex_run_vadjust, tex_run_vadjust); - - register_runner(char_given_cmd, tex_aux_run_new_paragraph, tex_aux_run_text_letter, tex_run_math_letter); - register_runner(other_char_cmd, tex_aux_run_new_paragraph, tex_aux_run_text_letter, tex_run_math_letter); - register_runner(letter_cmd, tex_aux_run_new_paragraph, tex_aux_run_text_letter, tex_run_math_letter); - - register_runner(accent_cmd, tex_aux_run_new_paragraph, tex_aux_run_text_accent, tex_run_math_accent); - register_runner(boundary_cmd, tex_aux_run_par_boundary, tex_aux_run_text_boundary, tex_aux_run_math_boundary); - register_runner(char_number_cmd, tex_aux_run_new_paragraph, tex_aux_run_text_char_number, tex_run_math_char_number); - register_runner(discretionary_cmd, tex_aux_run_new_paragraph, tex_aux_run_discretionary, tex_aux_run_discretionary); - register_runner(explicit_space_cmd, tex_aux_run_new_paragraph, tex_aux_run_space, tex_aux_run_space); - register_runner(math_shift_cmd, tex_aux_run_new_paragraph, tex_run_math_initialize, tex_run_math_shift); - register_runner(math_shift_cs_cmd, tex_aux_run_new_paragraph, tex_run_math_initialize, tex_run_math_shift); - - register_runner(end_paragraph_cmd, tex_aux_run_paragraph_end_vmode, tex_aux_run_paragraph_end_hmode, tex_aux_run_relax); - register_runner(spacer_cmd, tex_aux_run_relax, tex_aux_run_space, tex_aux_run_math_space); - register_runner(begin_paragraph_cmd, tex_aux_run_begin_paragraph_vmode, tex_aux_run_begin_paragraph_hmode, tex_aux_run_begin_paragraph_mmode); - register_runner(end_job_cmd, tex_aux_run_end_job, tex_aux_run_head_for_vmode, tex_aux_run_insert_dollar_sign); - - /*tex - These can share a handler if we move the mode test (we then also have 5 command codes - less) but it becomes less pretty for rules and so. When in the wrong more, a mode change - is enforced and the token is pushed back and ready for a new inspection. - */ - - register_runner(hmove_cmd, tex_aux_run_move, tex_aux_run_illegal_case, tex_aux_run_illegal_case); - register_runner(vmove_cmd, tex_aux_run_illegal_case, tex_aux_run_move, tex_aux_run_move); - - register_runner(hskip_cmd, tex_aux_run_new_paragraph, tex_aux_run_glue, tex_aux_run_glue); - register_runner(vskip_cmd, tex_aux_run_glue, tex_aux_run_head_for_vmode, tex_aux_run_insert_dollar_sign); - - register_runner(un_hbox_cmd, tex_aux_run_new_paragraph, tex_run_unpackage, tex_run_unpackage); - register_runner(un_vbox_cmd, tex_run_unpackage, tex_aux_run_head_for_vmode, tex_aux_run_insert_dollar_sign); - - register_runner(halign_cmd, tex_run_alignment_initialize, tex_aux_run_head_for_vmode, tex_aux_run_halign_mmode); - register_runner(valign_cmd, tex_aux_run_new_paragraph, tex_run_alignment_initialize, tex_aux_run_insert_dollar_sign); - - register_runner(hrule_cmd, tex_aux_run_hrule, tex_aux_run_head_for_vmode, tex_aux_run_insert_dollar_sign); - register_runner(vrule_cmd, tex_aux_run_new_paragraph, tex_aux_run_vrule, tex_aux_run_mrule); - - /* Just in case: */ - - register_runner(ignore_cmd, tex_aux_run_relax, tex_aux_run_relax, tex_aux_run_relax); - - register_runner(active_char_cmd, tex_aux_run_active, tex_aux_run_active, tex_aux_run_active); - - /*tex The next is unlikely to happen but compilers like the check. */ - - default: - /* printf("cmd code %i", cmd); */ - tex_confusion("unknown cmd code"); - break; - } - -} - -# else - inline static void tex_aux_big_switch(int mode, int cmd) { @@ -6503,7 +6354,7 @@ inline static void tex_aux_big_switch(int mode, int cmd) case after_something_cmd: tex_aux_run_after_something(); break; case begin_group_cmd: tex_aux_run_begin_group(); break; case penalty_cmd: tex_aux_run_penalty(); break; - case case_shift_cmd: tex_aux_run_shift_case(); break; + case case_shift_cmd: tex_aux_run_case_shift(); break; case catcode_table_cmd: tex_aux_run_catcode_table(); break; case end_cs_name_cmd: tex_aux_run_cs_error(); break; case end_group_cmd: tex_aux_run_end_group(); break; @@ -6616,19 +6467,13 @@ inline static void tex_aux_big_switch(int mode, int cmd) } break; case math_shift_cmd: + case math_shift_cs_cmd: switch (mode) { case vmode: tex_aux_run_new_paragraph(); break; case hmode: tex_run_math_initialize(); break; case mmode: tex_run_math_shift(); break; } break; - case math_shift_cs_cmd: - switch (mode) { - case vmode: tex_aux_run_new_paragraph(); break; - case hmode: tex_run_math_initialize(); break; - case mmode: tex_run_math_shift(); break; - } - break; case end_paragraph_cmd: switch (mode) { case vmode: tex_aux_run_paragraph_end_vmode(); break; @@ -6713,8 +6558,6 @@ inline static void tex_aux_big_switch(int mode, int cmd) } -# endif - /*tex Some preset values no longer make sense, like family 1 for some math symbols but we keep them for compatibility reasons. All settings are moved to the relevant modules. diff --git a/source/luametatex/source/tex/texmaincontrol.h b/source/luametatex/source/tex/texmaincontrol.h index 5b72a3d43..d46eddc5c 100644 --- a/source/luametatex/source/tex/texmaincontrol.h +++ b/source/luametatex/source/tex/texmaincontrol.h @@ -64,8 +64,6 @@ extern void tex_page_boundary_message (const char *s, halfword bou extern void tex_inject_text_or_line_dir (int d, int check_glue); -extern void tex_run_prefixed_command (void); - extern void tex_handle_assignments (void); /*tex Used in math. */ extern void tex_assign_internal_int_value (int a, halfword p, int val); diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index d2c0ff413..a9f1a3ed9 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -1235,7 +1235,7 @@ static void tex_aux_push_math(quarterword group, int style) static void tex_aux_enter_inline_math(int style) { - tex_aux_push_math(math_shift_group, style); + tex_aux_push_math(math_inline_group, style); update_tex_family(0, unused_math_family); if (every_math_par) { tex_begin_token_list(every_math_par, every_math_text); @@ -1294,14 +1294,12 @@ void tex_run_math_initialize(void) */ void tex_run_math_equation_number(void) { - if (tex_in_privileged_mode()) { - if (cur_group == math_shift_group) { - tex_set_saved_record(saved_equation_number_item_location, equation_number_location_save_type, 0, cur_chr); - lmt_save_state.save_stack_data.ptr += saved_equation_number_n_of_items; - tex_aux_enter_inline_math(text_style); - } else { - tex_off_save(); - } + if (cur_group == math_display_group) { + tex_set_saved_record(saved_equation_number_item_location, equation_number_location_save_type, 0, cur_chr); + lmt_save_state.save_stack_data.ptr += saved_equation_number_n_of_items; + tex_aux_enter_inline_math(text_style); + } else { + tex_off_save(); } } @@ -1367,8 +1365,9 @@ static int tex_aux_pre_math_par_direction(void) static void tex_aux_enter_display_math(halfword cmd) { if (math_display_mode_par) { - tex_aux_push_math(math_shift_group, display_style); + tex_aux_push_math(math_inline_group, display_style); cur_list.math_mode = cmd; + cur_list.mode = inline_mmode; /* new */ update_tex_family(0, unused_math_family); if (every_display_par) { tex_begin_token_list(every_display_par, every_display_text); @@ -1386,10 +1385,8 @@ static void tex_aux_enter_display_math(halfword cmd) if (cur_list.head == cur_list.tail || (node_next(cur_list.head) == cur_list.tail && node_type(cur_list.tail) == par_node && ! node_next(cur_list.tail))) { if (node_next(cur_list.head) == cur_list.tail) { /*tex - |resume_after_display| inserts a |par_node|, but if there is another display immediately following, we have to get rid of that node. - */ tex_flush_node(cur_list.tail); /* cur_list.tail = cur_list.head; */ /* probably needed */ @@ -1397,16 +1394,14 @@ static void tex_aux_enter_display_math(halfword cmd) tex_pop_nest(); size = - max_dimen; } else { - tex_line_break(1, math_shift_group); + tex_line_break(1, math_display_group); // size = tex_actual_box_width(lmt_linebreak_state.just_box, tex_x_over_n(tex_get_font_em_width(cur_font_par), 1000) * math_pre_display_gap_factor_par); size = tex_actual_box_width(lmt_linebreak_state.just_box, scaledround((tex_get_font_em_width(cur_font_par) / 1000.0) * math_pre_display_gap_factor_par)); } /*tex - Now we are in vertical mode, working on the list that will contain the display. A displayed equation is considered to be three lines long, so we calculate the length and offset of line number |prev_graf + 2|. - */ if (par_shape_par) { /*tex scope of paragraph shape specification */ @@ -1430,7 +1425,7 @@ static void tex_aux_enter_display_math(halfword cmd) width = hsize_par; indent = 0; } - tex_aux_push_math(math_shift_group, display_style); + tex_aux_push_math(math_display_group, display_style); cur_list.mode = mmode; update_tex_family(0, unused_math_family); update_tex_pre_display_size(size); @@ -4068,7 +4063,9 @@ void tex_run_math_fence(void) switch (cur_group) { case math_fence_group: break; - case math_shift_group: + case math_inline_group: + case math_display_group: + case math_number_group: tex_aux_scan_delimiter(null, no_mathcode, unset_noad_class); if (st == middle_fence_side) { tex_handle_error( @@ -4246,24 +4243,27 @@ static void tex_aux_check_inline_math_end(void) static void tex_aux_resume_after_display(void) { - if (cur_group == math_shift_group) { - tex_aux_unsave_math(); - cur_list.prev_graf += 3; - tex_push_nest(); - cur_list.mode = hmode; - cur_list.space_factor = 1000; - /*tex This needs to be intercepted in the display math start! Todo! */ - tex_tail_append(tex_new_par_node(penalty_par_subtype)); - tex_get_x_token(); - if (cur_cmd != spacer_cmd) { - tex_back_input(cur_tok); - } - if (lmt_nest_state.nest_data.ptr == 1) { - lmt_page_filter_callback(after_display_page_context, 0); - tex_build_page(); - } - } else { - tex_confusion("finishing display math"); + switch (cur_group) { + case math_display_group: + tex_aux_unsave_math(); + cur_list.prev_graf += 3; + tex_push_nest(); + cur_list.mode = hmode; + cur_list.space_factor = default_space_factor; + /*tex This needs to be intercepted in the display math start! Todo! */ + tex_tail_append(tex_new_par_node(penalty_par_subtype)); + tex_get_x_token(); + if (cur_cmd != spacer_cmd) { + tex_back_input(cur_tok); + } + if (lmt_nest_state.nest_data.ptr == 1) { + lmt_page_filter_callback(after_display_page_context, 0); + tex_build_page(); + } + break; + default: + tex_confusion("finishing display math"); + break; } } @@ -4328,10 +4328,6 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor quarterword glue_above, glue_below; /*tex glue parameter subtypes for before and after */ quarterword subtype_above, subtype_below; - /*tex tail of adjustment lists */ - halfword post_adjust_tail, pre_adjust_tail; - /*tex tail of migration lists */ - halfword post_migrate_tail, pre_migrate_tail; /*tex for equation numbers */ scaled eqno_width; /*tex true if the math and surrounding (par) dirs are different */ @@ -4350,15 +4346,6 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor attach_current_attribute_list(equation_box); equation = box_list(equation_box); /* */ - post_adjust_tail = lmt_packaging_state.post_adjust_tail; - pre_adjust_tail = lmt_packaging_state.pre_adjust_tail; - post_migrate_tail = lmt_packaging_state.post_migrate_tail; - pre_migrate_tail = lmt_packaging_state.pre_migrate_tail; - lmt_packaging_state.post_adjust_tail = null; - lmt_packaging_state.pre_adjust_tail = null; - lmt_packaging_state.post_migrate_tail = null; - lmt_packaging_state.pre_migrate_tail = null; - /* */ equation_width = box_width(equation_box); line_width = display_width_par; indent = display_indent_par; @@ -4518,7 +4505,19 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor } else { box_shift_amount(equation_box) = indent + displacement; } - /*tex check for prev: */ + /* */ + if (pre_adjust_head != lmt_packaging_state.pre_adjust_tail) { + tex_inject_adjust_list(pre_adjust_head, 1, lmt_linebreak_state.just_box, NULL); + } + lmt_packaging_state.pre_adjust_tail = null; + /* Pre-migrate content (callback). */ + if (pre_migrate_head != lmt_packaging_state.pre_migrate_tail) { + tex_append_list(pre_migrate_head, lmt_packaging_state.pre_migrate_tail); + // if (! lmt_page_builder_state.output_active) { + // lmt_append_line_filter_callback(pre_migrate_append_line_context, 0); + // } + } + /* */ tex_append_to_vlist(equation_box, lua_key_index(equation), NULL); /* eqbox has the formula */ if (eqnumber && number_width == 0 && ! atleft) { tex_tail_append(tex_new_penalty_node(infinite_penalty, equation_number_penalty_subtype)); @@ -4529,28 +4528,21 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor tex_append_to_vlist(eqnumber, lua_key_index(equation_number), NULL); glue_below = 0; /* shouldn't this be an option */ } - /*tex Migrating material comes after equation number: is this ok? */ - if (post_migrate_tail != post_migrate_head) { - node_next(cur_list.tail) = node_next(post_migrate_head); - node_prev(lmt_packaging_state.post_migrate_tail) = node_prev(cur_list.tail); - cur_list.tail = post_migrate_tail; - } - if (post_adjust_tail != post_adjust_head) { - node_next(cur_list.tail) = node_next(post_adjust_head); - node_prev(lmt_packaging_state.post_adjust_tail) = node_prev(cur_list.tail); - cur_list.tail = post_adjust_tail; - } - /*tex A weird place: is this ok? */ - if (pre_adjust_tail != pre_adjust_head) { - node_next(cur_list.tail) = node_next(pre_adjust_head); - node_prev(lmt_packaging_state.pre_adjust_tail) = node_prev(cur_list.tail); - cur_list.tail = pre_adjust_tail; + /* */ + if (post_migrate_head != lmt_packaging_state.post_migrate_tail) { + tex_append_list(post_migrate_head, lmt_packaging_state.post_migrate_tail); + // if (! lmt_page_builder_state.output_active) { + // lmt_append_line_filter_callback(post_migrate_append_line_context, 0); + // } } - if (pre_migrate_tail != pre_migrate_head) { - node_next(cur_list.tail) = node_next(pre_migrate_head); - node_prev(lmt_packaging_state.pre_migrate_tail) = node_prev(cur_list.tail); - cur_list.tail = pre_migrate_tail; + lmt_packaging_state.post_migrate_tail = null; + if (lmt_packaging_state.post_adjust_tail) { + if (post_adjust_head != lmt_packaging_state.post_adjust_tail) { + tex_inject_adjust_list(post_adjust_head, 1, null, NULL); + } + lmt_packaging_state.post_adjust_tail = null; } + /* */ tex_tail_append(tex_new_penalty_node(post_display_penalty_par, after_display_penalty_subtype)); tex_aux_inject_display_skip(glue_below, subtype_below); tex_aux_resume_after_display(); @@ -4570,166 +4562,174 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor void tex_run_math_shift(void) { - if (cur_group == math_shift_group) { - /*tex box containing equation number */ - halfword eqnumber = null; - /*tex Use |\leqno| instead of |\eqno|, we default to right. */ - int atleft = 0; - /*tex |mmode| or |-mmode| */ - 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); - int mathleft = cur_list.math_begin; - int mathright = cur_list.math_end; - if (cur_cmd == math_shift_cs_cmd) { - switch (cur_chr) { - case begin_inline_math_code: - case begin_display_math_code: - case begin_math_mode_code: - tex_you_cant_error(NULL); - break; - } - } - if (cur_list.mode == -mode) { // todo: symbolic - /*tex end of equation number */ - AGAIN: - switch (cur_cmd) { - case math_shift_cmd: - tex_aux_check_second_math_shift(); - break; - case end_paragraph_cmd: - tex_get_x_token(); - goto AGAIN; - default: - tex_aux_check_display_math_end(); - break; - } - tex_run_mlist_to_hlist(p, 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(); - /*tex now |cur_group = math_shift_group| */ - lmt_save_state.save_stack_data.ptr -= saved_equation_number_n_of_items; - 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); - } else { - tex_confusion("after math"); - } - } - if (mode < 0) { // mode == inline_mmode - /*tex - - The |unsave| is done after everything else here; hence an appearance of |\mathsurround| - inside of |$...$| affects the spacing at these particular |$|'s. This is consistent - with the conventions of |$$ ... $$|, since |\abovedisplayskip| inside a display affects - the space above that display. - - */ - halfword math = tex_new_node(math_node, begin_inline_math); - if (mathmode) { - switch (cur_cmd) { - case math_shift_cs_cmd: - if (cur_chr != end_display_math_code && cur_chr != end_math_mode_code) { - tex_aux_check_second_math_shift(); - } - break; - case math_shift_cmd: - tex_aux_check_second_math_shift(); - break; + switch (cur_group) { + case math_inline_group: + case math_display_group: + case math_number_group: + { + /*tex box containing equation number */ + halfword eqnumber = null; + /*tex Use |\leqno| instead of |\eqno|, we default to right. */ + int atleft = 0; + /*tex |mmode| or |-mmode| */ + 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); + int mathleft = cur_list.math_begin; + int mathright = cur_list.math_end; + if (cur_cmd == math_shift_cs_cmd) { + switch (cur_chr) { + case begin_inline_math_code: + case begin_display_math_code: + case begin_math_mode_code: + tex_you_cant_error(NULL); + break; + } } - } 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 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); - } else { - math_surround(math) = math_surround_par; + if (cur_list.mode == -mode) { // todo: symbolic + /*tex end of equation number */ + AGAIN: + switch (cur_cmd) { + case math_shift_cmd: + tex_aux_check_second_math_shift(); + break; + case end_paragraph_cmd: + tex_get_x_token(); + goto AGAIN; + default: + tex_aux_check_display_math_end(); + break; } - 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); - break ; - case math_skip_always_right: - case math_skip_ignore: - break ; - case math_skip_always_surround: - default: - math_surround(math) = 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_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 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_run_mlist_to_hlist(p, 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(); + /*tex now |cur_group = math_shift_group| */ + lmt_save_state.save_stack_data.ptr -= saved_equation_number_n_of_items; + 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); } else { - math_surround(math) = math_surround_par; + tex_confusion("after math"); } - 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); - break; - case math_skip_always_left: - case math_skip_ignore: - break; - case math_skip_always_surround: - default: - math_surround(math) = math_surround_par; - break; - } - /*tex end mathskip code */ - cur_list.space_factor = 1000; - mathleft = cur_list.math_begin; - mathright = cur_list.math_end; - tex_aux_unsave_math(); - } else { - if (! eqnumber) { - if (cur_cmd == math_shift_cmd) { - tex_aux_check_second_math_shift(); + } + if (mode == inline_mmode) { + // if (mode < 0) { + /*tex + + The |unsave| is done after everything else here; hence an appearance of |\mathsurround| + inside of |$...$| affects the spacing at these particular |$|'s. This is consistent + with the conventions of |$$ ... $$|, since |\abovedisplayskip| inside a display affects + the space above that display. + + */ + halfword math = tex_new_node(math_node, begin_inline_math); + if (mathmode) { + switch (cur_cmd) { + case math_shift_cs_cmd: + if (cur_chr != end_display_math_code && cur_chr != end_math_mode_code) { + tex_aux_check_second_math_shift(); + } + break; + case math_shift_cmd: + tex_aux_check_second_math_shift(); + break; + } + } 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 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); + } else { + math_surround(math) = 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); + break ; + case math_skip_always_right: + case math_skip_ignore: + break ; + case math_skip_always_surround: + default: + math_surround(math) = 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_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 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; + } else { + math_surround(math) = 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); + break; + case math_skip_always_left: + case math_skip_ignore: + break; + case math_skip_always_surround: + default: + math_surround(math) = math_surround_par; + break; + } + /*tex end mathskip code */ + cur_list.space_factor = default_space_factor; + mathleft = cur_list.math_begin; + mathright = cur_list.math_end; + tex_aux_unsave_math(); } else { - tex_aux_check_display_math_end(); + if (! eqnumber) { + if (cur_cmd == math_shift_cmd) { + tex_aux_check_second_math_shift(); + } else { + tex_aux_check_display_math_end(); + } + } + tex_run_mlist_to_hlist(p, 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)); } + /* local */ + update_tex_math_left_class(mathleft); + update_tex_math_right_class(mathright); + /* global */ + lmt_math_state.last_left = mathleft; + lmt_math_state.last_right = mathright; } - tex_run_mlist_to_hlist(p, 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)); - } - /* local */ - update_tex_math_left_class(mathleft); - update_tex_math_right_class(mathright); - /* global */ - lmt_math_state.last_left = mathleft; - lmt_math_state.last_right = mathright; - } else { - tex_off_save(); + break; + default: + tex_off_save(); + break; } } diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index b9453875e..79ab490e7 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -6574,12 +6574,13 @@ static void tex_mlist_to_hlist_preroll_dimensions(mliststate *state) state->max_depth = siz.dp; } } - DONE_WITH_NODE: +// DONE_WITH_NODE: if ((node_type(current) == simple_noad) && noad_new_hlist(current)) { if (has_noad_option_phantom(current) || has_noad_option_void(current)) { noad_new_hlist(current) = tex_aux_make_list_phantom(noad_new_hlist(current), has_noad_option_void(current), get_attribute_list(current)); } } + DONE_WITH_NODE: current = node_next(current); } } diff --git a/source/luametatex/source/tex/texnesting.c b/source/luametatex/source/tex/texnesting.c index 81d716958..87ca7715a 100644 --- a/source/luametatex/source/tex/texnesting.c +++ b/source/luametatex/source/tex/texnesting.c @@ -225,7 +225,7 @@ void tex_initialize_nesting(void) cur_list.prev_graf = 0; cur_list.mode_line = 0; cur_list.prev_depth = ignore_depth; /*tex |ignore_depth_criterium_par| is not yet available! */ - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; cur_list.incomplete_noad = null; cur_list.direction_stack = null; cur_list.math_dir = 0; @@ -408,3 +408,10 @@ void tex_tail_append(halfword p) node_prev(p) = cur_list.tail; cur_list.tail = p; } + +void tex_tail_append_list(halfword p) +{ + node_next(cur_list.tail) = p; + node_prev(p) = cur_list.tail; + cur_list.tail = tex_tail_of_node_list(p); +} diff --git a/source/luametatex/source/tex/texnesting.h b/source/luametatex/source/tex/texnesting.h index 1f87dbb22..5f98a44c3 100644 --- a/source/luametatex/source/tex/texnesting.h +++ b/source/luametatex/source/tex/texnesting.h @@ -49,6 +49,7 @@ extern void tex_initialize_nesting (void); extern void tex_push_nest (void); extern void tex_pop_nest (void); extern void tex_tail_append (halfword p); +extern void tex_tail_append_list (halfword p); extern halfword tex_pop_tail (void); extern const char *tex_string_mode (int m); extern void tex_show_activities (void); diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 3c9d54452..093978c4e 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -641,11 +641,6 @@ typedef enum kern_subtypes { # define kern_amount(a) vlink(a,2) /*tex aka |width = vlink(a,2)| */ # define kern_expansion(a) vinfo(a,2) /*tex expansion factor (hz) */ -inline static int tex_is_margin_kern(halfword n) -{ - return (n && node_type(n) == kern_node && (node_subtype(n) == left_margin_kern_subtype || node_subtype(n) == right_margin_kern_subtype)); -} - /*tex Disc nodes are complicated: they have three embedded nesting nodes to which the |pre_break|, diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c index 1eb9cc694..c4af153fc 100644 --- a/source/luametatex/source/tex/texpackaging.c +++ b/source/luametatex/source/tex/texpackaging.c @@ -741,13 +741,18 @@ inline static halfword tex_aux_used_order(halfword *total) */ +/*tex + For now we have this here but maybe it makes sense to move the adjust migration to the adjust + module (tracing and such). It's a bit fyzzy code anyway. +*/ + inline static void tex_aux_promote_pre_migrated(halfword r, halfword p) { - halfword pm = box_pre_migrated(p); halfword pa = box_pre_adjusted(p); + halfword pm = box_pre_migrated(p); if (pa) { if (lmt_packaging_state.pre_adjust_tail) { - lmt_packaging_state.pre_adjust_tail = tex_append_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, pa); + lmt_packaging_state.pre_adjust_tail = tex_append_adjust_list(pre_adjust_head, lmt_packaging_state.pre_adjust_tail, pa, "promote"); } else if (box_pre_adjusted(r)) { tex_couple_nodes(box_pre_adjusted(r), pa); } else { @@ -773,11 +778,11 @@ inline static void tex_aux_promote_pre_migrated(halfword r, halfword p) inline static void tex_aux_promote_post_migrated(halfword r, halfword p) { - halfword pm = box_post_migrated(p); halfword pa = box_post_adjusted(p); + halfword pm = box_post_migrated(p); if (pa) { if (lmt_packaging_state.post_adjust_tail) { - lmt_packaging_state.post_adjust_tail = tex_append_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, pa); + lmt_packaging_state.post_adjust_tail = tex_append_adjust_list(post_adjust_head, lmt_packaging_state.post_adjust_tail, pa, "promote"); } else if (box_post_adjusted(r)) { tex_couple_nodes(box_post_adjusted(r), pa); } else { @@ -2526,32 +2531,34 @@ void tex_package(singleword nature) tex_box_end(context, boxnode, shift, mainclass, slot); } +static int local_box_mapping[] = { + [local_left_box_box_code ] = local_left_box_code, + [local_right_box_box_code ] = local_right_box_code, + [local_middle_box_box_code] = local_middle_box_code +}; + void tex_run_unpackage(void) { int code = cur_chr; /*tex should we copy? */ - halfword head = cur_list.tail; - halfword tail = cur_list.tail; switch (code) { case box_code: case copy_code: case unpack_code: { - halfword n = tex_scan_box_register_number(); - halfword b = box_register(n); - if (! b) { - return; - } else { + halfword index = tex_scan_box_register_number(); + halfword box = box_register(index); + if (box) { int bad = 0; switch (cur_list.mode) { case vmode: case internal_vmode: - if (node_type(b) != vlist_node) { + if (node_type(box) != vlist_node) { bad = 1; } break; case hmode: case restricted_hmode: - if (node_type(b) != hlist_node) { + if (node_type(box) != hlist_node) { bad = 1; } break; @@ -2567,151 +2574,122 @@ void tex_run_unpackage(void) "Sorry, Pandora. (You sneaky devil.) I refuse to unbox an \\hbox in vertical mode\n" "or vice versa. And I can't open any boxes in math mode." ); - return; } else { /*tex Todo: check head, not needed, always a temp. */ - /*tex Via variables for varmem assignment. */ - halfword list = box_list(b); - halfword pre_migrated = code == unpack_code ? null : box_pre_migrated(b); - halfword post_migrated = code == unpack_code ? null : box_post_migrated(b); - // halfword pre_adjusted = code == (unpack_code || is_h_mode(cur_list.mode)) ? null : box_pre_adjusted(b); - // halfword post_adjusted = code == (unpack_code || is_h_mode(cur_list.mode)) ? null : box_post_adjusted(b); - // halfword pre_adjusted = code == unpack_code ? null : box_pre_adjusted(b); - // halfword post_adjusted = code == unpack_code ? null : box_post_adjusted(b); - halfword pre_adjusted = box_pre_adjusted(b); - halfword post_adjusted = box_post_adjusted(b); + /*tex We go via variables because we do varmem assignments. Probably not needed */ + halfword tail = cur_list.tail; + halfword list = box_list(box); + halfword pre_migrated = code == unpack_code ? null : box_pre_migrated(box); + halfword post_migrated = code == unpack_code ? null : box_post_migrated(box); + /* probably overkill as we inject vadjust again, maybe it should be an option, 'bind' or so */ + // halfword pre_adjusted = box_pre_adjusted(box); + // halfword post_adjusted = box_post_adjusted(box); + halfword pre_adjusted = code == unpack_code ? null : box_pre_adjusted(box); + halfword post_adjusted = code == unpack_code ? null : box_post_adjusted(box); + // halfword pre_adjusted = code == (unpack_code || is_h_mode(cur_list.mode)) ? null : box_pre_adjusted(box); + // halfword post_adjusted = code == (unpack_code || is_h_mode(cur_list.mode)) ? null : box_post_adjusted(box); + int prunekerns = list && node_type(box) == hlist_node && normalize_line_mode_permitted(normalize_line_mode_par, remove_margin_kerns_mode); + /*tex + This topskip move is an ugly catch for wrong usage: when messing with + vboxes the migrated material can end up outside the unvboxed (pagebody) + content which is not what one wants. The way to prevent is to force + hmode when unboxing. It makes no sense to complicate this mechanism + even more by soem fragile hackery. Best just create what gets asked + and remember that thsi was decided. We need to copy the list earlier + when we do this! + */ + /* + if (list) { + if (code == copy_code) { + list = tex_copy_node_list(list, null); + } else { + box_list(box) = null; + } + } + { + int movetopskip = list && (pre_adjusted || pre_migrated) && node_type(list) == glue_node && node_subtype(list) == top_skip_glue; + if (movetopskip) { + halfword topskip = list; + list = node_next(list); + node_prev(topskip) = null; + node_next(topskip) = null; + tex_try_couple_nodes(tail, topskip); + tail = topskip; + if (list) { + node_prev(list) = null; + } + if (pre_adjusted && tracing_adjusts_par > 1) { + tex_begin_diagnostic(); + tex_print_format("[adjust: topskip moved]"); + tex_end_diagnostic(); + } + } + } + */ if (pre_adjusted) { if (code == copy_code) { pre_adjusted = tex_copy_node_list(pre_adjusted, null); } else { - box_pre_adjusted(b) = null; - } - while (pre_adjusted) { - halfword p = pre_adjusted; - halfword h = adjust_list(pre_adjusted); - if (h) { - if (is_h_mode(cur_list.mode)) { - halfword n = tex_new_node(adjust_node, pre_adjust_code); - adjust_list(n) = h; - h = n; - } - if (! head) { - head = h; - } - tex_try_couple_nodes(tail, h); - tail = tex_tail_of_node_list(h); - adjust_list(pre_adjusted) = null; - } - pre_adjusted = node_next(pre_adjusted); - tex_flush_node(p); + box_pre_adjusted(box) = null; } + tail = tex_flush_adjust_prepend(pre_adjusted, tail); } if (pre_migrated) { if (code == copy_code) { pre_migrated = tex_copy_node_list(pre_migrated, null); } else { - box_pre_migrated(b) = null; + box_pre_migrated(box) = null; } tex_try_couple_nodes(tail, pre_migrated); tail = tex_tail_of_node_list(pre_migrated); - if (! head) { - head = pre_migrated; - } } if (list) { if (code == copy_code) { list = tex_copy_node_list(list, null); } else { - box_list(b) = null; - } + box_list(box) = null; + } tex_try_couple_nodes(tail, list); tail = tex_tail_of_node_list(list); - if (! head) { - head = list; - } } if (post_migrated) { if (code == copy_code) { post_migrated = tex_copy_node_list(post_migrated, null); } else { - box_post_migrated(b) = null; + box_post_migrated(box) = null; } tex_try_couple_nodes(tail, post_migrated); tail = tex_tail_of_node_list(post_migrated); - if (! head) { - head = post_migrated; - } } if (post_adjusted) { if (code == copy_code) { post_adjusted = tex_copy_node_list(post_adjusted, null); } else { - box_post_adjusted(b) = null; - } - while (post_adjusted) { - halfword p = post_adjusted; - halfword h = adjust_list(post_adjusted); - if (h) { - if (is_h_mode(cur_list.mode)) { - halfword n = tex_new_node(adjust_node, post_adjust_code); - adjust_list(n) = h; - h = n; - } - if (! head) { - head = h; - } - tex_try_couple_nodes(tail, h); - tail = tex_tail_of_node_list(h); - adjust_list(post_adjusted) = null; - } - post_adjusted = node_next(post_adjusted); - tex_flush_node(p); + box_post_adjusted(box) = null; } + tail = tex_flush_adjust_append(post_adjusted, tail); } if (code != copy_code) { - box_register(n) = null; - tex_flush_node(b); + box_register(index) = null; + tex_flush_node(box); } - if (! head) { - tail = null; - } else if (node_type(b) == hlist_node && normalize_line_mode_permitted(normalize_line_mode_par, remove_margin_kerns_mode)) { - /* only here head is used ... */ - tail = head; - while (1) { - halfword next = node_next(tail); - if (next) { - if (tex_is_margin_kern(next)) { - tex_try_couple_nodes(tail, node_next(next)); - tex_flush_node(next); - } else { - tail = next; - } - } else { - break; - } - } - } else { - tail = tex_tail_of_node_list(tail); - } - cur_list.tail = tail; + cur_list.tail = prunekerns ? tex_wipe_margin_kerns(cur_list.head) : tex_tail_of_node_list(tail); } - break; } + break; } - case last_box_code: + case page_discards_code: { - tex_try_couple_nodes(tail, lmt_packaging_state.page_discards_head); + tex_try_couple_nodes(cur_list.tail, lmt_packaging_state.page_discards_head); + cur_list.tail = tex_tail_of_node_list(cur_list.tail); lmt_packaging_state.page_discards_head = null; - cur_list.tail = tex_tail_of_node_list(tail); break; } - case tsplit_code: - case vsplit_code: - case dsplit_code: + case split_discards_code: { - tex_try_couple_nodes(tail, lmt_packaging_state.split_discards_head); + tex_try_couple_nodes(cur_list.tail, lmt_packaging_state.split_discards_head); + cur_list.tail = tex_tail_of_node_list(cur_list.tail); lmt_packaging_state.split_discards_head = null; - cur_list.tail = tex_tail_of_node_list(tail); break; } case insert_box_code: @@ -2741,7 +2719,7 @@ void tex_run_unpackage(void) if (boxnode) { halfword list = box_list(boxnode); if (list) { - tex_try_couple_nodes(tail, list); + tex_try_couple_nodes(cur_list.tail, list); cur_list.tail = tex_tail_of_node_list(list); box_list(boxnode) = null; } @@ -2755,21 +2733,11 @@ void tex_run_unpackage(void) break; } case local_left_box_box_code: - { - tex_try_couple_nodes(tail, tex_get_local_boxes(local_left_box_code)); - cur_list.tail = tex_tail_of_node_list(tail); - break; - } case local_right_box_box_code: - { - tex_try_couple_nodes(tail, tex_get_local_boxes(local_right_box_code)); - cur_list.tail = tex_tail_of_node_list(tail); - break; - } case local_middle_box_box_code: { - tex_try_couple_nodes(tail, tex_get_local_boxes(local_middle_box_code)); - cur_list.tail = tex_tail_of_node_list(tail); + tex_try_couple_nodes(cur_list.tail, tex_get_local_boxes(local_box_mapping[code])); + cur_list.tail = tex_tail_of_node_list(cur_list.tail); break; } default: @@ -2778,7 +2746,6 @@ void tex_run_unpackage(void) break; } } - /* margin stuff was here */ } /*tex @@ -2839,28 +2806,23 @@ void tex_append_to_vlist(halfword b, int location, const line_break_properties * case vlist_node: case rule_node: { - halfword p = tex_aux_depth_correction(result, properties); - tex_couple_nodes(cur_list.tail, p); - cur_list.tail = p; + halfword glue = tex_aux_depth_correction(result, properties); + tex_tail_append(glue); break; } } } - while (result) { - tex_couple_nodes(cur_list.tail, result); - cur_list.tail = result; - result = node_next(result); + if (result) { + tex_tail_append_list(result); } return; } } if (cur_list.prev_depth > ignore_depth_criterium_par) { - halfword p = tex_aux_depth_correction(b, properties); - tex_couple_nodes(cur_list.tail, p); - cur_list.tail = p; + halfword glue = tex_aux_depth_correction(b, properties); + tex_tail_append(glue); } - tex_couple_nodes(cur_list.tail, b); - cur_list.tail = b; + tex_tail_append(b); cur_list.prev_depth = box_depth(b); } @@ -3470,7 +3432,7 @@ void tex_begin_box(int boxcontext, scaled shift, halfword slot) tex_begin_token_list(every_vbox_par, every_vbox_text); } } else { - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; if (every_hbox_par) { tex_begin_token_list(every_hbox_par, every_hbox_text); } diff --git a/source/luametatex/source/tex/texpackaging.h b/source/luametatex/source/tex/texpackaging.h index dea884d0f..cba29f61f 100644 --- a/source/luametatex/source/tex/texpackaging.h +++ b/source/luametatex/source/tex/texpackaging.h @@ -39,7 +39,9 @@ typedef enum box_codes { insert_copy_code, local_left_box_box_code, local_right_box_box_code, - local_middle_box_box_code + local_middle_box_box_code, + page_discards_code, + split_discards_code, } box_codes; // typedef enum saved_spec_items { diff --git a/source/luametatex/source/tex/texrules.c b/source/luametatex/source/tex/texrules.c index 1d272f89e..b3d069ad3 100644 --- a/source/luametatex/source/tex/texrules.c +++ b/source/luametatex/source/tex/texrules.c @@ -19,8 +19,6 @@ halfword tex_aux_scan_rule_spec(rule_types t, halfword s) if (s == strut_rule_code) { rule_width(rule) = 0; node_subtype(rule) = strut_rule_subtype; - rule_height(rule) = null_flag; - rule_depth(rule) = null_flag; } else { rule_width(rule) = default_rule; } @@ -135,7 +133,7 @@ halfword tex_aux_scan_rule_spec(rule_types t, halfword s) void tex_aux_run_vrule(void) { tex_tail_append(tex_aux_scan_rule_spec(v_rule_type, cur_chr)); - cur_list.space_factor = 1000; + cur_list.space_factor = default_space_factor; } void tex_aux_run_hrule(void) diff --git a/source/luametatex/source/tex/texscanning.c b/source/luametatex/source/tex/texscanning.c index 845b6fa55..08d5cdaa0 100644 --- a/source/luametatex/source/tex/texscanning.c +++ b/source/luametatex/source/tex/texscanning.c @@ -38,13 +38,13 @@ void tex_scan_left_brace(void) while(1) { tex_get_x_token(); switch (cur_cmd) { + case left_brace_cmd: + /* we found one */ + return; case spacer_cmd: case relax_cmd: /* stay in while */ break; - case left_brace_cmd: - /* we found one */ - return; default: /* we recover */ tex_handle_error( @@ -1084,6 +1084,26 @@ static void tex_aux_set_cur_val_by_define_char_cmd(int chr) switches. */ +static halfword tex_aux_scan_math_style_number(halfword code) +{ + switch (code) { + case yet_unset_math_style: + return tex_scan_math_style_identifier(0, 0); + case scaled_math_style: + return cur_list.math_scale; + case former_choice_math_style: + return 0; + default: + return code; + } +} + +static void tex_aux_set_cur_val_by_math_style_cmd(halfword code) +{ + cur_val = tex_aux_scan_math_style_number(code); + cur_val_level = int_val_level; +} + void tex_scan_something_simple(halfword cmd, halfword chr) { int succeeded = 1; @@ -1151,8 +1171,7 @@ void tex_scan_something_simple(halfword cmd, halfword chr) break; } case math_style_cmd: - cur_val = (chr == yet_unset_math_style) ? tex_scan_math_style_identifier(0, 0) : chr; - cur_val_level = int_val_level; + tex_aux_set_cur_val_by_math_style_cmd(chr); break; case set_auxiliary_cmd: tex_aux_set_cur_val_by_auxiliary_cmd(chr); @@ -1165,6 +1184,7 @@ void tex_scan_something_simple(halfword cmd, halfword chr) break; /* end of tex_aux_short_scan_something_internal */ default: + /* weird message, this library */ tex_handle_error( normal_error_type, "You can't use '%C' as tex library index", @@ -1201,21 +1221,21 @@ static void tex_aux_missing_number_error(void) /* todo: get rid of cur_val */ -static int tex_aux_valid_tok_level(halfword level) -{ - if (level == tok_val_level) { - return 1; - } else { - if (lmt_error_state.intercept) { - lmt_error_state.last_intercept = 1 ; - } else { - tex_aux_missing_number_error(); - } - cur_val = 0; - cur_val_level = dimen_val_level; /* why dimen */ - return 0; - } -} +// static int tex_aux_valid_tok_level(halfword level) +// { +// if (level == tok_val_level) { +// return 1; +// } else { +// if (lmt_error_state.intercept) { +// lmt_error_state.last_intercept = 1 ; +// } else { +// tex_aux_missing_number_error(); +// } +// cur_val = 0; +// cur_val_level = dimen_val_level; /* why dimen */ +// return 0; +// } +// } static int tex_aux_scan_hyph_data_number(halfword code, halfword *target) { @@ -1307,8 +1327,7 @@ static halfword tex_aux_scan_something_internal(halfword cmd, halfword chr, int cur_val_level = int_val_level; break; case math_style_cmd: - cur_val = (chr == yet_unset_math_style) ? tex_scan_math_style_identifier(0, 0) : chr; - cur_val_level = int_val_level; + tex_aux_set_cur_val_by_math_style_cmd(chr); break; case set_auxiliary_cmd: tex_aux_set_cur_val_by_auxiliary_cmd(chr); @@ -1324,7 +1343,8 @@ static halfword tex_aux_scan_something_internal(halfword cmd, halfword chr, int break; /* end of tex_aux_short_scan_something_internal */ case define_font_cmd: - if (tex_aux_valid_tok_level(level)) { + // if (tex_aux_valid_tok_level(level)) { + if (level == tok_val_level) { /* Is this test still needed? */ cur_val = cur_font_par; cur_val_level = font_val_level; return cur_val; @@ -1332,7 +1352,8 @@ static halfword tex_aux_scan_something_internal(halfword cmd, halfword chr, int break; } case set_font_cmd: - if (tex_aux_valid_tok_level(level)) { + // if (tex_aux_valid_tok_level(level)) { + if (level == tok_val_level) { /* Is this test still needed? */ cur_val = cur_chr; cur_val_level = font_val_level; return cur_val; @@ -1958,8 +1979,8 @@ halfword tex_scan_int(int optional_equal, int *radix) lmt_error_state.last_intercept = 1 ; tex_back_input(cur_tok); } else { - result = '0'; /*tex Why not just 0. */ tex_aux_improper_constant_error(); + return 0; } } else { /*tex Scan an optional space. */ @@ -1971,19 +1992,18 @@ halfword tex_scan_int(int optional_equal, int *radix) } else if (cur_cmd >= min_internal_cmd && cur_cmd <= max_internal_cmd) { result = tex_aux_scan_something_internal(cur_cmd, cur_chr, int_val_level, 0, 0); if (cur_val_level != int_val_level) { - result = 0; tex_aux_scan_int_no_number(); + return 0; } } else if (cur_cmd == math_style_cmd) { - /* A pity that we need to check this way in |scan_int|. */ - result = (cur_chr == yet_unset_math_style) ? tex_scan_math_style_identifier(0, 0) : cur_chr; + result = tex_aux_scan_math_style_number(cur_chr); } else if (cur_cmd == hyphenation_cmd) { /* A pity that we need to check this way in |scan_int|. */ if (tex_aux_scan_hyph_data_number(cur_chr, &cur_chr)) { result = cur_chr; } else { - result = 0; tex_aux_scan_int_no_number(); + return 0; } } else { /*tex has an error message been issued? */ @@ -4870,23 +4890,23 @@ static halfword tex_scan_bit_int(int *radix) } } if (result > max_character_code) { - result = '0'; /*tex Why not just 0. */ tex_aux_improper_constant_error(); + return 0; } } else if (cur_cmd >= min_internal_cmd && cur_cmd <= max_internal_cmd) { result = tex_aux_scan_something_internal(cur_cmd, cur_chr, int_val_level, 0, 0); if (cur_val_level != int_val_level) { - result = 0; tex_aux_missing_number_error(); + return 0; } } else if (cur_cmd == math_style_cmd) { - result = (cur_chr == yet_unset_math_style) ? tex_scan_math_style_identifier(0, 0) : cur_chr; + result = tex_aux_scan_math_style_number(cur_chr); } else if (cur_cmd == hyphenation_cmd) { if (tex_aux_scan_hyph_data_number(cur_chr, &cur_chr)) { result = cur_chr; } else { - result = 0; tex_aux_missing_number_error(); + return 0; } } else { int vacuous = 1; diff --git a/source/luametatex/source/tex/textextcodes.c b/source/luametatex/source/tex/textextcodes.c index 2fef9857f..e76329685 100644 --- a/source/luametatex/source/tex/textextcodes.c +++ b/source/luametatex/source/tex/textextcodes.c @@ -54,10 +54,13 @@ void tex_set_cat_code(int h, int n, halfword v, int gl) { sa_tree_item item = { .uint_value = CATCODEDEFAULTS }; sa_tree tree = lmt_catcode_state.catcode_heads[h]; - if (h > lmt_catcode_state.catcode_max) { - lmt_catcode_state.catcode_max = h; - } +// if (h > lmt_catcode_state.catcode_max) { +// lmt_catcode_state.catcode_max = h; +// } if (! tree) { +if (h > lmt_catcode_state.catcode_max) { + lmt_catcode_state.catcode_max = h; +} tree = sa_new_tree(CATCODESTACK, 1, item); lmt_catcode_state.catcode_heads[h] = tree; } @@ -68,10 +71,13 @@ halfword tex_get_cat_code(int h, int n) { sa_tree_item item = { .uint_value = CATCODEDEFAULTS }; sa_tree tree = lmt_catcode_state.catcode_heads[h]; - if (h > lmt_catcode_state.catcode_max) { - lmt_catcode_state.catcode_max = h; - } +// if (h > lmt_catcode_state.catcode_max) { +// lmt_catcode_state.catcode_max = h; +// } if (! tree) { +if (h > lmt_catcode_state.catcode_max) { + lmt_catcode_state.catcode_max = h; +} tree = sa_new_tree(CATCODESTACK, 1, item); lmt_catcode_state.catcode_heads[h] = tree; } |