From 24c28ec82196d528b8b5ca57001b4b762fc1657e Mon Sep 17 00:00:00 2001
From: Luigi Scarso <luigi.scarso@gmail.com>
Date: Tue, 20 Sep 2016 10:53:49 +0000
Subject: [PATCH] experimental rule interceptor math (HH)

---
 source/texk/web2c/luatexdir/pdf/pdfrule.w     | 16 ++++++---
 source/texk/web2c/luatexdir/tex/commands.w    |  2 ++
 source/texk/web2c/luatexdir/tex/dumpdata.w    |  2 +-
 source/texk/web2c/luatexdir/tex/equivalents.h | 24 +++++++------
 source/texk/web2c/luatexdir/tex/mlist.w       | 34 +++++++++++--------
 source/texk/web2c/luatexdir/tex/texnodes.h    |  4 +++
 6 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/source/texk/web2c/luatexdir/pdf/pdfrule.w b/source/texk/web2c/luatexdir/pdf/pdfrule.w
index 2f75b4c76..df4979088 100644
--- a/source/texk/web2c/luatexdir/pdf/pdfrule.w
+++ b/source/texk/web2c/luatexdir/pdf/pdfrule.w
@@ -30,14 +30,22 @@ void pdf_place_rule(PDF pdf, halfword q, scaledpos size, int callback_id)
     pdfpos dim;
     pdfstructure *p = pdf->pstruct;
     scaledpos pos = pdf->posstruct->pos;
+    halfword s = subtype(q);
     /*  (void) q; */
