mathlive
Advanced tools
Changelog
0.60.1 2021-04-13
vite
bundler, the library location could not be determined
correctly. As a result, the assets (fonts and sounds) could not be loaded when
in their default location.\enclose{roundedbox}
and other variants.setOptions()
avoid changing the selection unless
necessary (react-mathlive issue #4).Changelog
0.60.0 2021-04-12
Renamed getCaretPosition()
and setCaretPosition()
to get/set caretPoint
.
"Position" refers to where the caret/insertion point is, as an offset inside the expression. These methods return client screen coordinates and the new name better reflect the correct terminology.
Removed deprecated (April 2019) method enterCommandMode()
Replaced ignoreSpacebarInMathMode
option with mathModeSpace
. The
ignoreSpacebarInMathMode
was accidentally not working (#859). However,
the boolean form is problematic as an element attribute (it defaults to true,
but element attributes default to false). It has been replaced with
mathModeSpace
which is more flexible (you can specify which space to use)
and doesn't have the issue of the default boolean value.
Support for iframes. Multiple mathfields in a single document but in different iframes can now share a single virtual keyboard. In the main document, use:
makeSharedVirtualKeyboard({
virtualKeyboardLayout: 'dvorak',
});
And in the iframes, use the use-shared-virtual-keyboard
attribute:
<math-field use-shared-virtual-keyboard></math-field>
See examples/iframe
for more info.
Contribution by https://github.com/alexprey. Thanks!
#555 Support for IME (Input Method Engines) for Japanese, Chinese, Korean and other complex scripts.
applyStyle()
has now more options. Previously it always toggled the style of
the selection. Now it can either toggle or set the style, and modify the
selection or a specific range.
#387 find()
method to search the fragments of an expression that match a
LaTeX string or regular expression.
For example the following code snippet will add a yellow background to the fractions in the expression:
mf.find(/^\\frac{[^}]*}{[^}]*}\$/).forEach((x) => {
mf.applyStyle({ backgroundColor: 'yellow' }, x, {
suppressChangeNotifications: true,
});
});
#387 replace()
method to replace fragments of an expression.
This method is similar to the replace()
method of the String
class. The
search pattern can be specified using a string or regular expression, and the
replacement pattern can be a string or a function. If using a regular
expression, it can contain capture groups, and those can be references in the
replacement pattern.
The following snippet will invert fractions in a formula:
mf.replace(/^\\frac{([^}]*)}{([^}]*)}$/, '\\frac{$2}{$1}');
New LaTeX Mode
This mode replaces the previous Command Mode. While the Command Mode (triggered by pressing the \ or ESC key) was only intended to insert a single LaTeX command (e.g. "\aleph"), the LaTeX Mode is a more comprehensive LaTeX editing mode.
To enter the LaTeX Mode, press the ESC key or the \ key. While in this mode, a complex LaTeX expression can be edited. Press the ESC or Return key to return to regular editing mode.
To quickly peek at the LaTeX code of an expression, select it, then press ESC. Press ESC again to return to the regular editing mode.
To insert a command, press the \ key, followed by the command name. Press the TAB key to accept a suggestion, then the RETURN key to return to regular editing mode (previously pressing the TAB key would have exited the command mode).
Added soundsDirectory
option to customize the location of the sound files,
similarly to fontsDirectory
.
Enabled audio feedback by default.
#707 added support for \begin{rcases}\end{rcases}
(reverse cases
, with
brace trailing instead of leading)
#730 added new CSS variables to control the height of the virtual keyboard:
--keycap-height
--keycap-font-size
--keycap-small-font-size
(only if needed)--keycap-extra-small-font-size
(only if needed)--keycap-tt-font-size
(only if needed)#732 Support for Dvorak keyboard layout
Synchronize the virtual keyboard layout (QWERTY, AZERTY, etc...) with the physical keyboard layout.
Added \htmlData
command, which takes as argument a comma-delimited string of
key/value pairs, e.g. \htmlData{foo=green,bar=blue}
. A corresponding
data-foo
and data-bar
DOM attribute is generated to the rendered DOM.
read-only
mode, it was still possible to
delete a portion of it by pressing the backspace key.typedText
selector dropped its options argument. As a result, the sound
feedback from the virtual keyboard only played for some keys.<math-field>
element the command popover did not
display correctly.plain/text
item.alt+e
, and they are properly
displayed as a composition (side effect of the fix for #555).Complete rewrite of selection handling.
This is mostly an internal change, but it will offer some benefits for new capabilities in the public API as well.
Warning: This is a very disruptive change, and there might be some edge cases that will need to be cleaned up.
The position of the insertion point is no longer represented by a path. It is now an offset from the start of the expression, with each possible insertion point position being assigned a sequential value.
The selection is no longer represented with a path and a sibling-relative offset. It is now a range, i.e. a start and end offset. More precisely, the selection is an array of ranges (to represent discontinuous selections, for example a column in a matrix) and a direction.
These changes have these benefits:
onDelete
function now regroups all the
special handling when pressing the Backspace and Delete keys.find()
method
which returns its results as an array of ranges. It is also possible now to
query and change the current selection, and to apply styling to a portion of
the expression other than the selection.On a historical note, the reason for the original implementation with paths
was based on the TeX implementation: when rendering a tree of atoms (which TeX
calls nodes), the TeX layout algorithm never needs to find the parent of an
atom. The MathLive rendering engine was implemented in the same way. However,
for interactive editing, being able to locate the parent of an atom is
frequently necessary. The paths were a mechanism to maintain a separate data
structure from the one needed by the rendering engine. However, they were a
complex and clumsy mechanism. Now, a parent
property has been introduced in
instance of Atom
, even though it is not necessary for the rendering phase.
It does make the handling of the interactive manipulation of the formula much
easier, though.
Changes to the handling of sentinel atoms (type "first"
)
This is an internal change that does not affect the public API.
Sentinel atoms are atoms of type "first"
that are inserted as the first
element in atom branches. Their purpose is to simplify the handling of "empty"
lists, for example an empty numerator or superscript.
Previously, these atoms where added when an editable atom tree was created,
i.e. in the editor
code branch, since they are not needed for pure
rendering. However, this created situations where the tree had to be
'corrected' by inserting missing "first"
. This code was complex and resulted
in some unexpected operations having the side effect of modifying the tree.
The "first"
atoms are now created during parsing and are present in editable
and non-editable atom trees.
Refactoring of Atom classes
This is an internal change that does not affect the public API.
Each 'kind' of atom (fraction, extensible symbol, boxed expression, etc...) is
now represented by a separate class extending the Atom
base class (for
example GenfracAtom
). Each of those classes have a render()
method that
generates a set of DOM virtual nodes representing the Atom and a serialize()
method which generates a LaTeX string representing the atom.
Previously the handling of the different kind of atoms was done procedurally and all over the code base. The core code is now much smaller and easier to read, while the specialized code specific to each kind of atom is grouped in their respective classes.
Unit testing using Jest snapshot
Rewrote the unit tests to use Jest snapshots for more comprehensive validation.
Changelog
0.59.0 2020-11-04
Changelog
0.58.0 2020-10-11
#225 Added onCommit
listener to mf.options
. This listener is invoked
when the user presses Enter or Return key, or when the field loses
focus and its value has changed since it acquired it. In addition, a change
event is triggered when using a MathfieldElement
. The event previously named
change
has been renamed to input
. This mimics the behavior of <input>
and <textarea>
elements.
#225 Changed the keyboard shortcuts to add columns and rows:
| Shortcut | Command |
| :-------------------------------------------------- | :---------------- |
| ctrl/cmd + Return/Enter | addRowAfter
|
| ctrl/cmd + shift + Return/Enter | addRowBefore
|
| ctrl/cmd + ; | addRowAfter
|
| ctrl/cmd + shift + ; | addRowBefore
|
| ctrl/cmd + , | addColumnAfter
|
| ctrl/cmd + shift + , | addColumnBefore
|
Note that Enter/Return no longer create a matrix/vector when inside a parenthesized expression. Use ctrl/cmd + Return/Enter instead.
Added a commit
command to programmatically trigger the onCommit
listener
change
event.
Added mount
and unmount
events to MathfieldElement
The $text()
method, which is deprecated, was accidentally prematurely
removed. It has been added back.
x=sin
→ x\sin
instead of x=\sin
\xrightarrow
were incorrectly treated
as if they had an invisible boundary, resulting in the cursor being positioned
incorrectly when navigating with the keyboard.Changelog
0.57.0 2020-10-09
This release introduce two major new features which will require code changes. For now, the older API remains supported but it will be dropped in an upcoming release.
Support for MathfieldElement
custom element/web component and <math-field>
tag.
The makeMathField()
function is still supported, but it will be removed in an
upcoming version. You should transition to using <math-field>
or
MathfieldElement
instead.
This transition require the following changes:
MathfieldElement
or declaratively// Before
let mf = MathLive.makeMathField(document.createElement('div'), {
virtualKeyboardMode: 'manual',
});
mf.$latex('f(x) = \\sin x');
document.body.appendChild(mf.$el());
// After
let mfe = new MathfieldElement({
virtualKeyboardMode: 'manual',
});
mfe.value = 'f(x) = \\sin x';
document.body.appendChild(mfe);
or:
<math-field virtual-keyboard-mode="manual">f(x) = \sin x</math-field>
// Before
mf.setConfig({ onContentDidChange: (mf) => {
console.log(mf.$latex())
});
// After
mfe.addEventListener('input', (ev) => {
console.log(mfe.value);
});
Support for web component is an opportunity to revisit the MathLive public API and modernize it.
The goals are:
$latex()
can be used to read or change the content
of the mathfield.$selectedText()
can return the value of the
selection, but there is no way to inspect (or save/restore) the selection.getConfig()
is called getOptions()
in most Javascript text editor
libraries.Mathfield methods
The following Mathfield
methods have been renamed as indicated:
| Before | After |
| :--------------------------- | :------------------------------------- |
| $setConfig()
| setOptions()
|
| getConfig()
| getOptions()
and getOption()
|
| $text()
| getValue()
|
| $latex()
| value
, getValue()
and setValue()
|
| $insert()
| insert()
|
| $hasFocus()
| hasFocus()
|
| $focus()
| focus()
|
| $blur()
| blur()
|
| $selectedText()
| mf.getValue(mf.selection)
|
| $selectionIsCollapsed()
| mf.selection[0].collapsed
|
| $selectionDepth()
| mf.selection[0].depth
|
| $selectionAtStart()
| mf.position === 0
|
| $selectionAtEnd()
| mf.position === mf.lastPosition
|
| $select()
| select()
|
| $clearSelection()
| executeCommand('delete-backward')
|
| $keystroke()
| executeCommand()
|
| $typedText()
| executeCommand('typed-text')
|
| $perform()
| executeCommand()
|
| $revertToOriginalContent()
| n/a |
| $el()
| n/a |
| n/a | selection
|
| n/a | position
|
The methods indicated with "n/a" in the After column have been dropped.
Only the new methods are available on MathfieldElement
(i.e. when using web
components). The Mathfield
class retains both the old methods and the new ones
to facilitate the transition, but the old ones will be dropped in an upcoming
version.
There is also a new selection
property on Mathfield
and MathfieldElement
which can be used to inspect and change the selection and a position
property
to inspect and change the insertion point (caret).
The getValue()
method also now take an (optional) Range
, which is the type
of the selection
property, to extract a fragment of the expression.
Default Exports
While default exports have the benefits of expediency, particularly when converting an existing code base to ES Modules, they are problematic for effective tree shaking. Therefore the default export will be eliminated.
This means that instead of:
import MathLive from 'mathlive';
MathLive.renderMathInDocument();
you will need to use:
import { renderMathInDocument } from 'mathlive';
renderMathInDocument();
The following functions have been renamed:
| Before | After |
| :-------------------------------- | :------------------------------ |
| MathLive.latexToAST()
| Use MathJSON |
| MathLive.latexToMarkup()
| convertLatexToMarkup()
|
| MathLive.latexToMathML()
| convertLatexToMathMl()
|
| MathLive.latexToSpeakableText()
| convertLatexToSpeakableText(
) |
getCaretPosition()
and setCaretPosition()
Selector
has been improvedgetOptions()
(getConfig()
) are more accurate\enclose
is emptyupward
and downward
hooks when navigating out of the
mathfield (now also sent as a focus-out
event)tabIndex
was set to
0 on the mathfield and some area of the mathfield were clicked on. The issue
was that with tabIndex="0"
the mathfield frame would be focusable and when
that happened the focus would correctly switch to the invisible <textarea>
element which is normally focused to receive keyboard events, but this
generated an incorrect blur
event (for the container losing focus) and an
incorrect focus
event (for the <textarea>
gaining focus)config.strings
property did not reflect the state of the localization
strings@stefnotch
for contributing several of the improvements in this
releaseChangelog
0.56.0 2020-08-22
\phantom
, \vphantom
, \hphantom
and \smash[]
\ce
and
\pu
, to display chemical equationsChangelog
0.55.0 2020-08-17
WebPack issues workaround and font loading configuration
Follow up to #508. The fonts can now be loaded either statically or dynamically.
dynamic loading by default, the fonts will get loaded programmatically
when they are needed and the rendering will be deferred until the fonts are
available to avoid unnecessary redrawing. Use this technique if you have a
simple build/bundle workflow. You can still customize the relative path to
the fonts folder using the fontsDirectory
configuration option.
static loading include the mathlive-fonts.css
stylesheet in your page.
The loading of this file will trigget the font to be loaded asynchronously
by the browser. Use this technique if you are using WebPack or have a
build/bundle workflow that renames the font files or in general require the
bundler to know about the required assets.
New packaging options. The distribution files have been split between
minified and non-minified version. In the more common cases, the minified
version (mathlive.min.js
and mathlive.min.mjs
should be used). The
non-minified version (mathlive.js
and mathlive.mjs
can be used to help in
debugging issues or to apply patches).
The fonts failed to load when loading MathLive using a <script>
tag and a
CDN. The fonts folder is now resolved correctly with the following
configurations:
- `<script>` tag and CDN
- `<script>` tag and local file
- `import` and CDN
- `import` and local file
Changelog
0.54.0 2020-06-24
#490 Firefox does not load fonts There is a bug in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1252821) where the status of fonts is reported incorrectly.
Implemented a workaround by always loading fonts in Firefox.
#506 Chrome was outputing a harmless warning about passive event listeners. The warning has been silenced.
#505 Chrome was outputing a harmless warning about passive event listeners. The warning has been silenced with extreme prejudice.
#503 Dynamic styles were not applied inside of shadow DOM
Changelog
0.53.3 2020-06-24
#504 "Spacing is inconsistent after editing"
The spacing of operators should be adjusted depending on what's around them: there is less space after a "-" sign when used as an infix operator than there is around a "-" sign used as a prefix operator (i.e. "-4" vs "3-4").
The code that was handling this was accounting for it by modifying the type of the element. This worked well enough for static rendering, but for dynamic rendering (i.e. editing), once modified the previous type of the element was lost and could not be restored (i.e. after deleting the atom in front of a "-" sign, the "-" was no longer a binary operator but a regular symbol).
This is now handled during layout without modifying the type of the element.
Workaround for a Safari bug where in some cases the caret would not blink.
#505 More consistent spacing between elements. Previously some Unicode math spacing characters were used. However, these characters are not rendered consistently. Switched to using CSS margins instead.
The LaTeX generated for a \left
command with another command as a fence was
lacking a space, e.g. \left\lbracka\right\rbrack
instead of
\left\lbrack a\right\rbrack
Smart fence for square brackets was not working correctly.
Fixed smartmode to avoid converting a decimal point to text when entering, e.g. "314.1576"
The alt/option+V shortcut now correctly inserts a placeholder in the square root
The "\arcos" function was incorrectly spelled "\arccos".
#508 In order to better support some deployment configurations, added a 'mathlive-fonts.css' file to the distribution package.
This is intended to be used by build/bundle environments that have an asset pipeline that can move/rename assets, including the font-files
Note that this method is not recommended. It will result in some cases where the layout is incorrect until the page is reloaded (especially for formulas using large symbols such as integrals or large parentheses).
To use it, add the following to the web pages using MathLive:
<link rel="stylesheet" href="dist/mathlive-fonts.css" />