groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 03/27: [eqn]: Implement "reset" primitive/command (1/3).


From: G. Branden Robinson
Subject: [groff] 03/27: [eqn]: Implement "reset" primitive/command (1/3).
Date: Mon, 28 Aug 2023 15:54:41 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 661dafc33b393b5191abade8fa5c25873d1f56e8
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Sat Aug 26 07:14:53 2023 -0500

    [eqn]: Implement "reset" primitive/command (1/3).
    
    * src/preproc/eqn/box.cpp: Use `static` storage class for parametric
      defaults, moving them to file scope from global.  Rename `param_table`
      array of structs to `default_param_table`.  Use the length of this
      array for iteration since it is known at compile time.  Convert
      `param_table` to a null pointer.
    
      (set_param): Update diagnostic message text.
    
      (reset_param): New function restores a rendering parameter in
      `param_table` to its corresponding value in `default_param_table`.
    
      (get_param): New function accesses `param_table` entries via a C
      string rather than integer lvalues.  Use `assert()` to dump core; this
      function is never called by the parser, but only by static logic.  Add
      `fatal()` under this same circumstance, in case anyone `#define`s
      `NDEBUG`.
    
      (init_param_table): New function populates the (mutable) `param_table`
      from the (immutable) `default_param_table` using heap storage.
    
      (free_param_table): New function avoids memory leak by freeing the
      heap storage allocated for `param_table`.
    
    * src/preproc/eqn/eqn.h: Drop external declaration of `nroff`.
    
    * src/preproc/eqn/eqn.ypp: Add new token `RESET`.
    
    * src/preproc/eqn/lex.cpp: Map C string "reset" to token `RESET` in
      untagged struct `token_table`.
    
      (do_reset): Handle new keyword; if argument valid, call
      `reset_param()` with it.
    
      (yylex): Hook up token `RESET` to `do_reset()`.
    
    * src/preproc/eqn/box.h: Declare `reset_param()`, `get_param()`,
      `init_param_table()`, and `free_param_table()`.
    
    * src/preproc/eqn/main.cpp (main): Call `init_param_table()` when
      starting up.  Register `free_param_table()` with `std::atexit()`.
    
    * src/preproc/eqn/pbox.h: Drop external declarations of rendering
      parameters.
    
    * src/preproc/eqn/delim.cpp (build_extensible)
      (define_extensible_string, delim_box::compute_metrics):
    * src/preproc/eqn/lex.cpp (yylex):
    * src/preproc/eqn/limit.cpp (limit_box::compute_metrics):
    * src/preproc/eqn/list.cpp (compute_spacing):
    * src/preproc/eqn/other.cpp (accent_box::compute_metrics)
      (overline_char_box::overline_char_box):
      (overline_box::compute_metrics, overline_box::output):
      (underline_char_box::underline_char_box):
      (underline_box::compute_metrics, underline_box::output):
      (fat_box::compute_metrics, fat_box::output):
      (vcenter_box::compute_metrics):
    * src/preproc/eqn/over.cpp (over_box::compute_metrics):
      (over_box::output):
    * src/preproc/eqn/pile.cpp (pile_box::compute_metrics):
      (matrix_box::compute_metrics, matrix_box::output):
    * src/preproc/eqn/script.cpp (script_box::compute_metrics):
    * src/preproc/eqn/sqrt.cpp (sqrt_box::compute_metrics): Migrate from
      lvalue access to `get_param()` for parameter retrieval.
    
    Fixes <https://savannah.gnu.org/bugs/?62692>.
---
 ChangeLog                  |  59 ++++++++++++++++++++
 src/preproc/eqn/box.cpp    | 136 ++++++++++++++++++++++++++++++---------------
 src/preproc/eqn/box.h      |   6 +-
 src/preproc/eqn/delim.cpp  |  20 ++++---
 src/preproc/eqn/eqn.h      |   3 +-
 src/preproc/eqn/eqn.ypp    |   3 +-
 src/preproc/eqn/lex.cpp    |  22 +++++++-
 src/preproc/eqn/limit.cpp  |  12 ++--
 src/preproc/eqn/list.cpp   |  16 +++---
 src/preproc/eqn/main.cpp   |   4 +-
 src/preproc/eqn/other.cpp  |  34 ++++++------
 src/preproc/eqn/over.cpp   |  32 ++++++-----
 src/preproc/eqn/pbox.h     |  44 +--------------
 src/preproc/eqn/pile.cpp   |  27 +++++----
 src/preproc/eqn/script.cpp |  31 ++++++-----
 src/preproc/eqn/sqrt.cpp   |  20 ++++---
 16 files changed, 286 insertions(+), 183 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ea412c70d..d3e347d0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,62 @@
