diff options
-rw-r--r-- | Build/source/texk/web2c/luatexdir/ChangeLog | 8 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/luafont.c | 92 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luatex_svnversion.h | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/commands.c | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/dumpdata.c | 2 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/equivalents.h | 6 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/mlist.c | 15 | ||||
-rw-r--r-- | Build/source/texk/web2c/luatexdir/tex/texmath.c | 38 | ||||
-rw-r--r-- | Build/source/texk/web2c/mplibdir/ChangeLog | 4 | ||||
-rw-r--r-- | Build/source/texk/web2c/mplibdir/mp.w | 8 |
10 files changed, 134 insertions, 43 deletions
diff --git a/Build/source/texk/web2c/luatexdir/ChangeLog b/Build/source/texk/web2c/luatexdir/ChangeLog index 350e7557c45..6f218f96332 100644 --- a/Build/source/texk/web2c/luatexdir/ChangeLog +++ b/Build/source/texk/web2c/luatexdir/ChangeLog @@ -1,3 +1,11 @@ +2021-04-21 Luigi Scarso <luigi.scarso@gmail.com> + *\discretionaryligaturemode: optionally block select disc creation + (see [Dev-luatex] [PATCH] Nested discretionaries M.F. Krüger) (HH) + +2021-04-19 Luigi Scarso <luigi.scarso@gmail.com> + *\mathdefaultsmode: different radical style defaults + (see [Dev-luatex] Uunderdelimiter & friends and mathstyles by M.F. Krüger) (HH) + 2021-04-19 Luigi Scarso <luigi.scarso@gmail.com> * A patch for linkarea in rtl context diff --git a/Build/source/texk/web2c/luatexdir/font/luafont.c b/Build/source/texk/web2c/luatexdir/font/luafont.c index 68068639dcf..2e08facb1d9 100644 --- a/Build/source/texk/web2c/luatexdir/font/luafont.c +++ b/Build/source/texk/web2c/luatexdir/font/luafont.c @@ -2223,6 +2223,22 @@ static halfword handle_lig_nest(halfword root, halfword cur) return root; } +/*tex + Because \LATEX\ dev wants to support more complex select sequences we get a + compatibility issue. For that reason we now can block select discs in so + called \quote {base} mode (the traditional \TEX\ font handling). By + completely blocking select discs (which actually were just implemented for + the rare case of having multiple hyphenation points in a three character + ligature) we simplify handling and possible side effects of patches in the + line break routines (which then becomes more complex). Because the \CONTEXT\ + font handler doesn't inject select discretionaries we don't expect side + effects there. The control parameter |\discretionaryligaturemode| defaults to + the value 0. A value of 1 reflects \quotation {lazy ligaturing} i.e.\ |f-f-i| + becomes |f-fi|, and a value of 2 turns |f-f-i| into |ff-i|. This mechanism is + backport of \LUAMETATEX\ where select discs had been abandoned already and + where lazy ligatures is one of the possible glyph properties. +*/ + static halfword handle_lig_word(halfword cur) { halfword right = null; @@ -2403,34 +2419,62 @@ static halfword handle_lig_word(halfword cur) && type(next) == glyph_node && ((tlink_post_break(cur) != null && test_ligature(&lig, tlink_post_break(cur), next)) || (tlink_no_break (cur) != null && test_ligature(&lig, tlink_no_break (cur), next)))) { - /*tex Building an |init_disc| followed by a |select_disc|: |{a-}{b}{AB} {-}{}{} c| */ + /*tex Optionally building an |init_disc| followed by a |select_disc|: |{a-}{b}{AB} {-}{}{} c| */ halfword last1 = vlink(next), tail; uncouple_node(next); try_couple_nodes(fwd, last1); - /*tex |{a-}{b}{AB} {-}{c}{}| */ - nesting_append(post_break(fwd), copy_node(next)); - /*tex |{a-}{b}{AB} {-}{c}{-}| */ - if (vlink_no_break(cur) != null) { - nesting_prepend(no_break(fwd), copy_node(vlink_pre_break(fwd))); - } - /*tex |{a-}{b}{AB} {b-}{c}{-}| */ - if (vlink_post_break(cur) != null) - nesting_prepend_list(pre_break(fwd), copy_node_list(vlink_post_break(cur))); - /*tex |{a-}{b}{AB} {b-}{c}{AB-}| */ - if (vlink_no_break(cur) != null) { - nesting_prepend_list(no_break(fwd), copy_node_list(vlink_no_break(cur))); + /* the modes are ported from luametatex (not one-to-one, so they need checking) */ + if (discretionary_ligature_mode_par == 1) { + /*tex f-f-i -> f-fi */ + halfword tail = tlink_no_break(cur); + nesting_append(no_break(cur), copy_node(next)); + handle_lig_nest(no_break(cur), tail); + tail = tlink_post_break(cur); + nesting_append(post_break(cur), next); + handle_lig_nest(post_break(cur), tail); + try_couple_nodes(alink(fwd), vlink(fwd)); + flush_node(fwd); + } else if (discretionary_ligature_mode_par == 2) { + /*tex f-f-i -> ff-i : |{a-}{b}{AB} {-}{c}{}| => |{AB-}{c}{ABc}| */ + nesting_append(post_break(fwd), copy_node(next)); + if (vlink_no_break(cur)) { + halfword tail; + nesting_prepend_list(no_break(fwd), copy_node_list(vlink_no_break(cur))); + tail = tlink_no_break(fwd); + nesting_append(no_break(fwd), next); + handle_lig_nest(no_break(fwd), tail); + nesting_prepend_list(pre_break(fwd), copy_node_list(vlink_no_break(cur))); + } + try_couple_nodes(alink(cur), vlink(cur)); + flush_node(cur); + cur = fwd; + } else { + /*tex |{a-}{b}{AB} {-}{c}{}| */ + nesting_append(post_break(fwd), copy_node(next)); + /*tex |{a-}{b}{AB} {-}{c}{-}| */ + if (vlink_no_break(cur) != null) { + nesting_prepend(no_break(fwd), copy_node(vlink_pre_break(fwd))); + } + /*tex |{a-}{b}{AB} {b-}{c}{-}| */ + if (vlink_post_break(cur) != null) + nesting_prepend_list(pre_break(fwd), copy_node_list(vlink_post_break(cur))); + /*tex |{a-}{b}{AB} {b-}{c}{AB-}| */ + if (vlink_no_break(cur) != null) { + nesting_prepend_list(no_break(fwd), copy_node_list(vlink_no_break(cur))); + } + /*tex |{a-}{b}{ABC} {b-}{c}{AB-}| */ + tail = tlink_no_break(cur); + nesting_append(no_break(cur), copy_node(next)); + handle_lig_nest(no_break(cur), tail); + /*tex |{a-}{BC}{ABC} {b-}{c}{AB-}| */ + tail = tlink_post_break(cur); + nesting_append(post_break(cur), next); + handle_lig_nest(post_break(cur), tail); + /*tex Set the subtypes: */ + subtype(cur) = init_disc; + subtype(fwd) = select_disc; } - /*tex |{a-}{b}{ABC} {b-}{c}{AB-}| */ - tail = tlink_no_break(cur); - nesting_append(no_break(cur), copy_node(next)); - handle_lig_nest(no_break(cur), tail); - /*tex |{a-}{BC}{ABC} {b-}{c}{AB-}| */ - tail = tlink_post_break(cur); - nesting_append(post_break(cur), next); - handle_lig_nest(post_break(cur), tail); - /*tex Set the subtypes: */ - subtype(cur) = init_disc; - subtype(fwd) = select_disc; + } } } diff --git a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h index e71e8868ac7..883b2d562f3 100644 --- a/Build/source/texk/web2c/luatexdir/luatex_svnversion.h +++ b/Build/source/texk/web2c/luatexdir/luatex_svnversion.h @@ -1 +1 @@ -#define luatex_svn_revision 7432 +#define luatex_svn_revision 7438 diff --git a/Build/source/texk/web2c/luatexdir/tex/commands.c b/Build/source/texk/web2c/luatexdir/tex/commands.c index 261f23f4a83..576306b35eb 100644 --- a/Build/source/texk/web2c/luatexdir/tex/commands.c +++ b/Build/source/texk/web2c/luatexdir/tex/commands.c @@ -176,6 +176,8 @@ void initialize_commands(void) primitive_luatex("exceptionpenalty", assign_int_cmd, int_base + exception_penalty_code, int_base); primitive_luatex("fixupboxesmode", assign_int_cmd, int_base + fixup_boxes_code, int_base); primitive_luatex("glyphdimensionsmode", assign_int_cmd, int_base + glyph_dimensions_code, int_base); + primitive_luatex("mathdefaultsmode", assign_int_cmd, int_base + math_defaults_mode_code, int_base); + primitive_luatex("discretionaryligaturemode", assign_int_cmd, int_base + discretionary_ligature_mode_code, int_base); /*tex diff --git a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c b/Build/source/texk/web2c/luatexdir/tex/dumpdata.c index e7d53050b29..8270277c38d 100644 --- a/Build/source/texk/web2c/luatexdir/tex/dumpdata.c +++ b/Build/source/texk/web2c/luatexdir/tex/dumpdata.c @@ -32,7 +32,7 @@ with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */ -#define FORMAT_ID (907+54) +#define FORMAT_ID (907+56) #if ((FORMAT_ID>=0) && (FORMAT_ID<=256)) #error Wrong value for FORMAT_ID. #endif diff --git a/Build/source/texk/web2c/luatexdir/tex/equivalents.h b/Build/source/texk/web2c/luatexdir/tex/equivalents.h index 83117c64fa1..459c2cb0143 100644 --- a/Build/source/texk/web2c/luatexdir/tex/equivalents.h +++ b/Build/source/texk/web2c/luatexdir/tex/equivalents.h @@ -309,8 +309,10 @@ the |number_regs| \.{\\dimen} registers. # define suppress_primitive_error_code 116 # define fixup_boxes_code 117 # define glyph_dimensions_code 118 +# define math_defaults_mode_code 119 /* > 0 : latex preferences */ +# define discretionary_ligature_mode_code 120 -# define math_option_code 119 +# define math_option_code 121 # define mathoption_int_base_code (math_option_code+1) /* one reserve */ # define mathoption_int_last_code (mathoption_int_base_code+8) @@ -811,6 +813,8 @@ extern halfword last_cs_name; #define fixup_boxes_par int_par(fixup_boxes_code) #define glyph_dimensions_par int_par(glyph_dimensions_code) +#define math_defaults_mode_par int_par(math_defaults_mode_code) +#define discretionary_ligature_mode_par int_par(discretionary_ligature_mode_code) /* */ diff --git a/Build/source/texk/web2c/luatexdir/tex/mlist.c b/Build/source/texk/web2c/luatexdir/tex/mlist.c index 2ac631ea339..c33e08f1315 100644 --- a/Build/source/texk/web2c/luatexdir/tex/mlist.c +++ b/Build/source/texk/web2c/luatexdir/tex/mlist.c @@ -2385,7 +2385,10 @@ static void make_over_delimiter(pointer q, int cur_style) pointer x, y, v; scaled shift_up, shift_down, clr, delta, wd; boolean stack; - x = clean_box(nucleus(q), sub_style(cur_style), cur_style, math_nucleus_list); + if (math_defaults_mode_par > 0) + x = clean_box(nucleus(q), sup_style(cur_style), cur_style, math_nucleus_list); + else + x = clean_box(nucleus(q), sub_style(cur_style), cur_style, math_nucleus_list); check_widths(q,x); y = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; @@ -2416,7 +2419,10 @@ static void make_under_delimiter(pointer q, int cur_style) pointer x, y, v; scaled shift_up, shift_down, clr, delta, wd; boolean stack; - y = clean_box(nucleus(q), sup_style(cur_style), cur_style, math_nucleus_list); + if (math_defaults_mode_par > 0) + y = clean_box(nucleus(q), sub_style(cur_style), cur_style, math_nucleus_list); + else + y = clean_box(nucleus(q), sup_style(cur_style), cur_style, math_nucleus_list); check_widths(q,y); x = do_delimiter(q, left_delimiter(q), cur_size, wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; @@ -2447,7 +2453,10 @@ static void make_delimiter_over(pointer q, int cur_style) pointer x, y, v; scaled shift_up, shift_down, clr, actual, wd; boolean stack; - y = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list); + if (math_defaults_mode_par > 0) + y = clean_box(nucleus(q), cramped_style(cur_style), cur_style, math_nucleus_list); + else + y = clean_box(nucleus(q), cur_style, cur_style, math_nucleus_list); check_widths(q,y); x = do_delimiter(q, left_delimiter(q), cur_size + (cur_size == script_script_size ? 0 : 1), wd, true, cur_style, true, &stack, NULL, NULL); left_delimiter(q) = null; diff --git a/Build/source/texk/web2c/luatexdir/tex/texmath.c b/Build/source/texk/web2c/luatexdir/tex/texmath.c index 461a51578fb..ebfb50a804a 100644 --- a/Build/source/texk/web2c/luatexdir/tex/texmath.c +++ b/Build/source/texk/web2c/luatexdir/tex/texmath.c @@ -1577,11 +1577,17 @@ static void scan_delimiter(pointer p, int r) return; } +/*tex + Because \LATEX\ expect some different defaults, we now have |math_defaults_mode_par| controlling + the style. By using a variable we can remain downward compatible. +*/ + void math_radical(void) { halfword q; int chr_code = cur_chr; halfword options = 0; + halfword used_style = cramped_style(m_style); tail_append(new_node(radical_noad, chr_code)); q = new_node(delim_node, 0); left_delimiter(tail) = q; @@ -1600,32 +1606,42 @@ void math_radical(void) } } radicaloptions(tail) = options; - if (chr_code == 0) + if (chr_code == 0) { /*tex \.{\\radical} */ scan_delimiter(left_delimiter(tail), tex_mathcode); - else if (chr_code == 1) + } else if (chr_code == 1) { /*tex \.{\\Uradical} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 2) + } else if (chr_code == 2) { /*tex \.{\\Uroot} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 3) + } else if (chr_code == 3) { /*tex \.{\\Uunderdelimiter} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 4) + if (math_defaults_mode_par > 0) { + used_style = sub_style(m_style); + } + } else if (chr_code == 4) { /*tex \.{\\Uoverdelimiter} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 5) + if (math_defaults_mode_par > 0) { + used_style = sup_style(m_style); + } + } else if (chr_code == 5) { /*tex \.{\\Udelimiterunder} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 6) + if (math_defaults_mode_par > 0) { + used_style = m_style; + } + } else if (chr_code == 6) { /*tex \.{\\Udelimiterover} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else if (chr_code == 7) + } else if (chr_code == 7) { /*tex \.{\\Uhextensible} */ scan_delimiter(left_delimiter(tail), umath_mathcode); - else + } else { confusion("math_radical"); + } if (chr_code == 7) { /*tex type will change */ q = new_node(sub_box_node, 0); @@ -1645,12 +1661,12 @@ void math_radical(void) vlink(degree(tail)) = null; q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail), cramped_style(m_style)); + (void) scan_math(nucleus(tail), used_style); } } else { q = new_node(math_char_node, 0); nucleus(tail) = q; - (void) scan_math(nucleus(tail), cramped_style(m_style)); + (void) scan_math(nucleus(tail), used_style); } } diff --git a/Build/source/texk/web2c/mplibdir/ChangeLog b/Build/source/texk/web2c/mplibdir/ChangeLog index 3a421c77907..1ad10d39285 100644 --- a/Build/source/texk/web2c/mplibdir/ChangeLog +++ b/Build/source/texk/web2c/mplibdir/ChangeLog @@ -1,3 +1,7 @@ +2021-05-09 Luigi Scarso <luigi.scarso@gmail.com> + * Impose mp->stack_size < 1001 in @d push_input to avoid stack overflow + due infinite recursion of macro expansion (thanks to A. Kakuto). + 2021-04-10 Luigi Scarso <luigi.scarso@gmail.com> * Metapost version 2.01 (needed to mark the patch mpx_copy_mpto). diff --git a/Build/source/texk/web2c/mplibdir/mp.w b/Build/source/texk/web2c/mplibdir/mp.w index 2a28640c215..acb64feed7f 100644 --- a/Build/source/texk/web2c/mplibdir/mp.w +++ b/Build/source/texk/web2c/mplibdir/mp.w @@ -18136,11 +18136,15 @@ new level (having, initially, the same properties as the old). @d push_input { /* enter a new input level, save the old */ if ( mp->input_ptr>mp->max_in_stack ) { mp->max_in_stack=mp->input_ptr; - if ( mp->input_ptr==mp->stack_size ) { + /* The mp->stack_size < 1001 condition is necessary to prevent stack overflow due infinite recursion. */ + if ( mp->input_ptr==mp->stack_size && mp->stack_size < 1001) { int l = (mp->stack_size+(mp->stack_size/4)); XREALLOC(mp->input_stack, l, in_state_record); mp->stack_size = l; - } + } else { + fprintf(stderr, "input stack overflow\n"); + exit(EXIT_FAILURE); + } } mp->input_stack[mp->input_ptr]=mp->cur_input; /* stack the record */ incr(mp->input_ptr); |