Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with scale with mtextInheritFont #3194

Closed
saraOrkide opened this issue Feb 24, 2024 · 15 comments
Closed

Problem with scale with mtextInheritFont #3194

saraOrkide opened this issue Feb 24, 2024 · 15 comments
Labels
Accepted Issue has been reproduced by MathJax team Merged Merged into develop branch Test Needed v4

Comments

@saraOrkide
Copy link

saraOrkide commented Feb 24, 2024

When I set the scale to 1.2 and mtextInheritFont = true, the formulas stick together
Screenshot from 2024-02-24 16-01-23
Screenshot from 2024-02-24 16-00-48

mathjax version: 4.0.0-beta.4
using mml-chtml.js
mathjax config:

window.MathJax = {
  options: {
    enableMenu: !1,
  },
  loader: {
    load: ["[tex]/tagformat", "output/chtml"],
    paths: {
      "mathjax-modern": "https://cdn.chista.me/chista-mathjax-4.0.0-beta.4/mathjax-modern-font"
    }
  },
  extensions: ["mml2jax.js", "MathMenu.js", "MathZoom.js"],
  MathML: {
    extensions: ["mml3.js"]
  },
  chtml: {
    displayAlign: 'right',
    scale: 1.2,
    minScale: .75,
    mtextInheritFont: !0,
    merrorInheritFont: !0,
    skipAttributes: {},
    exFactor: 18,
    displayAlign: "center",
    displayIndent: "0",
    matchFontHeight: 0,
    adaptiveCSS: !0
  },
  mtextFont: 'fontRegular', 
  mtextFontSize: 15,
  linebreaks: {
    inline: !0,
    width: "100%",
    lineleading: 2,
    LinebreakVisitor: null
  },
  includeHtmlTags: {
    br: "\n",
    wbr: "",
    "#comment": ""
  },
  ignoreHtmlClass: "tex2jax_ignore",
  processHtmlClass: "tex2jax_process",
  tex: {
    inlineMath: [["$", "$"]],
    processEscapes: !1
  },
  startup: {
    ready() {
      const t = MathJax._.input.tex.ParseMethods.default,
      { RegExpMap: a } = MathJax._.input.tex.TokenMap;
      new a("digit", t.digit, /[\d.٫۰-۹]/);
      const { ChtmlMn: e } = MathJax._.output.chtml.Wrappers.mn;
      e.prototype.remapChars = function (t) {
        const a = [];
        for (const e of t) {
          const t = this.font.getRemappedChar("mn", e);
          a.push(...(t ? this.unicodeChars(t, this.variant) : [e]));
        }
        return a;
      };
      const { FontData: n } = MathJax._.output.common.FontData,
      o = n.defaultMnMap;
      for (var s = 0; s < 10; s++) o[48 + s] = String.fromCodePoint(1776 + s);
      
      MathJax.startup.defaultReady();
    },
  },
});

using iran-yekan persian font :
IRANYekanXFaNum-Regular.zip
exmple mml for image number 2:

<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>
    <span dir=rtl>نمودار هریک از توابع زیر را رسم کنید. کدام یک از آنها در تمام دامنۀ خود، اکیداً یکنواست؟</span>
  </span>
</div>
<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>
    <span dir=rtl>الف)
      <span style='font-family:ChistaYekan'>&nbsp;&nbsp;&nbsp;</span>
      <span class='chistaFormula'>
        <math  display='inline'  mathcolor='#050038'>
          <mtext>f(x)</mtext>
          <mo>=</mo>
          <msqrt>
            <mtext>2</mtext>
            <mo>-</mo>
            <mtext>x</mtext>
          </msqrt>
        </math>
      </span>
    </span>
  </span>
</div>
<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>
    <span dir=rtl>ب)
      <span style='font-family:ChistaYekan'>&nbsp;&nbsp;&nbsp;</span>
      <span class='chistaFormula'>
        <math  display='inline'  mathcolor='#050038'>
          <mtext>g</mtext>
          <mfenced   separators='|'>
            <mrow>
              <mtext>x</mtext>
            </mrow>
          </mfenced>
          <mo>=</mo>
          <msup>
            <mrow>
              <mtext>2</mtext>
            </mrow>
            <mrow>
              <mo>-</mo>
              <mtext>x</mtext>
            </mrow>
          </msup>
        </math>
      </span>
    </span>
  </span>