+2023-08-25  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       [eqn]: Implement "reset" keyword.
+
+       * src/preproc/eqn/box.cpp: Use `static` storage class for
+       parametric defaults, moving them to file scope from global.
+       Rename `param_table` array of structs to `default_param_table`.
+       Use the length of this array for iteration since it is known at
+       compile time.  Convert `param_table` to a null pointer.
+       (set_param): Update diagnostic message text.
+       (reset_param): New function restores a rendering parameter in
+       `param_table` to its corresponding value in
+       `default_param_table`.
+       (get_param): New function accesses `param_table` entries via a C
+       string rather than integer lvalues.  Use `assert()` to dump
+       core; this function is never called by the parser, but only by
+       static logic.  Add `fatal()` under this same circumstance, in
+       case anyone `#define`s `NDEBUG`.
+       (init_param_table): New function populates the (mutable)
+       `param_table` from the (immutable) `default_param_table` using
+       heap storage.
+       (free_param_table): New function avoids memory leak by freeing
+       the heap storage allocated for `param_table`.
+       * src/preproc/eqn/eqn.h: Drop external declaration of `nroff`.
+       * src/preproc/eqn/eqn.ypp: Add new token `RESET`.
+       * src/preproc/eqn/lex.cpp: Map C string "reset" to token `RESET`
+       in untagged struct `token_table`.
+       (do_reset): Handle new keyword; if argument valid, call
+       `reset_param()` with it.
+       (yylex): Hook up token `RESET` to `do_reset()`.
+       * src/preproc/eqn/box.h: Declare `reset_param()`, `get_param()`,
+       `init_param_table()`, and `free_param_table()`.
+       * src/preproc/eqn/main.cpp (main): Call `init_param_table()`
+       when starting up.  Register `free_param_table()` with
+       `std::atexit()`.
+       * src/preproc/eqn/pbox.h: Drop external declarations of
+       rendering parameters.
+       * src/preproc/eqn/delim.cpp (build_extensible)
+       (define_extensible_string, delim_box::compute_metrics):
+       * src/preproc/eqn/lex.cpp (yylex):
+       * src/preproc/eqn/limit.cpp (limit_box::compute_metrics):
+       * src/preproc/eqn/list.cpp (compute_spacing):
+       * src/preproc/eqn/other.cpp (accent_box::compute_metrics)
+       (overline_char_box::overline_char_box):
+       (overline_box::compute_metrics, overline_box::output):
+       (underline_char_box::underline_char_box):
+       (underline_box::compute_metrics, underline_box::output):
+       (fat_box::compute_metrics, fat_box::output):
+       (vcenter_box::compute_metrics):
+       * src/preproc/eqn/over.cpp (over_box::compute_metrics):
+       (over_box::output):
+       * src/preproc/eqn/pile.cpp (pile_box::compute_metrics):
+       (matrix_box::compute_metrics, matrix_box::output):
+       * src/preproc/eqn/script.cpp (script_box::compute_metrics):
+       * src/preproc/eqn/sqrt.cpp (sqrt_box::compute_metrics): Migrate
+       from lvalue access to `get_param()` for parameter retrieval.
+
+       Fixes <https://savannah.gnu.org/bugs/?62692>.
+
 2023-08-24  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        * src/preproc/eqn/box.cpp (set_param): Migrate iteration style
diff --git a/src/preproc/eqn/box.cpp b/src/preproc/eqn/box.cpp
index a9dc0e01d..6a1313a9c 100644
--- a/src/preproc/eqn/box.cpp
+++ b/src/preproc/eqn/box.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -35,57 +35,57 @@ int negative_space = -1;
 
 int minimum_size = 5;
 
-int fat_offset = 4;
-int body_height = 85;
-int body_depth = 35;
-
-int over_hang = 0;
-int accent_width = 31;
-int delimiter_factor = 900;
-int delimiter_shortfall = 50;
-
-int null_delimiter_space = 12;
-int script_space = 5;
-int thin_space = 17;
-int half_space = 17;
-int medium_space = 22;
-int thick_space = 28;
-int full_space = 28;
-
-int num1 = 70;
-int num2 = 40;
+static int fat_offset = 4;
+static int over_hang = 0;
+static int accent_width = 31;
+static int delimiter_factor = 900;
+static int delimiter_shortfall = 50;
+
+static int null_delimiter_space = 12;
+static int script_space = 5;
+static int thin_space = 17;
+static int half_space = 17;
+static int medium_space = 22;
+static int thick_space = 28;
+static int full_space = 28;
+
+static int num1 = 70;
+static int num2 = 40;
 // we don't use num3, because we don't have \atop
-int denom1 = 70;
-int denom2 = 36;
-int axis_height = 26;          // in 100ths of an em
-int sup1 = 42;
-int sup2 = 37;
-int sup3 = 28;
-int default_rule_thickness = 4;
-int sub1 = 20;
-int sub2 = 23;
-int sup_drop = 38;
-int sub_drop = 5;
-int x_height = 45;
-int big_op_spacing1 = 11;
-int big_op_spacing2 = 17;
-int big_op_spacing3 = 20;
-int big_op_spacing4 = 60;
-int big_op_spacing5 = 10;
+static int denom1 = 70;
+static int denom2 = 36;
+static int axis_height = 26;   // in 100ths of an em
+static int sup1 = 42;
+static int sup2 = 37;
+static int sup3 = 28;
+static int default_rule_thickness = 4;
+static int sub1 = 20;
+static int sub2 = 23;
+static int sup_drop = 38;
+static int sub_drop = 5;
+static int x_height = 45;
+static int big_op_spacing1 = 11;
+static int big_op_spacing2 = 17;
+static int big_op_spacing3 = 20;
+static int big_op_spacing4 = 60;
+static int big_op_spacing5 = 10;
 
 // These are for piles and matrices.
 
-int baseline_sep = 140;                // = num1 + denom1
-int shift_down = 26;           // = axis_height
-int column_sep = 100;          // = em space
-int matrix_side_sep = 17;      // = thin space
+static int baseline_sep = 140;         // = num1 + denom1
+static int shift_down = 26;            // = axis_height
+static int column_sep = 100;           // = em space
+static int matrix_side_sep = 17;       // = thin space
 
