The API is designed to be loaded from the Math I Can Do Web site to ensure that users always have access to the latest version of the editor. (If you are interested in embedding the code or hosting it on your own server, contact us to discuss details.) Depending on your needs, the API can be loaded different ways:
<script>
tag.Each method is described in detail below. Choose whichever one suits your project and experience level.
Important: These examples use an API key that is all zeroes. This key will only work when testing your page on localhost. Deployed apps will not work unless you replace the
API_KEY
value inmain.ts
with a valid key. Contact us to get an API key.
To load the API in an ES6 module, import the createApi
function as follows:
import { createApi } from "https://www.mathicando.com/api/micd/mathicando.js";
Your script can then call the createApi
function to load the API when required. It must pass a valid API key, and can also pass an options object if desired. The function returns a Promise that resolves to the micd
namespace object. For example:
import { createApi } from "https://www.mathicando.com/api/micd/mathicando.js";
const API_KEY = "000-0000-0000-0000-0000-000";
createApi(API_KEY).then(micd => {
let view = new micd.View();
view.addToDom(document.body);
view.type("1+1=2");
view.focus();
// ...
});
Or, if your target environment supports top-level await, you could use code like the following:
import { createApi } from "https://www.mathicando.com/api/micd/mathicando.js";
const micd = await createApi(API_KEY);
const shell = await micd.shell.create(document.body);
// ...
If your environment does not support top-level await, you can simulate support by wrapping your code as follows:
import { createApi } from "https://www.mathicando.com/api/micd/mathicando.js";
(async function() {
const micd = await createApi(API_KEY);
const shell = await micd.shell.create(document.body);
// ...
})();
Global configuration options can be passed to createApi
as a second argument:
await createApi(API_KEY, { theme: { sBaseTheme: "dark" } });
Important: In your Web page, the script tag that loads an ES6 module script must have the
type="module"
attribute. For example:index.html
<!DOCTYPE html> <html> <head> <title>Example</title> <script defer type="module" src="main.js"></script> </head> <body> ... </body> </html>
main.js
import { createApi } from "https://www.mathicando.com/api/micd/mathicando.js"; // ...
Node.js is a JavaScript runtime that runs outside of the browser. It is commonly used to develop front ends for Web applications using bundling tools like webpack, Rollup, or Parcel.js.
Note: As there are myriad Node.js development setups, this section can only offer general guidance. Experienced Node.js developers should be fine, but if you are a beginner you should check out the quick start tutorial.
If you have not already done so, create a directory for your project and create an empty package.json
. For example:
cd path/to/my/project
npm init -y
Now install the Math I Can Do API node module in your project directory:
npm install https://www.mathicando.com/api/micd/mathicando-api.tgz
Then you can start using the API by requiring the module and calling createApi
to load the API. This will start the API asynchronously, returning a Promise that resolves when the API is ready to use:
index.js
const { createApi } = require("mathicando-api");
const API_KEY = "000-0000-0000-0000-0000-000";
createApi(API_KEY).then(micd => {
new micd.View().addToDom(document.body);
});
A development environment like VS Code should provide code completion and type checking automatically using the type information included with the module, but if not you may be able to nudge it along with an appropriate jsconfig.json
file in your project directory. For example:
jsconfig.json
{
"compilerOptions": {
"target": "es5",
"checkJs": true,
"moduleResolution": "node"
}
}
To load the API directly into a page using a <script>
tag, you must first define a global micd
object that contains a key
property set to your API key. Then add a script tag to load the API:
<script>micd = { key: "000-0000-0000-0000-0000-000" }</script>
<script data-cfasync="false" src="https://www.mathicando.com/api/micd/micd_loader/micd_loader.nocache.js"></script>
Once initialized, the API is available through the global variable micd
:
var view = new micd.View();
view.addToDom(document.body);
To know when the API has loaded, add a property named onReady
to the micd
object that you created for the API key. Set this to a function you wish to call once the API is ready to use:
<script>
micd = {
key: "000-0000-0000-0000-0000-000",
onReady: callWhenMicdHasLoaded
};
function callWhenMicdHasLoaded() {
// append a new editor to the page
new micd.View().addToDom(document.body);
}
</script>
<script defer data-cfasync="false" src="https://www.mathicando.com/api/micd/micd_loader/micd_loader.nocache.js"></script>
If you prefer a Promise that resolves when the API is available, you could instead use code like the following:
<script>
micd = { key: "000-0000-0000-0000-0000-000" };
apiLoadedPromise = new Promise(resolve => micd.onReady = resolve);
</script>
<script defer data-cfasync="false" src="https://www.mathicando.com/api/micd/micd_loader/micd_loader.nocache.js"></script>
<script defer src="main.js"></script>
Then in main.js
you could use code like the following:
apiLoadedPromise
.then(()=>{
// append a new editor to the page
new micd.View().addToDom(document.body);
});
Global configuration options can be specified by defining the config
property before loading the API. For example:
<script>
micd = {
key: "000-0000-0000-0000-0000-000",
onReady: callWhenMicdHasLoaded,
config: {
theme: { sBaseTheme: "dark" },
// ... more config options
}
};
</script>
If you have successfully loaded the API using any of the examples above, then you have already created your first editor! Each of those examples creates a View and adds it to the page using code like the following:
let view = new micd.View();
view.addToDom(document.body);
view.focus();
Views are the simplest way to interact with an editor. They are similar to a <textarea>
, except that they contain math notation instead of plain text.
Note: It is important to keep in mind that the API loads asynchronously. Make sure the API is loaded before executing any of the code in this section. If you are not sure how, refer back to the instructions for your chosen loading method. (Essentially, wait for the
createApi
Promise to resolve or for youronReady
function to be invoked.)
The API also includes a rich, app-like interface, the Shell. To create a Shell instead of a View, you could use code like the following:
micd.shell.create(document.body);
To keep load times down for pages that don't use a Shell, they are created asynchronously. That way, the additional resources needed to create the Shell interface are only loaded if you actually need them. The function called above, micd.shell.create returns a Promise that resolves to the new Shell. If you want to use properties or methods on the Shell (or the View or Editor that it includes), you need to wait for that Promise to resolve first. For example (in an async function):
const shell = await micd.shell.create(document.body);
shell.view.type("2");
shell.editor.apply("selectLine");
shell.editor.apply("squareRoot");
Shells size themselves to their parent element. One way to control their size is to create them in an appropriately styled container. For example:
style.css
#container {
width: 800px;
height: 600px;
}
main.js
let container = document.createElement("div");
container.id = "container";
document.body.appendChild(container);
micd.shell.create(container);
Views do not have a preset size, although they may have a minimum size. You can size a View by styling its View.rootElement or by placing it in a container element that sizes its children.
This API is still under development and is subject to change. Copyright © Math I Can Do Solutions Incorporated and/or its licensors.