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.
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:
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>
⁡
</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>
⁢
</mo><mi>
d</mi>
</mrow>
<mo>
−
</mo>
<mrow>
<mi>
b</mi><mo>
⁢
</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 〈〉
(⟨⟩
).
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 |
---|---|---|---|
… | … |
… |
Horizontal ellipsis |
⋮ | ⋮ |
⋮ |
Vertical ellipsis |
⋯ | ⋯ |
⋯ |
Midline horizontal ellipsis |
⋰ | ⋰ |
⋰ |
Up right diagonal ellipsis |
⋱ | ⋱ |
⋱ |
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.
<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>
⁣
</mo><mn>
1</mn></mrow>
</msub></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mn>
1</mn><mo>
⁣
</mo><mn>
2</mn></mrow>
</msub></mtd>
<mtd><mi>
⋯
</mi></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mn>
1</mn><mo>
⁣
</mo><mi>
n</mi></mrow>
</msub></mtd>
</mtr>
<mtr>
<mtd><msub>
<mi>
a</mi>
<mrow><mn>
2</mn><mo>
⁣
</mo><mn>
1</mn></mrow>
</msub></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mn>
2</mn><mo>
⁣
</mo><mn>
2</mn></mrow>
</msub></mtd>
<mtd><mi>
⋯
</mi></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mn>
2</mn><mo>
⁣
</mo><mi>
n</mi></mrow>
</msub></mtd>
</mtr>
<mtr>
<mtd><mi>
⋮
</mi></mtd>
<mtd><mi>
⋮
</mi></mtd>
<mtd><mi>
⋱
</mi></mtd>
<mtd><mi>
⋮
</mi></mtd>
</mtr>
<mtr>
<mtd><msub>
<mi>
a</mi>
<mrow><mi>
m</mi><mo>
⁣
</mo><mn>
1</mn></mrow>
</msub></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mi>
m</mi><mo>
⁣
</mo><mn>
2</mn></mrow>
</msub></mtd>
<mtd><mi>
⋯
</mi></mtd>
<mtd><msub>
<mi>
a</mi>
<mrow><mi>
m</mi><mo>
⁣
</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.
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>
⁢
</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>
.
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
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>
⁡
</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>
≤
</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>
>
</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>
.
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.