From fb63eac7402fbd3bb00d7591cc4fbac1b2db2582 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Wed, 7 Dec 2022 21:44:10 +0100
Subject: 2022-12-07 20:24:00

---
 source/luametatex/source/lua/lmtinterface.h       |  13 +-
 source/luametatex/source/lua/lmtnodelib.c         |   4 +-
 source/luametatex/source/lua/lmttexlib.c          |  67 +++---
 source/luametatex/source/tex/texdumpdata.h        |   2 +-
 source/luametatex/source/tex/texmath.c            |  21 +-
 source/luametatex/source/tex/texmlist.c           | 259 ++++++++++------------
 source/luametatex/source/tex/texnodes.c           |   8 +-
 source/luametatex/source/tex/texnodes.h           | 171 +++++++-------
 source/luametatex/source/tex/texprinting.c        |   8 +-
 source/luametatex/source/tex/texprinting.h        |   6 +-
 source/luametatex/source/tex/textypes.h           |   1 +
 source/luametatex/source/utilities/auxunistring.c |   3 +-
 12 files changed, 284 insertions(+), 279 deletions(-)

(limited to 'source/luametatex')

diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h
index 756a25331..67c3f56d5 100644
--- a/source/luametatex/source/lua/lmtinterface.h
+++ b/source/luametatex/source/lua/lmtinterface.h
@@ -675,6 +675,8 @@ make_lua_key(L, first);\
 make_lua_key(L, fixedboth);\
 make_lua_key(L, fixedbottom);\
 make_lua_key(L, fixedtop);\
+make_lua_key(L, fixedsuperorsubscript);\
+make_lua_key(L, fixedsuperandsubscript);\
 make_lua_key(L, flags);\
 make_lua_key(L, flataccent);\
 make_lua_key(L, flattenedaccentbasedepth);\
@@ -1279,6 +1281,7 @@ make_lua_key(L, smaller);\
 make_lua_key(L, smallfamily);\
 make_lua_key(L, some_item);\
 make_lua_key(L, source);\
+make_lua_key(L, sourceonnucleus);\
 make_lua_key(L, space);\
 make_lua_key(L, spaceafterscript);\
 make_lua_key(L, SpaceAfterScript);\
@@ -1650,6 +1653,10 @@ extern lmt_keys_info lmt_keys;
 # define lmt_checkhalfword(L,i)    (halfword)    luaL_checkinteger(L,i)
 # define lmt_opthalfword(L,i,j)    (halfword)    luaL_optinteger(L,i,j)
 
+# define lmt_tofullword(L,i)       (fullword)    lua_tointeger(L,i)
+# define lmt_checkfullword(L,i)    (fullword)    luaL_checkinteger(L,i)
+# define lmt_optfullword(L,i,j)    (fullword)    luaL_optinteger(L,i,j)
+
 # define lmt_toscaled(L,i)         (scaled)      lua_tointeger(L,i)
 # define lmt_checkscaled(L,i)      (scaled)      luaL_checkinteger(L,i)
 # define lmt_optscaled(L,i,j)      (scaled)      luaL_optinteger(L,i,j)
@@ -1658,9 +1665,9 @@ extern lmt_keys_info lmt_keys;
 # define lmt_checkquarterword(L,i) (quarterword) luaL_checkinteger(L,i)
 # define lmt_optquarterword(L,i,j) (quarterword) luaL_optinteger(L,i,j)
 
-# define lmt_tosingleword(L,i)     (singleword) lua_tointeger(L,i)
-# define lmt_checksingleword(L,i)  (singleword) luaL_checkinteger(L,i)
-# define lmt_optsingleword(L,i,j)  (singleword) luaL_optinteger(L,i,j)
+# define lmt_tosingleword(L,i)     (singleword)  lua_tointeger(L,i)
+# define lmt_checksingleword(L,i)  (singleword)  luaL_checkinteger(L,i)
+# define lmt_optsingleword(L,i,j)  (singleword)  luaL_optinteger(L,i,j)
 
 # undef lround
 # include <math.h>
diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c
index 58a98f7e3..afaa8bed5 100644
--- a/source/luametatex/source/lua/lmtnodelib.c
+++ b/source/luametatex/source/lua/lmtnodelib.c
@@ -2674,7 +2674,7 @@ static int nodelib_direct_setoptions(lua_State *L)
             case fraction_noad:
             case accent_noad:
             case fence_noad:
-                noad_options(n) = lmt_tohalfword(L, 2);
+                noad_options(n) = lmt_tofullword(L, 2);
                 break;
             case math_char_node:
             case math_text_char_node:
