W3C

MathML Core

Editors' Draft

This version:
...
Editors:
David Carlisle and Frédéric Wang

Abstract

This specification defines a core subset of Mathematical Markup Language, or MathML. MathML is a markup language for describing mathematical notation and capturing both its structure and content. The goal of MathML is to enable mathematics to be served, received, and processed on the World Wide Web, just as HTML has enabled this functionality for text.

Compared with prior versions of MathML, this specification tries to be as accurate as possible on the visual rendering of mathematical formulas using additional rules from the TeXBook’s Appendix G [TeXBook] and from the Open Font Format version 3 [OpenFontFormat3]. It also focuses on compatibility with existing technologies of web rendering engines [HTML5] by relying as much as possible on CSS, text & table layout and box models.

Status of this Document

This document is an editors' copy that has no official standing.

This document is governed by the 1 March 2017 W3C Process Document.

1 Introduction

1.1 Rationale for a new version of MathML

This section is non-normative.

The [MathML3] specification has two serious shortcomings that make it hard to implement presentation MathML in web rendering engines:

  1. The MathML 3 specification intentionally does not contain any detailed rendering rules. As a consequence, the fact that web rendering engines are compliant with the MathML 3 specification does not necessarily mean that they will have the rendering quality expected by most readers. For example, the specification essentially just says that “mfrac element is used for fractions” and that the default medium linethickness “is left up to the rendering agent” [MathML3]. As a comparison, to determine the exact spacing and thickness of fractions and stacks the TeXBook’s Appendix G [TeXBook] relies on parameters σ8, σ9, ξ8, 3ξ8, 7ξ8, σ11 and σ12 while the MATH table of the Open Font Format [OpenFontFormat3] extends these to parameters FractionNumeratorDisplayStyleShiftUp, FractionNumeratorShiftUp, FractionNumeratorDisplayStyleGapMin, FractionNumeratorGapMin, FractionRuleThickness, FractionDenominatorDisplayStyleGapMin, FractionDenominatorGapMin, FractionDenominatorDisplayStyleShiftDown, FractionDenominatorShiftDown, StackTopDisplayStyleShiftUp, StackTopShiftUp, StackDisplayStyleGapMin, StackGapMin, StackBottomDisplayStyleShiftDown and StackBottomShiftDown.

  2. The MathML 3 specification is designed as an independent XML language and browser vendors have almost not been involved in the standardization process. The Math WG and WHATWG worked together to integrate MathML in [HTML5] but MathML3 has inconsistencies and lacks of details when it comes to interaction with CSS / HTML5 features: vertical writing mode, user stylesheet, mstyle inheritance, out-of-flow elements, attributes sensitiveness, definition of space characters... The MathML 3 specification is sometimes biased by MathML rendering and authoring tools behaving quite differently from web rendering engines. Hence it is not always obvious whether all features are fundamental or whether they fit well into the web rendering engine codebase. For example, the <mfenced> element is just a “convenient form in which to express common constructs involving fences” but is strictly equivalent to an expanded form with <mrow> and <mo> elements. It requires web rendering engines to create many “anonymous” rendering frames and keep them up-to-date, to duplicate the logic for drawing and exposing the content of fenced expressions etc. [MathML3].

This "MathML Core" specification intends to address these issues by being as accurate as possible on the visual rendering of mathematical formulas using additional rules from the TeXBook’s Appendix G [TeXBook] and from the Open Font Format [OpenFontFormat3]. Focus has been put on keeping compatible with existing technologies of web rendering engines [HTML5] by relying as much as possible on CSS, text & table layout and box models. As a consequence, parts of MathML 3 that do not fit well in this framework or are rarely used in practice have been ommited and moved into a larger specification [MathML4].

By increasing the level of implementation details and by focusing more on browser-driven design, this specification is expected to greatly improve MathML interoperability. A auto is available in a separate auto. Browser vendors are encouraged to use these tests during implementation & automated testing. Contribution of new tests and error reports are welcome.

1.2 Terminology

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL, are to be interpreted as described in [IETFRFC2119].

This document relies on many definitions taken from the MATH specification of the Open Font Format [OpenFontFormat3]. These values are written with the following style: This is a definition from the MATH specification.

2 Relation with other technologies

2.1 HTML5 Tree

2.1.1 DOM, HTML, SVG and Javascript

User agents must use a HTML5 [HTML5] parser to build a DOM tree [DOM1] from the source code of web pages. In particular, they must follow the rules describing when elements must be in the MathML namespace http://www.w3.org/1998/Math/MathML and must recognize the entity definitions from the HTML MathML entity set of [XMLEntities]. They must also take into account the following integration points between SVG, MathML and HTML as allowed by [ValidatorSchemas]:

  1. The <math> element can be used at any position permitted for phrasing content or inside SVG <foreignObject> elements.

  2. The <svg> element can be used inside <annotation-xml> elements with encoding SVG1.1 or image/svg+xml.

  3. The <html> element and flow content can be used inside <annotation-xml> elements with encoding application/xhtml+xml or text/html.

  4. Any phrasing element can be used inside <mtext> elements.

From this DOM tree, user agents must provide a visual representation of the document. The DOM tree may be dynamically modified using Javascript [ECMA262] and the user agents must keep the visual representation in synchronization with the DOM tree.

When evaluating the SVG requiredExtensions attribute [SVG11], user agents must claim support for the extension of name http://www.w3.org/1998/Math/MathML. An algorithm to decide the visible child of the <semantics> element is proposed in section 4.7.

2.1.2 MathML

All MathML elements accept the id, class and style attributes [MathML3]. They must be interpreted as described in section 3.2.5 of the HTML5 specification [HTML5] and in particular they specify a unique identifier (to identify elements in links and scripting), affect CSS selectors, affect getElementsByClassName() and enable authors to do inline styling.

MathML 3 allows to use the href attribute on any MathML element [MathML3]. In the present document, it is only required to implement href on the mrow element with the behavior described in 4.8 of the HTML5 specification for the a element [HTML5]. It is recommended to make links visually distinguisable by default, for example by adding a rule in the user agent stylesheet (section 2.3.2) such as

mrow[href] {
  color: blue;
}

The toplevel math element accepts the altimg, altimg-width, altimg-height, altimg-valign and alttext attributes. These attributes allow to specify fallback content and must be ignored by user agents for rendering purpose. User agents that do not follow the current implementation note, may follow implementation suggestions from Appendix auto in order to use that fallback image.

The toplevel math element also accepts the display attribute, mathcolor, mathbackground attributes as well as other attributes from the mstyle element. These attributes must be supported and this may be achieved using specific rules in the user agent stylesheet as described in section 2.3.2.

In general MathML elements or attributes that are not mentioned in this document may just be ignored. This includes deprecated attributes or Content Markup described in chapter 4 of the MathML 3 specification [MathML3].

User agents must contain an operator dictionary describing the default properties of operators. For interoperability, it is recommended to use the one proposed in the non-normative Appendix C of [MathML3].

2.2 Text and Math layout

2.2.1 Open Font Format

Because math fonts generally contain very tall glyphs such as big integrals, using typographic metrics is important to avoid excessive line spacing of text. This behavior is specified in math fonts using the USE_TYPO_METRICS flag from the OS/2 table [OpenFontFormat3] and user agents must honor that flag.

Mathematical formulas can be viewed as an extension of standard text layout and thus user agents must be able to perfom complex text layout [CTL] using fonts under the Open Font Format [OpenFontFormat3]. In particular, they must implement bidirectional rendering and shaping of Arabic scripts.

Mathematical formulas may mix standard text with other graphical outlines (e.g. fraction or top radical bars). For consistency, these outlines should be rendered the same way as normal text. In particular, user agents must be able to apply visibility and color CSS properties to them. They may also support similar CSS properties for text such as text-shadow or opacity.

Good mathematical rendering requires use of non-Unicode glyphs. Mathematical fonts may only provide these glyphs when the math script tag is enabled and so user agents must ensure that the text within MathML token elements is rendered with that script tag. Some characters like primes already have script size by default and hence would be too small when used in a script position. Hence user agents must support glyph selections via the OpenType font feature ssty (Script Style) in order to display such “prescripted” characters with the appropriate size. For bidirectional layout, Unicode defines character-level mirroring to transform a character into its mirrored form, for example U+0028 LEFT PARENTHESIS into U+0029 RIGHT PARENTHESIS. User agents must also support the OpenType font feature rtlm (Right-to-left mirrored forms) to allow glyph-level mirroring in cases where character-level is not enough [OpenFontFormat3]. At the time of writing, Unicode does not distinguish between Chancery and Spencerian style for the Unicode MATHEMATICAL SCRIPT characters. Some mathematical fonts rely on salt or ssXY properties to provide both styles. User agents may support the CSS font-variant-alternates property and corresponding OpenType font features to enable page authors to get access to these styles [CSS3Font] [OpenFontFormat3].

User agents must be able to read information from the OpenType MATH table [OpenFontFormat3]. In particular they must be able to read the values from the MathConstants subtable. They must also be able to use the MathVariants subtable to solve the following problem: given a particular default glyph shape and a certain width or height, find a variant shape glyph (or a construct created by putting several glyphs together) that has the required measurement. More information are provided in see section 4.2.3.

2.2.2 LaTeX

Mathematical rendering rules in this document are implicitly based on MathML, OpenType MATH table and the TeXBook [MathML3] [OpenFontFormat3] [TeXBook]. In this section, we describe more precisely some rules from the TeXBook.

In addition to concepts similar to MathML’s displaystyle and scriptlevel, LaTeX has a “cramped” property, which is involved in the determination of script shifts. It is initially unset on the math element and in general all the children inherits the “cramped” property from their parent. However, it is set to true in the following children:

  1. The denominator of an mfrac element. See section 4.3.2.

  2. The subscripts of the msub, msubsup, munder and munderover elements. See section 4.4.

  3. The overscript of the mover and munderover elements when it is an accent per the MathML specification. See section 4.4.

  4. The children of the msqrt and mroot elements.

To implement math spacing, the TeXBook defines eight basic types (Ord for ordinary atoms, Op for large operators, Bin for binary operations, Rel for relations, Open for opening fences, Close for closing fences, Punct for punctuations and Inner for a delimited subformula) and define an inter space for each pair of such types. In the present document, we only follow the spacing algorithm of MathML 3: by default the inter space is always zero and the spacing is produced by spacing elements like mspace, mphantom or mpadded or by the leading and trailing space around embellished operators.

2.3 CSS Styling

2.3.1 Properties

User agents must support the CSS language [CSS2] and must take special styling into account when building the visual representation of the document. Many of the MathML elements accept attributes with length value whose general syntax is described in section 2.1.5.2 of the MathML specification [MathML3]. In general, the syntax is compatible with [CSS2] but user agents must handle specificities of the MathML specification. In particular, the keywords veryverythinmathspace, verythinmathspace, thinmathspace, mediummathspace, thickmathspace, verythickmathspace, veryverythickmathspace, negativeveryverythinmathspace, negativeverythinmathspace, negativethinmathspace, negativemediummathspace, negativethickmathspace, negativeverythickmathspace and negativeveryverythickmathspace must be interpreted as their equivalent em value. Also, percent values must be interpreted with respect to the appropriate reference value. Note that the mpadded element also accepts more general length values as discussed in section 4.3.6.

User agents must support at least the following properties:

  1. display: at least inline, block, inline-table, table-row, table-cell and none. It is used for the math and tabular elements. Appropriate values may be specified in the user agent stylesheet as described in section 2.3.2.

  2. direction. The dir attribute on the math, mstyle, mrow and token elements must be mapped to that property.

  3. font property and its shorthands. The mathsize attribute on the math, mstyle and token elements must mapped to that property.

  4. background and color. The mathcolor and mathbackground attributes on presentation MathML elements must be mapped to these properties.

  5. visibility. It is is used for the mphantom element and may be specified in the user agent stylesheet as described in section 2.3.2.

