Skip to content

Files

Latest commit

May 10, 2025
bd9ea08 · May 10, 2025

History

History
16595 lines (12000 loc) · 438 KB

kb-mathlive.md

File metadata and controls

16595 lines (12000 loc) · 438 KB
date title slug
Last Modified
Customizing a Mathfield
/mathfield/guides/customizing/

Customizing a Mathfield

The appearance and behavior of the mathfield is highly customizable.

In this section we'll go over some of the ways a mathfield can be customized.

Styling

To style the mathfield define a CSS rule targeting the mathfield or use the style attribute of the <math-field> element.

CSS attributes can be used to modify the appearance of the mathfield in many ways, for example changing the base font size or adding a border around it.

To remove the border around the mathfield, set the border property to none or 0.

To change the background color of the mathfield, use the background property.

:::html
<math-field style="border: none; background: #d8f0ff">
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

To display the mathfield as a block element, rather than an inline element, add an attribute style="display: block"

:::html
<p>Answer: 
  <math-field style="font-size:1.2rem">42</math-field>.
</p>
<p>Answer: 
  <math-field style="font-size:2rem; display: block">3.1415</math-field>
</p>

CSS Variables

To customize the appearance of the mathfield, use the following CSS variables (custom properties) in a ruleset that applies to the mathfield element.

math-field {
 --smart-fence-color: red ;
}

Although CSS styles are "invisible" to custom components, CSS variables are "passed through" and will affect the content of the <math-field> custom component.

Set these CSS variables on any selector that applies to the <math-field> element you want to customize, for example, body.

Alternatively these CSS variables programatically can be set programmatically:

document.body.style.setProperty("--smart-fence-color", "red");
CSS Variable Usage
--primary Primary accent color, used for example keyboard toggle and menu glyphs and in the virtual keyboard
--caret-color Color of the insertion point
--selection-color Color of the content when selected
--selection-background-color Background color of the selection
--contains-highlight-background-color Background color of items that contain the caret
--placeholder-color Color of the placeholder symbol
--placeholder-opacity Opacity (0-1) of the placeholder symbol
--smart-fence-color Color of a smart fence (default is current color)
--smart-fence-opacity Opacity of a smart fence (default is 50%)
--highlight-text The background color indicating the caret is in a text zone
--text-font-family The font stack used for content in a text zone
--latex-color The color of content in a LaTeX zone
--correct-color Highlight color of a prompt when in the "correct" state
--incorrect-color Highlight color of a prompt when in the "incorrect" state

For color values, you can use any valid CSS color value, such as a color name, or `transparent to remove the color.

Note To change the placeholder symbol, use the mf.placeholderSymbol property.

:::html
<style>
math-field {
  --caret-color: red;
  --selection-background-color: lightgoldenrodyellow;
  --selection-color: darkblue;
}
</style>
<math-field>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

You can customize the appearance and zindex of the virtual keyboard panel with some CSS variables associated with a selector that applies to the virtual keyboard panel container.

Read more about customizing the virtual keyboard appearance

Mathfield Parts

Because the mathfield is a custom element with a shadow DOM, its content is not directly accessible to CSS rules outside of the shadow DOM.

However, there are a few parts that can be used to style the content of the mathfield using the ::part() pseudo-element.

Pseudo-element Usage
virtual-keyboard-toggle The virtual keyboard toggle button
menu-toggle The menu toggle button
content The math formula
container The element containing the formula, the keyboard toggle and the menu toggle
keyboard-sink The hidden element capturing the physical keyboard input
placeholder The element containing the placeholder attribute when the mathfield is empty
prompt The prompts (placeholder{}) inside the mathfield

For example:

/* Right align the formula */
math-field::part(content) {
  text-align: right;
}

/* Right align the virtual keyboard toggle */
math-field::part(container) {
  flex-flow: row-reverse;
}

/* Hide the virtual keyboard toggle */
math-field::part(virtual-keyboard-toggle) {
  display: none;
}

/* Hide the menu toggle */
math-field::part(menu-toggle) {
  display: none;
}

Note When the menu toggle is hidden, the menu can still be opened by right-clicking on the mathfield. You can customize the menu to change this behavior.

Placeholder

To customize the placeholder text set the placeholder attribute on the <math-field> element.

Note that the content of the placeholder attributed is interpreted as a LaTeX string. To display it as regular text, use the \text{} command.

:::html
<math-field placeholder="\text{Enter a formula}">
</math-field>

Focus Ring

To change the appearance of the focus ring, use the :focus-within pseudo-element.

:::html
<style>
  math-field:focus-within {
    outline: 4px solid #d7170b;
    border-radius: 4px;
    background: rgba(251,	187,	182, .1);
  }
</style>
<math-field>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

:::warning

Caution Removing outlines in CSS creates issues for people navigating the web with a keyboard. However, you can change the appearance of the outline, for example to indicate an error condition. If you remove the outline on the mathfield, make sure to replace it with another indicator, for example by displaying an outline on an enclosing element.

:::

Math Display Options

The appearance of a formula, in an editable mathfield or as a static representation, can be controlled with some of the following options:

Color

To change the foreground ("ink") and background ("paper") colors of a formula programmatically, use the mf.applyStyle() function.

To change the foreground color, use the \textcolor{}{} command. To change the background color, use the \colorbox{}{} command.

The first argument of these commands is a color specified as:

  • a RGB color using the standard CSS format (#d7170b)
  • a CSS color name (goldenrod)
  • one of the 68 colors from dvips color name (cadetblue)
  • one of the 10 Mathematica color from ColorData[97, "ColorList"] (m0 to m9)
  • a color defined using the syntax from the xcolor package, for example: blue!20!black!30!green

The following color names are recommended. They can be applied using the color keys in the virtual keyboard:

:::info[Note]

These colors have been carefully selected for a balanced representation of the range of hues on the color circle, with similar lightness and intensity. They will map to different color values than the dvips colors of the same name.

:::

:::info[Note]

To have proper legibility based on usage, these color names will map to different values when used as a foreground color and a background color. To use a specific color value, use a RGB color instead.

:::

:::info[Note]

To customize how the color names are interpreted provide a colorMap or backgroundColorMap function.

:::

Size

To change the base font size, set the font-size CSS property to the desired value on the mathfield or static element.

Within a formula, the size can be specified from a font scale with 10 values, where 1 em is the base font size of the mathfield or static element.

fontSize   LaTeX Command
1 0.5 em \tiny
2 0.7 em \scriptsize
3 0.8 em \footnotesize
4 0.9 em \small
5 1 em \normalsize or \normal
6 1.2 em \large
7 1.44 em \Large
8 1.728 em \LARGE
9 2.074 em \huge
10 2.488 em \Huge

:::warning

In TeX, the sizing commands behave inconsistently when applied to math. Other implementations of TeX may also interpret the sizing commands differently.

:::

Math Layout

To control some aspects of the math typesetting, change the mathstyle with the commands \displaystyle, \textstyle, \scriptstyle, \scriptscriptstyle.

The displaystyle style is most appropriate when there is plenty of space around the formula. Limits over large operators, such as \sum are displayed above and below the operator. There is a generous amount of space below the numerator and above the denominator of fractions, and around relational (=) and binary (+) operators.

The textstyle style is useful when space is constrained or when displaying a formula with some regular text around it. The limits of large operators are displayed after the operator. The numerator and denominator of fractions is displayed using a smaller font size. However, the font-size for other characters is not affected.

The scriptstyle and scriptscriptstyle are rarely needed explicitly. The content is laid out using a smaller font-size (70% and 50% of the base font-size, respectively) and the spacing between operators is minimized. Note however that these styles are used automatically in some situations. For example, when using the displaystyle or textstyle, the limits of a large operator or the superscript or subscript of a symbol are displayed using these styles. Notice for example that n=0 in displaystyle does not include space around the = sign because the limit is displayed in scriptstyle.

To set the default mathstyle of a mathfield, set the mf.defaultMode property or the default-mode attribute.

Set it to "inline-math" to use textstyle or "math" to use displaystyle.

:::html
<p>The answer is 
  <math-field default-mode="inline-math">
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
  </math-field>.
</p>

By default, the mathfield element is laid out on the page as an inline element when in an inline context (when inside a <p> tag for example).

To get it laid out as a block element, set display: block on the mathfield.

Letter Shape Style

To control which letters are automatically italicized, set the letterShapeStyle property or letter-shape-style attribute.

letterShapeStyle xyz ABC αβɣ ΓΔΘ
iso xyz ABC αβɣ ΓΔΘ
tex xyz ABC αβɣ ΓΔΘ
french xyz ABC αβɣ ΓΔΘ
upright xyz ABC αβɣ ΓΔΘ

In the ISO style, lower and uppercase roman letter and lower and upper case greek letters are italicized when used as a variable. Mathematical constants such as \(e\) are written upright.

TeX has traditionally implemented a layout option that italicizes romman letters and lowercase greek letters, but not uppercase greek letters.

The French typographical convention is to only italicize lowercase roman letters.

The default letter shape style is auto: if the system locale is "french", the french style is used, otherwise tex is used.

Editing Options

The editing behavior of a mathfield can be customized by setting some properties on the mathfield, or the equivalent attributes on the <math-field> tag.

  • defaultMode:
    • "inline-math": use inline math mode
    • "math": use the display math mode
    • "text": use the text mode |
  • removeExtraneousParentheses: automatically remove extra parentheses around a numerator or denominator
  • scriptDepth: maximum levels of subscript or superscript. Set it to 0 to prevent the input of superscript and subscripts
  • smartFence: automatically convert parentheses to \left...\right markup.
  • smartMode: switch to text mode when text input is detected, for example when typing "if x > 0"
  • smartSuperscript: automatically move out of a superscript when a digit is typed

These properties can also be passed as an argument to new MathfieldElement() when programmatically creating mathfield elements.

In the interactive code playground below, try some of these options. For example, in line 1 add the attribute smart-mode=false, then type some parentheses in the mathfield.

:::html
<math-field smart-mode>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>


See `EditingOptions` for more details about these and other available options

Handling the Space Bar

In traditional math typesetting, spaces have no effect: the spacing of elements in a formula is determined by the nature of the elements: numbers, punctuation, relational, binary or unary operators, etc...

To control spacing in a formula, use some of the LaTeX spacing commands: \quad, \qquad, \!, \, (thin space), \: (medium space), \; (thick space), \enskip or \enspace.

By default, pressing the spacebar when in math mode does not insert anything.

To insert a LaTeX command when the spacebar is pressed, set the value of the mathModeSpace property to that command:

mf.mathModeSpace = '\\:';

Turning off the LaTeX mode

Pressing the \ (backslash) or ESC key switches to the LaTeX mode where it is possible to enter raw LaTeX command. For users familiar with LaTeX, it is a powerful way to enter or edit LaTeX in an expression. However, users unfamiliar with LaTeX may be confused if they accidentally press those keys.

To prevent the LaTeX mode from being enabled intercept the trigger keys and call `preventDefault().

mf.addEventListener(
  'keydown',
  (ev) => {
    if (ev.key === '\\') {
      ev.preventDefault();
      mf.executeCommand(['insert', '\\backslash']);
    } else if (ev.key === 'Escape') ev.preventDefault();
  },
  { capture: true }
);

Localization

The user interface of the mathfield is provided in english, arabic, german, greek, spanish, farsi, french, italian, japanese, polish and russian.

The language to use is detected automatically, but it can be overridden by using the MathfieldElement.locale static property. Setting this property will affect all mathfield elements on the page.

:::js
await customElements.whenDefined('math-field');
const locale = MathfieldElement.locale;
console.log("Locale:", locale);
console.log(MathfieldElement.strings[locale.substring(0, 2)]);


:::html
<math-field id=formula>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

Decimal Marker

The world is about evenly split between using a dot . or a comma , as a decimal marker.

To change the marker used with decimal numbers set the MathfieldElement.decimalSeparator property to "," or ".".

When set to ",", pressing the , key on a physical keyboard will insert a {,} LaTeX string, if in math mode and if before a digit.

The LaTeX sequence {,} is traditionally used to correctly typeset the comma and ensure the correct amount of space around it. Without the {}, the , is interpreted as a delimiter and has excessive amount of space around it.

When set to ",", the virtual keyboard is also changed so that the . keycap is labeled , instead and contextually inserts a {,} when appropriate.

:::js
await customElements.whenDefined('math-field');
MathfieldElement.decimalSeparator = ",";
:::html
<math-field id='formula'>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

Fraction Navigation Order

When using the arrow keys on the keyboard to navigate a fraction, the order in which the numerator and navigator are traversed can be customized.

To change the keyboard navigation order of fractions set the MathfieldElement.fractionNavigationOrder property.

The possible values are:

  • "numerator-denominator": first the elements in the numerator, then the elements in the denominator. This is the default behavior.
  • "denominator-numerator": first the elements in the denominator, then the elements in the numerator. In some East-Asian cultures, fractions are read and written denominator first (fēnzhī). With this option the keyboard navigation follows this convention.
:::js
await window.customElements.whenDefined('math-field');
MathfieldElement.fractionNavigationOrder = "denominator-numerator";

:::html
<math-field>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

Sounds and Haptic Feedback

The mathfield provides some audio feedback when a key is pressed on the virtual keyboard or when an action cannot be performed, for example when trying to delete when the mathfield is empty (the "plonk" sound).

The files for the sounds played by the mathfield should be located in a directory named sounds next to the mathfield library. If your bundler or asset management system require a different configuration you can specify where the sounds can be located using the MathfieldElement.soundsDirectory property.

MathfieldElement.soundsDirectory = 
  "https://cdn.jsdelivr.net/npm/mathlive/sounds/";

Specific sounds can be disabeld or customized with the MathfieldElement.keypressSound property.

MathfieldElement.keypressSound = {
  spacebar: null,
  return: "./sounds/return.mp3",
  delete: null,
  default: null,
}

Playing "Plonk" Sound

To play the "plonk" sound when an action cannot be performed, use MathfieldElement.playSound('plonk').

MathfieldElement.playSound('plonk');

Disabling Sounds

To turn off the sounds set the MathfieldElement.soundsDirectory property to null.

MathfieldElement.soundsDirectory = null;

Haptic Feedback

When a key on the virtual keyboard is pressed, a small vibration is triggered on devices that support it. This can be turned off by setting the MathfieldElement.keypressVibration property to false.

MathfieldElement.keypressVibration = false;

Fonts

The content of the mathfield is displayed using a family of high-quality fonts based on the original Computer Modern font from TeX. The mathfield will not display correctly using another font.

By default, the directory containing the fonts is located next to the file containing the mathlive library. If your bundler or asset management system require a different configuration you can specify where the fonts can be located using the MathfieldElement.fontsDirectory property.

:::style
.output:focus-within {
  outline: Highlight auto 1px;
  outline: -webkit-focus-ring-color auto 1px
}
.output math-field:focus, .output math-field:focus-within {
  outline: none;
}

:::js
await window.customElements.whenDefined("math-field");
MathfieldElement.fontsDirectory = "https://cdn.jsdelivr.net/npm/mathlive/fonts/";


:::html
<math-field>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>
```---
date: Last Modified
title: Matrix Editor
slug: /mathfield/matrix/
toc_max_heading_level: 2
---

<Intro>
A matrix is a useful way to represent and manipulate linear transformations. They are also used to represent systems of linear equations and many 
other mathematical structures.

Mathfields can display and edit matrices in a variety of ways.
</Intro>


## Creating a Matrix

There are several methods to create a matrix in a mathfield.

### Using Keyboard Shortcuts

**To create a matrix using the keyboard:** 

1. Type a parenthesis, square bracket, or curly brace.
2. Type the first element of the matrix.
3. Type the <kbd>ALT/OPTION</kbd>+<kbd>TAB</kbd> key to move to the next column: this will automatically
   transform the expression into a matrix
4. Type the <kbd>ALT/OPTION</kbd>+<kbd>RETURN</kbd> key to move to the next row.

### Using the Context Menu

The mathfield context menu provides a convenient way to create a matrix.

**To access the context menu** right click (or <kbd>CTRL</kbd>+click) on the 
mathfield. The menu is also available by typing <kbd>ALT</kbd>+<kbd>SPACE</kbd>, 
or by tapping on the menu button in the mathfield.



**To insert a matrix using the context menu** select the **Insert Matrix** 
menu, then select the number of rows and columns of the matrix.


## Matrix Borders

The borders of a matrix are parentheses by default. They can 
be changed to square brackets, curly braces, vertical bars, or none.

**To change the border of a matrix** right click (or <kbd>CTRL</kbd>+click) on the
matrix, then select the desired border from the **Matrix Border** menu.


In LaTeX, matrices are represented using the `\\begin\{\}...\\end\{\}` syntax. The argument to the `begin` command determines the type of matrix and is called
the **environment**.

Inside the environment, the matrix is specified using the `&` character to separate columns and the `\\\\` character to separate rows.

The following environments are supported:

| Environment | Description |
| --- | --- |
| `matrix` | A matrix with no delimiters |
| `pmatrix` | A matrix surrounded by parentheses |
| `bmatrix` | A matrix surrounded by square brackets |
| `Bmatrix` | A matrix surrounded by curly braces |
| `vmatrix` | A matrix surrounded by vertical bars |
| `Vmatrix` | A matrix surrounded by double vertical bars |
| `smallmatrix` | A matrix with no delimiters, in a smaller font |
| `array` | A matrix with no delimiters, with control over column alignment |

---
<Latex flow="column">{`
\\begin\{matrix\}
  a & b \\\\
  c & d