@@ -7372,7 +7372,7 @@ static int nodelib_common_setfield(lua_State *L, int direct, halfword n)
                             } else if (lua_key_eq(s, source)) {
                                 noad_source(n) = lmt_tohalfword(L, 3);
                             } else if (lua_key_eq(s, options)) {
-                                noad_options(n) = lmt_tohalfword(L, 3);
+                                noad_options(n) = lmt_tofullword(L, 3);
                             } else if (lua_key_eq(s, scriptorder)) {
                                 noad_script_order(n) = lmt_tosingleword(L, 3);
                             } else if (lua_key_eq(s, class)) {
diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c
index d3f4c0ab9..7d9395eb7 100644
--- a/source/luametatex/source/lua/lmttexlib.c
+++ b/source/luametatex/source/lua/lmttexlib.c
@@ -4757,38 +4757,41 @@ static int texlib_getglyphoptionvalues(lua_State *L)
 static int texlib_getnoadoptionvalues(lua_State *L)
 {
     lua_createtable(L, 2, 32);
-    lua_push_key_at_index(L, axis,                  noad_option_axis);
-    lua_push_key_at_index(L, noaxis,                noad_option_no_axis);
-    lua_push_key_at_index(L, exact,                 noad_option_exact);
-    lua_push_key_at_index(L, left,                  noad_option_left);
-    lua_push_key_at_index(L, middle,                noad_option_middle);
-    lua_push_key_at_index(L, right,                 noad_option_right);
-    lua_push_key_at_index(L, adapttoleftsize,       noad_option_adapt_to_left_size);
-    lua_push_key_at_index(L, adapttorightsize,      noad_option_adapt_to_right_size);
-    lua_push_key_at_index(L, nosubscript,           noad_option_no_sub_script);
-    lua_push_key_at_index(L, nosuperscript,         noad_option_no_super_script);
-    lua_push_key_at_index(L, nosubprescript,        noad_option_no_sub_pre_script);
-    lua_push_key_at_index(L, nosuperprescript,      noad_option_no_super_pre_script);
-    lua_push_key_at_index(L, noscript,              noad_option_no_script);
-    lua_push_key_at_index(L, nooverflow,            noad_option_no_overflow);
-    lua_push_key_at_index(L, void,                  noad_option_void);
-    lua_push_key_at_index(L, phantom,               noad_option_phantom);
-    lua_push_key_at_index(L, openupheight,          noad_option_openup_height);
-    lua_push_key_at_index(L, openupdepth,           noad_option_openup_depth);
-    lua_push_key_at_index(L, limits,                noad_option_limits);
-    lua_push_key_at_index(L, nolimits,              noad_option_no_limits);
-    lua_push_key_at_index(L, preferfontthickness,   noad_option_prefer_font_thickness);
-    lua_push_key_at_index(L, noruling,              noad_option_no_ruling);
-    lua_push_key_at_index(L, shiftedsubscript,      noad_option_shifted_sub_script);
-    lua_push_key_at_index(L, shiftedsuperscript,    noad_option_shifted_super_script);
-    lua_push_key_at_index(L, shiftedsubprescript,   noad_option_shifted_sub_pre_script);
-    lua_push_key_at_index(L, shiftedsuperprescript, noad_option_shifted_super_pre_script);
-    lua_push_key_at_index(L, unpacklist,            noad_option_unpack_list);
-    lua_push_key_at_index(L, nocheck,               noad_option_no_check);
-    lua_push_key_at_index(L, auto,                  noad_option_auto);
-    lua_push_key_at_index(L, unrolllist,            noad_option_unroll_list);
-    lua_push_key_at_index(L, followedbyspace,       noad_option_followed_by_space);
-    lua_push_key_at_index(L, proportional,          noad_option_proportional);
+    lua_push_key_at_index(L, axis,                   noad_option_axis);
+    lua_push_key_at_index(L, noaxis,                 noad_option_no_axis);
+    lua_push_key_at_index(L, exact,                  noad_option_exact);
+    lua_push_key_at_index(L, left,                   noad_option_left);
+    lua_push_key_at_index(L, middle,                 noad_option_middle);
+    lua_push_key_at_index(L, right,                  noad_option_right);
+    lua_push_key_at_index(L, adapttoleftsize,        noad_option_adapt_to_left_size);
+    lua_push_key_at_index(L, adapttorightsize,       noad_option_adapt_to_right_size);
+    lua_push_key_at_index(L, nosubscript,            noad_option_no_sub_script);
+    lua_push_key_at_index(L, nosuperscript,          noad_option_no_super_script);
+    lua_push_key_at_index(L, nosubprescript,         noad_option_no_sub_pre_script);
+    lua_push_key_at_index(L, nosuperprescript,       noad_option_no_super_pre_script);
+    lua_push_key_at_index(L, noscript,               noad_option_no_script);
+    lua_push_key_at_index(L, nooverflow,             noad_option_no_overflow);
+    lua_push_key_at_index(L, void,                   noad_option_void);
+    lua_push_key_at_index(L, phantom,                noad_option_phantom);
+    lua_push_key_at_index(L, openupheight,           noad_option_openup_height);
+    lua_push_key_at_index(L, openupdepth,            noad_option_openup_depth);
+    lua_push_key_at_index(L, limits,                 noad_option_limits);
+    lua_push_key_at_index(L, nolimits,               noad_option_no_limits);
+    lua_push_key_at_index(L, preferfontthickness,    noad_option_prefer_font_thickness);
+    lua_push_key_at_index(L, noruling,               noad_option_no_ruling);
+    lua_push_key_at_index(L, shiftedsubscript,       noad_option_shifted_sub_script);
+    lua_push_key_at_index(L, shiftedsuperscript,     noad_option_shifted_super_script);
+    lua_push_key_at_index(L, shiftedsubprescript,    noad_option_shifted_sub_pre_script);
+    lua_push_key_at_index(L, shiftedsuperprescript,  noad_option_shifted_super_pre_script);
+    lua_push_key_at_index(L, unpacklist,             noad_option_unpack_list);
+    lua_push_key_at_index(L, nocheck,                noad_option_no_check);
+    lua_push_key_at_index(L, auto,                   noad_option_auto);
+    lua_push_key_at_index(L, unrolllist,             noad_option_unroll_list);
+    lua_push_key_at_index(L, followedbyspace,        noad_option_followed_by_space);
+    lua_push_key_at_index(L, proportional,           noad_option_proportional);
+    lua_push_key_at_index(L, sourceonnucleus,        noad_option_source_on_nucleus);
+    lua_push_key_at_index(L, fixedsuperorsubscript,  noad_option_fixed_super_or_sub_script);
+    lua_push_key_at_index(L, fixedsuperandsubscript, noad_option_fixed_super_and_sub_script);
     return 1;
 }
 
diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h
index d9b4e5cdd..c8f373ea4 100644
--- a/source/luametatex/source/tex/texdumpdata.h
+++ b/source/luametatex/source/tex/texdumpdata.h
@@ -55,7 +55,7 @@
 
 */
 
-# define luametatex_format_fingerprint 676
+# define luametatex_format_fingerprint 677
 
 /* These end up in the string pool. */
 
diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c
index 1424e5e03..327e8e6a3 100644
--- a/source/luametatex/source/tex/texmath.c
+++ b/source/luametatex/source/tex/texmath.c
@@ -164,6 +164,14 @@ void tex_math_copy_char_data(halfword target, halfword source, int wipelist)
     }
 }
 
+static inline void tex_math_set_scripts_options(halfword n)
+{
+    switch (math_scripts_mode_par) { 
+        case 1: noad_options(n) |= noad_option_fixed_super_or_sub_script; break;
+        case 2: noad_options(n) |= noad_option_fixed_super_and_sub_script; break;
+    }
+}
+
 // static const math_styles map_cramped_style[] = { /*tex cramp the style */
 //     cramped_display_style,
 //     cramped_display_style,
@@ -2004,6 +2012,7 @@ static void tex_aux_append_math_char(mathcodeval mval, mathdictval dval, int aut
                 math_kernel_node_set_option(q, math_kernel_no_italic_correction);
             }
             node_subtype(p) = tex_aux_set_math_char(q, &mval, &dval);
+            tex_math_set_scripts_options(p);
             tex_tail_append(p);
         }
     }
