You’re reading Ry’s MathML Tutorial

Tables

Together with our existing elements, MathML tables open up several new layout possibilities for mathematical expressions. In this module, we’ll see how they can be used to create matrices, numbered equations, and piecewise functions.

Generic matrix with dashed lines between each cell

MathML tables work pretty much the same way native HTML tables do. In fact, they even use the same tag names, prefixed with the letter m. For example, instead of HTML’s <table> and <tr> elements, MathML uses <mtable> and <mtr>.

Matrices

Displaying matrices is one of the of the most common applications of MathML tables. Let’s start by adding the following code to our hello-mathml.html file.

<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mi>A</mi>
  <mo>=</mo>
  <mfenced open='[' close=']' separators=''>
    <mtable>
      <mtr>
        <mtd><mi>a</mi></mtd>
        <mtd><mi>b</mi></mtd>
      </mtr>
      <mtr>
        <mtd><mi>c</mi></mtd>
        <mtd><mi>d</mi></mtd>
      </mtr>
    </mtable>
  </mfenced>
</math>

The <mtable> tag begins a new MathML table, <mtr> creates a row, and <mtd> contains the column data for each row. The content inside each <mtd> should be an expression marked up with MathML tags. In this case, we just have variables marked as identifiers, which should look something like:

A=[[a,b],[c,d]]

Determinants

To create determinants, simply change the open and close attributes on the surrounding <mfenced> to a vertical bar:

<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mrow>
    <mi>det</mi>
    <mo>&ApplyFunction;</mo>
    <mfenced><mi>A</mi></mfenced>
  </mrow>
  <mo>=</mo>

  <mfenced open='|' close='|' separators=''>
    <mtable>
      <mtr>
        <mtd><mi>a</mi></mtd>
        <mtd><mi>b</mi></mtd>
      </mtr>
      <mtr>
        <mtd><mi>c</mi></mtd>
        <mtd><mi>d</mi></mtd>
      </mtr>
    </mtable>
  </mfenced>
  <mo>=</mo>

  <mrow>
    <mrow>
      <mi>a</mi><mo>&InvisibleTimes;</mo><mi>d</mi>
    </mrow>
    <mo>&minus;</mo>
    <mrow>
      <mi>b</mi><mo>&InvisibleTimes;</mo><mi>c</mi>
    </mrow>
  </mrow>
</math>

Notice how the <mfenced> brackets conveniently stretch to match the height of the table, regardless of which kind of bracket you use. This will work for any characters that are allowed to stretch vertically. The most common ones are [], ||, (), {}, and 〈〉 (&lang;&rang;).

det(A)=|[a,b],[c,d]|=ad-bc

This example also demonstrates technically accurate <mrow>’s for each operand.

Ellipsis Entities

The Calculus module introduced the midline ellipsis for use in a series, but for matrix elision, we need ellipses for all directions:

Symbol Entity Hex Description
&hellip; &#x2026; Horizontal ellipsis
&vellip; &#x22EE; Vertical ellipsis
&ctdot; &#x22EF; Midline horizontal ellipsis
&utdot; &#x22F0; Up right diagonal ellipsis
&dtdot; &#x22F1; Down right diagonal ellipsis

Remember that an ellipsis should always appear in the same kind of element it’s representing—<mn> for numbers, <mi> for variables, and <mo> for operators (though you probably won’t need the latter all that often). In the case of matrices, they should also be placed in the <mtd> where you want them to appear. For example, a generic matrix could be marked up as follows.

Box matrix with entries from a(1,1) to a(m,n)
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mi>A</mi>
  <mo>=</mo>
  <mfenced open='[' close=']' separators=''>
    <mtable>
      <mtr>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>1</mn><mo>&InvisibleComma;</mo><mn>1</mn></mrow>
        </msub></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>1</mn><mo>&InvisibleComma;</mo><mn>2</mn></mrow>
        </msub></mtd>
        <mtd><mi>&ctdot;</mi></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>1</mn><mo>&InvisibleComma;</mo><mi>n</mi></mrow>
        </msub></mtd>
      </mtr>

      <mtr>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>2</mn><mo>&InvisibleComma;</mo><mn>1</mn></mrow>
        </msub></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>2</mn><mo>&InvisibleComma;</mo><mn>2</mn></mrow>
        </msub></mtd>
        <mtd><mi>&ctdot;</mi></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mn>2</mn><mo>&InvisibleComma;</mo><mi>n</mi></mrow>
        </msub></mtd>
      </mtr>

      <mtr>
        <mtd><mi>&vellip;</mi></mtd>
        <mtd><mi>&vellip;</mi></mtd>
        <mtd><mi>&dtdot;</mi></mtd>
        <mtd><mi>&vellip;</mi></mtd>
      </mtr>

      <mtr>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mi>m</mi><mo>&InvisibleComma;</mo><mn>1</mn></mrow>
        </msub></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mi>m</mi><mo>&InvisibleComma;</mo><mn>2</mn></mrow>
        </msub></mtd>
        <mtd><mi>&ctdot;</mi></mtd>
        <mtd><msub>
          <mi>a</mi>
          <mrow><mi>m</mi><mo>&InvisibleComma;</mo><mi>n</mi></mrow>
        </msub></mtd>
      </mtr>
    </mtable>
  </mfenced>
</math>

Table Formatting

MathML table elements define several attributes for defining row and column size/alignment, but they are not fully implemented in either MathJax nor FireFox’s native MathML rendering engine. The ones that do work (at least in MathJax) are listed below.