\\end\{matrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{pmatrix\}
  a & b \\\\
  c & d
\\end\{pmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{bmatrix\}
  a & b \\\\
  c & d
\\end\{bmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{Bmatrix\}
  a & b \\\\
  c & d
\\end\{Bmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{vmatrix\}
  a & b \\\\
  c & d
\\end\{vmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{Vmatrix\}
  a & b \\\\
  c & d
\\end\{Vmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{smallmatrix\}
  a & b \\\\
  c & d
\\end\{smallmatrix\}
`}</Latex>
---

<Latex flow="column">{`
\\begin\{array\}\{cc\}
  a & b \\\\
  c & d
\\end\{array\}
`}</Latex>


## Changing the Shape of a Matrix

**To add or remove rows or columns** right click (or <kbd>CTRL</kbd>+click) on the
matrix, then select the desired action from the menu. Rows and columns 
get added or removed relative to the cell the cursor is in.


## Spacing

### Changing the spacing of an individual row

The spacing between rows can be adjusted by setting an 
optional argument to the `\\\\` command. The argument is a length, and can be positive or negative.

For example, the following matrix has no space between columns and a double space between rows:

<Latex flow="column">{`
\\begin\{pmatrix\}
  a & b \\\\[1.5em]
  c & d
\\end\{pmatrix\}
`}</Latex>

Units can be specified using the following abbreviations:
- `em` (the width of the letter `M` in the current font)
- `mu` (math unit, 1/18 em)
- `ex` (the height of the letter `x` in the current font)
- `pt` (a point, 1/72.27 inch)
- `pc` (a pica, 12 points)
- `px` (a pixel, 1/96 inch)
- `cm` (a centimeter)
- `mm` (a millimeter)
- `in` (an inch)
- `bp` (a big point, 1/72 inch)
- `dd` (a didot point, 1238/1157 mm)
- `cc` (a cicero, 12 didot points)
- `sp` (a scaled point, 65536 sp = 1 pt)

### Changing the spacing of all rows

The spacing between rows can be controlled by setting the `arraystretch` 
register. The default value is `1.0`.

The value of a register can also be modified by using the `\renewcommand` command.
In general, modifying registers using `mf.registers` is preferred, but
using `\renewcommand` might be handy, for example when rendering static LaTeX.


```json
mf.registers.arraystretch = 2.5

{\\renewcommand\{\\arraystretch\}\{2.5\} \\begin\{pmatrix\} a & b \\\\ c & d \\end\{pmatrix\}}

{\\renewcommand\{\\arraystretch\}\{0.5\} \\begin\{pmatrix\} a & b \\\\ c & d \\end\{pmatrix\}}


date: Last Modified title: Keyboard Shortcuts slug: /mathfield/reference/keybindings/

import { Children, useEffect } from 'react';

export function onDisplayChange(e) { const useGlyphs = e.target.value === 'glyphs'; // We currently combine the display of glyphs with the "apple" class // We could have them separated... document.body.classList.toggle('apple', useGlyphs); document.body.classList.toggle('glyphs', useGlyphs); }

export function Keybinding({value, appleValue, children}) { const asKeylabel = (s, cls) => { const keybindings = s.split(/ /); return Children.map(keybindings, (keybinding => { const keys = keybinding.split('+'); let labels = keys.map(key => {key}); // Insert a "+" between each key labels = labels.reduce((acc, curr) => acc === null ? [curr] : [...acc, '+', curr], null); return

{Children.map(labels, _ => _)}
})); }

// Substitute a text label for the glyphs const noGlyphs = (s) => { return s.replace(/⌘|⌃|⇧|⌥|⤒|⤓|⇞|⇟|⇥|⌫|⌦|⏎|⌤|⇥/g, (glyph) => { const noGlyph = { '⌘': 'Ctrl', '⌃': 'Ctrl', '⇧': 'Shift', '⌥': 'Alt', '⤒': "Home", '⤓': 'End', "⇞": 'Page Up', '⇟': "Page Down", '⌫': 'Backspace', '⌦': 'Del', '⏎': 'Return', '⌤': 'Enter', '⇥': 'Tab' }[glyph]; return noGlyph ?? glyph; });

}

return

{children}
{asKeylabel(noGlyphs(value), 'if-not-glyphs')} {asKeylabel(value, 'if-glyphs')} {appleValue && asKeylabel(appleValue, 'if-apple')}

}

export function Shortcut({value, children}) { return

{$$${value}$$}
{children}

}

export default function ({children}) { useEffect(() => { const platform = navigator['userAgentData']?.platform ?? navigator.platform; const isApple = /^mac/i.test(platform) || /iphone|ipod|ipad/i.test(navigator.userAgent);

// The body class gets cleared when the page is reloaded, so we need to
// set it again after a short delay.
if (isApple) 
  setTimeout(() => document.body.classList.add('apple', 'glyphs'), 16);

const glyphsRadio = document.getElementById('glyphs-radio');
const textRadio = document.getElementById('text-radio');
glyphsRadio.checked = isApple;
textRadio.checked = !isApple;
// Restore the body class when the page is reloaded
return () => document.body.classList.remove('apple', 'glyphs');

}, []); return <>{children}</>; }

<style>{` .keybinding-cell { display: flex; flex-flow: column; justify-content: start; gap: 4px; width: 20%; padding: 8px; margin: 0; background: transparent; border: 1px solid var(--callout-border-color); border-radius: 8px; box-sizing: content-box; font-family: var(--ui-font-family); font-weight: 400; text-align: center; } .keybinding-cell div:not(.keybinding-label) { align-items: center; justify-content: center; flex-wrap: wrap; color: var(--neutral-400); font-size: 1em; line-height: 2; } .keybinding-cell aside { margin-top: .5em; font-size: .8em; opacity: .8; } .keybinding-cell div kbd { display: flex; justify-content: center; align-items: center; font-family: var(--ui-font-family); font-size: .8em; line-height: 2; margin-left: 4px; margin-right: 4px; width: fit-content; min-width: 32px; min-height: 32px; height: 32px; padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; border: var(--code-border); background: var(--neutral-900); border-radius: 4px; color: var(--blue-800); box-shadow: none; } .keybinding-label { display: flex; flex-flow: column; min-height: 4em; background: var(--callout-background); color: var(--text-color); align-items: center; justify-content: center; overflow-wrap: anywhere; background: var(--callout-background); color: var(--text-color); line-height: 1.1; padding: 8px; border-radius: 8px; margin-bottom: 4px; } .shortcut-cell { display: flex; flex-flow: column; align-items: center; justify-content: start; border-radius: 8px; border: 1px solid var(--callout-border-color); background: transparent; margin: .5em; padding: .5em; width: 20%; } .shortcut-cell div { text-align: center; } .shortcut-label { display: flex; flex-flow: column; min-height: 1em; width: 100%; background: var(--callout-background); color: var(--text-color); align-items: center; justify-content: center; overflow-wrap: anywhere; background: var(--callout-background); color: var(--text-color); line-height: 1; padding: 8px; border-radius: 8px; margin-bottom: 4px; } .shortcut-keys { font-family: var(--monospace-font-family); color: var(--primary-color); font-weight: 600; font-feature-settings: "calt" 0; } .shortcut-cell kbd { box-shadow: none; } {/* kbd { display: flex; justify-content: center; align-items: center; font-family: var(--ui-font-family); padding-left: 4px; padding-right: 4px; padding-top: 2px; padding-bottom: 2px; font-size: 0.8em; border: var(--code-border); background: var(--neutral-900); border-radius: 4px; color: var(--blue-800); box-shadow: none; } */} @media (prefers-color-scheme: dark) { kbd { color: var(--blue-100); } } table td code { border: none; background: none; } table tr td:first-child { width: auto; } #special-keys { border-radius: 8px; margin-top: 2rem; border: var(--ui-border); padding: 1rem; } #special-keys-table { display: flex; flex-wrap: wrap; justify-content: space-around; gap: .25em; margin-bottom: 1em; } #special-keys-table > div { display: flex; flex-flow: column; align-items: center; width: 6em; font-size: 1rem; } #special-keys-table > div > kbd:first-child { display: flex; width: 74px; height: 64px; justify-content: center; align-items: center; font-size: 32px; font-weight: 500; color: var(--primary-color); } #special-keys-table > div > span, #special-keys-table > div > kbd:nth-child(2) { width: 100%; text-align: center; padding: 0; border: none; background: none; } #special-keys-table .label { font-size: 16px; } #special-keys-table .label kbd { padding: 0; border: none; box-shadow: none; background: none; font-weight: 600; } .keybindings-table { display: flex; flex-wrap: wrap; gap: 1em; } .inlineshortcut-table { display: flex; flex-wrap: wrap; } div[data-tooltip]:hover { position: relative; width: 100%; } div[data-tooltip]::after { display: none; position: absolute; content: attr(data-tooltip); min-width: calc(100% - 16px); height: calc(100% + 8px); padding: 8px 8px; top: -8px; left: 0; z-index: 2; justify-content: center; align-items: center; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); background: #616161; color: #fff; text-align: center; border-radius: 8px; font-family: var(--monospace-font-family); font-feature-settings: "calt" 0; /* Suppress ligatures */ font-weight: 400; font-size: 16px; } div[data-tooltip]:hover::after { display: flex; } .settings-row, .settings-stack { border-radius: 8px; border: var(--ui-border); padding: 1rem; display: flex; width: 100%; user-select: none; gap: 0; } .settings-row p , .settings-stack p { margin: 0; padding: 0; } .settings-row { align-items: center; justify-content: space-between; } .settings-stack { flex-flow: column; } .settings-stack .label { font-size: 1rem; font-weight: 700; margin-bottom: 0.5rem; } #special-keys { display: none; } body.apple #special-keys { display: block; } .if-apple, .keybinding-cell div.if-apple:not(.keybinding-label) { display: none; } body.apple .if-apple, body.apple .keybinding-cell div.if-apple:not(.keybinding-label) { display: inherit; } .if-glyphs, .if-not-glyphs { display: none; } body.glyphs .if-glyphs { display: inherit; } body:not(.glyphs) .if-not-glyphs { display: inherit; text-transform: uppercase; font-variant: small-caps; } `}</style>

Keybindings

Commands to edit and modify a formula can be invoked by pressing some key combinations.

:::info[Note] The keybindings below are applicable to a US QWERTY keyboard. Some of the keybindings may not be available with other keyboard layouts. :::

Read more about definining your own **keybindings** and **shortcuts**.
Display shortcuts for:
macOS, iPadOS, iOS Windows, Android, ChromeOS, Linux
Shift
Control
Option
Command
Home
End
Page Up
Page Down
Backspace
Del
Return
Enter
Tab

Editing

move backward move forward move up move down extend selection backward extend selection forward extend selection upward extend selection downward move to next placeholder move to previous placeholder delete backward delete forward move to previous word move to next word extend selection to previous word extend selection to next word move to group start move to group end extend selection to group start extend selection to group end move after parent move before parent move to mathfield start extend selection to mathfield start move to mathfield end extend selection to mathfield end move to opposite superscript/subscript, upper/lower move to superscript/upper move to subscript/lower finish reject accept suggestion complete select all undo redo scroll into view toggle keystroke caption toggle virtual keyboard show context menu apply text mode toggle math/text mode enter/exit LaTeX mode enter LaTeX mode speak parent speak all

Math Symbols

π \differentialD i = ( ) |  

Matrix Editing

insert square bracket matrix insert braces matrix insert row insert column

Inline Shortcuts

Some sequence of characters are automatically translated to symbols. For example, typing P followed by I will result in "π".

Many of the ASCIIMath symbols are supported.

If the conversion was not desired, for example you actually meant "pi", type ctrl/⌘+Z to undo it.

Letter-Like Symbols

infty
oo
ii
jj
ee
NN
ZZ
QQ
RR
CC
PP
forall
AA
exists
EE
!exists
!EE
$
%
#
\
diamond
square
|
TT
nabla
grad
del
dx
dy
dt
aleph

Functions

arcsin arccos arctan sin sinh cos cosh tan tanh sec csc cot log ln exp lim det mod max min erf erfc bessel mean median fft lcm gcd randomReal randomInteger Re Im

Relational Operators

!= >= <= << >>

~~
?= := :: -= ~= lt lt= gt gt=
-lt
-<
-<= ->= prop

Other Operators

* ** *** && xin in !in xx +- ÷ (-) (+) (/)

ox
(x)
(-) @ |>< ><| |><|
-:
divide
^^ ^^^ vv vvv nn nnn uu uuu setminus sub sup sube supe and or not

Delimiters

|__ __| |~ ~| || { } (: :)

Units

mm cm km kg

Arrows

iff \>-\> -\>\> \>-\>\> -\> -\>... |-\> --\> \<-- => ==> \<=\> \<-\> uarr darr rarr rArr larr lArr harr hArr |-- |==

Greek Letters

alpha beta gamma Gamma delta Delta epsilon varepsilon zeta eta theta vartheta Theta iota kappa lambda Lambda
mu
µ
nu xi Xi pi Pi rho sigma Sigma tau upsilon phi varphi Phi chi psi Psi Ω Omega

Miscellaneous

\% '' ∑ sum int prod sqrt neg liminf limsup argmin argmax ... +... -... :.
--- title: Mathfield API Reference sidebar_label: API Reference slug: /mathfield/api/ toc_max_heading_level: 3 --- import MemberCard from '@site/src/components/MemberCard';

Mathfield API Reference

Mathfield

MathfieldElement

The MathfieldElement class is a DOM element that provides a math input field.

It is a subclass of the standard HTMLElement class and as such inherits all of its properties and methods, such as style, tabIndex, addEventListener(), getAttribute(), etc...

The MathfieldElement class provides additional properties and methods to control the display and behavior of <math-field> elements.

To instantiate a MathfieldElement use the <math-field> tag in HTML. You can also instantiate a MathfieldElement programmatically using new MathfieldElement().

// 1. Create a new MathfieldElement
const mf = new MathfieldElement();

// 2. Attach it to the DOM
document.body.appendChild(mf);

// 3. Modifying options after the mathfield has been attached to the DOM
mf.addEventListener("mount"), () => {
 mf.smartFence = true;
});

Read more about customizing the appearance and behavior of the mathfield in the Customizing the Mathfield guide.

MathfieldElement CSS Variables

To customize the appearance of the mathfield, declare the following CSS variables (custom properties) in a ruleset that applies to the mathfield.

math-field {
 --hue: 10       // Set the highlight color and caret to a reddish hue
}

Alternatively you can set these CSS variables programatically:

document.body.style.setProperty("--hue", "10");

Read more about the CSS variables available for customization.

You can customize the appearance and zindex of the virtual keyboard panel with some CSS variables associated with a selector that applies to the virtual keyboard panel container.

Read more about customizing the virtual keyboard appearance

MathfieldElement CSS Parts

In addition to the CSS variables, the mathfield exposes CSS parts that can be used to style the mathfield.

For example, to hide the menu button:

math-field::part(menu-toggle) {
   display: none;
}

MathfieldElement Attributes

An attribute is a key-value pair set as part of the <math-field> tag:

<math-field letter-shape-style="tex"></math-field>

The supported attributes are listed in the table below with their corresponding property, which can be changed directly on the MathfieldElement object:

 mf.value = "\\sin x";
 mf.letterShapeStyle = "tex";

The values of attributes and properties are reflected, which means you can change one or the other, for example:

mf.setAttribute("letter-shape-style",  "french");
console.log(mf.letterShapeStyle);
// Result: "french"

mf.letterShapeStyle ="tex";
console.log(mf.getAttribute("letter-shape-style");
// Result: "tex"

An exception is the value property, which is not reflected on the value attribute. For consistency with other DOM elements, the value attribute remains at its initial value.

Attribute Property
disabled mf.disabled
default-mode mf.defaultMode
letter-shape-style mf.letterShapeStyle
min-font-scale mf.minFontScale
max-matrix-cols mf.maxMatrixCols
popover-policy mf.popoverPolicy
math-mode-space mf.mathModeSpace
read-only mf.readOnly
remove-extraneous-parentheses mf.removeExtraneousParentheses
smart-fence mf.smartFence
smart-mode mf.smartMode
smart-superscript mf.smartSuperscript
inline-shortcut-timeout mf.inlineShortcutTimeout
script-depth mf.scriptDepth
value value
math-virtual-keyboard-policy mathVirtualKeyboardPolicy

See more details about these attributes.

In addition, the following DOM elements global attributes are supported:

  • class
  • data-*
  • hidden
  • id
  • item*
  • style
  • tabindex

MathfieldElement Events

To listen to these events use mf.addEventListener(). For events with additional arguments, the arguments are available in event.detail.

Event Name Description
beforeinput The value of the mathfield is about to be modified.
input The value of the mathfield has been modified. This happens on almost every keystroke in the mathfield. The evt.data property includes a copy of evt.inputType. See InputEvent
change The user has committed the value of the mathfield. This happens when the user presses Return or leaves the mathfield.
selection-change The selection (or caret position) in the mathfield has changed
mode-change The mode (math, text) of the mathfield has changed
undo-state-change The state of the undo stack has changed. The evt.detail.type indicate if a snapshot was taken or an undo performed.
read-aloud-status-change The status of a read aloud operation has changed
before-virtual-keyboard-toggle The visibility of the virtual keyboard panel is about to change. The evt.detail.visible property indicate if the keyboard will be visible or not. Listen for this event on window.mathVirtualKeyboard
virtual-keyboard-toggle The visibility of the virtual keyboard panel has changed. Listen for this event on window.mathVirtualKeyboard
geometrychange The geometry of the virtual keyboard has changed. The evt.detail.boundingRect property is the new bounding rectangle of the virtual keyboard. Listen for this event on window.mathVirtualKeyboard
blur The mathfield is losing focus
focus The mathfield is gaining focus
move-out The user has pressed an arrow key or the tab key, but there is nowhere to go. This is an opportunity to change the focus to another element if desired.
`detail: {direction: 'forward'
keypress The user pressed a physical keyboard key
mount The element has been attached to the DOM
unmount The element is about to be removed from the DOM

Extends

  • HTMLElement

new MathfieldElement()

new MathfieldElement(options?): MathfieldElement

To create programmatically a new mathfield use:

let mfe = new MathfieldElement();

// Set initial value and options
mfe.value = "\\frac{\\sin(x)}{\\cos(x)}";

// Options can be set either as an attribute (for simple options)...
mfe.setAttribute("letter-shape-style", "french");

// ... or using properties
mfe.letterShapeStyle = "french";

// Attach the element to the DOM
document.body.appendChild(mfe);
options?

Partial<MathfieldOptions>

Accessing and changing the content

MathfieldElement.errors

Return an array of LaTeX syntax errors, if any.

MathfieldElement.expression
get expression(): any
set expression(mathJson: any): void

If the Compute Engine library is available, return a boxed MathJSON expression representing the value of the mathfield.

To load the Compute Engine library, use:

import 'https://esm.run/@cortex-js/compute-engine';
MathfieldElement.value
get value(): string
set value(value: string): void

The content of the mathfield as a LaTeX expression.

document.querySelector('mf').value = '\\frac{1}{\\pi}'
MathfieldElement.getValue()
getValue(format)
getValue(format?): string

Return a textual representation of the content of the mathfield.

format?

OutputFormat

The format of the result. If using math-json the Compute Engine library must be loaded, for example with:

import "https://esm.run/@cortex-js/compute-engine";

Default: "latex"

getValue(start, end, format)
getValue(start, end, format?): string

Return the value of the mathfield from start to end

start

number

end

number

format?

OutputFormat

getValue(range, format)
getValue(range, format?): string

Return the value of the mathfield in range

range

Range

format?

OutputFormat

MathfieldElement.insert()
insert(s, options?): boolean

Insert a block of text at the current insertion point.

This method can be called explicitly or invoked as a selector with executeCommand("insert").

After the insertion, the selection will be set according to the options.selectionMode.

s

string

options?

InsertOptions

MathfieldElement.setValue()
setValue(value?, options?): void

Set the content of the mathfield to the text interpreted as a LaTeX expression.

value?

string

options?

InsertOptions

Selection

MathfieldElement.lastOffset

The last valid offset.

MathfieldElement.position
get position(): number
set position(offset: number): void

The position of the caret/insertion point, from 0 to lastOffset.

MathfieldElement.selection
get selection(): Readonly<Selection>
set selection(sel: number | Selection): void

An array of ranges representing the selection.

It is guaranteed there will be at least one element. If a discontinuous selection is present, the result will include more than one element.

MathfieldElement.selectionIsCollapsed
MathfieldElement.getOffsetFromPoint()
getOffsetFromPoint(x, y, options?): number

The offset closest to the location (x, y) in viewport coordinate.

bias: if 0, the vertical midline is considered to the left or right sibling. If -1, the left sibling is favored, if +1, the right sibling is favored.

x

number

y

number

options?
bias?

-1 | 0 | 1

MathfieldElement.select()
select(): void

Select the content of the mathfield.

Customization

MathfieldElement.restoreFocusWhenDocumentFocused
static restoreFocusWhenDocumentFocused: boolean = true;

When switching from a tab to one that contains a mathfield that was previously focused, restore the focus to the mathfield.

This is behavior consistent with <textarea>, however it can be disabled if it is not desired.

Default: true

MathfieldElement.backgroundColorMap
get backgroundColorMap(): (name) => string
set backgroundColorMap(value: (name) => string): void
MathfieldElement.colorMap
get colorMap(): (name) => string
set colorMap(value: (name) => string): void

Map a color name as used in commands such as \textcolor{}{} or \colorbox{}{} to a CSS color value.

Use this option to override the standard mapping of colors such as "yellow" or "red".

If the name is not one you expected, return undefined and the default color mapping will be applied.

If a backgroundColorMap() function is not provided, the colorMap() function will be used instead.

If colorMap() is not provided, default color mappings are applied.

The following color names have been optimized for a legible foreground and background values, and are recommended:

  • red, orange, yellow, lime, green, teal, blue, indigo, purple, magenta, black, dark-grey, grey, light-grey, white
MathfieldElement.defaultMode
get defaultMode(): "text" | "math" | "inline-math"
set defaultMode(value: "text" | "math" | "inline-math"): void

The mode of the element when it is empty:

  • "math": equivalent to \displaystyle (display math mode)
  • "inline-math": equivalent to \inlinestyle (inline math mode)
  • "text": text mode
MathfieldElement.environmentPopoverPolicy
get environmentPopoverPolicy(): "auto" | "off" | "on"
set environmentPopoverPolicy(value: "auto" | "off" | "on"): void

If "auto" a popover with commands to edit an environment (matrix) is displayed when the virtual keyboard is displayed.

Default: "auto"

MathfieldElement.letterShapeStyle
get letterShapeStyle(): "auto" | "tex" | "iso" | "french" | "upright"
set letterShapeStyle(value: "auto" | "tex" | "iso" | "french" | "upright"): void

Control the letter shape style:

letterShapeStyle xyz ABC αβɣ ΓΔΘ
iso it it it it
tex it it it up
french it up up up
upright up up up up

(it) = italic (up) = upright

The default letter shape style is auto, which indicates that french should be used if the locale is "french", and tex otherwise.

Historical Note

Where do the "french" rules come from? The TeX standard font, Computer Modern, is based on Monotype 155M, itself based on the Porson greek font which was one of the most widely used Greek fonts in english-speaking countries. This font had upright capitals, but slanted lowercase. In France, the traditional font for greek was Didot, which has both upright capitals and lowercase.

As for roman uppercase, they are recommended by "Lexique des règles typographiques en usage à l’Imprimerie Nationale". It should be noted that this convention is not universally followed.

MathfieldElement.mathModeSpace
get mathModeSpace(): string
set mathModeSpace(value: string): void

The LaTeX string to insert when the spacebar is pressed (on the physical or virtual keyboard).

Use "\;" for a thick space, "\:" for a medium space, "\," for a thin space.

Do not use " " (a regular space), as whitespace is skipped by LaTeX so this will do nothing.

Default: "" (empty string)

MathfieldElement.maxMatrixCols
get maxMatrixCols(): number
set maxMatrixCols(value: number): void

Sets the maximum number of columns for the matrix environment. The default is 10 columns to match the behavior of the amsmath matrix environment. Default: 10

MathfieldElement.minFontScale
get minFontScale(): number
set minFontScale(value: number): void

Set the minimum relative font size for nested superscripts and fractions. The value should be a number between 0 and 1. The size is in releative em units relative to the font size of the math-field element. Specifying a value of 0 allows the math-field to use its default sizing logic.

Default: 0

MathfieldElement.placeholder
get placeholder(): string
set placeholder(value: string): void

A LaTeX string displayed inside the mathfield when there is no content.

MathfieldElement.placeholderSymbol
get placeholderSymbol(): string
set placeholderSymbol(value: string): void

The symbol used to represent a placeholder in an expression.

Default: U+25A2 WHITE SQUARE WITH ROUNDED CORNERS

MathfieldElement.popoverPolicy
get popoverPolicy(): "auto" | "off"
set popoverPolicy(value: "auto" | "off"): void

If "auto" a popover with suggestions may be displayed when a LaTeX command is input.

Default: "auto"

MathfieldElement.removeExtraneousParentheses
get removeExtraneousParentheses(): boolean
set removeExtraneousParentheses(value: boolean): void

If true, extra parentheses around a numerator or denominator are removed automatically.

Default: true

MathfieldElement.scriptDepth
get scriptDepth(): number | [number, number]
set scriptDepth(value: number | [number, number]): void

This option controls how many levels of subscript/superscript can be entered. For example, if scriptDepth is "1", there can be one level of superscript or subscript. Attempting to enter a superscript while inside a superscript will be rejected. Setting a value of 0 will prevent entry of any superscript or subscript (but not limits for sum, integrals, etc...)

This can make it easier to enter equations that fit what's expected for the domain where the mathfield is used.

To control the depth of superscript and subscript independently, provide an array: the first element indicate the maximum depth for subscript and the second element the depth of superscript. Thus, a value of [0, 1] would suppress the entry of subscripts, and allow one level of superscripts.

MathfieldElement.smartFence
get smartFence(): boolean
set smartFence(value: boolean): void

When true and an open fence is entered via typedText() it will generate a contextually appropriate markup, for example using \left...\right if applicable.

When false, the literal value of the character will be inserted instead.

MathfieldElement.smartMode
get smartMode(): boolean
set smartMode(value: boolean): void

When true, during text input the field will switch automatically between 'math' and 'text' mode depending on what is typed and the context of the formula. If necessary, what was previously typed will be 'fixed' to account for the new info.

For example, when typing "if x >0":

Type Interpretation
i math mode, imaginary unit
if text mode, english word "if"
if x all in text mode, maybe the next word is xylophone?
if x > "if" stays in text mode, but now "x >" is in math mode
if x > 0 "if" in text mode, "x > 0" in math mode

Default: false

Manually switching mode (by typing alt/option+=) will temporarily turn off smart mode.

Examples

  • slope = rise/run
  • If x > 0, then f(x) = sin(x)
  • x^2 + sin (x) when x > 0
  • When x&lt;0, x^{2n+1}&lt;0
  • Graph x^2 -x+3 =0 for 0&lt;=x&lt;=5
  • Divide by x-3 and then add x^2-1 to both sides
  • Given g(x) = 4x – 3, when does g(x)=0?
  • Let D be the set {(x,y)|0&lt;=x&lt;=1 and 0&lt;=y&lt;=x}
  • \int\_{the unit square} f(x,y) dx dy
  • For all n in NN
MathfieldElement.smartSuperscript
get smartSuperscript(): boolean
set smartSuperscript(value: boolean): void

When true and a digit is entered in an empty superscript, the cursor leaps automatically out of the superscript. This makes entry of common polynomials easier and faster. If entering other characters (for example "n+1") the navigation out of the superscript must be done manually (by using the cursor keys or the spacebar to leap to the next insertion point).

When false, the navigation out of the superscript must always be done manually.

Styles

MathfieldElement.onInsertStyle
get onInsertStyle(): InsertStyleHook
set onInsertStyle(value: InsertStyleHook): void
MathfieldElement.applyStyle()
applyStyle(style, options?): void

Update the style (color, bold, italic, etc...) of the selection or sets the style to be applied to future input.

If there is no selection and no range is specified, the style will apply to the next character typed.

If a range is specified, the style is applied to the range, otherwise, if there is a selection, the style is applied to the selection.

If the operation is "toggle" and the range already has this style, remove it. If the range has the style partially applied (i.e. only some sections), remove it from those sections, and apply it to the entire range.

If the operation is "set", the style is applied to the range, whether it already has the style or not.

The default operation is "set".

style

Readonly<Style>

options?

Range | { operation: "set" | "toggle"; range: Range; }

MathfieldElement.queryStyle()
queryStyle(style): "some" | "all" | "none"

If there is a selection, return if all the atoms in the selection, some of them or none of them match the style argument.

If there is no selection, return 'all' if the current implicit style (determined by a combination of the style of the previous atom and the current style) matches the style argument, 'none' if it does not.

style

Readonly<Style>

Macros

MathfieldElement.macros
get macros(): Readonly<MacroDictionary>
set macros(value: MacroDictionary): void

A dictionary of LaTeX macros to be used to interpret and render the content.

For example, to add a new macro to the default macro dictionary:

mf.macros = {
...mf.macros,
smallfrac: '^{#1}\\!\\!/\\!_{#2}',
};

Note that ...mf.macros is used to keep the existing macros and add to them. Otherwise, all the macros are replaced with the new definition.

The code above will support the following notation:

\smallfrac{5}{16}

Registers

MathfieldElement.registers
get registers(): Registers
set registers(value: Registers): void

TeX registers represent "variables" and "constants".

Changing the values of some registers can modify the layout of math expressions.

The following registers might be of interest:

  • thinmuskip: space between items of math lists
  • medmuskip: space between binary operations
  • thickmuskip: space between relational operators
  • nulldelimiterspace: minimum space to leave blank in delimiter constructions, for example around a fraction
  • delimitershortfall: maximum space to overlap adjacent elements when a delimiter is too short
  • jot: space between lines in an array, or between rows in a multiline construct
  • arraycolsep: space between columns in an array
  • arraystretch: factor by which to stretch the height of each row in an array

To modify a register, use:

mf.registers.arraystretch = 1.5;
mf.registers.thinmuskip = { dimension: 2, unit: "mu" };
mf.registers.medmuskip = "3mu";

Speech

MathfieldElement.readAloudHook()
static readAloudHook: (element, text) => void = defaultReadAloudHook;
MathfieldElement.speakHook()
static speakHook: (text) => void = defaultSpeakHook;
MathfieldElement.speechEngine
get static speechEngine(): "amazon" | "local"
set static speechEngine(value: "amazon" | "local"): void

Indicates which speech engine to use for speech output.

Use local to use the OS-specific TTS engine.

Use amazon for Amazon Text-to-Speech cloud API. You must include the AWS API library and configure it with your API key before use.

See mathfield/guides/speech/ | Guide: Speech

MathfieldElement.speechEngineRate
get static speechEngineRate(): string
set static speechEngineRate(value: string): void

Sets the speed of the selected voice.

One of x-slow, slow, medium, fast, x-fast or a value as a percentage.

Range is 20% to 200% For example 200% to indicate a speaking rate twice the default rate.

MathfieldElement.speechEngineVoice
get static speechEngineVoice(): string
set static speechEngineVoice(value: string): void

Indicates the voice to use with the speech engine.

This is dependent on the speech engine. For Amazon Polly, see here: https://docs.aws.amazon.com/polly/latest/dg/voicelist.html

MathfieldElement.textToSpeechMarkup
get static textToSpeechMarkup(): "" | "ssml" | "ssml_step" | "mac"
set static textToSpeechMarkup(value: "" | "ssml" | "ssml_step" | "mac"): void

The markup syntax to use for the output of conversion to spoken text.

Possible values are ssml for the SSML markup or mac for the macOS markup, i.e. &#91;&#91;ltr&#93;&#93;.

MathfieldElement.textToSpeechRules
get static textToSpeechRules(): "sre" | "mathlive"
set static textToSpeechRules(value: "sre" | "mathlive"): void

Specify which set of text to speech rules to use.

A value of mathlive indicates that the simple rules built into MathLive should be used.

A value of sre indicates that the Speech Rule Engine from Volker Sorge should be used.

(Caution) SRE is not included or loaded by MathLive. For this option to work SRE should be loaded separately.

See mathfield/guides/speech/ | Guide: Speech

MathfieldElement.textToSpeechRulesOptions
get static textToSpeechRulesOptions(): Readonly<Record<string, string>>
set static textToSpeechRulesOptions(value: Record<string, string>): void

A set of key/value pairs that can be used to configure the speech rule engine.

Which options are available depends on the speech rule engine in use. There are no options available with MathLive's built-in engine. The options for the SRE engine are documented here

Focus

MathfieldElement.blur()
blur(): void

Remove the focus from the mathfield (will no longer respond to keyboard input).

MathfieldElement.focus()
focus(): void

Sets the focus to the mathfield (will respond to keyboard input).

MathfieldElement.hasFocus()
hasFocus(): boolean

Return true if the mathfield is currently focused (responds to keyboard input).

Prompts

MathfieldElement.getPromptRange()
getPromptRange(id): Range

Return the selection range for the specified prompt.

This can be used for example to select the content of the prompt.

mf.selection = mf.getPromptRange('my-prompt-id');
id

string

MathfieldElement.getPrompts()
getPrompts(filter?): string[]

Return the id of the prompts matching the filter.

filter?
correctness?

"undefined" | "correct" | "incorrect"

id?

string

locked?

boolean

MathfieldElement.getPromptState()
getPromptState(id): ["correct" | "incorrect", boolean]
id

string

MathfieldElement.getPromptValue()
getPromptValue(placeholderId, format?): string

Return the content of the \placeholder{} command with the placeholderId

placeholderId

string

format?

OutputFormat

MathfieldElement.setPromptState()
setPromptState(id, state, locked?): void
id

string

state

"undefined" | "correct" | "incorrect"

locked?

boolean

MathfieldElement.setPromptValue()
setPromptValue(id, content, insertOptions): void
id

string

content

string

insertOptions

Omit<InsertOptions, "insertionMode">

Undo

MathfieldElement.canRedo()
canRedo(): boolean

Return whether there are redoable items

MathfieldElement.canUndo()
canUndo(): boolean

Return whether there are undoable items

MathfieldElement.resetUndo()
resetUndo(): void

Reset the undo stack

Keyboard Shortcuts

MathfieldElement.inlineShortcuts
get inlineShortcuts(): Readonly<InlineShortcutDefinitions>
set inlineShortcuts(value: InlineShortcutDefinitions): void

The keys of this object literal indicate the sequence of characters that will trigger an inline shortcut.

MathfieldElement.inlineShortcutTimeout
get inlineShortcutTimeout(): number
set inlineShortcutTimeout(value: number): void

Maximum time, in milliseconds, between consecutive characters for them to be considered part of the same shortcut sequence.

A value of 0 is the same as infinity: any consecutive character will be candidate for an inline shortcut, regardless of the interval between this character and the previous one.

A value of 750 will indicate that the maximum interval between two characters to be considered part of the same inline shortcut sequence is 3/4 of a second.

This is useful to enter "+-" as a sequence of two characters, while also supporting the "±" shortcut with the same sequence.

The first result can be entered by pausing slightly between the first and second character if this option is set to a value of 250 or so.

Note that some operations, such as clicking to change the selection, or losing the focus on the mathfield, will automatically timeout the shortcuts.

MathfieldElement.keybindings
get keybindings(): readonly Keybinding[]
set keybindings(value: readonly Keybinding[]): void

Menu

MathfieldElement.menuItems
get menuItems(): readonly MenuItem[]
set menuItems(menuItems: readonly MenuItem[]): void
MathfieldElement.showMenu()
showMenu(_): boolean
_
location

{ x: number; y: number; }

location.x

number

location.y

number

modifiers

KeyboardModifiers

Virtual Keyboard

MathfieldElement.keypressVibration
static keypressVibration: boolean = true;

When a key on the virtual keyboard is pressed, produce a short haptic feedback, if the device supports it.

MathfieldElement.mathVirtualKeyboardPolicy
get mathVirtualKeyboardPolicy(): VirtualKeyboardPolicy
set mathVirtualKeyboardPolicy(value: VirtualKeyboardPolicy): void
MathfieldElement.virtualKeyboardTargetOrigin
get virtualKeyboardTargetOrigin(): string
set virtualKeyboardTargetOrigin(value: string): void
MathfieldElement.keypressSound
get static keypressSound(): Readonly<{
  default: string;
  delete: string;
  return: string;
  spacebar: string;
}>
set static keypressSound(value: 
  | string
  | {
  default: string;
  delete: string;
  return: string;
  spacebar: string;
 }): void

When a key on the virtual keyboard is pressed, produce a short audio feedback.

If the property is set to a string, the same sound is played in all cases. Otherwise, a distinct sound is played:

  • delete a sound played when the delete key is pressed
  • return ... when the return/tab key is pressed
  • spacebar ... when the spacebar is pressed
  • default ... when any other key is pressed. This property is required, the others are optional. If they are missing, this sound is played as well.

The value of the properties should be either a string, the name of an audio file in the soundsDirectory directory or null to suppress the sound.

If the soundsDirectory is null, no sound will be played.

MathfieldElement.soundsDirectory
get static soundsDirectory(): string
set static soundsDirectory(value: string): void

A URL fragment pointing to the directory containing the optional sounds used to provide feedback while typing.

Some default sounds are available in the /dist/sounds directory of the SDK.

Use null to prevent any sound from being loaded.

Localization

MathfieldElement.decimalSeparator
get static decimalSeparator(): "," | "."
set static decimalSeparator(value: "," | "."): void

The symbol used to separate the integer part from the fractional part of a number.

When "," is used, the corresponding LaTeX string is {,}, in order to ensure proper spacing (otherwise an extra gap is displayed after the comma).

This affects:

  • what happens when the , key is pressed (if decimalSeparator is ",", the {,} LaTeX string is inserted when following some digits)
  • the label and behavior of the "." key in the default virtual keyboard

Default: "."

MathfieldElement.fractionNavigationOrder
get static fractionNavigationOrder(): "denominator-numerator" | "numerator-denominator"
set static fractionNavigationOrder(s: "denominator-numerator" | "numerator-denominator"): void

When using the keyboard to navigate a fraction, the order in which the numerator and navigator are traversed:

  • "numerator-denominator": first the elements in the numerator, then the elements in the denominator.
  • "denominator-numerator": first the elements in the denominator, then the elements in the numerator. In some East-Asian cultures, fractions are read and written denominator first ("fēnzhī"). With this option the keyboard navigation follows this convention.

Default: "numerator-denominator"

MathfieldElement.locale
get static locale(): string
set static locale(value: string): void

The locale (language + region) to use for string localization.

If none is provided, the locale of the browser is used.

MathfieldElement.strings
get static strings(): Readonly<Record<string, Record<string, string>>>
set static strings(value: Record<string, Record<string, string>>): void

An object whose keys are a locale string, and whose values are an object of string identifier to localized string.

Example

mf.strings = {
  "fr-CA": {
      "tooltip.undo": "Annuler",
      "tooltip.redo": "Refaire",
  }
}

If the locale is already supported, this will override the existing strings. If the locale is not supported, it will be added.

Other

MathfieldElement.createHTML()
static createHTML: (html) => any;

Support for Trusted Type.

This optional function will be called before a string of HTML is injected in the DOM, allowing that string to be sanitized according to a policy defined by the host.

Consider using this option if you are displaying untrusted content. Read more about Security Considerations

MathfieldElement.version
static version: string = '0.105.2';
MathfieldElement.disabled
get disabled(): boolean
set disabled(value: boolean): void
MathfieldElement.mode
get mode(): ParseMode
set mode(value: ParseMode): void
MathfieldElement.readonly
get readonly(): boolean
set readonly(value: boolean): void
MathfieldElement.readOnly
get readOnly(): boolean
set readOnly(value: boolean): void
MathfieldElement.computeEngine
get static computeEngine(): ComputeEngine
set static computeEngine(value: ComputeEngine): void

A custom compute engine instance. If none is provided, a default one is used. If null is specified, no compute engine is used.

MathfieldElement.fontsDirectory
get static fontsDirectory(): string
set static fontsDirectory(value: string): void

A URL fragment pointing to the directory containing the fonts necessary to render a formula.

These fonts are available in the /fonts directory of the npm package.

Customize this value to reflect where you have copied these fonts, or to use the CDN version.

The default value is "./fonts". Use null to prevent any fonts from being loaded.

Changing this setting after the mathfield has been created will have no effect.

{
     // Use the CDN version
     fontsDirectory: ''
}
{
     // Use a directory called "fonts", located next to the
     // `mathlive.js` (or `mathlive.mjs`) file.
     fontsDirectory: './fonts'
}
{
     // Use a directory located at the root of your website
     fontsDirectory: 'https://example.com/fonts'
}
MathfieldElement.isFunction
get static isFunction(): (command) => boolean
set static isFunction(value: (command) => boolean): void
MathfieldElement.plonkSound
get static plonkSound(): string
set static plonkSound(value: string): void

Sound played to provide feedback when a command has no effect, for example when pressing the spacebar at the root level.

The property is either:

  • a string, the name of an audio file in the soundsDirectory directory
  • null to turn off the sound

If the soundsDirectory is null, no sound will be played.

MathfieldElement.getElementInfo()
getElementInfo(offset): ElementInfo
offset

number

MathfieldElement.loadSound()
static loadSound(sound): Promise<void>
sound

"keypress" | "plonk" | "delete" | "spacebar" | "return"

MathfieldElement.openUrl()
static openUrl(href): void
href

string

MathfieldElement.playSound()
static playSound(name): Promise<void>
name

"keypress" | "plonk" | "delete" | "spacebar" | "return"

Commands

MathfieldElement.executeCommand()
executeCommand(selector)
executeCommand(selector): boolean

Execute a command defined by a selector.

mfe.executeCommand('add-column-after');
mfe.executeCommand(['switch-mode', 'math']);
selector

Selector

A selector, or an array whose first element is a selector, and whose subsequent elements are arguments to the selector.

Selectors can be passed either in camelCase or kebab-case.

// Both calls do the same thing
mfe.executeCommand('selectAll');
mfe.executeCommand('select-all');
executeCommand(selector, args)
executeCommand(selector, ...args): boolean

Execute a command defined by a selector.

mfe.executeCommand('add-column-after');
mfe.executeCommand(['switch-mode', 'math']);
selector

Selector

A selector, or an array whose first element is a selector, and whose subsequent elements are arguments to the selector.

Selectors can be passed either in camelCase or kebab-case.

// Both calls do the same thing
mfe.executeCommand('selectAll');
mfe.executeCommand('select-all');
args

...unknown[]

executeCommand(selector)
executeCommand(selector): boolean

Execute a command defined by a selector.

mfe.executeCommand('add-column-after');
mfe.executeCommand(['switch-mode', 'math']);
selector

[Selector, ...unknown[]]

A selector, or an array whose first element is a selector, and whose subsequent elements are arguments to the selector.

Selectors can be passed either in camelCase or kebab-case.

// Both calls do the same thing
mfe.executeCommand('selectAll');
mfe.executeCommand('select-all');

Hooks

MathfieldElement.onExport
get onExport(): (from, latex, range) => string
set onExport(value: (from, latex, range) => string): void

This hook is invoked when the user has requested to export the content of the mathfield, for example when pressing ctrl/command+C.

This hook should return as a string what should be exported.

The range argument indicates which portion of the mathfield should be exported. It is not always equal to the current selection, but it can be used to export a format other than LaTeX.

By default this is:

 return `\\begin{equation*}${latex}\\end{equation*}`;
MathfieldElement.onInlineShortcut
get onInlineShortcut(): (sender, symbol) => string
set onInlineShortcut(value: (sender, symbol) => string): void

A hook invoked when a string of characters that could be interpreted as shortcut has been typed.

If not a special shortcut, return the empty string "".

Use this handler to detect multi character symbols, and return them wrapped appropriately, for example \mathrm{${symbol}}.

MathfieldElement.onScrollIntoView
get onScrollIntoView(): (sender) => void
set onScrollIntoView(value: (sender) => void): void

A hook invoked when scrolling the mathfield into view is necessary.

Use when scrolling the page would not solve the problem, e.g. when the mathfield is in another div that has scrollable content.

MathfieldElementAttributes

These attributes of the <math-field> element correspond to matching properties.

Indexable

[key: string]: unknown
MathfieldElementAttributes.default-mode
default-mode: string;
MathfieldElementAttributes.inline-shortcut-timeout
inline-shortcut-timeout: string;

Maximum time, in milliseconds, between consecutive characters for them to be considered part of the same shortcut sequence.

A value of 0 is the same as infinity: any consecutive character will be candidate for an inline shortcut, regardless of the interval between this character and the previous one.

A value of 750 will indicate that the maximum interval between two characters to be considered part of the same inline shortcut sequence is 3/4 of a second.

This is useful to enter "+-" as a sequence of two characters, while also supporting the "±" shortcut with the same sequence.

The first result can be entered by pausing slightly between the first and second character if this option is set to a value of 250 or so.

Note that some operations, such as clicking to change the selection, or losing the focus on the mathfield, will automatically timeout the shortcuts.

MathfieldElementAttributes.letter-shape-style
letter-shape-style: string;
MathfieldElementAttributes.math-mode-space
math-mode-space: string;

The LaTeX string to insert when the spacebar is pressed (on the physical or virtual keyboard). Empty by default. Use \; for a thick space, \: for a medium space, \, for a thin space.

MathfieldElementAttributes.math-virtual-keyboard-policy
math-virtual-keyboard-policy: VirtualKeyboardPolicy;
  • "auto": the virtual keyboard is triggered when a mathfield is focused on a touch capable device.
  • "manual": the virtual keyboard is not triggered automatically
  • "sandboxed": the virtual keyboard is displayed in the current browsing context (iframe) if it has a defined container or is the top-level browsing context.
MathfieldElementAttributes.max-matrix-cols
max-matrix-cols: number;
MathfieldElementAttributes.min-font-scale
min-font-scale: number;
MathfieldElementAttributes.placeholder
placeholder: string;

When the mathfield is empty, display this placeholder LaTeX string instead

MathfieldElementAttributes.popover-policy
popover-policy: string;
MathfieldElementAttributes.read-only
read-only: boolean;

When true, the user cannot edit the mathfield.

MathfieldElementAttributes.remove-extraneous-parentheses
remove-extraneous-parentheses: boolean;
MathfieldElementAttributes.script-depth
script-depth: string;
MathfieldElementAttributes.smart-fence
smart-fence: string;

When on and an open fence is entered via typedText() it will generate a contextually appropriate markup, for example using \left...\right if applicable.

When off, the literal value of the character will be inserted instead.

MathfieldElementAttributes.smart-mode
smart-mode: string;

When on, during text input the field will switch automatically between 'math' and 'text' mode depending on what is typed and the context of the formula. If necessary, what was previously typed will be 'fixed' to account for the new info.

For example, when typing "if x >0":

Type Interpretation
"i" math mode, imaginary unit
"if" text mode, english word "if"
"if x" all in text mode, maybe the next word is xylophone?
"if x >" "if" stays in text mode, but now "x >" is in math mode
"if x > 0" "if" in text mode, "x > 0" in math mode

Smart Mode is off by default.

Manually switching mode (by typing alt/option+=) will temporarily turn off smart mode.

Examples

  • slope = rise/run
  • If x > 0, then f(x) = sin(x)
  • x^2 + sin (x) when x > 0
  • When x<0, x^&#007b;2n+1&#007d;<0
  • Graph x^2 -x+3 =0 for 0<=x<=5
  • Divide by x-3 and then add x^2-1 to both sides
  • Given g(x) = 4x – 3, when does g(x)=0?
  • Let D be the set &#007b;(x,y)|0<=x<=1 and 0<=y<=x&#007d;
  • \int_&#007b;the unit square&#007d; f(x,y) dx dy
  • For all n in NN
MathfieldElementAttributes.smart-superscript
smart-superscript: string;

When on, when a digit is entered in an empty superscript, the cursor leaps automatically out of the superscript. This makes entry of common polynomials easier and faster. If entering other characters (for example "n+1") the navigation out of the superscript must be done manually (by using the cursor keys or the spacebar to leap to the next insertion point).

When off, the navigation out of the superscript must always be done manually.

MathfieldElementAttributes.virtual-keyboard-target-origin
virtual-keyboard-target-origin: string;

Specify the targetOrigin parameter for postMessage to send control messages from child to parent frame to remote control of mathfield component.

Default: window.origin

ElementInfo

Some additional information about an element of the formula returned by mf.getElementInfo().

ElementInfo.bounds?
optional bounds: DOMRect;

The bounding box of the element

ElementInfo.data?
optional data: Record<string, string | undefined>;

HTML attributes associated with element or its ancestores, set with \htmlData

ElementInfo.depth?
optional depth: number;

The depth in the expression tree. 0 for top-level elements

ElementInfo.id?
optional id: string;

id associated with this element or its ancestor, set with \htmlId or \cssId

ElementInfo.latex?
optional latex: string;

A LaTeX representation of the element

ElementInfo.mode?
optional mode: ParseMode;

The mode (math, text or LaTeX)

ElementInfo.style?
optional style: Style;

The style (color, weight, variant, etc...) of this element.

InsertOptions

InsertOptions.feedback?
optional feedback: boolean;

If true, provide audio and haptic feedback

InsertOptions.focus?
optional focus: boolean;

If true, the mathfield will be focused after the insertion

InsertOptions.format?
optional format: OutputFormat | "auto";

The format of the input string:

"auto" The string is a LaTeX fragment or command (default)
"latex" The string is a LaTeX fragment
InsertOptions.insertionMode?
optional insertionMode: "replaceSelection" | "replaceAll" | "insertBefore" | "insertAfter";
InsertOptions.mode?
optional mode: ParseMode | "auto";

If "auto" or omitted, the current mode is used

InsertOptions.scrollIntoView?
optional scrollIntoView: boolean;

If true, scroll the mathfield into view after insertion such that the insertion point is visible

InsertOptions.selectionMode?
optional selectionMode: "placeholder" | "after" | "before" | "item";

Describes where the selection will be after the insertion:

"placeholder" The selection will be the first available placeholder in the text that has been inserted (default)
"after" The selection will be an insertion point after the inserted text
"before" The selection will be an insertion point before the inserted text
"item" The inserted text will be selected
InsertOptions.silenceNotifications?
optional silenceNotifications: boolean;

If true, silence notifications during insertion

InsertOptions.style?
optional style: Style;

The style applied to the inserted content

MoveOutEvent

Event re-targeting

Some events bubble up through the DOM tree, so that they are detectable by any element on the page.

Bubbling events fired from within shadow DOM are re-targeted so that, to any listener external to your component, they appear to come from your component itself.

Custom Event Bubbling

By default, a bubbling custom event fired inside shadow DOM will stop bubbling when it reaches the shadow root.

To make a custom event pass through shadow DOM boundaries, you must set both the composed and bubbles flags to true.

The move-out event signals that the user pressed an arrow key or tab key but there was no navigation possible inside the mathfield.

This event provides an opportunity to handle this situation, for example by focusing an element adjacent to the mathfield.

If the event is canceled (i.e. evt.preventDefault() is called inside your event handler), the default behavior is to play a "plonk" sound.

MoveOutEvent.direction
direction: "forward" | "backward" | "upward" | "downward";

OutputFormat

type OutputFormat = 
  | "ascii-math"
  | "latex"
  | "latex-expanded"
  | "latex-unstyled"
  | "latex-without-placeholders"
  | "math-json"
  | "math-ml"
  | "plain-text"
  | "spoken"
  | "spoken-text"
  | "spoken-ssml"
  | "spoken-ssml-with-highlighting";
Format Description
"ascii-math" A string of ASCIIMath.
"latex" LaTeX rendering of the content, with LaTeX macros not expanded.
"latex-expanded" All macros are recursively expanded to their definition.
"latex-unstyled" Styling (background color, color) is ignored
"latex-without-placeholders" Replace \placeholder commands with their body
"math-json" A MathJSON abstract syntax tree, as an object literal formated as a JSON string. Note: you must import the CortexJS Compute Engine to obtain a result.
"math-ml" A string of MathML markup.
"plain-text" A plain text rendering of the content.
"spoken" Spoken text rendering, using the default format defined in config, which could be either text or SSML markup.
"spoken-text" A plain spoken text rendering of the content.
"spoken-ssml" A SSML (Speech Synthesis Markup Language) version of the content, which can be used with some text-to-speech engines such as AWS.
"spoken-ssml-with-highlighting" Like "spoken-ssml" but with additional annotations necessary for synchronized highlighting (read aloud).

To use the"math-json" format the Compute Engine library must be loaded. Use for example:

import "https://esm.run/@cortex-js/compute-engine";

Selection

Offset

type Offset = number;

Position of the caret/insertion point from the beginning of the formula. The first position is 0. The last valid offset is mf.lastOffset.

See Also

Range

type Range = [Offset, Offset];

A pair of offsets (boundary points) that denote a fragment of a formula.

A range is said to be collapsed when start and end are equal.

When specifying a range, a negative offset can be used to indicate an offset relative to the last valid offset, i.e. -1 is the last valid offset, -2 is one offset before that, etc...

A normalized range will always be such that start <= end, start >= 0, end >= 0, start < lastOffset, end < lastOffset. All the methods return a normalized range.

See Also

Selection

A selection is a set of ranges (to support discontinuous selection, for example when selecting a column in a matrix).

If there is a single range and that range is collapsed, the selection is collapsed.

A selection can also have a direction. While many operations are insensitive to the direction, a few are. For example, when selecting a fragment of a formula from left to right, the direction of this range will be "forward".

Pressing the left arrow key will sets the insertion at the start of the range.

Conversely, if the selection is made from right to left, the direction is "backward" and pressing the left arrow key will set the insertion point at the end of the range.

See Also

Selection.direction?
optional direction: "forward" | "backward" | "none";
Selection.ranges
ranges: Range[];

Styles

Style

Style.backgroundColor?
optional backgroundColor: string;
Style.color?
optional color: string;
Style.fontFamily?
optional fontFamily: FontFamily;
Style.fontSeries?
optional fontSeries: FontSeries;
Style.fontShape?
optional fontShape: FontShape;
Style.fontSize?
optional fontSize: "auto" | FontSize;
Style.variant?
optional variant: Variant;
Style.variantStyle?
optional variantStyle: VariantStyle;

ApplyStyleOptions

ApplyStyleOptions.operation?
optional operation: "set" | "toggle";
ApplyStyleOptions.range?
optional range: Range;
ApplyStyleOptions.silenceNotifications?
optional silenceNotifications: boolean;

FontFamily

type FontFamily = "none" | "roman" | "monospace" | "sans-serif";

FontSeries

type FontSeries = "auto" | "m" | "b" | "l" | "";

FontShape

type FontShape = "auto" | "n" | "it" | "sl" | "sc" | "";

FontSize

type FontSize = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;

InsertStyleHook()

type InsertStyleHook = (sender, at, info) => Readonly<Style>;

MathstyleName

type MathstyleName = "displaystyle" | "textstyle" | "scriptstyle" | "scriptscriptstyle";

Variant

type Variant = 
  | "ams"
  | "double-struck"
  | "calligraphic"
  | "script"
  | "fraktur"
  | "sans-serif"
  | "monospace"
  | "normal"
  | "main"
  | "math";

Variants indicate a stylistic alternate for some characters.

Typically, those are controlled with explicit commands, such as \mathbb{} or \mathfrak{}. This type is used with the MathfieldElement.applyStyle method to change the styling of a range of selected characters.

In mathematical notation these variants are used not only for visual presentation, but they may have semantic significance.

For example,

  • the set ℂ should not be confused with
  • the physical unit 𝖢 (Coulomb).

When rendered, these variants can map to some built-in fonts.

LaTeX supports a limited set of characters. However, MathLive will map characters not supported by LaTeX fonts (double-stuck variant for digits for example) to a Unicode character (see Mathematical Alphanumeric Symbols on Wikipedia ).

normal is a synthetic variant that maps either to main (upright) or math (italic) depending on the symbol and the letterShapeStyle.

The math variant has italic characters as well as slightly different letter shape and spacing (a bit more space after the "f" for example), so it's not equivalent to a main variant with italic variant style applied.

See Also

VariantStyle

type VariantStyle = "up" | "bold" | "italic" | "bolditalic" | "";

Some variants support stylistic variations.

Note that these stylistic variations support a limited set of characters, typically just uppercase and lowercase letters, and digits 0-9 in some cases.

variant up bold italic bolditalic
normal ABCabc012 𝐀𝐁𝐂𝐚𝐛𝐜𝟎𝟏𝟐 𝐴𝐵𝐶𝑎𝑏𝑐 𝑨𝑩𝑪𝒂𝒃𝒄
double-struck 𝔸𝔹ℂ𝕒𝕓𝕔𝟘𝟙𝟚 n/a n/a n/a
calligraphic 𝒜ℬ𝒞𝒶𝒷𝒸 𝓐𝓑𝓒𝓪𝓫𝓬 n/a n/a
fraktur 𝔄𝔅ℭ𝔞𝔟𝔠 𝕬𝕭𝕮𝖆𝖇𝖈 n/a n/a
sans-serif 𝖠𝖡𝖢𝖺𝖻𝖼𝟢𝟣𝟤 𝗔𝗕𝗖𝗮𝗯𝗰𝟬𝟭𝟮 𝘈𝘉𝘊𝘢𝘣𝘤 𝘼𝘽𝘾𝙖𝙗𝙘
monospace 𝙰𝙱𝙲𝚊𝚋𝚌 n/a n/a n/a

Macros

MacroDefinition

See Also

MacroDefinition.args?
optional args: number;

Number of arguments (#1, etc...) in the macro definition

MacroDefinition.captureSelection?
optional captureSelection: boolean;

If false elements inside the macro can be selected

MacroDefinition.def
def: string;

Definition of the macro as a LaTeX expression

MacroDefinition.expand?
optional expand: boolean;

If false, even if expandMacro is true, do not expand.

MacroDictionary

type MacroDictionary = Record<string, 
  | string
  | Partial<MacroDefinition>
| MacroPackageDefinition>;

A dictionary of LaTeX macros to be used to interpret and render the content.

For example:

mf.macros = { smallfrac: "^{#1}\\!\\!/\\!_{#2}" };

The code above will support the following notation:

\smallfrac{5}{16}

See Also

MacroPackageDefinition

MacroPackageDefinition.captureSelection?
optional captureSelection: boolean;
MacroPackageDefinition.package
package: Record<string, string | MacroDefinition>;
MacroPackageDefinition.primitive?
optional primitive: boolean;

NormalizedMacroDictionary

type NormalizedMacroDictionary = Record<string, MacroDefinition>;

Registers

Dimension

A dimension is used to specify the size of things

Dimension.dimension
dimension: number;
Dimension.unit?
optional unit: DimensionUnit;

DimensionUnit

type DimensionUnit = 
  | "pt"
  | "mm"
  | "cm"
  | "ex"
  | "px"
  | "em"
  | "bp"
  | "dd"
  | "pc"
  | "in"
  | "mu"
  | "fil"
  | "fill"
  | "filll";

Glue

Glue represents flexible spacing, that is a dimension that can grow (by the grow property) or shrink (by the shrink property).

Glue.glue
glue: Dimension;
Glue.grow?
optional grow: Dimension;
Glue.shrink?
optional shrink: Dimension;

LatexValue

type LatexValue = {
  relax: boolean;
 } & 
  | Dimension
  | Glue
  | {
  string: string;
 }
  | {
  base: "decimal" | "octal" | "hexadecimal" | "alpha";
  number: number;
 }
  | {
  factor: number;
  global: boolean;
  register: string;
};

A LaTeX expression represent a sequence of tokens that can be evaluated to a value, such as a dimension.

Registers

type Registers = Record<string, number | string | LatexValue>;

TeX registers represent "variables" and "constants".

Changing the values of some registers can modify the layout of math expressions.

The following registers might be of interest:

  • thinmuskip: space between items of math lists
  • medmuskip: space between binary operations
  • thickmuskip: space between relational operators
  • nulldelimiterspace: minimum space to leave blank in delimiter constructions, for example around a fraction
  • delimitershortfall: maximum space to overlap adjacent elements when a delimiter is too short
  • jot: space between lines in an array, or between rows in a multiline construct
  • arraycolsep: space between columns in an array
  • arraystretch: factor by which to stretch the height of each row in an array

To modify a register, use:

mf.registers.arraystretch = 1.5;
mf.registers.thinmuskip = { dimension: 2, unit: "mu" };
mf.registers.medmuskip = "3mu";

Editing Commands

Commands

To perform editing commands on a mathfield, use MathfieldElement.executeCommand with the commands below.

const mf = document.getElementById('mathfield');
mf.executeCommand('selectAll');
mf.executeCommand('copyToClipboard');

Some commands require an argument, for example to insert a character:

mf.executeCommand('insert("x")' });

The argument can be specified in parentheses after the command name, or using an array:

mf.executeCommand(['switchMode', 'latex']);
// Same as mf.executeCommand('switchMode("latex")');

Commands (and executeCommand()) return true if they resulted in a dirty state.

Selection

Commands.extendSelectionBackward()
extendSelectionBackward: (model) => boolean;
Commands.extendSelectionDownward()
extendSelectionDownward: (model) => boolean;
Commands.extendSelectionForward()
extendSelectionForward: (model) => boolean;
Commands.extendSelectionUpward()
extendSelectionUpward: (model) => boolean;
Commands.extendToGroupEnd()
extendToGroupEnd: (model) => boolean;
Commands.extendToGroupStart()
extendToGroupStart: (model) => boolean;
Commands.extendToMathFieldEnd()
extendToMathFieldEnd: (model) => boolean;
Commands.extendToMathFieldStart()
extendToMathFieldStart: (model) => boolean;
Commands.extendToNextBoundary()
extendToNextBoundary: (model) => boolean;
Commands.extendToNextWord()
extendToNextWord: (model) => boolean;
Commands.extendToPreviousBoundary()
extendToPreviousBoundary: (model) => boolean;
Commands.extendToPreviousWord()
extendToPreviousWord: (model) => boolean;
Commands.moveAfterParent()
moveAfterParent: (model) => boolean;
Commands.moveBeforeParent()
moveBeforeParent: (model) => boolean;
Commands.moveDown()
moveDown: (model) => boolean;
Commands.moveToGroupEnd()
moveToGroupEnd: (model) => boolean;
Commands.moveToGroupStart()
moveToGroupStart: (model) => boolean;
Commands.moveToMathfieldEnd()
moveToMathfieldEnd: (model) => boolean;
Commands.moveToMathfieldStart()
moveToMathfieldStart: (model) => boolean;
Commands.moveToNextChar()
moveToNextChar: (model) => boolean;
Commands.moveToNextGroup()
moveToNextGroup: (model) => boolean;
Commands.moveToNextPlaceholder()
moveToNextPlaceholder: (model) => boolean;
Commands.moveToNextWord()
moveToNextWord: (model) => boolean;
Commands.moveToOpposite()
moveToOpposite: (model) => boolean;
Commands.moveToPreviousChar()
moveToPreviousChar: (model) => boolean;
Commands.moveToPreviousGroup()
moveToPreviousGroup: (model) => boolean;
Commands.moveToPreviousPlaceholder()
moveToPreviousPlaceholder: (model) => boolean;
Commands.moveToPreviousWord()
moveToPreviousWord: (model) => boolean;
Commands.moveToSubscript()
moveToSubscript: (model) => boolean;
Commands.moveToSuperscript()
moveToSuperscript: (model) => boolean;
Commands.moveUp()
moveUp: (model) => boolean;
Commands.selectAll()
selectAll: (model) => boolean;
Commands.selectGroup()
selectGroup: (model) => boolean;

Other

Commands.applyStyle()
applyStyle: (mathfield, style) => boolean;
Commands.commit()
commit: (mathfield) => boolean;
Commands.dispatchEvent()
dispatchEvent: (mathfield, name, detail) => boolean;

Dispatch a custom event on the host (mathfield)

Commands.hideVirtualKeyboard()
hideVirtualKeyboard: (mathfield) => boolean;
Commands.insert()
insert: (mathfield, s, options) => boolean;
Commands.insertDecimalSeparator()
insertDecimalSeparator: (mathfield) => boolean;
Commands.performWithFeedback()
performWithFeedback: (mathfield, command) => boolean;

Perform a command and include interactive feedback such as sound and haptic feedback.

This is useful to simulate user interaction, for example for commands from the virtual keyboard

Commands.plonk()
plonk: (mathfield) => boolean;
Commands.showVirtualKeyboard()
showVirtualKeyboard: (mathfield) => boolean;
Commands.speak()
speak: (mathfield, scope, options) => boolean;
mathfield

Mathfield

scope

SpeechScope

How much of the formula should be spoken:

all the entire formula
selection the selection portion of the formula
left the element to the left of the selection
right the element to the right of the selection
group the group (numerator, root, etc..) the selection is in
parent the parent of the selection
options
withHighlighting

boolean

In addition to speaking the requested portion of the formula, visually highlight it as it is read (read aloud functionality)

Commands.switchMode()
switchMode: (mathfield, mode) => boolean;
Commands.toggleContextMenu()
toggleContextMenu: (mathfield) => boolean;
Commands.toggleKeystrokeCaption()
toggleKeystrokeCaption: (mathfield) => boolean;
Commands.toggleVirtualKeyboard()
toggleVirtualKeyboard: (mathfield) => boolean;
Commands.typedText()
typedText: (text, options) => boolean;

Array

Commands.addColumnAfter()
addColumnAfter: (model) => boolean;
Commands.addColumnBefore()
addColumnBefore: (model) => boolean;
Commands.addRowAfter()
addRowAfter: (model) => boolean;
Commands.addRowBefore()
addRowBefore: (model) => boolean;
Commands.removeColumn()
removeColumn: (model) => boolean;
Commands.removeRow()
removeRow: (model) => boolean;
Commands.setEnvironment()
setEnvironment: (model, environment) => boolean;

Auto-complete

Commands.complete()
complete: (mathfield) => boolean;
Commands.nextSuggestion()
nextSuggestion: (mathfield) => boolean;
Commands.previousSuggestion()
previousSuggestion: (mathfield) => boolean;

Clipboard

Commands.copyToClipboard()
copyToClipboard: (mathfield) => boolean;
Commands.cutToClipboard()
cutToClipboard: (mathfield) => boolean;
Commands.pasteFromClipboard()
pasteFromClipboard: (mathfield) => boolean;

Deleting

Commands.deleteAll()
deleteAll: (model) => boolean;
Commands.deleteBackward()
deleteBackward: (model) => boolean;
Commands.deleteForward()
deleteForward: (model) => boolean;
Commands.deleteNextWord()
deleteNextWord: (model) => boolean;
Commands.deletePreviousWord()
deletePreviousWord: (model) => boolean;
Commands.deleteToGroupEnd()
deleteToGroupEnd: (model) => boolean;
Commands.deleteToGroupStart()
deleteToGroupStart: (model) => boolean;
Commands.deleteToMathFieldEnd()
deleteToMathFieldEnd: (model) => boolean;
Commands.deleteToMathFieldStart()
deleteToMathFieldStart: (model) => boolean;

Prompt

Commands.insertPrompt()
insertPrompt: (mathfield, id?, options?) => boolean;

Scrolling

Commands.scrollIntoView()
scrollIntoView: (mathfield) => boolean;
Commands.scrollToEnd()
scrollToEnd: (mathfield) => boolean;
Commands.scrollToStart()
scrollToStart: (mathfield) => boolean;

Undo/Redo

Commands.redo()
redo: (mathfield) => boolean;
Commands.undo()
undo: (mathfield) => boolean;

VirtualKeyboardCommands

VirtualKeyboardCommands.hideVirtualKeyboard()
hideVirtualKeyboard: () => boolean;
VirtualKeyboardCommands.showVirtualKeyboard()
showVirtualKeyboard: () => boolean;
VirtualKeyboardCommands.switchKeyboardLayer()
switchKeyboardLayer: (mathfield, layer) => boolean;
VirtualKeyboardCommands.toggleVirtualKeyboard()
toggleVirtualKeyboard: () => boolean;

Selector

type Selector = Keys<Commands>;

Speech

SpeechScope

type SpeechScope = "all" | "selection" | "left" | "right" | "group" | "parent";

How much of the formula should be spoken:

all the entire formula
selection the selection portion of the formula
left the element to the left of the selection
right the element to the right of the selection
group the group (numerator, root, etc..) the selection is in
parent the parent of the selection

Keyboard Shortcuts

InlineShortcutDefinition

type InlineShortcutDefinition = 
  | string
  | {
  after: string;
  value: string;
};

An inline shortcut can be specified as a simple string or as an object literal with additional options:

    config.inlineShortcuts = {
     half: '\\frac{1}{2}',
     in: {
         after: 'space+letter+digit+symbol+fence',
         value: '\\in',
     },
 };

When using a string, the shortcut applies regardless of the characters surrounding it.

When using an object literal the value key is required an indicate the shortcut substitution.

The "after" key, if present, indicate in what context (preceding characters) the shortcut will apply. One or more values can be specified, separated by a '|' character. If any of the values match, the shortcut is applicable.

Possible values are:

"space" A spacing command, such as \quad
"nothing" The begining of a group
"surd" A square root or n-th root
"frac" A fraction
"function" A function such as \sin or f
"letter" A letter, such as x or n
"digit" 0 through 9
"binop" A binary operator, such as +
"relop" A relational operator, such as =
"punct" A punctuation mark, such as ,
"array" An array, such as a matrix or cases statement
"openfence" An opening fence, such as (
"closefence" A closing fence such as }
"text" Some plain text

InlineShortcutDefinitions

type InlineShortcutDefinitions = Record<string, InlineShortcutDefinition>;

Keybinding

A keybinding associates a combination of physical keyboard keys with a command.

For example:

{
     "key": "cmd+a",
     "command": "selectAll",
},
{
     "key": 'ctrl+[Digit2]',
     "ifMode": 'math',
     "command": ['insert', '\\sqrt{#0}'],
}
Keybinding.command
command: 
  | Selector
  | string[]
  | [string, any]
  | [string, any, any]
  | [string, any, any, any];

The command is a single selector, or a selector with arguments

Keybinding.ifLayout?
optional ifLayout: string[];
Keybinding.ifMode?
optional ifMode: ParseMode;

If specified, this indicates in which mode this keybinding will apply. If none is specified, the keybinding will apply in every mode.

Keybinding.ifPlatform?
optional ifPlatform: 
  | "macos"
  | "!macos"
  | "windows"
  | "!windows"
  | "linux"
  | "!linux"
  | "ios"
  | "!ios"
  | "android"
  | "!android"
  | "chromeos"
  | "!chromeos";

If specified, this indicates the OS platform to which this keybinding apply.

For example, if set to !macos this key binding will apply to every platform, except macOS.

Keybinding.key
key: string;

The pressed keys that will trigger this keybinding.

The key is made up of modifiers and the key itself.

The following modifiers can be used:

Platform Modifiers
macOS, iOS ctrl, shift, alt, cmd
Windows ctrl, shift, alt, win
Linux, Android, ChromeOS ctrl, shift, alt, meta

If the cmd modifier is used, the keybinding will only apply on macOS. If the win modifier is used, the keybinding will only apply to Windows. If the meta modifier is used, the keybinding will apply to platforms other than macOS or Windows.

The alt key is the option key on Apple keyboards.

The following values for keys can be used:

  • az, 09
  • `, -, =, [, ], \, ;, ', ,, ., /
  • left, up, right, down, pageup, pagedown, end, home
  • tab, enter, escape, space, backspace, delete
  • f1f19
  • pausebreak, capslock, insert
  • numpad0numpad9, numpad_multiply, numpad_add, numpad_separator
  • numpad_subtract, numpad_decimal, numpad_divide

The values will be remapped based on the current keyboard layout. So, for example if a is used, on a French AZERTY keyboard the keybinding will be associated with the key labeled 'A' (event though it corresponds to the key labeled 'Q' on a US QWERTY keyboard).

To associate keybindings with physical keys independent of the keyboard layout, use the following keycodes:

  • [KeyA][KeyZ], [Digit0][Digit9]
  • [Backquote], [Minus], [Equal], [BracketLeft], [BracketRight], [Backslash], [Semicolon], [Quote], [Comma], [Period], [Slash]
  • [ArrowLeft], [ArrowUp], [ArrowRight], [ArrowDown], [PageUp], [PageDown], [End], [Home]
  • [Tab], [Enter], [Escape], [Space], [Backspace], [Delete]
  • [F1][F19]
  • [Pause], [CapsLock], [Insert]
  • [Numpad0][Numpad9], [NumpadMultiply], [NumpadAdd], [NumpadComma]
  • [NumpadSubtract], [NumpadDecimal], [NumpadDivide]

For example, using [KeyQ] will map to the the key labeled 'Q' on a QWERTY keyboard, and to the key labeled 'A' on an AZERTY keyboard.

As a general guideline, it is preferable to use the key values az for keybinding that are pseudo-mnemotechnic. For the other, it is generally preferable to use the keycodes.

Consider the key combination: alt+2. With an AZERTY (French) layout, the digits (i.e. '2') are only accessible when shifted. The '2' key produces 'é' when not shifted. It is therefore impossible on an AZERTY keyboard to produce the alt+2 key combination, at best it would be alt+shift+2. To indicate that the intended key combination should be alt and the key on the keyboard which has the position of the 2 key on a US keyboard, a key code should be used instead: alt+[Digit2]. This will correspond to a key combination that can be generated on any keyboard.

Menu

DynamicValue<T>

type DynamicValue<T> = T | (modifiers) => T;

Type declaration

• T

MenuItem<T>

type MenuItem<T> = 
  | MenuItemDivider
  | MenuItemHeading
  | MenuItemSubmenu
| MenuItemCommand<T>;

Declaration of a menu item

Type declaration

• T = unknown

MenuItemCommand<T>

MenuItemCommand.ariaLabel?
optional ariaLabel: DynamicValue<string>;

An accessible text string that describes the item. Usually not necessary, as the label is used for this, however if the menu item is for example a color swatch, the ariaLabel can be used to describe the color.

MenuItemCommand.checked?
optional checked: DynamicValue<boolean | "mixed">;
MenuItemCommand.class?
optional class: DynamicValue<string>;

A CSS class applied to the item

MenuItemCommand.data?
optional data: T;

This data payload is passed to the onMenuSelect() hook and with the menu-select event

MenuItemCommand.enabled?
optional enabled: DynamicValue<boolean>;
MenuItemCommand.id?
optional id: string;

This id string is passed to the onMenuSelect() hook and with the menu-select event

MenuItemCommand.keyboardShortcut?
optional keyboardShortcut: string;
MenuItemCommand.label?
optional label: DynamicValue<string>;

A string of HTML markup used to describe the item

MenuItemCommand.onMenuSelect()?
optional onMenuSelect: (_) => void;

When this menu item is selected, a menu-select event is dispatched and this hook is called.

MenuItemCommand.tooltip?
optional tooltip: DynamicValue<string>;
MenuItemCommand.type?
optional type: "command";
MenuItemCommand.visible?
optional visible: DynamicValue<boolean>;

MenuItemDivider

A divider is a visual separator between menu items. It is not selectable.

MenuItemDivider.type
type: "divider";

MenuItemHeading

A heading is a menu item that is not selectable and used to group menu items.

If following items (until next divider or heading) are not visible, the heading is not visible either.

MenuItemHeading.ariaLabel?
optional ariaLabel: DynamicValue<string>;
MenuItemHeading.class?
optional class: DynamicValue<string>;
MenuItemHeading.label?
optional label: DynamicValue<string>;
MenuItemHeading.tooltip?
optional tooltip: DynamicValue<string>;
MenuItemHeading.type
type: "heading";

MenuItemProps<T>

These props are passed to the menu-select event and onMenuSelect hook

  • id: the id associated with the menu item.
  • data: the data payload associated with the menu item
  • modifiers: the keyboard modifiers that were pressed when the menu item was selected
MenuItemProps.data?
optional data: T;
MenuItemProps.id?
optional id: string;
MenuItemProps.modifiers?
optional modifiers: KeyboardModifiers;

MenuItemSubmenu

MenuItemSubmenu.ariaLabel?
optional ariaLabel: DynamicValue<string>;
MenuItemSubmenu.class?
optional class: DynamicValue<string>;
MenuItemSubmenu.columnCount?
optional columnCount: number;

If the menu is arranged in a custom grid, this is the number of columns.

This property is used for keyboard navigation with the arrow keys.

Default: 1.

MenuItemSubmenu.enabled?
optional enabled: DynamicValue<boolean>;
MenuItemSubmenu.label?
optional label: DynamicValue<string>;
MenuItemSubmenu.submenu
submenu: Readonly<MenuItem[]>;
MenuItemSubmenu.submenuClass?
optional submenuClass: string;

The class applied to the submenu container.

MenuItemSubmenu.tooltip?
optional tooltip: DynamicValue<string>;
MenuItemSubmenu.type?
optional type: "submenu";
MenuItemSubmenu.visible?
optional visible: DynamicValue<boolean>;

MenuItemType

type MenuItemType = "command" | "divider" | "heading" | "submenu";

The type of a menu item:

  • command: a command that can be selected and executed
  • divider: a visual separator
  • heading: a heading, not selectable. If following items (until next divider or heading) are not visible, the heading is not visible either.
  • submenu: a submenu

Virtual Keyboard

NormalizedVirtualKeyboardLayer

NormalizedVirtualKeyboardLayer.backdrop?
optional backdrop: string;
NormalizedVirtualKeyboardLayer.container?
optional container: string;
NormalizedVirtualKeyboardLayer.id?
optional id: string;
NormalizedVirtualKeyboardLayer.markup?
optional markup: string;
NormalizedVirtualKeyboardLayer.rows?
optional rows: Partial<VirtualKeyboardKeycap>[][];
NormalizedVirtualKeyboardLayer.style?
optional style: string;

VirtualKeyboardInterface

This interface is implemented by:

  • VirtualKeyboard: when the browsing context is a top-level document
  • VirtualKeyboardProxy: when the browsing context is an iframe

Extends

VirtualKeyboardInterface.boundingRect
readonly boundingRect: DOMRect;
VirtualKeyboardInterface.isShifted
readonly isShifted: boolean;
VirtualKeyboardInterface.normalizedLayouts
readonly normalizedLayouts: VirtualKeyboardLayoutCore & {
  layers: NormalizedVirtualKeyboardLayer[];
 }[];

This property is the "expanded" version of the layouts property. It is normalized to include all the default values for the properties of the layout and layers.

VirtualKeyboardInterface.originValidator
originValidator: OriginValidator;

Specify behavior how origin of message from postMessage should be validated.

Default: "none"

VirtualKeyboardInterface.targetOrigin
targetOrigin: string;

Specify the targetOrigin parameter for postMessage to send control messages from parent to child frame to remote control of mathfield component.

Default: globalThis.origin

VirtualKeyboardInterface.visible
visible: boolean;
VirtualKeyboardInterface.alphabeticLayout
set alphabeticLayout(value: AlphabeticKeyboardLayout): void

Layout of the alphabetic layers: AZERTY, QWERTY, etc...

VirtualKeyboardInterface.container
set container(value: HTMLElement): void

Element the virtual keyboard element gets appended to.

When using full screen elements that contain mathfield, set this property to the full screen element to ensure the virtual keyboard will be visible.

Default: document.body

VirtualKeyboardInterface.editToolbar
set editToolbar(value: EditToolbarOptions): void

Configuration of the action toolbar, displayed on the right-hand side.

Use "none" to disable the right hand side toolbar of the virtual keyboard.

VirtualKeyboardInterface.layouts
get layouts(): readonly (
  | VirtualKeyboardLayout
  | VirtualKeyboardName)[]
set layouts(value: 
  | VirtualKeyboardLayout
  | VirtualKeyboardName
  | VirtualKeyboardLayout | VirtualKeyboardName[]
  | readonly VirtualKeyboardLayout | VirtualKeyboardName[]): void

A layout is made up of one or more layers (think of the main layer and the shift layer on a hardware keyboard).

A layout has a name and styling information.

In addition, a layout can be represented as a standard name which includes "numeric", "functions", "symbols", "alphabetic" and `"greek".

*See mathfield/guides/virtual-keyboards | Guide: Virtual Keyboards

VirtualKeyboardInterface.connect()
connect(): void
VirtualKeyboardInterface.disconnect()
disconnect(): void
VirtualKeyboardInterface.executeCommand()
executeCommand(command): boolean
command

string | [string, ...any[]]

VirtualKeyboardInterface.getKeycap()
getKeycap(keycap): Partial<VirtualKeyboardKeycap>

Some keycaps can be customized: [left], [right], [up], [down], [return], [action], [space], [tab], [backspace], [shift], [undo], [redo], [foreground-color], [background-color], [hide-keyboard], [.], [,], [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [+], [-], [*], [/], [^], [_], [=], [.], [(], [)],

keycap

string

VirtualKeyboardInterface.hide()
hide(options?): void
options?
animate

boolean

VirtualKeyboardInterface.setKeycap()
setKeycap(keycap, value): void
keycap

string

value

Partial<VirtualKeyboardKeycap>

VirtualKeyboardInterface.show()
show(options?): void
options?
animate

boolean

VirtualKeyboardInterface.update()
update(mf): void
mf

MathfieldProxy

VirtualKeyboardInterface.updateToolbar()
updateToolbar(mf): void

The content or selection of the mathfield has changed and the toolbar may need to be updated accordingly

mf

MathfieldProxy

VirtualKeyboardKeycap

VirtualKeyboardKeycap.aside
aside: string;

Markup displayed with the key label (for example to explain what the symbol of the key is)

VirtualKeyboardKeycap.class
class: string;

CSS classes to apply to the keycap.

  • tex: use the TeX font for its label. Using the tex class is not necessary if using the latex property to define the label.
  • shift: a shift key
  • small: display the label in a smaller size
  • action: an “action” keycap (for arrows, return, etc…)
  • separator w5: a half-width blank used as a separator. Other widths include w15 (1.5 width), w20 (double width) and w50 (five-wide, used for the space bar).
  • bottom, left, right: alignment of the label
VirtualKeyboardKeycap.command
command: 
  | string
  | string[]
  | [string, any]
  | [string, any, any]
  | [string, any, any, any];

Command to perform when the keycap is pressed

VirtualKeyboardKeycap.insert
insert: string;

LaTeX fragment to insert when the keycap is pressed (ignored if command is specified)

VirtualKeyboardKeycap.key
key: string;

Key to insert when keycap is pressed (ignored if command, insert or latex is specified)

VirtualKeyboardKeycap.label
label: string;

The HTML markup displayed for the keycap

VirtualKeyboardKeycap.latex
latex: string;

Label of the key as a LaTeX expression, also the LaTeX inserted if no command or insert property is specified.

VirtualKeyboardKeycap.layer
layer: string;

Name of the layer to shift to when the key is pressed

VirtualKeyboardKeycap.shift
shift: string | Partial<VirtualKeyboardKeycap>;

Variant of the keycap when the shift key is pressed

VirtualKeyboardKeycap.stickyVariantPanel
stickyVariantPanel: boolean;

Open variants panel without long press and does not close automatically

VirtualKeyboardKeycap.tooltip
tooltip: string;
VirtualKeyboardKeycap.variants
variants: 
  | string
  | (string | Partial<VirtualKeyboardKeycap>)[];

A set of keycap variants displayed on a long press

variants: [
 '\\alpha',    // Same label as value inserted
 { latex: '\\beta', label: 'beta' }
]
VirtualKeyboardKeycap.width
width: 0.5 | 1 | 1.5 | 2 | 5;

Width of the keycap, as a multiple of the standard keycap width

VirtualKeyboardLayer

VirtualKeyboardLayer.backdrop?
optional backdrop: string;

A CSS class name to customize the appearance of the background of the layer

VirtualKeyboardLayer.container?
optional container: string;

A CSS class name to customize the appearance of the container the layer

VirtualKeyboardLayer.id?
optional id: string;

A unique string identifying the layer

VirtualKeyboardLayer.markup?
optional markup: string;
VirtualKeyboardLayer.rows?
optional rows: (string | Partial<VirtualKeyboardKeycap>)[][];

The rows of keycaps in this layer

VirtualKeyboardLayer.style?
optional style: string;

The CSS stylesheet associated with this layer

VirtualKeyboardOptions

Extended by

VirtualKeyboardOptions.normalizedLayouts
readonly normalizedLayouts: VirtualKeyboardLayoutCore & {
  layers: NormalizedVirtualKeyboardLayer[];
 }[];

This property is the "expanded" version of the layouts property. It is normalized to include all the default values for the properties of the layout and layers.

VirtualKeyboardOptions.originValidator
originValidator: OriginValidator;

Specify behavior how origin of message from postMessage should be validated.

Default: "none"

VirtualKeyboardOptions.targetOrigin
targetOrigin: string;

Specify the targetOrigin parameter for postMessage to send control messages from parent to child frame to remote control of mathfield component.

Default: globalThis.origin

VirtualKeyboardOptions.alphabeticLayout
set alphabeticLayout(value: AlphabeticKeyboardLayout): void

Layout of the alphabetic layers: AZERTY, QWERTY, etc...

VirtualKeyboardOptions.container
set container(value: HTMLElement): void

Element the virtual keyboard element gets appended to.

When using full screen elements that contain mathfield, set this property to the full screen element to ensure the virtual keyboard will be visible.

Default: document.body

VirtualKeyboardOptions.editToolbar
set editToolbar(value: EditToolbarOptions): void

Configuration of the action toolbar, displayed on the right-hand side.

Use "none" to disable the right hand side toolbar of the virtual keyboard.

VirtualKeyboardOptions.layouts
get layouts(): readonly (
  | VirtualKeyboardLayout
  | VirtualKeyboardName)[]
set layouts(value: 
  | VirtualKeyboardLayout
  | VirtualKeyboardName
  | VirtualKeyboardLayout | VirtualKeyboardName[]
  | readonly VirtualKeyboardLayout | VirtualKeyboardName[]): void

A layout is made up of one or more layers (think of the main layer and the shift layer on a hardware keyboard).

A layout has a name and styling information.

In addition, a layout can be represented as a standard name which includes "numeric", "functions", "symbols", "alphabetic" and `"greek".

*See mathfield/guides/virtual-keyboards | Guide: Virtual Keyboards

VirtualKeyboardOptions.getKeycap()
getKeycap(keycap): Partial<VirtualKeyboardKeycap>

Some keycaps can be customized: [left], [right], [up], [down], [return], [action], [space], [tab], [backspace], [shift], [undo], [redo], [foreground-color], [background-color], [hide-keyboard], [.], [,], [0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [+], [-], [*], [/], [^], [_], [=], [.], [(], [)],

keycap

string

VirtualKeyboardOptions.setKeycap()
setKeycap(keycap, value): void
keycap

string

value

Partial<VirtualKeyboardKeycap>

AlphabeticKeyboardLayout

type AlphabeticKeyboardLayout = "auto" | "qwerty" | "azerty" | "qwertz" | "dvorak" | "colemak";

EditToolbarOptions

type EditToolbarOptions = "none" | "default";

NormalizedVirtualKeyboardLayout

type NormalizedVirtualKeyboardLayout = VirtualKeyboardLayoutCore & {
  layers: NormalizedVirtualKeyboardLayer[];
};

OriginValidator

type OriginValidator = (origin) => boolean | "same-origin" | "none";

Specify behavior for origin validation when using the virtual keyboard.

Value Description
"same-origin" The origin of received message must be the same of hosted window, instead exception will throw.
(origin: string) => boolean The callback to verify origin to be expected validation. When callback return false value, message will rejected and exception will throw.
"none" No origin validation for post messages.

VirtualKeyboardLayout

type VirtualKeyboardLayout = VirtualKeyboardLayoutCore & 
  | {
  layers: (string | VirtualKeyboardLayer)[];
 }
  | {
  rows: (string | Partial<VirtualKeyboardKeycap>)[][];
 }
  | {
  markup: string;
};

VirtualKeyboardLayoutCore

VirtualKeyboardLayoutCore.displayEditToolbar?
optional displayEditToolbar: boolean;

If false, do not include the edit toolbar in the layout

VirtualKeyboardLayoutCore.displayShiftedKeycaps?
optional displayShiftedKeycaps: boolean;

If false, keycaps that have a shifted variant will be displayed as if they don't

VirtualKeyboardLayoutCore.id?
optional id: string;

A unique string identifying the layout

VirtualKeyboardLayoutCore.label?
optional label: string;

A human readable string displayed in the layout switcher toolbar

VirtualKeyboardLayoutCore.labelClass?
optional labelClass: string;
VirtualKeyboardLayoutCore.tooltip?
optional tooltip: string;

A human readable tooltip associated with the label

VirtualKeyboardMessage

type VirtualKeyboardMessage = 
  | {
  action: "execute-command";
  command: Selector | [Selector, ...any[]];
  type: "mathlive#virtual-keyboard-message";
 }
  | {
  action: "geometry-changed";
  boundingRect: DOMRect;
  type: "mathlive#virtual-keyboard-message";
 }
  | {
  action: "synchronize-proxy";
  alphabeticLayout: AlphabeticKeyboardLayout;
  boundingRect: DOMRect;
  editToolbar: EditToolbarOptions;
  isShifted: boolean;
  layers: Record<string, string | Partial<VirtualKeyboardLayer>>;
  layouts: Readonly<(string | VirtualKeyboardLayout)[]>;
  setKeycap: {
     keycap: string;
     value: Partial<VirtualKeyboardKeycap>;
    };
  type: "mathlive#virtual-keyboard-message";
 }
  | {
  action: "update-setting";
  alphabeticLayout: AlphabeticKeyboardLayout;
  editToolbar: EditToolbarOptions;
  layers: Record<string, string | Partial<VirtualKeyboardLayer>>;
  layouts: Readonly<(
     | VirtualKeyboardName
     | VirtualKeyboardLayout)[]>;
  setKeycap: {
     keycap: string;
     value: Partial<VirtualKeyboardKeycap>;
    };
  type: "mathlive#virtual-keyboard-message";
 }
  | {
  action: "show" | "hide";
  animate: boolean;
  type: "mathlive#virtual-keyboard-message";
 }
  | {
  action:   | "connect"
     | "disconnect"
     | "proxy-created"
     | "focus"
     | "blur"
     | "update-state"
     | "update-toolbar";
  type: "mathlive#virtual-keyboard-message";
};

VirtualKeyboardMessageAction

type VirtualKeyboardMessageAction = 
  | "connect"
  | "disconnect"
  | "proxy-created"
  | "execute-command"
  | "show"
  | "hide"
  | "update-setting"
  | "update-toolbar"
  | "synchronize-proxy"
  | "geometry-changed"
  | "update-state"
  | "focus"
  | "blur";

VirtualKeyboardName

type VirtualKeyboardName = 
  | "default"
  | "compact"
  | "minimalist"
  | "numeric-only"
  | "numeric"
  | "symbols"
  | "alphabetic"
  | "greek";

VirtualKeyboardPolicy

type VirtualKeyboardPolicy = "auto" | "manual" | "sandboxed";
  • "auto": the virtual keyboard is triggered when a mathfield is focused on a touch capable device.
  • "manual": the virtual keyboard is not triggered automatically
  • "sandboxed": the virtual keyboard is displayed in the current browsing context (iframe) if it has a defined container or is the top-level browsing context.

Localization

KeyboardLayoutName

type KeyboardLayoutName = 
  | "apple.en-intl"
  | "apple.french"
  | "apple.german"
  | "apple.spanish"
  | "dvorak"
  | "windows.en-intl"
  | "windows.french"
  | "windows.german"
  | "windows.spanish"
  | "linux.en"
  | "linux.french"
  | "linux.german"
  | "linux.spanish";

See setKeyboardLayout.

Name Platform Display name
"apple.en-intl" Apple English (International)
"apple.french" Apple French (AZERTY)
"apple.german" Apple German (QWERTZ)
"dvorak" English (Dvorak)
"windows.en-intl" Windows English (International)
"windows.french" Windows French (AZERTY)
"windows.german" Windows German (QWERTZ)
"linux.en" Linux English
"linux.french" Linux French (AZERTY)
"linux.german" Linux German (QWERTZ)

setKeyboardLayout()

function setKeyboardLayout(name): void

Change the current physical keyboard layout.

Note that this affects some keybindings, but not general text input.

If set to auto the keyboard layout is guessed.

name

"auto" | KeyboardLayoutName

setKeyboardLayoutLocale()

function setKeyboardLayoutLocale(locale): void

Change the current physical keyboard layout to a layout that matches the specified locale, if one is available.

Note that this affects some keybindings, but not general text input.

locale

string

Static Rendering

StaticRenderOptions

type StaticRenderOptions = Partial<LayoutOptions> & {
  asciiMath: {
     delimiters: {
        display: string[];
        inline: string[];
       };
    };
  ignoreClass: string;
  processClass: string;
  processMathJSONScriptType: string;
  processScriptType: string;
  readAloud: boolean;
  renderAccessibleContent: string;
  skipTags: string[];
  TeX: {
     className: {
        display: string;
        inline: string;
       };
     delimiters: {
        display: [string, string][];
        inline: [string, string][];
       };
     processEnvironments: boolean;
    };
};

StaticRenderOptions.ignoreClass?

optional ignoreClass: string;

A string used as a regular expression of class names of elements whose content will not be scanned for delimiter

Default: "tex2jax_ignore"

StaticRenderOptions.processClass?

optional processClass: string;

A string used as a regular expression of class names of elements whose content will be scanned for delimiters, even if their tag name or parent class name would have prevented them from doing so.

Default: "tex2jax_process"

StaticRenderOptions.processMathJSONScriptType?

optional processMathJSONScriptType: string;

<script> tags with this type will be processed as MathJSON.

Default: "math/json"

StaticRenderOptions.processScriptType?

optional processScriptType: string;

<script> tags with this type will be processed as LaTeX.

Default: "math/tex"

StaticRenderOptions.readAloud?

optional readAloud: boolean;

If true, generate markup that can be read aloud later using speak

Default: false

StaticRenderOptions.renderAccessibleContent?

optional renderAccessibleContent: string;

The format(s) in which to render the math for screen readers:

  • "mathml" MathML
  • "speakable-text" Spoken representation

You can pass an empty string to turn off the rendering of accessible content. You can pass multiple values separated by spaces, e.g "mathml speakable-text"

Default: "mathml"

StaticRenderOptions.skipTags?

optional skipTags: string[];

An array of tag names whose content will not be scanned for delimiters (unless their class matches the processClass pattern below).

Default: ['math-field', 'noscript', 'style', 'textarea', 'pre', 'code', 'annotation', 'annotation-xml']

renderMathInDocument()

function renderMathInDocument(options?): void

Transform all the elements in the document body that contain LaTeX code into typeset math.

Caution

This is a very expensive call, as it needs to parse the entire DOM tree to determine which elements need to be processed. In most cases this should only be called once per document, once the DOM has been loaded.

To render a specific element, use renderMathInElement()

options?

StaticRenderOptions

Example

import { renderMathInDocument } from 'https://esm.run/mathlive';
// Alternatively, you can use the **unpkg** CDN to load the library
// import { renderMathInDocument } from 'https://unpkg.com/mathlive?module';

renderMathInDocument();

renderMathInElement()

function renderMathInElement(element, options?): void

Transform all the children of element that contain LaTeX code into typeset math, recursively.

element

An HTML DOM element, or a string containing the ID of an element.

string | HTMLElement

options?

StaticRenderOptions

Example

import { renderMathInElement } from 'https://esm.run/mathlive';
renderMathInElement("formula");

Conversion

LatexSyntaxError<T>

LatexSyntaxError.after?
optional after: string;
LatexSyntaxError.arg?
optional arg: string;
LatexSyntaxError.before?
optional before: string;
LatexSyntaxError.code
code: T;
LatexSyntaxError.latex?
optional latex: string;

ParserErrorCode

type ParserErrorCode = 
  | "unknown-command"
  | "invalid-command"
  | "unbalanced-braces"
  | "unknown-environment"
  | "unbalanced-environment"
  | "unbalanced-mode-shift"
  | "missing-argument"
  | "too-many-infix-commands"
  | "unexpected-command-in-string"
  | "missing-unit"
  | "unexpected-delimiter"
  | "unexpected-token"
  | "unexpected-end-of-string"
  | "improper-alphabetic-constant";

Error codes returned by the mf.errors property.

unknown-command There is no definition available for this LaTeX command, e.g. \zin
unknown-environment There is no definition available for this environment, e.g. \begin{foo}
invalid-command This command is not valid in the current context (e.g. text command in math mode)
unbalanced-braces There are too many or too few { or }
unbalanced-environment An environment was open but never closed (\begin{array}) or the \end command does not match the \begin command (\begin{array*}\end{array})
unbalanced-mode-shift A $, $$, \( or \[ was not balanced
missing-argument A required argument is missing, e.g. \frac{2}
too-many-infix-commands A group can include only one infix command (i.e. \choose, \atop). In general it's best to avoid infix commands.
unexpected-command-in-string A command expected a string argument, but there was a command instead
missing-unit An argument requiring a dimension was missing an unit.
unexpected-delimiter An invalid symbol or command was used as a delimiter.
unexpected-token An unexpected character was encountered.
unexpected-end-of-string The end of the string was reached, but some required arguments were missing.
improper-alphabetic-constant The alphabetic constant prefix ` was not followed by a letter or single character command.

convertAsciiMathToLatex()

function convertAsciiMathToLatex(ascii): string

Convert an AsciiMath string to a LaTeX string.

convertAsciiMathToLatex("1/2");
// -> "\\frac{1}{2}"
ascii

string

convertLatexToAsciiMath()

function convertLatexToAsciiMath(latex, parseMode): string

Convert a LaTeX string to a string of AsciiMath.

convertLatexToAsciiMath("\\frac{1}{2}");
// -> "1/2"
latex

string

parseMode

ParseMode = 'math'

convertLatexToMarkup()

function convertLatexToMarkup(text, options?): string

Convert a LaTeX string to a string of HTML markup.

:::info[Note]

This function does not interact with the DOM. It does not load fonts or inject stylesheets in the document. It can safely be used on the server side. :::

To get the output of this function to correctly display in a document, use the mathlive static style sheet by adding the following to the <head> of the document:

<link
 rel="stylesheet"
 href="https://cdn.jsdelivr.net/npm/mathlive/mathlive-static.css"
/>

or

<link
 rel="stylesheet"
 href="https://unpkg.com/mathlive/mathlive-static.css"
/>
text

string

A string of valid LaTeX. It does not have to start with a mode token such as $$ or \(.

options?

Partial<LayoutOptions>

convertLatexToMathMl()

function convertLatexToMathMl(latex, options): string

Convert a LaTeX string to a string of MathML markup.

latex

string

A string of valid LaTeX. It does not have to start with a mode token such as a $$ or \(.

options
generateID?

boolean

If true, add an "extid" attribute to the MathML nodes with a value matching the atomID. This can be used to map items on the screen with their MathML representation or vice-versa.

convertLatexToSpeakableText()

function convertLatexToSpeakableText(latex): string

Convert a LaTeX string to a textual representation ready to be spoken

latex

string

A string of valid LaTeX. It does not have to start with a mode token such as a $$ or \(.

Example

console.log(convertLatexToSpeakableText('\\frac{1}{2}'));
// 'half'

convertMathJsonToLatex()

function convertMathJsonToLatex(json): string

Convert a MathJSON expression to a LaTeX string.

convertMathJsonToLatex(["Add", 1, 2]);
// -> "1 + 2"
json

Expression

validateLatex()

function validateLatex(s): LatexSyntaxError[]

Check if a string of LaTeX is valid and return an array of syntax errors.

s

string

MathJSON

Expression

type Expression = 
  | number
  | string
  | {}
  | [Expression, ...Expression[]];

Other

version

const version: {
  mathlive: string;
};

Current version: 0.105.2

The version string of the SDK using the semver convention:

MAJOR.MINOR.PATCH

  • MAJOR is incremented for incompatible API changes
  • MINOR is incremented for new features
  • PATCH is incremented for bug fixes
--- title: Changelog - Mathfield sidebar_label: Changelog slug: /mathfield/changelog/ toc_max_heading_level: 2 ---

Mathfield Changelog

import ChangeLog from '@site/src/components/ChangeLog';

## Coming Soon

Resolved Issues

  • Using the kebab version of commands (for example "select-all" instead of "SelectAll") would incorrectly result in a runtime error.

0.105.1 2025-04-18

Resolved Issues

  • #2526 In the virtual keyboard, the keycap text over CSS variables was not displayed correctly.
  • #2567 Avoid potential race condition when changing the focus of the mathfield.
  • #2638, #2479 Fragments that were styled with some color were not rendered correctly when the mathfield was not focused.
  • #2669 If a page had multiple mathfields, when using the suggestion popover, the suggestion popover would be inserted in the wrong mathfield.
  • #2584 In some cases, a menu item could get inadvertently selected when when brining up the menu.
  • #2673 When using the CJS version of the library, the height of the virtual keyboard was not correctly calculated.
  • #2666 In some cases, the state of the Undo/Redo buttons could get out of sync with the state of the mathfield.
  • #2667 The edit toolbar was not displayed in the alphabetic keyboard layout.

Improvements

  • Accessibility: Improved support for the high-contrast mode.
  • There is a new CSS variable to control the z-index of the suggestion popover: --suggestion-zindex. This allows the suggestion popover to be displayed above other elements on the page.
  • Added support for the \strut and \mathstrut commands. These commands are used to insert a strut, which is an invisible element that takes up space in the math expression. This is useful for aligning expressions or for creating space between elements.
  • #2662 When the command popover is displayed, pressing the Return key will insert the command in the mathfield and close the popover.
  • #2658 Improved localization for Italian.
  • #2671 When inserting a command with an argument with the suggestion popover, position the cursor inside the argument.

0.105.0 2025-03-27

Breaking Changes

In order to support alternate CDNs, in particular jsdelivr, the file layout of the npm package has changed. The files that were previously in the ./dist/ directory are now in the root of the package. This should not affect most users, but if you are importing the library or auxiliary files from the dist directory, you will need to update your paths.

To use jsdelivr, use:

import { MathfieldElement } from "https://esm.run/mathlive";

or:

<script defer src="https://cdn.jsdelivr.net/npm/mathlive"></script>

Issues Resolved

  • #2647, #2634, #2562 Some accents (\hat{}, \vec{}) where not rendered correctly in some cases.

  • #2635 In Chrome (and Firefox), clicking on the padding area of the mathfield would not result in the focus getting into a zombie state and keyboard event no longer being dispatched.

0.104.2 2025-03-23

Issues Resolved

  • #2588 With Chrome 133+ input with the physical keyboard was disabled after showing the virtual keyboard.

0.104.1 2025-03-18

Improvements

  • Improved support for the jsdelivr CDN. To use it, use:
import { MathfieldElement } from "https://esm.run/mathlive";

Issues Resolved

  • #2628 Attempting to delete an empty line in a multiline environment would not delete the line.
  • #2585 In some cases, the arguments of a macro were not serialized correctly. This could happen when using a macro in conjunction with a inline shortcut.
  • #2586 The \pdiff{}{} command was not properly serialized to LaTeX.

0.104.0 2025-02-08

Security Advisories

As a reminder, if you are handling untrusted input, you should consider using the MathfieldElement.createHTML() method to sanitize content. The createHTML() method follows the recommendations from the Trusted Type specification.

For example, using the DOMPurify library (there are other HTML sanitizers available):

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.2.3/purify.min.js"></script>
MathfieldElement.createHTML = (html) => DOMPurify.sanitize(html);
  • security advisory Untrusted input could be used to inject arbitrary HTML or JavaScript code in a page using a mathfield or math content rendered by the library, if the content included an \htmlData{} command with maliciously crafted input and no DOM sanitizer was used.

    The content of the \htmlData{} command is now sanitized and the 🚫 emoji is displayed instead in the mathfield if the content is unsafe. When using convertLatexToMarkup(), an exception is thrown.

  • The \href{}{} command now only allows URLs with the http or https protocol.

Issues Resolved

  • Generate only standard trigonometric functions, i.e. those available in the amsmath package. Use \operatorname{} for the others. The standard commands are:

    • \arccos
    • \arcsin
    • \arctan
    • \arg
    • \cos
    • \cosh
    • \cot
    • \coth
    • \csc
    • \sec
    • \sin
    • \sinh
    • \tan
    • \tanh
  • Added support for \dddot and \ddddot commands.

  • #2573 The \operatorname{} command when round-tripped would incldue an extraneous \mathrm{} command.

  • #2132, #2548 Improved handling of multi-line mathfields. To use a multi-line mathfield, include a multi-line environment:

    • \displaylines{}: single column of left-aligned equations
    • gather: single column of centered equations
    • multline: centered equations with the first line aligned left and the last line aligned to the right
    • align: two columns, the first column right-aligned, the second column left-aligned; used for one equation per line
    • split: two columns of equations, the first column right-aligned, the second column left-aligned; used for a single equation split over multiple lines

For example:

<math-field>\displaylines{x=1 \\y = 2}</math-field>
<math-field>\begin{align}
  f(0) &= 1 \\
  f(x + 1) &= f(x-1) + f(x)
\end{align}
</math-field>
  • When in a multi-line environment, the Return key will move to the next line. The Backspace key will delete the current line if the cursor is at the beginning of the line. Note that no placeholder is inserted on a new line: the line is simply blank.

  • The Add Row Before, Add Row After, Add Column Before, Add Column After, Delete Row and Delete Columns commands are available in the context menu when the cursor is inside a matrix. They are not available in multi-line environments.

  • #2574 The commands \coloneq, \Coloneq, \Coloneqq, \eqcolon and \Eqcolon were mapped to incorrect symbols (some of them used obsolete definitions of those commands from the mathtools package that changed in the Summer of 2022). They are now correctly mapped to the corresponding symbols.

  • #2576 The command \perp was mapped to the wrong symbol (U+22A5). It is now mapped to the correct symbol (U+27C2)

  • Improved ASCIIMath serialization.

0.103.0 2024-12-10

Issues Resolved

  • #2530 The AsciiMath 1/2 is now parsed as \frac{1}{2}
  • The \displaylines command is now correctly parsed as a command with an argument, not as a group command.

0.102.0 2024-11-29

Issues Resolved

  • #2550 The subpath exports in the main package.json have been updated to comply with Node.js's subpath patterns, which utilize "direct static matching and replacement.

Improvements

  • #2554 Option for sticky virtual keyboard variant panel

    When long pressing a key on the virtual keyboard, a variant panel is displayed that offers alternatives (variants) for that key. The panel is only displayed while your finger is pressing the key (like a smartphone keyboard). This new options allows the variant panel to remain displayed even if you lift your finger from the screen.

    Add the stickyVariantPanel property to a virtual keyboard keycap definition to make the variant panel sticky.

    See ./examples/sticky-variant-panel/ for an example.

0.101.2 2024-11-15

Issues Resolved

  • Correctly display the caret following a \mathop{} command.
  • #2540 When using renderMathInElement() some white space was occasionally incorrectly removed.
  • #2545 (?) Use \rightarrow instead of \rarr in the virtual keyboard.
  • #2543 The MathfieldElement.fractionNavigationOrder was not respected when navigating in a fraction with the arrow keys.
  • #2251 Fixed the serialization of \displaylines{}

0.101.1 2024-10-15

Issues Resolved

  • #2533 When using the virtual keyboard to insert a character with a blackboard style followed by a non-alphabetic symbol without a blackboard style, the second symbol would incorrectly be serialized with a blackboard style.
  • In some cases, the placeholder attribute would not be displayed when the mathfield was empty.
  • When using static math, the font-familly for text content was not correctly inherited from the parent element.
  • In some cases, the inherent style of a macro could get overriden. For example typing the "RR" inline shortcut resulted in an unstyled R instead of the expected blackboard R.

0.101.0 2024-07-17

Breaking Changes

  • The properties mathVirtualKeyboard.actionKeycap, mathVirtualKeyboard.shiftKeycap, mathVirtualKeyboard.backspaceKeycap, and mathVirtualKeyboard.tabKeycap have been removed. Use the more general mathVirtualKeyboard.setKeycap() method to customize these keycaps, that is mathVirtualKeyboard.setKeycap('[action]', {...}) etc...

Improvements and New Features

  • Macros can now be specified with renderMathInElement() and renderMathInDocument() using the macros option. For example:

    renderMathInElement(element, {macros: {RR: '\\mathbb{R}'}})
  • Performance improvements for pages with many mathfields. The initial rendering can be up to 2x as fast.

  • Some keycaps in the virtual keyboard can be customized without having to define an entire virtual keyboard layout.

    The mathVirtualKeyboard.getKeycap() give access to the definition of special keycaps and mathVirtualKeyboard.setKeycap() can be used to change that definition.

    The keycaps are one of these special shortcuts:

    • [left], [right], [up], [down], [return], [action],
    • [space], [tab], [backspace], [shift],
    • [undo], [redo], [foreground-color], [background-color],
    • [hide-keyboard],
    • [.], [,],
    • [0], [1], [2], [3], [4],
    • [5], [6], [7], [8], [9],
    • [+], [-], [*], [/], [^], [_], [=], [.],
    • [(], [)]

    For example, to change the LaTeX inserted when the multiplication key is pressed use:

    mathVirtualKeyboard.setKeycap('[*]', {latex: '\\times'});

Issues Resolved

  • #2455 Serialization to ASCII Math of brackets and braces is now correct.
  • When using Chrome in some locale (such as es-419), the context menu would not be displayed.
  • When the MathfieldElement.isFunction handler is updated, re-render all the mathfields on the page to take it into account.
  • #2415 A content change event is now dispatched when the value of the mathfield is changed as a result of switch from LaTeX mode to math mode by changing the selection.
  • Dispatch a contextmenu event any time the context menu is about to be displayed. This allows the event to be canceled.
  • #2413 When setting the alphabeticLayout, the current keyboard would not be updated in some cases.
  • #2412 The serialization of some expressions to LaTeX could result in some spaces being omitted. For example, \lnot p would serialize as \lnotp.
  • #2403 The virtual keyboard Keycap Variants panel was positioned incorrectly when the page used a RTL layout direction.
  • In the virtual keyboard, the background of the variant panel was sometimes displayed transparently.
  • #2402 Characters inserted after a \mathbb{} command were not styled correctly.
  • The math-virtual-keyboard-command event was not dispatched when a mathfield was focused and a keycap was pressed.
  • There are now CSS selectors to customize the size of glyphs in the virtual keyboard (shift, enter, etc...):
    • --keycap-glyph-size
    • --keycap-glyph-size-lg
    • --keycap-glyph-size-xl
  • #2397 When a beforeinput event was canceled, the text would still be inserted when using the physical keyboard.
  • #2398 When a placeholder was the only element in a group, i.e. {\placeholder{}}, the placeholder was not automatically selected.

0.100.0 2024-06-12

Issues Resolved

  • #2396 Pressing the arrow keys in the virtual keyboard would not move the selection in the mathfield and display a runtime error in the console.

  • #2392 Pressing the backspace key after typing several digits would delete all the digits.

  • #2395 Added a dispatchEvent command which can be attached to a custom keycap.

    Its first argument is the name of the dispatched event, and the second argument is an object with the detail property, which is the data associated with the event.

      {
        label: "✨",
        command: "dispatchEvent('customEvent', {detail: 'some data'})"
      }

    To handle the event, add an event listener to the mathfield element:

    mf.addEventListener('customEvent', (ev) => {
      console.log(ev.detail);
    });

0.99.0 2024-06-10

Breaking Changes

  • The mf.offsetFromPoint() method has been renamed mf.getOffsetFromPoint()

  • The mf.setCaretPoint() method has been replaced with mf.position = mf.getOffsetFromPoint()

  • The mf.scriptDepth() and mf.hitboxFromOffset() methodds have been replaced with mf.getElementInfo().

    The getElementInfo() method provides more information including any id that may have been applied with \htmlId{}.

    It is useful from within a click handler to get more information about the element that was clicked, e.g.

      mf.getElementInfo(mf.getOffsetFromPoint(ev.clientX, ev.clientY))

    The info returned is an object with the following properties:

    export type ElementInfo = {
      /** The depth in the expression tree. 0 for top-level elements */
      depth?: number;
    
      /** The bounding box of the element */
      bounds?: DOMRect;
    
      /** id associated with this element or its ancestor, set with `\htmlId` or
         `\cssId`
      */
      id?: string;
    
      /** HTML attributes associated with element or its ancestores, set with
       * `\htmlData`
       */
      data?: Record<string, string | undefined>;
    
      /** The mode (math, text or LaTeX) */
      mode?: ParseMode;
    
      /** A LaTeX representation of the element */
      latex?: string;
    
      /** The style (color, weight, variant, etc...) of this element. */
      style?: Style;
    };

Bold

The way bold is handled in LaTeX is particularly confusing, reflecting limitations of the text rendering technology of the time.

Various attempts have been made over the years to improve the rendering of bold, but this has resulted in inconsistent behavior. Furthermore, various implementations of LaTeX and LaTeX-like systems have implemented bold in different ways.

This release introduces a more consistent and intuitive handling of bold, although it may result in different rendering of some formulas compared to some implementations of LaTeX.

The original bold command in LaTeX is \mathbf. This command renders its argument using a bold variant of the current font. However, only letters and numbers can be rendered by this command. It does not affect symbols, operators, or greek characters.

For example, \mathbf{a+b} will render as 𝐚+𝐛, with the a and b in bold, but the + in normal weight. Characters rendered by \mathbf are rendered upright, even if they would have been rendered as italic otherwise.

The \boldsymbol command is an alternative to \mathbf that affects more characters, including Greek letters and symbols. It does not affect the style of the characters, so they remain italic if they were italic before. However, the inter-character spacing and italic correction may not be rendered correctly.

The \bm command from the bm package is a more modern alternative that affects even more characters. It also preserves the style of the characters, so they remain italic if they were italic before. The inter-character spacing and italic correction are handled correctly.

The \bm command is recommended over \boldsymbol and \mathbf. However, it is not part of the standard LaTeX distribution, so it may not always be available.

When serializing to LaTeX, MathLive will now use \mathbf when possible, and fall back to \bm when not. This should result in more consistent rendering of bold text.

When parsing, MathLive will interpret both \mathbf, \boldsymbol and \bm as bold.

The bold style is now consistently inherited by sub-expressions.

Similarly, when applying a bold style using mf.applyStyle({weight: "bold"}), the bold attribute is applied to the entire selection, not just the letters and numbers.

Mode Switching

  • #2375 The switch-mode command has two optionals arguments, a prefix and suffix. The prefix is inserted before the mode switch, and the suffix after. The command was behaving incorrectly. It now behaves as expected.
  • It is now possible to roundtrip between math and text mode. For example, selecting a fraction \frac{a}{b} and pressing alt+shift+T will convert the selection to (a)/(b). Pressing alt+shift+T again will convert it back to \frac{a}{b}.
  • When in LaTeX mode, changing the selection would sometimes unexpectedly exit LaTeX mode, for example after the Select All command. This has been fixed.

New Features

  • \href

    The \href{url}{content} command, a MathJax extension that allows a link to be associated with some content, is now supported.

    Clicking on the content will open the link. By default, the link is opened in a new window, and only links with a HTTP, HTTPS or FILE protocol are allowed. This can be controlled by the new MathfieldElement.openUrl property. This property is a function with a single argument, the URL to be opened, that is called when the content of the \href command is clicked on.

  • Tooltip appearance

    Added CSS variables to control the appearance of the toolip displayed with \mathtip and \texttip:

    • --tooltip-border
    • --tooltip-color
    • --tooltip-background-color
    • --tooltip-box-shadow
    • --tooltip-border-radius.
  • The maxMatrixCols property has been added that specifies the maximum number of columns that a matrix may have. The default value is 10, which follows the default value from the amsmath package. The property applies to all of the matrix environments (matrix, pmatrix, bmatrix, etc.). This property is also accessible via the max-matrix-cols attribute.

  • The virtual keyboard now supports variants for shifted-keys. This includes support for Swedish specific characters such as å, ä, and ö and their uppercase variants.

  • Accept "true" and "false" as values for on/off attributes in the <math-field> element, for example <math-field smart-fence="true">.

  • Added a target property (a MathfieldElement) to the onMenuSelect arguments.

  • #2337 Added an option MathfieldElement.restoreFocusWhenDocumentFocused to control whether a mathfield that was previously focused regains focus when the tab or window regains focus. This is true by default and matches the previous behavior, and the behavior of the <textarea> element.

  • An alternate syntax for selectors with arguments. Selectors are used for example to associate actions with a keycap, such as switchKeyboardLayer. The previous syntax was command: ["switchKeyboardLayer", "alt-layer"], the new syntax is command: 'switchKeyboardLayer("alt-layer")'. This is more concise and easier to read.

Issues Resolved

  • #2387 When using a macro, the spacing around the macro was incorrect in some cases.
  • #2370 The order of the keydown and input event is now consistent with the <textarea> element.
  • #2369 After typing a shortcut, using the backspace key could result in unexpected behavior. Now, pressing the backspace key after a shortcut has been typed will undo the conversion of the shortcut.
  • #2380 In some cases, when using the menu, some spurious focus/blur events would be dispatched.
  • #2384 When using repeating decimals after a comma (i.e. 123{,}4(1)), do not use a \left...\right command in order to get the proper spacing.
  • #2349 The positioning of subscripts for extensible symbols, such as \int was incorrect.
  • #2326 The Cut and Copy commands in the context menu are now working correctly in Safari.
  • #2309 When using styled text (e.g. \textit{}), the content could sometimes be serialized with an unnecessary \text{} command, i.e. \text{\textit{...}}.
  • #2376 When smart-fence was off, the { and } keys would not insert braces.
  • #2273 Using one of the Chinese locales would result in a runtime error.
  • #2355 When pressing the down arrow key in \sqrt[#?]{1} from the #? position, a runtime exception would occur.
  • #2298 When using screen readers, pressing the spacebar would not always correctly focus the mathfield.
  • #2297 In some cases, when using touch input, the previously selected item in a context menu would appear to be selected.
  • #2289 When changing the value of the mathfield, the selection is now preserved. In addition, when using a controlled component with React an unnecessary update is avoided.
  • #2282 Don't display selection when the mathfield is not focused
  • #2280 Handle better very deeply nested expressions
  • #2261 When a style was applied to an empty range, the style was ignored.
  • #2208 When setting a variant style (i.e. blackboard, fraktur, etc...) the style is no longer adopted by subsequent characters.
  • #2104, #2260 When replacing the selection by typing, the new content would not always be correctly styled. The content now inherits the style of the selection, or the style of the insertion point if the selection is collapsed.
  • Better handle the case where the mathlive library gets loaded before the DOM is constructed.
  • On Safari, the Insert Matrix submenu was displayed incorrectly.
  • When the mathfield is an iframe, the before-virtual-keyboard-toggle and virtual-keyboard-toggle events are now dispatched on the window.mathVirtualKeyboard object of the iframe. This can be used to detect a request (and prevent) for the virtual keyboard to be displayed.
  • If the unknown in an expression was a complex identifier, such as \mathcal{C} it would not be displayed correctly in the "Solve for" menu.
  • The \mathrlap command was incorrectly rendering like \mathllap.

0.98.6 2024-01-27

New Features

  • Added StaticRenderOptions.TeX.className to specify that an element with the specified class name should be rendered as a LaTeX formula.
  • #2273 Added a --keycap-width CSS variable to specify the width of a keycap in a virtual-keyboard. By default, if the CSS variable is not specified, the width of the keycap is calculated based on the width of the parent container. However, this requires browser that support the cq CSS unit. If the browser does not support the cq CSS unit, this CSS variable can be used to specify the width of the keycap. (See #2028, #2133)
  • #2255 Support for gather* environment
  • #2242 A virtual keyboard keycap can now include a tooltip for its shifted variant.

Issues Resolved

  • When using some APIs such as renderToMarkup() or renderToMathML() in a server-side environment, a runtime error would occur.
  • When tabbing in a mathfield with multiple prompts, tab out of the mathfield when the last or first prompt is reached.
  • **#2243##, **#2245** Unicode characters such as ² or are now interpreted as their LaTeX equivalent only when in math mode.
  • #2237 The command \iff now renders correctly
  • #2246 Changing the mf.value property would not always update the value of the mathfield.
  • #2244 Worked around an issue in Safari on iOS where doing a double-tap on the virtual keyboard would result in the mathfield losing focus and the virtualy keyboard closing.
  • #2252 At some viewport sizes, the integral sign in the symbols virtual keyboard would be clipped.
  • #2235 Improved serialization to ASCIIMath.
  • Avoid conflicts with some class names when rendering static math.
  • When using renderMathToElement() or renderMathInDocument(), coalesce adjacent text nodes.
  • Correctly parse the \cfrac optional alignment argument
  • The commands \bf, \bfseries, \mdseries, \upshape, \itshape, \slshape, \scshape, \rmfamily, \sffamily, \ttfamily are now interpreted correctly.
  • The command \operatorname is now spoken correctly
  • #2152 On Safari, fill-in-the-blank prompts containing a fraction were rendered incorrectly.
--- date: Last Modified title: Macros slug: /mathfield/guides/macros/ ---

Macros

Over [800 LaTeX commands](/mathfield/reference/commands/) are predefined. Some are primitives but others are macros, that is commands defined with a LaTeX expression. You can define your own macros.

Adding/Removing Macros

To add a macro use mf.macros = {...mf.macros, ...}.

If you do not include the ...mf.macros expression, all the standard macros will be turned off.

The example below will define a new command, \average, which will be replaced by \operatorname{average}, that is displayed as a single unit using an upright font.

Try changing \operatorname to \mathbf to see the difference.

:::html
<math-field id="mf">\average([2, 4, 8])</math-field>

:::js
const mf = document.getElementById("mf");
mf.macros = { ...mf.macros,
  average: '\\operatorname{average}',
};

You can use standard LaTeX commands in the definition of a macro. For example, the following macro definition uses the \, and \; commands to insert horizontal spacing and {}^ to place the \prime command on the subscript line.

mf.macros = { ...mf.macros,
  minutes: "\\,{}^\\prime\\;",
  seconds: "\\,\\doubleprime\\;",
};

The macro definition can contain up to eight arguments, represented by #1 to #9.

:::js
const mf = document.getElementById("mf");
mf.macros = {...mf.macros, 
  smallfrac: "{}^{#1}\\!\\!/\\!{}_{#2}",
};


:::html
<math-field id="mf">\smallfrac{5}{7}+\frac{5}{7}</math-field>

By default, a macro command behaves as a group whose subcomponents cannot be modified. This behavior can be controlled using the captureSelection flag in the expanded definition of a macro.

To define a macro whose content is selectable and editable set captureSelection to false.

:::js
const mf = document.getElementById("mf");
mf.macros = {...mf.macros,
  smallfrac: {
    args: 2,
    def: '{}^{#1}\\!\\!/\\!{}_{#2}',
    captureSelection: false,
  },
};


:::html
<math-field id="mf">\scriptCapitalE=\smallfrac{5}{7}+\frac{5}{7}</math-field>

To remove a macro set its definition to undefined:

:::js
const mf = document.getElementById('mf');
mf.macros = {...mf.macros, diamonds: undefined };

:::html
<math-field id="mf">\diamonds</math-field>

Adding a Matching Shortcut

By defining a new macro, a new LaTeX command is added to the dictionary of commands that can be used in a LaTeX expression.

To input a macro, type \ followed by the macro name, then RETURN

Custom macros are also included in the value of the mathfield expressed as a LaTeX string (mf.value).

It may also be convenient to associate the macro with an inline shortcut. Inline shortcuts can be typed without having to enter the LaTeX editing mode (without having to type the \ key).

To define an associated inline shortcut, use the inlineShortcuts option.

:::js
const mf = document.getElementById('mf');
//
mf.macros = {...mf.macros,
  // This means that the command macro `\minutes`
  // will be replaced with `\,{}^\\prime\\;`
  minutes: '\\,{}^\\prime\\;',
  seconds: '\\,\\doubleprime\\;',
};
//
mf.inlineShortcuts = {...mf.inlineShortcuts,
  // This means that typing the inline shortcut 
  // "minutes" will insert the command "\minutes"
  minutes: '\\minutes', 
  seconds: '\\seconds',
};


:::html
<math-field id="mf">
  3\minutes 15\seconds
</math-field>

Inspecting Available Macros

To view the available macros, inspect the macros property:

:::js
const mf = document.getElementById('mf');
console.log(mf.macros);


:::html
<math-field id='mf'>x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}</math-field>

Disabling Macros

To turn off all macros, use mf.macros = {}.


date: Last Modified title: Static Math Formulas slug: /mathfield/guides/static/

Static Math Formulas

Converting LaTeX to Various Formats

The mathfield library includes some utility functions to convert between various formats. These utility functions can be used without a mathfield. In fact, they do not require a browser environment at all, and can be used in a Node.js environment.

They are available as a Service Side Render (SSR) package which can be imported as follows:

import * from 'mathlive/ssr';

To convert LaTeX to HTML, use the convertLatexToMarkup() function.

import { convertLatexToMarkup } from 'mathlive';
console.log(convertLatexToMarkup('x^2 + y^2 = z^2'));

To convert LaTeX to MathML, use the latexToMathML() function.

import { convertLatexToMathMl } from 'mathlive';
console.log(convertLatexToMathMl('x^2 + y^2 = z^2'));

To convert LaTeX to spoken text, use the convertLatexToSpeakableText() function.

import { convertLatexToSpeakableText } from 'mathlive';
console.log(convertLatexToSpeakableText('x^2 + y^2 = z^2'));

To convert LaTeX to AsciiMath, use the convertLatexToAsciiMath() function.

import { convertLatexToAsciiMath } from 'mathlive';
console.log(convertLatexToAsciiMath('x^2 + y^2 = z^2'));

Converting From Various Formats to LaTeX

To convert MathJson to LaTeX, use the convertMathJsonToLatex() function.

import { convertMathJsonToLatex } from 'mathlive';
console.log(convertMathJsonToLatex(["Add", "x", "y"]));

To convert AsciiMath to LaTeX, use the convertAsciiMathToLatex() function.

import { asciiMathToLatex } from 'mathlive';
console.log(convertAsciiMathToLatex('x^2 + y^2 = z^2'));

Rendering Static Math Formulas

To render math contained in a document as a static (non-editable) formula, call renderMathInDocument() at the end of your document, or in a DOMContentLoaded event handler.

<script defer type="module">
  window.addEventListener('DOMContentLoaded', () => 
    import('https://esm.run/mathlive').then((mathlive) => 
      mathlive.renderMathInDocument()
    )
  );
</script>

By default, any LaTeX code in the text element of a DOM element that is enclosed with the following delimiters will be rendered as math:

  • \[...\] or $$...$$ -- rendered in Display Style (CSS display block)
  • \(...\) -- rendered in Text Style (CSS display inline)
<h1>Taxicab Number</h1>
<p>The second taxicab number 
   is \\(1729 = 10^3 + 9^3 = 12^3 + 1^3\\)
</p>

More complex expressions can be wrapped in a <script> tag. One of the benefits of this approach is that the browser will not attempt to display the content of the <script> tag before it is typeset, avoiding an unsightly flash of code on screen.

To render LaTeX code, use <script type="math/tex">

To render MathJSON, use <script type="math/json">

To render the formula inline, append ; mode=text to the type. If no mode is provided, or mode=display, the display (block) style is used.

<h1>Quadratic roots</h1>
<script type="math/json"> ["Add", 
    ["Multiply", "a", ["Square", "x"]]], 
    ["Multiply", "b", "x"], 
    "c"
  ]
</script>
<script type="math/tex; mode=text">
  =  a
  \left( x - \frac{-b + \sqrt {b^2-4ac}}{2a} \right)
  \left( x - \frac{-b - \sqrt {b^2-4ac}}{2a} \right)
</script>

The following DOM elements are ignored for conversion: <noscript>, <style>, <textarea>, <pre>, <code>, <annotation> and <annotation-xml>.

If you dynamically generate content, call renderMathInElement(element) to render your element after the page has been loaded. This is a recursive call that will be applied to element and all its children.

To render again elements or a whole document that has already been rendered, call renderMathInElement() and renderMathInDocument() again. This is useful when a change in the environment requires the layout to be updated.

To customize the behavior of the renderMathInElement() and renderMathInDocument() functions pass an optional options object literal:

  • skipTags: an array of tag names whose content will not be scanned for delimiters
  • processScriptType: <script> tags of the indicated type will be processed while others will be ignored. Default: "math/tex".
  • ignoreClass: a string used as a regular expression of class names of elements whose content will not be scanned for delimiters ("tex2jax_ignore" by default)
  • processClass: a string used as a regular expression of class names of elements whose content will be scanned for delimiters, even if their tag name or parent class name would have prevented them from doing so. ("tex2jax_process" by default)
  • TeX.processEnvironments: if false, math expression that start with \begin{ will not automatically be rendered. (true by default)
  • TeX.delimiters.inline and TeX.delimiters.display arrays of delimiters that will trigger a render of the content in 'textstyle' or 'displaystyle' style, respectively.
renderMathInElement(document.getElementById('formulas'), {
  // Elements with a class of "instruction" or "source"
  // will be skipped
  ignoreClass: 'instruction|source',
  TeX: {
    delimiters: {
      // Allow math formulas surrounded by $...$ or \(...\)
      // to be rendered as inline (textstyle) content.
      inline: [
        ['$', '$'],
        ['\\(', '\\)'],
      ],
      display: [],
    },
  },
});

Read-only Mathfield

When a math formula is displayed as a static element using renderMathInDocument(), the formula is transformed into some static markup. As a result, only the markup content can be selected, not the underlying LaTeX formula. Selection of a portion of the formula may also lead to unexpected results.

If preserving the ability to select a formula is important, consider using a read-only mathfield instead.

To create a read-only mathfield, add the read-only attribute to a <math-field> element.

:::html
<style>
math-field[read-only] {
  border: none;
  background-color: transparent;
}
</style>
<p>The solution of the equation is
<math-field read-only style="display:inline-block">
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>
</p>

date: Last Modified title: Speech slug: /mathfield/guides/speech/

Using Speech Output

To speak the formula or a portion of it, use these keyboard shortcuts:

  • alt/⌥ + ctrl + : speak the entire formula
  • alt/⌥ + ctrl + : speak the selection

To programatically trigger speech output, use:

mf.executeCommand('speak');

The command above will speak the entire formula. To speak a subset of the formula use:

mf.executeCommand(['speak', 'selection');

The options to specify the speech "scope" are:

all the entire formula
selection the selection portion of the formula
left the element to the left of the selection
right the element to the right of the selection
group the group (numerator, root, etc..) the selection is in
parent the parent of the selection

To get a textual representation of a spoken description of the formula, use the spoken-text format:

mf.getValue('spoken-text');

Configuring Speech Options

There are two aspects that can be configured independently:

  1. Speech Rules: the set of rules use to produce readable text from a math expression.

  2. Text-to-Speech engine: the software used to transform the readable text produced by the speech rules into sound. By default, the TTS engine provide by the operating system will be used, but you can use the Amazon Cloud TTS engine as well.

Speech Rules

A set of speech rules define how a math formula is transformed to speakable text.

To use the built-in speech rules, set MathfieldElement.textToSpeechRules to "mathlive".

Another set of speech rules supported are the SRE speech rules from Volker Sorge

To use the SRE speech rules:

  1. Include the browser version of the SRE JavaScript file in your project. You can download it on GitHub
  2. Set MathfieldElement.textToSpeechRules to "sre".

To configure SRE, set the MathfieldElement.textToSpeechRulesOptions property.

For example:

MathfieldElement.textToSpeechRulesOptions = {
    domain: 'mathspeak', // 'mathspeak' or 'chromevox'
    ruleset: 'mathspeak-brief',   // 'mathspeak-default', 
    // 'mathspeak-brief', 'mathspeak-sbrief', 'chromevox-short', 
    // 'chromevox-default' or 'chromevox-alternative'
};

Text-to-Speech Engine

Using the Local TTS Engine

To use the local (built-in, OS specific) TTS engine, set MathfieldElement.speechEngine to "local".

There is great variation between platforms (and browsers) on the quality of the TTS engine. However, it can be used even when offline, while the Amazon TTS engine offers higher quality and better consistency, but it does require a network connection.

Using Amazon Polly TTS Engine

  1. Include the AWS SDK for JavaScript in your app. See here for details. This may be as simple as adding this:
<head>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.657.0.min.js"></script>
    <script>
        AWS.config.region = 'eu-west-1';
        AWS.config.accessKeyId = 'YOUR-KEY';
        AWS.config.secretAccessKey = 'YOUR-SECRET';
    </script>
</head>

See npm for the latest version.

  1. To get the necessary keys, follow these instructions

    2.1 Create a custom policy in your AWS console with action: Read SynthesizeSpeech and a request condition of a referrer with a StringEquals to your domain, e.g. 'https://example.com/*'

    2.2 Create a group, and associated it with the policy above

    2.3. Create a new user, for example the name of your app. Give it 'programmatic access' and associate it with the group above

    2.4 At the end of the creation, you will be provided by the access key and the secret access key.

Carefully consider how to handle the access and secret access keys. With the setup above they are somewhat restricted to a domain, however, they could be abused if accessed by an unauthorized user. To prevent this, you could require users to authenticate and use AWS Cognito.

Speech Output Format

To configure the format of the speech output engine, use the MathfieldElement.textToSpeechMarkup. Set it to:

  • "ssml" to request an output using the SSML markup language. Both SRE and the Mathfield rules can produce this format.
  • "mac" to request an output using Mac OS speech markup, e.g. '[[slc 150]]'. This format can only be used on Mac OS (and may not work will all browsers). On platforms other than Mac OS, this option does nothing.
  • "" (empty string) to request no markup.

The Amazon TTS engine supports SSML, and it is recommended to use this option for the highest quality.


title: Changelog - Mathfield sidebar_label: Changelog slug: /mathfield/changelog/ toc_max_heading_level: 2

Mathfield Changelog

import ChangeLog from '@site/src/components/ChangeLog';

--- date: Last Modified title: Math Virtual Keyboard id: virtual-keyboard slug: /mathfield/virtual-keyboard/ --- Typing math requires access to many special symbols. While [keyboard shortcuts and inline shortcuts](/mathfield/guides/shortcuts) can help when a physical keyboard is available, touch-enabled devices without a physical keyboard attached need another solution.

The math virtual keyboard is a keyboard displayed on screen that gives access to specialized symbols for math input with only a tap.

Layout Selector

The math keyboard includes multiple layouts which can be chosen with the layout selector.

The default layouts include the most common math symbols. They are: numeric, symbols, alphabetic and greek letters.

These layouts can be customized to fit specific needs. Learn more about **customizing virtual keyboards**.

Undo/Redo/Paste

The Editing Toolbar display icons for common editing functions: Undo, Redo, Paste, Cut and Copy.

If you have a physical keyboard attached, these commands can be invoked with their corresponding keybindings: Ctrl/Command+Z, Ctrl/Command+Y, Ctrl/Command+V, Ctrl/Command+X and Ctrl/Command+C.

Shift Key

Press the Shift Key to access alternative symbols. The keyboard updates when the key is pressed to reveal the symbols.

If a physical keyboard is available, the SHIFT or CAPSLOCK key on the physical keyboard can also be used.

The symbol corresponding to the shifted variant is displayed in the top right corner of some keys. Some keys have a shifted variant even though they may not include a top-right label.

Variants

A key variant is a symbol that can be accessed by a long press on a keycap. The variant is often related to the original symbol.

To display variants related to a keycap, press and hold the keycap.

Many keycaps have variants, but a few don't.

Numeric Layout

Numeric Keyboard

Numeric Keyboard

Numeric Keyboard, shifted

Symbols Layout

Symbols Keyboard

Symbols Keyboard, shifted

Alphabetic Layout

Greek Layout


title: Menu slug: /mathfield/guides/menu/

Menu

The **Mathfield Context Menu** provides a set of commands to perform common operations on a mathfield.

To display the context menu:

  • Right-click on the mathfield
  • Long press on the mathfield
  • Tap on the menu toggle (hamburger icon) in the mathfield
  • Press the ALT/OPTION+SPACE, FN+F10 or MENU key on a physical keyboard

The context menu is fully accessible. It can be navigated using the keyboard, and the menu items are announced by screen readers.

To navigate the context menu, use the arrow keys.

An item can also be selected by typing some of the letters of its label.

The default context menu has a set of commands that are useful for most applications, but you can customize the menu by adding or removing commands as needed.

Filtering Menu Items

To select which menu items are displayed, use the filter() method on the mf.menuItems property.

For example, to omit all commands related to the Compute Engine (such as Evaluate, Simplify and Solve), you can filter the menu items by their id:

mf.menuItems = mf.menuItems.filter(item => !item.id.startWith('ce-'));

:::warning The mf.menuItems property is a read-only property. It returns a copy of the original array of menu items.

Do not modify the value of the elements of mf.menuItems directly. This will result in a runtime error.

For example, do not use mf.menuItems[0].visible = false. :::

Replacing the Menu

To replace the context menu with your own, set the mf.menuItems property.

The menuItems property is an array of menu items.

Each menu item is an object with the following properties:

  • type: one of "command", "divider", "submenu", "checkbox", "radio". The default is "command".
  • label: The label to display for the menu item. This can be a string literal or a function that returns a string. If a function is provided, it will be called to update the label whenever the menu is displayed or when the keyboard modifiers change. The value of the string is interpreted as HTML markup.
  • ariaLabel and ariaDetails: If provided, these will be used to set the aria-label and aria-details attributes of the menu item, which can be used by screen readers. Like the label property they can be either a string literal or a function that returns a string.
  • visible, enabled, checked are status flags that can be set to true or false to control the visibility, enabled state and checked state of the menu item.
  • id: A unique identifier for the menu item. This is the value that will be passed to the menu-select event when the menu item is selected.
  • data: An arbitrary data payload associated with the menu item, if any.
  • submenu: If the type is "submenu", an array of menu items to display when the menu item is selected.
  • onMenuSelect: A function handler that is called when the menu item is selected.
mf. menuItems = [
  {
    label: 'Copy',
    onMenuSelect: () => console.log('Copy')
  },
  {
    label: 'Paste',
    onMenuSelect: () => console.log('Paste')
  },
  {
    type: 'divider'
  },
  {
    label: 'Submenu',
    submenu: [
      {
        label: 'Submenu 1',
        onMenuSelect: () => console.log('Submenu 1')
      },
      {
        label: 'Submenu 2',
        onMenuSelect: () => console.log('Submenu 2')
      }
    ]
  },
];

Adding a Menu Item

To add a menu item, use the spread operator (...) to create a new array of menu items, and add the new menu item to the copy of the original array.:

mf.menuItems = [
  {
    label: "Cancel",
    visible: () =>
      mf.isSelectionEditable && !mf.selectionIsCollapsed,
    onMenuSelect: () => mf.insert("\\cancel{#@}"),
  },
  ...mf.menuItems,
];

In this example, a new menu item for a Cancel command is added at the beginning of the menu.

The visible handler checks that the selection is editable and not collapsed.

The onMenuSelect handler replaces the selection with a \cancel{} command. The #@ token is replaced with the current selection, effectively wrapping the selection in a \cancel{} command.

To add a menu item at a specific position, use the findIndex() method to find the index of the menu item you want to insert relative to.

const isNonEmptySelection = () => mf.getValue(mf.selection).length > 0;
const getCancelArgument = () => {
  const selection = mf.getValue(mf.selection);
  // Is the selection a \cancel{...} command?
  const match = selection.match(/^\\cancel{([^}]*)}$/);
  return match ? match[1] : '';
};

const menuItems = mf.menuItems;

// Find the index of the "Cut" menu item
const index = menuItems.findIndex(item => item.id === 'cut');
mf.menuItems = [
  // Add the new menu item before the "Cut" menu item
  ...menuItems.slice(0, index),

  // Add the new commands
  { type: 'divider' },
  {
    label: "Cancel",
    visible: () =>
      mf.isSelectionEditable && isNonEmptySelection() && !getCancelArgument(),
    onMenuSelect: () => 
      mf.insert("\\cancel{#@}", { selectionMode: 'item' }),
  },
  {
    label: "Uncancel",
    visible: () => mf.isSelectionEditable && getCancelArgument(),
    onMenuSelect: () => 
      mf.insert(getCancelArgument(), { selectionMode: 'item' }),
  },
  { type: 'divider' },

  // Add the rest of the menu items after the "Cut" menu item
  ...menuItems.slice(index)
];

In this example, new menu items are added after the Cut menu item. We make a new array of menu items by slicing the original array into two parts:

  • The first part is the menu items before the Cut item.
  • The second part is the menu items after the Cut item. The new menu items are added in between the two parts.

We add a divider before and after the new menu items, which can be useful to group related menu items together.

We add two new menu items: Cancel and Uncancel. The Cancel item is only visible when the selection is editable, not empty and not already a cancel command. The Uncancel item is only visible when the selection is editable and is a cancel command. At most one of the two commands will be visible, allowing the user to either cancel or uncancel the selection.

Listening to Menu Events

When a menu item is selected, its onMenuSelect handler is invoked and a menu-select custom event is dispatched.

It is generally simpler to provide a onMenuSelect handler for each menu item, but you can also listen to the menu-select event to handle all menu item selections in a single event handler.

The detail property of the menu-select event contains the following properties:

  • id: The id of the menu item that was selected.
  • label: The label of the menu item that was selected.
  • data: The data payload associated with the menu item, if any.
  • modifiers: An object containing the state of the modifier keys when the menu item was selected. The following properties are defined:
    • altKey
    • ctrlKey
    • metaKey
    • shiftKey

The example above which use onMenuSelect can be rewritten to use the menu-select event instead. Note that in this case, the menu items have an id property, which is used to identify the menu item that was selected.

mf. menuItems = [
  {
    label: 'Copy',
    id: 'copy'
  },
  {
    label: 'Paste',
    id: 'paste'
  },
  {
    type: 'divider'
  },
  {
    label: 'Submenu',
    submenu: [
      {
        label: 'Submenu 1',
        id: 'submenu-1'
      },
      {
        label: 'Submenu 2',
        id: 'submenu-2'
      }
    ]
  },
];

mf.addEventListener('menu-select', (event) => 
  console.log('Menu item selected:', event.detail.id)
);

Controling the Menu Visibility

To hide the menu toggle button use the following CSS:

math-field::part(menu-toggle) {
  display: none;
}

Even when the menu toggle button is hidden, the context menu is still accessible with a keyboard shortcut, right-click or long press.

To prevent the menu from being displayed, set the mf.menuItems property to an empty array:

mf.menuItems = [];

date: Last Modified title: Using a Mathfield with Svelte slug: /mathfield/guides/svelte/

Theory of Operations

A Svelte wrapper manages the scaffolding of the web component, allowing it to be used like a standard web component with all attributes forwarded.

Install Mathlive

$ npm install --save-dev mathlive

Create a Svelte Wrapper Component

<script lang="ts">
  import "mathlive";
  import type { MathfieldElement, MathfieldElementAttributes } from "mathlive";
  import { on } from "svelte/events";

  type Props = { value?: string } & Partial<MathfieldElementAttributes>;

  let { value = $bindable(), ...rest }: Props = $props();

  const init = (node: MathfieldElement) => {
    $effect(() => {
      if (value) node.value = value;
    });
    $effect(() => {
      return on(node, "input", () => {
        value = node.value;
      });
    });
  };
</script>

<math-field use:init {...rest}></math-field>

Append the following to src/app.d.ts. This provides autocomplete for the web component.

// ...previous code

import { type MathfieldElementAttributes } from "mathlive";

declare namespace svelteHTML {
	interface IntrinsicElements {
    'math-field': MathfieldElementAttributes;
	}
}

Usage

<script>
  import MathField from "$lib/MathField.svelte";
</script>

<MathField />

Customization

<script>
  import MathField from "$lib/MathField.svelte";
  let value = $state("1");

  const config = {
    "smart-mode": true
    // ...
    // see here for the full list of API's
    // https://cortexjs.io/mathfield/api/
  }
</script>

<!-- define settings via props -->
<MathField smart-mode="true" style="width:100%"></MathField>

<!-- define settings via an object -->
<MathField {...config}></MathField>

<!-- 2-way binding -->
<MathField bind:value></MathField>

<p>Current value: {value}</p>

<button
  onclick={() => {value = String.raw`x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}`}}>
  reset to default
</button>
A ready-to-run example project is available on **Sveltelab**

date: Last Modified title: Keybindings and Inline Shortcuts slug: /mathfield/guides/shortcuts/ toc_max_heading_level: 2

Keybindings

A key binding is a combination of keys pressed simultaneously on a physical keyboard that triggers a command.

For example, pressing the Alt/Option/⌥ key and the V key at the same time will insert a square root. Pressing the Control/Command/⌘ key and the Z key at the same time will undo the last command.

There is an extensive set of default keybindings available.

To override, customize or add to the list of supported keybindings, set the keybindings property on a mathfield element.

const mf = document.getElementById('mf');
mf.keybindings = [
  ...mf.keybindings,  // preserve existing keybindings
  {
    key: 'ctrl+alt+shift+[KeyT]',
    ifMode: 'math',
    command: ['switchMode', 'text'],
  },
  {
    key: 'ctrl+alt+shift+[KeyT]',
    ifMode: 'text',
    command: ['switchMode', 'math'],
  },
];

If using an insert command, the LaTeX fragment argument of the function can include one of the following special placeholder tokens:

  • #@: replaced with the selection, if there is one. If there is no selection, replaced with an implicit argument to the left of the caret. For example, for 12+34, if the caret is at the end, #@ would be replaced with 34.
  • #?: replaced with a \placeholder{} expression

International Keyboards

Correctly handling keyboard shortcuts while accounting for non-US keyboard layout is surprisingly difficult. The mathfield element uses some heuristics that may occasionally result in surprising results.

This section details how keyboard events are used to determine which keyboard shortcut to activate.

Let's consider the keyboard shortcut CONTROL/⌘+ALT/OPTION+A

When this key combination is pressed on a keyboard with a US keyboard layout, the event received will have the properties code = "KeyA" and key = "\u00e5".

On a French AZERTY keyboard layout, the event received will have code = "KeyQ" and key = "\u00e6".

Why is the code KeyQ even though the user pressed the key labeled A on their AZERTY keyboard? On this keyboard layout, the Q and A keys are swapped compared to the US layout and the code property reflects the "physical" key pressed.

This is not unusual. While some keys retain their positions, many keys are swapped around or altogether unique in some layouts, particularly for punctuations and symbols. The code property of the event does not represent the label of the key, but indicates the physical position of the key as if it was on a US keyboard, in this case "the key immediately to the right of the caps lock key, which is labeled Q on a US keyboard (but is labeled A on a French keyboard)".

What we want to know is that the user pressed a key labeled A. But none of the information in the event record tells us that. The value of the key field varies depending on the keyboard layout and the modifiers pressed.

However, if we know the keyboard layout, we can use a table that maps the value of the key field to infer the label of the key the user pressed, i.e. what the user sees printed on the top of the key cap, regardless of its physical location on the keyboard. Once we have the label, we can figure out that the user pressed CONTROL/COMMAND/⌘ + A using the modifier fields of the event.

But how do we know what is the current keyboard layout? There is unfortunately no web platform API (broadly supported) to obtain that information. So one approach is to indicate programmatically which keyboard layout the user is using. Otherwise, the mathfield will use the user locale to guess the keyboard (for example, guessing to use the French AZERTY keyboard if the user locale is France).

Finally, the mathfield uses a heuristic to refine its guess: with each keyboard event, the mathfield checks that the info in the event record (specifically the code and key fields) is consistent with the current keyboard layout. If not, it finds a better matching keyboard layout, and will switch to that keyboard layout if it is confident enough of that guess.

The mathfield element currently has a limited set of "known" keyboard layouts. If you happen to use an unknown keyboard layout, it will guess the wrong keyboard layout. As a result some keyboard shortcuts may produce unexpected results.

Inline Shortcuts

An inline shortcut is a sequence of keystrokes typed on the keyboard that get replaced with another symbol. Unlike keybindings they cannot be used to trigger a command, only to insert a LaTeX fragment.

For example, typing the P key followed by the I key will result in the \pi \[ \pi \] LaTeX fragment being inserted, and not the pi characters.

Inline shortcuts can be typed either using a physical keyboard or the virtual keyboard.

If a substitution was undesirable, use Undo (Control/Command/⌘ + Z) to revert to the raw input.

To prevent two consecutive characters to be recognized as part of a shortcut sequence, press the Space bar between them.

Some built-in inline shortcuts are defined, but they can be replaced or enhanced with additional shortcuts.

On line 4, we're adding a shortcut for "infty".

:::js
const mf = document.getElementById('mf');
mf.inlineShortcuts = {
  ...mf.inlineShortcuts,    // Preserve default shortcuts
  "infty": '\\infty'
};
:::html
<math-field id="mf">
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

To constraint the context in which a shortcut should apply, use the after property:

mf.inlineShortcuts = {
  ...mf.inlineShortcuts,    // Preserve default shortcuts
  "in": {
      after: "space | letter | digit | symbol | fence",
      value: "\\in",
  }
};

The after property indicate in what context the shortcut should apply. One or more values can be specified, separated by a | sign. If any of the values match, the shortcut will be applicable.

Possible values are:

  • "space" A spacing command, such as \quad
  • "nothing" The begining of a group
  • "surd" A square root or n-th root
  • "frac" A fraction
  • "function" A function such as \sin or f
  • "letter" A letter, such as x or n
  • "digit" 0 through 9
  • "binop" A binary operator, such as +
  • "relop" A relational operator, such as =
  • "punct" A punctuation mark, such as ,
  • "array" An array, such as a matrix or cases statement
  • "openfence" An opening fence, such as (
  • "closefence" A closing fence such as }
  • "text" Some plain text

Multicharacter Symbols

It may not be possible to define in advance all the keystroke combinations that should be interpreted as an inline shortcut.

For example, it might be desirable to recognize multi-character symbols, e.g. \( \mathrm{speed} = \frac{\mathrm{distance}}{\mathrm{time}} \)

There are several ways to represent multicharacter symbols in LaTeX. Conventionally, the \mathit{} command is used to represent variables and the \mathrm{} for function names. You may prefer to use \mathrm{} in both cases. The command \operatorname{} may also be used for this purpose.

To recognize multicharacter symbols, provide a onInlineShortcut() handler. If the handler recognize the input as a valid multichar symbols, it should return a command representing this symbols.

The string passed to the onInlineShortcut handler is a raw sequence of characters the user typed on the physical or virtual keyboard.

mf.onInlineShortcut = (_mf, s) => {
  if (/^[A-Z][a-z]+$/.test(s)) return `\\mathrm{${s}}`;
  if (/^[a-z][a-z]+$/.test(s)) return `\\mathit{${s}}`;
  return '';
};

You can use the onInlineShortcut handler to recognize arbitrary patterns.

For example:

mf.onInlineShortcut = (_mf, s) => {
  if (/^[a-zA-Z][a-zA-Z0-9]*'?(_[a-zA-Z0-9]+'?)?$/.test(s)) {
    const m = s.match(/^([a-zA-Z]+)([0-9]+)$/);
    if (m) {
      if (['alpha', 'beta', 'gamma'].includes(m[1]))
        return `\\${m[1]}_{${m[2]}}`;
      return `\\mathrm{${m[1]}}_{${m[2]}}`;
    }
    return `\\mathrm{${s}}`;
  }
  return '';
};

This will recognize "alpha34" -> \alpha_{34} or "speed" -> \mathrm{speed}.

Customizing the Inline Shortcut Sensitivity

To change how quickly a set of keys must be typed to be considered a shortcut set the inlineShortcutTimeout property.

It represents the maximum amount of time, in milliseconds, between consecutive characters for them to be considered part of the same shortcut sequence.

A value of 0 is the same as infinity: any consecutive character will be candidate for an inline shortcut, regardless of the interval between this character and the previous one.

A value of 750 will indicate that the maximum interval between two characters to be considered part of the same inline shortcut sequence is 3/4 of a second.

This is useful to enter +- as a sequence of two characters, while also supporting the ± shortcut with the same sequence.

The first result can be entered by pausing slightly between the first and second character if this option is set to a value of 250 or so.

Note that some operations, such as clicking to change the selection, or losing the focus on the mathfield, will automatically timeout the shortcuts.

ASCIIMath Inline Shortcuts

ASCIIMath defines a series of shortcuts that can be typed with ASCII characters to represent mathematical symbols and expressions.

**Learn more:** ASCIIMath and other default keybindings

title: Getting Started slug: /mathfield/guides/getting-started/

Getting Started

Let's add an editable mathfield to a web page.

1. Load the Mathfield library from a CDN with a <script> tag.

<script defer src="https://cdn.jsdelivr.net/npm/mathlive"></script>

Alternatively, you can use the unpkg CDN to load the module:

<script defer src="https://unpkg.com/mathlive"></script>

2. Add a <math-field> tag. The content of this tag is the initial value of the mathfield, as a LaTeX expression.

<math-field>f(x) = \sin(x+\pi)</math-field>

:::info[Note] LaTeX is a plain text markup language for structured documents. Most LaTeX commands start with a \, for example \sqrt, \frac and \sin.

Read more about the LaTeX commands available in a mathfield :::

Try it Out

In the code playground below, change the content inside the <math-field> tag.

For example change it to f(x) = \frac{x}{2}.

:::info[Note]

The code playground here and in the rest of the documentation are live: when you modify the HTML or JavaScript code the output will update to reflect your changes.

Press Reset to bring back the playground to its original state.

:::

:::html
<math-field>
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

Vanilla HTML Example

Here's a complete web page using a <math-field> in vanilla HTML:

<!doctype html>
<html>

<head>
  <meta charset="utf-8" />
  <title>untitled</title>
  <script defer src="https://cdn.jsdelivr.net/npm/mathlive"></script>
</head>

<body>
  <math-field id="mf">x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}</math-field>
  <script>
    mf.addEventListener('input', evt =>
      console.log('Value:', evt.target.value)
    );
  </script>
</body>

</html>

React Example

To use mathfields in a React project, use a <math-field> tag with JSX:

import "https://esm.run/mathlive";
import { useState } from "react";

export View = () => {
  const [value, setValue] = useState("f(x) = \\frac{x}{2}");

  return (
    <math-field 
      onInput={evt => setValue(evt.target.value)}
    > {value} </math-field>
    <p>Value: {value}</p>
  );
}
Read more about using mathfields with **React** Read more about using mathfields with **Svelte**

Caution

:::warning[Caution: HTML quirks mode]

The HTML quirks mode is not supported.

The host page must use the strict mode by including a <!DOCTYPE html> directive at the top of the page.

Without it, the layout of the expression inside the mathfield may be incorrect.

:::

:::warning[Caution: file:// protocol] For security reasons there are some restrictions when using the file:// protocol. This happens if you open a file in the browser from your local file storage. You will notice the adress in the browser address bar starts with file://.

In this situation, some functionality may not be available and some errors may be displayed in the console.

To prevent this, use a local file server.

With VSCode, the Live Server extension can be used to launch a local development server with one click.

:::

:::warning[Caution: CSP (Content Security Policy)]

In order to interactively display mathfields, some CSS styles are generated dynamically. If you are using a Content Security Policy (CSP), you may need to adjust it to allow the use of inline styles.

Specifically, you may need to add 'unsafe-inline' to the style-src directive in your CSP.

<meta http-equiv="Content-Security-Policy" content="style-src 'self' 'unsafe-inline';">

:::

Learn more about other options to add mathfields to your project

date: Last Modified title: Commands slug: /mathfield/guides/commands/

toc: true


Commands

You can perform editing operations on the mathfield programmatically. For example, to insert a fraction when the user clicks a button.

You can do this by dispatching commands to the mathfield, such as "select-all", "move-to-next-char", "delete-backward", etc...

To dispatch commands use the mf.executeCommand() method.

mf.executeCommand("delete-backward");

To associate commands with virtual keyboard keycaps use the command property of the keycap definition. For example:

{ 
  "class": "action", 
  "label": "Delete", 
  "command": 'perform-with-feedback("delete-backward")'
}

Commands are identified by a string called the selector.

The selector can use either CamelCase or kebab-case syntax. For example: "moveToNextChar" or "move-to-next-char" are the same selector.

Most commands take no parameters. When a command does have a parameter, a tuple with the selector and the commands arguments can be passed to executeCommand(). For example:

mf.executeCommand(["insert", "(#0)"]);

The command above will insert an open and close parenthesis around the selection (the #0 sequence is replaced with the current selection).

Editing Commands

  • insert This selector takes two arguments. The first one is required and is the content to be inserted, as a string. The second one is an optional set of key value pairs:
    • insertionMode: one of "replaceSelection", "replaceAll", "insertBefore" or "insertAfter".
    • selectionMode: one of "placeholder" (the selection will be the first available placeholder in the item that has been inserted), "after" (the selection will be an insertion point after the item that has been inserted), "before" (the selection will be an insertion point before the item that has been inserted) or "item" (the item that was inserted will be selected).
  • delete Synonym for deleteNextChar
  • deleteBackward deleteForward
  • deleteNextWord deletePreviousWord
  • deleteToGroupStart deleteToGroupEnd
  • deleteToMathFieldEnd
  • deleteAll
  • transpose

Edit Menu

  • undo
  • redo
  • cutToClipboard
  • copyToClipboard
  • pasteFromClipboard

User Interface

  • commit The user has completed input. Triggered when pressing the RETURN or ENTER key.
  • switchMode
  • complete Exit command mode and insert result
  • nextSuggestion and previousSuggestion when the popover panel is selected, display the next/previous suggestion
  • toggleKeystrokeCaption Show/hide the keystroke caption panel. This panel displays the keys being typed, including the shortcuts. Great for demos!
  • toggleVirtualKeyboard Show/hide the virtual keyboard

Scrolling

  • scrollToStart
  • scrollToEnd
  • scrollIntoView

Navigating

  • moveToNextChar moveToPreviousChar
  • moveToNextPlaceholder moveToPreviousPlaceholder
  • moveToNextWord moveToPreviousWord
  • moveToGroupStart moveToGroupEnd
  • moveToMathfieldStart moveToMathfieldEnd
  • moveUp moveDown
  • moveToSuperscript moveToSubscript
  • moveToOpposite
  • moveBeforeParent moveAfterParent

Extending the Selection

  • selectGroup
  • selectAll
  • extendToNextChar extendToPreviousChar
  • extendToNextWord extendToPreviousWord
  • extendUp extendDown
  • extendToNextBoundary extendToPreviousBoundary
  • extendToGroupStart extendToGroupEnd
  • extendToMathFieldStart extendToMathFieldEnd

Arrays

  • addRowAfter addRowBefore
  • addColumnAfter addColumnBefore
  • removeRow removeColumn

Speech

  • speak This selector takes an optional argument, the string that determines what should be spoken. The valid values are:

    • all
    • left
    • right
    • selection
    • parent
    • group

    The second parameter determines whether what is being spoken should be highlighted. It is an object: {withHighlighting: boolean} (default is false). Note: highlighting currently only works when using Amazon's AWS speech synthesizer.


date: Last Modified title: Interacting with a Mathfield slug: /mathfield/guides/interacting/

Interacting with a Mathfield

Changing the Content of a Mathfield

To change the value of a <math-field> element programatically set its value property.

In the playground below, the LaTeX input field is editable and is reflected in the mathfield, and vice-versa.

:::info[Note]

Note that we use the silenceNotifications option when changing the content of the mathfield, to prevent an "input" event from being triggered and creating an infinite loop.

:::

:::js
const mf = document.getElementById("formula");
const latex = document.getElementById("latex");
//
mf.addEventListener("input",(ev) => latex.value = mf.value);
//
latex.value = mf.value;
//
// Listen for changes in the "latex" text field, 
// and reflect its value in the mathfield.
//
latex.addEventListener("input", (ev) => 
    mf.setValue(
      ev.target.value, 
      {silenceNotifications: true}
    )
);

:::html
<label>Mathfield</label>
<math-field id="formula">
    x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>          
<label>Latex</label>
<textarea id="latex" autocapitalize="off" autocomplete="off"
  autocorrect="off" spellcheck="false"></textarea>

Reading the Content of a Mathfield

To read the content of a <math-field> element as a LaTeX string use its value property, just like with a <textarea>.

To be notified when the content of the mathfield is modified listen for an "input" event.

Try: modify the "input" event below to a "change" event. Notice how the "change" event is only sent if you press the RETURN or ENTER key, or when the mathfield loses focus and the content has been modified.

:::js
document.getElementById('formula').addEventListener('input',(ev) => {
  // `ev.target` is an instance of `MathfieldElement`
  console.log(ev.target.value);
});

:::html
<math-field id="formula">
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

Reading the value property is equivalent to calling the getValue() method with no argument.

To control the format of the result, pass options to getValue(). For example to get the content as a MathJSON expression, use mf.getValue('math-json').

Try: Other formats are available: change "math-json" to "spoken-text".

:::html
<math-field id="formula">
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

:::js
import 'compute-engine';
const mf = document.getElementById('formula');

// `ev.target` is an instance of `MathfieldElement`
mf.addEventListener('input',
  (ev) => console.log(ev.target.getValue('math-json'))
);

Using a Mathfield with the Compute Engine

The MathJSON format is a lightweight mathematical notation interchange format.

The Compute Engine is a JavaScript library that can perform mathematical operations on MathJSON expressions.

To use the Compute Engine, import the Compute Engine library, e.g. import "https://esm.run/@cortex-js/compute-engine"

If the Compute Engine has been loaded in the page, mathfields will automatically create an instance of the compute engine when needed.

To access that shared Compute Engine instance, use MathfieldElement.computeEngine.

:::info[Note] If the value returned is undefined, it means that the Compute Engine has not been loaded in the page. :::

You can also create your own instance of the Compute Engine and pass it to the mathfield using the computeEngine property.

import { ComputeEngine } from 'compute-engine';
MathfieldElement.computeEngine = new ComputeEngine();

:::info[Note] This is usually not necessary and you can rely on the default shared instance of the Compute Engine. :::

To read the content of a <math-field> element as a boxed MathJSON expression use the mathfield expression property.

Using mf.expression is equivalent to calling MathfieldElement.computeEngine.parse(mf.value) or MathfieldElement.computeEngine.box(mf.getValue("math-json")).

Once you have a boxed expression, you can perform operations on it using the Compute Engine.

For example, you can:

:::info[Note]

Note that the expressions are returned by default in a canonical form, which means that they may be different from the original input. For example, x + 1 and 1 + x are considered equal, and will be returned as 1 + x. If necessary you can request non-canonical forms. :::

Learn more about **canonical forms**.

You can also extend the definitions of the Compute Engine by adding your own.

:::html
<math-field id="formula">
  \mathrm{Expand}((a+b)^6)
</math-field>

:::js
import 'compute-engine';
const mf = document.getElementById('formula');
mf.addEventListener('input', () => 
  console.log(mf.expression.evaluate())
);
console.log(mf.expression.evaluate());
Learn more about **symbolic computing** with the Compute Engine

Listening for Changes to a Mathfield

The mathfield element dispatches the beforeinput and input Input Events, which are also implemented by <textarea> and similar elements.

The beforeinput and input events implement the InputEvent interface.

These events are sent before (beforeinput event) and after (input event) a user attempts to edit the mathfield. This includes insertion and deletion of content, and formatting changes.

The events include an inputType property that describe what caused the event to be dispatched.

inputType
insertText Some content was added. It could be math content, plain text or raw latex. It could also be a row or column in matrix that was added.
insertLineBreak The RETURN or ENTER key was pressed. Note that the actual content of the mathfield may not have changed.
insertFromPaste The content of the mathfield was changed because of a paste operation
deleteWordBackward
deleteWordForward
deleteWordForward
deleteSoftLineBackward
deleteSoftLineForward
deleteHardLineBackward
deleteHardLineForward
deleteByCut The content was changed because of a cut operation
deleteContent Some content was deleted, but no particular direction applied
deleteContentBackward
deleteContentForward
historyUndo The content was changed because of an undo command
historyRedo The content was changed because of a redo command

:::warning

On iOS, the inputType property is removed. However, its content can also be access as ev.data. Until this issue is addressed in iOS, for better compatibility, use ev.data.

:::

The beforeinput event is dispatched before any modifications to the mathfield have been done. This event is cancelable. Calling preventDefault() on the event will cause the modification to be prevented.

If the beforeinput event is not canceled, the mathfield content is modified and a input event is dispatched. The input event is not cancelable.

Detecting When the User has Finished Editing a Mathfield

To detect when the user presses the RETURN or ENTER key in a mathfield, listen for the change event.

Note that this event is not fired when in LaTeX editing mode, where Return or Enter is used to exit the mode.

This event is also fired if the mathfield loses focus, even if the user did not use the keyboard. This behavior matches the <textarea> element.

To listen specifically for a press of the RETURN or ENTER key on the keyboard listen for an input event with an inputType (or ev.data on iOS) property of "insertLineBreak".

mf.addEventListener('beforeinput', (ev) => {
  if (ev.inputType === 'insertLineBreak') {
    mf.executeCommand("moveToNextPlaceholder");
    ev.preventDefault();
  };
});

Detecting a Click on a Mathfield

In most cases MathLive will respond to mouse and keyboard interactions with the mathfield. However, in some cases it might be useful to detect when a mathfield is clicked on. For example, you could display one or more read-only mathfields in a list and prompt the user to pick one by clicking on it.

In general, to be notified of an event, use mf.addEventListener(). This includes some generic events, as well as some that are specific to mathfields.

Events that target a DOM element inside the mathfield (inside the shadow DOM) will bubble and be retargeted to appear as if they had targeted the mathfield (that is, the evt.target will be the mathfield itself).

This include the following standard events:

  • change: the RETURN or ENTER key was pressed, or the field lost focus.
  • blur, focus, focusin, focusout
  • click
  • mousedown, mouseup, mousemove, mouseout, mouseover`
  • beforeinput, input. If the inputType property of the event is "insertLineBreak" the RETURN or ENTER key was pressed
  • keydown, keypress, keyup
  • wheel
  • all the pointer events such as pointerdown, pointerup, etc... and all the touch events

As well as these mathfield specific events:

  • mount: the mathfield has been connected to the DOM
  • unmount: the mathfield is no longer connected to the DOM
  • focus-out: tab key interactions
  • move-out: arrow key interactions
  • mode-change: change to math, text or latex mode
  • read-aloud-status-change
  • selection-change
  • undo-state-change

Detecting Navigation out of a Mathfield

A user may navigate outside of a mathfield by pressing the arrow keys, or the tab, home and end keys.

By default, the mathfield reacts as a standard textarea field: moving to the next focusable element when the TAB (or SHIFT+TAB) key is pressed, and doing nothing when reaching the start or end of the mathfield when navigation with the arrow keys.

In some cases, you may want to implement a different behavior. For example if a mathfield is embedded inside an editable paragraph, you may want the arrow keys to exit the mathfield when reaching the end/start. Or you may want the TAB key to simply move the caret to the end/start of the mathfield.

To change the behavior of a mathfield when navigation out of a mathfield listen for the focus-out and move-out events.

The detail property of those events indicate the direction of navigation. To cancel the default behavior, use ev.preventDefault().

mf.addEventListener('move-out', (ev) => {
ev.preventDefault();
  // Remove focus from mathfield
  mf.blur();
  // Focus some other element, use ev.detail.direction to detect if 
  // navigating backward, forward, upward or downward
  // ...
});

mf.addEventListener('focus-out', (ev) => {
  ev.preventDefault();
  // Move the cursor to the start/end of the mathfield on tab
  if (ev.detail.direction === 'forward')
    mf.executeCommand('moveToMathfieldEnd');
  else if (ev.detail.direction === 'backward')
    mf.executeCommand('moveToMathfieldStart');
});

Interacting with the Clipboard

Users can export the content of the mathfield by using standard Copy/Cut commands (Control/⌘ X and Control/⌘ C).

Multiple flavors are put on the clipboard:

text/plain LaTeX wrapped with a $$.
application/x-latex Raw LaTeX
application/json A MathJSON representation of the formula.

The recipient of the Paste operation can pick whichever is most appropriate. If the recipient is a web app, the specific flavor can be accessed using the event.clipboardData.getData() API. If the recipient is a native app, the most popular browsers currently only make accessible the text flavor, with a LaTeX representation of the formula.

The LaTeX in the text/plain flavor is "wrapped" to make it easier for the recipient of the paste to recognize that this content is in LaTeX format.

:::info[Note]

For improved interoperability, the exported LaTeX uses the latex-expanded format. In this format, any macros in the formula are expanded to their definition. For example, the \differentialD command is exported as its corresponding definition, \mathrm{d}. :::

To customize the content of the text/plain flavor, use the onExport() hook.

For example, to wrap the exported latex with <math>...</math> instead:

mf.onExport = (mf, latex) => `<math>${latex}</math>`

To export the "raw" (not expanded) LaTeX), use:

mf.onExport = (mf, latex, range) => `$$${mf.getValue(range, 'latex')}$$`

The exported format doesn't have to be LaTeX. To export ASCIIMath instead:

mf.onExport = (mf, latex, range) => 
    "`" + mf.getValue(range, 'ascii-math') + "`"

:::info[Note]

The standard delimiter for ASCIIMath is the ` (backtick) character

:::

Applying Style to a Mathfield

The text color ("ink") and background color ("paper"), as well as other stylistic attributes, can be changed on a mathfield, or a portion of a mathfield using applyStyle().

:::info[Note] This style applies to the content of the formula and will be reflected in the LaTeX output. To change the appearance of the mathfield but not the content of the formula, see Customizing. :::

:::js
const mf = document.getElementById('formula');

// Change the background color of the entire mathfield
mf.applyStyle(
  { backgroundColor: 'yellow' },
  { range: [0, -1] }
);

:::html
<math-field id="formula">
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

To change the style of a portion of the mathfield, specify a selection range to applyStyle().

:::js
const mf = document.getElementById('formula');

// Change the color and size of the first two characters of the mathfield
mf.applyStyle({color: "red", fontSize: 7 }, { range: [0, 2] });

:::html
<math-field id="formula">
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

To remove a style, set the value of the fontFamily, color or backgroundColor property to "none", or the value of the fontShape, fontSeries or fontSize property to "auto".

:::info[Note] You can ignore styles applied to a formula by using mf.getValue('latex-unstyled') :::


date: Last Modified title: Virtual Keyboard slug: /mathfield/guides/virtual-keyboard/

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

Customizing the Virtual Keyboard

The **Mathfield virtual keyboard** is a keyboard displayed on screen that gives access to specialized symbols for math input with only a tap.

This guide explains how to customize the virtual keyboard.

Learn more about **using the math virtual keyboard**

Controlling when the Virtual Keyboard is Displayed

The default behavior is to display the virtual keyboard when a mathfield is focused on a touch-enabled devices: mobile phones, tablets and laptops with a touch-screen.

This behavior can be changed with the mf.mathVirtualKeyboardPolicy property or the equivalent math-virtual-keyboard-policy attribute (set one or the other, not both).

mathVirtualKeyboardPolicy
"auto" On touch-enabled devices, show the virtual keyboard panel when the mathfield is focused. This is the default behavior.
"manual" Do not show the virtual keyboard panel automatically. The visibility of the virtual keyboard panel can be controlled programatically with mathVirtualKeyboard.show() and mathVirtualKeyboard.hide()
"sandboxed" The virtual keyboard is displayed in the current browsing context (iframe) if it has a defined container or is the top-level browsing context.

To show the math virtual keyboard anytime the mathfield is focused, on touch or non-touch devices, use:

mf.mathVirtualKeyboardPolicy = "manual";
mf.addEventListener("focusin", () =>  mathVirtualKeyboard.show());
mf.addEventListener("focusout", () =>  mathVirtualKeyboard.hide());

Controlling the Virtual Toggle Visibility

The virtual keyboard toggle is displayed by default when the mathfield can be modified, that is when it's not read-only or disabled.

To control the visibility of the virtual keyboard toggle, use CSS.

For example to hide the toggle unless on a touch-enabled device, use:

@media not (pointer: coarse) {
  math-field::part(virtual-keyboard-toggle) {
    display: none;
  }
}

Customizing the Layouts

The virtual keyboard panel displays multiple layouts which can be toggled using the layout switcher: numeric, symbols, alphabetic and greek.

To choose which layouts are listed in the layout switcher, use the mathVirtualKeyboard.layouts property.

For example, to only show the numeric and symbols layouts, use:

:::html
<math-field>x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}</math-field>

:::js
document.querySelector('math-field').
  addEventListener('focus', () => { 
    mathVirtualKeyboard.layouts = ["numeric", "symbols"];
    mathVirtualKeyboard.visible = true;
  });

To revert to the default layouts, use:

mathVirtualKeyboard.layouts = "default";

Different Layouts for Multiple Mathfields

There is a single instance of the virtual keyboard panel, shared by all mathfields. The layouts are shared by all mathfields as well.

To display a different set of layouts for a specific mathfield, change the mathVirtualKeyboardLayouts property of the mathfield when it is focused.

// Layout for mathfield mf1
mf1.addEventListener("focusin", () => {
  mathVirtualKeyboard.layouts = ["numeric", "symbols"];
});

// Layout for mathfield mf2
mf2.addEventListener("focusin", () => {
  mathVirtualKeyboard.layouts = ["minimalist"];
});

Additional Layouts

In addition to numeric, symbols, alphabetic and greek, the following layouts are available:

Minimalist Layout

The "minimalist" layout is focused on entry of simple expressions.

mathVirtualKeyboard.layouts = ["minimalist"];

Compact Layout

The "compact" layout is similar to "minimalist" but the keycaps include variants.

mathVirtualKeyboard.layouts = ["compact"];

Numeric Only Layout

The "numeric-only" layout is suitable for input that is purely numeric.

mathVirtualKeyboard.layouts = ["numeric-only"];

Defining Custom Layouts

In addition to the built-in layouts, you can define your own layouts.

The simplest way to define a custom layout is to set mathVirtualKeyboard.layouts to an object literal with a rows property, an array of keycaps.

For best result, you should make sure the rows have no more than 10 keycaps.


:::html
<math-field>x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}</math-field>

:::js
document.querySelector('math-field').
  addEventListener('focus', () => {
    mathVirtualKeyboard.layouts = {
      rows: [
        [
          "+", "-", "\\times", "\\frac{#@}{#?}", "=", ".",
          "(", ")", "\\sqrt{#0}", "#@^{#?}",
        ],
        ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
      ]
  };
  mathVirtualKeyboard.visible = true;
});

Each keycap is a LaTeX string which is used both as the label of the keycap, and as the content inserted when the keycap is pressed.

Placeholder Tokens

You'll notice from the example above that the LaTeX fragments defining the keycap can contain some special placeholder tokens:

Token
#@ Replaced with the selection, if there is one. If there is no selection, replaced with an implicit argument to the left of the caret. For example, for 12+34, if the caret is at the end, #@ would be replaced with 34.
#0 Replaced with the selection if there is one, a \placeholder{} command otherwise
#? Replaced with a \placeholder{} command

Keycap Shortcuts

The value of the keycap can be a LaTeX string, or one of the special values below, corresponding to a standard keycap. These shortcuts define the label, appearance, command when pressed, shifted command and variants for those keys.

"[left]" "[right]" "[return]" "[hide-keyboard]" "[shift]"

"[backspace]" "[undo]" "[redo]" "[cut]" "[copy]" "[paste]"

"[.]" "[+]" "[-]" "[/]" "[*]" "[=]"

"[(]" "[)]"

"[0]" "[1]" "[2]" "[3]" "[4]" "[5]" "[6]" "[7]" "[8]" "[9]"

"[separator]" ["hr"]

"[foreground-color]" "[background-color]"

Advanced Keycaps

For more control over the appearance and behavior of a keycap use an object literal with the following properties:

  • label: the label of the keycap, displayed using the system font. This can include some HTML markup, for example "<span><i>x</i>&thinsp;²</span>". If property is absent, the latex property is used for the label of the keycap. The label can also be one of the keycap shortcuts mentioned above, e.g. [left]. If a keycap shortcut is used, the other properties override the values defined by the shortcut.
  • latex: if no label is provided, the value of the latex property is used as the label of the keycap. This property is also used to insert content in the mathfield when the keycap is pressed.
  • key: if present, when the keycap is pressed the corresponding physical keyboard key is simulated, potentially triggering keyboard shortcuts.
  • insert: if present, a LaTeX string to be inserted when the keycap is pressed.
  • command: the command to perform when the keycap is pressed. For example: ["performWithFeedback", "commit"].
  • class: a set of CSS classes to style this keycap. The classes can be custom defined (see below about the style layer property), or be one or more of the standard ones:
    • tex: use the TeX font for its label. Using the tex class is not necessary if using the latex property to define the label.
    • ghost: the keycap with no border or background
    • small: display the label in a smaller size
    • action: an "action" keycap (for arrows, return, etc...)
    • bottom, left, right: alignment of the label
    • hide-shift: do not display the shift top-right label on the keycap if a shift property is provided.
  • width: the width of the keycap, as a multiple of a standard keycap. That is, 0.5 for half-wide keys, 1.5 for one and half wide keys, etc...
  • aside: an optional small label displayed below the keycap. This label may not be displayed if the space available is too small.
  • shift: a LaTeX string or a keycap record indicating what happens when this keycap is pressed with the SHIFT key down.
  • variants: an array of keycaps (either as string or keycap records) defining the variants for this keycap (see below).

If neither insert nor command are provided, the latex or key properties are used to define the content inserted when the keycap is pressed.

Learn more about the **available commands**

Here's an example of a basic keyboard layout:

mathVirtualKeyboard.layouts = {
  label: 'Basic',
  rows: [
    [
      '[7]', '[8]', '[9]', '[+]', 
      { label: '[separator]', width: 0.5 },
      { class: 'small', latex: '\\frac{#@}{#0}' },
      '\\varnothing', '\\infty', '\\in', '\\notin',
      '[separator]',
    ],
    [
      '[4]', '[5]', '[6]', '[-]', 
      { label: '[separator]', width: 0.5 },
      '[(]', '[)]', '\\lt', '\\le', '\\hat{=}', '[separator]',
    ],
    [
      '[1]', '[2]', '[3]', '\\cdot', 
      { label: '[separator]', width: 0.5 },
      '[', ']', '\\gt', '\\ge',

      { label: '[backspace]', width: 2 },
    ],
    [
      { label: '[0]', width: 2 }, '[.]', '\\colon', 
      { label: '[separator]', width: 0.5 },
      '\\lbrace', '\\rbrace', '=', '\\ne', '[left]', '[right]',
    ],
  ],
};

Keycap Variants

The default layouts include variants for many of their keycaps. These variants are accessed with a long press on the keycap. The variants are typically related, but less frequently used version of the main keycap.

You can define variants for a custom layout by specifying a variants property with the definition of a keycap. The value of the variants property is an array of VirtualKeyboardKeycap. As a shortcut, a string can also be used, which is equivalent to a VirtualKeyboardKeycap with a latex property equal to the string, that is, it will display the latex string as the keycap label and insert it when the key is pressed.

rows: [
  [
    { latex: "a", variants: ["A", "\\alpha", "\\Alpha"] }
    ...
  ]
]

Layer Styling

If you want to apply custom CSS classes to some keycaps, you can provide a definition for them using the style property. Note that in that case you can't use the rows shortcut, you must provide the full definition of the layers.

mathVirtualKeyboard.layouts = [
  {
    label: "minimal",
    tooltip: "Only the essential",
    layers: [
      {
        style: ".digit { background: blue; color: white }",
        rows: [
          [
            '+',
            '-',
            '\\times',
            '\\frac{#@}{#?}',
            '=',
            '.',
            '(',
            ')',
            '\\sqrt{#0}',
            '#@^{#?}',
          ],
          [
            { class: 'digit', latex: '1' },
            { class: 'digit', latex: '2' },
            { class: 'digit', latex: '3' },
            { class: 'digit', latex: '4' },
            { class: 'digit', latex: '5' },
            { class: 'digit', latex: '6' },
            { class: 'digit', latex: '7' },
            { class: 'digit', latex: '8' },
            { class: 'digit', latex: '9' },
            { class: 'digit', latex: '0' },
          ],
        ],
      },
    ],
  },
  "alphabetic",
];

Multiple Layers

Most keyboard layouts are made of a single layer. However, if your layout includes multiple layers, use the layers property to provide an array of layers.

mathVirtualKeyboard.layouts = {
  layers: [
    {
      rows: [
        [
          "+", "-", "\\times", "\\frac{#@}{#?}", "=", ".",
          "(", ")", "\\sqrt{#0}", "#@^{#?}",
        ],
      ]
    },
    {
      rows: [
        ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
      ]
    }

  ],
};

Multiple Layouts

You can also mix default layouts with your own. For example, to add the alphabetic layout after your own:

mathVirtualKeyboard.layouts = [
  {
    label: "minimal",
    tooltip: "Only the essential",
    rows: [
      [
        "+", "-", "\\times", "\\frac{#@}{#?}", "=", ".",
        "(", ")", "\\sqrt{#0}", "#@^{#?}",
      ],
      ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"],
    ]
  }, 
  "alphabetic"
];

If you include more than one layout, it's a good idea to provide a label and tooltip so they get propertly displayed in the layout switcher.

Customizing the Appearance of the Virtual Keyboard

To customize the appearance of the virtual keyboard panel set the following CSS variables on a selector that applies to the container of the virtual keyboard panel, which is the <body> element by default:

body {
  --keyboard-zindex: 3000;
}

You can also set these CSS variables programmatically:

document.body.style.setProperty("--keyboard-zindex", "3000");

Customizing the Virtual Keyboard Stack Order

To specify the stack order of the virtual keyboard relative to other DOM elements set the --keyboard-zindex CSS variable.

The default zindex of the virtual keyboard is 105.

Customizing the Virtual Keyboard Colors

To control the appearance of the virtual keyboard text and background colors, set the value of the following CSS variables to a CSS color:

  • --keyboard-accent-color

  • --keyboard-toolbar-text

  • --keyboard-toolbar-text-active

  • --keyboard-toolbar-background

  • --keyboard-toolbar-background-hover

  • --keyboard-toolbar-background-selected

  • --keycap-background

  • --keycap-background-hover

  • --keycap-background-active

  • --keycap-background-pressed

  • --keycap-border

  • --keycap-border-bottom

  • --keycap-text

  • --keycap-text-active

  • --keycap-text-hover

  • --keycap-text-pressed

  • --keycap-shift-text

  • --keycap-shift-color

  • --keycap-primary-background

  • --keycap-primary-text

  • --keycap-primary-background-hover

  • --keycap-secondary-background

  • --keycap-secondary-background-hover

  • --keycap-secondary-text

  • --keycap-secondary-border

  • --keycap-secondary-border-bottom

  • --box-placeholder-color

  • --variant-panel-background

  • --variant-keycap-text

  • --variant-keycap-text-active

  • --variant-keycap-background-active

The following CSS variables are a border shorthand value:

  • --keyboard-border
  • --keyboard-horizontal-rule

Customizing the Size of the Keyboard

By default the virtual keyboard is sized so that it can be used comfortably on touch-devices. Its size will adjust based on the available space in its container, which is the viewport by default.

However, you may want to have a more compact virtual keyboard to leave more room for the content. You can control the appearance of the virtual keyboard using some CSS variables. Set those variables in a rule that applies to the entire document, for example the body element selector.

body {
  --keycap-height: 24px;
  --keycap-font-size: 16px;
  --keycap-shift-font-size: 9px;
  --keycap-small-font-size: 9px;
  --keycap-extra-small-font-size: 9px;
  --keyboard-toolbar-font-size: 16px;
  --keycap-gap: 1px;
}

The following CSS variables can be used to adjust the layout:

  • --keycap-height

  • --keycap-max-width

  • --keycap-gap

  • --keycap-font-size

  • --keycap-shift-font-size

  • --keycap-small-font-size

  • --keycap-extra-small-font-size

  • --keycap-secondary-border-bottom

  • --keycap-secondary-border-bottom

  • --keyboard-toolbar-font-size

  • --keyboard-padding-horizontal

  • --keyboard-padding-top

  • --keyboard-padding-bottom

  • --keyboard-row-padding-left

  • --keyboard-row-padding-right

  • --variant-keycap-length

  • --variant-keycap-font-size

  • --variant-keycap-aside-font-size

Preventing Input from the Physical Keyboard

To require the virtual keyboard to be used for input and ignore keys pressed on the physical keyboard listen and preventDefault() on "keydown" events during the capture phase, and show the virtual keyboard when the mathfield is focused.

mf.addEventListener("keydown", (evt) =>  
  evt.preventDefault(), { capture: true });

mf.addEventListener("focus", () => 
  mathVirtualKeyboard.show());

Displaying the Virtual Keyboard in a Custom Container

By default the virtual keyboard is inserted at the end of the document's body element.

In some cases you may want to display the virtual keyboard in some other container.

For example when using full screen elements that contain a mathfield, you want to make sure the virtual keyboard panel is visible by attaching it to the full screen element.

To select which DOM element the virtual keyboard is attached to, set the mathVirtualKeyboard.container property to the desired DOM element.

:::warning

The container element should be at least 320px wide to ensure that the default layouts can fit. The height of the container element will be adjusted so that the virtual keyboard can fit.

:::

Reacting to the Virtual Keyboard Geometry Changes

The virtual keyboard panel is positioned relative to the container element using the position: absolute CSS property. This means that the virtual keyboard panel will not affect the layout of the container element.

However, the container element may need to adjust its layout to make room for the virtual keyboard panel. For example, if the container element is a full screen element, it may need to adjust its height to make room for the virtual keyboard panel.

To react to the geometry changes of the virtual keyboard panel, listen to the "geometrychange" event on the mathVirtualKeyboard object.

The bounding rectangle of the virtual keyboard is available in the mathVirtualKeyboard.boundingRect property.

For example, to adjust the height of the container element to make room for the virtual keyboard panel:

mathVirtualKeyboard.addEventListener("geometrychange", () => {
  container.style.height = 
    mathVirtualKeyboard.boundingRect.height + "px";
});

Customizing the Alphabetical Layout

By default the "alphabetic" layout is determined based on the locale (QWERTY for english speaking countries, AZERTY for french speaking countries, etc..).

To select a different alphabetic layout, such as DVORAK or COLEMAK, use the mathVirtualKeyboard.alphabeticLayout property.

:::js
const mf = document.querySelector('math-field');
document.querySelector('math-field').addEventListener('focus', () => {
  mathVirtualKeyboard.layouts = ["alphabetic"];
  mathVirtualKeyboard.alphabeticLayout = "dvorak";
  mathVirtualKeyboard.visible = true;
});

:::html
<math-field>
  x=\frac{-b\pm \sqrt{b^2-4ac}}{2a}
</math-field>

QWERTZ layout

QWERTZ layout, shifted

AZERTY layout

AZERTY layout, shifted

DVORAK Layout

DVORAK Layout, shifted

--- title: "Tutorial: Simple Quiz" slug: /tutorials/simple-quiz/ ---

Tutorial Simple Quiz

In this tutorial, we'll create a web-based quiz application that allows students to practice simplifying mathematical expressions into polynomials.

We'll use two powerful tools: MathLive for math input and Compute Engine for evaluating mathematical expressions.

Step 1: Setting Up Your Project

In this tutorial, we'll use HTML and JavaScript.

Let's start by setting up our HTML file.

<!doctype html>
<html>
<head>
    <title>Math Quiz</title>
</head>
<body>
    <!-- Interactive elements will be added here -->
</body>
<script type="module">
  // Import the Mathfield and Compute Engine libraries
  import "https://esm.run/mathlive";
  import "https://esm.run/@cortex-js/compute-engine";
  
  // JavaScript code will be added here

</script>
</html>

For convenience, we're loading the MathLive and ComputeEngine library from the jsdelivr CDN. You can also download the libraries and host them locally.

Since we want to use the Compute Engine, we'll need to load its library as well. We could use MathLive without the Compute Engine, but we'll need it to evaluate the student's input.

:::warning Note that the <script> tag has a type="module" attribute. This is required to use the import statement. :::

Step 2: Creating the Quiz Interface

Our quiz will have a simple interface: a question area, an input field for the answer, a submission button, and a feedback section.

<p>Simplify the expression: (x+1)(2x -1)</p>
<math-field id="answer"></math-field>
<button id="submitAnswer">Check Answer</button>
<div id="feedback"></div>

When the MathLive library is loaded, a new HTML element becomes available: <math-field>.

This element is a math input field that allows users to type math expressions.

We'll use this element to allow students to input their answers.

Let's add some CSS to make our quiz look nicer.

<style>
  math-field {
    width: 100%;
    border-radius: 8px;
    margin: 8px 0;
  }
  button {
    border-radius: 8px;
    padding: 8px;
    margin: 8px 0;
    font-size: 1em;
    font-weight: bold;
    font-family: system-ui;
  }
  p {
    font-family: system-ui;
    font-size: 1.5em;
    padding: 8px;
  }
  #feedback {
    font-family: system-ui;
    font-size: 1.2em;
    font-weight: bold;
    display: flex;
    justify-content: center;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 8px;
    background: #f0f0f0;
  }
</style>

Step 3: Processing and Checking Answers

Now, let's add functionality to process the student's input and compare it with the expected answer.

const expectedAnswer = "2x^2+x-1";

function checkAnswer() {
  const studentInput = mathfield.value;

  // Compare the expressions as strings
  const feedback = studentInput === expectedAnswer ?
     'Correct! 😃' : 'Try again. 😞';

  document.getElementById('feedback').textContent = feedback;
}

const answerButton = document.getElementById('submitAnswer');
answerButton.addEventListener('click', checkAnswer);

To read the content of the math input field, we use the value property of the <math-field> element. This property returns a LaTeX string representation of the math expression

We then compare the student's input with the expected answer. If the student's input matches the expected answer, we'll display a "Correct!" message. Otherwise, we'll display a "Try again." message.

Step 4: Using the Compute Engine

While comparing the student's input with the expected answer works, it's not very flexible. For example, if we want to accept equivalent answers, we'll have to manually check for each possible equivalent answer. This can be tedious and error-prone.

Instead, we can use the Compute Engine to evaluate the student's input and compare it with the expected answer. This way, we can accept equivalent answers without having to manually check for each one.

When the Compute Engine library is loaded in the page, the MathLive library automatically uses it to evaluate the math expressions entered in the math input field.

The Compute Engine represents mathematical expressions as a MathJSON data structure. This is a more flexible representation than LaTeX, and allows us to compare expressions in a more robust way.

To get the MathJSON representation of the student's input, we can use the expression property of the <math-field> element.

We can get a reference to the Compute Engine instance used by MathLive by accessing the computeEngine property of MathfieldElement. We can then use the parse() method to convert the expected answer into a MathJSON expression.

We'll modify our checkAnswer() function as follows:

const ce = MathfieldElement.computeEngine;
const expectedAnswer = ce.parse("2x^2+x-1");

function checkAnswer() {
  const studentInput = mathfield.expression;

  // Compare the expressions using `isSame()`
  const feedback = studentInput.isSame(expectedAnswer) ?
     'Correct! 😃' : 'Try again. 😞';

  document.getElementById('feedback').textContent = feedback;
}

The method ce.parse() returns a boxed expression from a LaTeX string. A boxed expression is a JavaScript object that represents a mathematical expression.

The Compute Engine provides many operations that can be performed on boxed expressions, including calculus, statistical operations and linear algebra.

For example, we can simplify an expression, expand it or evaluate it for a given value of x.

Using the isSame() method, we can compare the student's input with the expected answer. This method returns true if the two expressions are structurally equivalent, and false otherwise.

This method compares the two expressions not as strings, but as mathematical expressions. For example, it will consider 2x or 2\times x to be the same.

Step 5: Listening for Keyboard Events

We can make our quiz more user-friendly by allowing students to validate their answer by pressing the Enter key.

To do this, we'll add an event listener to the math input field to listen for keyboard events.

const answerField = document.getElementById('answer');
answerField.addEventListener('input', (event) => {
  if (event.data === 'insertLineBreak') checkAnswer()
});

Note that we could also use the keypress event, but the input event is will work both when using a physical keyboard and when using the virtual keyboard.

Step 6: Displaying Static Math

In our example so far, we display the question in plain text. We can display it as LaTeX instead. It doesn't make much of a difference in this case, but it can be useful when we want to display more complex math.

First, we'll modify the HTML to indicate that a portion of the question should be rendered as math by surrounding it with $$ delimiters.

<div>Simplify the expression: $$ (x+1)(2x-1) $$</div>

Then we'll call the renderMathInElement() function to render the math in the question.

renderMathInElement(document.getElementById('question'));

If we had a lot of math in our quiz, we could call renderMathInDocument() to render all the math in the page.

We also need to load a CSS stylesheet to render the math. We can use the mathlive-static.css stylesheet provided by the MathLive library.

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/mathlive/mathlive-static.css"
/>

Another way to render math is to use the convertLatexToMarkup() function.

To do this, we'll modify our markup to use a <span> element.

<p>Simplify the expression: <span id="question">(x+1)(2x-1)</span></p>

Then we'll modify our JavaScript to use this function to render the question.

const questionSpan = document.getElementById('question');
questionSpan.innerHTML = 
  convertLatexToMarkup(questionSpan.textContent);

Here we're using convertLatexToMarkup() to convert the LaTeX representation of the expression into HTML markup. It's a more direct way to render static math in the page.

Note that we need to modify our import statement to import the convertLatexToMarkup() function.

import { renderMathInElement, convertLatexToMarkup } from "https://esm.run/mathlive";

Step 7: Generating Random Questions

So far our quiz always asks the same question. To keep it interesting, we can generate random questions.

We'll create a function that generates a product of two random terms.

function generateRandomQuestion() {
  const ce = MathfieldElement.computeEngine;
  const a = Math.floor(Math.random() * 10) + 1;
  const b = Math.floor(Math.random() * 10) ;
  const c = Math.floor(Math.random() * 10) + 1;
  const d = Math.floor(Math.random() * 10) ;
  // (ax+b)(cx+d)
  return ce.box(["Multiply", 
    ["Add", ["Multiply", a, "x"], b], 
    ["Add", ["Multiply", c, "x"], d]]);
}

The ce.box() function creates a boxed expression from a MathJSON expression.

Then we'll update our script to use this function to generate the question.

const question = generateRandomQuestion();
document.getElementById('question').innerHTML = 
  convertLatexToMarkup(question.latex);
const expectedAnswer = question.simplify();

Since we expect the student to have simplified the expression, we use simplify() to simplify the product of two terms into a polynomial and compare it with the student's input.

Conclusion

Here's the complete code for our quiz application:

<!doctype html>
<html>
<head>
    <title>Math Quiz</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/mathlive/mathlive-static.css"
    />
    <style>
      math-field {
        width: 100%;
        border-radius: 8px;
        margin: 8px 0;
      }
      button {
        border-radius: 8px;
        padding: 8px;
        margin: 8px 0;
        font-size: 1em;
        font-weight: bold;
        font-family: system-ui;
      }
      p {
        font-family: system-ui;
        font-size: 1.5em;
        padding: 8px;
      }
      #feedback {
        font-family: system-ui;
        font-size: 1.2em;
        font-weight: bold;
        display: flex;
        justify-content: center;
        padding: 8px;
        border: 1px solid #ddd;
        border-radius: 8px;
        background: #f0f0f0;
      }
    </style>
</head>
<body>
    <p>Simplify the expression <span id="question"></span></p>
    <math-field id="answer"></math-field>
    <button id="submitAnswer">Check Answer</button>
    <div id="feedback"></div>
</body>
<script type="module">
  import { convertLatexToMarkup } from "https://esm.run/mathlive";
  import "https://esm.run/@cortex-js/compute-engine";
  const ce = MathfieldElement.computeEngine;
  const question = generateRandomQuestion();
  const expectedAnswer = question.simplify();

  document.getElementById('question').innerHTML = 
    convertLatexToMarkup(question.latex);
  
  const answerButton = document.getElementById('submitAnswer');
  answerButton.addEventListener('click', checkAnswer);

  const answerField = document.getElementById('answer');
  answerField.addEventListener('input', (event) => {
    if (event.data === 'insertLineBreak') checkAnswer();
  });

  function generateRandomQuestion() {
      const a = Math.floor(Math.random() * 10) + 1;
      const b = Math.floor(Math.random() * 10) ;
      const c = Math.floor(Math.random() * 10) + 1;
      const d = Math.floor(Math.random() * 10) ;
      // (ax+b)(cx+d)
      return ce.box(["Multiply", 
        ["Add", ["Multiply", a, "x"], b], 
        ["Add", ["Multiply", c, "x"], d]]);
  }

  function checkAnswer() {
    const answer = document.getElementById('answer');
    const studentInput = answer.expression;

    // Compare the expressions using `isSame()`
    const feedback = studentInput.isSame(expectedAnswer) ?
      'Correct! 😃' : 'Try again. 😞';

    document.getElementById('feedback').textContent = feedback;
  }
</script>
</html>

We've just scratched the surface of what's possible with MathLive and Compute Engine. This simple quiz application demonstrates the potential for creating interactive educational tools. Explore further to see how you can enhance and adapt this application to suit various educational needs.

date: Last Modified title: Using A Mathfield with React slug: /mathfield/guides/react/

Theory of Operations

A mathfield behaves as a regular DOM element:

  • define mathfields using the <math-field> tag in JSX
  • get a reference to the corresponding DOM element with the useRef() hook
  • customize the mathfield on mount with useEffect(..., []) hook

Using A Mathfield with React

To use a mathfield with React, import the MathLive library and use a <math-field> tag.

import "https://esm.run/mathlive";
import { useState } from "react";

export default function App() {
  const [value, setValue] = useState("");

  return (
    <div>
      <math-field 
        onInput={evt => setValue(evt.target.value)}
      >
        {value}
      </math-field>
      <p>Value: {value}</p>
    </div>
  );
}

export default App;

Using A Mathfield with React and TypeScript

To use a mathfield with React and TypeScript, you need to add TypeScript definitions for mathfield elements.

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'math-field': React.DetailedHTMLProps<React.HTMLAttributes<MathfieldElement>, MathfieldElement>;
    }
  }
}


import "https://esm.run/mathlive";
import { useState } from "react";

export default function App({children}) {
  const [value, setValue] = useState<string>("");

  return (
    <div>
      <math-field 
        onInput={
          (evt: React.ChangeEvent<HTMLElement>) => 
            setValue(evt.target.value)
        }
      >
        {children}
      </math-field>
      <p>Value: {value}</p>
    </div>
  );
}

Using LaTeX strings with JSX

To specify the initial value of the mathfield provide a LaTeX string as a child of the <math-field> tag.

However, since both JSX and LaTeX use curly braces, you need to escape the LaTeX braces. The easiest way to do this is to use a backtick string. The content of the backtick string will be interpreted as a JavaScript string, which means that the backslashes will need to be escaped as well.

<math-field>{`
  \\frac{1}{2}
`}</math-field>

Customization

To customize a mathfield, use a useRef callback.

With the current property of the ref, you can access and manipulate all the properties and methods that are specific to the mathfield (value, selection, insert(), etc...). See MathfieldElement.

import "./App.css";
import "https://esm.run/mathlive";
import { useState, useEffect, useRef } from "react";

export default function App({children}) {
  const [value, setValue] = useState("");

  return (
    <div className="App">
      <math-field 
        ref={(el) => {
          if (el === null) {
            // When el is null, the mathfield is being destroyed
            // You may want to unsubscribe from events here
            return;
          }
          // Customize the mathfield when it is created
          mf.current.mathVirtualKeyboardPolicy = "manual";
          mf.current.addEventListener("focusin", (evt) => 
            window.mathVirtualKeyboard.show()
          );
          mf.current.addEventListener("focusout", (evt) => 
            window.mathVirtualKeyboard.hide()
        }} 
        onInput={evt => setValue(evt.target.value)}
      >
        {children}
      </math-field>
      <p>Value: {value}</p>
    </div>
  );
}
A ready-to-run example project is available on **GitHub**

date: Last Modified title: LaTeX Commands slug: /mathfield/reference/commands/ toc_max_heading_level: 2

Mathfields support over **800** LaTeX commands. **To find the name of the LaTeX command matching the shape of a symbol you can draw**, use **Detexify**

To enter a LaTeX command in mathfield press the ESC key or \
to enter LaTeX editing mode. Press ESC to exit LaTeX editing mode.

To examine the LaTeX code for an expression, select it, then press ESC.

The most common symbols can be entered using **keyboard shortcuts**.

Text Zone, Math Zone and Math Style

Math Zone

When in a Math Zone, the content is laid out using typesetting rules specific to math.

For example, variables such as x are displayed in italics, an appropriate amount of space is inserted around some letters such as $ f $ to improve their legibility, and white spaces are ignored.

In a Math Zone, the layout and size of some math elements is adjusted based on the context in which they are used. For example, superscripts and subscripts are displayed using a smaller font size: $ 2^2 $.

Inside a Math Zone, the Math Style indicate the size of the font used to display the content, and some layout options, such as placement of the limits of a sum or integral.

To override the default Math Style, use the following commands:

Math Style
\displaystyle

For equations in their own paragraph/block
\displaystyle \sum_{i=0}^n \frac{a_i}{1+x} i = 0 n a i 1 + x
\textstyle

Confusingly, for inline math, not for text content
\textstyle \sum_{i=0}^n \frac{a_i}{1+x} i = 0 n a i 1 + x
\scriptstyle

For subscripts and superscripts
\scriptstyle \sum_{i=0}^n \frac{a_i}{1+x} i = 0 n a i 1 + x
\scriptscriptstyle

For subscripts and superscripts of subscripts and superscripts
\scriptscriptstyle \sum_{i=0}^n \frac{a_i}{1+x} i = 0 n a i 1 + x

Text Zone

To include some textual content, use the \text{} or \textrm{} commands to switch to a Text Zone. Inside a Text Zone, white spaces are preserved and the spacing of characters is not adjusted.

The \text{} command will use the font defined by the CSS font-family property of the enclosing mathfield. The size of the text will adjust depending on the current math style (smaller in superscript/subscript).


The \textrm{} command works like \text{} but will use a serif (roman) font.


The \mbox{} command uses the same font as \text but its size does not account for the current math style.


The \textnormal{} command works like \text{}. But it's longer to type.

When in a Text Zone, use $...$ to switch back to an Inline Math Zone or \\[...\\] to switch to a Display (block) Math Zone.

Fractions and Binomials

The \frac command is used to represent a fraction. The first argument is the numerator, the second argument is the denominator. It will size itself according to the current math style (display, text (inline), script, scriptscript). The \dfrac and \tfrac commands force the math style to be display or text (inline) style respectively.

The \cfrac (continuous fraction) command has an optional argument, [l] or [r], that controls if the numerator is left-aligned or right-aligned.

The \pdiff command is a convenient shortcut for partial differentials.


The \binom command is used to represent a binomial coefficient. The \dbinom and \tbinom commands force the math style to be display or text (inline) style respectively.

:::warning[Deprecated]

The following commands are supported but their usage is generally discouraged when creating modern LaTeX content.

:::

Binary Operators

Some binary operators can also be used as a unary operator: +, -, etc... Their spacing is adjusted accordingly. For example in \( -1-2 \) there is less space between - and 1 than there is between - and 2.




Functions

Trigonometry

Non-Standard Trig Functions

The commands in this section are not part of the standard LaTeX distribution but are available in some packages. Use them with caution as they may not be supported by all LaTeX engines. Consider using \operatorname{} instead.

Bounds

Projections

Modulo

Custom Functions

To define a custom function use the \operatorname{} command: the name of the function will be displayed in upright font and with the appropriate spacing.

Unicode

If a symbol is not available as a LaTeX command, you can use the Unicode codepoint of the character. The commands below can be used to insert a Unicode character in a mathfield.

Command
\unicode{} The argument is a Unicode codepoint expressed as a number. To use a hexadecimal number, start the argument with x or " and use uppercase A-F for hexadecimal digits.
  • The following macros are not allowed: unicode

    $$\Large\unicode{10775} $$
    \unicode{10775}
  • The following macros are not allowed: unicode

    $$\Large\unicode{"2A17}$$
    \unicode{"2A17}
  • The following macros are not allowed: unicode

    $$\Large\unicode{x2A17}$$
    \unicode{x2A17}
\char The argument is also a Unicode codepoint, but the {...} delimiters are optional when using ".
  • \char " 2 A 17 \char"2A17
^^
^^^^
Followed by 2 or 4 hexadecimal digits with lowercase a-f to specify a Unicode codepoint.
  • Missing open brace for superscript

    $$\Large^^4a $$
    ^^4a
  • Missing open brace for superscript

    $$\Large^^^^2a17 $$
    ^^^^2a17

:::info[Note] The codepoint of the Unicode character ⨗ U+2A17 INTEGRAL WITH LEFTWARDS ARROW WITH HOOK is 10775 in decimal, 2A1716 in hexadecimal. The codepoint of the letter J is 004A16 in hexadecimal. Learn more about Mathematical Operators and Symbols in Unicode on Wikipedia. :::

Large Operators

Large operators display their limits above and below or adjacent to the operator, depending on the math style (Display Style or Text Style) and on the operator.

The position of the limits can be controlled with \limits, \nolimits or \displaylimits after the operator. The \limits command forces the display of the limits above and below the operator, \nolimits forces the display of the limits adjacent to the operator, and \displaylimits uses an automatic position, based on the operator and current math style.

\limits \nolimits \displaylimits
i = 0 n i = 0 n i = 0 n \displaylimits
\sum_{i=0}^n\limits \sum_{i=0}^n\nolimits \sum_{i=0}^n\displaylimits
0 0 0 \displaylimits
\int_0^\infty\limits \int_0^\infty\nolimits \int_0^\infty\displaylimits

In Display Style, the \intop and \ointop commands display their limits above and below by default, while the \int command display its limit adjacent.


Logic

Quantifiers

Unary/Binary Operators

Relational Operators

Arrows

Negated Arrows