MathJax icon indicating copy to clipboard operation
MathJax copied to clipboard

\color in \Set

Open hbghlyj opened this issue 2 years ago • 1 comments

Issue Summary

\Set{\color{red}222|11111}

is rendered differently in

MathJax LaTeX
formula Untitled-1

LaTeX only applies color to the first part.

Technical details:

  • MathJax Version: 3.2

hbghlyj avatar Jan 20 '24 16:01 hbghlyj

Thanks for the report. This turns out to be due to an internal issue where MathJax's TeX parser doesn't properly handle the | in the set when the \color macro is present. I have made a PR that fixes the issue, but in the meantime, you can use

MathJax = {
  loader: {load: ['[tex]/braket']},
  tex: {packages: {'[+]': ['braket', 'my-braket']}},
  startup: {
    ready() {
      const Stack = MathJax._.input.tex.Stack.default;
      const {Configuration} = MathJax._.input.tex.Configuration;
      const {CommandMap, MacroMap} = MathJax._.input.tex.TokenMap;
      const BraketMethods = MathJax._.input.tex.braket.BraketMethods.default;
      const {TEXCLASS} = MathJax._.core.MmlTree.MmlNode;
      
      Stack.prototype.height = function () {return this.stack.length};

      const MyBraketMethods = {
        Braket(parser, name, open, close, stretchy, barmax, space = false) {
          BraketMethods.Braket(parser, name, open, close, stretchy, barmax, space);
          parser.stack.Top().env.braketItem = parser.stack.height() - 1;
        },
        Bar(parser, name) {
          let c = name === '|' ? '|' : '\u2016';
          const n = parser.stack.height() - parser.stack.env.braketItem;
          const top = parser.stack.Top(n);
          if (!top || !top.isKind('braket') || top.getProperty('barcount') >= top.getProperty('barmax')) {
            return false;
          }
          if (c === '|' && parser.GetNext() === '|') {
            parser.i++;
            c = '\u2016';
          }
          if (!top.getProperty('stretchy')) {
            let node = parser.create('token', 'mo', {stretchy: false, 'data-braketbar': true, texClass: TEXCLASS.ORD}, c);
            parser.Push(node);
            return;
          }
          let close = parser.itemFactory.create('close').setProperty('braketbar', true);
          parser.Push(close);
          top.barNodes.push(
            parser.create('node', 'TeXAtom', [], {texClass: TEXCLASS.CLOSE}),
            parser.create('token', 'mo', {stretchy: true, 'data-braketbar': true, texClass: TEXCLASS.BIN}, c),
            parser.create('node', 'TeXAtom', [], {texClass: TEXCLASS.OPEN})
          );
          top.setProperty('barcount', top.getProperty('barcount') + 1);
        }
      };
      
      new CommandMap('my-braket-macros', {
        braket: ['Braket', '\u27E8', '\u27E9', false, Infinity],
        'set': ['Braket', '{', '}', false, 1],
        Braket: ['Braket', '\u27E8', '\u27E9', true, Infinity],
        Set: ['Braket', '{', '}', true, 1, true],
        '|': 'Bar'
      }, MyBraketMethods);
      new MacroMap('my-braket-characters', {
        '|': 'Bar'
      }, MyBraketMethods);

      Configuration.create(
        'my-braket', {
          handler: {
            character: ['my-braket-characters'],
            macro: ['my-braket-macros']
          },
          priority: 1   // must come before base configuration
        }
      );
      MathJax.startup.defaultReady();
    }
  }
};

for your configuration to work around the issue. Unfortunately, I could not work out a smaller patch, but this should do the trick, if you need it before the next release.

dpvc avatar Jan 24 '24 18:01 dpvc