-int nroff = 0;                 // should we grok ndefine or tdefine?
+static int body_height = 85;
+static int body_depth = 35;
+
+static int nroff = 0;          // should we grok ndefine or tdefine?
 
 struct param {
   const char *name;
   int *ptr;
-} param_table[] = {
+} default_param_table[] = {
   { "fat_offset", &fat_offset },
   { "over_hang", &over_hang },
   { "accent_width", &accent_width },
@@ -128,14 +128,58 @@ struct param {
   { "nroff", &nroff },
 };
 
+struct param *param_table = 0 /* nullptr */;
+
+// Use the size of default_param_table to iterate through both it and
+// param_table, because the former is known constant to the compiler.
+
 void set_param(const char *name, int value)
 {
-  for (size_t i = 0; i < array_size(param_table); i++)
+  for (size_t i = 0; i <= array_size(default_param_table); i++)
+    if (strcmp(param_table[i].name, name) == 0) {
+      *(param_table[i].ptr) = value;
+      return;
+    }
+  error("'set' primitive does not recognize parameter name '%1'", name);
+}
+
+void reset_param(const char *name)
+{
+  for (size_t i = 0; i < array_size(default_param_table); i++)
     if (strcmp(param_table[i].name, name) == 0) {
-      *param_table[i].ptr = value;
+      *param_table[i].ptr = *(default_param_table[i].ptr);
       return;
     }
-  error("unrecognised parameter '%1'", name);
+  error("'reset' primitive does not recognize parameter name '%1'",
+       name);
+}
+
+int get_param(const char *name)
+{
+  for (size_t i = 0; i < array_size(default_param_table); i++)
+    if (strcmp(param_table[i].name, name) == 0)
+      return *(param_table[i].ptr);
+  assert(0 == "attempted to access parameter not in table");
+  fatal("internal error: unrecognized parameter name '%1'", name);
+}
+
+void init_param_table()
+{
+  param_table = new param[array_size(default_param_table)];
+  for (size_t i = 0; i < array_size(default_param_table); i++) {
+    param_table[i].name = default_param_table[i].name;
+    param_table[i].ptr = new int(*(default_param_table[i].ptr));
+  }
+}
+
+void free_param_table()
+{
+  if (param_table != 0 /* nullptr */) {
+    for (size_t i = 0; i < array_size(default_param_table); i++)
+      delete param_table[i].ptr;
+    delete[] param_table;
+    param_table = 0 /* nullptr */;
+  }
 }
 
 int script_style(int style)
diff --git a/src/preproc/eqn/box.h b/src/preproc/eqn/box.h
index fc53e148b..b80c89ee2 100644
--- a/src/preproc/eqn/box.h
+++ b/src/preproc/eqn/box.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -282,6 +282,10 @@ void restore_compatibility();
 void set_script_reduction(int n);
 void set_minimum_size(int n);
 void set_param(const char *name, int value);
+void reset_param(const char *name);
+int get_param(const char *name);
+void init_param_table();
+void free_param_table();
 
 void set_char_type(const char *type, char *ch);
 
diff --git a/src/preproc/eqn/delim.cpp b/src/preproc/eqn/delim.cpp
index 56519f188..25f0b02fb 100644
--- a/src/preproc/eqn/delim.cpp
+++ b/src/preproc/eqn/delim.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -242,7 +242,7 @@ static void build_extensible(const char *ext, const char 
*top, const char *mid,
     printf("/2");
   printf(">?0+\\n[" EXT_HEIGHT_REG "]+\\n[" EXT_DEPTH_REG "]-1/(\\n["
         EXT_HEIGHT_REG "]+\\n[" EXT_DEPTH_REG "])\n");
-  
+
   printf(".nr " TOTAL_HEIGHT_REG " +(\\n[" EXT_HEIGHT_REG "]+\\n["
         EXT_DEPTH_REG "]*\\n[" TEMP_REG "]");
   if (mid)
@@ -250,7 +250,7 @@ static void build_extensible(const char *ext, const char 
*top, const char *mid,
   printf(")\n");
   printf(".ds " DELIM_STRING " \\Z" DELIMITER_CHAR
         "\\v'-%dM-(\\n[" TOTAL_HEIGHT_REG "]u/2u)'\n",
-        axis_height);
+        get_param("axis_height"));
   if (top)
     printf(".as " DELIM_STRING " \\v'\\n[" TOP_HEIGHT_REG "]u'"
           "\\Z" DELIMITER_CHAR "%s" DELIMITER_CHAR
@@ -313,7 +313,7 @@ static void define_extensible_string(char *delim, int uid,
         ".nr " TOTAL_HEIGHT_REG " \\n[rst]-\\n[rsb]\n"
         ".if \\n[" TOTAL_HEIGHT_REG "]<\\n[" DELTA_REG "] "
         "\\{",
-        current_roman_font, d->small, axis_height,
+        current_roman_font, d->small, get_param("axis_height"),
         current_roman_font, d->small);
 
   char buf[256];
@@ -337,7 +337,7 @@ static void define_extensible_string(char *delim, int uid,
         ".el .nr " INDEX_REG " 0-1\n"
         "..\n"
         "." TEMP_MACRO "\n",
-        buf, buf, axis_height, buf);
+        buf, buf, get_param("axis_height"), buf);
   if (d->ext) {
     printf(".if \\n[" INDEX_REG "]<0 \\{.if c%s \\{\\\n", d->ext);
     build_extensible(d->ext, d->top, d->mid, d->bot);
@@ -348,10 +348,10 @@ static void define_extensible_string(char *delim, int uid,
   printf(".nr " WIDTH_FORMAT " +\\n[" DELIM_WIDTH_REG "]\n", uid);
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]"
         ">?(\\n[" TOTAL_HEIGHT_REG "]/2+%dM)\n",
-        uid, uid, axis_height);
+        uid, uid, get_param("axis_height"));
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]"
         ">?(\\n[" TOTAL_HEIGHT_REG "]/2-%dM)\n",
-        uid, uid, axis_height);
+        uid, uid, get_param("axis_height"));
 }
 
 int delim_box::compute_metrics(int style)
@@ -362,10 +362,12 @@ int delim_box::compute_metrics(int style)
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " DELTA_REG " \\n[" HEIGHT_FORMAT "]-%dM"
         ">?(\\n[" DEPTH_FORMAT "]+%dM)\n",
