The MathML working group is planning to deprecate the <mfenced> element as well as the <mo> fence and separator attributes for use on the web. The justification is to simplify web implementations by deprecating MathML features that are redundant. This post explains how <mfenced> and the fence and separator attributes can be handled in other ways and it discusses the implications for OfficeMath.
Emulating <mfenced> with <mrow>
The MathML <mfenced> element is handy for representing a variety of delimited expressions, such as parenthesized, braced, and bracketed expressions. The expressions can contain separators. Examples are (𝑎 + 𝑏), (𝑎 + 𝑏], and the quantum mechanical expectation value ⟨𝜓|ℋ|𝜓⟩, in which the ‘|’ is a separator. The <mfenced> element corresponds quite closely to the OMML delimiters element <d> used in Office app files, which is why the OfficeMath MathML writers use it.
To show how <mfenced> can be emulated by an <mrow>, consider (𝑎 + 𝑏]. Using <mfenced>, it is represented by
<mfenced close="]">
<mi>a</mi><mo>+</mo><mi>b</mi>
</mfenced>
Since left parenthesis is the default start delimiter, the <mfenced> doesn’t need the attribute open=”(“, although it could have it. The equivalent <mrow> representation is
<mrow>
<mo>(</mo>
< mi>a</mi><mo>+</mo><mi>b</mi>
<mo>]</mo>
</mrow>
Here the <mo> fence=”true” attribute isn’t needed since the MathML operator dictionary assigns fence=”true” to parentheses, brackets, braces and other Unicode characters that are fences by default. You need the attribute fence=”false” or stretchy=”false” if you don’t want the delimiters to grow to fit their content.
Comparing these representations, we see that <mfenced> is more compact. On the other hand, the <mrow> emulation is more general in that you can include attributes like different math colors on the individual delimiters and you can embellish the delimiters with accents. If you want a delimited expression with just the open delimiter, e.g., {𝑎 + 𝑏, you omit the <mo> for the close delimiter. Similarly, a delimited expression with no open delimiter, e.g., 𝑎 + 𝑏}, omits the open delimiter. For more discussion of <mfenced> and <mrow>, see the MathML 3.0 spec.
Parsing <mrow> emulation of <mfenced>
The <mfenced> element is an example of Polish prefix notation: you know up front what kind of math object is involved. In contrast, you must parse an <mrow> emulation of <mfenced> to figure out what it represents. The parsing is a little tricky, but it’s not that hard since the delimiter roles are implied by the order in which the delimiters appear inside the <mrow>.
The basic principle is that the start and end delimiters are fences, and any delimiters in between are separators. The main OfficeMath MathML reader uses a SAX parser, which cannot look ahead. But the reader can store information for looking behind. The algorithm is: the first delimiter of an <mrow> is a start delimiter <mo> and other delimiters are marked as separators. When the parser comes to the end of the delimiter expression (</mrow>), it remarks the last delimiter as an end delimiter. If there are only two delimiters, there are no separators. If there’s only one delimiter, it’s a start delimiter unless it comes at the end. This algorithm converts <mrow> delimiter elements into the OfficeMath <d> equivalent. It will be used soon in Office apps since FireFox removed support of <mfenced> (OneNote counted on it in FireFox!) and the Chromium code base won’t support it either. Yes, Chromium will support “core” Presentation MathML. Many browsers are based on Chromium, e.g., Chrome and Edge.
Some MathML elements are “inferred mrow’s” in that they treat multiple children as a single argument and the algorithm works with them as well. Such elements include <math>, <msqrt>, <menclose>, <mphantom>, <mpadded> and <mtd>.
Poorly formed <mrow> expressions
Best practice <mrow> delimiter emulation restricts the contents of the <mrow> to the contents of the delimited expression. But what if there are other things inside an <mrow> such as in (note: <math> is an inferred <mrow>)
<math > <mo>(</mo> <mi>a</mi> <mo>+</mo> <mi>b</mi> <mo>)</mo> <mo>+</mo> <mo>|</mo> <mi>a</mi> <mo>+</mo> <mi>b</mi> <mo>|</mo> </math>
Two tricks are useful: with no form-disambiguating attribute like “form”=”prefix” on the delimiter <mo>’s (as in this example), use the default form value given in the MathML operator dictionary. This works for all default delimiter pairs, but not for ‘|’ which can be used as a separator (infix), open delimiter (prefix), or close delimiter (postfix). For ‘|’ use the algorithm above with a small twist: when there is an active ‘|’ start delimiter, treat a ‘|’ as an end delimiter. When finished processing any delimiter expression, reset the state to “no delimiters”. As such ‘|’ is alternately a start delimiter and end delimiter. This algorithm cannot produce nested absolute-value expressions. To nest an absolute value, use appropriate form attributes, or, best practice, put the absolute value in its own <mrow>.
0 comments