UNPKG

itutor-mathlive

Version:

Beautifully typeset math made easy

682 lines (570 loc) 82.4 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"><title>core/parser.js - 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">core/parser.js</h1> <section> <article> <pre class="prettyprint source linenums"> <code> /** * @private */ define(['mathlive/core/definitions', 'mathlive/core/color', 'mathlive/core/fontMetrics', 'mathlive/core/lexer', 'mathlive/core/mathAtom'], function(Definitions, Color, FontMetrics, Lexer, MathAtomModule) { const MathAtom = MathAtomModule.MathAtom; /** * A parser transforms a list of tokens into a list of MathAtom. * * @param {InputToken[]} tokens - An array of tokens generated by the lexer. * @param {Object} [args] - An optional list of arguments. `#n` tokens will be * substituted with the corresponding element in the args array. This is used * when parsing macros. * @property {Object} [macros] - Optional macro definitions. * @class Parser * @global * @property {InputToken[]} tokens - An array of tokens generated by the lexer. * @property {Object} args - Optional arguments to substitute the `#` token. * @property {Object} macros - A dictionary of objects, index by the name of * the macro, with the following keys: * * args: an integer, the number of arguments, default 0. They can be referenced as #0, * #1, #2... inside the definition of the macro * * def: a string, the definition of the macro, which can reference other macros * @property {number} index - The current token to be parsed: index in `this.tokens` * @property {MathAtom[]} mathList - Accumulated result of the parsing by * `parseAtom()` * @property {string} parseMode - The parse mode indicates the syntax rules to * use to parse the upcoming tokens. * Valid values include: * - `'math'`: spaces are ignored, math functions are allowed * - `'text'`: spaces are accounted for, math functions are ignored * - `'string'` * - `'color'`: color name, hex value: `'#fff'`, `'#a0a0a0'` * - `'number'`: `+/-12.56` * - `'dimen'`: `'25mu'`, `'2pt'` * - `'skip'`: `'25mu plus 2em minus fiLll'`, `'2pt'` * - `'colspec'`: formating of a column in tabular environment, e.g. `'r@{.}l'` * @property {boolean} tabularMode - When in tabular mode, `'&amp;'` is interpreted as * a column separator and `'\'` as a row separator. Used for matrixes, etc... * @property {number} endCount - Counter to prevent deadlock. If `end()` is * called too many times (1,000) in a row for the same token, bail. * @private */ function Parser(tokens, args, macros) { this.tokens = tokens; this.index = 0; this.args = args; this.macros = macros; this.mathList = []; this.parseMode = 'math'; this.tabularMode = false; this.endCount = 0; } Parser.prototype.swapMathList = function(newMathList) { const result = this.mathList; this.mathList = newMathList || []; return result; } Parser.prototype.swapParseMode = function(mode) { const result = this.parseMode; this.parseMode = mode; return result; } /** * True if we've reached the end of the token stream. * @method Parser#end * @private */ Parser.prototype.end = function() { // To prevent a deadlock, count how many times end() is called without the // index advancing. If it happens more than 1,000 times in a row, // assume something is broken and pretend the stream is finished. this.endCount++; return this.index >= this.tokens.length || this.endCount > 1000; } Parser.prototype.get = function() { this.endCount = 0; return this.index &lt; this.tokens.length ? this.tokens[this.index++] : null; } Parser.prototype.peek = function(offset) { const index = this.index + (offset ? offset : 0); return index &lt; this.tokens.length ? this.tokens[index] : null; } /** * Return the last atom of the math list. * If force is true (or undefined) and the list is empty, a new empty * atom is created and returned as the result. * @method Parser#lastMathAtom */ Parser.prototype.lastMathAtom = function() { if (this.mathList.length === 0 || this.mathList[this.mathList.length - 1].type !== 'mop') { // ZERO WIDTH SPACE const lastAtom = new MathAtom(this.parseMode, 'msubsup', '\u200b', 'main'); lastAtom.attributes = { "aria-hidden": true }; this.mathList.push(lastAtom); } return this.mathList[this.mathList.length - 1]; } /** * @param {string} type * @return {boolean} True if the next token is of the specified type * @method Parser#hasToken */ Parser.prototype.hasToken = function(type) { const index = this.index; return index &lt; this.tokens.length ? this.tokens[index].type === type : false; } /** * @param {string} [value] * @return {boolean} True if the next token is of type `'literal` and has the * specified value. If `value` is empty, return true if the token is of type * `'literal'` * @method Parser#hasLiteral */ Parser.prototype.hasLiteral = function(value) { const index = this.index; return index &lt; this.tokens.length ? this.tokens[index].type === 'literal' &amp;&amp; (!value || this.tokens[index].value === value) : false; } /** * @param {RegEx} pattern * @return {boolean} True if the next token is of type `'literal` and matches * the specified regular expression pattern. * @method Parser#hasLiteralPattern */ Parser.prototype.hasLiteralPattern = function(pattern) { return this.hasToken('literal') &amp;&amp; pattern.test(this.tokens[this.index].value); } Parser.prototype.hasCommand = function(command) { console.assert(command === '\\' || command.charAt(0) !== '\\', 'hasCommand() does not require a \\'); const index = this.index; return index &lt; this.tokens.length ? this.tokens[index].type === 'command' &amp;&amp; this.tokens[index].value === command : false; } Parser.prototype.hasInfixCommand = function() { const index = this.index; if (index &lt; this.tokens.length &amp;&amp; this.tokens[index].type === 'command') { const info = Definitions.getInfo('\\' + this.tokens[index].value, this.parseMode, this.macros); return info &amp;&amp; info.infix; } return false; } Parser.prototype.hasColumnSeparator = function() { const index = this.index; return this.tabularMode &amp;&amp; index &lt; this.tokens.length ? this.tokens[index].type === 'literal' &amp;&amp; this.tokens[index].value === '&amp;' : false; } Parser.prototype.hasRowSeparator = function() { const index = this.index; return this.tabularMode &amp;&amp; index &lt; this.tokens.length ? this.tokens[index].type === 'command' &amp;&amp; (this.tokens[index].value === '\\' || this.tokens[index].value === 'cr') : false; } Parser.prototype.parseColumnSeparator = function() { if (this.hasColumnSeparator()) { this.index++; return true; } return false; } /** * Return the appropriate value for a placeholder, either a default * one, or if a value was provided for #? via args, that value. */ Parser.prototype.placeholder = function() { if (this.args &amp;&amp; typeof this.args['?'] === 'string') { // If there is a specific value defined for the placeholder, // use it. return parseTokens(Lexer.tokenize(this.args['?']), this.parseMode, null, this.macros); } // U+2753 = BLACK QUESTION MARK ORNAMENT return [new MathAtom(this.parseMode, 'placeholder', '?')]; } const SIZING_COMMANDS = [ 'tiny', 'scriptsize', 'footnotesize', 'small', 'normalsize', 'large', 'Large', 'LARGE', 'huge', 'Huge', ]; const MATHSTYLE_COMMANDS = [ 'displaystyle', 'textstyle', 'scriptstyle', 'scriptscriptstyle', ] Parser.prototype.hasImplicitCommand = function(commands) { if (this.index &lt; this.tokens.length) { const token = this.tokens[this.index] if (token.type === 'command') { return commands.includes(token.value); } } return false; } Parser.prototype.parseRowSeparator = function() { if (this.hasRowSeparator()) { this.index++; return true; } return false; } /** * @param {string} type * @method Parser#parseToken */ Parser.prototype.parseToken = function(type) { if (this.hasToken(type)) { this.index++; return true; } return false; } Parser.prototype.skipUntilToken = function(type) { while (!this.end() &amp;&amp; !this.parseToken(type)) { this.get(); } } Parser.prototype.parseCommand = function(command) { if (this.hasCommand(command)) { this.index++; return true; } return false; } Parser.prototype.parseLiteral = function(literal) { if (this.hasLiteral(literal)) { this.index++; return true; } return false; } Parser.prototype.parseFiller = function() { let skipped = false; let done = false; do { const skippedSpace = this.parseToken('space'); const skippedRelax = this.parseCommand('relax'); skipped = skipped || skippedSpace || skippedRelax; done = !skippedSpace &amp;&amp; !skippedRelax; } while (!done); return skipped; } /** * Keywords are used to specify dimentions, and for various other * syntactic constructs. Unlike commands, they are not case sensitive. * There are 25 keywords: * at by bp cc cm dd depth em ex fil fill filll height in minus * mm mu pc plus pt sp spread to true width * * TeX: 8212 * @return {boolean} true if the expected keyword is present * @method Parser#parseKeyword * @private */ Parser.prototype.parseKeyword = function(keyword) { const savedIndex = this.index; let done = this.end(); let value = ''; while(!done) { const token = this.get(); if (token.type === 'literal') { value += token.value; } done = this.end() || token.type !== 'literal' || value.length >= keyword.length; } const hasKeyword = keyword.toUpperCase() === value.toUpperCase(); if (!hasKeyword) this.index = savedIndex; return hasKeyword; } /** * Return a sequence of characters as a string. * i.e. 'abcd' returns 'abcd'. * Terminates on the first non-character encountered * e.g. '{', '}' etc... * Will also terminate on ']' * @return {string} * @method Parser#scanString * @private */ Parser.prototype.scanString = function() { let result = ''; let done = this.end(); while(!done) { if (this.hasLiteral(']')) { done = true; } else if (this.hasToken('literal')) { result += this.get().value; done = this.end(); } else if (this.parseToken('space')) { result += ' '; done = this.end(); } else if (this.hasToken('command')) { // TeX will give a 'Missing \endcsname inserted' error // if it encounters any command when expecting a string. // We're a bit more lax. const token = this.get(); const info = Definitions.getInfo('\\' + token.value, this.parseMode, this.macros); // If parseMode is 'math', info.type will never be 'textord' // Otherwise, info.type will never be 'mord' if (info &amp;&amp; (info.type === 'mord' || info.type === 'textord') &amp;&amp; info.value) { result += info.value; } done = this.end(); } else { done = true; } } return result; } /** * Return a CSS color (#rrggbb) * @method Parser#scanColor * @private */ Parser.prototype.scanColor = function() { return Color.stringToColor(this.scanString()); } /** * Return as a number a group of characters representing a * numerical quantity. * * From TeX:8695 (scan_int): * An integer number can be preceded by any number of spaces and `\.+' or * `\.-' signs. Then comes either a decimal constant (i.e., radix 10), an * octal constant (i.e., radix 8, preceded by~\.\'), a hexadecimal constant * (radix 16, preceded by~\."), an alphabetic constant (preceded by~\.\`), or * an internal variable. * @return {number} * @method Parser#scanNumber * @private */ Parser.prototype.scanNumber = function(isInteger) { const negative = this.parseLiteral('-'); // Optional (ignorable) '+' sign if (!negative) this.parseLiteral('+'); this.parseToken('space'); isInteger = !!isInteger; let radix = 10; let digits = /[0-9]/; if (this.parseLiteral("'")) { // Apostrophe indicates an octal value radix = 8; digits = /[0-7]/; isInteger = true; } else if (this.parseLiteral('"') || this.parseLiteral('x')) { // Double-quote indicates a hex value // The 'x' prefix notation for the hexadecimal numbers is a MathJax extension. // For example: 'x3a' radix = 16; // Hex digits have to be upper-case digits = /[0-9A-F]/; isInteger = true; } let value = ''; while (this.hasLiteralPattern(digits)) { value += this.get().value; } // Parse the fractional part, if applicable if (!isInteger &amp;&amp; (this.parseLiteral('.') || this.parseLiteral(','))) { value += '.'; while (this.hasLiteralPattern(digits)) { value += this.get().value; } } const result = isInteger ? parseInt(value, radix) : parseFloat(value); return negative ? -result : result; } /** * Return as a floating point number a dimension in pt (1 em = 10 pt) * * See TeX:8831 * @todo: note that some units depend on the font (em, ex). So it might be * better to return a dimen struct with the value + unit and resolve * later when we have a font context.... * @return {number} * @method Parser#scanDimen * @private */ Parser.prototype.scanDimen = function() { const value = this.scanNumber(false); this.parseToken('space'); let result; if (this.parseKeyword('pt')) { result = FontMetrics.toEm(value, 'pt'); } else if (this.parseKeyword('mm')) { result = FontMetrics.toEm(value, 'mm'); } else if (this.parseKeyword('cm')) { result = FontMetrics.toEm(value, 'cm'); } else if (this.parseKeyword('ex')) { result = FontMetrics.toEm(value, 'ex'); } else if (this.parseKeyword('px')) { result = FontMetrics.toEm(value, 'px'); } else if (this.parseKeyword('em')) { result = FontMetrics.toEm(value, 'em'); } else if (this.parseKeyword('bp')) { result = FontMetrics.toEm(value, 'bp'); } else if (this.parseKeyword('dd')) { result = FontMetrics.toEm(value, 'dd'); } else if (this.parseKeyword('pc')) { result = FontMetrics.toEm(value, 'pc'); } else if (this.parseKeyword('in')) { result = FontMetrics.toEm(value, 'in'); } else if (this.parseKeyword('mu')) { result = FontMetrics.toEm(value, 'mu'); } else { // If the units are missing, TeX assumes 'pt' result = FontMetrics.toEm(value, 'pt'); } return result; } Parser.prototype.scanSkip = function() { const result = this.scanDimen(); // We parse, but ignore the optional 'plus' and 'minus' // arguments. this.parseToken('space'); // 'plus', optionally followed by 'minus' // ('minus' cannot come before 'plus') // dimen or 'hfill' if (this.parseKeyword('plus')) { // @todo there could also be a \hFilLlL command here this.scanDimen(); } this.parseToken('space'); if (this.parseKeyword('minus')) { // @todo there could also be a \hFilLlL command here this.scanDimen(); } return result; } Parser.prototype.scanColspec = function() { this.parseToken('space'); const result = []; while (!this.end() &amp;&amp; !(this.hasToken('}') || this.hasLiteral(']'))) { if (this.hasLiteral()) { const literal = this.get().value; if ('lcr'.includes(literal)) { result.push({align: literal}); } else if (literal === '|') { result.push({rule: true}); } else if (literal === '@') { if (this.parseToken('{')) { const savedParsemode = this.swapParseMode('math'); result.push({gap: this.scanImplicitGroup( token => token.type === '}')}); this.swapParseMode(savedParsemode); } this.parseToken('}'); } } } return result; } /** * Parse a `\(...\)` or `\[...\]` sequence * @return {MathAtom} group for the sequence or null * @method Parser#scanModeSet * @private */ Parser.prototype.scanModeSet = function() { let final; if (this.parseCommand('(')) final = ')'; if (!final &amp;&amp; this.parseCommand('[')) final = ']'; if (!final) return null; const savedParsemode = this.swapParseMode('math'); const result = new MathAtom('math', 'group'); result.mathstyle = final === ')' ? 'textstyle' : 'displaystyle'; result.body = this.scanImplicitGroup( token => token.type === 'command' &amp;&amp; token.value === final); this.parseCommand(final); this.swapParseMode(savedParsemode); if (!result.body || result.body.length === 0) return null; return result; } /** * Parse a `$...$` or `$$...$$` sequence * @method Parser#scanModeShift * @private */ Parser.prototype.scanModeShift = function() { if (!this.hasToken('$') &amp;&amp; !this.hasToken('$$')) return null; const final = this.get().type; const result = new MathAtom('math', 'group'); result.mathstyle = final === '$' ? 'textstyle' : 'displaystyle'; result.latexOpen = result.mathstyle === 'textstyle' ? '$' : '$$'; result.latexClose = result.latexOpen; const savedParsemode = this.swapParseMode('math'); result.body = this.scanImplicitGroup(token => token.type === final); this.parseToken(final); this.swapParseMode(savedParsemode); if (!result.body || result.body.length === 0) return null; return result; } /** * Parse a \begin{env}...\end{end} sequence * @method Parser#scanEnvironment * @private */ Parser.prototype.scanEnvironment = function() { // An environment starts with a \begin command if (!this.parseCommand('begin')) return null; // The \begin command is immediately followed by the environment // name, as a string argument const envName = this.scanArg('string'); const env = Definitions.getEnvironmentInfo(envName); // If the environment has some arguments, parse them const args = []; if (env &amp;&amp; env.params) { for (const param of env.params) { // Parse an argument if (param.optional) { // If it's not present, return t