From d5307b80da8df3ea9fe8dfedf96fd691afd14055 Mon Sep 17 00:00:00 2001
From: Chris Sangwin <C.J.Sangwin@ed.ac.uk>
Date: Wed, 17 Jul 2024 16:09:13 +0100
Subject: [PATCH] Fix to issue #1080: fine tune display of stackunits, i.e.
 change multiplication sign.

---
 doc/en/Authoring/Options.md           |  4 ++--
 doc/en/Developer/Development_track.md |  1 +
 doc/en/Topics/Units.md                |  8 ++++++++
 stack/maxima/stackunits.mac           |  7 +++++--
 tests/castext_test.php                | 22 ++++++++++++++++++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/doc/en/Authoring/Options.md b/doc/en/Authoring/Options.md
index d2354de24..4ee4ee92c 100644
--- a/doc/en/Authoring/Options.md
+++ b/doc/en/Authoring/Options.md
@@ -75,9 +75,9 @@ The expression `(make_multsgn("cross"), a*b)` uses parentheses as an abbreviatio
 
 The value of this option `onum` will only put a multiplication sign between numbers.  This means you will see \(3\times 5\, x\) and not \(3\, 5\, x\) as you would if you have "none".
 
-There is a special atom which controls the multiplication symbol.  If you would like a dot then define
+There is a special atom which controls the multiplication symbol used with option `onum`.  If you would like a dot then define
 
-    texput(multsgnonlyfornumberssym, "\\times");
+    texput(multsgnonlyfornumberssym, "\\cdot");
 
 in the question variables.
 
diff --git a/doc/en/Developer/Development_track.md b/doc/en/Developer/Development_track.md
index ec307f5ee..a4f1fb07f 100644
--- a/doc/en/Developer/Development_track.md
+++ b/doc/en/Developer/Development_track.md
@@ -12,6 +12,7 @@ DONE
 1. Fix [issue #1160](https://github.com/maths/moodle-qtype_stack/issues/879) Allow configuring the MathJax URL
 2. Add in stack preamble via `%_stack_preamble_end;` in the question variables to allow some variables to be available in inputs.  This fixes [issue #1207](https://github.com/maths/moodle-qtype_stack/issues/1207]) and [issue #1133](https://github.com/maths/moodle-qtype_stack/issues/1133).
 3. Allow Maxima code in keyvals to terminate expressions with a `$` (as in Maxima) [issue #1019](https://github.com/maths/moodle-qtype_stack/issues/1019]).  This will allow better copy/paste to and from desktop maxima.
+4. Add in an option to fine-tune the multiplication sign used for scientific units:  `multsgnstackunits`.  See discussion in [issue #1080](https://github.com/maths/moodle-qtype_stack/issues/1080]).
 
 Issues with [github milestone 4.7.0](https://github.com/maths/moodle-qtype_stack/issues?q=is%3Aissue+milestone%3A4.7.0) include
 
diff --git a/doc/en/Topics/Units.md b/doc/en/Topics/Units.md
index 20d775e7a..451eef9aa 100644
--- a/doc/en/Topics/Units.md
+++ b/doc/en/Topics/Units.md
@@ -159,6 +159,14 @@ try to split the expression into units and numbers, and the return the units and
 
 The function `stack_units_split` is deprecated.  DO NOT USE.
 
+## Fine-tuning the display ##
+
+By default STACK's TeX function prints out `stackunits(10,m/s)` as \( 10\, m/s\).  That is, without any multiplication sign between the numerical part and the units.  In some edge cases you might want to add this multiplication sign in.  To do this, use
+
+    texput(multsgnstackunits, "\\cdot");
+
+in the question variables.  In castext you can use, e.g. `{@(texput(multsgnstackunits, "\\cdot "), stackunits(1, s^-1))@}` to create output \({1\cdot s^ {- 1 }}\).
+
 ## Custom units ##
 
 The teacher may want to use their own units. For example, the core `unit` package in Maxima does not include `mm` (millimetre), it is defined there as a word `millimetre`.  This is one reason for creating our own custom units package.
diff --git a/stack/maxima/stackunits.mac b/stack/maxima/stackunits.mac
index 3ddb9cd4a..f24075b6e 100644
--- a/stack/maxima/stackunits.mac
+++ b/stack/maxima/stackunits.mac
@@ -392,8 +392,10 @@ stack_validate_units(expr, LowestTerms, TAns, fracdisp) := block( [simp:false, e
   return(expr)
 )$
 
+texput(multsgnstackunits, "\\, ");
+
 /* Finer control over display of units, separating out the number from the units. */
-stackunitstex(ex) := block ([a, b, c, astr, bstr],
+stackunitstex(ex) := block([a, b, c, astr, bstr],
   a:first(args(ex)),
   b:second(args(ex)),
   if scientific_notationp(a) then make_multsgn("cross"),
@@ -410,8 +412,9 @@ stackunitstex(ex) := block ([a, b, c, astr, bstr],
   bstr:tex1(b),
   if is(strim(" ", astr)="") then return(bstr),
   if is(strim(" ", bstr)="") then return(astr),
-  sconcat(astr,"\\, ", bstr)
+  sconcat(astr, tex1(multsgnstackunits), bstr)
 )$
+
 texput(stackunits, stackunitstex);
 texput(NULLUNITS, "");
 texput(NULLNUM, "");
diff --git a/tests/castext_test.php b/tests/castext_test.php
index 89c21cc4c..f6f72a65f 100644
--- a/tests/castext_test.php
+++ b/tests/castext_test.php
@@ -2369,4 +2369,26 @@ class castext_test extends qtype_stack_testcase {
         $this->assertEquals('\({x-0}\), \({x-0.0}\), \({x\cdot \left(-0.0\right)}\), \({-27}\).',
             $at1->get_rendered());
     }
+
+    /**
+     * @covers \qtype_stack\stack_cas_castext2_latex
+     * @covers \qtype_stack\stack_cas_keyval
+     */
+    public function test_make_mult_sgn_stackunits() {
+        $options = new stack_options();
+        $options->set_option('simplify', false);
+        $cs2 = new stack_cas_session2([], $options, 123456);
+
+        $textinput = '{@stackunits(10,m/s)@}, ' .
+            '{@(texput(multsgnstackunits, "\\\\cdot "), stackunits(1, s^-1))@}, ' .
+            '{@(texput(multsgnstackunits, "\\\\, "), stackunits(1, s^-1))@}. ' .
+            'Multiplication unaffected: {@(texput(multsgnstackunits, "\\\\, "), a*b)@}.';
+        $at1 = castext2_evaluatable::make_from_source($textinput, 'test-case');
+        $this->assertTrue($at1->get_valid());
+        $cs2->add_statement($at1);
+        $cs2->instantiate();
+
+        $this->assertEquals('\({10\, \frac{m}{s}}\), \({1\cdot s^ {- 1 }}\), \({1\, s^ {- 1 }}\). ' .
+            'Multiplication unaffected: \({a\cdot b}\).', $at1->get_rendered());
+    }
 }
-- 
GitLab