-        p->uid, axis_height, p->uid, axis_height);
+        p->uid, get_param("axis_height"), p->uid,
+        get_param("axis_height"));
   printf(".nr " DELTA_REG " 0\\n[" DELTA_REG "]*%d/500"
         ">?(\\n[" DELTA_REG "]*2-%dM)\n",
-        delimiter_factor, delimiter_shortfall);
+        get_param("delimiter_factor"),
+        get_param("delimiter_shortfall"));
   if (left) {
     define_extensible_string(left, uid, LEFT_DELIM);
     printf(".rn " DELIM_STRING " " LEFT_DELIM_STRING_FORMAT "\n",
diff --git a/src/preproc/eqn/eqn.h b/src/preproc/eqn/eqn.h
index a4143cbc5..3e603186e 100644
--- a/src/preproc/eqn/eqn.h
+++ b/src/preproc/eqn/eqn.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -35,7 +35,6 @@ extern int inline_flag;
 extern int draw_flag;
 extern int one_size_reduction_flag;
 extern int compatible_flag;
-extern int nroff;
 extern eqnmode_t output_format;
 extern int xhtml;
 
diff --git a/src/preproc/eqn/eqn.ypp b/src/preproc/eqn/eqn.ypp
index 3843bf4da..63828fa33 100644
--- a/src/preproc/eqn/eqn.ypp
+++ b/src/preproc/eqn/eqn.ypp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -98,6 +98,7 @@ void yyerror(const char *);
 %token DELIM
 %token CHARTYPE
 %token SET
+%token RESET
 %token GRFONT
 %token GBFONT
 %token GIFONT
diff --git a/src/preproc/eqn/lex.cpp b/src/preproc/eqn/lex.cpp
index 16e634f93..5e0d0ffd8 100644
--- a/src/preproc/eqn/lex.cpp
+++ b/src/preproc/eqn/lex.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -110,6 +110,7 @@ static struct {
   { "type", TYPE },
   { "vcenter", VCENTER },
   { "set", SET },
+  { "reset", RESET },
   { "opprime", PRIME },
   { "grfont", GRFONT },
   { "gbfont", GBFONT },
@@ -1155,6 +1156,18 @@ void do_set()
   set_param(param.contents(), n);
 }
 
+void do_reset()
+{
+  int t = get_token(2);
+  if (t != TEXT && t != QUOTED_TEXT) {
+    lex_error("invalid parameter name argument to 'reset' primitive");
+    return;
+  }
+  token_buffer += '\0';
+  string param = token_buffer;
+  reset_param(param.contents());
+}
+
 int yylex()
 {
   for (;;) {
@@ -1170,13 +1183,13 @@ int yylex()
       do_definition(0);
       break;
     case TDEFINE:
-      if (!nroff)
+      if (!get_param("nroff"))
        do_definition(0);
       else
        ignore_definition();
       break;
     case NDEFINE:
-      if (nroff)
+      if (get_param("nroff"))
        do_definition(0);
       else
        ignore_definition();
@@ -1214,6 +1227,9 @@ int yylex()
     case SET:
       do_set();
       break;
+    case RESET:
+      do_reset();
+      break;
     case QUOTED_TEXT:
     case TEXT:
       token_buffer += '\0';
diff --git a/src/preproc/eqn/limit.cpp b/src/preproc/eqn/limit.cpp
index c8b0eb943..95540d273 100644
--- a/src/preproc/eqn/limit.cpp
+++ b/src/preproc/eqn/limit.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -115,20 +115,22 @@ int limit_box::compute_metrics(int style)
   if (to != 0) {
     printf(".nr " SUP_RAISE_FORMAT " %dM+\\n[" DEPTH_FORMAT
           "]>?%dM+\\n[" HEIGHT_FORMAT "]\n",
-          uid, big_op_spacing1, to->uid, big_op_spacing3, p->uid);
+          uid, get_param("big_op_spacing1"), to->uid,
+          get_param("big_op_spacing3"), p->uid);
     printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
           HEIGHT_FORMAT "]+%dM\n",
-          uid, uid, to->uid, big_op_spacing5);
+          uid, uid, to->uid, get_param("big_op_spacing5"));
   }
   else
     printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
   if (from != 0) {
     printf(".nr " SUB_LOWER_FORMAT " %dM+\\n[" HEIGHT_FORMAT
           "]>?%dM+\\n[" DEPTH_FORMAT "]\n",
-          uid, big_op_spacing2, from->uid, big_op_spacing4, p->uid);
+          uid, get_param("big_op_spacing2"), from->uid,
+          get_param("big_op_spacing4"), p->uid);
     printf(".nr " DEPTH_FORMAT " \\n[" SUB_LOWER_FORMAT "]+\\n["
           DEPTH_FORMAT "]+%dM\n",
-          uid, uid, from->uid, big_op_spacing5);
+          uid, uid, from->uid, get_param("big_op_spacing5"));
   }
   else
     printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
diff --git a/src/preproc/eqn/list.cpp b/src/preproc/eqn/list.cpp
index 2e0cb104a..d22f4f215 100644
--- a/src/preproc/eqn/list.cpp
+++ b/src/preproc/eqn/list.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -64,25 +64,25 @@ static int compute_spacing(int is_script, int left, int 
right)
   if (left == SUPPRESS_TYPE || right == SUPPRESS_TYPE)
     return 0;
   if (left == PUNCTUATION_TYPE)
-    return is_script ? 0 : thin_space;
+    return is_script ? 0 : get_param("thin_space");
   if (left == OPENING_TYPE || right == CLOSING_TYPE)
     return 0;
   if (right == BINARY_TYPE || left == BINARY_TYPE)
-    return is_script ? 0 : medium_space;
+    return is_script ? 0 : get_param("medium_space");
   if (right == RELATION_TYPE) {
     if (left == RELATION_TYPE)
       return 0;
     else
-      return is_script ? 0 : thick_space;
+      return is_script ? 0 : get_param("thick_space");
   }
   if (left == RELATION_TYPE)
-    return is_script ? 0 : thick_space;
+    return is_script ? 0 : get_param("thick_space");
   if (right == OPERATOR_TYPE)
