mathjax / MathJax

Beautiful and accessible math in all browsers
http://www.mathjax.org/
Apache License 2.0
10.09k stars 1.16k forks source link

line breaking in MathML (V4) #3188

Open leberman opened 6 months ago

leberman commented 6 months ago

I am using the latest version of MathJax But line breaking is not working.

2024-02-20_10-23


<math id="mml4814">
   <mstyle displaystyle="true">
      <mrow>
         <mrow>
            <munderover>
               <mo stretchy="false">&sum;</mo>
               <mrow>
                  <mi>i</mi>
                  <mo>=</mo>
                  <mn>1</mn>
               </mrow>
               <mrow>
                  <mi>N</mi>
               </mrow>
            </munderover>
            <mrow>
               <msubsup>
                  <mrow>
                     <mi>d</mi>
                  </mrow>
                  <mrow>
                     <mi>i</mi>
                  </mrow>
                  <mrow>
                     <mi>Y</mi>
                     <mi>N</mi>
                  </mrow>
               </msubsup>
               <mrow>
                  <mrow>
                     <mi mathvariant="normal">ln</mi>
                  </mrow>
                  <mo>&#8289;</mo>
                  <mrow>
                     <mfenced separators="|">
                        <mrow>
                           <mi>&Phi;</mi>
                           <mfenced separators="|">
                              <mrow>
                                 <msub>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>Z</mi>
                                          </mrow>
                                          <mrow>
                                             <mi>'</mi>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>i</mi>
                                    </mrow>
                                 </msub>
                                 <mfrac>
                                    <mrow>
                                       <mi>&beta;</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                                 <mo>-</mo>
                                 <mfrac>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>t</mi>
                                          </mrow>
                                          <mrow>
                                             <mn>1</mn>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                              </mrow>
                           </mfenced>
                           <mo>-</mo>
                           <mi>&Phi;</mi>
                           <mfenced separators="|">
                              <mrow>
                                 <msub>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>Z</mi>
                                          </mrow>
                                          <mrow>
                                             <mi>'</mi>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>i</mi>
                                    </mrow>
                                 </msub>
                                 <mfrac>
                                    <mrow>
                                       <mi>&beta;</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                                 <mo>-</mo>
                                 <mfrac>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>t</mi>
                                          </mrow>
                                          <mrow>
                                             <mn>2</mn>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                              </mrow>
                           </mfenced>
                        </mrow>
                     </mfenced>
                  </mrow>
               </mrow>
               <mo>+</mo>
               <msubsup>
                  <mrow>
                     <mi>d</mi>
                  </mrow>
                  <mrow>
                     <mi>i</mi>
                  </mrow>
                  <mrow>
                     <mi>Y</mi>
                     <mi>Y</mi>
                  </mrow>
               </msubsup>
               <mrow>
                  <mrow>
                     <mi mathvariant="normal">ln</mi>
                  </mrow>
                  <mo>&#8289;</mo>
                  <mrow>
                     <mfenced separators="|">
                        <mrow>
                           <mi>&Phi;</mi>
                           <mfenced separators="|">
                              <mrow>
                                 <msub>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>Z</mi>
                                          </mrow>
                                          <mrow>
                                             <mi>'</mi>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>i</mi>
                                    </mrow>
                                 </msub>
                                 <mfrac>
                                    <mrow>
                                       <mi>&beta;</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                                 <mo>-</mo>
                                 <mfrac>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>t</mi>
                                          </mrow>
                                          <mrow>
                                             <mn>2</mn>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                              </mrow>
                           </mfenced>
                        </mrow>
                     </mfenced>
                  </mrow>
               </mrow>
               <mo>+</mo>
               <msubsup>
                  <mrow>
                     <mi>d</mi>
                  </mrow>
                  <mrow>
                     <mi>i</mi>
                  </mrow>
                  <mrow>
                     <mi>N</mi>
                     <mi>Y</mi>
                  </mrow>
               </msubsup>
               <mrow>
                  <mrow>
                     <mi mathvariant="normal">ln</mi>
                  </mrow>
                  <mo>&#8289;</mo>
                  <mrow>
                     <mfenced separators="|">
                        <mrow>
                           <mi>&Phi;</mi>
                           <mfenced separators="|">
                              <mrow>
                                 <msub>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>Z</mi>
                                          </mrow>
                                          <mrow>
                                             <mi>'</mi>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>i</mi>
                                    </mrow>
                                 </msub>
                                 <mfrac>
                                    <mrow>
                                       <mi>&beta;</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                                 <mo>-</mo>
                                 <mfrac>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>t</mi>
                                          </mrow>
                                          <mrow>
                                             <mn>2</mn>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                              </mrow>
                           </mfenced>
                           <mo>-</mo>
                           <mi>&Phi;</mi>
                           <mfenced separators="|">
                              <mrow>
                                 <msub>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>Z</mi>
                                          </mrow>
                                          <mrow>
                                             <mi>'</mi>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>i</mi>
                                    </mrow>
                                 </msub>
                                 <mfrac>
                                    <mrow>
                                       <mi>&beta;</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                                 <mo>-</mo>
                                 <mfrac>
                                    <mrow>
                                       <msup>
                                          <mrow>
                                             <mi>t</mi>
                                          </mrow>
                                          <mrow>
                                             <mn>2</mn>
                                          </mrow>
                                       </msup>
                                    </mrow>
                                    <mrow>
                                       <mi>&sigma;</mi>
                                    </mrow>
                                 </mfrac>
                              </mrow>
                           </mfenced>
                        </mrow>
                     </mfenced>
                  </mrow>
               </mrow>
               <mo>+</mo>
               <msubsup>
                  <mrow>
                     <mi>d</mi>
                  </mrow>
                  <mrow>
                     <mi>i</mi>
                  </mrow>
                  <mrow>
                     <mi>N</mi>
                     <mi>N</mi>
                  </mrow>
               </msubsup>
               <mi>l</mi>
               <mi>n</mi>
               <mfenced separators="|">
                  <mrow>
                     <mn>1</mn>
                     <mo>-</mo>
                     <mi>&Phi;</mi>
                     <mfenced separators="|">
                        <mrow>
                           <msub>
                              <mrow>
                                 <msup>
                                    <mrow>
                                       <mi>Z</mi>
                                    </mrow>
                                    <mrow>
                                       <mi>'</mi>
                                    </mrow>
                                 </msup>
                              </mrow>
                              <mrow>
                                 <mi>i</mi>
                              </mrow>
                           </msub>
                           <mfrac>
                              <mrow>
                                 <mi>&beta;</mi>
                              </mrow>
                              <mrow>
                                 <mi>&sigma;</mi>
                              </mrow>
                           </mfrac>
                           <mo>-</mo>
                           <mfrac>
                              <mrow>
                                 <msup>
                                    <mrow>
                                       <mi>t</mi>
                                    </mrow>
                                    <mrow>
                                       <mn>2</mn>
                                    </mrow>
                                 </msup>
                              </mrow>
                              <mrow>
                                 <mi>&sigma;</mi>
                              </mrow>
                           </mfrac>
                        </mrow>
                     </mfenced>
                  </mrow>
               </mfenced>
            </mrow>
         </mrow>
      </mrow>
   </mstyle>