-    if (subtype(q) == box_rule) {
+    if (s >= math_over_rule && s <= math_radical_rule) {
+        if (callback_id == 0) {
+            s = normal_rule;
+        } else {
+            s = user_rule;
+        }
+    }
+    if (s == box_rule) {
         pdf_place_form(pdf,q);
-    } else if (subtype(q) == image_rule) {
+    } else if (s == image_rule) {
         pdf_place_image(pdf,q);
-    } else if (subtype(q) == empty_rule) {
+    } else if (s == empty_rule) {
         /* place nothing, only take space */
-    } else if (subtype(q) == user_rule) {
+    } else if (s == user_rule) {
         if (callback_id != 0) {
             pdf_goto_pagemode(pdf);
             pdf_puts(pdf, "q\n");
diff --git a/source/texk/web2c/luatexdir/tex/commands.w b/source/texk/web2c/luatexdir/tex/commands.w
index e4a269d93..b89dadffd 100644
--- a/source/texk/web2c/luatexdir/tex/commands.w
+++ b/source/texk/web2c/luatexdir/tex/commands.w
@@ -754,6 +754,8 @@ void initialize_etex_commands(void)
     primitive_luatex("mathdisplayskipmode", assign_int_cmd, int_base + math_display_skip_mode_code, int_base);
     primitive_luatex("mathscriptsmode", assign_int_cmd, int_base + math_scripts_mode_code, int_base);
     primitive_luatex("mathnolimitsmode", assign_int_cmd, int_base + math_nolimits_mode_code, int_base);
+    primitive_luatex("mathrulesmode", assign_int_cmd, int_base + math_rules_mode_code, int_base);
+    primitive_luatex("mathrulesfam", assign_int_cmd, int_base + math_rules_fam_code, int_base);
     primitive_luatex("synctex", assign_int_cmd, int_base + synctex_code, int_base);
 
     primitive_etex("currentgrouplevel", last_item_cmd, current_group_level_code, 0);
diff --git a/source/texk/web2c/luatexdir/tex/dumpdata.w b/source/texk/web2c/luatexdir/tex/dumpdata.w
index 85ff55f4e..526113b70 100644
--- a/source/texk/web2c/luatexdir/tex/dumpdata.w
+++ b/source/texk/web2c/luatexdir/tex/dumpdata.w
@@ -23,7 +23,7 @@
 
 /* we start with 907: the sum of the values of the bytes of "don knuth" */
 
-#define FORMAT_ID (907+18)
+#define FORMAT_ID (907+19)
 #if ((FORMAT_ID>=0) && (FORMAT_ID<=256))
 #error Wrong value for FORMAT_ID.
 #endif
diff --git a/source/texk/web2c/luatexdir/tex/equivalents.h b/source/texk/web2c/luatexdir/tex/equivalents.h
index b2bda5f60..27a4f9640 100644
--- a/source/texk/web2c/luatexdir/tex/equivalents.h
+++ b/source/texk/web2c/luatexdir/tex/equivalents.h
@@ -279,20 +279,22 @@ the |number_regs| \.{\\dimen} registers.
 #  define math_display_skip_mode_code 88
 #  define math_scripts_mode_code 89
 #  define math_nolimits_mode_code 90
-#  define synctex_code 91                                               /* is synctex file generation enabled ?  */
-#  define shape_mode_code 92
-#  define first_valid_language_code 93
-#  define hyphenation_bounds_code 94
+#  define math_rules_mode_code 91
+#  define math_rules_fam_code 92
+#  define synctex_code 93                                               /* is synctex file generation enabled ?  */
+#  define shape_mode_code 94
+#  define first_valid_language_code 95
+#  define hyphenation_bounds_code 96
 
-#  define math_option_code 95
+#  define math_option_code 97
 
-#  define mathoption_int_base (int_base+96)                             /* one reserve */
-#  define mathoption_int_last (int_base+104)
+#  define mathoption_int_base (int_base+98)                             /* one reserve */
+#  define mathoption_int_last (int_base+106)
 
-#  define backend_int_base (int_base+105)
-#  define backend_int_last (int_base+129)
+#  define backend_int_base (int_base+107)
+#  define backend_int_last (int_base+131)
 
-#  define tex_int_pars (130)                                            /* total number of integer parameters */
+#  define tex_int_pars (132)                                            /* total number of integer parameters */
 
 #  define page_direction_code (tex_int_pars)
 #  define body_direction_code (tex_int_pars+1)
@@ -639,6 +641,8 @@ extern halfword last_cs_name;
 #define disable_space_par                  int_par(disable_space_code)
 #define scripts_mode_par                   int_par(math_scripts_mode_code)
 #define nolimits_mode_par                  int_par(math_nolimits_mode_code)
+#define math_rules_mode_par                int_par(math_rules_mode_code)
+#define math_rules_fam_par                 int_par(math_rules_fam_code)
 
 #define thin_mu_skip_par                   glue_par(thin_mu_skip_code)
 #define med_mu_skip_par                    glue_par(med_mu_skip_code)
diff --git a/source/texk/web2c/luatexdir/tex/mlist.w b/source/texk/web2c/luatexdir/tex/mlist.w
index 51ce16652..295e78eeb 100644
--- a/source/texk/web2c/luatexdir/tex/mlist.w
+++ b/source/texk/web2c/luatexdir/tex/mlist.w
@@ -271,7 +271,7 @@ static scaled minimum_operator_size(int var)
 the backward compatibility code, and it means that we can't raise an error here.
 
 @c
-static scaled radical_rule(int var)
+static scaled radical_rule_par(int var)
 {
     scaled a = get_math_param(math_param_radical_rule, var);
     return a;
@@ -978,10 +978,16 @@ static pointer math_clone(pointer q)
   that eventually contains it.
 
 @c
-static pointer do_fraction_rule(scaled t, pointer att)
+static pointer do_fraction_rule(scaled t, pointer att, halfword some_rule, halfword cur_size, halfword cur_fam)
 {
     pointer p;                  /* the new node */
-    p = new_rule(normal_rule);
+    if (math_rules_mode_par) {
+        p = new_rule(some_rule);
+        rule_index(p) = cur_size;
+        rule_transform(p) = cur_fam;
+    } else {
+        p = new_rule(normal_rule);
+    }
     rule_dir(p) = math_direction_par;
     height(p) = t;
     depth(p) = 0;
@@ -994,13 +1000,13 @@ static pointer do_fraction_rule(scaled t, pointer att)
   fraction rule of thickness |t| under additional space of height |ht|.
 
 @c
-static pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att)
+static pointer overbar(pointer b, scaled k, scaled t, scaled ht, pointer att, halfword index, halfword cur_size, halfword cur_fam)
 {
     pointer p, q;               /* nodes being constructed */
     p = new_kern(k);
     reset_attributes(p, att);
     couple_nodes(p,b);
-    q = do_fraction_rule(t, att);
+    q = do_fraction_rule(t, att, index, cur_size, cur_fam);
     couple_nodes(q,p);
     p = new_kern(ht);
     reset_attributes(p, att);
@@ -1796,17 +1802,17 @@ illustrate the general setup of such procedures, let's begin with a
 couple of simple ones.
 
 @c
-static void make_over(pointer q, int cur_style)
+static void make_over(pointer q, int cur_style, int cur_size, int cur_fam)
 {
     pointer p;
     p = overbar(clean_box(nucleus(q), cramped_style(cur_style), cur_style),
                 overbar_vgap(cur_style), overbar_rule(cur_style),
-                overbar_kern(cur_style), node_attr(nucleus(q)));
+                overbar_kern(cur_style), node_attr(nucleus(q)), math_over_rule, cur_size, cur_fam);
     math_list(nucleus(q)) = p;
     type(nucleus(q)) = sub_box_node;
 }
 
-static void make_under(pointer q, int cur_style)
+static void make_under(pointer q, int cur_style, int cur_size, int cur_fam)
 {
     pointer p, x, y, r;         /* temporary registers for box construction */
     scaled delta;               /* overall height plus depth */
@@ -1814,7 +1820,7 @@ static void make_under(pointer q, int cur_style)
     p = new_kern(underbar_vgap(cur_style));
     reset_attributes(p, node_attr(q));
     couple_nodes(x,p);
-    r = do_fraction_rule(underbar_rule(cur_style), node_attr(q));
+    r = do_fraction_rule(underbar_rule(cur_style), node_attr(q), math_under_rule, cur_size, cur_fam);
     couple_nodes(p,r);
     y = vpackage(x, 0, additional, max_dimen, math_direction_par);
     reset_attributes(y, node_attr(q));
@@ -1878,7 +1884,7 @@ static void make_radical(pointer q, int cur_style)
     scaled delta, clr, theta, h; /* dimensions involved in the calculation */
     x = clean_box(nucleus(q), cramped_style(cur_style), cur_style);
     clr = radical_vgap(cur_style);
-    theta = radical_rule(cur_style);
+    theta = radical_rule_par(cur_style);
     if (theta == undefined_math_parameter) {
         /* a real radical */
         theta = fraction_rule(cur_style);
@@ -1912,7 +1918,7 @@ static void make_radical(pointer q, int cur_style)
     }
     shift_amount(y) = (height(y) - theta) - (height(x) + clr);
     h = depth(y) + height(y);
-    p = overbar(x, clr, theta, radical_kern(cur_style), node_attr(y));
+    p = overbar(x, clr, theta, radical_kern(cur_style), node_attr(y), math_radical_rule, cur_size, small_fam(left_delimiter(q)));
     couple_nodes(y,p);
     if (degree(q) != null) {
         scaled wr, br, ar;
@@ -2559,7 +2565,7 @@ static void make_fraction(pointer q, int cur_style)
             p = new_kern((shift_up - depth(x)) - (height(z) - shift_down));
             couple_nodes(p,z);
         } else {
-            y = do_fraction_rule(thickness(q), node_attr(q));
+            y = do_fraction_rule(thickness(q), node_attr(q), math_fraction_rule, cur_size, math_rules_fam_par);
             p = new_kern((math_axis_size(cur_size) - delta) - (height(z) - shift_down));
             reset_attributes(p, node_attr(q));
             couple_nodes(y,p);
@@ -3913,10 +3919,10 @@ void mlist_to_hlist(pointer mlist, boolean penalties, int cur_style)
                 }
                 break;
             case over_noad_type:
-                make_over(q, cur_style);
+                make_over(q, cur_style, cur_size, math_rules_fam_par);
                 break;
             case under_noad_type:
-                make_under(q, cur_style);
+                make_under(q, cur_style, cur_size, math_rules_fam_par);
                 break;
             case vcenter_noad_type:
                 make_vcenter(q);
diff --git a/source/texk/web2c/luatexdir/tex/texnodes.h b/source/texk/web2c/luatexdir/tex/texnodes.h
index 6650d17f4..7205aa98d 100644
--- a/source/texk/web2c/luatexdir/tex/texnodes.h
+++ b/source/texk/web2c/luatexdir/tex/texnodes.h
@@ -261,6 +261,10 @@ typedef enum {
     image_rule,
     empty_rule,
     user_rule,
+    math_over_rule,
+    math_under_rule,
+    math_fraction_rule,
+    math_radical_rule,
 } rule_subtypes;
 
 #  define rule_node_size       8
-- 
GitLab