</div>
<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>
    <span dir=rtl>پ)
      <span style='font-family:ChistaYekan'>&nbsp;&nbsp;&nbsp;</span>
      <span class='chistaFormula'>
        <math  display='inline'  mathcolor='#050038'>
          <mtext>h(x)</mtext>
          <mo>=</mo>
          <msubsup>
            <mrow>
              <mtext>log</mtext>
            </mrow>
            <mrow>
              <mtext>2</mtext>
            </mrow>
            <mrow>
              <mtext>x</mtext>
            </mrow>
          </msubsup>
        </math>
      </span>
    </span>
  </span>
</div>
<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>&ensp;</span>
</div>
<div class='chistaItem' style='text-align:right;justify-content:right;/*MARK-BY-CHISTA-PARSER*/;direction:rtl;/*MARK-BY-CHISTA-PARSER*/;'>
  <span class='chistaText'>&ensp;</span>
</div>
@dpvc
Copy link
Member

dpvc commented Feb 24, 2024

Yes, 4.0.0-beta.4 does not get the width of text correct when mtextInheritFont is true and scale is not 1. This was fixed several months ago in mathjax/MathJax-src#1014, but there has not been a beta release since then. You can incorporate the following configuration:

MathJax = {
  output: {
    linebreaks: {inline: false},
    mtextInheritFont: true,
    scale: 1.2
  },
  startup: {
    ready() {
      const {CHTML} = MathJax._.output.chtml_ts;
      Object.assign(CHTML.prototype, {
        _unknownText: CHTML.prototype.unknownText,
        unknownText(text, variant, width = null, rscale = 1) {
          const node = this._unknownText(text, variant, width, rscale);
          if (width !== null) {
            this.adaptor.setStyle(node, 'width', this.fixed(width * this.math.metrics.scale * rscale) + 'em');
          }
          return node;
        },
        measureTextNode(textNode) {
          const adaptor = this.adaptor;
          const text = adaptor.clone(textNode);
          adaptor.setStyle(text, 'font-family', adaptor.getStyle(text, 'font-family').replace(/MJXZERO, /g, ''));
          const em = this.math.metrics.em;
          const style = {
            position: 'absolute', top: 0, left: 0,
            'white-space': 'nowrap',
            'font-size': this.fixed(em, 3) + 'px'
          };
          const node = this.html('mjx-measure-text', {style}, [text]);
          adaptor.append(adaptor.parent(this.math.start.node), this.container);
          adaptor.append(this.container, node);
          let w = adaptor.nodeSize(text, em)[0];
          adaptor.remove(this.container);
          adaptor.remove(node);
          return {w: w, h: .75, d: .2};
        }
      });
      MathJax.startup.defaultReady();
      
    }
  }
}

as a work-around until beta.5 is released.

@dpvc dpvc added Accepted Issue has been reproduced by MathJax team Test Needed Merged Merged into develop branch v4 labels Feb 24, 2024
@dpvc
Copy link
Member

dpvc commented Feb 24, 2024

I should point out that there are a number of issues with your MathJax configuration. You seem to be mixing v2 options with the v3/v4 configuration, and other options are out of place.

For example,

  extensions: ["mml2jax.js", "MathMenu.js", "MathZoom.js"],
  MathML: {
    extensions: ["mml3.js"]
  },

are v2 options, and have not effect in v3/v4. It is also a bit odd to set enableMenu to false, but indicate you want the MathMenu here.

The options

  mtextFont: 'fontRegular', 
  ...
  linebreaks: {
    inline: !0,
    width: "100%",
    lineleading: 2,
    LinebreakVisitor: null
  },

are in the wrong place, as they should be in the chtml block. I'm not sure what fontRegular is, but it should be a font name or list of names. The line breaks values are all the defaults, so you don't need them to be set here.

The option

  mtextFontSize: 15,

doesn't exist, so has no effect.

The options

  includeHtmlTags: {
    br: "\n",
    wbr: "",
    "#comment": ""
  },
  ignoreHtmlClass: "tex2jax_ignore",
  processHtmlClass: "tex2jax_process",

all belong in the options block, not in the top-level of the configuration. Since the includeHtmlTags options are all the defaults, there is no need to include them at all.

Since you are using MathML input, not TeX, the block

  tex: {
    inlineMath: [["$", "$"]],
    processEscapes: !1
  },