-    return thin_space;
+    return get_param("thin_space");
   if (left == INNER_TYPE || right == INNER_TYPE)
-    return is_script ? 0 : thin_space;
+    return is_script ? 0 : get_param("thin_space");
   if (left == OPERATOR_TYPE && right == ORDINARY_TYPE)
-    return thin_space;
+    return get_param("thin_space");
   return 0;
 }
 
diff --git a/src/preproc/eqn/main.cpp b/src/preproc/eqn/main.cpp
index 19c8b29a5..aed51dd46 100644
--- a/src/preproc/eqn/main.cpp
+++ b/src/preproc/eqn/main.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -424,6 +424,8 @@ int main(int argc, char **argv)
     }
   init_table(device);
   init_char_table();
+  init_param_table();
+  std::atexit(free_param_table);
   printf(".do if !dEQ .ds EQ\n"
         ".do if !dEN .ds EN\n");
   if (output_format == troff) {
diff --git a/src/preproc/eqn/other.cpp b/src/preproc/eqn/other.cpp
index c7e95cb5d..8f61874aa 100644
--- a/src/preproc/eqn/other.cpp
+++ b/src/preproc/eqn/other.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -60,7 +60,7 @@ int accent_box::compute_metrics(int style)
   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
-        uid, p->uid, x_height);
+        uid, p->uid, get_param("x_height"));
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
         SUP_RAISE_FORMAT "]\n",
         uid, ab->uid, uid);
@@ -109,7 +109,7 @@ int accent_box::compute_metrics(int style)
         uid, p->uid, ab->uid, p->uid, uid);
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
-        uid, p->uid, x_height);
+        uid, p->uid, get_param("x_height"));
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
         SUP_RAISE_FORMAT "]\n",
         uid, ab->uid, uid);
@@ -174,10 +174,12 @@ overline_char_box::overline_char_box()
 void overline_char_box::output()
 {
   if (output_format == troff) {
-    printf("\\v'-%dM/2u-%dM'", 7*default_rule_thickness, x_height);
+    printf("\\v'-%dM/2u-%dM'", 7 * get_param("default_rule_thickness"),
+          get_param("x_height"));
     printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
-          accent_width);
-    printf("\\v'%dM/2u+%dM'", 7*default_rule_thickness, x_height);
+          get_param("accent_width"));
+    printf("\\v'%dM/2u+%dM'", 7 * get_param("default_rule_thickness"),
+          get_param("x_height"));
   }
   else if (output_format == mathml)
     printf("<mo>&macr;</mo>");
@@ -213,7 +215,7 @@ int overline_box::compute_metrics(int style)
   int r = p->compute_metrics(cramped_style(style));
   // 9
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+%dM\n",
-        uid, p->uid, default_rule_thickness*5);
+        uid, p->uid, get_param("default_rule_thickness") * 5);
   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
   return r;
@@ -225,7 +227,7 @@ void overline_box::output()
     // 9
     printf("\\Z" DELIMITER_CHAR);
     printf("\\v'-\\n[" HEIGHT_FORMAT "]u-(%dM/2u)'",
-          p->uid, 7*default_rule_thickness);
+          p->uid, 7 * get_param("default_rule_thickness"));
     if (draw_flag)
       printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
     else
@@ -354,10 +356,10 @@ underline_char_box::underline_char_box()
 void underline_char_box::output()
 {
   if (output_format == troff) {
-    printf("\\v'%dM/2u'", 7*default_rule_thickness);
+    printf("\\v'%dM/2u'", 7 * get_param("default_rule_thickness"));
     printf((draw_flag ? "\\D'l%dM 0'" : "\\l'%dM\\&\\(ru'"),
-          accent_width);
-    printf("\\v'-%dM/2u'", 7*default_rule_thickness);
+          get_param("accent_width"));
+    printf("\\v'-%dM/2u'", 7 * get_param("default_rule_thickness"));
   }
   else if (output_format == mathml)
     printf("<mo>&lowbar;</mo>");
@@ -395,7 +397,7 @@ int underline_box::compute_metrics(int style)
   int r = p->compute_metrics(style);
   // 10
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
-        uid, p->uid, default_rule_thickness*5);
+        uid, p->uid, get_param("default_rule_thickness") * 5);
   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
   return r;
@@ -407,7 +409,7 @@ void underline_box::output()
     // 10
     printf("\\Z" DELIMITER_CHAR);
     printf("\\v'\\n[" DEPTH_FORMAT "]u+(%dM/2u)'",
-          p->uid, 7*default_rule_thickness);
+          p->uid, 7 * get_param("default_rule_thickness"));
     if (draw_flag)
       printf("\\D'l\\n[" WIDTH_FORMAT "]u 0'", p->uid);
     else
@@ -553,7 +555,7 @@ int fat_box::compute_metrics(int style)
 {
   int r = p->compute_metrics(style);
   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]+%dM\n",
-        uid, p->uid, fat_offset);
+        uid, p->uid, get_param("fat_offset"));
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]\n", uid, p->uid);
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]\n", uid, p->uid);
   return r;
@@ -564,7 +566,7 @@ void fat_box::output()
   if (output_format == troff) {
     p->output();
     printf("\\h'-\\n[" WIDTH_FORMAT "]u'", p->uid);
-    printf("\\h'%dM'", fat_offset);
+    printf("\\h'%dM'", get_param("fat_offset"));
     p->output();
   }
   else if (output_format == mathml) {
@@ -678,7 +680,7 @@ int vcenter_box::compute_metrics(int style)
   printf(".nr " WIDTH_FORMAT " 0\\n[" WIDTH_FORMAT "]\n", uid, p->uid);
   printf(".nr " SUP_RAISE_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
         HEIGHT_FORMAT "]/2+%dM\n",
-        uid, p->uid, p->uid, axis_height);
+        uid, p->uid, p->uid, get_param("axis_height"));
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]+\\n["
         SUP_RAISE_FORMAT "]>?0\n", uid, p->uid, uid);
   printf(".nr " DEPTH_FORMAT " \\n[" DEPTH_FORMAT "]-\\n["
diff --git a/src/preproc/eqn/over.cpp b/src/preproc/eqn/over.cpp
index 8a5729a3c..11697234b 100644
--- a/src/preproc/eqn/over.cpp
+++ b/src/preproc/eqn/over.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -76,27 +76,31 @@ int over_box::compute_metrics(int style)
   }
   if (reduce_size)
     printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
