The MICD API allows editor content to be converted to and from a semantic object. This structure expresses the document as a heavily annotated JavaScript object that can be serialized via JSON. Leveraging our patented technology, semantic objects capture both the mathematical meaning and written structure of the content as expressed by the document author in a form that is accessible, familiar, and convenient for developers. Semantic objects are an ideal substrate for implementing advanced transformation, conversion, and computation tasks. Working with them is similar to working with a Walker or VisitorFunction, but with additional benefits:
An editor's document content can be exported to a semantic object by calling Editor.toSemanticObject. The result is comparable to a graph of walker nodes, except for minor structural changes related to further abstraction, and semantic objects expressing child fields with arrays instead of the Field interface.
Semantic objects can be constructed by developers and imported into an editor by passing them to Editor.fromSemanticObject. This replaces the editor content with the semantic object, returning an array of any errors encountered while importing. While exported objects are strictly standardized, the API is extremely flexible with regard to imported objects.
Many properties of a semantic object are informational annotations that are not required to recreate the original content. These can be safely elided from objects generated for import. The following properties are significant and are generally required to import an object if they would be present in an exported semantic object of the desired type:
type
This is the primary way that objects are identified. Where other properties of an object conflict with the value of this property, this property is given precedence. For example, an object with type "plus"
will be converted to a standard addition object regardless of the value of the symbol
property.
fields
For objects that have fields, this property must be present if the object's children are to be included. The fields are listed in the same order as they would be completed in the editor. Missing fields will be left empty, while excess fields will be ignored. If an object has only one field, you may instead use the property name field
and leave off the outer array. (If both properties are present, fields
takes precedence.)
size
For objects with a variable rectangular shape, such as matrices, this field must be present to describe the dimensions used to interpret the fields
property. The fields of such objects are listed in row-major order. This property is also used to describe the dimensions of certain objects, such as worksheet graphics.
symbol
This property is part of numbers, operators, variables, and identifiers. For numbers, it is the digit string that describes the number value (such as "3.14"
). For variables and identifiers, it is the variable or identifier name (such as "y"
). For operators, it is the mathematical symbol that represents the operation (such as "+"
). It is not a significant property for most operators (see notes below).
symbolAbove
This is a rare property of some operators that have an additional symbol stacked above the primary symbol. An example is the chemistry operator "yields with heat". Where a Unicode code point exists that already combines the symbols in question, it should be used as the symbol and this property left undefined.
accent
For variables, this property indicates the type of accent applied to the variable, if any. It is optional if the variable has no accent.
dataType
For variables and identifiers, this property indicates the data type of the object, that is, the type of information that the symbol is standing in for. If not specified, the scalar type is used.
placement
For operators, this property can be used to give the operator symbol an operator placement other than the default. It is not significant if the operator is specified by type
(see notes below).
text
For text annotations, this property's value is the text content of the node.
red
, green
blue
, opacity
For styles that affect colour, these properties describe the desired colour.
scale
For style that affect size, this property describes the target size.
Primitive values in a field array will be coerced into semantic objects as follows:
"booleanTrue"
or "booleanFalse"
;"number"
with a symbol equivalent to the number's value;For example, the field ["x", "plus", 1, "=", "y"]
would be imported as x + 1 = y.
Exported objects always begin from a "documentRoot"
object with a list of fields, where each field describes one line. When importing, if the imported object is an array, a document root will be synthesized as follows:
fields
value of a document root);If a primitive value is imported, it will be coerced into a semantic object as described above and a document root will be synthesized that results in a document of a single line containing only the coerced object.
When importing a number, the symbol
property holds the value of the number, such as "3.14"
. The number will be inserted as if by using Walker.insert.number
.
Simple operators (those with no child objects) can be described in one of two ways. If the operator is a standard math object, it can be imported using an object whose type
is the API name of the object. Alternatively, the operator can be imported using a type
of "operator"
and a symbol
property with the desired symbol. The placement
property may optionally be specified to give the operator a non-standard placement. Thus, the following:
{ type: "plus" }
is equivalent to:
{
type: "operator",
symbol: "+",
placement: "contextual"
}
Note: Using the operator type, it is possible to create new operators (operators with no equivalent MathObject or ChemistryObject). These can be used in an editor like any other operator, with some caveats: the editor may not have have the font support needed to properly render the specified symbol; exporting to other formats may not work as expected; and advanced features such as computation will not know how to apply the operator.
Variable names (as described by the symbol
property) are restricted to a single code point from a list of allowed characters (generally, letters). When importing a variable that does not meet these requirements, it will be transformed into a valid identifier if possible.
When exporting a node followed by a power (superscript) and/or index (subscript) node, all nodes will be merged into a single placeholder node with three fields: the base node, the index, and the power. Missing scripts will have empty fields, but are definitively indicated by special properties. An object like the following could be used for 16²:
{
type: "script",
hasIndex: false,
hasPower: true,
fields: [
[{ type: "number", symbol: "16" }],
[],
[{ type: "number", symbol: "2" }]
]
}
When importing, hasIndex
and hasPower
are optional. If they are not explicit properties of the object, they are assumed to be true; if only two fields are provided and neither property is defined, the second field it is taken to represent an exponent. The same is true if two fields are provided and only hasPower
is true. This is an exception to the usual rule that missing fields are treated as empty.
An alternative to using a "script"
object is to list the components inline in the field, as they would occur in the editor:
[
{ type: "number", symbol: "16" },
{ type: "toThePower", fields: [ [{ type: "number", symbol: "2" }] ] }
]
When exporting, these are always exported by type using the full element name (for example, "carbon"
or "carbonIsotope"
). When importing, they can also be imported by symbol by using type "element"
or "isotope"
. For example, these two objects are equivalent:
[
{ type: "helium" },
{ type: "element", symbol: "He" }
]
An object with no type but with a text property will be interpreted as a text annotation:
{ text: "Proof (by induction):" }
This API is still under development and is subject to change. Copyright © Math I Can Do Solutions Incorporated and/or its licensors.