@@ -2420,6 +2429,7 @@ static void tex_aux_math_math_component(halfword target, int append)
 void tex_run_math_math_component(void)
 {
     halfword n = tex_new_node(simple_noad, ordinary_noad_subtype);
+    tex_math_set_scripts_options(n);
     tex_aux_math_math_component(n, 1);
 }
 
@@ -2472,6 +2482,9 @@ void tex_run_math_modifier(void)
                 noad_options(tail) |= noad_option_void;
                 break;
             case source_modifier_code:
+                if (tex_scan_keyword("nucleus")) {
+                    noad_options(tail) |= noad_option_source_on_nucleus;    
+                }
                 noad_source(tail) = tex_scan_int(0, NULL);
                 break;
             case openup_height_modifier_code:
@@ -2606,7 +2619,7 @@ static void tex_aux_scan_delimiter(halfword target, int code, int class)
 void tex_run_math_radical(void)
 {
     halfword code = cur_chr;
-    halfword options = 0;
+    fullword options = 0;
     halfword radical = tex_new_node(radical_noad, (quarterword) code);
     halfword style = yet_unset_math_style;
     halfword variant = 0; /* quad, harmless */
@@ -3437,7 +3450,7 @@ void tex_run_math_fraction(void)
         halfword autostyle = tex_math_style_variant(cur_list.math_style, math_parameter_fraction_variant);
         halfword userstyle = -1;
         halfword attrlist = null;
-        halfword options = 0;
+        fullword options = 0;
         halfword class = fraction_noad_subtype;
         halfword rulethickness = preset_rule_thickness;
         int ruledone = 0;
@@ -3846,7 +3859,7 @@ void tex_run_math_fence(void)
     scaled dp = 0;
     scaled top = 0;
     scaled bottom = 0;
-    halfword options = 0;
+    fullword options = 0;
     halfword mainclass = unset_noad_class;
     halfword leftclass = unset_noad_class;
     halfword rightclass = unset_noad_class;
@@ -4549,7 +4562,7 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor
 }
 
 /*tex
-*
+
     A |math_node|, which occurs only in horizontal lists, appears before and after mathematical
     formulas. The |subtype| field is |before| before the formula and |after| after it. There is a
     |surround| field, which represents the amount of surrounding space inserted by |\mathsurround|.
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c
index b5412872a..83a8a8a96 100644
--- a/source/luametatex/source/tex/texmlist.c
+++ b/source/luametatex/source/tex/texmlist.c
@@ -4289,125 +4289,69 @@ static halfword tex_aux_analyze_script(halfword init, scriptdata *data)
 /*tex
 
     These prescripts are kind of special. For instance, should top and bottom scripts be aligned?
-    When there is are two top or two bottom, should we then just use the maxima?
+    When there is are two top or two bottom, should we then just use the maxima? Watch out, the 
+    implementation changed wrt \LUATEX. 
 
 */
 
-static void tex_aux_get_math_sup_shifts(halfword sup, halfword style, scaled *shift_up)
+static void tex_aux_get_math_sup_shifts(halfword target, halfword sup, halfword style, scaled *shift_up)
 {
-    switch (math_scripts_mode_par) {
-        case 1:
-            *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up);
-            break;
-        case 2:
-            *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up);
-            break;
-        case 3:
-            *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up)
-                      + tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down)
-                      - tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        case 4:
-            *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up)
-                      + tex_half_scaled(tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down)
-                      - tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down));
-            break;
-        case 5:
-            *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up)
-                      + tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down)
-                      - tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        default:
-            {
-                scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up);
-                scaled bot = tex_get_math_y_parameter_checked(style, math_parameter_superscript_bottom_min);
-                if (*shift_up < clr) {
-                    *shift_up = clr;
-                }
-                clr = box_depth(sup) + bot;
-                if (*shift_up < clr) {
-                    *shift_up = clr;
-                }
-                break;
-            }
+    if (has_noad_option_fixed_super_or_sub_script(target) || has_noad_option_fixed_super_and_sub_script(target)) { 
+        *shift_up = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up);
+    } else { 
+        scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_superscript_shift_up);
+        scaled bot = tex_get_math_y_parameter_checked(style, math_parameter_superscript_bottom_min);
+        if (*shift_up < clr) {
+            *shift_up = clr;
+        }
+        clr = box_depth(sup) + bot;
+        if (*shift_up < clr) {
+            *shift_up = clr;
+        }
     }
 }
 
-static void tex_aux_get_math_sub_shifts(halfword sub, halfword style, scaled *shift_down)
+static void tex_aux_get_math_sub_shifts(halfword target, halfword sub, halfword style, scaled *shift_down)
 {
-    switch (math_scripts_mode_par) {
-        case 1:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        case 2:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
-            break;
-        case 3:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
-            break;
-        case 4:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down)
-                        + tex_half_scaled(tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down)
-                        - tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down)) ;
-            break;
-        case 5:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        default:
-            {
-                scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-                scaled top = tex_get_math_y_parameter_checked(style, math_parameter_subscript_top_max);
-                if (*shift_down < clr) {
-                    *shift_down = clr;
-                }
-                clr = box_height(sub) - top;
-                if (*shift_down < clr) {
-                    *shift_down = clr;
-                }
-                break;
-            }
+    if (has_noad_option_fixed_super_or_sub_script(target)) { 
+        *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
+    } else if (has_noad_option_fixed_super_and_sub_script(target)) { 
+        *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
+    } else { 
+        scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
+        scaled top = tex_get_math_y_parameter_checked(style, math_parameter_subscript_top_max);
+        if (*shift_down < clr) {
+            *shift_down = clr;
+        }
+        clr = box_height(sub) - top;
+        if (*shift_down < clr) {
+            *shift_down = clr;
+        }
     }
 }
 
