diff options
Diffstat (limited to 'source/luametatex')
-rw-r--r-- | source/luametatex/source/lua/lmtnodelib.c | 18 | ||||
-rw-r--r-- | source/luametatex/source/lua/lmttexlib.c | 21 | ||||
-rw-r--r-- | source/luametatex/source/luametatex.h | 2 | ||||
-rw-r--r-- | source/luametatex/source/tex/texcommands.c | 1 | ||||
-rw-r--r-- | source/luametatex/source/tex/texequivalents.h | 2 | ||||
-rw-r--r-- | source/luametatex/source/tex/texlinebreak.c | 146 | ||||
-rw-r--r-- | source/luametatex/source/tex/texmath.c | 2 | ||||
-rw-r--r-- | source/luametatex/source/tex/texmlist.c | 38 | ||||
-rw-r--r-- | source/luametatex/source/tex/texnodes.h | 16 | ||||
-rw-r--r-- | source/luametatex/source/tex/texpackaging.c | 2 |
10 files changed, 205 insertions, 43 deletions
diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index 58c3bb0a7..66cf528fc 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -2647,6 +2647,15 @@ static int nodelib_direct_getoptions(lua_State *L) case disc_node: lua_pushinteger(L, disc_options(n)); return 1; + case glue_node: + lua_pushinteger(L, glue_options(n)); + return 1; + case math_node: + lua_pushinteger(L, math_options(n)); + return 1; + case penalty_node: + lua_pushinteger(L, penalty_options(n)); + return 1; case simple_noad: case radical_noad: case fraction_noad: @@ -2674,6 +2683,15 @@ static int nodelib_direct_setoptions(lua_State *L) case disc_node: set_disc_options(n, lmt_tohalfword(L, 2)); break; + case glue_node: + tex_add_glue_option(n, lmt_tohalfword(L, 2)); + return 1; + case math_node: + tex_add_math_option(n, lmt_tohalfword(L, 2)); + return 1; + case penalty_node: + tex_add_penalty_option(n, lmt_tohalfword(L, 2)); + return 1; case simple_noad: case radical_noad: case fraction_noad: diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c index 1bfd2c38c..4f2ecbb5c 100644 --- a/source/luametatex/source/lua/lmttexlib.c +++ b/source/luametatex/source/lua/lmttexlib.c @@ -5015,6 +5015,24 @@ static int texlib_getglyphoptionvalues(lua_State *L) return 1; } +static int texlib_getglueoptionvalues(lua_State *L) +{ + lua_createtable(L, 3, 0); + lua_set_string_by_index(L, glue_option_normal, "normal"); + lua_set_string_by_index(L, glue_option_no_auto_break, "noautobreak"); + lua_set_string_by_index(L, glue_option_short_math, "shortmath"); + return 1; +} + +static int texlib_getpenaltyoptionvalues(lua_State *L) +{ + lua_createtable(L, 3, 0); + lua_set_string_by_index(L, penalty_option_normal, "normal"); + lua_set_string_by_index(L, penalty_option_math_forward, "mathforward");; + lua_set_string_by_index(L, penalty_option_math_backward, "mathbackward"); + return 1; +} + static int texlib_getnoadoptionvalues(lua_State *L) { lua_createtable(L, 2, 37); @@ -5780,6 +5798,9 @@ static const struct luaL_Reg texlib_function_list[] = { { "setrunstate", texlib_setrunstate }, { "gethyphenationvalues", texlib_gethyphenationvalues }, { "getglyphoptionvalues", texlib_getglyphoptionvalues }, + { "getglueoptionvalues", texlib_getglueoptionvalues }, + { "getmathoptionvalues", texlib_getglueoptionvalues }, + { "getpenaltyoptionvalues", texlib_getpenaltyoptionvalues }, { "getnoadoptionvalues", texlib_getnoadoptionvalues }, { "getdiscoptionvalues", texlib_getdiscoptionvalues }, { "getlistanchorvalues", texlib_getlistanchorvalues }, diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index d9df0e14c..a6e9b5295 100644 --- a/source/luametatex/source/luametatex.h +++ b/source/luametatex/source/luametatex.h @@ -92,7 +92,7 @@ # define luametatex_version 210 # define luametatex_revision 9 # define luametatex_version_string "2.10.09" -# define luametatex_development_id 20230529 +# define luametatex_development_id 20230530 # define luametatex_name_camelcase "LuaMetaTeX" # define luametatex_name_lowercase "luametatex" diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 26ae7cef9..1423c80d0 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -167,6 +167,7 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "preinlinepenalty", internal_int_cmd, pre_inline_penalty_code, internal_int_base); tex_primitive(luatex_command, "postshortinlinepenalty", internal_int_cmd, post_short_inline_penalty_code, internal_int_base); tex_primitive(luatex_command, "preshortinlinepenalty", internal_int_cmd, pre_short_inline_penalty_code, internal_int_base); + tex_primitive(luatex_command, "shortinlineorphanpenalty", internal_int_cmd, short_inline_orphan_penalty_code, internal_int_base); tex_primitive(tex_command, "pretolerance", internal_int_cmd, pre_tolerance_code, internal_int_base); tex_primitive(tex_command, "relpenalty", internal_int_cmd, post_relation_penalty_code, internal_int_base); /*tex For old times sake. */ tex_primitive(tex_command, "righthyphenmin", internal_int_cmd, right_hyphen_min_code, internal_int_base); diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index b129cb047..384a17e06 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -437,6 +437,7 @@ typedef enum int_codes { post_inline_penalty_code, /*tex penalty for breaking just after an inlined formula */ pre_short_inline_penalty_code, /*tex penalty for breaking just before a single character inlined formula */ post_short_inline_penalty_code, /*tex penalty for breaking just after a single character inlined formula */ + short_inline_orphan_penalty_code, inter_line_penalty_code, /*tex additional penalty between lines */ double_hyphen_demerits_code, /*tex demerits for double hyphen break */ final_hyphen_demerits_code, /*tex demerits for final hyphen break */ @@ -1411,6 +1412,7 @@ extern void tex_forced_word_define (int g, halfword p, singleword flag, halfword # define post_inline_penalty_par count_parameter(post_inline_penalty_code) # define pre_short_inline_penalty_par count_parameter(pre_short_inline_penalty_code) # define post_short_inline_penalty_par count_parameter(post_short_inline_penalty_code) +# define short_inline_orphan_penalty_par count_parameter(short_inline_orphan_penalty_code) # define local_interline_penalty_par count_parameter(local_interline_penalty_code) # define local_broken_penalty_par count_parameter(local_broken_penalty_code) diff --git a/source/luametatex/source/tex/texlinebreak.c b/source/luametatex/source/tex/texlinebreak.c index 0c2445ffe..93a537ca7 100644 --- a/source/luametatex/source/tex/texlinebreak.c +++ b/source/luametatex/source/tex/texlinebreak.c @@ -2051,7 +2051,7 @@ static void tex_aux_try_break( } else { demerits = demerits * demerits; } - if (penalty != 0) { + if (penalty) { if (penalty > 0) { demerits += (penalty * penalty); } else if (penalty > eject_penalty) { @@ -2198,6 +2198,30 @@ inline static halfword tex_aux_upcoming_penalty(halfword p) { # define max_prev_graf (max_integer/2) +static inline int tex_aux_short_math(halfword m) { + return m && node_subtype(m) == begin_inline_math && math_penalty(m) > 0 && tex_has_math_option(m, glue_option_short_math); +} + +static inline void tex_aux_adapt_short_math_penalty(halfword m, halfword p1, halfword p2) { + if (p1 > math_penalty(m)) { + math_penalty(m) = p1; + } + if (p2 > math_penalty(m)) { + math_penalty(m) = p2; + } +} + +static inline halfword tex_aux_backtrack_over_math(halfword m) +{ + if (node_subtype(m) == end_inline_math) { + do { + m = node_prev(m); + } while (m && node_type(m) != math_node); + } + return m; +} + + void tex_do_line_break(line_break_properties *properties) { /*tex Miscellaneous nodes of temporary interest. */ @@ -2256,7 +2280,7 @@ void tex_do_line_break(line_break_properties *properties) also skip a penalty in the list. */ - if (properties->orphan_penalties || properties->orphan_penalty) { + if (properties->orphan_penalties || properties->orphan_penalty || short_inline_orphan_penalty_par) { halfword current = node_prev(properties->parfill_right_skip); if (current) { /*tex Skip over trailing glue and penalties. */ @@ -2272,37 +2296,119 @@ void tex_do_line_break(line_break_properties *properties) } INJECT: if (properties->orphan_penalties) { - /*tex Inject specified penalties before spaces. */ + /*tex + Inject specified penalties before spaces. When wwe see a math node with a penalty + set then we take the max and jump over a (preceding) skip. Maybe at some point + the |short_inline_orphan_penalty_par| value will also move into the par state. + */ int n = specification_count(properties->orphan_penalties); if (n > 0) { + int skip = 0; halfword i = 0; while (current) { - if (node_type(current) == glue_node) { - switch (node_subtype(current)) { - case space_skip_glue: - case xspace_skip_glue: - case zero_space_skip_glue: - current = tex_aux_inject_orphan_penalty(current, tex_get_specification_penalty(properties->orphan_penalties, ++i)); + switch (node_type(current)) { + case glue_node: + switch (node_subtype(current)) { + case space_skip_glue: + case xspace_skip_glue: + case zero_space_skip_glue: + if (skip) { + skip = 0; + } else { + current = tex_aux_inject_orphan_penalty(current, tex_get_specification_penalty(properties->orphan_penalties, ++i)); + } + if (i == n) { + goto ALLDONE; + } else { + break; + } + } + break; + case math_node: + current = tex_aux_backtrack_over_math(current); + if (tex_aux_short_math(current)) { + halfword p = tex_get_specification_penalty(properties->orphan_penalties, ++i); + tex_aux_adapt_short_math_penalty(current, short_inline_orphan_penalty_par, p); if (i == n) { goto ALLDONE; } else { - break; + skip = 1; } - } + } else { + goto ALLDONE; + } + break; + default: + skip = 0; + break; } current = node_prev(current); } } - } else { + } else if (properties->orphan_penalty) { + /*tex + We inject a penalty before the space but we need to intercept the math penalty + that actually is set on the math mode. If no math orphan penalty is set of when + we have wider math then we assume it's okay. We don't want interference in math + penalties. + + */ while (current) { - if (node_type(current) == glue_node) { - switch (node_subtype(current)) { - case space_skip_glue: - case xspace_skip_glue: - case zero_space_skip_glue: - tex_aux_inject_orphan_penalty(current, properties->orphan_penalty); - goto ALLDONE; - } + switch (node_type(current)) { + case glue_node: + switch (node_subtype(current)) { + case space_skip_glue: + case xspace_skip_glue: + case zero_space_skip_glue: + tex_aux_inject_orphan_penalty(current, properties->orphan_penalty); + goto ALLDONE; + default: + /* maybe we should always quit here */ + break; + } + break; + case math_node: + current = tex_aux_backtrack_over_math(current); + if (tex_aux_short_math(current)) { + tex_aux_adapt_short_math_penalty(current, short_inline_orphan_penalty_par, properties->orphan_penalty); + } + goto ALLDONE; + case disc_node: + /* + This is (or has been) actually an old \CONTEXT\ feature doen in \LUA, + so what should we do here: set the penalty and quit or maybe run till we + hit a non glyph, disc or font kern? Hyphens already get penalties. So, + we do nothong. + */ + break; + } + current = node_prev(current); + } + } else if (short_inline_orphan_penalty_par) { + /*tex + Short formulas at the end of a line are normally not followed by something other + than punctuation. In practice one can set this penalty to e.g. a relatively low + 200 to get the desired effect. We definitely quit on a space and take for granted + what comes before we see the formula. + + */ + while (current) { + switch (node_type(current)) { + case glue_node: + switch (node_subtype(current)) { + case space_skip_glue: + case xspace_skip_glue: + case zero_space_skip_glue: + goto ALLDONE; + } + break; + case math_node: + current = tex_aux_backtrack_over_math(current); + if (tex_aux_short_math(current)) { + tex_aux_adapt_short_math_penalty(current, short_inline_orphan_penalty_par, 0); + } + goto ALLDONE; + } current = node_prev(current); } diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index e2b4f9c39..923ffa56e 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -5010,6 +5010,8 @@ void tex_run_math_shift(void) if (post_short_inline_penalty_par != max_integer) { math_penalty(endmath) = post_short_inline_penalty_par; } + tex_add_math_option(beginmath, glue_option_short_math); + tex_add_math_option(endmath, glue_option_short_math); } cur_list.space_factor = default_space_factor; mathleft = cur_list.math_begin; diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 1b9201172..d91ee50ae 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -1981,7 +1981,7 @@ void tex_run_mlist_to_hlist(halfword mlist, halfword penalties, halfword style, node_next(temp_head) = null; } if (penalties) { // && tex_in_main_math_style(style) - /*tex This makes no sense in display math not in script styles. */ + /*tex This makes no sense in display math nor in script styles. */ switch (style) { case text_style: case cramped_text_style: @@ -1992,8 +1992,8 @@ void tex_run_mlist_to_hlist(halfword mlist, halfword penalties, halfword style, halfword i = 1; while (h && i <= n) { if (tex_aux_is_math_penalty(h)) { - penalty_amount(h) += tex_get_specification_penalty(math_forward_penalties_par, i); - ++i; + penalty_amount(h) += tex_get_specification_penalty(math_forward_penalties_par, i++); + tex_add_penalty_option(h, penalty_option_math_forward); } h = node_next(h); } @@ -2006,8 +2006,8 @@ void tex_run_mlist_to_hlist(halfword mlist, halfword penalties, halfword style, halfword i = 1; while (t && i <= n) { if (tex_aux_is_math_penalty(t)) { - penalty_amount(t) += tex_get_specification_penalty(math_backward_penalties_par, i); - ++i; + penalty_amount(t) += tex_get_specification_penalty(math_backward_penalties_par, i++); + tex_add_penalty_option(t, penalty_option_math_backward); } t = node_prev(t); } @@ -7304,13 +7304,13 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) recent_subtype = node_subtype(recent); /* todo: maybe also check the mainclass of the recent */ if ((recent_type != penalty_node) && ! (recent_type == simple_noad && tex_math_has_class_option(recent_subtype, omit_penalty_class_option))) { - halfword z = tex_new_penalty_node(post_penalty, math_post_penalty_subtype); - tex_attach_attribute_list_copy(z, current); - tex_couple_nodes(p, z); - p = z; + halfword penalty = tex_new_penalty_node(post_penalty, math_post_penalty_subtype); + tex_attach_attribute_list_copy(penalty, current); + tex_couple_nodes(p, penalty); + p = penalty; if (tracing_math_par >= 2) { tex_begin_diagnostic(); - tex_print_format("[math: post penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(z)); + tex_print_format("[math: post penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(penalty)); tex_end_diagnostic(); } } @@ -7330,11 +7330,11 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) recent_plus_glyph = current_plus_glyph; // if (first && recent_left_slack) { if (p == temp_head && recent_left_slack) { - halfword k = tex_new_kern_node(-recent_left_slack, horizontal_math_kern_subtype); - halfword h = node_next(temp_head); - tex_attach_attribute_list_copy(k, p); - tex_couple_nodes(k, h); - node_next(temp_head) = k; + halfword kern = tex_new_kern_node(-recent_left_slack, horizontal_math_kern_subtype); + halfword head = node_next(temp_head); + tex_attach_attribute_list_copy(kern, p); + tex_couple_nodes(kern, head); + node_next(temp_head) = kern; if (tracing_math_par >= 2) { tex_begin_diagnostic(); tex_print_format("[math: nilling recent left slack %p]", recent_left_slack); @@ -7344,10 +7344,10 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) recent = current; current = node_next(current); if (! current && recent_right_slack) { - halfword k = tex_new_kern_node(-recent_right_slack, horizontal_math_kern_subtype); - tex_attach_attribute_list_copy(k, p); - tex_couple_nodes(p, k); - p = k; + halfword kern = tex_new_kern_node(-recent_right_slack, horizontal_math_kern_subtype); + tex_attach_attribute_list_copy(kern, p); + tex_couple_nodes(p, kern); + p = kern; if (tracing_math_par >= 2) { tex_begin_diagnostic(); tex_print_format("[math: nilling recent right slack %p]", recent_right_slack); diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 80ab40f03..3550e7345 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -422,8 +422,19 @@ typedef enum attribute_subtypes { with arguments. */ -# define penalty_node_size 3 -# define penalty_amount(a) vlink(a,2) +# define penalty_node_size 3 +# define penalty_amount(a) vlink(a,2) +# define penalty_options(a) vinfo(a,2) + +inline static void tex_add_penalty_option (halfword a, halfword r) { penalty_options(a) |= r; } +inline static void tex_remove_penalty_option (halfword a, halfword r) { penalty_options(a) &= ~(r | penalty_options(a)); } +inline static int tex_has_penalty_option (halfword a, halfword r) { return (penalty_options(a) & r) == r; } + +typedef enum penalty_option_codes { + penalty_option_normal = 0x0000, + penalty_option_math_forward = 0x0001, + penalty_option_math_backward = 0x0002, +} penalty_option_codes; typedef enum penalty_subtypes { user_penalty_subtype, @@ -522,6 +533,7 @@ typedef enum glue_option_codes { // glue_force_auto_break = 0x0001, // glue_originates_in_math = 0x0002, glue_option_no_auto_break = 0x0001, + glue_option_short_math = 0x0002, } glue_option_codes; typedef enum math_subtypes { diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c index 83ace07fa..9f66232a7 100644 --- a/source/luametatex/source/tex/texpackaging.c +++ b/source/luametatex/source/tex/texpackaging.c @@ -2781,7 +2781,7 @@ static halfword tex_aux_depth_correction(halfword b, const line_break_properties p = tex_new_param_glue_node(line_skip_code, line_skip_glue); } else { p = tex_new_param_glue_node(baseline_skip_code, baseline_skip_glue); - glue_amount(p) = d; + glue_amount(p) = d; /* we keep the stretch and shrink */ } } return p; |