</math>

I am using the following MathJax configuration:

window.MathJax = {
        chtml: {
            displayOverflow: 'linebreak'
        },
        linebreaks: {                  // options for when overflow is linebreak
            inline: true,                   
            width: '100%',                 
            lineleading: 2,               
            LinebreakVisitor: null,         
        }
    }

and loading MathJax via

<script src="https://cdn.jsdelivr.net/npm/mathjax@4.0.0-beta.4/tex-mml-chtml.js"></script>

Implemented sample:

https://codepen.io/Mohammad-Shahbazi-the-styleful/pen/OJqGXmx

leberman commented 6 months ago

Update: this worked with version 2.7.8

Screenshot from 2024-02-22 21-06-00

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
        "auto-collapse": {
            disabled: false,
         },
         collapsible: {
            disabled: false,
          },
        showMathMenu: false,
        zoom: "None",
        zscale: "100%",
        texHints: true,
        jax: ["input/MathML", "output/HTML-CSS"],
        CommonHTML: {
            scale: 90,
            minScaleAdjust: 55,
            mtextFontInherit: false,
            linebreaks: {automatic: true}
        },
        Safe: {
            sizeMin: .4,
            sizeMax: 1.44
        }
    });
</script>
dpvc commented 6 months ago

Note that your math items are in-line math items because the math node does not have the display="block" attribute, so display defaults to inline. The mstyle with displaystyle="true" means that the display style rules will be used in the rendering, but it is still considered an in-line expression.