is superfluous, unless you are using TeX notation elsewhere. And the tex2jax_ignore and tex2jax_process values are not used for MathML input, so they don't need to be included here.

As for

    load: ["[tex]/tagformat", "output/chtml"],

you are loading the [tex]/tagformat TeX extension, but are not using TeX, and haven't configured the tag formats, which is the only reason for loading that extension. Plus you haven't added it to the TeX package list, so you are loading code you don't need. Since you aren't loading the MathML input component, I assume you are using one of the combined components, like mml-chtml.js or perhaps tex-mml-chtml.js (though that would be more than you need if you aren't actually using TeX input). Those combined components already include the CHTML output component, so there is no need to load it by hand. So your load array is unnecessary.

Finally, in

  chtml: {
    displayAlign: 'right',
    scale: 1.2,
    minScale: .75,
    mtextInheritFont: !0,
    merrorInheritFont: !0,
    skipAttributes: {},
    exFactor: 18,
    displayAlign: "center",
    displayIndent: "0",
    matchFontHeight: 0,
    adaptiveCSS: !0
  },

you have specified displayAlign twice so the second one ('center') will be used. Since you have disabled matchFontHeight, the minScale value will not be used, so no need to specify it. The skipAttributes, second displayAlign, displayIndent, and adaptiveCSS options are all the defaults, so no need to include them here.

The exFactor is only used when the surrounding font's ex-height can't be computed (as is the case for node applications, but never for in-browser use), so is unneeded in your case. Also, your value of 18 means that the height of an ex is 18em, or 18 times with width of an M. If that were true, it would be a very strange font indeed.

So a minimal configuration that is equivalent to the one you have would be:

window.MathJax = {
  options: {
    enableMenu: !1
  },
  loader: {
    paths: {
      "mathjax-modern": "https://cdn.chista.me/chista-mathjax-4.0.0-beta.4/mathjax-modern-font"
    }
  },
  chtml: {
    displayAlign: 'right',
    scale: 1.2,
    mtextInheritFont: !0,
    merrorInheritFont: !0,
    matchFontHeight: 0
  },
  startup: {
    ready() {
      const t = MathJax._.input.tex.ParseMethods.default,
      { RegExpMap: a } = MathJax._.input.tex.TokenMap;
      new a("digit", t.digit, /[\d.٫۰-۹]/);
      const { ChtmlMn: e } = MathJax._.output.chtml.Wrappers.mn;
      e.prototype.remapChars = function (t) {
        const a = [];
        for (const e of t) {
          const t = this.font.getRemappedChar("mn", e);
          a.push(...(t ? this.unicodeChars(t, this.variant) : [e]));
        }
        return a;
      };
      const { FontData: n } = MathJax._.output.common.FontData,
      o = n.defaultMnMap;
      for (var s = 0; s < 10; s++) o[48 + s] = String.fromCodePoint(1776 + s);
      
      MathJax.startup.defaultReady();
    }
  }
});

@dpvc
Copy link
Member

dpvc commented Feb 24, 2024

One of the reasons you have run into this width issue is that your re using <mtext> elements inappropriately. For example,

<mtext>f(x)</mtext>

should be

<mi>f</mi>
<mrow>
  <mo>(<mo>
  <mi>x</mi>
  <mo>)</mo>
</mrow>

If you put everything into <mtext> tags, the spacing and italicization will not be correct. It will also produce the wrong results for users with assistive technology like screen readers (but since you have disabled the MathJax menu, they won't be able to turn on the accessibility, so perhaps you don't care about that).

Since the width issue only affect <mtext> content with scale not equal to 1, had you used the proper MathML markup, you would have not had the overlap issue, except for when you actually do need <mtext>, like around Persian words embedded in an expression.

@saraOrkide
Copy link
Author

saraOrkide commented Feb 25, 2024

I should point out that there are a number of issues with your MathJax configuration. You seem to be mixing v2 options with the v3/v4 configuration, and other options are out of place. ...

If you don't use load: ["[tex]/tagformat"] because I use the following code, there is an error:

MathJax(?): Cannot read properties of undefined (reading 'ParseMethods')

