MathCAT: Math Capable Assistive Technology
Information for AT and Other Library Users
When calling from python, the general ordering is:
- The location of the MathCAT
Rulesdirectory is set [SetRulesDir]
- Whatever preferences the AT needs to set, it is done with calls to [
SetPreference]. Typically the
Languageand TTS engine to use (if any – strongly recommended) are given.
- The MathML is sent over via [
- AT calls to get the speech [
GetSpokenText] and calls [
GetBraille] to get the (Unicode) braille. If the id of a node is given, then the corresponding braille cells will be highlighted.
Navigation can be done via calls to either:
DoNavigateKeyPress] (takes key events as input)
DoNavigateCommand] (takes the commands the key events internally map to)
Both return a string to speak.
To highlight the current navigation node, ‘id’s are used. If they weren’t already present,
SetMathML] returns a string representing MathML that contains ‘id’s for any node that doesn’t already
have an ‘id’ set. You can get the current node with
GetNavigationMathML] – returns a string representing the MathML for the selected node
Note: a second integer is returned by both of these calls. This number is the offset in characters for a leaf node. This is needed when navigating by character for multi-symbol leaf nodes such as “sin” and “1234”. Currently the value is always ‘0’ – this feature needs more implementation work.
It is also possible to find out what preferences are currently set by calling [
All functions return a potential error code.
MathCAT is written in Rust, so all you need to do is build MathCAT and in your project’s Cargo.toml file add something like
[dependencies.MathCAT] mathcat = 0.2.0 # check for what the latest version is and use that
The exact function signatures are (with comments):
You can build your own Python interface, or use the one that is built with the related project MathCATForPython. This uses the Rust package pyo3.
The Python interface is basically the same as the Rust interface. The Python interface uses CamelCase rather than Rust’s snake_case. For example,
SetRulesDir in the Python interface. When calling a function, it should be wrapped in
try: ... except Exception as e: ... # log the error 'e'
I built a web assembly version. Has a few compromises and requires some hand tweaks during the build process. Those need to be automated. It can be found at MathCatDemo. This builds a web page for demo purposes, so it is not a pure build for the Web. Nonetheless, it does demonstrate how that can be done.
There is a C/C++ interface. It can be found at the related project MathCatForC. Rust and C have separate memory managers, and so the interface is a little clunky because the memory needs to be free’d. That can be hidden by wrapping the calls in a small function as demonstrated by
SetMathCatPreference in the sample code. Otherwise, it is easy to use. If someone knows a better way to deal with the memory issues, please let me know or submit a PR. This is new territory for me as a Rust programmer.