Previous versions: v0.2.
This page shows all MathKeyboardEngine for Python classes and functions that you can directly use. Helper functions that are not avaible from the root namespace of the library, are not mentioned. This documentation is not exhaustive. Use View declaration to see the class or function declaration and use Search occurrences for finding all occurrences in unit tests and other parts of the GitHub repository.
Before diving into this documentation:
If you type into a 'math textbox', you use a KeyboardMemory instance for that textbox. The KeyboardMemory class will hold the syntax tree of what you've typed and what the current
position is of the cursor. If you'd like to have multiple math textboxes on one page, then use multple instances of the KeyboardMemory class, each linked to a single 'textbox'.
In the LatexConfiguration class, the cursor is called the "active placeholder". You can choose the shape and color of the active placeholder ('cursor') and also of all other Placeholders that are empty but that are not the current position of your 'cursor'.
You can also choose how to highlight a selection - for example via a background color. (See select_left.)
Calling get_edit_mode_latex outputs the LaTeX for display in a 'math textbox'. It will also contain the cursor (called the "active placeholder" in LatexConfiguration).
If you use MathKeyboardEngine for a course in which the typed answers of students need to be checked, you'll probably also want to use get_view_mode_latex, which outputs the LaTeX without cursor.
A Placeholder can be empty or it can contain TreeNodes. If you type a, + and 1, then the syntax tree consists of one Placeholder (KeyboardMemory's syntax_tree_root
) and three TreeNodes:
A TreeNode can be as simple as '3', which is called a LeafNode (it has no Placeholders). A fraction has two Placeholders: the numerator and the denominator. If a TreeNode has one or multiple Placeholders, it is called a BranchingNode.
The base class for all TreeNodes that have no Placeholders. You'll probably not use this class directly in your code, unless you would like to create your own SyntaxTree-manipulating functions.
A single LeafNode - not nested in the KeyboardMemory's syntax_tree_root
:
The StandardLeafNode should be used for everything that has no Placeholder, except if it is part of a number with digits (such as 12.75, for which you should use DigitNodes and the DecimalSeparatorNode). So, use this for variables x, y, z, for arrows, and more.
Use the DigitNode for composing a number with 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (and maybe other symbols if you like to type not in base 10, but in - for example - base 12) and the DecimalSeparatorNode for its decimal separator ('.' or ',' in some cultures).
The DigitNode and DecimalSeparatorNode are treated specially by some functions. For example, insert_with_encapsulate_current treats '12.75' as a single 'thing' instead of 5 separate TreeNodes, so that if you insert a fraction after typing a number, it moves the whole number to the numerator of the fraction.
The base class for all TreeNodes that have one or multiple Placeholders. You'll probably not use this class directly in your code, unless you would like to create your own SyntaxTree-manipulating functions.
A single-placeholder BranchingNode that contains a LeafNode:
A multi-placeholder BranchingNode of which the first Placeholder contains two LeafNodes and the second Placeholder is empty:
A single-placeholder BranchingNode that contains two LeafNodes and one multi-placeholder BranchingNode:
The StandardBranchingNode is a BranchingNode with one or multiple Placeholders. The number of Placeholders that is created, depends on the number of constructor arguments as follows:
number of placeholders = number of constructor arguments - 1
Use StandardBranchingNode for all single-placeholder BranchingNodes, except for a pair of round brackets (then use the RoundBracketsNode).
Examples:
StandardBranchingNode(r'\sqrt{', '}')
StandardBranchingNode('', '^2')
The AscendingBranchingNode and DescendingBranchingNode both extend the StandardBranchingNode, but also have ready-to-use up/down navigation.
When "reading" a power from left to right, you first read its base and then its exponent, which is slightly higher. So, you're reading from left to right and "upwards" or in an "ascending" manner. The AscendingBranchingNode provides ready-to-use up/down navigation, where move_right is equal to move_up (unless your cursor is in the last Placeholder).
For fractions, subscripts, etc. that are read "downwards", the DescendingBranchingNode provides ready-to-use up/down navigation.
Examples:
AscendingBranchingNode('', '^{', '}')
DescendingBranchingNode(r'\frac{', '}{', '}')
Instead of using two StandardLeafNodes or one single-placeholder StandardBranchingNode for two brackets, you probably want to use the RoundBracketsNode, because some functions treat it specially.
Especially when typing with the physical keyboard, the need for special treatment arises: when typing ( 1 + x ) / x you probably want \frac{1+x}{x}
as output - so, without brackets.
A trick to do this, is: let pressing ( result in inserting the RoundBracketsNode, let pressing ) result in a move_right and let pressing / result in insert_with_encapsulate_current (with the argument delete_outer_round_brackets_if_any = True
) for a fraction node (as DescendingBranchingNode).
The MatrixNode has ready-to-use left/right/up/down navigation.
The first constructor argument is the type of matrix, for example "pmatrix" for a matrix with round brackets on the left and right. Search the documentation of your typesetting library (for example KaTeX or MathJax) for other matrix types.
Whether you're using MathKeyboardEngine with virtual keys, physical keys or both, you'll need to add nodes to a KeyboardMemory instance via one of the four insert functions.
You could use only this function and skip the other insert functions, but users "expect" certain behaviour - for example at "2 to the power of 10":
not:
but:insert(k, AscendingBranchingNode('', '^{', '}'))
insert(k, DigitNode('2'))
move_right(k)
insert(k, DigitNode('1'))
insert(k, DigitNode('0'))
Both result in the (view_mode_)latexinsert(k, DigitNode('2'))
insert_with_encapsulate_current(k, AscendingBranchingNode('', '^{', '}'))
insert(k, DigitNode('1'))
insert(k, DigitNode('0'))
2^{10}
.
See the explanation at insert.
Let's say you've typed 1 + x and you then* decide that this should become the numerator of a fraction. In that case, you can use select_left and call insert_with_encapsulate_selection to insert a "fraction node".
*There are multiple ways to do this more efficiently.
Let's say you wanted to type "2 to the power of 10", but you type "210". Now you can (enter "selection mode" and) use select_left twice, followed by insert_with_encapsulate_selection_and_previous to get what you intended to get.
Deletes a node on the left of the cursor, like the Backspace key on most physical keyboards - on Mac Delete.
This function has special behaviour (depending on the position of the cursor) for BranchingNodes.
Deletes a node on the right of the cursor, like the Delete key on most physical keyboards - on Mac fn in tandem with Delete.
This function has special behaviour (depending on the position of the cursor) for BranchingNodes.
To be used together with - for example - select_left. Very probably, users will use delete_left multiple times instead. But if you're in selection and the delete key is pressed, this function provides the expected behaviour.
Moves the cursor to the left.
Moves the cursor to the right.
The MatrixNode, AscendingBranchingNode and DescendingBranchingNode implement BranchingNode's get_move_down_suggestion
and therefore support moving the cursor down. You can also extend the BranchingNode class to support other up/down-navigation patterns.
The MatrixNode, AscendingBranchingNode and DescendingBranchingNode implement BranchingNode's get_move_up_suggestion
, and therefore support moving the cursor up. You can also extend the BranchingNode class to support other up/down-navigation patterns.
Several functions to be used together with - for example - insert_with_encapsulate_selection, insert_with_encapsulate_selection_and_previous or delete_selection.
Of course you can decide not to use any of the "Selection" functions if you don't need the functionality.
Do or undo a (highlighted) selection of parts of what you've typed. Set your preferred highlighting color in the LatexConfiguration.
Do or undo a (highlighted) selection of parts of what you've typed. Set your preferred highlighting color in the LatexConfiguration.
To make your virtual math keyboard culture-independent, you may want to have a "enter selection mode" key that has no text, but has the same background color as the highlighting color as configured via the LatexConfiguration's selection_hightlight_start
and selection_hightlight_end
.
Note that the command for coloring may differ per typesetting library - for example KaTeX uses a colorbox
and MathJax uses a bbox
.
Forgetting to call leave_selection_mode may lead to weird behaviour... for example at inserting a TreeNode while still being in selection mode.
Depending on the type of application you're building, you may want to parse a LaTeX string. For example:
For adding the result to an existing KeyboardMemory instance, use something like
parsed_nodes = parsed_keyboardmemory.syntax_tree_root.nodes
insert(keyboardmemory, parsed_nodes)
A few notes about non-configurable behaviour:
x^2
, then a StandardLeafNode('^')
is inserted for the ^
symbol. If the input is x^{2}
, then an AscendingBranchingNode('', '^{', '}')
is inserted. Analogous for a_1
and a_{1}
.
\text{}
command and its contents can be parsed, but for editing its content, a few tricks are probably needed. For example: how to add a space? You could add a space via a StandardLeafNode(' ')
.
\command_{}^{}
is inserted as a StandardLeafNode(r'\command')
followed by a AscendingBranchingNode('_{', '}^{', '}')
, so that editing the \command
(e.g. \int
, \sum
, etc) is possible without losing the (sub/super)scripts.
You can use the default settings and call the parser without LatexParserConfiguration like this:
keyboardmemory = parse_latex(latex_string)
For most use cases this is probably enough, because:
.
and {,}
are understood as DecimalSeparatorNodes,\command[]{}
and \command{}{}
as DescendingBranchingNodes,\command{}
are interpreted as StandardBranchingNodes with one Placeholder,\begin{pmatrix}
and \begin{rcases}
are interpreted as MatrixNodes,A few notes about configurable behaviour:
(
, )
, \left(
and \right)
are inserted as StandardLeafNodes or as a RoundBracketsNode depending on the setting prefer_roundbracketsnode
. By default, prefer_roundbracketsnode = True
.
additionalDigits
if you're parsing a LaTeX string that contains digits that are not 0, 1, ..., 9 (for example for working with base 12) to make sure that those other digits are parsed as DigitNodes. (Unless you don't mind that those other digits are inserted as StandardLeafNodes.)
preferred_decimal_separator
if you want to change the LaTeX output of the parsed DecimalSeparatorNodes.
.
and {,}
are parsed as DecimalSeparatorNode, because ,
should probably not be interpreted as a decimal separator. However, you're free to assign a different value to decimalSeparatorMatchers
.
Note that this setting is only about interpreting the input - for telling the parser which symbols should be a DecimalSeparatorNode and which should be a StandardLeafNode - not for configuring the output.
You could for example set it to [ '.', ',', '{,}' ]
while using no preferred_decimal_separator
.