I'm using code for persian digit:

                       const t = MathJax._.input.tex.ParseMethods.default,
                            { RegExpMap: a } = MathJax._.input.tex.TokenMap;
                        new a("digit", t.digit, /[\d.٫۰-۹]/);
                        const { ChtmlMn: e } = MathJax._.output.chtml.Wrappers.mn;
                        e.prototype.remapChars = function (t) {
                            const a = [];
                            for (const e of t) {
                                const t = this.font.getRemappedChar("mn", e);
                                a.push(...(t ? this.unicodeChars(t, this.variant) : [e]));
                            }
                            return a;
                        };
                        const { FontData: n } = MathJax._.output.common.FontData,
                            o = n.defaultMnMap;
                        for (var s = 0; s < 10; s++) o[48 + s] = String.fromCodePoint(1776 + s);

Since you aren't using TeX input (you are using mml-xhtml.js, so no TeX), you can drop the lines

const t = MathJax._.input.tex.ParseMethods.default,
    { RegExpMap: a } = MathJax._.input.tex.TokenMap;
new a("digit", t.digit, /[\d.٫۰-۹]/);

since they are for TeX, and aren't needed for MathML. That will avoid the error without having to load the tagformat extension (which will cause all the TeX input code to be loaded unnecessarily).

@saraOrkide
Copy link
Author

saraOrkide commented Apr 13, 2024

I fixed the small problem of displaying indices in the formulas according to what you said
But now I have another problem, if the index is written in capital letters, it will be too big
Do you think there is a solution for it?
example: The first part of the formula before equalization, in my opinion, the A index is too big
Screenshot from 2024-04-13 13-16-51
mml code:
<div class='chistaItem' style='text-align:left;justify-content:left;/*MARK-BY-CHISTA-PARSER*/;direction:ltr;/*MARK-BY-CHISTA-PARSER*/;'> <span class='chistaText'><span class='chistaFormula'><math xmlns='http://www.w3.org/1998/Math/MathML' display='inline' mathcolor='#050038'> <mfenced open='{' close='' separators='|'> <mrow> <mtable> <mtr> <mtd> <msub> <mrow> <mtext>p</mtext> </mrow> <mrow> <mtext>A</mtext> </mrow> </msub> <mo>=</mo> <msub> <mrow> <mtext>ρ</mtext> </mrow> <mrow> <mtext>gh</mtext> </mrow> </msub> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> <mspace width='3px' /> </mtd> <mtd /> </mtr> <mtr> <mtd> <msub> <mrow> <mtext>p</mtext> </mrow> <mrow> <mtext>B</mtext> </mrow> </msub> <mo>=</mo> <msub> <mrow> <mtext>ρ</mtext> </mrow> <mrow> <mtext>gh</mtext> </mrow> </msub> <mo>+</mo> <msub> <mrow> <mtext>ρ</mtext> </mrow> <mrow> <mtext>g</mtext> </mrow> </msub> <mfrac> <mrow> <mtext>۵</mtext> </mrow> <mrow> <mtext>۱۰۰</mtext> </mrow> </mfrac> <mo>+</mo> <msub> <mrow> <mover accent='true'> <mrow> <mtext>ρ</mtext> </mrow> <mo>´</mo> </mover> </mrow> <mrow> <mtext>g</mtext> </mrow> </msub> <mfrac> <mrow> <mtext>۵</mtext> </mrow> <mrow> <mtext>۱۰۰</mtext> </mrow> </mfrac> </mtd> <mtd /> </mtr> </mtable> </mrow> </mfenced> <mtext>Δ</mtext> <msub> <mrow> <mtext>p</mtext> </mrow> <mrow> <mtext>AB</mtext> </mrow> </msub> <mo>=</mo> <msub> <mrow> <mtext>ρ</mtext> </mrow> <mrow> <mtext>g</mtext> </mrow> </msub> <mfrac> <mrow> <mtext>۵</mtext> </mrow> <mrow> <mtext>۱۰۰</mtext> </mrow> </mfrac> <mo>+</mo> <msub> <mrow> <mover accent='true'> <mrow> <mtext>ρ</mtext> </mrow> <mo>´</mo> </mover> </mrow> <mrow> <mtext>g</mtext> </mrow> </msub> <mtext>Δ</mtext> <msub> <mrow> <mover accent='true'> <mrow> <mtext>P</mtext> </mrow> <mo>´</mo> </mover> </mrow> <mrow> <mtext>AB</mtext> </mrow> </msub> <mfrac> <mrow> <mtext>۵</mtext> </mrow> <mrow> <mtext>۱۰۰</mtext> </mrow> </mfrac> </math></span></span></div>
persian font:
Dana-Regular.zip
mathjax setting:
`(window.MathJax = {
options: {
enableMenu: !1,
},
loader: {
paths: {
"mathjax-fira": "https://cdn.chista.me/chista-mathjax-4.0.0-beta.4/mathjax-fira-font",
}
},
chtml: {
displayAlign: 'right',
scale: 1,
merrorInheritFont: !0,
matchFontHeight: false,
mtextFont: 'fontRegular, Noto Sans, sans-serif',
mtextInheritFont: false,
unknownFamily: 'fontRegular, Noto Sans, sans-serif',
font: 'mathjax-fira',
},

        startup: {
            ready() {
                const { ChtmlMn: e } = MathJax._.output.chtml.Wrappers.mn;
                e.prototype.remapChars = function (t) {
                    const a = [];
                    for (const e of t) {
                        const t = this.font.getRemappedChar("mn", e);
                        a.push(...(t ? this.unicodeChars(t, this.variant) : [e]));
                    }
                    return a;
                };
                const { FontData: n } = MathJax._.output.common.FontData,
                    o = n.defaultMnMap;
                for (var s = 0; s < 10; s++) o[48 + s] = String.fromCodePoint(1776 + s);
                const { CHTML } = MathJax._.output.chtml_ts;
                Object.assign(CHTML.prototype, {
                    _unknownText: CHTML.prototype.unknownText,
                    unknownText(text, variant, width = null, rscale = 1) {
                        const node = this._unknownText(text, variant, width, rscale);
                        if (width !== null) {
                            this.adaptor.setStyle(node, 'width', this.fixed(width * this.math.metrics.scale * rscale) + 'em');
                        }
                        return node;
                    },
                    measureTextNode(textNode) {
                        const adaptor = this.adaptor;
                        const text = adaptor.clone(textNode);
                        adaptor.setStyle(text, 'font-family', adaptor.getStyle(text, 'font-family').replace(/MJXZERO, /g, ''));
                        const em = this.math.metrics.em;
                        const style = {
                            position: 'absolute', top: 0, left: 0,
                            'white-space': 'nowrap',
                            'font-size': this.fixed(em, 3) + 'px'
                        };
                        const node = this.html('mjx-measure-text', { style }, [text]);
                        adaptor.append(adaptor.parent(this.math.start.node), this.container);
                        adaptor.append(this.container, node);
                        let w = adaptor.nodeSize(text, em)[0];
                        adaptor.remove(this.container);
                        adaptor.remove(node);

                        return { w: w, h: .85, d: .3 };
                    }
                });
                const { MmlMath } = MathJax._.core.MmlTree.MmlNodes.math;
                const { MmlMstyle } = MathJax._.core.MmlTree.MmlNodes.mstyle;
                MmlMath.defaults.scriptsizemultiplier = MmlMstyle.defaults.scriptsizemultiplier = 1;
                MathJax.startup.defaultReady();
                const params = MathJax.startup.document.outputJax.font.params;
                params.rule_thickness = .130;
                params.rule_factor = .75;
            },
        },
    });`

