Thousands separators (commas) in numbers (AsciiMath)

137 views
Skip to first unread message

k...@accepi.com

unread,
Sep 19, 2017, 1:43:25 PM9/19/17
to MathJax Users
Hi,

MathJax with AciiMath renders the expression `1,000/5` as 1, * 000/5, where the numerator of the fraction just shows as 000 instead of 1,000.

JSFiddle: https://jsfiddle.net/kai100/wLhbqkru/

The input numbers are not typed in by me, but come from a different system, so I can't just remove the thousands separators.

How can I configure MathJax to interpret the comma as a thousands separator?

Any help would be much appreciated (I searched the MathJax docs, Wiki, Stackoverflow and this user group for both "comma" and "thousands separator").

Thank you for your time
Kai

Peter Krautzberger

unread,
Sep 21, 2017, 4:48:16 AM9/21/17
to mathja...@googlegroups.com
Hi,

The AsciiMath configuration options are unfortunately not properly documented.

You can specify this via 

   AsciiMath: {
                    decimal: ","
                  },

in you configuration block.

Note that this causes various parsing complications for  (e.g., (1,2) ).

Regards,
Peter.

--
You received this message because you are subscribed to the Google Groups "MathJax Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Peter Krautzberger

unread,
Sep 21, 2017, 5:44:27 AM9/21/17
to mathja...@googlegroups.com
PS: the docs are at http://docs.mathjax.org/en/latest/options/input-processors/AsciiMath.html and that it took me a while to recall where it resides, probably means it's not integrated well enough.

k...@accepi.com

unread,
Sep 21, 2017, 10:20:55 AM9/21/17
to MathJax Users
That works well, thanks a lot, Peter.

Kai
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-user...@googlegroups.com.

k...@accepi.com

unread,
Sep 21, 2017, 11:52:53 AM9/21/17
to MathJax Users
However, adding "decimal: ',' " helps with the thousands separators, but also causes MathJax to add a space after every decimal sign, e.g., "0. 12". Is there a solution for that problem?

Thank you
Kai

Davide Cervone

unread,
Sep 21, 2017, 3:46:26 PM9/21/17
to mathja...@googlegroups.com
Setting

decimal: ','

tells AsciiMath to use the European number format, which uses a comma as the decimal place separator rather than a period.  That is why you are not longer seeing "0.12" treated as a number.  AsciiMath does not have a mechanism of parsing commas every three digits.

The best I can suggest is use a AsciiMath pre-filter to pre-process the AsciiMath to remove the commas before AsciiMath parses the expression.  Adding something like

<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
  function removeCommas(n) {return n.replace(/,/g,'')}
  MathJax.InputJax.AsciiMath.prefilterHooks.Add(function (data) {
    data.math = data.math.replace(/\d{1,3}(?:\,\d\d\d)+/g,removeCommas);
  });
});
</script>

to the page just BEFORE the script that loads MathJax.js should do the trick.  Note that this will mean the commas don't appear in the output, either; there is no natural way to do that, unless you wanted to add commas to ALL numbers that have 4 or more digits (even if they didn't have commas to start with).  That would require a post-filter to go back over the MathML that is produced and convert the numbers to having the commas.  It could be done, but is a bit harder than the filter above.

Davide

k...@accepi.com

unread,
Sep 22, 2017, 7:56:46 PM9/22/17
to MathJax Users
Thank you, Davide. I do want to add commas to all numbers with 4 or more digits.

I've defined a function addCommas(n) to do just that and know that I should add a post-filter hook. What data should I call addCommas() on?

MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
    function addCommas(n){
var parts = n.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
};

function removeCommas(n) {
return n.replace(/,/g,'')
};
MathJax.InputJax.AsciiMath.prefilterHooks.Add(function (data) {
        data.math = data.math.replace(/\d{1,3}(?:\,\d{3})+/g,removeCommas);
});
MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data) {
???;
});
});

Davide Cervone

unread,
Sep 23, 2017, 9:30:57 AM9/23/17
to mathja...@googlegroups.com
OK, here is an example for the post-filter.  The data.math is an ElementJax object for the math that has been parsed by AsciiMath.  The ElementJax is the internal form for the math, and the data.math.root is essentially a MathML tree (of javascript objects that mirror the MathML structure).  The recursiveAddCommas() function walks that tree looking for <mn> elements (which are number elements) and modifies the string contained within the node to add the commas.

MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
  function removeCommas(n) {
    return n.replace(/,/g,'');
  }
  function addCommas(n){
    return n.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
  }
  function recursiveAddCommas(node) {
    if (node.isToken) {
      if (node.type === 'mn') {
        node.data[0].data[0] = addCommas(node.data[0].data[0]);
      }
    } else {
      for (var i = 0, m = node.data.length; i < m; i++) {
        recursiveAddCommas(node.data[i]);
      }
    }
  }
  MathJax.InputJax.AsciiMath.prefilterHooks.Add(function (data) {
    data.math = data.math.replace(/\d{1,3}(?:\,\d{3})+/g, removeCommas);
  });
  MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data) {
    recursiveAddCommas(data.math.root);
  });
});


That should do it, I think.

Davide

k...@accepi.com

unread,
Sep 24, 2017, 8:53:29 PM9/24/17
to MathJax Users
That does work, thank you very much.

Here's the complete configuration for anyone who wants to use AsciiMath with commas as thousands separators:

<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook("AsciiMath Jax Ready", function () {
        function addCommas(n){
var parts = n.toString().split(".");
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return parts.join(".");
};

function removeCommas(n) {
return n.replace(/,/g,'')
};

        function recursiveAddCommas(node) {
if (node.isToken) {
if (node.type === 'mn') {
node.data[0].data[0] = addCommas(node.data[0].data[0]);
}
}
else {
for (var i = 0, m = node.data.length; i < m; i++) {
recursiveAddCommas(node.data[i]);
}
}
}

MathJax.InputJax.AsciiMath.prefilterHooks.Add(function (data) {
data.math = data.math.replace(/\d{1,3}(?:\,\d{3})+/g,removeCommas);
});

MathJax.InputJax.AsciiMath.postfilterHooks.Add(function (data) {
recursiveAddCommas(data.math.root);
});
});
</script>
Reply all
Reply to author
Forward
0 new messages