User agents must support the displaystyle attribute. This may be implemented using a new mathml-math-style property described in table 2.3.1. The expected behavior may be completely specified in the user agent stylesheet as described in section 2.3.2.

User agents must support the mathvariant attribute. This may be implemented using a new mathml-math-variant property described in table Unknown Reference. The expected behavior may be implemented by mapping mathvariant attributes on the math, mstyle and token elements to mathml-math-variant. Then during the rendering of text nodes, the mathml-math-variant value must be taken into account to remap some characters to their equivalent code points, as specified by the MathML specification. However, as indicated in section 2.2.2, when mathml-math-variant is none on an mi element with a single character, it must actually be treated as if the mathvariant was italic.

User agents must implement the scriptlevel attributes and support automatic incrementation of the scriptlevel described in the MathML specification.

TODO: Rewrite this using https://github.com/mathml-refresh/mathml-css-proposals#mathml-css-proposals

2.3.2 User Agent Stylesheet for MathML

Because mathematical formulas are generally written with special fonts, the default user agent stylesheet must reset the CSS font-family on the math element to serif. User agents should then use their own mechanism to try and interpret this serif value on the math element as a font with an OpenType MATH table.

Below is an example on a stylesheet to style MathML elements on which the User Agents may rely. Unfortunately, some rendering engines do not allow universal selectors in their user agent stylesheets and so rules must be expanded to list all possible MathML elements described in the present document. For example mfrac > * can be converted into mfrac > mi, mfrac > mn, mfrac > mo, mfrac > mtext, mfrac > mspace, mfrac > ms, mfrac > mrow, mfrac > mfrac, mfrac > msqrt, mfrac > mroot, mfrac > mstyle, mfrac > merror, mfrac > mpadded, mfrac > mphantom, mfrac > menclose, mfrac > msub, mfrac > msubsup, mfrac > munder, mfrac > mover, mfrac > munderover, mfrac > mmultiscripts, mfrac > mtable, mfrac > maction.