-  printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]", 
+  printf(".nr " WIDTH_FORMAT " (\\n[" WIDTH_FORMAT "]>?\\n[" WIDTH_FORMAT "]",
         uid, num->uid, den->uid);
   // allow for \(ru being wider than both the numerator and denominator
   if (!draw_flag)
     fputs(">?\\w" DELIMITER_CHAR "\\(ru" DELIMITER_CHAR, stdout);
-  printf(")+%dM\n", null_delimiter_space*2 + over_hang*2);
+  printf(")+%dM\n", get_param("null_delimiter_space") * 2
+         + get_param("over_hang") * 2);
   // 15b
   printf(".nr " SUP_RAISE_FORMAT " %dM\n",
-        uid, (reduce_size ? num2 : num1));
+        uid, (reduce_size ? get_param("num2") : get_param("num1")));
   printf(".nr " SUB_LOWER_FORMAT " %dM\n",
-        uid, (reduce_size ? denom2 : denom1));
+        uid, (reduce_size ? get_param("denom2")
+                          : get_param("denom1")));
 
   // 15d
   printf(".nr " SUP_RAISE_FORMAT " +(\\n[" DEPTH_FORMAT
         "]-\\n[" SUP_RAISE_FORMAT "]+%dM+(%dM/2)+%dM)>?0\n",
-        uid, num->uid, uid, axis_height, default_rule_thickness,
-        default_rule_thickness*(reduce_size ? 1 : 3));
+        uid, num->uid, uid, get_param("axis_height"),
+        get_param("default_rule_thickness"),
+        get_param("default_rule_thickness") * (reduce_size ? 1 : 3));
   printf(".nr " SUB_LOWER_FORMAT " +(\\n[" HEIGHT_FORMAT
         "]-\\n[" SUB_LOWER_FORMAT "]-%dM+(%dM/2)+%dM)>?0\n",
-        uid, den->uid, uid, axis_height, default_rule_thickness,
-        default_rule_thickness*(reduce_size ? 1 : 3));
+        uid, den->uid, uid, get_param("axis_height"),
+        get_param("default_rule_thickness"),
+        get_param("default_rule_thickness") * (reduce_size ? 1 : 3));
 
 
   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
@@ -166,14 +170,14 @@ void over_box::output()
     if (reduce_size)
       printf("\\s[\\n[" SIZE_FORMAT "]u]", uid);
     // draw the line
-    printf("\\h'%dM'", null_delimiter_space);
-    printf("\\v'-%dM'", axis_height);
+    printf("\\h'%dM'", get_param("null_delimiter_space"));
+    printf("\\v'-%dM'", get_param("axis_height"));
     fputs(draw_flag ? "\\D'l" : "\\l'", stdout);
     printf("\\n[" WIDTH_FORMAT "]u-%dM",
-          uid, 2*null_delimiter_space);
+          uid, 2 * get_param("null_delimiter_space"));
     fputs(draw_flag ? " 0'" : "\\&\\(ru'", stdout);
-    printf("\\v'%dM'", axis_height);
-    printf("\\h'%dM'", null_delimiter_space);
+    printf("\\v'%dM'", get_param("axis_height"));
+    printf("\\h'%dM'", get_param("null_delimiter_space"));
   }
   else if (output_format == mathml) {
     // FIXME: passing a displaystyle attribute doesn't validate.
diff --git a/src/preproc/eqn/pbox.h b/src/preproc/eqn/pbox.h
index e4cd88e29..abd4cf546 100644
--- a/src/preproc/eqn/pbox.h
+++ b/src/preproc/eqn/pbox.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -16,48 +16,6 @@ for more details.
 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
-extern int fat_offset;
-
-extern int over_hang;
-extern int accent_width;
-
-extern int delimiter_factor;
-extern int delimiter_shortfall;
-
-extern int null_delimiter_space;
-extern int script_space;
-extern int thin_space;
-extern int medium_space;
-extern int thick_space;
-extern int half_space;
-extern int full_space;
-
-extern int num1;
-extern int num2;
-// we don't use num3, because we don't have \atop
-extern int denom1;
-extern int denom2;
-extern int axis_height;
-extern int sup1;
-extern int sup2;
-extern int sup3;
-extern int default_rule_thickness;
-extern int sub1;
-extern int sub2;
-extern int sup_drop;
-extern int sub_drop;
-extern int x_height;
-extern int big_op_spacing1;
-extern int big_op_spacing2;
-extern int big_op_spacing3;
-extern int big_op_spacing4;
-extern int big_op_spacing5;
-
-extern int baseline_sep;
-extern int shift_down;
-extern int column_sep;
-extern int matrix_side_sep;
-
 // ms.eqn relies on this!
 
 #define LINE_STRING "10"
diff --git a/src/preproc/eqn/pile.cpp b/src/preproc/eqn/pile.cpp
index 5ce8ee9eb..ab1f2c371 100644
--- a/src/preproc/eqn/pile.cpp
+++ b/src/preproc/eqn/pile.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -36,16 +36,18 @@ int pile_box::compute_metrics(int style)
     printf(">?\\n[" WIDTH_FORMAT "]", col.p[i]->uid);
   printf("\n");
   printf(".nr " BASELINE_SEP_FORMAT " %dM",
-        uid, baseline_sep+col.space);
+        uid, get_param("baseline_sep") + col.space);
   for (i = 1; i < col.len; i++)
     printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
