Set background color of some equations with a style sheet?

448 views
Skip to first unread message

christoph...@gmail.com

unread,
Jan 14, 2019, 5:24:22 PM1/14/19
to MathJax Users
Good day,
I would like to highlight the most important equations in several pages for students.  Since several pages are involved, and the highlighting color may need to change, a style sheet is a good way to do this.  A starting point for doing this is to figure out how to highlight all the equations in a page.  Here is a style that works:
<style>
   .MathJax * {
       background: aqua;
   }
</style>
Here's what it looks like, so far:

MathJaxProblem.PNG


(Thanks to the wiki community for that idea.)  That gives all the equations an aqua background.  However, I'd like to add the background to just some of the equations.  One approach is to wrap only the equations to be emphasized with an <mstyle> element:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
   <mstyle class="FormatThis">
      <mrow>
         <mrow>
            <mtext>speed</mtext>
            <mo>=</mo>
            <mfrac>
               <mrow>
                  <mtext>distance</mtext>
               </mrow>
               <mrow>
                  <mtext>time</mtext>
               </mrow>
            </mfrac>
         </mrow>
      </mrow>
   </mstyle>
</math>

Then, maybe only equations containing that mstyle element could be selected.
Here's what the opening <span> containing the MathJax looks like:
<span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;><mstyle><mrow><mrow><mtext>speed</mtext><mo>=</mo><mfrac><mrow><mtext>distance</mtext></mrow><mrow><mtext>time</mtext></mrow></mfrac></mrow></mrow></mstyle></math>" role="presentation" style="text-align: center; position: relative;">
Does anyone see a way to modify the selector in the style above so that only the equations contain an mstyle element will be formatted?  A better way of doing this would probably involve adding a class, but class names seem to get stripped out of the span element attributes.
I'm using the latest version of MathJax.  The output mode is HTML-CSS.  Currently using the latest version of the Goggle Chrome browser.  The styles are in an internal style sheet, rather than in the MathJax config parameters.
Thanks!
Chris


christoph...@gmail.com

unread,
Jan 16, 2019, 3:12:30 PM1/16/19
to MathJax Users
I figured out a solution.  Here's what the output looks like:
I had three formatting tasks that needed to all be done using a style sheet. 
  1. Find a way to tag and highlight equations that are of special significance.
  2. Adjust the padding and margins of the equations.
  3. Highlight the final answer portion of an equation (for use in working out sample exercises).
The problem that had to be worked around is that class names are stripped out of the MathJax code that is generated in the browser.  A work-around is to add to the HTML tags a made-up attribute.  I enclosed the MML code to be highlighted in an mstyle tag with an attribute:  <mstyle special="MainEq">.  Unlike classes, this unknown attribute and its value get passed on to the code the browser sees.  Likewise, the tag surrounding the portion of an equation containing the answer is given an attribute, such as <mtext special="MathAns">.

The style sheet and configuration that do the job are below.  I've included styles for use with either commonHTML or HTML-CSS output.
    <style>
        /* The following two styles are for when the output is commonHTML */
        /* Highlight an entire equation if any of its elements
           contain the attribute special="MainEq" */
        span.mjx-chtml.MathJax_CHTML[data-mathml*="MainEq"] {
            background: aqua;
        }
        /* Highlight the answer part of an equation if an
           mml element contains the attribute special="MathAns" */
        span.mjx-chtml.MathJax_CHTML span[special=MathAns] {
            background: palegreen;
            padding: 0.3em 0.2em;
        }
        /* The following two styles are for when the output is HTML-CSS */
        div.MathJax_Display span.MathJax[data-mathml*="MainEq"] * {
            background: aqua;
        }
        nobr span[special=MathAns] {
            background: palegreen;
            padding: 0.3em 0.4em !important;
        }
    </style>
    <script type="text/x-mathjax-config">
        MathJax.Hub.Config({
            // These styles adjust the spacing above and below
            // all the equations on the page.  Only needed for commonHTML.
            styles: {
                "span.mjx-chtml.MJXc-display": {
                    margin: "0.1em 0em"
                },
                "span.mjx-chtml.MathJax_CHTML": {
                    padding: "0.3em",
                }
            },
            "HTML-CSS": {
                scale: 100,
                linebreaks: {automatic: true},
                styles: {
                    "div.MathJax_Display": {
                        margin: "0.1em 0em"
                    },
                    "span.math": {
                        padding: "0.3em"
                    }
                }
            },
            config: ["Safe.js"],
            errorSettings: { message: ["!"] },
            messageStyle: "normal"
        });
    </script>
    <script async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/latest.js?config=TeX-MML-AM_HTMLorMML">
        <!-- config=TeX-MML-AM_CHTML or TeX-MML-AM_HTMLorMML -->
    </script>