MathJax v2 did not perform in-line breaking except in limited situations, so the line-breaking you show from v2 would likely have to have been for displayed equations, not in-line ones (the equation numbers also suggest that that is the case, as in-line expressions don't get equation numbers). So I suspect the examples you have used are not actually the same in both cases.

MathJax v4 does implement in-line breaking, but note that the rules for in-line breaking are based on the TeX in-line breaking rules, which only break an expression at a top-level operator that is of class BIN or REL (a binary operator or a relational operator). Such operators must be children of the top-level math element (or of top-level mstyle or semantics elements) in order for a breakpoint to be allowed. In particular, content inside an explicit mrow element will not have in-line breaks, just as TeX will not break at operators within braces. That is, in x + {y + z} the only in-line breakpoint that can be made is at the first plus sign (the second is not valid as it is inside braces). Similarly,

<math>
  <mi>x</mi>
  <mo>+</mo>
  <mrow>
    <mi>y</mi>
    <mo>+</mo>
    <mi>z</mi>
  </mrow>
</math>

has only one valid in-line breakpoint at the first plus sign, and the second plus is not a breakpoint as it is inside an explicit mrow tag.

The expressions you point to in your screen shot all have explicit mrow elements around the complete expression, and so that prevents any inline breaks in those expressions. For example, the first one is

        <math id="mml367">
          <mstyle displaystyle="true">
            <mrow>
              <mi>A</mi>
              <mo>=</mo>
              <mi>&pi;</mi>
              <msqrt>
                <mn>1</mn>
                <mi>a</mi>
              </msqrt>
              <mo>&larr;</mo>
              <mo>&uarr;</mo>
              <mo>&rarr;</mo>
              <mo>&darr;</mo>
              <mi>&infin;</mi>
              <mo>&ne;</mo>
              <mo>&prop;</mo>
              <mo>&cong;</mo>
              <mo>&asymp;</mo>
              <mo>&equiv;</mo>
              <mo>&forall;</mo>
              <mo>&exist;</mo>
              <mi>&empty;</mi>
              <mo>&cap;</mo>
              <mo>&cup;</mo>
              <mo>&part;</mo>
              <mi>&rho;</mi>
              <mi>&phi;</mi>
              <mi>&gamma;</mi>
              <mi>&sigmaf;</mi>
              <mo>&sub;</mo>
              <mo>&sup;</mo>
              <mo>&oplus;</mo>
              <mo>&#8861;</mo>
              <mo>&otimes;</mo>
              <mi>&sigma;</mi>
              <mi>&omega;</mi>
              <mo>&ni;</mo>
              <mo>&isin;</mo>
              <mo>&#8710;</mo>
              <mi>&gamma;</mi>
              <mi>&epsilon;</mi>
              <mi>&theta;</mi>
              <mi>&tau;</mi>
            </mrow>
          </mstyle>
        </math>

which won't break, but if you remove the outer mrow, as in

        <math id="mml367">
           <mstyle displaystyle="true">
              <mi>A</mi>
              <mo>=</mo>
              <mi>&pi;</mi>
              <msqrt>
                <mn>1</mn>
                <mi>a</mi>
              </msqrt>
              <mo>&larr;</mo>
              <mo>&uarr;</mo>
              <mo>&rarr;</mo>
              <mo>&darr;</mo>
              <mi>&infin;</mi>
              <mo>&ne;</mo>
              <mo>&prop;</mo>
              <mo>&cong;</mo>
              <mo>&asymp;</mo>
              <mo>&equiv;</mo>
              <mo>&forall;</mo>
              <mo>&exist;</mo>
              <mi>&empty;</mi>
              <mo>&cap;</mo>
              <mo>&cup;</mo>
              <mo>&part;</mo>
              <mi>&rho;</mi>
              <mi>&phi;</mi>
              <mi>&gamma;</mi>
              <mi>&sigmaf;</mi>
              <mo>&sub;</mo>
              <mo>&sup;</mo>
              <mo>&oplus;</mo>
              <mo>&#8861;</mo>
              <mo>&otimes;</mo>
              <mi>&sigma;</mi>
              <mi>&omega;</mi>
              <mo>&ni;</mo>
              <mo>&isin;</mo>
              <mo>&#8710;</mo>
              <mi>&gamma;</mi>
              <mi>&epsilon;</mi>
              <mi>&theta;</mi>
              <mi>&tau;</mi>
           </mstyle>
        </math>

then line breaks are possible (try it in your codepen example).

The other expression also has mrow elements that are preventing inline breaks, but you have to remove several of them in order to get the line breaks. I will leave that to you.

Note that line breaking of displayed equations is more general, and can break inside mrow and other nested nodes. If you add display="block" indentalign="left" to the long expression you provide in your first message, then you will get line breaking within that expression without having to remove the mrow elements.

So the upshot is, this is the expected behavior for MathJax's line breaking.