using mml-chtml.js
version: mathjax-4.0.0-beta.4

@saraOrkide saraOrkide reopened this Apr 13, 2024
@dpvc
Copy link
Member

dpvc commented Apr 15, 2024

Can you provide a screen shot for the following expression:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <msub>
    <mtext>A</mtext>
    <mtext>A</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">A</mi>
    <mi mathvariant="normal">A</mi>
  </msub>
  <msub>
    <mtext>p</mtext>
    <mtext>p</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">p</mi>
    <mi mathvariant="normal">p</mi>
  </msub>
</math>

Thanks.

Also, it is best to open a new issue rather than reopen an old one, when you have a new problem to report.

@saraOrkide
Copy link
Author

Can you provide a screen shot for the following expression:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <msub>
    <mtext>A</mtext>
    <mtext>A</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">A</mi>
    <mi mathvariant="normal">A</mi>
  </msub>
  <msub>
    <mtext>p</mtext>
    <mtext>p</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">p</mi>
    <mi mathvariant="normal">p</mi>
  </msub>
</math>

Thanks.

Also, it is best to open a new issue rather than reopen an old one, when you have a new problem to report.

Yes, sure, I thought it would be better this way, I apologize

@saraOrkide
Copy link
Author

Can you provide a screen shot for the following expression:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
  <msub>
    <mtext>A</mtext>
    <mtext>A</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">A</mi>
    <mi mathvariant="normal">A</mi>
  </msub>
  <msub>
    <mtext>p</mtext>
    <mtext>p</mtext>
  </msub>
  <msub>
    <mi mathvariant="normal">p</mi>
    <mi mathvariant="normal">p</mi>
  </msub>