-static void tex_aux_get_math_sup_sub_shifts(halfword sup, halfword sub, halfword style, scaled *shift_up, scaled *shift_down)
+static void tex_aux_get_math_sup_sub_shifts(halfword target, halfword sup, halfword sub, halfword style, scaled *shift_up, scaled *shift_down)
 {
-    switch (math_scripts_mode_par) {
-        case 1:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        case 2:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
-            break;
-        case 3:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
-            break;
-        case 4:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down)
-                        + tex_half_scaled(tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down)
-                        - tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down));
-            break;
-        case 5:
-            *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
-            break;
-        default:
-            {
-                scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
-                scaled gap = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_vgap);
-                scaled bot = tex_get_math_y_parameter_checked(style, math_parameter_superscript_subscript_bottom_max);
-                if (*shift_down < clr) {
-                    *shift_down = clr;
-                }
-                clr = gap - ((*shift_up - box_depth(sup)) - (box_height(sub) - *shift_down));
-                if (clr > 0) {
-                    *shift_down += clr;
-                    clr = bot - (*shift_up - box_depth(sup));
-                    if (clr > 0) {
-                        *shift_up += clr;
-                        *shift_down -= clr;
-                    }
-                }
-                break;
+    if (has_noad_option_fixed_super_or_sub_script(target)) { 
+        *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_shift_down);
+    } else if (has_noad_option_fixed_super_and_sub_script(target)) { 
+        *shift_down = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
+    } else { 
+        scaled clr = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_shift_down);
+        scaled gap = tex_get_math_y_parameter_checked(style, math_parameter_subscript_superscript_vgap);
+        scaled bot = tex_get_math_y_parameter_checked(style, math_parameter_superscript_subscript_bottom_max);
+        if (*shift_down < clr) {
+            *shift_down = clr;
+        }
+        clr = gap - ((*shift_up - box_depth(sup)) - (box_height(sub) - *shift_down));
+        if (clr > 0) {
+            *shift_down += clr;
+            clr = bot - (*shift_up - box_depth(sup));
+            if (clr > 0) {
+                *shift_up += clr;
+                *shift_down -= clr;
             }
+        }
     }
 }
 
@@ -4802,6 +4746,24 @@ inline static int tex_aux_raise_prime_composed(halfword target)
     return mainclass >= 0 ? tex_math_has_class_option(mainclass, raise_prime_option) : 0;                
 }
 