@namespace url(http://www.w3.org/1998/Math/MathML);
/* The <math> element */
math {
  direction: ltr;
  display: inline;
  font-size: inherit;
  font-style: normal;
  font-family: serif;
  mathml-math-style: inline;
}
math[display="block"] {
  display: block;
  text-align: center;
  mathml-math-style: display;
}
math[display="inline"] {
  display: inline;
  mathml-math-style: inline;
}
math[displaystyle="false"] {
  mathml-math-style: inline;
}
math[displaystyle="true"] {
  mathml-math-style: display;
}
/* Links */
mrow[href] {
  color: blue;
}
/* Tabular elements */
mtable {
  display: inline-table;
  mathml-math-style: inline;
}
mtable[displaystyle="true"] {
  mathml-math-style: display;
}
mtable[frame="none"] {
  border: none;
}
mtable[frame="solid"] {
  border: solid thin;
}
mtable[frame="dashed"] {
  border: dashed thin;
}
mtr, mlabeledtr {
  display: table-row;
  vertical-align: baseline;
}
mlabeledtr > mtd:first-child {
  display: none;
}
mtd {
  display: table-cell;
  vertical-align: inherit;
  text-align: center;
  padding: 0.5ex 0.4em;
}
/* The <ms> element */
ms {
  display: inline;
}
ms:before, ms:after {
  content: "\0022"
}
ms[lquote]:before {
  content: attr(lquote)
}
ms[rquote]:after {
  content: attr(rquote)
}
/*  The <merror> element */
merror {
 outline: solid thin red;
 background-color: lightYellow;
}
/* The <mphantom> element */
mphantom {
  visibility: hidden;
}
/* Scriptlevel and displaystyle for other elements */
mstyle[displaystyle="false"] {
  mathml-math-style: inline;
}
mstyle[displaystyle="true"] {
  mathml-math-style: display;
}
mfrac > * {
  mathml-script-level: auto;
  mathml-math-style: inline;
}
mroot > :not(:first-child) {
  mathml-script-level: increment-by 2;
  mathml-math-style: inline;
}
msub > :not(:first-child),
msup > :not(:first-child),
msubsup > :not(:first-child),
mmultiscripts > :not(:first-child) {
  mathml-script-level: increment-by 1;
  mathml-math-style: inline;
}
munder > :not(:first-child),
mover > :not(:first-child),
munderover > :not(:first-child) {
  mathml-math-style: inline;
}

3 MathML Core Attribute Syntax

Several MathML elements have attributes sharing common syntax for constructs such as 3.1 or color. the syntax for these attributes is defined below.

3.1 Length

MathML Core attributes of type length must have value consisting of an optional U+002D HYPHEN-MINUS (-) followed by a string of characters representing a length or percentage as specifed by HTML5 percentages and lengths.

3.2 Color

MathML Core attributes of type color must have value consisting of a string of characters representing a color as specified by HTML5 color.

4 Presentation Markup

4.1 Introduction

4.1.1 Box Model

User agents must also follow the rules described in section 4.7.14 Embedded content, MathML of [HTML5], in particular the equivalence with implicit mtext and merror to handle non-conforming MathML markup.

MathML elements have the following box model. The <math> root may have inline or block display, as suggested in section 2.3.2. Tabular MathML elements have table, table-row and table-cell display as discussed in section 4.5. The <math> and <mtd> elements generate an anonymous <mrow> MathML box child that contains the boxes of their children and use the box parameters below to layout this anonymous <mrow> box. No line breaking can happen within MathML boxes and the min-content width is equal to the max-content width, these are simply called the intrinsic width. Each MathML box has the following parameters:

  1. intrinsic width W.

  2. logical width w, ascent above the origin a and descent below the origin b. The height is then a + b.

  3. ink ascent A and descent B, corresponding to the exact box enclosing ink of text and bars within the MathML box.

x y ( x 1 , y 1 ) w 1 = W 1 A 1 B 1 a 1 b 1 ( x 2 , y 2 ) w 2 = W 2 A 2 B 2 a 2 b 2
Figure 1: Generic Box Model for MathML elements

For MathML element containing only text nodes or foreign elements, we assume that the content is simple enough to determine these values. For example, in most case, this is just a single text node and w = W. A MathML element containing only other MathML elements follow special rules to layout their children at position (xi, yi) with parameters Wi, wi, ai, bi, Ai, Bi. Then as a general rule, its box parameters are given by taking the union of child boxes, that is:

w = max1 ≤ i ≤ n (xi + wi) − max1 ≤ i ≤ n xi

W = max1 ≤ i ≤ n (xi + Wi) − max1 ≤ i ≤ n xi

a = max1 ≤ i ≤ n (ai − yi)

b = max1 ≤ i ≤ n (bi + yi)

A = max1 ≤ i ≤ n (Ai − yi)

B = max1 ≤ i ≤ n (Bi + yi)

Note that the schemas in this document are drawn assuming left-to-right directionality. If the CSS direction is set to right-to-left, then the elements should be layout by making the x-axis pointing from right-to-left. In this document, we use the terminology of [MathML3]: “leading” means “left” in right-to-left and “right” in right-to-left mode, while “trailing” means “right” in right-to-left and “left” in right-to-left mode.

The MathItalicsCorrectionInfo table contains the italic correction of some glyphs, which provides a measure of how slanted the glyphs are (see figure 2). The MathTopAccentAttachment table also contains a reference points that is used for the horizontal positioning of glyphs as an accent (see figure 3). In later sections, we generalize this by claiming that all MathML boxes have italic correction and top accent attachment values. The values for glyphs are used to try and extend to token elements or to special boxes that do not change child metrics. Otherwise fallback values are used: 0 for italic correction and half the width of the box for top accent attachment.

Italic Correction Bounding Bo x Italic Correction Bounding Bo x
Figure 2: Examples of italic correction for italic f and large integral
T op Accen t A ttac hmen t
Figure 3: Example of top accent attachment for a circumflex accent

The present document assumes that W, w, a, b, A, B, italic correction and top accent attachment are nonnegative values. If computations result in negative values, then they must be interpreted as being zero. Note that some MathML elements such as mspace or mpadded may set box dimensions to negative values.

4.1.2 Layout Steps

For compatibility with HTML5 rendering, the MathML layout is performed in two independent steps:

  1. In the first step, we determine the intrinsic width W of MathML boxes. To do so we just follow the description given in this document for each MathML box. We rely on vertical positions x as well as values for italic correction and top accent attachment. However, we ignore any vertical positioning or metrics.

  2. In the second step, we do the final layout of MathML boxes following the description given in this document. We obtain all the box metrics, including the actual width w, vertical metrics a, b, A, B and vertical positions y.

In order to perform the first step independently of the second one, the horizontal metrics must not depend on the vertical metrics. As described in section 4.3.6, this adds some restrictions on the possible pseudo-units of the mpadded element. As indicated in section 4.2.3, the width of size variants or of the glyph assembly used for vertical stretchy operators may depend on the target size to cover. Taking the maximum widths for all these size variants or for the glyph assembly during the first step makes the intrinsic width independent of the target size but may lead to a small over-estimation.

Each of this step is done recursively: the metrics of a given MathML box are determined from those of the child boxes. User agents must implement the “Exception for embellished operators” described in [MathML3]. This means that the actual stretching of operators described in section 4.2.3 may be “delayed” until we reach the top of its embellished operator subtree. We then have to apply the current operation again to this embellished operator (intrinsic width determination or layout). Fortunately, such embellished operator subtrees are not deep in practice.

This document does not require support for operator stretching in table cells. The “delayed” stretching of all operators must then be performed when we arrive at the anonymous <mrow> child of <math> and <mtd> elements. That way, the intrinsic width of this anonymous <mrow> is well-defined for the layout of mtable elements and of the containers of the <math> element. Similarly, the final layout of this anonymous <mrow> is already done when we want to perform the one of its ancestors.

4.2 Token Elements

4.2.1 Identifier <mi>

An mi element represents a symbolic name or arbitrary text that should be rendered as an identifier. Identifiers can include variables, function names, and symbolic constants.

In general, the mi element must be treated the same as the mtext element. However, when the mathvariant on an mi element is none and the mi content is made of a single character then the element must behave as if mathvariant was actually set to italic.

4.2.2 Number <mn>

An mn element represents a "numeric literal" or other data that should be rendered as a numeric literal. Generally speaking, a numeric literal is a sequence of digits, perhaps including a decimal point, representing an unsigned integer or real number.

For the layout algorithm described in this document, the mn element must be treated the same as the mtext element.

4.2.3 Operator, Fence, Separator or Accent <mo>

An mo element represents an operator or anything that should be rendered as an operator. In general, the notational conventions for mathematical operators are quite complicated, and therefore MathML provides a relatively sophisticated mechanism for specifying the rendering behavior of an mo element. As a consequence, in MathML the list of things that should "render as an operator" includes a number of notations that are not mathematical operators in the ordinary sense. Besides ordinary operators with infix, prefix, or postfix forms, these include fence characters such as braces, parentheses, and "absolute value" bars; separators such as comma and semicolon; and mathematical accents such as a bar or tilde over a symbol. We will use the term "operator" in this chapter to refer to operators in this broad sense.

Many properties of an mo element can be specified via attribute on that element. The default value of the form of an mo element is obtained as described in section “Default value of the form attribute” of [MathML3]. From the form and the text content, we can deduce other default values from the operator dictionary or use the fallback values given in “Dictionary-based attributes” of [MathML3].

The leading space lspace and trailing space rspace must be added on each side of the mo element (or its outermost embellished ancestor).

In most cases, the mo element is treated as an mtext element. However, when an mo element with a single character must be displayed as a large operator then instead we use the MathVariants table to try and find a glyph of height at least DisplayOperatorMinHeight (figure 4). If none is found, we fallback to the largest one. Because this parameter does not always give the best size, user agents may also use the following heuristic: ensure that the large variant height is at least 2 times as large as the base height for integrals and √2 times as large as the base height for other operators.

Base Heigh t Large V arian t Heigh t
Figure 4: Base and displaystyle sizes of the summation symbol

When an mo element with a single character must be displayed as a horizontal or vertical operator then instead of displaying the normal character we use the MathVariants table to try and find a glyph that has at least the desired size or an assembly from several glyphs to cover at least the desired size (figure 5). The rules for vertical stretching are a bit more complicated and are described in section “Vertical Stretching Rules” of [MathML3]. If the operator has property symmetric="true", it must be stretched symmetrically with respect to the math axis, which is given by the AxisHeight value. Figure 6 compares the symmetric and non-symmetric stretching.

The size variant or construction used for vertical stretchy operators will depend on the target size to cover. To determine the intrinsic width W of the operator, we consider the maximum of all possible widths for the base size, size variants and construction available for the given operator. It is assumed that the width of the operator is almost independent of the stretch size, which is the case in practice for most math fonts and operators.

Base Size Size V arian ts Glyph Assem bly
Figure 5: Base size, size variants and glyph assembly for the left brace
Non-symmetric Heigh t Depth Symmetric Heigh t Depth Non-stretc h y MaxHeigh t MaxDepth Baseline Axis Heigh t
Figure 6: Symmetric and non-symmetric stretching of vertical operators

See section 4.3.1 for details about how to treat “embellished ancestor”, and how decide when to display operators larger or when to stretch them vertically & horizontally.

4.2.4 Text <mtext>

An mtext element is used to represent arbitrary text that should be rendered as itself. In general, the mtext element is intended to denote commentary text.

In most cases the <mtext> element contains some text that is laid out without line breaks using complex text layout [CTL]. It is assumed that we can measure the ink ascent & descent, logical ascent & descent and advance width of the text frame and use these values for the MathML box of the <mtext> element.

If the trailing glyph of the text content has an entry in the MathItalicsCorrectionInfo table then the specified value is used as the italic correction. User agents may subtract the advance width from the abscissa of the trailing ink edge as a heuristic value for the italic correction of the <mtext> element when it is not specified in the MathItalicsCorrectionInfo table.

If the text content is made of a single glyph and this glyph has an entry in the MathTopAccentAttachment table then the specified value is used as the top accent attachment of the <mtext> element.

If the CSS direction on the <mtext> element is set to right-to-left then user agents must enable the rtlm OpenType feature on text nodes unless it contradicts what the page author has specified with the font-feature-settings CSS property.

If <mtext> is used at a non-zero scriptlevel then user agents must enable the ssty OpenType feature on text nodes unless it contradicts what the page author has specified with the font-feature-settings CSS property.

In the most general case, the <mtext> element may contain text with line breaks or arbitrary HTML5 phrasing elements. We assume that we can still determine logical dimensions and max-content width of the text content and use it for both the logical and ink values of the <mtext> element. The italic correction and top accent attachment are assigned the fallback values indicated in section 4.1.1

4.2.5 Space <mspace/>

An mspace empty element represents a blank space of any desired size, as set by its attributes.

The mspace element is laid out as shown on figure 7. The logical box is determined by the height, depth and width attributes defined in [MathML3]. The ink box matches the logical box. The linebreak attribute on the <mspace/> element must be ignored.

Width Heigh t Depth
Figure 7: Box model for the mspace element

4.2.6 String Literal <ms>

The ms element is used to represent "string literals" in expressions meant to be interpreted by computer algebra systems or other systems containing "programming languages".

In general, ms must be treated the same as the mtext element except that quotes are automatically added around its content. The user agents may implement the lquote or rquote attributes with the following style in the user agent stylesheet as suggested in section 2.3.2:

ms {
  display: inline;
}
ms:before, ms:after {
  content: "\0022"
}
ms[lquote]:before {
  content: attr(lquote)
}
ms[rquote]:after {
  content: attr(rquote)
}

4.3 General Layout Schemata

4.3.1 Horizontally Group Sub-Expressions <mrow>

An mrow element is used to group together any number of sub-expressions, usually consisting of one or more mo elements acting as "operators" on one or more other expressions that are their "operands".

The dir attribute must be mapped to the direction CSS property. The current version of this document does not define any linebreaking algorithm for the mrow element, user agents may just ignore linebreaking rules.

User agents must follow the rules for inferred mrows described in [MathML3]. For example, to layout <msqrt>child_1 child_2 child_3 ...</msqrt>, one must follow the layout rules described for msqrt in section 4.3.3 using the box of <mrow>child_1 child_2 child_3 ... child_N</mrow> as the base.

The <mrow>child_1 child_2 child_3 ... child_N</mrow> element is laid out as show on figure 8. The boxes of child1, child2, … childN are put in a horizontal row one after the other with all their baselines aligned. As a consequence of this and of child box models, graphical elements such as fraction bars or symmetric stretchy operators will also be aligned along the math axis when the AxisHeight is unchanged (e.g. in the typical case where the math font is unchanged).

As indicated in section auto, we generally do not add special spacing around the children. For example, the leading and trailing spacing is already included in the box metrics of embellished operators. The only exception is for the italic correction: when a “slanted” child is followed by a “straight” child, then an horizontal space corresponding to the italic correction of the “slanted” child is added between the two children [OpenFontFormat3]. The italic correction of the last child is also added after that child when it is “slanted” and when the mrow has more than one child. In this document, we interpret “slanted” as a child that is not an operator with largeop="true" (or an embellished operator whose mo element core has largeop="true") and has nonzero italic correction and “straight” as “non-slanted”.

When the mrow element contains only one child then the previous description implies that the box metrics of the mrow is the same as the one of its unique child. As indicated in section 4.1.1, we thus use the italic correction and top accent attachment of the child as the corresponding values of the mrow box.

c hild 1 c hild 2 c hild 3 Leading Space T railing Space c hild 5 Italic Correction c hild 7 c hild 8
Figure 8: Box model for the mrow element

4.3.2 Fractions <mfrac>

The mfrac element is used for fractions. It can also be used to mark up fraction-like objects such as binomial coefficients and Legendre symbols. The syntax for mfrac is
<mfrac> numerator denominator </mfrac>

The displaystyle and scriptlevel changes be achieved with the following style in the user agent stylesheet as suggested in section 2.3.2:

mfrac > * {
  mathml-script-level: auto;
  mathml-math-style: inline;
}

The axis of the mfrac element is always given by AxisHeight.

The default line thickness is given by FractionRuleThickness Use the linethickness attribute [MathML3] to determine the actual thickness of the fraction bar. A percent or unitless length is interpreted as a multiple of the default rule thickness. The color and visibility of the fraction bar must honor the values given by the color and visibility CSS properties on the mfrac element.

If the actual line thickness is nonzero, the mfrac element is laid out as shown on figure 9. The width is given by the maximum width of the numerator and denominator and the numerator and denominator are horizontally centered. A fraction bar with the actual thickness is drawn centered on the axis height. The numerator and denominator are shifted up and down using the values FractionNumeratorShiftUp, FractionDenominatorShiftDown in inline style and FractionNumeratorDisplayStyleShiftUp, FractionDenominatorDisplayStyleShiftDown in display style. If necessary, these shift values are increased to ensure that the gaps between the numerator/denominator and fraction bar satisfy the minimal values provided by FractionDenominatorGapMin and FractionNumeratorGapMin in inline style and FractionDenominatorDisplayStyleGapMin and FractionNumeratorDisplayStyleGapMin in display style.

Axis Heigh t Actual Linethic kness Numerator Shift Denominator Shift Numerator Gap Denominator Gap
Figure 9: Box model for the mfrac element

If the actual line thickness is zero, the mfrac element is instead laid out as shown on figure 10. The gap between the top and bottom boxes is equally split around the axis height. The relevant shift values are now StackTopShiftUp, StackBottomShiftDown in inline style and StackTopDisplayStyleShiftUp, StackBottomDisplayStyleShiftDown in display style. If necessary, the two shift values are increased by a same value to ensure the gap between the top and bottom boxes satisfy the values provided by by StackGapMin in inline style and StackDisplayStyleGapMin in display style.

Axis Heigh t Stac k T op Shift Stac k Bottom Shift Stac k Gap
Figure 10: Box model for the mfrac element without bar

In order to prevent the fraction bar to be confused with other items around the fraction (e.g. minus sign or the bar of another fraction), a 1 pixel space must actually be added on each side of the mfrac element.

If the numerator is an embellished operator and the mfrac element is the outermost element in this embellished operator hierarchy then the operator leading and trailing spaces must be added around the fraction.

4.3.3 Radicals <msqrt>, <mroot>

The MathML specification describes radicals as follows [MathML3]:

These elements construct radicals. The msqrt element is used for square roots, while the mroot element is used to draw radicals with indices, e.g. a cube root. The syntax for these elements is:
<msqrt> base </msqrt>
<mroot> base index </mroot>

The displaystyle and scriptlevel changes be achieved with the following style in the user agent stylesheet as suggested in section 2.3.2:

mroot > :not(:first-child) {
  mathml-script-level: increment 2;
  mathml-math-style: inline;
}

The line thickness of the overbar is given by RadicalRuleThickness. The gap between the overbar and base is given by RadicalVerticalGap in inline style and RadicalDisplayStyleVerticalGap in display style. The ascent above the overbase is given by RadicalExtraAscender. The surd is drawn by trying to vertically stretch the character U+221A SQUARE ROOT to at least the sum of the ink height of the base, the radical gap and the radical rule thickness. If the CSS direction is set to right-to-left, then the surd is actually drawn from the glyph obtained by mirroring U+221A SQUARE ROOT via the rtlm OpenType feature. The color and visibility of the surd and overbar must honor the values given by the color and visibility CSS properties on the msqrt element.

The msqrt element is laid out as shown on figure 11. The width is given by the sum of the width of the surd and of the base. The baseline of the square root matches the baseline of the base. The ink box is determined from the ink boxes of the surd and base while the logical box takes into account the extra ascender

Radical Extra Ascender Radical Rule Thic kness Radical Gap
Figure 11: Box model for the msqrt element

The mroot element is laid out as shown on figure 12. We start by ignoring the root index and we layout the base and surd as shown on figure 11 to obtain a box B. The horizontal metrics of the mroot element are obtained by putting RadicalKernBeforeDegree before the root index, then placing the root index, then a kerning of RadicalKernAfterDegree after the root index and finally placing B. In general the kerning before the root index is positive while the kerning after it is negative, which means that the root element will have some space before it and that the root index will overlap the surd. For the vertical metrics of the mroot element, we first take the baseline of B as the baseline. We graduate the ink height of B with a linear scale going from the bottom at coordinate 0 to the top at coordinate 1. Then the ink bottom of the root index will be vertically positioned at coordinate RadicalDegreeBottomRaisePercent. Finally, we take into consideration the box of the root index and B to deduce the metrics for the whole box of the mroot element.

Bottom (0%) Radical Degree Bottom Raise P ercen t T op (100%) Radical Kerning Before Degree Radical Kerning After Degree
Figure 12: Box model for the mroot element

4.3.4 Style Change <mstyle>

The mstyle element is used to make style changes that affect the rendering of its contents.

For the layout algorithm described in this document, the mstyle element must be treated the same as the mrow element. However, some attributes on the mstyle element must be mapped to CSS properties as indicated in section 2.3.1. All the other mstyle attributes not defined in this document must be ignored.

4.3.5 Error Message <merror>

The merror element displays its contents as an ”error message”. This might be done, for example, by displaying the contents in red, flashing the contents, or changing the background color.

For the layout algorithm described in this document, the merror element must be treated the same as the mrow element. The user agent stylesheet must set some CSS properties on the merror element in order to highlight the error. As suggested in section 2.3.2, this can for example be achieved with the rule:

merror {
  outline: solid thin red;
  background-color: lightYellow;
}

4.3.6 Adjust Space Around Content <mpadded>

An mpadded element renders the same as its child content, but with the size of the child’s bounding box and the relative positioning point of its content modified according to mpadded’s attributes.

See [MathML3] for how the metrics of mpadded element are determined. Note that pseudo-units allows horizontal metrics to depend on vertical metrics, for example width="2height" which can be problematic to determine intrinsic widths. Hence in the present document, if the value of the width and lspace attributes contains ”height” or ”depth” pseudo-units, then they must be ignored.

The mpadded element is laid out as shown on figure 13. The height, depth and width of the content in [MathML3] corresponds to the logical box of the content. The content of the mpadded element is positioned from the origin of the mpadded element as follows: We shift the content forward by a distance of lspace and shift it upward by a distance of voffset. The logical metrics of the mpadded element are given by the height, depth and width of the mpadded element described in [MathML3]. The ink metrics of the mpadded element match their logical metrics.

Con ten t Width Con ten t Heigh t Con ten t Depth Width Heigh t Depth Lspace V offset
Figure 13: Box model for the mpadded element

4.3.7 Making Sub-Expressions Invisible <mphantom>

The mphantom element renders invisibly, but with the same size and other dimensions, including baseline position, that its contents would have if they were rendered normally.

For the layout algorithm described in this document, the mphantom element must be treated the same as the mrow element. The user agent stylesheet must set some CSS properties on the mphantom element in order to hide its content. As suggested in section 2.3.2, this can for example be achieved with the rule:

mphantom {
  visibility: hidden;
}

4.3.8 Enclose Expression Inside Notation <menclose>

The menclose element renders its content inside the enclosing notation specified by its notation attribute.

The color and visibility of the menclose notations must honor the values given by the color and visibility CSS properties on the menclose element.

Based on [OpenFontFormat3] [TeXBook], we use the notation ξ8 from the TeXBook to denote the default rule thickness and use 3ξ8 for gaps. We actually let ξ8 be OverbarRuleThickness. Note that contrary to what is done in general and unless specified otherwise, the x-axis direction of notations is assumed to be independent of the CSS direction. In order to determine the metrics of the menclose notation, we compute each notation individually and take the union of the metrics:

  1. The left notation is drawn by putting a vertical bar of thickness ξ8 on the left of the content of the menclose element. The length of the bar is obtained by extending the height of the content with OverbarVerticalGap plus OverbarRuleThickness above and UnderbarVerticalGap plus UnderbarRuleThickness below. The gap between the bar and the content is 3ξ8. The logical box is obtained by adding some space of width ξ8 on the left of the bar. See figure 14.

    Con ten t Width Con ten t Heigh t Con ten t Depth Width Heigh t Depth Lspace V offset
    Figure 14: Box model for the left notation of the menclose element
  2. The right notation is drawn the same as the left notation, but with the vertical bar placed on the right.

  3. The top notation is drawn by putting an overbar of thickness OverbarRuleThickness over the content of the menclose element. The length of the bar is obtained by extending the width of the content with 4ξ8 on each side. The gap between the overbar and the content is OverbarVerticalGap. The logical box is obtained by adding some space of height OverbarExtraAscender above the bar. See figure 15.

    Ov erbar V ertical Gap Ov erbar Rule Thic kness Ov erbar Extra Ascender 4 ξ 8 4 ξ 8
    Figure 15: Box model for the top notation of the menclose element
  4. The bottom notation is drawn the same as the top notation, but with the vertical bar placed below the content and using parameters UnderbarRuleThickness, UnderbarVerticalGap. and UnderExtraDescender.

  5. The box notation is treated as equivalent to left right top bottom.

  6. To draw the roundedbox notation, we consider the box obtained by expanding the ink box by 7ξ8 / 2 on each side. Using SVG terminology, we draw a rounded rectangle on this expanded box with parameters rx, ry and stroke-width set to 3ξ8 [SVG11]. To obtain the logical box we again add a space of ξ8 on each side of the ink box. See figure 16.

    3 ξ 8 ξ 8 ξ 8 3 ξ 8 ξ 8 ξ 8 3 ξ 8
    Figure 16: Box model for the roundedbox notation of the menclose element
  7. The actuarial notation is treated as equivalent to right top.

  8. The madruwb notation is treated as equivalent to right bottom.

  9. The horizontalstrike notation is drawn with an horizontal bar of thickness ξ8 and vertically centered inside the menclose content. This does not change the box metrics. See figure 17.

    ξ 8
    Figure 17: Box model for the horizontalstrike notation of the menclose element
  10. The verticalstrike notation is drawn the same as horizontalstrike but with a vertical bar of thickness ξ8 and horizontally centered inside the menclose content.

  11. The updiagonalstrike notation is drawn with a line of thickness ξ8 going from the bottom left corner of the menclose content to its top right corner. Using SVG terminology, the stroke-linecap of the line is butt [SVG11]. As an approximation, the ink box is set equal to the logical box and obtained by increasing the original box from each side by ξ8 / 2. See figure 18.

    ξ 8 ξ 8 2 ξ 8 2
    Figure 18: Box model for the updiagonalstrike notation of the menclose element
  12. The downdiagonalstrike notation is drawn as an updiagonalstrike but the line strike goes from the top left corner to the bottom right corner. Using SVG terminology, the stroke-linecap of the line is butt [SVG11].

  13. The longdiv notation is drawn similarly to the msqrt element (figure 11). It is independent of CSS direction and U+221A SQUARE ROOT is replaced with U+0029 RIGHT PARENTHESIS. The rule thickness is ξ8, the gap between content and overbar is 3ξ8 and the extra ascender is ξ8.

  14. To draw the circle notation, we first consider the ink box of width w and height h. We draw the ellipse of axes the axes of symmetry of this ink box, of radii w * √2 / 2 and h * √2 / 2 and of thickness ξ8. We ensure that the logical box also has space ξ8 around each side of the ellipse ink box.

    ξ 8 ξ 8 Heigh t 2 Heigh t
    Figure 19: Box model for the circle notation of the menclose element
  15. This document does define any layout algorithm for other menclose notations. User agents may ignore them.

Authors are encouraged to use the msqrt element to represent square roots instead of relying on the radical notation of the menclose element.

4.4 Script and Limit Schemata

4.4.1 Subscripts and Superscripts <msub>, <msup>, <msubsup>

The msub element attaches a subscript to a base using the syntax
<msub> base subscript </msub>

The msup element attaches a superscript to a base using the syntax
<msup> base superscript </msup>

The msubsup element is used to attach both a subscript and superscript to a base expression.
<msubsup> base subscript superscript </msubsup>

As suggested in section section 2.3.2, the displaystyle and scriptlevel changes be achieved with the following style in the user agent stylesheet:

msub > :not(:first-child),
msup > :not(:first-child),
msubsup > :not(:first-child) {
  mathml-script-level: increment 1;
  mathml-math-style: inline;
}

The msub element is laid out as shown on figure 20. The baseline is the baseline of the base while the baseline of the script is shifted down by SubShift, which is the minimal value honoring the following conditions:

  1. SubShift is at least SubscriptShiftDown.

  2. The top of the subscript SubTop with respect to the baseline is not above SubscriptTopMax.

  3. The drop SubscriptBaselineDrop from the bottom of the base to the baseline of the script is at least SubscriptBaselineDropMin.

When determining the logical box, a space of width SpaceAfterScript is added after the subscript. By default, the leading edge of the subscript is aligned with the trailing edge of the base. However, if the base is an operator with largeop="true" (or an embellished operator whose mo element core has largeop="true") the subscript is horizontally shifted backward by the italic correction of the base.

SubShift LargeOpItalicCorrection SubT op SpaceAfterScript SubscriptBaselineDrop
Figure 20: Box model for the msub element

The msup element is laid out as shown on figure 21. The baseline is the baseline of the base while the baseline of the script is shifted up by SuperShift, which is the minimal value honoring the following conditions:

  1. SuperShift is at least SuperscriptShiftUpCramped if the msup element is cramped (section auto) or at least SuperscriptShiftUp otherwise.

  2. The bottom of the superscript SuperBottom with respect to the baseline is not below SuperscriptBottomMin.

  3. The drop SuperscriptBaselineDrop from the top of the base to the baseline of the script is at most SuperscriptBaselineDropMax.

When determining the logical box, a space of width SpaceAfterScript is added after the superscript. By default, the leading edge of the superscript is aligned with the trailing edge of the base and shifted forward by the italic correction of the base, except if the base is an operator with largeop="true" (or an embellished operator whose mo element core has largeop="true").

Sup erShift ItalicCorrection Sup erBottom SpaceAfterScript Sup erscriptBaselineDrop
Figure 21: Box model for the msup element

The msubsup element is laid out as shown on figure 22. The baseline is the baseline of the base while the baseline of the script is shifted down by SubShift and the superscript is shifted up by SuperShift which is initially set to the minimal values honoring the following conditions:

  1. SubShift is at least SuperscriptShiftUpCramped if the msup element is cramped (section auto) or at least SuperscriptShiftUp otherwise.

  2. The top of the subscript SubTop with respect to the baseline is not above SubscriptTopMax.

  3. The drop SuperscriptBaselineDrop from the top of the base to the baseline of the superscript is at most SuperscriptBaselineDropMax.

  4. SubShift is at least SuperscriptShiftUpCramped if the msup element is cramped (section auto) or at least SuperscriptShiftUp otherwise.

  5. The bottom of the superscript SuperBottom with respect to the baseline is not below SuperscriptBottomMin.

  6. The drop SubscriptBaselineDrop from the bottom of the base to the the baseline of the subscript is at least SubscriptBaselineDropMin.

We then increase the gap SubSuperGap between the bottom of the superscript and the top of the subscript to ensure it is at least SubSuperscriptGapMin: This is first done by continuing to shift the superscript up as long as the SuperBottom does not exceed SuperscriptBottomMaxWithSubscript and next by continuing to shift the subscript down.

When determining the logical box, a space of width SpaceAfterScript is added after each script. By default the leading edges of the scripts are aligned with the trailing edge and either the superscript is shifted forward by the italic correction of the base. However, if the base is an operator with largeop="true" (or an embellished operator whose mo element core has largeop="true") then instead the subscript is shifted forward by the italic correction of the base.

Sup erShift Sup erBottom SpaceAfterScript SubShift SubT op SpaceAfterScript SubSup erGap Sup erscriptBaselineDrop SubscriptBaselineDrop
Figure 22: Box model for the msubsup element

4.4.2 Underscripts and Overscripts <munder>, <mover>, <munderover>

The munder element attaches an accent or limit placed under a base using the syntax
<munder> base underscript </munder>
If base is an operator with movablelimits="true" (or an embellished operator whose mo element core has movablelimits="true"), and displaystyle="false", then underscript is drawn in a subscript position. In this case, the accentunder attribute is ignored. […]

The mover element attaches an accent or limit placed over a base using the syntax
<mover> base overscript </mover>
If base is an operator with movablelimits="true" (or an embellished operator whose mo element core has movablelimits="true"), and displaystyle="false", then overscript is drawn in a superscript position. In this case, the accent attribute is ignored.

The munderover element attaches accents or limits placed both over and under a base using the syntax
<munderover> base underscript overscript </munderover>
If base is an operator with movablelimits="true" (or an embellished operator whose mo element core has movablelimits="true"), and displaystyle="false", then underscript and overscript are drawn in a subscript and superscript position, respectively. In this case, the accentunder and accent attributes are ignored.

User Agents must perform the scriptlevel increment by checking the appropriate accent or accentunder value, which can not be done using only CSS. However, displaystyle changes can be achieved with the following style in the user agent stylesheet, as suggested in section 2.3.2:

munder > :not(:first-child),
mover > :not(:first-child),
munderover > :not(:first-child) {
  mathml-math-style: inline;
} 

In cases where underscript and overscript are drawn as subscript and superscript position then the layout algorithm is the same as section 4.4.1. Note that in that case, accent or accentunder are ignored so the scriptlevel increment is always performed.

The general layout of munderover is shown on figure 23. The overscript is placed above the base, the underscript below the base and by default are aligned with respect to their geometrical center. If the overscript is an accent and has a TopAccentAttachment value, then this value may be used to horizontally align the accent instead of its geometrical center. OverShift is the distance between the top ink of the base and the baseline of the overscript, OverGap is the distance between the top ink of the base and the bottom ink of the overscript, OverExtraAscender is extra space to add above the overscript when determining the logical box. UnderShift, UnderGap and UnderExtraDescender are defined similarly for the underscripts. We distinguish three cases:

  1. If the base is an operator with largeop="true" (or an embellished operator whose mo element core has largeop="true") then ensure that OverGap is at least UpperLimitGapMin, that OverShift is at least UpperLimitBaselineRiseMin that UnderGap is at least LowerLimitGapMin, that UnderShift is at least LowerLimitBaselineDropMin. OverExtraAscender and UnderExtraDescender are zero. The underscript is shifted backward by half the italic correction of the base. The overscript is shifted forward by half the italic correction of the base.

  2. If the base is a horizontal operator with stretchy="true" (or a horizontal embellished operator whose mo element core has stretchy="true"). Then ensure that OverGap is at least StretchStackGapBelowMin, that OverShift is at least StretchStackTopShiftUp that UnderGap is at least StretchStackGapAboveMin, that UnderShift is at least StretchStackBottomShiftDown. OverExtraAscender and UnderExtraDescender are zero.

  3. In other cases we proceed as follows. There are not any specific conditions to satisfy on OverShift or UnderShift. OverExtraAscender and OverExtraAscender are respectively set to OverbarExtraAscender and UnderExtraDescender. We set UnderGap to UnderbarVerticalGap if the underscript is not an accent and to zero otherwise. We set OverGap to OverbarVerticalGap if the overscript is not an accent and generally to zero otherwise. However, if overscript is an accent and if the base ascent is at most AccentBaseHeight then we actually set OverGap to their nonnegative difference.

Remark: For accent overscripts and bases with ascents that are at most AccentBaseHeight, the rule from [OpenFontFormat3] [TeXBook] is actually to align the baselines of the overscripts and of the bases. This assumes that accent glyphs are designed in such a way that their ink bottoms are more or less AccentBaseHeight above their baselines. Hence, the previous rule will guarantee that all the overscript bottoms are aligned while still avoiding collision with the bases. However, MathML can have arbitrary accent overscripts so we provide a more general and simpler rule above: Ensure that the bottom of overscript is at least AccentBaseHeight above the baseline of the base.

Ov erGap Ov erShift Ov erExtraAscender UnderGap UnderShift UnderExtraDescender LargeOpItalicCorrection
Figure 23: Box model for the munderover element

The layout of munder and mover is the same as the one of munderover except that one script and its corresponding extra space are ignored.

4.4.3 Prescripts and Tensor Indices <mmultiscripts>

Presubscripts and tensor notations are represented by a single element, mmultiscripts, using the syntax:
<mmultiscripts>
base
(subscript superscript)*
[ <mprescripts/> (presubscript presuperscript)* ]
</mmultiscripts>

This element allows the representation of any number of vertically-aligned pairs of subscripts and superscripts, attached to one base expression. It supports both postscripts and prescripts. Missing scripts can be represented by the empty element none.

The displaystyle and scriptlevel changes be achieved with the following style in the user agent stylesheet as suggested in section 2.3.2:

mmultiscripts > :not(:first-child) {
  mathml-script-level: increment 1;
  mathml-math-style: inline;
}

Any layout for mmultiscripts is acceptable as long as it follows the condition of the MathML 3 specification [MathML3] and is consistent with section 4.4.1 for mmultiscripts contructions that are equivalent to msubsup. Here is a possible algorithm that is represented on figure 24.

  1. Determine the vertical shifts for each subscript/superscript pair using the algorithm for msub (if the superscript is none), msup (if the subscript is none) or msubsup (if none of the scripts are none) or otherwise use shifts of zero (if both scripts of the pair are none). When placing the scripts, use the maximum of the subscript shift for all subscript and the maximum of the superscript shift for all superscripts.

  2. For the horizontal layout of postscripts, use the trailing edge of the base or of the previous pair as the leading edge of the current pair. For each pair, apply the same italic correction described for msubsup in section 4.4.1. Apply the same italic corrections for all these postscripts.

  3. For the horizontal layout of prescripts, use the leading edge of the base or of next pair as the trailing edge of the current pair. Do not apply any italic correction for prescripts.

Figure 24: Box model for the mmultiscripts element

4.5 Tabular Math

Matrices, arrays and other table-like mathematical notation are marked up using mtable, mtr, mlabeledtr and mtd elements. These elements are similar to the table, tr and td elements of HTML, except that they provide specialized attributes for the fine layout control necessary for commutative diagrams, block matrices and so on.

In the present document, we restrict ourselves to a minimal implementation compatible with HTML tables. First the mtable element must be treated as a HTML table and by [MathML3], mtable must accept a displaystyle attribute with default value false. To implement that, one may rely on the following rules for the user agent stylesheet as suggested in section 2.3.2:

mtable {
  display: inline-table;
  mathml-math-style: inline;
}
mtable[displaystyle="true"] {
  mathml-math-style: display;
}

In addition, user agents may use the following rules to emulate the frame attribute:

mtable[frame="none"] {
  border: none;
}
mtable[frame="solid"] {
  border: solid thin;
}
mtable[frame="dashed"] {
  border: dashed thin;
}

By default, user agents must align the vertical center of the table on the math axis, which is provided by the AxisHeight value. User agents may also support non-default align attribute values.

The mtr and mlabeledtr elements must be treated as HTML table rows and the label of mlabeledtr element must be hidden by default. The default value of rowalign must be baseline. One may rely on the following rules for the user agent stylesheet as suggested in section 2.3.2:

mtr, mlabeledtr {
  display: table-row;
  vertical-align: baseline;
}
mlabeledtr > mtd:first-child {
  display: none;
}

Finally, the mtd elements must be treated as a HTML table cell. The default value of rowalign must be baseline and the default value of colulmnalign must be center. User agents may also try to approximate the default rowspacing and columnspacing between cells. This can be achieved with the following CSS:

mtd {
  display: table-cell;
  vertical-align: inherit;
  text-align: center;
  padding: 0.5ex 0.4em;
}

The mtd element must also support the columnspan (sic) and rowspan attributes. This can be implemented the same way as the HTML colspan and rowspan attributes.

4.6 Enlivening Expressions

To provide a mechanism for binding actions to expressions, MathML provides the maction element. This element accepts any number of sub-expressions as arguments and the type of action that should happen is controlled by the actiontype attribute. Only three actions are predefined by MathML, but the list of possible actions is open.

User agents must display at most one of the child of a maction element. User agents must determine the visible child as follows:

  1. If actiontype is toggle and the selection attribute (with default value 1) points to a valid child index between 1 and the number of children, then use the specified child.

  2. If the actiontype is statusline or tooltip then use the first child (if any).

  3. Otherwise, the visible child is undetermined.

For the layout algorithm described in this document, the maction element must be treated the same as the mrow element containing its visible child. If it is undetermined, the user agent may treat the maction element as an empty mrow element or as an merror element with some relevant error message indicating invalid or unsupported markup.

User agents may additionally provide a complete implementation of the toggle actiontype updating the value of the selection attribute after the maction element receives a click event. For statusline and tooltip attributes, they may also display the second child in some way when the maction element receives a hover event. This document does not define how these DOM events are propagated or how to change the default behavior.

Given the similarity with the semantics element described in section 4.7, it is suggested to share the implementation of semantics and maction.

4.7 Semantics and Presentation

The semantics element is the container element that associates annotations with a MathML expression. The semantics element has as its first child the expression to be annotated. Any MathML expression may appear as the first child of the semantics element. Subsequent annotation and annotation-xml children enclose the annotations. An annotation represented in XML is enclosed in an annotation-xml element. An annotation represented in character data is enclosed in an annotation element.

User agents must display at most one of the child of a semantics element. For example, they may always display the first child (if any) or may use this more advanced algorithm to determine a visible child:

  1. If the semantics element has a first child that is any of the MathML elements (other than annotation and annotation-xml) whose rendering is described in this document then use it as the visible child and stop.

  2. Otherwise, check the children of the semantics element in the DOM order to try and find the first child that is

    1. Either an annotation without any src attribute.

    2. Or an annotation-xml without any src attribute and with an encoding attribute that has value "application/mathml-presentation+xml", "MathML-Presentation", "image/svg+xml", "SVG1.1", "application/xhtml+xml" or "text/html".

  3. Otherwise, fallback to the first child (if any).

  4. Otherwise, the semantics element is empty and the visible child is undetermined.

For the layout algorithm described in this document, the annotation-xml element must be treated the same as the mrow element, the annotation element must be treated the same as the mtext element. The semantics element must be treated the same as an mrow element containing only its visible child. If it is undetermined, the user agent may treat the semantics element as an empty mrow element or as an merror element with some error message indicating invalid markup.

Given the similarity with the maction element described in section 4.6, it is suggested to share the implementation of semantics and maction.

Appendix A OpenType

This section is non-normative.

It is not clear how the DisplayOperatorMinHeight is supposed to be used or whether it is really reliable. More specifically, integral symbols (e.g. INTEGRAL U+222B) are typically taller than N-ary operators (e.g. N-ARY SUMMATION U+2211) so a unique minimal height may not always be enough to determine the display size. Suppose for example that the sum has three size variants: the base size of height 1em, the display size of height 2em and a bigger variant of height 3em. Suppose that the integral has three sizes: a base size of height 1em, a larger size variant of height 2em and a display size of height 3em. If DisplayOperatorMinHeight is less than 3em then it does not force the display size of the integral to be selected. If it is more than 3em then none of the available sizes satisfies the condition. How to interpret that? Should we pick the largest as a fallback? If it is 3em, the desired size will be selected for the integral in display size but the one selected for the sum in display size will be too large. A heuristic is proposed in section 4.2.3 to workaround limitations of DisplayOperatorMinHeight.

The OpenType MATH specification does not seem to take into account linebreaking. As explained in section 4.1.2 it is important in a HTML5 context to be able to determine the min-content width and the max-content width. However when an operator is stretched vertically to cover a target size, it is not possible to know the selected size variant or glyph assembly without knowing the target size and so the min-content and max-content widths can only be approximated. In practice, the width of the vertical operators is almost independent on its stretch size. Should that be a requirement of the OpenType MATH specification?

In section 4.3.8 we describe the MathML menclose element. This one contains many notations that are not mentioned in the OpenType MATH specification. Some rendering suggestions are given based on the value of OverbarRuleThickness but perhaps new values should be introduced in the MathConstants subtable to cover these notations.

Appendix B Image Fallback

This section is non-normative.

User agents that do not support MathML may decide to render the fallback content provided by the altimg* attributes in some situations e.g. when they are specified or under a preference option. In that case, an approximate implementation is to render the math element as a HTML img element with the value of altimg as an src attribute, the value of alttext as an alt attribute, the value of altimg-width as the CSS width property, the value of altimg-height as the CSS height property and the value of altimg-valign as the CSS vertical-align property [HTML5] [CSS2]. Here is a partial implementation using the attr() function of [CSS3Values]:

math {
  display: inline;
}
math[display="block"] {
  display: block;
  text-align: center;
}
math {
  background-image: attr(altimg url);
  width: attr(altimg-width length);
  height: attr(altimg-height length);
  vertical-align: attr(altimg-valign length);
}
math > * {
  display: none;
}

Appendix C Relax NG

This section displays a non-normative Relax NG Schema which details the elements and attributes defined by this specification. Note that MathML does not need to be expressed in XML syntax, in particular the syntax defined by HTML may be used. However this schema may be taken as an informal specification of the structure, whatever syntax is used.

example# mathml4-core
default namespace m = "http://www.w3.org/1998/Math/MathML"

start = math

math = element math {math.attributes,MathExpression*}

CommonAtt = attribute id {xsd:ID}?,
            attribute xref {text}?,
            attribute class {xsd:NMTOKENS}?,
            attribute style {xsd:string}?,
            attribute href {xsd:anyURI}?

math.attributes = CommonAtt,
               attribute display {"block" | "inline"}?,
               # attribute maxwidth {length}?,
               # attribute overflow {"linebreak" | "scroll" | "elide" | "truncate" | "scale"}?,
               attribute altimg {xsd:anyURI}?,
               attribute altimg-width {length}?,
               attribute altimg-height {length}?,
               attribute altimg-valign {length | "top" | "middle" | "bottom"}?,
               attribute alttext {text}?

annotation = element annotation {CommonAtt,(src|text)}

anyElement =  element (* - m:*) {(attribute * {text}|text| anyElement)*}

annotation-xml = element annotation-xml {CommonAtt,
					 encoding?,
				         (src|MathExpression*|anyElement*)}

encoding=attribute encoding {xsd:string}
src=attribute src {xsd:string}

semantics = element semantics {CommonAtt,
                               MathExpression, 
                              (annotation|annotation-xml)*}

length = xsd:string {
  pattern = '\s*((-?[0-9]*([0-9]\.?|\.[0-9])[0-9]*(e[mx]|in|cm|mm|p[xtc]|%))|0|(negative)?((very){0,2}thi(n|ck)|medium)mathspace)\s*'
}


## mathml3-presentation, simplified

MathExpression = TokenExpression|
                     mrow|mfrac|msqrt|mroot|mstyle|merror|mpadded|mphantom|
                     menclose|msub|msup|msubsup|munder|mover|munderover|
                     mmultiscripts|mtable|maction

ImpliedMrow = MathExpression*

TableRowExpression = mtr|mlabeledtr

MultiScriptExpression = (MathExpression|none),(MathExpression|none)

mpadded-length = xsd:string {
  pattern = '\s*([\+\-]?[0-9]*([0-9]\.?|\.[0-9])[0-9]*\s*((%?\s*(height|depth|width)?)|e[mx]|in|cm|mm|p[xtc]|((negative)?((very){0,2}thi(n|ck)|medium)mathspace))?)\s*' }

linestyle = "none" | "solid" | "dashed"

verticalalign =
      "top" |
      "bottom" |
      "center" |
      "baseline" |
      "axis"

columnalignstyle = "left" | "center" | "right"

notationstyle =
     "longdiv" |
     "actuarial" |
     "box" |
     "roundedbox" |
     "circle" |
     "left" |
     "right" |
     "top" |
     "bottom" |
     "updiagonalstrike" |
     "downdiagonalstrike" |
     "verticalstrike" |
     "horizontalstrike" |
     "madruwb"

idref = text

color =  xsd:string {
  pattern = '\s*((#[0-9a-fA-F]{3}([0-9a-fA-F]{3})?)|[aA][qQ][uU][aA]|[bB][lL][aA][cC][kK]|[bB][lL][uU][eE]|[fF][uU][cC][hH][sS][iI][aA]|[gG][rR][aA][yY]|[gG][rR][eE][eE][nN]|[lL][iI][mM][eE]|[mM][aA][rR][oO][oO][nN]|[nN][aA][vV][yY]|[oO][lL][iI][vV][eE]|[pP][uU][rR][pP][lL][eE]|[rR][eE][dD]|[sS][iI][lL][vV][eE][rR]|[tT][eE][aA][lL]|[wW][hH][iI][tT][eE]|[yY][eE][lL][lL][oO][wW])\s*'}

TokenExpression = mi|mn|mo|mtext|mspace|ms

mi = element mi {mi.attributes, text}
mi.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt

mn = element mn {mn.attributes, text}
mn.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt

mo = element mo {mo.attributes, text}
mo.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute form {"prefix" | "infix" | "postfix"}?,
  attribute fence {"true" | "false"}?,
  attribute separator {"true" | "false"}?,
  attribute lspace {length}?,
  attribute rspace {length}?,
  attribute stretchy {"true" | "false"}?,
  attribute symmetric {"true" | "false"}?,
  # attribute maxsize {length | "infinity"}?,
  # attribute minsize {length}?,
  attribute largeop {"true" | "false"}?,
  attribute movablelimits {"true" | "false"}?,
  attribute accent {"true" | "false"}?
  # attribute linebreak {"auto" | "newline" | "nobreak" | "goodbreak" | "badbreak"}?

mtext = element mtext {mtext.attributes, text}
mtext.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt

mspace = element mspace {mspace.attributes, empty}
mspace.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute width {length}?,
  attribute height {length}?,
  attribute depth {length}?

ms = element ms {ms.attributes, text}
ms.attributes = 
  CommonAtt,
  CommonPresAtt,
  TokenAtt,
  attribute lquote {text}?,
  attribute rquote {text}?

none = element none {none.attributes,empty}
none.attributes = 
  CommonAtt,
  CommonPresAtt

mprescripts = element mprescripts {mprescripts.attributes,empty}
mprescripts.attributes = 
  CommonAtt,
  CommonPresAtt

CommonPresAtt = 
  attribute mathcolor {color}?,
  attribute mathbackground {color | "transparent"}?

TokenAtt = 
  attribute mathvariant {"normal" | "bold" | "italic" | "bold-italic" | "double-struck" | "bold-fraktur" | "script" | "bold-script" | "fraktur" | "sans-serif" | "bold-sans-serif" | "sans-serif-italic" | "sans-serif-bold-italic" | "monospace" | "initial" | "tailed" | "looped" | "stretched"}?,
  attribute mathsize {length}?,
  attribute dir {"ltr" | "rtl"}?

mrow = element mrow {mrow.attributes, MathExpression*}
mrow.attributes = 
  CommonAtt, CommonPresAtt,
  attribute dir {"ltr" | "rtl"}?

mfrac = element mfrac {mfrac.attributes, MathExpression, MathExpression}
mfrac.attributes = 
  CommonAtt, CommonPresAtt,
  attribute linethickness {length}?,
  attribute numalign {"left" | "center" | "right"}?,
  attribute denomalign {"left" | "center" | "right"}?,
  attribute bevelled {"true" | "false"}?

msqrt = element msqrt {msqrt.attributes, ImpliedMrow}
msqrt.attributes = 
  CommonAtt, CommonPresAtt

mroot = element mroot {mroot.attributes, MathExpression, MathExpression}
mroot.attributes = 
  CommonAtt, CommonPresAtt

mstyle = element mstyle {mstyle.attributes, ImpliedMrow}
mstyle.attributes = 
  CommonAtt, CommonPresAtt,
  attribute scriptlevel {xsd:integer}?,
  attribute displaystyle {"true" | "false"}?,
  attribute scriptsizemultiplier {xsd:decimal}?

math.attributes &= CommonPresAtt
math.attributes &= mstyle.attributes

merror = element merror {merror.attributes, ImpliedMrow}
merror.attributes = 
  CommonAtt, CommonPresAtt

mpadded = element mpadded {mpadded.attributes, ImpliedMrow}
mpadded.attributes = 
  CommonAtt, CommonPresAtt,
  attribute height {mpadded-length}?,
  attribute depth {mpadded-length}?,
  attribute width {mpadded-length}?,
  attribute lspace {mpadded-length}?,
  attribute voffset {mpadded-length}?

mphantom = element mphantom {mphantom.attributes, ImpliedMrow}
mphantom.attributes = 
  CommonAtt, CommonPresAtt

menclose = element menclose {menclose.attributes, ImpliedMrow}
menclose.attributes = 
  CommonAtt, CommonPresAtt,
  attribute notation {notationstyle}?

msub = element msub {msub.attributes, MathExpression, MathExpression}
msub.attributes = 
  CommonAtt, CommonPresAtt,
  attribute subscriptshift {length}?

msup = element msup {msup.attributes, MathExpression, MathExpression}
msup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute superscriptshift {length}?

msubsup = element msubsup {msubsup.attributes, MathExpression, MathExpression, MathExpression}
msubsup.attributes = 
  CommonAtt, CommonPresAtt,
  attribute subscriptshift {length}?,
  attribute superscriptshift {length}?

munder = element munder {munder.attributes, MathExpression, MathExpression}
munder.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accentunder {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?

mover = element mover {mover.attributes, MathExpression, MathExpression}
mover.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accent {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?

munderover = element munderover {munderover.attributes, MathExpression, MathExpression, MathExpression}
munderover.attributes = 
  CommonAtt, CommonPresAtt,
  attribute accent {"true" | "false"}?,
  attribute accentunder {"true" | "false"}?,
  attribute align {"left" | "right" | "center"}?

mmultiscripts = element mmultiscripts {mmultiscripts.attributes,
				       MathExpression,
				       MultiScriptExpression*,
				       (mprescripts,MultiScriptExpression*)?}
mmultiscripts.attributes = 
  msubsup.attributes

mtable = element mtable {mtable.attributes, TableRowExpression*}
mtable.attributes = 
  CommonAtt, CommonPresAtt,
  attribute frame {linestyle}?,
  attribute displaystyle {"true" | "false"}?

mlabeledtr = element mlabeledtr {mlabeledtr.attributes, mtd+}
mlabeledtr.attributes = 
  mtr.attributes

mtr = element mtr {mtr.attributes, mtd*}
mtr.attributes = 
  CommonAtt, CommonPresAtt,
  attribute rowalign {"top" | "bottom" | "center" | "baseline" | "axis"}?

mtd = element mtd {mtd.attributes, ImpliedMrow}
mtd.attributes = 
  CommonAtt, CommonPresAtt,
  attribute rowspan {xsd:positiveInteger}?,
  attribute columnspan {xsd:positiveInteger}?,
  attribute rowalign {"top" | "bottom" | "center" | "baseline" | "axis"}?,
  attribute columnalign {columnalignstyle}?

maction = element maction {maction.attributes, MathExpression+}
maction.attributes = 
  CommonAtt, CommonPresAtt,
  attribute actiontype {text},
  attribute selection {xsd:positiveInteger}?

Appendix D Operator Dictionary

The following table gives the suggested dictionary of rendering properties for operators, fences, separators, and accents in MathML, all of which are represented by mo elements. For brevity, all such elements will be called simply operators in this Appendix.

D.1 Indexing of the operator dictionary

Note that the dictionary is indexed not just by the element content, but by the element content and form attribute value, together. Operators with more than one possible form have more than one entry. The MathML specification describes how the renderer chooses (infers) which form to use when no form attribute is given; see .

Having made that choice, or with the form attribute explicitly specified in the <mo> element's start tag, the MathML renderer uses the remaining attributes from the dictionary entry for the appropriate single form of that operator, ignoring the entries for the other possible forms.

In the table below, all non-ASCII characters are represented by XML-style hexadecimal numeric character references. The choice of markup (character data, numeric character reference or named entity reference) for a given character in MathML has no effect on its rendering.

D.2 Format of operator dictionary entries

Each row of the table is indexed as described above by the both the character (given by code point and Unicode Name) and the value of the form attribute. The fourth column gives the priority which as described in ??), is significant for the proper grouping of sub-expressions using mrow. The rule described there is especially relevant to the automatic generation of MathML by conversion from other formats for displayed mathematics, such as TEX, which do not always specify how sub-expressions nest.

The length valued attributes such as lspace are given explicitly in the following columns. Boolean valued attributes such as stretchy are specified together in the final Properties column by listing the attribute name if its value should be set to true by the dictionary. Finally some rarely used non-boolean properties are shown in the Properties column together with a value, for example linebreakstyle=after.

Any attribute not listed for some entry has its default value, which is given in parentheses in the table of attributes in ??.

( ( left parenthesis prefix 1 0 0 fence , stretchy

could be expressed as an mo element by:

<mo form="prefix" fence="true" stretchy="true" lspace="0em" rspace="0em"> ( </mo>
(note the whitespace added around the content for readability; Such whitespace will be ignored by a MathML system, as described in .

This entry means that, for MathML renderers which use this suggested operator dictionary, giving the element <mo form="prefix"> ( </mo> alone, or simply <mo> ( </mo> in a position for which form="prefix" would be inferred (see below), is equivalent to giving the element with all attributes as shown above.

In some versions of this specification, the rows of the table may be reordered by clicking on a h2ing in the top row, to cause the table to be ordered by that column.

D.3 Notes on lspace and rspace attributes

The values for lspace and rspace given here range from 0 to 7, they are given numerically in order to save space in the table, the values should be taken as referring to the named mathematical spaces, as follows.

Table Entry Named Space Default Length
0 0 em
1 veryverythinmathspace 1/18 em
2 verythinmathspace 2/18 em
3 thinmathspace 3/18 em
4 mediummathspace 4/18 em
5 thickmathspace 5/18 em
6 verythickmathspace 6/18 em
7 veryverythickmathspace 7/18 em

For the invisible operators whose content is &InvisibleTimes; or &ApplyFunction;, it is suggested that MathML renderers choose spacing in a context-sensitive way (which is an exception to the static values given in the following table). For <mo>&ApplyFunction;</mo>, the total spacing ( lspace+ rspace) in expressions such as sin x (where the right operand doesn't start with a fence) should be greater than zero; for <mo>&InvisibleTimes;</mo>, the total spacing should be greater than zero when both operands (or the nearest tokens on either side, if on the baseline) are identifiers displayed in a non-slanted font (i.e.. under the suggested rules, when both operands are multi-character identifiers).

D.4 Operator dictionary entries

Character Glyph Name form priority lspace rspace Properties
&#x1EEF0; 𞻰 arabic mathematical operator meem with hah with tatweel prefix stretchy
&#x1EEF1; 𞻱 arabic mathematical operator hah with dal prefix stretchy
&#x2018; left single quotation mark prefix 10 0 0 fence
&#x2019; right single quotation mark postfix 10 0 0 fence
&#x201C; left double quotation mark prefix 10 0 0 fence
&#x201D; right double quotation mark postfix 10 0 0 fence
( ( left parenthesis prefix 20 0 0 fence, stretchy, symmetric
) ) right parenthesis postfix 20 0 0 fence, stretchy, symmetric
[ [ left square bracket prefix 20 0 0 fence, stretchy, symmetric
] ] right square bracket postfix 20 0 0 fence, stretchy, symmetric
{ { left curly bracket prefix 20 0 0 fence, stretchy, symmetric
| | vertical line prefix 20 0 0 fence, stretchy, symmetric
| | vertical line postfix 20 0 0 fence, stretchy, symmetric
|| || multiple character operator: || prefix 20 0 0 fence, stretchy, symmetric
|| || multiple character operator: || postfix 20 0 0 fence, stretchy, symmetric
||| ||| multiple character operator: ||| prefix 20 0 0 fence, stretchy, symmetric
||| ||| multiple character operator: ||| postfix 20 0 0 fence, stretchy, symmetric
} } right curly bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2016; double vertical line prefix 20 0 0 fence, stretchy
&#x2016; double vertical line postfix 20 0 0 fence, stretchy
&#x2308; left ceiling prefix 20 0 0 fence, stretchy, symmetric
&#x2309; right ceiling postfix 20 0 0 fence, stretchy, symmetric
&#x230A; left floor prefix 20 0 0 fence, stretchy, symmetric
&#x230B; right floor postfix 20 0 0 fence, stretchy, symmetric
&#x2329; left-pointing angle bracket prefix 20 0 0 fence, stretchy, symmetric
&#x232A; right-pointing angle bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2772; light left tortoise shell bracket ornament prefix 20 0 0 fence, stretchy, symmetric
&#x2773; light right tortoise shell bracket ornament postfix 20 0 0 fence, stretchy, symmetric
&#x27E6; mathematical left white square bracket prefix 20 0 0 fence, stretchy, symmetric
&#x27E7; mathematical right white square bracket postfix 20 0 0 fence, stretchy, symmetric
&#x27E8; mathematical left angle bracket prefix 20 0 0 fence, stretchy, symmetric
&#x27E9; mathematical right angle bracket postfix 20 0 0 fence, stretchy, symmetric
&#x27EA; mathematical left double angle bracket prefix 20 0 0 fence, stretchy, symmetric
&#x27EB; mathematical right double angle bracket postfix 20 0 0 fence, stretchy, symmetric
&#x27EC; mathematical left white tortoise shell bracket prefix 20 0 0 fence, stretchy, symmetric
&#x27ED; mathematical right white tortoise shell bracket postfix 20 0 0 fence, stretchy, symmetric
&#x27EE; mathematical left flattened parenthesis prefix 20 0 0 fence, stretchy, symmetric
&#x27EF; mathematical right flattened parenthesis postfix 20 0 0 fence, stretchy, symmetric
&#x2980; triple vertical bar delimiter prefix 20 0 0 fence, stretchy
&#x2980; triple vertical bar delimiter postfix 20 0 0 fence, stretchy
&#x2983; left white curly bracket prefix 20 0 0 fence, stretchy, symmetric
&#x2984; right white curly bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2985; left white parenthesis prefix 20 0 0 fence, stretchy, symmetric
&#x2986; right white parenthesis postfix 20 0 0 fence, stretchy, symmetric
&#x2987; z notation left image bracket prefix 20 0 0 fence, stretchy, symmetric
&#x2988; z notation right image bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2989; z notation left binding bracket prefix 20 0 0 fence, stretchy, symmetric
&#x298A; z notation right binding bracket postfix 20 0 0 fence, stretchy, symmetric
&#x298B; left square bracket with underbar prefix 20 0 0 fence, stretchy, symmetric
&#x298C; right square bracket with underbar postfix 20 0 0 fence, stretchy, symmetric
&#x298D; left square bracket with tick in top corner prefix 20 0 0 fence, stretchy, symmetric
&#x298E; right square bracket with tick in bottom corner postfix 20 0 0 fence, stretchy, symmetric
&#x298F; left square bracket with tick in bottom corner prefix 20 0 0 fence, stretchy, symmetric
&#x2990; right square bracket with tick in top corner postfix 20 0 0 fence, stretchy, symmetric
&#x2991; left angle bracket with dot prefix 20 0 0 fence, stretchy, symmetric
&#x2992; right angle bracket with dot postfix 20 0 0 fence, stretchy, symmetric
&#x2993; left arc less-than bracket prefix 20 0 0 fence, stretchy, symmetric
&#x2994; right arc greater-than bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2995; double left arc greater-than bracket prefix 20 0 0 fence, stretchy, symmetric
&#x2996; double right arc less-than bracket postfix 20 0 0 fence, stretchy, symmetric
&#x2997; left black tortoise shell bracket prefix 20 0 0 fence, stretchy, symmetric
&#x2998; right black tortoise shell bracket postfix 20 0 0 fence, stretchy, symmetric
&#x29FC; left-pointing curved angle bracket prefix 20 0 0 fence, stretchy, symmetric
&#x29FD; right-pointing curved angle bracket postfix 20 0 0 fence, stretchy, symmetric
; ; semicolon infix 30 0 3 separator, linebreakstyle=after
, , comma infix 40 0 3 separator, linebreakstyle=after
&#x2063; invisible separator infix 40 0 0 separator, linebreakstyle=after
&#x2234; therefore infix 70 5 5
&#x2235; because infix 70 5 5
-> -> multiple character operator: -> infix 90 5 5
.. .. multiple character operator: .. postfix 100 0 0
... ... multiple character operator: ... postfix 100 0 0
: : colon infix 100 1 2
&#x3F6; ϶ greek reversed lunate epsilon symbol infix 110 5 5
&#x2026; horizontal ellipsis infix 150 0 0
&#x22EE; vertical ellipsis infix 150 5 5
&#x22EF; midline horizontal ellipsis infix 150 0 0
&#x22F1; down right diagonal ellipsis infix 150 5 5
&#x220B; contains as member infix 160 5 5
&#x22A2; right tack infix 170 5 5
&#x22A3; left tack infix 170 5 5
&#x22A4; down tack infix 170 5 5
&#x22A8; true infix 170 5 5
&#x22A9; forces infix 170 5 5
&#x22AC; does not prove infix 170 5 5
&#x22AD; not true infix 170 5 5
&#x22AE; does not force infix 170 5 5
&#x22AF; negated double vertical bar double right turnstile infix 170 5 5
&#x2228; logical or infix 190 4 4
&amp;&amp; && multiple character operator: && infix 200 4 4
&#x2227; logical and infix 200 4 4
&#x2200; for all prefix 230 2 1
&#x2203; there exists prefix 230 2 1
&#x2204; there does not exist prefix 230 2 1
&#x2201; complement infix 240 1 2
&#x2208; element of infix 240 5 5
&#x2209; not an element of infix 240 5 5
&#x220C; does not contain as member infix 240 5 5
&#x2282; subset of infix 240 5 5
&#x2282;&#x20D2; ⊂⃒ subset of with vertical line infix 240 5 5
&#x2283; superset of infix 240 5 5
&#x2283;&#x20D2; ⊃⃒ superset of with vertical line infix 240 5 5
&#x2284; not a subset of infix 240 5 5
&#x2285; not a superset of infix 240 5 5
&#x2286; subset of or equal to infix 240 5 5
&#x2287; superset of or equal to infix 240 5 5
&#x2288; neither a subset of nor equal to infix 240 5 5
&#x2289; neither a superset of nor equal to infix 240 5 5
&#x228A; subset of with not equal to infix 240 5 5
&#x228B; superset of with not equal to infix 240 5 5
&lt;= <= multiple character operator: <= infix 241 5 5
&#x2264; less-than or equal to infix 241 5 5
&#x2265; greater-than or equal to infix 242 5 5
> > greater-than sign infix 243 5 5
>= >= multiple character operator: >= infix 243 5 5
&#x226F; not greater-than infix 244 5 5
&lt; < less-than sign infix 245 5 5
&#x226E; not less-than infix 246 5 5
&#x2248; almost equal to infix 247 5 5
&#x223C; tilde operator infix 250 5 5
&#x2249; not almost equal to infix 250 5 5
&#x2262; not identical to infix 252 5 5
&#x2260; not equal to infix 255 5 5
!= != multiple character operator: != infix 260 4 4
*= *= multiple character operator: *= infix 260 4 4
+= += multiple character operator: += infix 260 4 4
-= -= multiple character operator: -= infix 260 4 4
/= /= multiple character operator: /= infix 260 4 4
:= := multiple character operator: := infix 260 4 4
= = equals sign infix 260 5 5
== == multiple character operator: == infix 260 4 4
&#x221D; proportional to infix 260 5 5
&#x2224; does not divide infix 260 5 5
&#x2225; parallel to infix 260 5 5
&#x2226; not parallel to infix 260 5 5
&#x2241; not tilde infix 260 5 5
&#x2243; asymptotically equal to infix 260 5 5
&#x2244; not asymptotically equal to infix 260 5 5
&#x2245; approximately equal to infix 260 5 5
&#x2246; approximately but not actually equal to infix 260 5 5
&#x2247; neither approximately nor actually equal to infix 260 5 5
&#x224D; equivalent to infix 260 5 5
&#x2254; colon equals infix 260 5 5
&#x2257; ring equal to infix 260 5 5
&#x2259; estimates infix 260 5 5
&#x225A; equiangular to infix 260 5 5
&#x225B; star equals infix 260 5 5
&#x225C; delta equal to infix 260 5 5
&#x225F; questioned equal to infix 260 5 5
&#x2261; identical to infix 260 5 5
&#x2268; less-than but not equal to infix 260 5 5
&#x2269; greater-than but not equal to infix 260 5 5
&#x226A; much less-than infix 260 5 5
&#x226A;&#x338; ≪̸ much less than with slash infix 260 5 5
&#x226B; much greater-than infix 260 5 5
&#x226B;&#x338; ≫̸ much greater than with slash infix 260 5 5
&#x226D; not equivalent to infix 260 5 5
&#x2270; neither less-than nor equal to infix 260 5 5
&#x2271; neither greater-than nor equal to infix 260 5 5
&#x227A; precedes infix 260 5 5
&#x227B; succeeds infix 260 5 5
&#x227C; precedes or equal to infix 260 5 5
&#x227D; succeeds or equal to infix 260 5 5
&#x2280; does not precede infix 260 5 5
&#x2281; does not succeed infix 260 5 5
&#x22A5; up tack infix 260 5 5
&#x22B4; normal subgroup of or equal to infix 260 5 5
&#x22B5; contains as normal subgroup or equal to infix 260 5 5
&#x22C9; left normal factor semidirect product infix 260 4 4
&#x22CA; right normal factor semidirect product infix 260 4 4
&#x22CB; left semidirect product infix 260 4 4
&#x22CC; right semidirect product infix 260 4 4
&#x22D4; pitchfork infix 260 5 5
&#x22D6; less-than with dot infix 260 5 5
&#x22D7; greater-than with dot infix 260 5 5
&#x22D8; very much less-than infix 260 5 5
&#x22D9; very much greater-than infix 260 5 5
&#x22EA; not normal subgroup of infix 260 5 5
&#x22EB; does not contain as normal subgroup infix 260 5 5
&#x22EC; not normal subgroup of or equal to infix 260 5 5
&#x22ED; does not contain as normal subgroup or equal infix 260 5 5
&#x25A0; black square infix 260 3 3
&#x25A1; white square infix 260 3 3
&#x25AA; black small square infix 260 3 3
&#x25AB; white small square infix 260 3 3
&#x25AD; white rectangle infix 260 3 3
&#x25AE; black vertical rectangle infix 260 3 3
&#x25AF; white vertical rectangle infix 260 3 3
&#x25B0; black parallelogram infix 260 3 3
&#x25B1; white parallelogram infix 260 3 3
&#x25B3; white up-pointing triangle infix 260 4 4
&#x25B4; black up-pointing small triangle infix 260 4 4
&#x25B5; white up-pointing small triangle infix 260 4 4
&#x25B6; black right-pointing triangle infix 260 4 4
&#x25B7; white right-pointing triangle infix 260 4 4
&#x25B8; black right-pointing small triangle infix 260 4 4
&#x25B9; white right-pointing small triangle infix 260 4 4
&#x25BC; black down-pointing triangle infix 260 4 4
&#x25BD; white down-pointing triangle infix 260 4 4
&#x25BE; black down-pointing small triangle infix 260 4 4
&#x25BF; white down-pointing small triangle infix 260 4 4
&#x25C0; black left-pointing triangle infix 260 4 4
&#x25C1; white left-pointing triangle infix 260 4 4
&#x25C2; black left-pointing small triangle infix 260 4 4
&#x25C3; white left-pointing small triangle infix 260 4 4
&#x25C4; black left-pointing pointer infix 260 4 4
&#x25C5; white left-pointing pointer infix 260 4 4
&#x25C6; black diamond infix 260 4 4
&#x25C7; white diamond infix 260 4 4
&#x25C8; white diamond containing black small diamond infix 260 4 4
&#x25C9; fisheye infix 260 4 4
&#x25CC; dotted circle infix 260 4 4
&#x25CD; circle with vertical fill infix 260 4 4
&#x25CE; bullseye infix 260 4 4
&#x25CF; black circle infix 260 4 4
&#x25D6; left half black circle infix 260 4 4
&#x25D7; right half black circle infix 260 4 4
&#x25E6; white bullet infix 260 4 4
&#x29C0; circled less-than infix 260 5 5
&#x29C1; circled greater-than infix 260 5 5
&#x29E3; equals sign and slanted parallel infix 260 5 5
&#x29E4; equals sign and slanted parallel with tilde above infix 260 5 5
&#x29E5; identical to and slanted parallel infix 260 5 5
&#x29E6; gleich stark infix 260 5 5
&#x29F3; error-barred black circle infix 260 3 3
&#x2A87; less-than and single-line not equal to infix 260 5 5
&#x2A88; greater-than and single-line not equal to infix 260 5 5
&#x2AAF; precedes above single-line equals sign infix 260 5 5
&#x2AAF;&#x338; ⪯̸ precedes above single-line equals sign with slash infix 260 5 5
&#x2AB0; succeeds above single-line equals sign infix 260 5 5
&#x2AB0;&#x338; ⪰̸ succeeds above single-line equals sign with slash infix 260 5 5
&#x2044; fraction slash infix 265 4 4 stretchy
&#x2206; increment infix 265 3 3
&#x220A; small element of infix 265 5 5
&#x220D; small contains as member infix 265 5 5
&#x220E; end of proof infix 265 3 3
&#x2215; division slash infix 265 4 4 stretchy
&#x2217; asterisk operator infix 265 4 4
&#x2218; ring operator infix 265 4 4
&#x2219; bullet operator infix 265 4 4
&#x221F; right angle infix 265 5 5
&#x2223; divides infix 265 5 5
&#x2236; ratio infix 265 5 5
&#x2237; proportion infix 265 5 5
&#x2238; dot minus infix 265 4 4
&#x2239; excess infix 265 5 5
&#x223A; geometric proportion infix 265 4 4
&#x223B; homothetic infix 265 5 5
&#x223D; reversed tilde infix 265 5 5
&#x223D;&#x331; ∽̱ reversed tilde with underline infix 265 3 3
&#x223E; inverted lazy s infix 265 5 5
&#x223F; sine wave infix 265 3 3
&#x2242; minus tilde infix 265 5 5
&#x2242;&#x338; ≂̸ minus tilde with slash infix 265 5 5
&#x224A; almost equal or equal to infix 265 5 5
&#x224B; triple tilde infix 265 5 5
&#x224C; all equal to infix 265 5 5
&#x224E; geometrically equivalent to infix 265 5 5
&#x224E;&#x338; ≎̸ geometrically equivalent to with slash infix 265 5 5
&#x224F; difference between infix 265 5 5
&#x224F;&#x338; ≏̸ difference between with slash infix 265 5 5
&#x2250; approaches the limit infix 265 5 5
&#x2251; geometrically equal to infix 265 5 5
&#x2252; approximately equal to or the image of infix 265 5 5
&#x2253; image of or approximately equal to infix 265 5 5
&#x2255; equals colon infix 265 5 5
&#x2256; ring in equal to infix 265 5 5
&#x2258; corresponds to infix 265 5 5
&#x225D; equal to by definition infix 265 5 5
&#x225E; measured by infix 265 5 5
&#x2263; strictly equivalent to infix 265 5 5
&#x2266; less-than over equal to infix 265 5 5
&#x2266;&#x338; ≦̸ less-than over equal to with slash infix 265 5 5
&#x2267; greater-than over equal to infix 265 5 5
&#x226C; between infix 265 5 5
&#x2272; less-than or equivalent to infix 265 5 5
&#x2273; greater-than or equivalent to infix 265 5 5
&#x2274; neither less-than nor equivalent to infix 265 5 5
&#x2275; neither greater-than nor equivalent to infix 265 5 5
&#x2276; less-than or greater-than infix 265 5 5
&#x2277; greater-than or less-than infix 265 5 5
&#x2278; neither less-than nor greater-than infix 265 5 5
&#x2279; neither greater-than nor less-than infix 265 5 5
&#x227E; precedes or equivalent to infix 265 5 5
&#x227F; succeeds or equivalent to infix 265 5 5
&#x227F;&#x338; ≿̸ succeeds or equivalent to with slash infix 265 5 5
&#x228C; multiset infix 265 4 4
&#x228D; multiset multiplication infix 265 4 4
&#x228E; multiset union infix 265 4 4
&#x228F; square image of infix 265 5 5
&#x228F;&#x338; ⊏̸ square image of with slash infix 265 5 5
&#x2290; square original of infix 265 5 5
&#x2290;&#x338; ⊐̸ square original of with slash infix 265 5 5
&#x2291; square image of or equal to infix 265 5 5
&#x2292; square original of or equal to infix 265 5 5
&#x2293; square cap infix 265 4 4
&#x2294; square cup infix 265 4 4
&#x229A; circled ring operator infix 265 4 4
&#x229B; circled asterisk operator infix 265 4 4
&#x229C; circled equals infix 265 4 4
&#x229D; circled dash infix 265 4 4
&#x22A6; assertion infix 265 5 5
&#x22A7; models infix 265 5 5
&#x22AA; triple vertical bar right turnstile infix 265 5 5
&#x22AB; double vertical bar double right turnstile infix 265 5 5
&#x22B0; precedes under relation infix 265 5 5
&#x22B1; succeeds under relation infix 265 5 5
&#x22B2; normal subgroup of infix 265 5 5
&#x22B3; contains as normal subgroup infix 265 5 5
&#x22B6; original of infix 265 5 5
&#x22B7; image of infix 265 5 5
&#x22B9; hermitian conjugate matrix infix 265 5 5
&#x22BA; intercalate infix 265 4 4
&#x22BB; xor infix 265 4 4
&#x22BC; nand infix 265 4 4
&#x22BD; nor infix 265 4 4
&#x22BE; right angle with arc infix 265 3 3
&#x22BF; right triangle infix 265 3 3
&#x22C4; diamond operator infix 265 4 4
&#x22C6; star operator infix 265 4 4
&#x22C7; division times infix 265 4 4
&#x22C8; bowtie infix 265 5 5
&#x22CD; reversed tilde equals infix 265 5 5
&#x22CE; curly logical or infix</