</math>

Thanks.
Also, it is best to open a new issue rather than reopen an old one, when you have a new problem to report.

Yes, sure, I thought it would be better this way, I apologize

Screenshot from 2024-04-16 13-39-33

@dpvc
Copy link
Member

dpvc commented Apr 16, 2024

Thanks for the screen shot. It looks like something in your MathJax configuration or CSS is preventing subscripts from being reduced in size.

At one point, I gave you code for changing the scriptsizemultiplier; what did you set that to?

Do you have any CSS that is intended to affect MathJax output, and if so, what is it?

Does your browser have a minimum font size setting, and if so, what is it?

In the past, the subscripts where properly sized (see your screen shots in #3176, for example), so something you have changed since then is causing this.

@saraOrkide
Copy link
Author

saraOrkide commented Apr 17, 2024

I didn't change anything, just what happened
If the index with capital letters is attached to a small letter, it would not be displayed very well in my opinion, like this
Screenshot from 2024-04-17 09-11-25
I also changed the font size from 13px to 14px
I also set scriptsizemultiplier to 1
Also, I was using Iran Yakan font, I changed it to Dana font

If both numbers are lowercase or both uppercase, there is no problem, everything is correct

I think there is a way to fix it with this dana font

I think it is from this piece of code that you sent me:

                        measureTextNode(textNode) {
                            const adaptor = this.adaptor;
                            const text = adaptor.clone(textNode);
                            adaptor.setStyle(text, 'font-family', adaptor.getStyle(text, 'font-family').replace(/MJXZERO, /g, ''));
                            const em = this.math.metrics.em;
                            const style = {
                                position: 'absolute', top: 0, left: 0,
                                'white-space': 'nowrap',
                                'font-size': this.fixed(em, 3) + 'px'
                            };
                            const node = this.html('mjx-measure-text', { style }, [text]);
                            adaptor.append(adaptor.parent(this.math.start.node), this.container);
                            adaptor.append(this.container, node);
                            let w = adaptor.nodeSize(text, em)[0];
                            adaptor.remove(this.container);
                            adaptor.remove(node);

                            return { w: w, h: 1, d: .3 };
                        }

I had changed the value of h to .85 because signs like radical were displayed too long
If I reduce this value to 1, the situation will be better:
Screenshot from 2024-04-17 09-32-12

radical Screenshot:
Screenshot from 2024-04-17 09-54-37

Screenshot from 2024-04-17 10-36-47

@dpvc
Copy link
Member

dpvc commented Apr 17, 2024

I also set scriptsizemultiplier to 1

That is what is causing the problem. The scriptsizemultiplier is the factor by which the scale of super- and subscripts are determined from the scale of the base. A value of .5 would mean it is half the size of the base. The default is 1/sqrt(2), or about .707. A value of 1 means the subscript is the same size as the base (no reduction in size), which is what you are seeing. So MathJax is doing exactly what you asked it to.

If the index with capital letters is attached to a small letter, it would not be displayed very well in my opinion,

I agree, but that is what you have requested by setting scriptsizemultiplier to 1.

I had changed the value of h to .85 because signs like radical were displayed too long

I don't know if the images you presented are for h = .85 or h = 1, and whether you are saying these are bad or OK.

Setting h=.85 is probably OK, and setting d = .2 or maybe even .15 would probably also be OK. These are the height and depth of the characters in the font, but setting them too small may mean the line over a radical may hit the top of some characters, or the bottom of some might hit the fraction line if they are in the numerator. You will have to set these based on the font you are using and testing various letters with ascenders and descenders.

@saraOrkide
Copy link
Author

saraOrkide commented Apr 18, 2024

Thank you very much for your explanation
Can you explain about the following
const params = MathJax.startup.document.outputJax.font.params; params.rule_thickness = .130; params.rule_factor = .75;

@saraOrkide
Copy link
Author

saraOrkide commented Apr 18, 2024

I don't know if the images you presented are for h = .85 or h = 1, and whether you are saying these are bad or OK.

For h = 1 it is not good in my opinion

@saraOrkide
Copy link
Author

saraOrkide commented Apr 18, 2024

I set these settings and sent you a screenshot
As you can see, for example, the parentheses are attached to the water index
And the index that has uppercase letters is not shown very well based on lowercase letters

Screenshot from 2024-04-18 15-29-53

            startup: {
                ready() {
                    const { ChtmlMn: e } = MathJax._.output.chtml.Wrappers.mn;
                    e.prototype.remapChars = function (t) {
                        const a = [];
                        for (const e of t) {
                            const t = this.font.getRemappedChar("mn", e);
                            a.push(...(t ? this.unicodeChars(t, this.variant) : [e]));
                        }
                        return a;
                    };
                    const { FontData: n } = MathJax._.output.common.FontData,
                        o = n.defaultMnMap;
                    for (var s = 0; s < 10; s++) o[48 + s] = String.fromCodePoint(1776 + s);
                    const { CHTML } = MathJax._.output.chtml_ts;
                    Object.assign(CHTML.prototype, {
                        _unknownText: CHTML.prototype.unknownText,
                        unknownText(text, variant, width = null, rscale = 1) {
                            const node = this._unknownText(text, variant, width, rscale);
                            if (width !== null) {
                                this.adaptor.setStyle(node, 'width', this.fixed(width * this.math.metrics.scale * rscale) + 'em');
                            }
                            return node;
                        },
                        measureTextNode(textNode) {
                            const adaptor = this.adaptor;
                            const text = adaptor.clone(textNode);
                            adaptor.setStyle(text, 'font-family', adaptor.getStyle(text, 'font-family').replace(/MJXZERO, /g, ''));
                            const em = this.math.metrics.em;
                            const style = {
                                position: 'absolute', top: 0, left: 0,
                                'white-space': 'nowrap',
                                'font-size': this.fixed(em, 3) + 'px'
                            };
                            const node = this.html('mjx-measure-text', { style }, [text]);
                            adaptor.append(adaptor.parent(this.math.start.node), this.container);
                            adaptor.append(this.container, node);
                            let w = adaptor.nodeSize(text, em)[0];
                            adaptor.remove(this.container);
                            adaptor.remove(node);

                            return { w: w, h: .85, d: .15 };
                        }
                    });
                    const { MmlMath } = MathJax._.core.MmlTree.MmlNodes.math;
                    const { MmlMstyle } = MathJax._.core.MmlTree.MmlNodes.mstyle;
                    MmlMath.defaults.scriptsizemultiplier = MmlMstyle.defaults.scriptsizemultiplier = .875;
                    MathJax.startup.defaultReady();
                    const params = MathJax.startup.document.outputJax.font.params;
                    params.rule_thickness = .130;
                    params.rule_factor = .75;
                },
            },

@dpvc
Copy link
Member

dpvc commented Apr 18, 2024

Can you explain about the following

const params = MathJax.startup.document.outputJax.font.params; params.rule_thickness = .130; params.rule_factor = .75;

Yes, please see the comment where I gave you those changes. This was in response to your asking for more space between fraction lines and the numerator and denominator.

the parentheses are attached to the water index

This is an error in the code I gave you. The * rscale should be removed from the line

              this.adaptor.setStyle(node, 'width', this.fixed(width * this.math.metrics.scale * rscale) + 'em');

making it

              this.adaptor.setStyle(node, 'width', this.fixed(width * this.math.metrics.scale) + 'em');

instead.

And the index that has uppercase letters is not shown very well based on lowercase letters

The size of the subscripts are controlled by the scriptsizemultiplier, which you have set to .875, so there is not much shrinkage, so capital letters will be pretty big (only 12.5% smaller than the base characters).

If you don't want to make the subscripts smaller, there is another parameter that is used in determining how far down to put subscripts. If you set

params.sub1 = .3;

along with the changes to rule_thickness and rule_factor, that will push the subscripts down further. The default value is .15; adjust the value to your preferences. Note that this affects both upper- and lower-case letters.

dpvc added a commit to mathjax/MathJax-src that referenced this issue Apr 18, 2024
dpvc added a commit to mathjax/MathJax-src that referenced this issue Apr 23, 2024
Correct width for unknown fonts in scaled text in CHTML (mathjax/MathJax#3194)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Accepted Issue has been reproduced by MathJax team Merged Merged into develop branch Test Needed v4
Projects
None yet
Development

No branches or pull requests

2 participants