-          col.p[i-1]->uid, col.p[i]->uid, default_rule_thickness*5);
+          col.p[i-1]->uid, col.p[i]->uid,
+          get_param("default_rule_thickness") * 5);
   // round it so that it's a multiple of the vertical motion quantum
   printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
 
   printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
         "+%dM\n",
-        uid, uid, col.len-1, axis_height - shift_down);
+        uid, uid, col.len-1, get_param("axis_height")
+                             - get_param("shift_down"));
   printf(".nr " HEIGHT_FORMAT " \\n[" SUP_RAISE_FORMAT "]+\\n["
         HEIGHT_FORMAT "]\n",
         uid, uid, col.p[0]->uid);
@@ -157,21 +159,24 @@ int matrix_box::compute_metrics(int style)
     printf("\n");
   }
   printf(".nr " WIDTH_FORMAT " %dM",
-        uid, column_sep*(len-1)+2*matrix_side_sep);
+        uid, get_param("column_sep") * (len - 1) + 2
+        * get_param("matrix_side_sep"));
   for (i = 0; i < len; i++)
     printf("+\\n[" COLUMN_WIDTH_FORMAT "]", uid, i);
   printf("\n");
   printf(".nr " BASELINE_SEP_FORMAT " %dM",
-        uid, baseline_sep+space);
+        uid, get_param("baseline_sep") + space);
   for (i = 0; i < len; i++)
     for (j = 1; j < p[i]->len; j++)
       printf(">?(\\n[" DEPTH_FORMAT "]+\\n[" HEIGHT_FORMAT "]+%dM)",
-          p[i]->p[j-1]->uid, p[i]->p[j]->uid, default_rule_thickness*5);
+          p[i]->p[j-1]->uid, p[i]->p[j]->uid,
+          get_param("default_rule_thickness") * 5);
   // round it so that it's a multiple of the vertical motion quantum
   printf("+(\\n(.V/2)/\\n(.V*\\n(.V\n");
   printf(".nr " SUP_RAISE_FORMAT " \\n[" BASELINE_SEP_FORMAT "]*%d/2"
         "+%dM\n",
-        uid, uid, max_len-1, axis_height - shift_down);
+        uid, uid, max_len-1, get_param("axis_height")
+        - get_param("shift_down"));
   printf(".nr " HEIGHT_FORMAT " 0\\n[" SUP_RAISE_FORMAT "]+(0",
         uid, uid);
   for (i = 0; i < len; i++)
@@ -190,7 +195,7 @@ int matrix_box::compute_metrics(int style)
 void matrix_box::output()
 {
   if (output_format == troff) {
-    printf("\\h'%dM'", matrix_side_sep);
+    printf("\\h'%dM'", get_param("matrix_side_sep"));
     for (int i = 0; i < len; i++) {
       int j;
       printf("\\v'-\\n[" SUP_RAISE_FORMAT "]u'", uid);
@@ -232,9 +237,9 @@ void matrix_box::output()
       printf("\\v'-(%du*\\n[" BASELINE_SEP_FORMAT "]u)'", p[i]->len - 1, uid);
       printf("\\h'\\n[" COLUMN_WIDTH_FORMAT "]u'", uid, i);
       if (i != len - 1)
-       printf("\\h'%dM'", column_sep);
+       printf("\\h'%dM'", get_param("column_sep"));
     }
-    printf("\\h'%dM'", matrix_side_sep);
+    printf("\\h'%dM'", get_param("matrix_side_sep"));
   }
   else if (output_format == mathml) {
     int n = p[0]->len; // Each column must have the same number of rows in it
diff --git a/src/preproc/eqn/script.cpp b/src/preproc/eqn/script.cpp
index 7bb16a5b9..34fe1fe74 100644
--- a/src/preproc/eqn/script.cpp
+++ b/src/preproc/eqn/script.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -88,9 +88,9 @@ int script_box::compute_metrics(int style)
   }
   else {
     printf(".nr " SUP_RAISE_FORMAT " \\n[" HEIGHT_FORMAT "]-%dM>?0\n",
-          uid, p->uid, sup_drop);
+          uid, p->uid, get_param("sup_drop"));
     printf(".nr " SUB_LOWER_FORMAT " \\n[" DEPTH_FORMAT "]+%dM\n",
-          uid, p->uid, sub_drop);
+          uid, p->uid, get_param("sub_drop"));
   }
   printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
   if (sup == 0) {
@@ -98,35 +98,37 @@ int script_box::compute_metrics(int style)
     // 18b
     printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM>?(\\n["
           HEIGHT_FORMAT "]-(%dM*4/5))\n",
-          uid, uid, sub1, sub->uid, x_height);
+          uid, uid, get_param("sub1"), sub->uid,
+          get_param("x_height"));
   }
   else {
     // sup != 0
     // 18c
     int pos;
     if (style == DISPLAY_STYLE)
-      pos = sup1;
+      pos = get_param("sup1");
     else if (style & 1)                // not cramped
-      pos = sup2;
+      pos = get_param("sup2");
     else
-      pos = sup3;
+      pos = get_param("sup3");
     printf(".nr " SUP_RAISE_FORMAT " \\n[" SUP_RAISE_FORMAT
           "]>?%dM>?(\\n[" DEPTH_FORMAT "]+(%dM/4))\n",
-          uid, uid, pos, sup->uid, x_height);
+          uid, uid, pos, sup->uid, get_param("x_height"));
     // 18d
     if (sub != 0) {
       printf(".nr " SUB_LOWER_FORMAT " \\n[" SUB_LOWER_FORMAT "]>?%dM\n",
-            uid, uid, sub2);
+            uid, uid, get_param("sub2"));
       // 18e
       printf(".nr " TEMP_REG " \\n[" DEPTH_FORMAT "]-\\n["
             SUP_RAISE_FORMAT "]+\\n[" HEIGHT_FORMAT "]-\\n["
             SUB_LOWER_FORMAT "]+(4*%dM)\n",
-            sup->uid, uid, sub->uid, uid, default_rule_thickness);
+            sup->uid, uid, sub->uid, uid,
+            get_param("default_rule_thickness"));
       printf(".if \\n[" TEMP_REG "] \\{");
       printf(".nr " SUB_LOWER_FORMAT " +\\n[" TEMP_REG "]\n", uid);
       printf(".nr " TEMP_REG " (%dM*4/5)-\\n[" SUP_RAISE_FORMAT
             "]+\\n[" DEPTH_FORMAT "]>?0\n",
-            x_height, uid, sup->uid);
+            get_param("x_height"), uid, sup->uid);
       printf(".nr " SUP_RAISE_FORMAT " +\\n[" TEMP_REG "]\n", uid);
       printf(".nr " SUB_LOWER_FORMAT " -\\n[" TEMP_REG "]\n", uid);
       printf(".\\}\n");
