itutor-mathlive
Version:
Beautifully typeset math made easy
379 lines (354 loc) • 58.5 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"><title>Contributor Guide - MathLive Docs</title><meta name="description" content="Beautifully typeset math made easy"><meta name="keywords" content="latex, tex, math, typesetting, documentation, docs">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,700|Source+Sans+Pro:400,400i,700,900" rel="stylesheet">
<style>pre.prettyprint{background: #35434e;}</style>
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow-night.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
<link type="text/css" rel="stylesheet" href="styles/custom.css">
</head>
<body>
<div class="forkme"><a href="https://github.com/arnog/mathlive"><img style="position: absolute; top: 0; right: 0; border: 0; z-index:1;" src="https://camo.githubusercontent.com/52760788cde945287fbb584134c4cbc2bc36f904/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f77686974655f6666666666662e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png"></a></div>
<section role="navigation">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav id="nav">
<h3 class="group-title home"><a href="index.html">MathLive Docs</a></h3><input class="search" placeholder="Search" type="text"><div class="list"><h3 class="group-title">Tutorials</h3><ul><li><a href="tutorial-CONTRIBUTOR_GUIDE.html">Contributor Guide</a></li><li><a href="tutorial-MASTON.html">MASTON</a></li><li><a href="tutorial-USAGE_GUIDE.html">Usage Guide</a></li></ul><h3 class="group-title">Classes</h3><ul><li class="private"><a href="Context.html" class="className">Context</a><ul class='methods private'><li data-type='method' class='private'><a href="Context.html#clone" class="methodName">clone</a></li><li data-type='method' class='private'><a href="Context.html#cloneWith" class="methodName">cloneWith</a></li><li data-type='method' class='private'><a href="Context.html#getBackgroundColor" class="methodName">getBackgroundColor</a></li><li data-type='method' class='private'><a href="Context.html#getColor" class="methodName">getColor</a></li><li data-type='method' class='private'><a href="Context.html#setMathstyle" class="methodName">setMathstyle</a></li><li data-type='method' class='private'><a href="Context.html#withMathstyle" class="methodName">withMathstyle</a></li></ul></li><li><a href="EditableMathlist.html" class="className">EditableMathlist</a><ul class='methods'><li data-type='method'><a href="EditableMathlist.html#_addCell" class="methodName">_addCell</a></li><li data-type='method'><a href="EditableMathlist.html#_deleteAtoms" class="methodName">_deleteAtoms</a></li><li data-type='method'><a href="EditableMathlist.html#addColumnAfter_" class="methodName">addColumnAfter_</a></li><li data-type='method'><a href="EditableMathlist.html#addColumnBefore_" class="methodName">addColumnBefore_</a></li><li data-type='method'><a href="EditableMathlist.html#addRowAfter_" class="methodName">addRowAfter_</a></li><li data-type='method'><a href="EditableMathlist.html#addRowBefore_" class="methodName">addRowBefore_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#ancestor" class="methodName">ancestor</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#anchor" class="methodName">anchor</a></li><li data-type='method'><a href="EditableMathlist.html#applyStyle" class="methodName">applyStyle</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#commandOffsets" class="methodName">commandOffsets</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#commitCommandStringBeforeInsertionPoint" class="methodName">commitCommandStringBeforeInsertionPoint</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#contains" class="methodName">contains</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#decorateCommandStringAroundInsertionPoint" class="methodName">decorateCommandStringAroundInsertionPoint</a></li><li data-type='method'><a href="EditableMathlist.html#delete" class="methodName">delete</a></li><li data-type='method'><a href="EditableMathlist.html#delete_" class="methodName">delete_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteAll_" class="methodName">deleteAll_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteNextChar_" class="methodName">deleteNextChar_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteNextWord_" class="methodName">deleteNextWord_</a></li><li data-type='method'><a href="EditableMathlist.html#deletePreviousChar_" class="methodName">deletePreviousChar_</a></li><li data-type='method'><a href="EditableMathlist.html#deletePreviousWord_" class="methodName">deletePreviousWord_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteToGroupEnd_" class="methodName">deleteToGroupEnd_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteToGroupStart_" class="methodName">deleteToGroupStart_</a></li><li data-type='method'><a href="EditableMathlist.html#deleteToMathFieldEnd_" class="methodName">deleteToMathFieldEnd_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#endOffset" class="methodName">endOffset</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#extend" class="methodName">extend</a></li><li data-type='method'><a href="EditableMathlist.html#extendDown_" class="methodName">extendDown_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToGroupEnd_" class="methodName">extendToGroupEnd_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToGroupStart_" class="methodName">extendToGroupStart_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToMathFieldEnd_" class="methodName">extendToMathFieldEnd_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToMathFieldStart_" class="methodName">extendToMathFieldStart_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToNextBoundary_" class="methodName">extendToNextBoundary_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToNextChar_" class="methodName">extendToNextChar_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToNextWord_" class="methodName">extendToNextWord_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToPreviousBoundary_" class="methodName">extendToPreviousBoundary_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToPreviousChar_" class="methodName">extendToPreviousChar_</a></li><li data-type='method'><a href="EditableMathlist.html#extendToPreviousWord_" class="methodName">extendToPreviousWord_</a></li><li data-type='method'><a href="EditableMathlist.html#extendUp_" class="methodName">extendUp_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#extractCharactersBeforeInsertionPoint" class="methodName">extractCharactersBeforeInsertionPoint</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#extractCommandStringAroundInsertionPoint" class="methodName">extractCommandStringAroundInsertionPoint</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#extractContents" class="methodName">extractContents</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#extractContentsOrdInGroupBeforeInsertionPoint" class="methodName">extractContentsOrdInGroupBeforeInsertionPoint</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#filter" class="methodName">filter</a></li><li data-type='method'><a href="EditableMathlist.html#insert" class="methodName">insert</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#insertFirstAtom" class="methodName">insertFirstAtom</a></li><li data-type='method'><a href="EditableMathlist.html#isCollapsed" class="methodName">isCollapsed</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#jump" class="methodName">jump</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#leap" class="methodName">leap</a></li><li data-type='method'><a href="EditableMathlist.html#moveAfterParent_" class="methodName">moveAfterParent_</a></li><li data-type='method'><a href="EditableMathlist.html#moveBeforeParent_" class="methodName">moveBeforeParent_</a></li><li data-type='method'><a href="EditableMathlist.html#moveDown_" class="methodName">moveDown_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToGroupEnd_" class="methodName">moveToGroupEnd_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToGroupStart_" class="methodName">moveToGroupStart_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToMathFieldEnd_" class="methodName">moveToMathFieldEnd_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToMathFieldStart_" class="methodName">moveToMathFieldStart_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToNextChar_" class="methodName">moveToNextChar_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToNextPlaceholder_" class="methodName">moveToNextPlaceholder_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToNextWord_" class="methodName">moveToNextWord_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToOpposite_" class="methodName">moveToOpposite_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToPreviousChar_" class="methodName">moveToPreviousChar_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToPreviousPlaceholder_" class="methodName">moveToPreviousPlaceholder_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToPreviousWord_" class="methodName">moveToPreviousWord_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToSubscript_" class="methodName">moveToSubscript_</a></li><li data-type='method'><a href="EditableMathlist.html#moveToSuperscript_" class="methodName">moveToSuperscript_</a></li><li data-type='method'><a href="EditableMathlist.html#moveUp_" class="methodName">moveUp_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#next" class="methodName">next</a></li><li data-type='method'><a href="EditableMathlist.html#selectAll_" class="methodName">selectAll_</a></li><li data-type='method'><a href="EditableMathlist.html#selectGroup_" class="methodName">selectGroup_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#setExtent" class="methodName">setExtent</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#setRange" class="methodName">setRange</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#setSelection" class="methodName">setSelection</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#sibling" class="methodName">sibling</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#siblings" class="methodName">siblings</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#skip" class="methodName">skip</a></li><li data-type='method'><a href="EditableMathlist.html#speakAll_" class="methodName">speakAll_</a></li><li data-type='method'><a href="EditableMathlist.html#speakAllWithSynchronizedHighlighting_" class="methodName">speakAllWithSynchronizedHighlighting_</a></li><li data-type='method'><a href="EditableMathlist.html#speakGroup_" class="methodName">speakGroup_</a></li><li data-type='method'><a href="EditableMathlist.html#speakLeftSibling_" class="methodName">speakLeftSibling_</a></li><li data-type='method'><a href="EditableMathlist.html#speakParent_" class="methodName">speakParent_</a></li><li data-type='method'><a href="EditableMathlist.html#speakRightSibling_" class="methodName">speakRightSibling_</a></li><li data-type='method'><a href="EditableMathlist.html#speakSelection_" class="methodName">speakSelection_</a></li><li data-type='method'><a href="EditableMathlist.html#speakSelectionWithSynchronizedHighlighting_" class="methodName">speakSelectionWithSynchronizedHighlighting_</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#startOffset" class="methodName">startOffset</a></li><li data-type='method' class='private'><a href="EditableMathlist.html#toString" class="methodName">toString</a></li><li data-type='method'><a href="EditableMathlist.html#transpose_" class="methodName">transpose_</a></li></ul></li><li class="private"><a href="Lexer.html" class="className">Lexer</a><ul class='methods private'><li data-type='method' class='private'><a href="Lexer.html#end" class="methodName">end</a></li><li data-type='method' class='private'><a href="Lexer.html#get" class="methodName">get</a></li><li data-type='method' class='private'><a href="Lexer.html#isWhiteSpace" class="methodName">isWhiteSpace</a></li><li data-type='method' class='private'><a href="Lexer.html#makeToken" class="methodName">makeToken</a></li><li data-type='method' class='private'><a href="Lexer.html#peek" class="methodName">peek</a></li><li data-type='method' class='private'><a href="Lexer.html#scan" class="methodName">scan</a></li></ul></li><li class="private"><a href="MathAtom.html" class="className">MathAtom</a><ul class='methods private'><li data-type='method' class='private'><a href="MathAtom.html#.toSpeakableText" class="methodName">toSpeakableText</a></li><li data-type='method' class='private'><a href="MathAtom.html#bind" class="methodName">bind</a></li><li data-type='method' class='private'><a href="MathAtom.html#decompose" class="methodName">decompose</a></li><li data-type='method' class='private'><a href="MathAtom.html#decomposeGenfrac" class="methodName">decomposeGenfrac</a></li><li data-type='method' class='private'><a href="MathAtom.html#decomposeLeftright" class="methodName">decomposeLeftright</a></li><li data-type='method' class='private'><a href="MathAtom.html#decomposeLine" class="methodName">decomposeLine</a></li><li data-type='method' class='private'><a href="MathAtom.html#decomposeRule" class="methodName">decomposeRule</a></li><li data-type='method' class='private'><a href="MathAtom.html#filter" class="methodName">filter</a></li><li data-type='method' class='private'><a href="MathAtom.html#makeSpan" class="methodName">makeSpan</a></li></ul></li><li><a href="MathField.html" class="className">MathField</a><ul class='methods'><li data-type='method' class='private'><a href="MathField.html#_getCaretPosition" class="methodName">_getCaretPosition</a></li><li data-type='method' class='private'><a href="MathField.html#_onKeystroke" class="methodName">_onKeystroke</a></li><li data-type='method' class='private'><a href="MathField.html#complete_" class="methodName">complete_</a></li><li data-type='method'><a href="MathField.html#el" class="methodName">el</a></li><li data-type='method' class='private'><a href="MathField.html#enterCommandMode_" class="methodName">enterCommandMode_</a></li><li data-type='method'><a href="MathField.html#insert" class="methodName">insert</a></li><li data-type='method'><a href="MathField.html#keystroke" class="methodName">keystroke</a></li><li data-type='method'><a href="MathField.html#latex" class="methodName">latex</a></li><li data-type='method'><a href="MathField.html#perform" class="methodName">perform</a></li><li data-type='method'><a href="MathField.html#perform" class="methodName">perform</a></li><li data-type='method' class='private'><a href="MathField.html#render" class="methodName">render</a></li><li data-type='method'><a href="MathField.html#revertToOriginalContent" class="methodName">revertToOriginalContent</a></li><li data-type='method'><a href="MathField.html#selectedText" class="methodName">selectedText</a></li><li data-type='method'><a href="MathField.html#selectionAtEnd" class="methodName">selectionAtEnd</a></li><li data-type='method'><a href="MathField.html#selectionAtStart" class="methodName">selectionAtStart</a></li><li data-type='method'><a href="MathField.html#selectionDepth" class="methodName">selectionDepth</a></li><li data-type='method'><a href="MathField.html#selectionIsCollapsed" class="methodName">selectionIsCollapsed</a></li><li data-type='method'><a href="MathField.html#setConfig" class="methodName">setConfig</a></li><li data-type='method'><a href="MathField.html#text" class="methodName">text</a></li><li data-type='method'><a href="MathField.html#typedText" class="methodName">typedText</a></li></ul></li><li class="private"><a href="module-mathstyle.Mathstyle.html" class="className">Mathstyle</a></li><li class="private"><a href="Parser.html" class="className">Parser</a><ul class='methods private'><li data-type='method' class='private'><a href="Parser.html#end" class="methodName">end</a></li><li data-type='method' class='private'><a href="Parser.html#hasLiteral" class="methodName">hasLiteral</a></li><li data-type='method' class='private'><a href="Parser.html#hasLiteralPattern" class="methodName">hasLiteralPattern</a></li><li data-type='method' class='private'><a href="Parser.html#hasToken" class="methodName">hasToken</a></li><li data-type='method' class='private'><a href="Parser.html#lastMathAtom" class="methodName">lastMathAtom</a></li><li data-type='method' class='private'><a href="Parser.html#parseAtom" class="methodName">parseAtom</a></li><li data-type='method' class='private'><a href="Parser.html#parseKeyword" class="methodName">parseKeyword</a></li><li data-type='method' class='private'><a href="Parser.html#parseLimits" class="methodName">parseLimits</a></li><li data-type='method' class='private'><a href="Parser.html#parseSupSub" class="methodName">parseSupSub</a></li><li data-type='method' class='private'><a href="Parser.html#parseToken" class="methodName">parseToken</a></li><li data-type='method' class='private'><a href="Parser.html#scanArg" class="methodName">scanArg</a></li><li data-type='method' class='private'><a href="Parser.html#scanColor" class="methodName">scanColor</a></li><li data-type='method' class='private'><a href="Parser.html#scanDelim" class="methodName">scanDelim</a></li><li data-type='method' class='private'><a href="Parser.html#scanDimen" class="methodName">scanDimen</a></li><li data-type='method' class='private'><a href="Parser.html#scanEnvironment" class="methodName">scanEnvironment</a></li><li data-type='method' class='private'><a href="Parser.html#scanGroup" class="methodName">scanGroup</a></li><li data-type='method' class='private'><a href="Parser.html#scanImplicitGroup" class="methodName">scanImplicitGroup</a></li><li data-type='method' class='private'><a href="Parser.html#scanLeftRight" class="methodName">scanLeftRight</a></li><li data-type='method' class='private'><a href="Parser.html#scanModeSet" class="methodName">scanModeSet</a></li><li data-type='method' class='private'><a href="Parser.html#scanModeShift" class="methodName">scanModeShift</a></li><li data-type='method' class='private'><a href="Parser.html#scanNumber" class="methodName">scanNumber</a></li><li data-type='method' class='private'><a href="Parser.html#scanString" class="methodName">scanString</a></li><li data-type='method' class='private'><a href="Parser.html#scanToken" class="methodName">scanToken</a></li></ul></li><li class="private"><a href="Span.html" class="className">Span</a></li><li class="private"><a href="Token.html" class="className">Token</a></li><li class="private"><a href="UndoManager.html" class="className">UndoManager</a><ul class='methods private'><li data-type='method' class='private'><a href="UndoManager.html#canRedo" class="methodName">canRedo</a></li><li data-type='method' class='private'><a href="UndoManager.html#canUndo" class="methodName">canUndo</a></li><li data-type='method' class='private'><a href="UndoManager.html#redo" class="methodName">redo</a></li><li data-type='method' class='private'><a href="UndoManager.html#snapshot" class="methodName">snapshot</a></li><li data-type='method' class='private'><a href="UndoManager.html#undo" class="methodName">undo</a></li></ul></li></ul><h3 class="group-title">Modules</h3><ul><li class="private"><a href="module-color.html" class="className">color</a><ul class='methods private'><li data-type='method' class='private'><a href="module-color.html#.stringToColor" class="methodName">stringToColor</a></li></ul></li><li class="private"><a href="module-definitions.html" class="className">definitions</a><ul class='methods private'><li data-type='method' class='private'><a href="module-definitions.html#.defineEnvironment" class="methodName">defineEnvironment</a></li><li data-type='method' class='private'><a href="module-definitions.html#.defineFunction" class="methodName">defineFunction</a></li><li data-type='method' class='private'><a href="module-definitions.html#.defineSymbol" class="methodName">defineSymbol</a></li><li data-type='method' class='private'><a href="module-definitions.html#.defineSymbolRange" class="methodName">defineSymbolRange</a></li><li data-type='method' class='private'><a href="module-definitions.html#.defineSymbols" class="methodName">defineSymbols</a></li><li data-type='method' class='private'><a href="module-definitions.html#.frequency" class="methodName">frequency</a></li><li data-type='method' class='private'><a href="module-definitions.html#.getInfo" class="methodName">getInfo</a></li><li data-type='method' class='private'><a href="module-definitions.html#.matchCodepoint" class="methodName">matchCodepoint</a></li><li data-type='method' class='private'><a href="module-definitions.html#.matchFunction" class="methodName">matchFunction</a></li><li data-type='method' class='private'><a href="module-definitions.html#.parseParamTemplateArgument" class="methodName">parseParamTemplateArgument</a></li><li data-type='method' class='private'><a href="module-definitions.html#.suggest" class="methodName">suggest</a></li></ul></li><li class="private"><a href="module-delimiters.html" class="className">delimiters</a><ul class='methods private'><li data-type='method' class='private'><a href="module-delimiters.html#.makeCustomSizedDelim" class="methodName">makeCustomSizedDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeInner" class="methodName">makeInner</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeLargeDelim" class="methodName">makeLargeDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeLeftRightDelim" class="methodName">makeLeftRightDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeNullFence" class="methodName">makeNullFence</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeSizedDelim" class="methodName">makeSizedDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeSmallDelim" class="methodName">makeSmallDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.makeStackedDelim" class="methodName">makeStackedDelim</a></li><li data-type='method' class='private'><a href="module-delimiters.html#.traverseSequence" class="methodName">traverseSequence</a></li></ul></li><li class="private"><a href="module-editor_editableMathlist.html" class="className">editor/editableMathlist</a><ul class='methods private'><li data-type='method' class='private'><a href="module-editor_editableMathlist.html#~atomContains" class="methodName">atomContains</a></li></ul></li><li class="private"><a href="module-editor_keyboard.html" class="className">editor/keyboard</a><ul class='methods private'><li data-type='method' class='private'><a href="module-editor_keyboard.html#.delegateKeyboardEvents" class="methodName">delegateKeyboardEvents</a></li><li data-type='method' class='private'><a href="module-editor_keyboard.html#.keyboardEventToString" class="methodName">keyboardEventToString</a></li></ul></li><li class="private"><a href="module-editor_mathfield.html" class="className">editor/mathfield</a><ul class='methods private'><li data-type='method' class='private'><a href="module-editor_mathfield.html#nearestElementFromPoint" class="methodName">nearestElementFromPoint</a></li></ul></li><li class="private"><a href="module-editor_mathpath.html" class="className">editor/mathpath</a><ul class='methods private'><li data-type='method' class='private'><a href="module-editor_mathpath.html#.pathCommonAncestor" class="methodName">pathCommonAncestor</a></li><li data-type='method' class='private'><a href="module-editor_mathpath.html#.pathDistance" class="methodName">pathDistance</a></li><li data-type='method' class='private'><a href="module-editor_mathpath.html#.pathFromString" class="methodName">pathFromString</a></li><li data-type='method' class='private'><a href="module-editor_mathpath.html#.pathToString" class="methodName">pathToString</a></li></ul></li><li class="private"><a href="module-editor_shortcuts.html" class="className">editor/shortcuts</a><ul class='methods private'><li data-type='method' class='private'><a href="module-editor_shortcuts.html#.match" class="methodName">match</a></li><li data-type='method' class='private'><a href="module-editor_shortcuts.html#.matchKeystroke" class="methodName">matchKeystroke</a></li><li data-type='method' class='private'><a href="module-editor_shortcuts.html#.platform" class="methodName">platform</a></li><li data-type='method' class='private'><a href="module-editor_shortcuts.html#.stringify" class="methodName">stringify</a></li></ul></li><li class="private"><a href="module-fontMetrics.html" class="className">fontMetrics</a><ul class='methods private'><li data-type='method' class='private'><a href="module-fontMetrics.html#.getCharacterMetrics" class="methodName">getCharacterMetrics</a></li></ul></li><li class="private"><a href="module-lexer.html" class="className">lexer</a><ul class='methods private'><li data-type='method' class='private'><a href="module-lexer.html#.tokenize" class="methodName">tokenize</a></li></ul></li><li class="private"><a href="module-mathAtom.html" class="className">mathAtom</a><ul class='methods private'><li data-type='method' class='private'><a href="module-mathAtom.html#.decompose" class="methodName">decompose</a></li><li data-type='method' class='private'><a href="module-mathAtom.html#.getFontName" class="methodName">getFontName</a></li><li data-type='method' class='private'><a href="module-mathAtom.html#.makeColGap" class="methodName">makeColGap</a></li><li data-type='method' class='private'><a href="module-mathAtom.html#.makeColOfRepeatingElements" class="methodName">makeColOfRepeatingElements</a></li><li data-type='method' class='private'><a href="module-mathAtom.html#.makeStack" class="methodName">makeStack</a></li></ul></li><li><a href="module-mathlive.html" class="className">mathlive</a><ul class='methods'><li data-type='method'><a href="module-mathlive.html#latexToAST" class="methodName">latexToAST</a></li><li data-type='method'><a href="module-mathlive.html#latexToMarkup" class="methodName">latexToMarkup</a></li><li data-type='method'><a href="module-mathlive.html#latexToMathML" class="methodName">latexToMathML</a></li><li data-type='method'><a href="module-mathlive.html#latexToSpeakableText" class="methodName">latexToSpeakableText</a></li><li data-type='method'><a href="module-mathlive.html#makeMathField" class="methodName">makeMathField</a></li><li data-type='method'><a href="module-mathlive.html#pauseReadAloud" class="methodName">pauseReadAloud</a></li><li data-type='method'><a href="module-mathlive.html#playReadAloud" class="methodName">playReadAloud</a></li><li data-type='method'><a href="module-mathlive.html#readAloud" class="methodName">readAloud</a></li><li data-type='method'><a href="module-mathlive.html#readAloudStatus" class="methodName">readAloudStatus</a></li><li data-type='method'><a href="module-mathlive.html#renderMathInDocument" class="methodName">renderMathInDocument</a></li><li data-type='method'><a href="module-mathlive.html#renderMathInElement" class="methodName">renderMathInElement</a></li><li data-type='method'><a href="module-mathlive.html#resumeReadAloud" class="methodName">resumeReadAloud</a></li><li data-type='method'><a href="module-mathlive.html#revertToOriginalContent" class="methodName">revertToOriginalContent</a></li><li data-type='method'><a href="module-mathlive.html#revertToOriginalContent" class="methodName">revertToOriginalContent</a></li></ul></li><li class="private"><a href="module-mathstyle.html" class="className">mathstyle</a><ul class='methods private'><li data-type='method' class='private'><a href="module-mathstyle.html#.toMathstyle" class="methodName">toMathstyle</a></li></ul></li><li class="private"><a href="module-span.html" class="className">span</a><ul class='methods private'><li data-type='method' class='private'><a href="module-span.html#.coalesce" class="methodName">coalesce</a></li><li data-type='method' class='private'><a href="module-span.html#.makeFontSizer" class="methodName">makeFontSizer</a></li><li data-type='method' class='private'><a href="module-span.html#.makeHlist" class="methodName">makeHlist</a></li><li data-type='method' class='private'><a href="module-span.html#.makeSpan" class="methodName">makeSpan</a></li><li data-type='method' class='private'><a href="module-span.html#.makeSpanOfType" class="methodName">makeSpanOfType</a></li><li data-type='method' class='private'><a href="module-span.html#.makeSymbol" class="methodName">makeSymbol</a></li><li data-type='method' class='private'><a href="module-span.html#.makeVlist" class="methodName">makeVlist</a></li><li data-type='method' class='private'><a href="module-span.html#.toString" class="methodName">toString</a></li></ul></li></ul><label class="checkbox"><input id="toggle-private" type="checkbox" onclick="
if (!document.getElementById('toggle-private').checked) {
document.documentElement.classList.add('no-private')
writeCookie('symbol-access', 'no-private')
} else {
document.documentElement.classList.remove('no-private')
writeCookie('symbol-access', 'private')
}
">Include Private Symbols</input></label></div>
<footer role="contentInfo">
Made with <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>.
</footer>
</nav>
</section>
<main id="main">
<h1 class="page-title">Contributor Guide</h1>
<section>
<header>
</header>
<article>
<p>This guide is for developers who want to contribute code to MathLive,
or who want to understand in more depth how MathLive works.
If you simply want to use MathLive with your web content, see the <a href="tutorial-USAGE_GUIDE.html">Usage Guide</a>.</p>
<h2 id="table-of-contents">Table of Contents</h2>
<ul>
<li><a href="#getting-started-setting-up-your-development-environment">Getting Started: Setting up Your Development Environment</a></li>
<li><a href="#code-structure">Code Structure</a></li>
<li><a href="#language-and-coding-style">Language and Coding Style</a></li>
<li><a href="#naming-conventions">Naming Conventions</a></li>
<li><a href="#browser-support">Browser Support</a></li>
<li><a href="#accessibility-a11y">Accessibility</a></li>
<li><a href="#architecture">Architecture</a></li>
<li><a href="#files">Files</a></li>
<li><a href="#common-tasks">Common Tasks</a></li>
</ul>
<h2 id="getting-started-setting-up-your-development-environment">Getting Started: Setting up Your Development Environment</h2>
<p>The project uses <a href="https://docs.npmjs.com/misc/scripts">NPM scripts</a>
for its build system. The <code>package.json</code>
file contains the definitions of the build scripts.</p>
<p>To get started developing:</p>
<ol>
<li>Install <a href="http://nodejs.org">Node.js</a> on your dev machine</li>
<li>In your shell, type:<pre class="prettyprint source lang-bash"><code>$ git clone https://github.com/arnog/mathlive && cd mathlive
$ npm install</code></pre>The <code>npm install</code> command installs in the <code>mathlive/</code> directory all the Node
modules necessary to build and test the MathLive library and its documentation.</li>
</ol>
<p>Depending on your system setup, you may need to run as admin, in which case
use <code>sudo npm install</code>.</p>
<p>Once the installation is successful, you can use the following commands:</p>
<pre class="prettyprint source lang-bash"><code># Build the project for local use
# 1. Compile the `.css/.less` file to `build/*.css`
# 2. "npm run lint" on the .js files
# 3. "npm run docs" to generate the documentation
$ npm run build
# Auto re-build the project when a file changes.
# Watch for changed files, and does "npm run build" and "npm run test"
$ npm run dev
# Run test scripts
$ npm test
# Lint Javascript files
$ npm run lint
# Calculate the code coverage and output to build/coverage/
$ npm run coverage
# Build the documentation file to `docs/`
$ npm run docs
# Clean up (deletes) the contents of the `build/`, `dist/` and `docs/` directories
$ npm run clean
# Clean, build, then transpile, minimize and bundle to `dist/`.
# The `dist/` folder will contain the `.js`, `.css` and font files necessary to
# use MathLive. The `docs/` folder will also be updated.
$ npm run dist</code></pre><p>During development, it is recommended that you keep the <code>npm run dev</code>
command running in a terminal window while you make the necessary changes
to the source files of the project in your favorite editor. When you
save a file, if any problem with your code is detected (linting
failure, unit test failure), it will be displayed in the terminal window.</p>
<p>Before doing a commit to <code>master</code> it is also recommended that you do a
<code>npm run dist</code> to make sure that the content of the <code>dist/</code>
and <code>docs/</code> directory are in sync with your latest changes.</p>
<p>After you push your changes to <code>master</code>, a Travis continuous integration
task will run <code>npm run dist</code> and <code>npm run test</code>. If either of those tasks
fail, the build will be marked as failed and will need immediate fixing.</p>
<h3 id="publishing">Publishing</h3>
<p>Once you have made significant changes that are ready to be shared broadly,
use the following commands:</p>
<pre class="prettyprint source lang-bash"><code># Increase the version number of the library
# Only do this before making a new public distribution
# After doing this, you can `npm publish`
$ npm version major | minor | patch |
# Do a full build (code, docs, test), then publish the package to npmjs.com
$ npm publish</code></pre><p><strong>Note on versioning</strong> Use the <a href="http://semver.org/">semver</a> convention for
versions:</p>
<ul>
<li><code>npm version patch</code>: bug fixes and other minor changes. Last number of the
version is incremented, e.g. <code>1.2.41</code> → <code>1.2.42</code></li>
<li><code>npm version minor</code>: new features which don't break existing features. Middle
number of the version is incremented, e.g. <code>1.2.42</code> → <code>1.3.0</code></li>
<li><code>npm version major</code>: changes which break backward compatibility of the API.
Increment the first number, e.g. <code>1.3.56</code> → <code>2.0.0</code></li>
</ul>
<h2 id="code-structure">Code Structure</h2>
<p>The MathLive library consists of the following key directories:</p>
<ul>
<li><code>css/</code> the stylesheets and fonts used by MathLive</li>
<li><code>src/core</code> the core Javascript code needed to render math. This module depends
on the <code>css/</code> module.</li>
<li><code>src/editor</code> the Javascript code needed for the editor. This module depends
on the <code>src/core</code> module.</li>
<li><code>src/addons</code> some optional modules that provide additional functionality</li>
</ul>
<p>You can include only the files you need. For example, if you only
need to display math, you can skip <code>src/editor/</code> and <code>src/addons</code>.</p>
<p>In addition, the <code>build/</code> and <code>dist/</code> directories contain optimized
output generated from the <code>css/</code> and <code>src/</code> directories:</p>
<ul>
<li>the <code>build/</code> directory contains intermediary build results. These
intermediary results can be used for debugging during development, but are
not suitable for distribution. For example, this directory will contain the
<code>.css</code> files generated from the <code>.less</code> in <code>css/</code>. However, a transpiled or
minified <code>.js</code> file would not, as those are intended for distribution and
should be in the <code>dist/</code> directory.</li>
<li>the <code>dist/</code> directory contains the build results that are ready
for distribution. The files in this directory should be transpiled (for
<code>.js</code> files), autoprefixed (for <code>.css</code> files), minimized and bundled.</li>
<li>finally, the <code>docs/</code> directory contain documentation generated from the
source code.</li>
</ul>
<p>The content of the <code>build/</code>, <code>dist/</code> and <code>docs/</code> directories are entirely
generated as part of the build process. No other directory should contain
intermediated files generated as part of the build process.</p>
<h2 id="language-and-coding-style">Language and Coding Style</h2>
<p>MathLive is written in Javascript, using the <a href="https://www.ecma-international.org/ecma-262/7.0/">ES2016 dialect</a>. This
includes in particular these features:</p>
<ul>
<li><code>let</code> and <code>const</code> instead of <code>var</code></li>
<li>block-scoped variables and functions</li>
<li><code>Array.prototype.includes()</code></li>
<li><code>Object.assign()</code></li>
<li>arrow functions (to a limited extent, there appears to be issues with transpilers)</li>
<li>template strings</li>
<li><code>for...of</code> iterators</li>
<li>string searching <code>String.startsWith()</code>, <code>String.endsWith()</code></li>
<li>number formatting</li>
</ul>
<p>Features that have not been adopted include:</p>
<ul>
<li>classes. The syntax doesn't seem to offer that much benefit and forces
utility functions to be separated from methods that use them.</li>
<li>getters/setters: would probably be a good idea</li>
<li>destructuring: probably some opportunities to simplify some code</li>
<li>default parameters: would clean up some code</li>
<li>rest/spread</li>
<li>generators</li>
</ul>
<p>Before publishing, <a href="https://babeljs.io">Babel</a> transpiles the code so it can
run on recent browsers, even if they don't support all the ES2016 features yet.
The code is also optimized for performance and minimized to reduce the load
time.</p>
<p>The code base attempts to follow these general guidelines:</p>
<ul>
<li><strong>Consistency</strong> All code in the codebase should look as if it had been
written by a single person. Don't write code for yourself, but for the many
people who will read it later.</li>
<li><strong>Clarity before performance</strong> Write code that is easy to read, and avoid
obscure constructs that may obfuscate the code to improve performance. For
example, RegEx are crazy fast in all modern browsers, and trying to roll out
your own pattern matching will result in more code and less performance.
If you think something could be made faster, use <a href="https://jsperf.com">jsperf.com</a> to
try out options in various browsers and compare the results. You might be
surprised.</li>
<li><strong>Follow Postel's Law, the Robustness Principle</strong> "Be conservative in what
you do, be liberal in what you accept from others". For example, functions that
are invoked internally do not need to check that the input parameters are valid.
However, public APIs should check the validity of parameters, and behave
reasonably when they aren't. </li>
</ul>
<p>Use the <code>.eslintrc.json</code> file to follow the linting conventions used in the
project. In addition, follow these guidelines:</p>
<ul>
<li><strong>Tabs</strong> are expanded to <strong>four spaces</strong></li>
<li>Quotes are preferably <strong>single quotes</strong>. Use double-quotes when inside a
single-quoted string. Using backtick (template strings)for multiline
quotes is OK.<pre class="prettyprint source lang-javascript"><code> let s = 'hello, ' + 'world';
s = 'hello, "world"';
s = `hello:
world`;</code></pre></li>
<li><strong>Typecheck</strong> using <code>typeof v === 'string'</code>, <code>typeof v === 'number'</code>, etc...
Use <code>Array.isArray(v)</code> to check for arrays.</li>
<li><strong>Conditional evaluation.</strong> Use conditional evaluation shortcuts when applicable
for example, use <code>if (string)</code> instead of <code>if (string !== '')</code></li>
<li>The variable holding the return value of a function is usually named
<strong><code>result</code></strong></li>
<li><strong>Avoid boolean as arguments.</strong> Instead, use an <code>options</code> object with
key/value pairs spelling out the meaning of the boolean.
Don't do:<pre class="prettyprint source lang-javascript"><code> f(true);</code></pre>Do: <pre class="prettyprint source lang-javascript"><code> f({reverse: true})</code></pre></li>
<li><strong>Use <code>||</code> for default values.</strong> For example <pre class="prettyprint source lang-javascript"><code> m = f(n) || d;</code></pre>If the function <code>f</code> returns <code>null</code>, <code>undefined</code> or an empty string,
<code>m</code> will have the value <code>d</code></li>
<li><strong>Braces for control structures</strong> should always be used, except for short
<code>if</code> statement, for example <code>if (done) return;</code></li>
<li><strong>Avoid method chaining.</strong> Method chaining is a programming style where a
method returns the <code>this</code> object so that it can be called again. For example
<code>div.css('color', 'white').height(50).width(50)</code>.</li>
<li><strong>Use loose typing.</strong> For example, a function argument could accept a string
or an array and behave appropriately:<pre class="prettyprint source lang-javascript"><code> function f(argument) {
if (Array.isArray(argument)) {
argument = argument.join(';');
}
}</code></pre></li>
</ul>
<h2 id="naming-conventions">Naming Conventions</h2>
<p>Those naming conventions are particularly important for objects that are exposed
as part of the public API, such as <code>MathLive</code> and <code>MathField</code>.</p>
<ul>
<li>variables and function names that begin with <code>_</code> are private and should not
be used.</li>
<li>functions that end in <code>_</code> are selectors and should not be invoked directly.
Instead, a <code>MathField.perform()</code> call should be made. Note that the perform call
does not include the <code>_</code>, so you would call <code>MathField.perform('selectAll')</code>.</li>
<li>functions that neither begin nor end with an <code>_</code> are public and can be called
directly.</li>
</ul>
<h2 id="browser-support">Browser Support</h2>
<p>MathLive is designed for the modern web. Supporting older browsers complicates
the effort involved in building new features, but it is also an insecure
practice that should not be encouraged. </p>
<p>In this context, <em>modern</em> means the latest two releases of Chrome, IE, Safari
and Firefox. Both desktop and mobile are supported.</p>
<h2 id="accessibility-a11y">Accessibility - A11Y</h2>
<h3 id="rendering">Rendering</h3>
<p>MathLive renders math using HTML and CSS. Digits, letters and math symbols are
displayed in <code><span></code> tags with the necessary CSS styling to display them in
the right place. In addition, rules (lines) such as the fraction line, are
rendered using CSS borders. In a few rare cases, SVG is used to render
some decorations, such as the annotations of the <code>\enclose</code> command.</p>
<p>The rendered math is not purely graphical, and as such can be accessed by
screen readers.</p>
<h3 id="alternate-renditions">Alternate renditions</h3>
<p>However, in addition to the "visual" HTML+CSS representation that MathLive
outputs, it can also generate alternate renditions, including:</p>
<ul>
<li><strong>LaTeX</strong>: a string of LaTeX code equivalent to the formula.</li>
<li><strong>Spoken Text</strong>: a text representation of the formula as someone would speak it,
for example: <code>f(x) = x^2</code> → "f of x equals x squared"</li>
<li><strong>Annotated Spoken Text</strong>: as above, but in addition prosody hints are
inserted for a more natural rendition by text to speech systems (breathing
pauses, variation in pitch, etc...).</li>
</ul>
<p>Those alternate renditions can be rendered as an ARIA-label, or as an element
that is not visually rendered, but visible to screen readers.</p>
<h3 id="speech">Speech</h3>
<p>Although MathLive works with screen readers, since math is its own language
MathLive has its own built-in text to speech renderer. With the speech interface
it is possible to:</p>
<ul>
<li>read the current group (numerator or subscript, for example)<ul>
<li>Mac: <code>Ctrl + Command + Down</code></li>
<li>Windows/Linux/ChromeOS: <code>Ctrl + Alt + Down</code></li>
</ul>
</li>
<li>read what's before or after the selection<ul>
<li>Mac: <code>Ctrl + Command + Left/Right</code></li>
<li>Windows/Linux/ChromeOS: <code>Ctrl + Alt + Left/Right</code></li>
</ul>
</li>
<li>read the parent of the current group<ul>
<li>Mac: <code>Ctrl + Command + Up</code></li>
<li>Windows/Linux/ChromeOS: <code>Ctrl + Alt + Up</code></li>
</ul>
</li>
<li>read the current selection<ul>
<li>Mac: <code>Ctrl + Command + Shift + Down</code></li>
<li>Windows/Linux/ChromeOS: <code>Ctrl + Alt + Shift + Down</code></li>
</ul>
</li>
</ul>
<p>With these convenient keyboard shortcuts, it is possible to aurally navigate
and understand even complex formulas.</p>
<h3 id="input-and-navigation">Input and navigation</h3>
<p>MathLive supports multiple modalities for input: in addition to pointer devices
(mouse, trackpad, touch screen), MathLive has an extensive set of keyboard
shortcuts that allow navigation and editing of the most complex formulas.
Every operation is possible without the use of a pointing device.</p>
<p>Conversely, it is possible to enter commands and complex mathematical symbols
using only a pointing device: the command bar can be invoked by tapping a round
toggle button displayed to the right of the formula. The command bar offers
large buttons that act as a virtual keyboard, but offer contextual operations
depending on the current selection, and the content around it. Those buttons
are easy to use on touch screens and for users of alternative pointing devices.</p>
<h2 id="architecture">Architecture</h2>
<p>The core of MathLive is a math rendering engine that can output to HTML and
CSS. This engine uses the TeX layout algorithms because of their quality.
Given the same input, MathLive will render pixel for pixel what TeX would
have rendered.
To do so, it makes use of a web version of the fonts used by TeX and which are
included in the <code>dist/fonts/</code> directory.
Although the rendering engine follows the TeX algorithms, MathLive also has
an in-memory data structure to represent a math expression while it is being
edited (the math atom tree).</p>
<p>Here are some of the key concepts used throughout the code base.</p>
<h3 id="span">Span</h3>
<p>A span is an object that is used to represent an element displayed in
a web page:
a symbol such as <em>x</em> or <em>=</em>, an open brace, a line separating the numerator
and denominator of a fraction, etc...</p>
<p>The basic layout strategy is to calculate the vertical placement of the spans and
position them accordingly, while letting the HTML rendering engine position
and display the horizontal items. When horizontal adjustments need to be made,
such as additional space between items the CSS margin are adjusted.</p>
<p><strong>Spans</strong> can be rendered to HTML markup with <code>Span.toMarkup()</code> before being
displayed on the page.</p>
<h3 id="math-atom">Math Atom</h3>
<p>An atom is an object encapsulating an elementary mathematical unit, independent
of its graphical representation. </p>
<p>It can be of one of the following types:</p>
<ul>
<li><strong>ord</strong>: ordinary symbol, e.g. <em>x</em>, <em>\alpha</em></li>
<li><strong>bin</strong>: binary operator: <em>+</em>, <em>*</em>, etc...</li>
<li><strong>rel</strong>: relational operator: <em>=</em>, <em>\ne</em>, etc...</li>
<li><strong>punct</strong>: punctuation: <em>,</em>, <em>:</em>, etc...</li>
<li><strong>open</strong>: opening fence: <em>(</em>, <em>\langle</em>, etc...</li>
<li><strong>close</strong>: closing fence: <em>)</em>, <em>\rangle</em>, etc...</li>
<li><strong>op</strong>: (big) operators, <em>\sum</em>, <em>\cap</em>.</li>
<li><strong>inner</strong>: special layout cases, overlap</li>
<li><strong>accent</strong>: a diacritic mark above a symbol</li>
</ul>
<p>In addition to these basic types, which correspond to the TeX atom types,
some atoms represent more complex compounds, including:</p>
<ul>
<li><strong>space</strong> and <strong>spacing</strong>: blank space between atoms</li>
<li><strong>mathstyle</strong>: to change the math style