Below is the HTML for the two example equations shown.
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block" class="EqEmphasis">
    <mstyle special="MainEq">

        <mrow>
            <mrow>
                <mtext>speed</mtext>
                <mo>=</mo>
                <mfrac>
                    <mrow>
                        <mtext>distance</mtext>
                    </mrow>
                    <mrow>
                        <mtext>time</mtext>
                    </mrow>
                </mfrac>
            </mrow>
        </mrow>
    </mstyle>
</math>
<p>An Olympic-quality sprinter can
    run 100 m in approximately 10 s, corresponding to an average speed of

    <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
        <mrow>
            <mrow>
                <mfrac>
                    <mrow>
                        <mtext>100 m</mtext>
                    </mrow>
                    <mrow>
                        <mtext>10 s</mtext>
                    </mrow>
                </mfrac>
                <mo>=</mo>
                <mtext special="MathAns">10 m/s</mtext>
            </mrow>
        </mrow>

    </math>
</p>

Hope that helps someone else!
Chris

Davide Cervone

unread,
Jan 20, 2019, 1:13:24 PM1/20/19
to mathja...@googlegroups.com
I'd like to add the background to just some of the equations.  One approach is to wrap only the equations to be emphasized with an <mstyle> element:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
   <mstyle class="FormatThis">
      <mrow>
         <mrow>
            <mtext>speed</mtext>
            <mo>=</mo>
            <mfrac>
               <mrow>
                  <mtext>distance</mtext>
               </mrow>
               <mrow>
                  <mtext>time</mtext>
               </mrow>
            </mfrac>
         </mrow>
      </mrow>
   </mstyle>
</math>


Rather than put an element inside the math, how about wrapping the man in an element whose background you set:

<span class="math-highlight">
<math display="block">
...
</math>
</span>

and then use

.math-highlight .MathJax, .math-highlight .MathJax_CHTML {
    background-color: aqua;
    padding: .3em .4em ! important
}

to color it and give it some padding?  (Use a <div> rather than <span> around display math.)

If you must do it within the math, then you could use

<math display="block" class="math-highlight">
...
</math>

with

.math-highlight {
    background-color: aqua;
    padding: .3em .4em ! important
}

to get a similar effect.

Here's what the opening <span> containing the MathJax looks like:
<span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" data-mathml="<math xmlns=&quot;http://www.w3.org/1998/Math/MathML&quot; display=&quot;block&quot;><mstyle><mrow><mrow><mtext>speed</mtext><mo>=</mo><mfrac><mrow><mtext>distance</mtext></mrow><mrow><mtext>time</mtext></mrow></mfrac></mrow></mrow></mstyle></math>" role="presentation" style="text-align: center; position: relative;">

When I do this, the data-mathml attribute's <mstyle> DOES include the class, so I'm not sure how come yours doesn't.

A better way of doing this would probably involve adding a class, but class names seem to get stripped out of the span element attributes.

No, they don't.  For example, 

<math display="block" class="math-hilight">
  <mi class="math-x">x</mi>
</math>

produces

<div class="MathJax_Display" style="text-align: center;">
  <span class="MathJax" id="MathJax-Element-1-Frame" tabindex="0" style="text-align: center;">
    <nobr>
      <span class="math math-hilight" id="MathJax-Span-1" style="width: 0.758em; display: inline-block;">
        <span style="display: inline-block; position: relative; width: 0.584em; height: 0px; font-size: 123%;">
          <span style="position: absolute; clip: rect(1.513em, 1000.526em, 2.326em, -999.997em); top: -2.146em; left: 0em;">
            <span class="mrow" id="MathJax-Span-2">
              <span class="mi math-x" id="MathJax-Span-3" style="font-family: MathJax_Math; font-style: italic;">
              x
              </span>
            </span>
            <span style="display: inline-block; width: 0px; height: 2.152em;">
            </span>
          </span>
        </span>
        <span style="display: inline-block; overflow: hidden; vertical-align: -0.068em; border-left-width: 0px; border-left-style: solid; width: 0px; height: 0.718em;">
        </span>
      </span>
    </nobr>
  </span>
</div>

where the spans corresponding to the MathML elements containing the classes do have the appropriate classes included.

So you CAN use classes to style MathJax output.  But you should NOT use styles that change the SIZE of the math, like changes to padding, as MathJax will not know you have made those changes, and will not take that into account when it creates things like square roots, fractions, etc, that depend on the size of their content.  (CommonHTML is better than HTML-CSS at this, however.)

On the other hand, you can use MathML to do the entire thing, including the padding and coloring.  For example:

<math display="block">
  <mpadded height="+.3em" depth="+.3em" width=".8em" lspace=".4em" mathbackground="aqua">
    ...
  </mpadded>
</math>