+static halfword tex_aux_shift_to_kern(halfword target, halfword box, scaled shift)
+{
+    halfword result; 
+    if (box_source_anchor(box)) { 
+        halfword kern = tex_new_kern_node(shift, vertical_math_kern_subtype);
+        tex_attach_attribute_list_copy(kern, target);
+        tex_couple_nodes(kern, box);
+        result = tex_vpack(kern, 0, packing_additional, max_dimen, (singleword) math_direction_par, holding_none_option);
+        tex_attach_attribute_list_copy(result, target);
+        node_subtype(result) = math_scripts_list;
+        box_shift_amount(result) = shift;
+    } else { 
+        box_shift_amount(box) = shift;
+        result = box;
+    }
+    return result;
+}
+
 static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic, int style, scaled supshift, scaled subshift, scaled supdrop, kernset *kerns)
 {
     halfword result = null;
@@ -5178,9 +5140,9 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
         /* */
         if (postsupdata.box) {
             /* Do we still want to chain these sups or should we combine it? */
-            tex_aux_get_math_sup_shifts(postsupdata.box, style, &shift_up); /* maybe only in else branch */
+            tex_aux_get_math_sup_shifts(target, postsupdata.box, style, &shift_up); /* maybe only in else branch */
             if (postsubdata.box) {
-                tex_aux_get_math_sup_sub_shifts(postsupdata.box, postsubdata.box, style, &shift_up, &shift_down);
+                tex_aux_get_math_sup_sub_shifts(target, postsupdata.box, postsubdata.box, style, &shift_up, &shift_down);
                 tex_aux_get_sup_kern(kernel, &postsupdata, shift_up, supshift, &supkern, kerns);
                 tex_aux_get_sub_kern(kernel, &postsubdata, shift_down, subshift, &subkern, kerns);
                 if (primestate == prime_at_begin_location) {
@@ -5225,23 +5187,21 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
                 } else if (supkern) {
                     tex_aux_prepend_hkern_to_box_list(postsupdata.box, supkern, math_shape_kern_subtype, "post sup shape");
                 }
-                box_shift_amount(postsupdata.box) = -shift_up;
-                result = postsupdata.box;
+                result = tex_aux_shift_to_kern(target, postsupdata.box, -shift_up);
                 if (presupdata.kern) {
                     kern_amount(presupdata.kern) += -supkern - subkern - italicmultiplier * italic;
                     kern_amount(postsupdata.kern) += supkern + subkern + italicmultiplier * italic;
                 }
             }
         } else {
-            tex_aux_get_math_sub_shifts(postsubdata.box, style, &shift_down);
+            tex_aux_get_math_sub_shifts(target, postsubdata.box, style, &shift_down);
             tex_aux_get_sub_kern(kernel, &postsubdata, shift_down, subshift, &subkern, kerns);
             if (primestate == prime_at_begin_location) {
                 subkern = 0;
             } else if (subkern) {
                 tex_aux_prepend_hkern_to_box_list(postsubdata.box, subkern, math_shape_kern_subtype, "post sub shape");
             }
-            box_shift_amount(postsubdata.box) = shift_down;
-            result = postsubdata.box;
+            result = tex_aux_shift_to_kern(target, postsubdata.box, shift_down);
             if (presubdata.kern) {
                 kern_amount(presubdata.kern) += -subkern;
                 kern_amount(postsubdata.kern) += subkern;
@@ -5275,8 +5235,8 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
     if (presubdata.box) {
         if (presupdata.box) {
             /* Do we still want to chain these sups or should we combine it? */
-            tex_aux_get_math_sup_shifts(presupdata.box, style, &shift_up);
-            tex_aux_get_math_sup_sub_shifts(presupdata.box, presubdata.box, style, &shift_up, &shift_down);
+            tex_aux_get_math_sup_shifts(target, presupdata.box, style, &shift_up);
+            tex_aux_get_math_sup_sub_shifts(target, presupdata.box, presubdata.box, style, &shift_up, &shift_down);
             prekern = box_width(presupdata.box);
             // test: what with negative extra kerns and what with a negative width
             if (! splitscripts) {
@@ -5297,7 +5257,7 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
                 box_shift_amount(preresult) = shift_down;
             }
         } else {
-            tex_aux_get_math_sub_shifts(presubdata.box, style, &shift_down);
+            tex_aux_get_math_sub_shifts(target, presubdata.box, style, &shift_down);
             if (! splitscripts) {
                 prekern = box_width(presubdata.box);
                 presubdata.box = tex_aux_combine_script(target, kernelsize.wd, presubdata.box, null, &presubdata.kern, &postsubdata.kern);
@@ -5306,7 +5266,7 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
             preresult = presubdata.box;
         }
     } else if (presupdata.box) {
-        tex_aux_get_math_sup_shifts(presupdata.box, style, &shift_up);
+        tex_aux_get_math_sup_shifts(target, presupdata.box, style, &shift_up);
         if (! splitscripts) {
             prekern = box_width(presupdata.box);
             presupdata.box = tex_aux_combine_script(target, kernelsize.wd, presupdata.box, null, &presupdata.kern, &postsupdata.kern);
@@ -6231,22 +6191,46 @@ static void tex_aux_show_math_list(const char *fmt, halfword list)
     tex_end_diagnostic();
 }
 
-static void tex_aux_wrapup_nucleus_and_add_scripts(halfword current, halfword nxt, int current_style, halfword *italic, kernset *kerns)
+static halfword tex_aux_check_source(halfword current, halfword list, int repack)
 {
-    halfword p = tex_aux_check_nucleus_complexity(current, italic, current_style, lmt_math_state.size, kerns);
-    if (p && noad_source(current)) {
-        switch (node_type(p)) {
+    if (list && noad_source(current)) {
+        switch (node_type(list)) {
             case hlist_node:
             case vlist_node:
-                if (! box_source_anchor(p)) {
-                    box_source_anchor(p) = noad_source(current);
-                    tex_set_box_geometry(p, anchor_geometry);
-                }
+             // printf("anchoring to list: %i\n", noad_source(current));
+                box_source_anchor(list) = noad_source(current);
+                tex_set_box_geometry(list, anchor_geometry);
+                noad_source(current) = 0; 
                 break;
             default:
-                /*tex Todo: maybe pack and assign! */
+                if (repack) {
+                    if (tracing_math_par >= 2) {
+                        tex_begin_diagnostic();
+                        tex_print_format("[math: packing due to source field %D]", noad_source(current));
+                        tex_end_diagnostic();
+                    }
+                    list = tex_hpack(list, 0, packing_additional, direction_unknown, holding_none_option);
+                 // printf("anchoring to wrapped list: %i\n", noad_source(current));
+                    tex_attach_attribute_list_copy(list, current);
+                    box_source_anchor(list) = noad_source(current);
+                    noad_source(current) = 0; 
+                    tex_set_box_geometry(list, anchor_geometry);
+                    noad_new_hlist(current) = list;
+                    node_subtype(list) = math_pack_list;
+                }
                 break;
         }
+    } else {
+        /* can't happen as we already checked before the call */
+    }
+    return list; 
+}
+
+static void tex_aux_wrapup_nucleus_and_add_scripts(halfword current, halfword nxt, int current_style, halfword *italic, kernset *kerns)
+{
+    halfword p = tex_aux_check_nucleus_complexity(current, italic, current_style, lmt_math_state.size, kerns);
+    if (p && noad_source(current)) {
+        p = tex_aux_check_source(current, p, has_noad_option_source_on_nucleus(current));
     }
     if (noad_has_scripts(current)) {
         scaled drop = 0;
@@ -6730,28 +6714,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
                                     current_subtype = disc_class(box_list(list));
                                 }
                                 if (list && noad_source(current)) {
-                                    if (tracing_math_par >= 2) {
-                                        tex_begin_diagnostic();
-                                        tex_print_format("[math: packing due to source field %D]", noad_source(current));
-                                        tex_end_diagnostic();
-                                    }
-                                    switch (node_type(list)) {
-                                        case hlist_node:
-                                        case vlist_node:
-                                            if (! box_source_anchor(list)) {
-                                                box_source_anchor(list) = noad_source(current);
-                                                tex_set_box_geometry(list, anchor_geometry);
-                                            }
-                                            break;
-                                        default:
-                                            list = tex_hpack(list, 0, packing_additional, direction_unknown, holding_none_option);
-                                            tex_attach_attribute_list_copy(list, current);
-                                            box_source_anchor(list) = noad_source(current);
-                                            tex_set_box_geometry(list, anchor_geometry);
-                                            noad_new_hlist(current) = list;
-                                            node_subtype(list) = math_pack_list;
-                                            break;
-                                    }
+                                    tex_aux_check_source(current, list, 1);
                                 } 
                                 break;
                             }
diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c
index 1c4a6b896..7eba8a787 100644
--- a/source/luametatex/source/tex/texnodes.c
+++ b/source/luametatex/source/tex/texnodes.c
@@ -761,7 +761,7 @@ void lmt_nodelib_initialize(void) {
     lmt_interface.node_data[nesting_node]        = (node_info) { .id = nesting_node,        .size = nesting_node_size,        .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(nestedlist),     .lua = lua_key_index(nestedlist),      .visible = 0 };
     lmt_interface.node_data[span_node]           = (node_info) { .id = span_node,           .size = span_node_size,           .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(span),           .lua = lua_key_index(span),            .visible = 0 };
     lmt_interface.node_data[align_stack_node]    = (node_info) { .id = align_stack_node,    .size = align_stack_node_size,    .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(alignstack),     .lua = lua_key_index(alignstack),      .visible = 0 };
-    lmt_interface.node_data[noad_state_node]     = (node_info) { .id = noad_state_node,     .size = noad_state_node_size,     .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(noadstate),      .lua = lua_key_index(noadstate),       .visible = 0 };
+ // lmt_interface.node_data[noad_state_node]     = (node_info) { .id = noad_state_node,     .size = noad_state_node_size,     .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(noadstate),      .lua = lua_key_index(noadstate),       .visible = 0 };
     lmt_interface.node_data[if_node]             = (node_info) { .id = if_node,             .size = if_node_size,             .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(ifstack),        .lua = lua_key_index(ifstack),         .visible = 0 };
     lmt_interface.node_data[unhyphenated_node]   = (node_info) { .id = unhyphenated_node,   .size = active_node_size,         .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(unhyphenated),   .lua = lua_key_index(unhyphenated),    .visible = 0 };
     lmt_interface.node_data[hyphenated_node]     = (node_info) { .id = hyphenated_node,     .size = active_node_size,         .first = 0, .last = 0,                         .subtypes = NULL,              .fields = NULL,                           .name = lua_key(hyphenated),     .lua = lua_key_index(hyphenated),      .visible = 0 };
@@ -1199,7 +1199,7 @@ halfword tex_copy_node(halfword p)
                     copy_sub_list(noad_subprescr(r), noad_subprescr(p)) ;
                     copy_sub_list(noad_supprescr(r), noad_supprescr(p)) ;
                     copy_sub_list(noad_prime(r), noad_prime(p)) ;
-                    copy_sub_list(noad_state(r), noad_state(p)) ;
+                 // copy_sub_list(noad_state(r), noad_state(p)) ;
                     switch (t) {
                         case radical_noad:
                             copy_sub_node(radical_left_delimiter(r), radical_left_delimiter(p)) ;
@@ -1381,7 +1381,7 @@ void tex_flush_node(halfword p)
                     tex_aux_free_sub_node_list(noad_subprescr(p));
                     tex_aux_free_sub_node_list(noad_supprescr(p));
                     tex_aux_free_sub_node_list(noad_prime(p));
-                    tex_aux_free_sub_node_list(noad_state(p));
+                 // tex_aux_free_sub_node_list(noad_state(p));
                     switch (t) {
                         case fraction_noad:
                          // tex_aux_free_sub_node_list(fraction_numerator(p));
@@ -1503,7 +1503,7 @@ static void tex_aux_check_node(halfword p)
             tex_aux_node_range_test(p, noad_subprescr(p));
             tex_aux_node_range_test(p, noad_supprescr(p));
             tex_aux_node_range_test(p, noad_prime(p));
-            tex_aux_node_range_test(p, noad_state(p));
+         // tex_aux_node_range_test(p, noad_state(p));
             switch (t) {
                 case radical_noad:
                     tex_aux_node_range_test(p, radical_degree(p));
diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h
index 8a462ebac..c6cc61ff2 100644
--- a/source/luametatex/source/tex/texnodes.h
+++ b/source/luametatex/source/tex/texnodes.h
@@ -128,7 +128,7 @@ typedef enum node_types {
     nesting_node,
     span_node,
     align_stack_node,
-    noad_state_node,
+ // noad_state_node,
     if_node,
     /*tex These two are active nodes. */
     unhyphenated_node, 
@@ -1601,15 +1601,15 @@ typedef enum simple_choice_subtypes {
 
 */
 
-# define noad_state_node_size      6
-# define noad_state_topright(a)    vlink(a,2)
-# define noad_state_bottomright(a) vinfo(a,2)
-# define noad_state_topleft(a)     vlink(a,3)
-# define noad_state_bottomleft(a)  vinfo(a,3)
-# define noad_state_height(a)      vlink(a,4)
-# define noad_state_depth(a)       vinfo(a,4)
-# define noad_state_toptotal(a)    vlink(a,5)
-# define noad_state_bottomtotal(a) vinfo(a,5)
+//define noad_state_node_size      6
+//define noad_state_topright(a)    vlink(a,2)
+//define noad_state_bottomright(a) vinfo(a,2)
+//define noad_state_topleft(a)     vlink(a,3)
+//define noad_state_bottomleft(a)  vinfo(a,3)
+//define noad_state_height(a)      vlink(a,4)
+//define noad_state_depth(a)       vinfo(a,4)
+//define noad_state_toptotal(a)    vlink(a,5)
+//define noad_state_bottomtotal(a) vinfo(a,5)
 
 # define noad_size            14
 # define noad_new_hlist(a)    vlink(a,2)    /*tex the translation of an mlist; a bit confusing name */
@@ -1622,12 +1622,17 @@ typedef enum simple_choice_subtypes {
 # define noad_width(a)        vinfo(a,5)
 # define noad_height(a)       vlink(a,6)
 # define noad_depth(a)        vinfo(a,6)
-# define noad_options(a)      vlink(a,7)
-# define noad_style(a)        vinfo00(a,7)
-# define noad_family(a)       vinfo01(a,7)
-# define noad_script_state(a) vinfo02(a,7)
-# define noad_analyzed(a)     vinfo03(a,7)  /*tex used for experiments */
-# define noad_state(a)        vlink(a,8)    /*tex this might replace */
+//define noad_options(a)      vlink(a,7)
+//define noad_style(a)        vinfo00(a,7)
+//define noad_family(a)       vinfo01(a,7)
+//define noad_script_state(a) vinfo02(a,7)
+//define noad_analyzed(a)     vinfo03(a,7)  /*tex used for experiments */
+//define noad_state(a)        vlink(a,8)    /*tex this might replace */
+# define noad_options(a)      lvalue(a,7)   /*tex 64 bit fullword */
+# define noad_style(a)        vlink00(a,8)
+# define noad_family(a)       vlink01(a,8)
+# define noad_script_state(a) vlink02(a,8)
+# define noad_analyzed(a)     vlink03(a,8)  /*tex used for experiments */
 # define noad_class_main(a)   vinfo00(a,8)
 # define noad_class_left(a)   vinfo01(a,8)
 # define noad_class_right(a)  vinfo02(a,8)
@@ -1717,41 +1722,52 @@ typedef struct noad_classes {
     If we run out of options we can combine some, like auto.
 */
 
+// # if (defined(_MSC_VER) && ! defined(__MINGW32__))
+// typedef enum noad_options : unsigned __int64 {
+// # else 
 typedef enum noad_options {
-    noad_option_axis                     = 0x00000001,
-    noad_option_no_axis                  = 0x00000002,
-    noad_option_exact                    = 0x00000004,
-    noad_option_left                     = 0x00000008, /* align option for overflown under/over */ /* used ? */
-    noad_option_middle                   = 0x00000010, /* idem */
-    noad_option_right                    = 0x00000020, /* idem */
-    noad_option_adapt_to_left_size       = 0x00000040, /* old trickery, might go away but kind of fun */
-    noad_option_adapt_to_right_size      = 0x00000080, /* idem */
-    noad_option_no_sub_script            = 0x00000100,
-    noad_option_no_super_script          = 0x00000200,
-    noad_option_no_sub_pre_script        = 0x00000400,
-    noad_option_no_super_pre_script      = 0x00000800,
-    noad_option_no_script                = 0x00001000,
-    noad_option_no_overflow              = 0x00002000, /* keep (middle) extensible widthin target size */
-    noad_option_void                     = 0x00004000, /* wipe and set width to zero */
-    noad_option_phantom                  = 0x00008000, /* wipe */
-    noad_option_openup_height            = 0x00010000,
-    noad_option_openup_depth             = 0x00020000,
-    noad_option_limits                   = 0x00040000, /* traditional modifier */
-    noad_option_no_limits                = 0x00080000, /* idem */
-    noad_option_prefer_font_thickness    = 0x00100000,
-    noad_option_no_ruling                = 0x00200000,
-    noad_option_shifted_sub_script       = 0x00400000,
-    noad_option_shifted_super_script     = 0x00800000,
-    noad_option_shifted_sub_pre_script   = 0x01000000,
-    noad_option_shifted_super_pre_script = 0x02000000,
-    noad_option_unpack_list              = 0x04000000,
-    noad_option_no_check                 = 0x08000000, /* don't check for missing end fence */
-    noad_option_auto                     = 0x10000000,
-    noad_option_unroll_list              = 0x20000000,
-    noad_option_followed_by_space        = 0x40000000,
-    noad_option_proportional             = 0x80000000,
+// # endif 
+    noad_option_axis                       = 0x000000001,
+    noad_option_no_axis                    = 0x000000002,
+    noad_option_exact                      = 0x000000004,
+    noad_option_left                       = 0x000000008, /* align option for overflown under/over */ /* used ? */
+    noad_option_middle                     = 0x000000010, /* idem */
+    noad_option_right                      = 0x000000020, /* idem */
+    noad_option_adapt_to_left_size         = 0x000000040, /* old trickery, might go away but kind of fun */
+    noad_option_adapt_to_right_size        = 0x000000080, /* idem */
+    noad_option_no_sub_script              = 0x000000100,
+    noad_option_no_super_script            = 0x000000200,
+    noad_option_no_sub_pre_script          = 0x000000400,
+    noad_option_no_super_pre_script        = 0x000000800,
+    noad_option_no_script                  = 0x000001000,
+    noad_option_no_overflow                = 0x000002000, /* keep (middle) extensible widthin target size */
+    noad_option_void                       = 0x000004000, /* wipe and set width to zero */
+    noad_option_phantom                    = 0x000008000, /* wipe */
+    noad_option_openup_height              = 0x000010000,
+    noad_option_openup_depth               = 0x000020000,
+    noad_option_limits                     = 0x000040000, /* traditional modifier */
+    noad_option_no_limits                  = 0x000080000, /* idem */
+    noad_option_prefer_font_thickness      = 0x000100000,
+    noad_option_no_ruling                  = 0x000200000,
+    noad_option_shifted_sub_script         = 0x000400000,
+    noad_option_shifted_super_script       = 0x000800000,
+    noad_option_shifted_sub_pre_script     = 0x001000000,
+    noad_option_shifted_super_pre_script   = 0x002000000,
+    noad_option_unpack_list                = 0x004000000,
+    noad_option_no_check                   = 0x008000000, /* don't check for missing end fence */
+    noad_option_auto                       = 0x010000000,
+    noad_option_unroll_list                = 0x020000000,
+    noad_option_followed_by_space          = 0x040000000,
+    noad_option_proportional               = 0x080000000,
+    /*tex Watch out: the following options exceed halfword: |noad_options| are |long long|. */
 } noad_options;
 
+/*tex The Microsoft compiler truncates to int, so: */
+
+# define noad_option_source_on_nucleus          0x100000000
+# define noad_option_fixed_super_or_sub_script  0x200000000
+# define noad_option_fixed_super_and_sub_script 0x400000000
+
 # define has_option(a,b)     (((a) & (b)) == (b))
 # define unset_option(a,b)   ((a) & ~(b))
 
@@ -1777,34 +1793,37 @@ inline static int has_noad_no_script_option(halfword n, halfword option)
 # define has_noad_option_nosubprescript(a) has_noad_no_script_option(a, noad_option_no_sub_pre_script)
 # define has_noad_option_nosupprescript(a) has_noad_no_script_option(a, noad_option_no_super_pre_script)
 
-# define has_noad_option_shiftedsubscript(a)    (has_option(noad_options(a), noad_option_shifted_sub_script))
-# define has_noad_option_shiftedsupscript(a)    (has_option(noad_options(a), noad_option_shifted_super_script))
-# define has_noad_option_shiftedsubprescript(a) (has_option(noad_options(a), noad_option_shifted_sub_pre_script))
-# define has_noad_option_shiftedsupprescript(a) (has_option(noad_options(a), noad_option_shifted_super_pre_script))
-# define has_noad_option_axis(a)                (has_option(noad_options(a), noad_option_axis))
-# define has_noad_option_exact(a)               (has_option(noad_options(a), noad_option_exact))
-# define has_noad_option_noaxis(a)              (has_option(noad_options(a), noad_option_no_axis))
-# define has_noad_option_openupheight(a)        (has_option(noad_options(a), noad_option_openup_height))
-# define has_noad_option_openupdepth(a)         (has_option(noad_options(a), noad_option_openup_depth))
-# define has_noad_option_adapttoleft(a)         (has_option(noad_options(a), noad_option_adapt_to_left_size))
-# define has_noad_option_adapttoright(a)        (has_option(noad_options(a), noad_option_adapt_to_right_size))
-# define has_noad_option_limits(a)              (has_option(noad_options(a), noad_option_limits))
-# define has_noad_option_nolimits(a)            (has_option(noad_options(a), noad_option_no_limits))
-# define has_noad_option_nooverflow(a)          (has_option(noad_options(a), noad_option_no_overflow))
-# define has_noad_option_preferfontthickness(a) (has_option(noad_options(a), noad_option_prefer_font_thickness))
-# define has_noad_option_noruling(a)            (has_option(noad_options(a), noad_option_no_ruling))
-# define has_noad_option_unpacklist(a)          (has_option(noad_options(a), noad_option_unpack_list))
-# define has_noad_option_nocheck(a)             (has_option(noad_options(a), noad_option_no_check))
-# define has_noad_option_exact(a)               (has_option(noad_options(a), noad_option_exact))
-# define has_noad_option_left(a)                (has_option(noad_options(a), noad_option_left))
-# define has_noad_option_middle(a)              (has_option(noad_options(a), noad_option_middle))
-# define has_noad_option_right(a)               (has_option(noad_options(a), noad_option_right))
-# define has_noad_option_auto(a)                (has_option(noad_options(a), noad_option_auto))
-# define has_noad_option_phantom(a)             (has_option(noad_options(a), noad_option_phantom))
-# define has_noad_option_void(a)                (has_option(noad_options(a), noad_option_void))
-# define has_noad_option_unrolllist(a)          (has_option(noad_options(a), noad_option_unroll_list))
-# define has_noad_option_followedbyspace(a)     (has_option(noad_options(a), noad_option_followed_by_space))
-# define has_noad_option_proportional(a)        (has_option(noad_options(a), noad_option_proportional))
+# define has_noad_option_shiftedsubscript(a)           (has_option(noad_options(a), noad_option_shifted_sub_script))
+# define has_noad_option_shiftedsupscript(a)           (has_option(noad_options(a), noad_option_shifted_super_script))
+# define has_noad_option_shiftedsubprescript(a)        (has_option(noad_options(a), noad_option_shifted_sub_pre_script))
+# define has_noad_option_shiftedsupprescript(a)        (has_option(noad_options(a), noad_option_shifted_super_pre_script))
+# define has_noad_option_axis(a)                       (has_option(noad_options(a), noad_option_axis))
+# define has_noad_option_exact(a)                      (has_option(noad_options(a), noad_option_exact))
+# define has_noad_option_noaxis(a)                     (has_option(noad_options(a), noad_option_no_axis))
+# define has_noad_option_openupheight(a)               (has_option(noad_options(a), noad_option_openup_height))
+# define has_noad_option_openupdepth(a)                (has_option(noad_options(a), noad_option_openup_depth))
+# define has_noad_option_adapttoleft(a)                (has_option(noad_options(a), noad_option_adapt_to_left_size))
+# define has_noad_option_adapttoright(a)               (has_option(noad_options(a), noad_option_adapt_to_right_size))
+# define has_noad_option_limits(a)                     (has_option(noad_options(a), noad_option_limits))
+# define has_noad_option_nolimits(a)                   (has_option(noad_options(a), noad_option_no_limits))
+# define has_noad_option_nooverflow(a)                 (has_option(noad_options(a), noad_option_no_overflow))
+# define has_noad_option_preferfontthickness(a)        (has_option(noad_options(a), noad_option_prefer_font_thickness))
+# define has_noad_option_noruling(a)                   (has_option(noad_options(a), noad_option_no_ruling))
+# define has_noad_option_unpacklist(a)                 (has_option(noad_options(a), noad_option_unpack_list))
+# define has_noad_option_nocheck(a)                    (has_option(noad_options(a), noad_option_no_check))
+# define has_noad_option_exact(a)                      (has_option(noad_options(a), noad_option_exact))
+# define has_noad_option_left(a)                       (has_option(noad_options(a), noad_option_left))
+# define has_noad_option_middle(a)                     (has_option(noad_options(a), noad_option_middle))
+# define has_noad_option_right(a)                      (has_option(noad_options(a), noad_option_right))
+# define has_noad_option_auto(a)                       (has_option(noad_options(a), noad_option_auto))
+# define has_noad_option_phantom(a)                    (has_option(noad_options(a), noad_option_phantom))
+# define has_noad_option_void(a)                       (has_option(noad_options(a), noad_option_void))
+# define has_noad_option_unrolllist(a)                 (has_option(noad_options(a), noad_option_unroll_list))
+# define has_noad_option_followedbyspace(a)            (has_option(noad_options(a), noad_option_followed_by_space))
+# define has_noad_option_proportional(a)               (has_option(noad_options(a), noad_option_proportional))
+# define has_noad_option_source_on_nucleus(a)          (has_option(noad_options(a), noad_option_source_on_nucleus))
+# define has_noad_option_fixed_super_or_sub_script(a)   (has_option(noad_options(a), noad_option_fixed_super_or_sub_script))
+# define has_noad_option_fixed_super_and_sub_script(a)  (has_option(noad_options(a), noad_option_fixed_super_and_sub_script))
 
 /*tex
     In the meantime the codes and subtypes are in sync. The variable component does not really
diff --git a/source/luametatex/source/tex/texprinting.c b/source/luametatex/source/tex/texprinting.c
index d18445f36..6d01854b7 100644
--- a/source/luametatex/source/tex/texprinting.c
+++ b/source/luametatex/source/tex/texprinting.c
@@ -592,9 +592,9 @@ void tex_print_sparse_dimension(scaled s, int unit)
     as an unsigned. 
 */
 
-void tex_print_hex(int sn)
+void tex_print_hex(long long sn)
 {
-    unsigned int n = (unsigned int) sn;
+    unsigned long long n = (unsigned long long) sn;
     int k = 0;
     unsigned char digits[24];
     do {
@@ -612,13 +612,13 @@ void tex_print_hex(int sn)
     }
 }
 
-void tex_print_qhex(int n)
+void tex_print_qhex(long long n)
 {
     tex_print_char('"');
     tex_print_hex(n);
 }
 
-void tex_print_uhex(int n)
+void tex_print_uhex(long long n)
 {
     tex_print_str("U+");
     if (n < 16) {
diff --git a/source/luametatex/source/tex/texprinting.h b/source/luametatex/source/tex/texprinting.h
index 5e311a0bb..745b8eeb0 100644
--- a/source/luametatex/source/tex/texprinting.h
+++ b/source/luametatex/source/tex/texprinting.h
@@ -59,9 +59,9 @@ extern void        tex_print_banner           (void);
 extern void        tex_print_log_banner       (void);
 extern void        tex_print_version_banner   (void);
 extern void        tex_print_int              (int n);
-extern void        tex_print_hex              (int n);
-extern void        tex_print_uhex             (int n);
-extern void        tex_print_qhex             (int n);
+extern void        tex_print_hex              (long long n);
+extern void        tex_print_uhex             (long long n);
+extern void        tex_print_qhex             (long long n);
 extern void        tex_print_roman_int        (int n);
 extern void        tex_print_current_string   (void);
 extern void        tex_print_cs_checked       (halfword p);                    /*tex Also does the |IMPOSSIBLE| etc. */
diff --git a/source/luametatex/source/tex/textypes.h b/source/luametatex/source/tex/textypes.h
index 3eebccbf1..a09409522 100644
--- a/source/luametatex/source/tex/textypes.h
+++ b/source/luametatex/source/tex/textypes.h
@@ -81,6 +81,7 @@
 
 typedef int             strnumber;
 typedef int             halfword;
+typedef long long       fullword;
 typedef unsigned short  quarterword;   /*tex It really is an unsigned one! But \MPLIB| had it signed. */
 typedef unsigned char   singleword;
 typedef int             scaled;
diff --git a/source/luametatex/source/utilities/auxunistring.c b/source/luametatex/source/utilities/auxunistring.c
index 10ae6393d..9fe5531d6 100644
--- a/source/luametatex/source/utilities/auxunistring.c
+++ b/source/luametatex/source/utilities/auxunistring.c
@@ -135,10 +135,9 @@ unsigned aux_splitutf2uni(unsigned int *ubuf, const char *utf8buf)
 
 size_t aux_utf8len(const char *text, size_t size)
 {
-    size_t ls = size;
     size_t ind = 0;
     size_t num = 0;
-    while (ind < ls) {
+    while (ind < size) {
         unsigned char i = (unsigned char) *(text + ind);
         if (i < 0x80) {
             ind += 1;
-- 
cgit v1.2.3