Attribute Description
width The width of the table. Value should be a length measured in px, pt, em, etc.
side The alignment for labels (discussed in Numbered Equations). Can be left, right, leftoverlap, or rightoverlap.
frame The kind of border to add to the table. Can be none, solid, or dashed.
framespacing The space to add between each row. Value should be two lengths specifying horizontal spacing and vertical spacing (e.g., 24px 12px).
rowalign The vertical alignment of each cell with respect to other cells in the same row. Can be top, bottom, center, baseline, or axis.
rowlines The kind of border to add between each row. Can be none, solid, or dashed.
rowspacing The space to add between each row. Value should be a length.
columnalign The horizontal alignment of each cell with respect to other cells in the same column. Can be left, right, or center.
columnlines The kind of border to add between each column. Can be none, solid, or dashed.
columnspacing The space to add between each column. Value should be a length.
columnwidth The explicit width of each column. Value should be a length.
equalrows Whether each row should be the same height. Can be true or false.
equalcolumns Whether each column should be the same width. Can be true or false.

Most of these attributes are self-explanatory, so I’ll leave them for you to explore. A few of them will be demonstrated in the upcoming examples.

Nested Tables

Cutting a matrix down a row/column is a common way to create submatrices. It’s possible to draw this in MathML by combining the rowlines and columnlines attributes from the previous step with nested tables. For example, the following code splits a matrix into two identity matrices.

<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mfenced open='[' close=']' separators=''>
    <mtable columnlines='solid'>
      <mtr>
        <mtd>
          <!-- Left -->
          <mtable>
            <mtr>
              <mtd><mn>1</mn></mtd>
              <mtd><mn>0</mn></mtd>
            </mtr>
            <mtr>
              <mtd><mn>0</mn></mtd>
              <mtd><mn>1</mn></mtd>
            </mtr>
          </mtable>
        </mtd>
        <mtd>
          <!-- Right -->
          <mtable>
            <mtr>
              <mtd><mn>1</mn></mtd>
              <mtd><mn>0</mn></mtd>
            </mtr>
            <mtr>
              <mtd><mn>0</mn></mtd>
              <mtd><mn>1</mn></mtd>
            </mtr>
          </mtable>
        </mtd>
      </mtr>
    </mtable>
  </mfenced>
</math>

This should display the following if you’re using MathJax, but unfortunately, columnalign is not implemented in FireFox’s native MathML rendering engine.

[[1,0,1,0],[1,0,1,0]] split into two 2x2 identity matrices

That covers pretty much everything you’ll ever have to do with matrices in MathML. The remaining sections cover a few other applications of <mtable>.

Numbered Equations

Tables can also be used to display numbered equations. Instead of <mtr>, we can use an <mlabeledtr> tag. It’s pretty much what it sounds like—a labeled row. Its first <mtd> acts as a label, and the remaining cells are treated as if they were in a normal <mtr>.

So, to create a numbered equation, we simply put the number in the first <mtd>, like so:

<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mtable side='left'>
    <mlabeledtr>
      <mtd><mtext>(1.4)</mtext></mtd>
      <mtd>
        <mi>E</mi>
        <mo>=</mo>
        <mrow>
          <mi>m</mi>
          <mo>&InvisibleTimes;</mo>
          <msup><mi>c</mi><mn>2</mn></msup>
        </mrow>
      </mtd>
    </mlabeledtr>
  </mtable>
</math>

Notice the side attribute defining the label alignment. This should render as the following in MathJax, but, once again, FireFox’s native engine doesn’t support <mlabeledtr>.

{% figure "media/tables/numbered-equations.png" %}

If you’re using an automated numbering scheme, <mlabeledtr> is particularly useful, since your equation numbers will always be in the same place: the first child of every <mlabeledtr> element.

Piecewise Functions

f(x)=(x if x≤0) or (x^2 if x>0)

Defining piecewise functions with MathML tables is relatively straightforward: just put each function and its domain in a separate <mtr>. For example, the function above can be represented as:

<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'>
  <mrow>
    <mi>f</mi>
    <mo>&ApplyFunction;</mo>
    <mfenced><mi>x</mi></mfenced>
  </mrow>
  <mo>=</mo>
  <mfenced open='{' close='' separators=''>
    <mtable columnalign='left'>
      <mtr>
        <mtd><mi>x</mi></mtd>
        <mtd>
          <mo>if</mo>
          <mi>x</mi><mo>&le;</mo><mn>0</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <msup><mi>x</mi><mn>2</mn></msup>
        </mtd>
        <mtd>
          <mo>if</mo>
          <mi>x</mi><mo>&gt;</mo><mn>0</mn>
        </mtd>
      </mtr>
    </mtable>
  </mfenced>
</math>

First, note the columnalign attribute that makes sure the functions line up correctly. Second, you’ve probably noticed that the if statement is encoded using an <mo> element, which might be somewhat unexpected.

Remember that <mo> is designed to hold operator-like content—it’s not strictly limited to symbols like + and . Many times, it’s the most appropriate container for logical statements like if, there exists, not all, etc. We’ll look at other ways to combine text with symbols in the Advanced Formatting module.

Summary

This chapter looked at the MathML table elements, which proved very similar to the native HTML table tags. By now, you should be comfortable with <mtable>, <mtr>, <mlabeledtr>, and <mtd>.

Remember, tables are just a framework for other MathML elements. They are a generic way to control where elements appear in relation to one another, which means they can be used for much more than just matrices and numbered equations. With a bit of finagling, it’s even possible to draw worked long division problems and other elementary math exercises using <mtable>.

Long division problem showing 172/4=43

Next, the final installment of Ry’s MathML Tutorial will teach you how to integrate mathematical expressions with surrounding text. After that, you should have all the skills you need to write in-depth articles, or even books, using HTML and MathML.

Mailing List

Sign up for my low-volume mailing list to find out when new content is released. Next up is a comprehensive Swift tutorial planned for late January.

You’ll only receive emails when new tutorials are released, and your contact information will never be shared with third parties. Click here to unsubscribe.