You can do the same for internal components of the expression:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
            <mfrac>
                <mtext>100 m</mtext>
                <mtext>10 s</mtext>
            </mfrac>
            <mo>=</mo>
    <mpadded height="+.3em" depth="+.3em" width="+.8em" lspace=".4em" mathbackground="palegreen">
                <mtext>10 m/s</mtext>
            </mpadded>
</math>

This will make sure MathJax knows about the adjusted spacing, so the you can have highlighted math inside roots or in fractions, etc.

Davide

christoph...@gmail.com

unread,
Jan 24, 2019, 10:33:45 AM1/24/19
to MathJax Users
Davide,
Thanks for replying.  Your ideas for highlighting an entire equation and handling margins and padding worked very well.  I configured MathJax to use the commonHTML output.  I wrapped the block equation to be highlighted like so:
<div class="math-highlight">

   <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
      <mrow>
         .
         .
      </mrow>
   </math>
</div>

This was formatted with three styles. 
.MJXc-display {
  margin: 0.4em 0em !important;
}
.math-highlight .MJXc-display {
  margin: 0.1em 0em !important;
}
.math-highlight .MathJax_CHTML {
  padding: .3em;
  background: aqua;
}
The first sets the margins for all block equations.  The other two set the margins, padding, and highlighting for the selected equations.

Formatting just a portion of a math equation using classes didn't initially work for me because the Safe extension was loaded.  It is part of the MathJax configuration recommended by Moodle (a learning management system), so I had included it in my workspace.  By removing Safe.js from the configuration things worked as expected.  Thanks for suggesting using <mpadded>.  I used the following:
<mpadded height="+.3em" depth="+.3em" width="+.8em" lspace=".4em" class="MJX-Ans">

   <mtext>10 m/s</mtext>
</mpadded>
The class was formatted with the following:
.MJX-Ans {
  background: palegreen;
}

Though not essential, I would have liked to include the extra security that Safe provides.  It looked like class names that start with "MJX-" are supposed to be allowed with Safe running, but the class above, MJX-Ans, didn't work.  I tried configuring the Safe options with everything allowed, but that didn't work, either:
   <script type="text/x-mathjax-config">
      MathJax.Hub.Config({
         extensions: ["Safe.js"],
         Safe: {
            allow: {
            URLs: "all",
            classes: "all",
            cssIDs: "all",
            styles: "all",
            fontsize: "all",
            require: "all"

            }
         },
         errorSettings: { message: ["!"] },
         messageStyle: "normal"
      });
   </script>
(The first line, extensions: ["Safe.js"],, doesn't seem to be necessary.)
I expected that, with classes: "all", class names should be allowed and should be processed, but that doesn't seem to be the case.  This might be a bug, or (more likely) I may be missing something.
Chris

Davide Cervone

unread,
Jan 25, 2019, 9:59:47 AM1/25/19
to mathja...@googlegroups.com
Formatting just a portion of a math equation using classes didn't initially work for me because the Safe extension was loaded.
 ...
It looked like class names that start with "MJX-" are supposed to be allowed with Safe running, but the class above, MJX-Ans, didn't work. 

Classes that begin with MJX- are reserved for internal use by MathJax.  They are used by the MathML input to handle additional features that are not part of the MathML specification (e.g., the TeX input may mark some elements with classes to indicate the TeX class of an element as set by macros like \mathbin, etc.).  The MathML input jax will remove these classes when they are processed.  So while the Safe extension doesn't remove these classes, the MathML input jax does.  Classes beginning with MJX- are not intended for your own use.

You can, however, provide your own filter for the class names.  Something like

<script type="tet/x-mathjax-config">
MathJax.Hub.Register.StartupHook("Safe Extension Ready", function () {
  var FILTER = MathJax.Extension.Safe.filterClass;
  MathJax.Extension.Safe.filterClass = function (CLASS) {
    return (CLASS.match(/^MY-/) ? CLASS : FILTER.call(this, CLASS));
  };
});
</script>

should allow any class beginning with MY- to be passed through (and the MathML input jax won't remove those later).

(The first line, extensions: ["Safe.js"],, doesn't seem to be necessary.)

Unless you are loading it as part of your config= parameter on the script that loads MathJax.js itself, then yes, it should be necessary if you want the Safe extension to be loaded.

I expected that, with classes: "all", class names should be allowed and should be processed, but that doesn't seem to be the case.

They are passed through (Safe does not remove them), but the ones beginning with MJX- are processed and removed by the MathML input jax.

Davide

christoph...@gmail.com

unread,
Feb 6, 2019, 10:04:09 AM2/6/19
to MathJax Users
Davide,
Wow!  Everything is now working just like I wanted it to.  Thanks so much for your help.
Chris
Reply all
Reply to author
Forward
0 new messages