Documentation (C#)

Previous versions: v0.2.

This page shows all MathKeyboardEngine for C# classes and methods that you can directly use. Helper methods that are not exposed by the library, are not mentioned. This documentation is not exhaustive. Use View declaration to see the class or method declaration and use Search occurrences for finding all occurrences in unit tests and other parts of the GitHub repository.

Before diving into this documentation:

1. Basics

KeyboardMemory

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'.

LatexConfiguration

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 SelectLeft.)

GetEditModeLatex and GetViewModeLatex

Calling GetEditModeLatex 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 GetViewModeLatex, which outputs the LaTeX without cursor.

2. Syntax tree components

Placeholder

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 SyntaxTreeRoot) and three TreeNodes:

a
+
1

TreeNode

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.

LeafNode

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 methods.

A single LeafNode - not nested in the KeyboardMemory's SyntaxTreeRoot:

y

StandardLeafNode

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.

DigitNode and DecimalSeparatorNode

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 methods. For example, InsertWithEncapsulateCurrent 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.

BranchingNode

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 methods.

A single-placeholder BranchingNode that contains a LeafNode:

\sqrt{
2
}

A multi-placeholder BranchingNode of which the first Placeholder contains two LeafNodes and the second Placeholder is empty:

\frac{
2
x
}{
}

A single-placeholder BranchingNode that contains two LeafNodes and one multi-placeholder BranchingNode:

\sqrt{
1
+
\frac{
}{
}
}

StandardBranchingNode

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:

Note: the StandardBranchingNode does not have pre-configured up/down navigation, so for most multi-placeholder BranchingNodes, you'd probably want to use AscendingBranchingNode or DescendingBranchingNode.

AscendingBranchingNode and DescendingBranchingNode

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 MoveRight is equal to MoveUp (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:

RoundBracketsNode

Instead of using two StandardLeafNodes or one single-placeholder StandardBranchingNode for two brackets, you probably want to use the RoundBracketsNode, because some methods 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 MoveRight and let pressing / result in InsertWithEncapsulateCurrent (with Options.DeleteOuterRoundBracketsIfAny) for a fraction node (as DescendingBranchingNode).

MatrixNode

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.

3. Adding to KeyboardMemory

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 methods.

Insert

You could use only this method and skip the other insert methods, but users "expect" certain behaviour - for example at "2 to the power of 10":
not:

        Insert(new AscendingBranchingNode("", "^{", "}"));
        Insert(new DigitNode("2"));
        MoveRight(k);
        Insert(new DigitNode("1"));
        Insert(new DigitNode("0"));
    
but:
        Insert(new DigitNode("2"));
        InsertWithEncapsulateCurrent(new AscendingBranchingNode("", "^{", "}"));
        Insert(new DigitNode("1"));
        Insert(new DigitNode("0"));
    
Both result in the (ViewMode)LaTeX 2^{10}.

InsertWithEncapsulateCurrent

See the explanation at Insert.

InsertWithEncapsulateSelection

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 SelectLeft and call InsertWithEncapsulateSelection to insert a "fraction node".

*There are multiple ways to do this more efficiently.

InsertWithEncapsulateSelectionAndPrevious

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 SelectLeft twice, followed by InsertWithEncapsulateSelectionAndPrevious to get what you intended to get.

4. Deleting from KeyboardMemory

DeleteLeft

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.

DeleteRight

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.

DeleteSelection

To be used together with - for example - SelectLeft. Very probably, users will use DeleteLeft multiple times instead. But if you're in selection and the delete key is pressed, this method provides the expected behaviour.

5. Navigation

MoveLeft

Moves the cursor to the left.

MoveRight

Moves the cursor to the right.

MoveDown

The MatrixNode, AscendingBranchingNode and DescendingBranchingNode implement BranchingNode's GetMoveDownSuggestion and therefore support moving the cursor down. You can also extend the BranchingNode class to support other up/down-navigation patterns.

MoveUp

The MatrixNode, AscendingBranchingNode and DescendingBranchingNode implement BranchingNode's GetMoveUpSuggestion, and therefore support moving the cursor up. You can also extend the BranchingNode class to support other up/down-navigation patterns.

6. Selection mode

Several methods to be used together with - for example - InsertWithEncapsulateSelection, InsertWithEncapsulateSelectionAndPrevious or DeleteSelection.
Of course you can decide not to use any of the "Selection" methods if you don't need the functionality.

SelectLeft

Do or undo a (highlighted) selection of parts of what you've typed. Set your preferred highlighting color in the LatexConfiguration.

SelectRight

Do or undo a (highlighted) selection of parts of what you've typed. Set your preferred highlighting color in the LatexConfiguration.

EnterSelectionMode

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 SelectionHightlightStart and SelectionHightlightEnd.
Note that the KaTeX example uses a colorbox and the MathJax example uses a bbox.

LeaveSelectionMode

Forgetting to call LeaveSelectionMode may lead to weird behaviour... for example at inserting a new TreeNode while still being in selection mode.

InSelectionMode

7. Parsing a LaTeX string

Depending on the type of application you're building, you may want to parse a LaTeX string. For example:

The method Parse.Latex returns a KeyboardMemory instance that contains the syntax tree of parsed LaTeX.

For adding the result to an existing KeyboardMemory instance, use something like

    var parsedNodes = parsedKeyboardMemory.SyntaxTreeRoot.Nodes;
    keyboardMemory.Insert(parsedNodes);
        

Parse.Latex

A few notes about non-configurable behaviour:

LatexParserConfiguration

You can use the default settings and call the parser without LatexParserConfiguration like this:

    var keyboardMemory = Parse.Latex(latexString);
        
For most use cases this is probably enough, because:

A few notes about configurable behaviour:




































If you've found an error on this page, please report it or open a pull request.