@@ -136,12 +138,13 @@ int script_box::compute_metrics(int style)
   if (sub != 0 && sup != 0)
     printf("+((\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]>?\\n["
           WIDTH_FORMAT "])+%dM)>?0\n",
-          sub->uid, p->uid, sup->uid, script_space);
+          sub->uid, p->uid, sup->uid, get_param("script_space"));
   else if (sub != 0)
     printf("+(\\n[" WIDTH_FORMAT "]-\\n[" SUB_KERN_FORMAT "]+%dM)>?0\n",
-          sub->uid, p->uid, script_space);
+          sub->uid, p->uid, get_param("script_space"));
   else if (sup != 0)
-    printf("+(\\n[" WIDTH_FORMAT "]+%dM)>?0\n", sup->uid, script_space);
+    printf("+(\\n[" WIDTH_FORMAT "]+%dM)>?0\n", sup->uid,
+          get_param("script_space"));
   else
     printf("\n");
   printf(".nr " HEIGHT_FORMAT " \\n[" HEIGHT_FORMAT "]",
diff --git a/src/preproc/eqn/sqrt.cpp b/src/preproc/eqn/sqrt.cpp
index a4ae8d724..78e85ce2a 100644
--- a/src/preproc/eqn/sqrt.cpp
+++ b/src/preproc/eqn/sqrt.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2020 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2023 Free Software Foundation, Inc.
      Written by James Clark (jjc@jclark.com)
 
 This file is part of groff.
@@ -50,8 +50,9 @@ int sqrt_box::compute_metrics(int style)
   int r = p->compute_metrics(cramped_style(style));
   printf(".nr " TEMP_REG " \\n[" HEIGHT_FORMAT "]+\\n[" DEPTH_FORMAT
         "]+%dM+(%dM/4)\n",
-        p->uid, p->uid, default_rule_thickness,
-        (style > SCRIPT_STYLE ? x_height : default_rule_thickness));
+        p->uid, p->uid, get_param("default_rule_thickness"),
+        (style > SCRIPT_STYLE ? get_param("x_height")
+                              : get_param("default_rule_thickness")));
   printf(".nr " SIZE_FORMAT " \\n[.ps]\n", uid);
   printf(".ds " SQRT_STRING_FORMAT " " SQRT_CHAR "\n", uid);
   printf(".ds " BAR_STRING " " RADICAL_EXTENSION_CHAR "\n");
@@ -59,7 +60,7 @@ int sqrt_box::compute_metrics(int style)
         " 0\\w" DELIMITER_CHAR SQRT_CHAR DELIMITER_CHAR "\n",
         uid);
   printf(".if \\n[rst]-\\n[rsb]-%dM<\\n[" TEMP_REG "] \\{",
-        default_rule_thickness);
+        get_param("default_rule_thickness"));
 
   printf(".nr " INDEX_REG " 0\n"
         ".de " TEMP_MACRO "\n"
@@ -76,7 +77,7 @@ int sqrt_box::compute_metrics(int style)
         ".el .nr " INDEX_REG " 0-1\n"
         "..\n"
         "." TEMP_MACRO "\n",
-        uid, uid, default_rule_thickness);
+        uid, uid, get_param("default_rule_thickness"));
 
   printf(".if \\n[" INDEX_REG "]<0 \\{");
 
@@ -98,14 +99,14 @@ int sqrt_box::compute_metrics(int style)
         ".\\}\n"
         "..\n"
         "." TEMP_MACRO "\n",
-        uid, uid, default_rule_thickness);
-  
+        uid, uid, get_param("default_rule_thickness"));
+
   printf(".\\}\\}\n");
 
   printf(".nr " SMALL_SIZE_FORMAT " \\n[.ps]\n", uid);
   // set TEMP_REG to the amount by which the radical sign is too big
   printf(".nr " TEMP_REG " \\n[rst]-\\n[rsb]-%dM-\\n[" TEMP_REG "]\n",
-        default_rule_thickness);
+        get_param("default_rule_thickness"));
   // If TEMP_REG is negative, the bottom of the radical sign should
   // be -TEMP_REG above the bottom of p. If it's positive, the bottom
   // of the radical sign should be TEMP_REG/2 below the bottom of p.
@@ -141,7 +142,8 @@ int sqrt_box::compute_metrics(int style)
         ">?(\\n[" SUP_RAISE_FORMAT "]+\\n[rst])\n",
         uid, p->uid, uid);
   // put a bit of extra space above the bar
-  printf(".nr " HEIGHT_FORMAT " +%dM\n", uid, default_rule_thickness);
+  printf(".nr " HEIGHT_FORMAT " +%dM\n", uid,
+        get_param("default_rule_thickness"));
   printf(".ps \\n[" SIZE_FORMAT "]u\n", uid);
   return r;
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]