jax.js 68 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
  1. /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
  2. /* vim: set ts=2 et sw=2 tw=80: */
  3. /*************************************************************
  4. *
  5. * MathJax/jax/input/AsciiMath/jax.js
  6. *
  7. * An Input Jax for AsciiMath notation
  8. * (see http://www1.chapman.edu/~jipsen/mathml/asciimath.html).
  9. *
  10. * Originally adapted for MathJax by David Lippman.
  11. * Additional work done by Davide P. Cervone.
  12. *
  13. * The current development repository for AsciiMathML is
  14. * https://github.com/mathjax/asciimathml
  15. *
  16. * A portion of this file is taken from
  17. * ASCIIMathML.js Version 2.2 Mar 3, 2014, (c) Peter Jipsen http://www.chapman.edu/~jipsen
  18. * and is used by permission of Peter Jipsen, who has agreed to allow us to
  19. * release it under the Apache2 license (see below). That portion is indicated
  20. * via comments.
  21. *
  22. * The remainder falls under the copyright that follows.
  23. *
  24. * ---------------------------------------------------------------------
  25. *
  26. * Copyright (c) 2012-2018 The MathJax Consortium
  27. *
  28. * Licensed under the Apache License, Version 2.0 (the "License");
  29. * you may not use this file except in compliance with the License.
  30. * You may obtain a copy of the License at
  31. *
  32. * http://www.apache.org/licenses/LICENSE-2.0
  33. *
  34. * Unless required by applicable law or agreed to in writing, software
  35. * distributed under the License is distributed on an "AS IS" BASIS,
  36. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  37. * See the License for the specific language governing permissions and
  38. * limitations under the License.
  39. */
  40. (function (ASCIIMATH) {
  41. var MML; // Filled in later
  42. //
  43. // Make a documentFragment work-alike that uses MML objects
  44. // rather than DOM objects.
  45. //
  46. var DOCFRAG = MathJax.Object.Subclass({
  47. firstChild: null,
  48. lastChild: null,
  49. Init: function () {
  50. this.childNodes = [];
  51. },
  52. appendChild: function (node) {
  53. if (node.parent) {node.parent.removeChild(node)}
  54. if (this.lastChild) {this.lastChild.nextSibling = node}
  55. if (!this.firstChild) {this.firstChild = node}
  56. this.childNodes.push(node); node.parent = this;
  57. this.lastChild = node;
  58. return node;
  59. },
  60. removeChild: function (node) {
  61. for (var i = 0, m = this.childNodes.length; i < m; i++)
  62. {if (this.childNodes[i] === node) break}
  63. if (i === m) return;
  64. this.childNodes.splice(i,1);
  65. if (node === this.firstChild) {this.firstChild = node.nextSibling}
  66. if (node === this.lastChild) {
  67. if (!this.childNodes.length) {this.lastChild = null}
  68. else {this.lastChild = this.childNodes[this.childNodes.length-1]}
  69. }
  70. if (i) {this.childNodes[i-1].nextSibling = node.nextSibling}
  71. node.nextSibling = node.parent = null;
  72. return node;
  73. },
  74. replaceChild: function (node,old) {
  75. for (var i = 0, m = this.childNodes.length; i < m; i++)
  76. {if (this.childNodes[i] === old) break}
  77. if (i) {this.childNodes[i-1].nextSibling = node} else {this.firstChild = node}
  78. if (i >= m-1) {this.lastChild = node}
  79. this.childNodes[i] = node; node.nextSibling = old.nextSibling;
  80. old.nextSibling = old.parent = null;
  81. return old;
  82. },
  83. hasChildNodes: function (node) {
  84. return (this.childNodes.length>0);
  85. },
  86. toString: function () {return "{"+this.childNodes.join("")+"}"}
  87. });
  88. var INITASCIIMATH = function () {
  89. MML = MathJax.ElementJax.mml;
  90. var MBASEINIT = MML.mbase.prototype.Init;
  91. //
  92. // Make MML elements looks like DOM elements (add the
  93. // methods that AsciiMath needs)
  94. //
  95. MML.mbase.Augment({
  96. firstChild: null,
  97. lastChild: null,
  98. nodeValue: null,
  99. nextSibling: null,
  100. Init: function () {
  101. var obj = MBASEINIT.apply(this,arguments) || this;
  102. obj.childNodes = obj.data;
  103. obj.nodeName = obj.type;
  104. return obj;
  105. },
  106. appendChild: function (node) {
  107. if (node.parent) {node.parent.removeChild(node)}
  108. var nodes = arguments;
  109. if (node.isa(DOCFRAG)) {
  110. nodes = node.childNodes;
  111. node.data = node.childNodes = [];
  112. node.firstChild = node.lastChild = null;
  113. }
  114. for (var i = 0, m = nodes.length; i < m; i++) {
  115. node = nodes[i];
  116. if (this.lastChild) {this.lastChild.nextSibling = node}
  117. if (!this.firstChild) {this.firstChild = node}
  118. this.Append(node);
  119. this.lastChild = node;
  120. }
  121. return node;
  122. },
  123. removeChild: function (node) {
  124. for (var i = 0, m = this.childNodes.length; i < m; i++)
  125. {if (this.childNodes[i] === node) break}
  126. if (i === m) return;
  127. this.childNodes.splice(i,1);
  128. if (node === this.firstChild) {this.firstChild = node.nextSibling}
  129. if (node === this.lastChild) {
  130. if (!this.childNodes.length) {this.lastChild = null}
  131. else {this.lastChild = this.childNodes[this.childNodes.length-1]}
  132. }
  133. if (i) {this.childNodes[i-1].nextSibling = node.nextSibling}
  134. node.nextSibling = node.parent = null;
  135. return node;
  136. },
  137. replaceChild: function (node,old) {
  138. for (var i = 0, m = this.childNodes.length; i < m; i++)
  139. {if (this.childNodes[i] === old) break}
  140. // FIXME: make this work with DOCFRAG's?
  141. if (i) {this.childNodes[i-1].nextSibling = node} else {this.firstChild = node}
  142. if (i >= m-1) {this.lastChild = node}
  143. this.SetData(i,node); node.nextSibling = old.nextSibling;
  144. old.nextSibling = old.parent = null;
  145. return old;
  146. },
  147. hasChildNodes: function (node) {
  148. return (this.childNodes.length>0);
  149. },
  150. setAttribute: function (name,value) {this[name] = value}
  151. });
  152. };
  153. //
  154. // Set up to isolate ASCIIMathML.js
  155. //
  156. var window = {}; // hide the true window
  157. //
  158. // Hide the true document, and add functions that
  159. // use and produce MML objects instead of DOM objects
  160. //
  161. var document = {
  162. getElementById: true,
  163. createElementNS: function (ns,type) {
  164. var node = MML[type]();
  165. if (type === "mo" && ASCIIMATH.config.useMathMLspacing) {node.useMMLspacing = 0x80}
  166. return node;
  167. },
  168. createTextNode: function (text) {return MML.chars(text).With({nodeValue:text})},
  169. createDocumentFragment: function () {return DOCFRAG()}
  170. };
  171. var navigator = {appName: "MathJax"}; // hide the true navigator object
  172. /******************************************************************
  173. *
  174. * The following section is ASCIIMathML.js Version 2.2
  175. * (c) Peter Jipsen, used with permission.
  176. *
  177. * Some sections are commented out to save space in the
  178. * minified version (but that is not strictly necessary).
  179. *
  180. ******************************************************************/
  181. /*
  182. ASCIIMathML.js
  183. ==============
  184. This file contains JavaScript functions to convert ASCII math notation
  185. and (some) LaTeX to Presentation MathML. The conversion is done while the
  186. HTML page loads, and should work with Firefox and other browsers that can
  187. render MathML.
  188. Just add the next line to your HTML page with this file in the same folder:
  189. <script type="text/javascript" src="ASCIIMathML.js"></script>
  190. Version 2.2 Mar 3, 2014.
  191. Latest version at https://github.com/mathjax/asciimathml
  192. If you use it on a webpage, please send the URL to jipsen@chapman.edu
  193. Copyright (c) 2014 Peter Jipsen and other ASCIIMathML.js contributors
  194. Permission is hereby granted, free of charge, to any person obtaining a copy
  195. of this software and associated documentation files (the "Software"), to deal
  196. in the Software without restriction, including without limitation the rights
  197. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  198. copies of the Software, and to permit persons to whom the Software is
  199. furnished to do so, subject to the following conditions:
  200. The above copyright notice and this permission notice shall be included in
  201. all copies or substantial portions of the Software.
  202. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  203. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  204. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  205. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  206. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  207. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  208. THE SOFTWARE.
  209. */
  210. //var asciimath = {};
  211. //(function(){
  212. var mathcolor = "blue"; // change it to "" (to inherit) or another color
  213. //var mathfontsize = "1em"; // change to e.g. 1.2em for larger math
  214. //var mathfontfamily = "serif"; // change to "" to inherit (works in IE)
  215. // or another family (e.g. "arial")
  216. //var automathrecognize = false; // writing "amath" on page makes this true
  217. //var checkForMathML = true; // check if browser can display MathML
  218. //var notifyIfNoMathML = true; // display note at top if no MathML capability
  219. //var alertIfNoMathML = false; // show alert box if no MathML capability
  220. //var translateOnLoad = true; // set to false to do call translators from js
  221. //var translateASCIIMath = true; // false to preserve `..`
  222. var displaystyle = true; // puts limits above and below large operators
  223. var showasciiformulaonhover = true; // helps students learn ASCIIMath
  224. var decimalsign = "."; // change to "," if you like, beware of `(1,2)`!
  225. //var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters
  226. //var AMdocumentId = "wikitext" // PmWiki element containing math (default=body)
  227. var fixphi = true; //false to return to legacy phi/varphi mapping
  228. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  229. var isIE = (navigator.appName.slice(0,9)=="Microsoft");
  230. /*
  231. var noMathML = false, translated = false;
  232. if (isIE) { // add MathPlayer info to IE webpages
  233. document.write("<object id=\"mathplayer\"\
  234. classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>");
  235. document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>");
  236. }
  237. // Add a stylesheet, replacing any previous custom stylesheet (adapted from TW)
  238. function setStylesheet(s) {
  239. var id = "AMMLcustomStyleSheet";
  240. var n = document.getElementById(id);
  241. if(document.createStyleSheet) {
  242. // Test for IE's non-standard createStyleSheet method
  243. if(n)
  244. n.parentNode.removeChild(n);
  245. // This failed without the &nbsp;
  246. document.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd","&nbsp;<style id='" + id + "'>" + s + "</style>");
  247. } else {
  248. if(n) {
  249. n.replaceChild(document.createTextNode(s),n.firstChild);
  250. } else {
  251. n = document.createElement("style");
  252. n.type = "text/css";
  253. n.id = id;
  254. n.appendChild(document.createTextNode(s));
  255. document.getElementsByTagName("head")[0].appendChild(n);
  256. }
  257. }
  258. }
  259. setStylesheet("#AMMLcloseDiv \{font-size:0.8em; padding-top:1em; color:#014\}\n#AMMLwarningBox \{position:absolute; width:100%; top:0; left:0; z-index:200; text-align:center; font-size:1em; font-weight:bold; padding:0.5em 0 0.5em 0; color:#ffc; background:#c30\}");
  260. function init(){
  261. var msg, warnings = new Array();
  262. if (document.getElementById==null){
  263. alert("This webpage requires a recent browser such as Mozilla Firefox");
  264. return null;
  265. }
  266. if (checkForMathML && (msg = checkMathML())) warnings.push(msg);
  267. if (warnings.length>0) displayWarnings(warnings);
  268. if (!noMathML) initSymbols();
  269. return true;
  270. }
  271. function checkMathML(){
  272. if (navigator.appName.slice(0,8)=="Netscape")
  273. if (navigator.appVersion.slice(0,1)>="5") noMathML = null;
  274. else noMathML = true;
  275. else if (navigator.appName.slice(0,9)=="Microsoft")
  276. try {
  277. var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
  278. noMathML = null;
  279. } catch (e) {
  280. noMathML = true;
  281. }
  282. else if (navigator.appName.slice(0,5)=="Opera")
  283. if (navigator.appVersion.slice(0,3)>="9.5") noMathML = null;
  284. else noMathML = true;
  285. //noMathML = true; //uncomment to check
  286. if (noMathML && notifyIfNoMathML) {
  287. var msg = "To view the ASCIIMathML notation use Internet Explorer + MathPlayer or Mozilla Firefox 2.0 or later.";
  288. if (alertIfNoMathML)
  289. alert(msg);
  290. else return msg;
  291. }
  292. }
  293. function hideWarning(){
  294. var body = document.getElementsByTagName("body")[0];
  295. body.removeChild(document.getElementById('AMMLwarningBox'));
  296. body.onclick = null;
  297. }
  298. function displayWarnings(warnings) {
  299. var i, frag, nd = createElementXHTML("div");
  300. var body = document.getElementsByTagName("body")[0];
  301. body.onclick=hideWarning;
  302. nd.id = 'AMMLwarningBox';
  303. for (i=0; i<warnings.length; i++) {
  304. frag = createElementXHTML("div");
  305. frag.appendChild(document.createTextNode(warnings[i]));
  306. frag.style.paddingBottom = "1.0em";
  307. nd.appendChild(frag);
  308. }
  309. nd.appendChild(createElementXHTML("p"));
  310. nd.appendChild(document.createTextNode("For instructions see the "));
  311. var an = createElementXHTML("a");
  312. an.appendChild(document.createTextNode("ASCIIMathML"));
  313. an.setAttribute("href","http://www.chapman.edu/~jipsen/asciimath.html");
  314. nd.appendChild(an);
  315. nd.appendChild(document.createTextNode(" homepage"));
  316. an = createElementXHTML("div");
  317. an.id = 'AMMLcloseDiv';
  318. an.appendChild(document.createTextNode('(click anywhere to close this warning)'));
  319. nd.appendChild(an);
  320. var body = document.getElementsByTagName("body")[0];
  321. body.insertBefore(nd,body.childNodes[0]);
  322. }
  323. function translate(spanclassAM) {
  324. if (!translated) { // run this only once
  325. translated = true;
  326. var body = document.getElementsByTagName("body")[0];
  327. var processN = document.getElementById(AMdocumentId);
  328. if (translateASCIIMath) AMprocessNode((processN!=null?processN:body), false, spanclassAM);
  329. }
  330. }
  331. */
  332. function createElementXHTML(t) {
  333. if (isIE) return document.createElement(t);
  334. else return document.createElementNS("http://www.w3.org/1999/xhtml",t);
  335. }
  336. var AMmathml = "http://www.w3.org/1998/Math/MathML";
  337. function AMcreateElementMathML(t) {
  338. if (isIE) return document.createElement("m:"+t);
  339. else return document.createElementNS(AMmathml,t);
  340. }
  341. function createMmlNode(t,frag) {
  342. var node;
  343. if (isIE) node = document.createElement("m:"+t);
  344. else node = document.createElementNS(AMmathml,t);
  345. if (frag) node.appendChild(frag);
  346. return node;
  347. }
  348. function newcommand(oldstr,newstr) {
  349. AMsymbols.push({input:oldstr, tag:"mo", output:newstr, tex:null, ttype:DEFINITION});
  350. refreshSymbols();
  351. }
  352. function newsymbol(symbolobj) {
  353. AMsymbols.push(symbolobj);
  354. refreshSymbols();
  355. }
  356. // character lists for Mozilla/Netscape fonts
  357. var AMcal = ["\uD835\uDC9C","\u212C","\uD835\uDC9E","\uD835\uDC9F","\u2130","\u2131","\uD835\uDCA2","\u210B","\u2110","\uD835\uDCA5","\uD835\uDCA6","\u2112","\u2133","\uD835\uDCA9","\uD835\uDCAA","\uD835\uDCAB","\uD835\uDCAC","\u211B","\uD835\uDCAE","\uD835\uDCAF","\uD835\uDCB0","\uD835\uDCB1","\uD835\uDCB2","\uD835\uDCB3","\uD835\uDCB4","\uD835\uDCB5","\uD835\uDCB6","\uD835\uDCB7","\uD835\uDCB8","\uD835\uDCB9","\u212F","\uD835\uDCBB","\u210A","\uD835\uDCBD","\uD835\uDCBE","\uD835\uDCBF","\uD835\uDCC0","\uD835\uDCC1","\uD835\uDCC2","\uD835\uDCC3","\u2134","\uD835\uDCC5","\uD835\uDCC6","\uD835\uDCC7","\uD835\uDCC8","\uD835\uDCC9","\uD835\uDCCA","\uD835\uDCCB","\uD835\uDCCC","\uD835\uDCCD","\uD835\uDCCE","\uD835\uDCCF"];
  358. var AMfrk = ["\uD835\uDD04","\uD835\uDD05","\u212D","\uD835\uDD07","\uD835\uDD08","\uD835\uDD09","\uD835\uDD0A","\u210C","\u2111","\uD835\uDD0D","\uD835\uDD0E","\uD835\uDD0F","\uD835\uDD10","\uD835\uDD11","\uD835\uDD12","\uD835\uDD13","\uD835\uDD14","\u211C","\uD835\uDD16","\uD835\uDD17","\uD835\uDD18","\uD835\uDD19","\uD835\uDD1A","\uD835\uDD1B","\uD835\uDD1C","\u2128","\uD835\uDD1E","\uD835\uDD1F","\uD835\uDD20","\uD835\uDD21","\uD835\uDD22","\uD835\uDD23","\uD835\uDD24","\uD835\uDD25","\uD835\uDD26","\uD835\uDD27","\uD835\uDD28","\uD835\uDD29","\uD835\uDD2A","\uD835\uDD2B","\uD835\uDD2C","\uD835\uDD2D","\uD835\uDD2E","\uD835\uDD2F","\uD835\uDD30","\uD835\uDD31","\uD835\uDD32","\uD835\uDD33","\uD835\uDD34","\uD835\uDD35","\uD835\uDD36","\uD835\uDD37"];
  359. var AMbbb = ["\uD835\uDD38","\uD835\uDD39","\u2102","\uD835\uDD3B","\uD835\uDD3C","\uD835\uDD3D","\uD835\uDD3E","\u210D","\uD835\uDD40","\uD835\uDD41","\uD835\uDD42","\uD835\uDD43","\uD835\uDD44","\u2115","\uD835\uDD46","\u2119","\u211A","\u211D","\uD835\uDD4A","\uD835\uDD4B","\uD835\uDD4C","\uD835\uDD4D","\uD835\uDD4E","\uD835\uDD4F","\uD835\uDD50","\u2124","\uD835\uDD52","\uD835\uDD53","\uD835\uDD54","\uD835\uDD55","\uD835\uDD56","\uD835\uDD57","\uD835\uDD58","\uD835\uDD59","\uD835\uDD5A","\uD835\uDD5B","\uD835\uDD5C","\uD835\uDD5D","\uD835\uDD5E","\uD835\uDD5F","\uD835\uDD60","\uD835\uDD61","\uD835\uDD62","\uD835\uDD63","\uD835\uDD64","\uD835\uDD65","\uD835\uDD66","\uD835\uDD67","\uD835\uDD68","\uD835\uDD69","\uD835\uDD6A","\uD835\uDD6B"];
  360. /*var AMcal = [0xEF35,0x212C,0xEF36,0xEF37,0x2130,0x2131,0xEF38,0x210B,0x2110,0xEF39,0xEF3A,0x2112,0x2133,0xEF3B,0xEF3C,0xEF3D,0xEF3E,0x211B,0xEF3F,0xEF40,0xEF41,0xEF42,0xEF43,0xEF44,0xEF45,0xEF46];
  361. var AMfrk = [0xEF5D,0xEF5E,0x212D,0xEF5F,0xEF60,0xEF61,0xEF62,0x210C,0x2111,0xEF63,0xEF64,0xEF65,0xEF66,0xEF67,0xEF68,0xEF69,0xEF6A,0x211C,0xEF6B,0xEF6C,0xEF6D,0xEF6E,0xEF6F,0xEF70,0xEF71,0x2128];
  362. var AMbbb = [0xEF8C,0xEF8D,0x2102,0xEF8E,0xEF8F,0xEF90,0xEF91,0x210D,0xEF92,0xEF93,0xEF94,0xEF95,0xEF96,0x2115,0xEF97,0x2119,0x211A,0x211D,0xEF98,0xEF99,0xEF9A,0xEF9B,0xEF9C,0xEF9D,0xEF9E,0x2124];*/
  363. var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4,
  364. RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,
  365. LEFTRIGHT = 9, TEXT = 10, /*BIG = 11, LONG = 12, STRETCHY = 13,
  366. MATRIX = 14,*/ UNARYUNDEROVER = 15; // token types
  367. var AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT};
  368. var AMsymbols = [
  369. //some greek symbols
  370. {input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST},
  371. {input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST},
  372. {input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST},
  373. {input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST},
  374. {input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST},
  375. {input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST},
  376. {input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST},
  377. {input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST},
  378. {input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST},
  379. {input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST},
  380. {input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST},
  381. {input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST},
  382. {input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},
  383. {input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},
  384. {input:"lamda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},
  385. {input:"Lamda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},
  386. {input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST},
  387. {input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST},
  388. {input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST},
  389. {input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST},
  390. {input:"phi", tag:"mi", output:fixphi?"\u03D5":"\u03C6", tex:null, ttype:CONST},
  391. {input:"varphi", tag:"mi", output:fixphi?"\u03C6":"\u03D5", tex:null, ttype:CONST},
  392. {input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST},
  393. {input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST},
  394. {input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST},
  395. {input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST},
  396. {input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST},
  397. {input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST},
  398. {input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST},
  399. {input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST},
  400. {input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST},
  401. {input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST},
  402. {input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST},
  403. {input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST},
  404. {input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST},
  405. {input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST},
  406. {input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST},
  407. {input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST},
  408. //binary operation symbols
  409. //{input:"-", tag:"mo", output:"\u0096", tex:null, ttype:CONST},
  410. {input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},
  411. {input:"**", tag:"mo", output:"\u2217", tex:"ast", ttype:CONST},
  412. {input:"***", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST},
  413. {input:"//", tag:"mo", output:"/", tex:null, ttype:CONST},
  414. {input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST},
  415. {input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST},
  416. {input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST},
  417. {input:"|><", tag:"mo", output:"\u22C9", tex:"ltimes", ttype:CONST},
  418. {input:"><|", tag:"mo", output:"\u22CA", tex:"rtimes", ttype:CONST},
  419. {input:"|><|", tag:"mo", output:"\u22C8", tex:"bowtie", ttype:CONST},
  420. {input:"-:", tag:"mo", output:"\u00F7", tex:"div", ttype:CONST},
  421. {input:"divide", tag:"mo", output:"-:", tex:null, ttype:DEFINITION},
  422. {input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST},
  423. {input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST},
  424. {input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST},
  425. {input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST},
  426. {input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER},
  427. {input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER},
  428. {input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST},
  429. {input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER},
  430. {input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST},
  431. {input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER},
  432. {input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST},
  433. {input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER},
  434. {input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST},
  435. {input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER},
  436. //binary relation symbols
  437. {input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},
  438. {input:":=", tag:"mo", output:":=", tex:null, ttype:CONST},
  439. {input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},
  440. {input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},
  441. {input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},
  442. {input:"gt", tag:"mo", output:">", tex:null, ttype:CONST},
  443. {input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},
  444. {input:"gt=", tag:"mo", output:"\u2265", tex:"geq", ttype:CONST},
  445. {input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST},
  446. {input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST},
  447. {input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST},
  448. {input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST},
  449. {input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST},
  450. {input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST},
  451. {input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST},
  452. {input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST},
  453. {input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST},
  454. {input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST},
  455. {input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST},
  456. {input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST},
  457. {input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST},
  458. {input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST},
  459. {input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST},
  460. //logical symbols
  461. {input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE},
  462. {input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE},
  463. {input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST},
  464. {input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST},
  465. {input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE},
  466. {input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST},
  467. {input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST},
  468. {input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST},
  469. {input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST},
  470. {input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST},
  471. {input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST},
  472. {input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST},
  473. //grouping brackets
  474. {input:"(", tag:"mo", output:"(", tex:"left(", ttype:LEFTBRACKET},
  475. {input:")", tag:"mo", output:")", tex:"right)", ttype:RIGHTBRACKET},
  476. {input:"[", tag:"mo", output:"[", tex:"left[", ttype:LEFTBRACKET},
  477. {input:"]", tag:"mo", output:"]", tex:"right]", ttype:RIGHTBRACKET},
  478. {input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET},
  479. {input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET},
  480. {input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT},
  481. {input:":|:", tag:"mo", output:"|", tex:null, ttype:CONST},
  482. {input:"|:", tag:"mo", output:"|", tex:null, ttype:LEFTBRACKET},
  483. {input:":|", tag:"mo", output:"|", tex:null, ttype:RIGHTBRACKET},
  484. //{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT},
  485. {input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},
  486. {input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},
  487. {input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET},
  488. {input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET},
  489. {input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},
  490. {input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},
  491. //miscellaneous symbols
  492. {input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST},
  493. {input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION},
  494. {input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION},
  495. {input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION},
  496. {input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION},
  497. {input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST},
  498. {input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST},
  499. {input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST},
  500. {input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},
  501. {input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},
  502. {input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},
  503. {input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST},
  504. {input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},
  505. {input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST},
  506. {input:":'", tag:"mo", output:"\u2235", tex:"because", ttype:CONST},
  507. {input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST},
  508. {input:"/_\\", tag:"mo", output:"\u25B3", tex:"triangle", ttype:CONST},
  509. {input:"'", tag:"mo", output:"\u2032", tex:"prime", ttype:CONST},
  510. {input:"tilde", tag:"mover", output:"~", tex:null, ttype:UNARY, acc:true},
  511. {input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST},
  512. {input:"frown", tag:"mo", output:"\u2322", tex:null, ttype:CONST},
  513. {input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST},
  514. {input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST},
  515. {input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST},
  516. {input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST},
  517. {input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST},
  518. {input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST},
  519. {input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST},
  520. {input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST},
  521. {input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST},
  522. {input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST},
  523. {input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST},
  524. {input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST},
  525. {input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST},
  526. {input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST},
  527. {input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST},
  528. {input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST},
  529. {input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true},
  530. {input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true},
  531. //standard functions
  532. {input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},
  533. {input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},
  534. {input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},
  535. {input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},
  536. {input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},
  537. {input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},
  538. {input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},
  539. {input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},
  540. {input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},
  541. {input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},
  542. {input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},
  543. {input:"arcsin", tag:"mo", output:"arcsin", tex:null, ttype:UNARY, func:true},
  544. {input:"arccos", tag:"mo", output:"arccos", tex:null, ttype:UNARY, func:true},
  545. {input:"arctan", tag:"mo", output:"arctan", tex:null, ttype:UNARY, func:true},
  546. {input:"coth", tag:"mo", output:"coth", tex:null, ttype:UNARY, func:true},
  547. {input:"sech", tag:"mo", output:"sech", tex:null, ttype:UNARY, func:true},
  548. {input:"csch", tag:"mo", output:"csch", tex:null, ttype:UNARY, func:true},
  549. {input:"exp", tag:"mo", output:"exp", tex:null, ttype:UNARY, func:true},
  550. {input:"abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, rewriteleftright:["|","|"]},
  551. {input:"norm", tag:"mo", output:"norm", tex:null, ttype:UNARY, rewriteleftright:["\u2225","\u2225"]},
  552. {input:"floor", tag:"mo", output:"floor", tex:null, ttype:UNARY, rewriteleftright:["\u230A","\u230B"]},
  553. {input:"ceil", tag:"mo", output:"ceil", tex:null, ttype:UNARY, rewriteleftright:["\u2308","\u2309"]},
  554. {input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},
  555. {input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},
  556. {input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true},
  557. {input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST},
  558. {input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST},
  559. {input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},
  560. {input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true},
  561. {input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST},
  562. {input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST},
  563. {input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},
  564. {input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},
  565. {input:"Sin", tag:"mo", output:"Sin", tex:null, ttype:UNARY, func:true},
  566. {input:"Cos", tag:"mo", output:"Cos", tex:null, ttype:UNARY, func:true},
  567. {input:"Tan", tag:"mo", output:"Tan", tex:null, ttype:UNARY, func:true},
  568. {input:"Arcsin", tag:"mo", output:"Arcsin", tex:null, ttype:UNARY, func:true},
  569. {input:"Arccos", tag:"mo", output:"Arccos", tex:null, ttype:UNARY, func:true},
  570. {input:"Arctan", tag:"mo", output:"Arctan", tex:null, ttype:UNARY, func:true},
  571. {input:"Sinh", tag:"mo", output:"Sinh", tex:null, ttype:UNARY, func:true},
  572. {input:"Cosh", tag:"mo", output:"Cosh", tex:null, ttype:UNARY, func:true},
  573. {input:"Tanh", tag:"mo", output:"Tanh", tex:null, ttype:UNARY, func:true},
  574. {input:"Cot", tag:"mo", output:"Cot", tex:null, ttype:UNARY, func:true},
  575. {input:"Sec", tag:"mo", output:"Sec", tex:null, ttype:UNARY, func:true},
  576. {input:"Csc", tag:"mo", output:"Csc", tex:null, ttype:UNARY, func:true},
  577. {input:"Log", tag:"mo", output:"Log", tex:null, ttype:UNARY, func:true},
  578. {input:"Ln", tag:"mo", output:"Ln", tex:null, ttype:UNARY, func:true},
  579. {input:"Abs", tag:"mo", output:"abs", tex:null, ttype:UNARY, notexcopy:true, rewriteleftright:["|","|"]},
  580. //arrows
  581. {input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},
  582. {input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},
  583. {input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},
  584. {input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},
  585. {input:">->", tag:"mo", output:"\u21A3", tex:"rightarrowtail", ttype:CONST},
  586. {input:"->>", tag:"mo", output:"\u21A0", tex:"twoheadrightarrow", ttype:CONST},
  587. {input:">->>", tag:"mo", output:"\u2916", tex:"twoheadrightarrowtail", ttype:CONST},
  588. {input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},
  589. {input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},
  590. {input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},
  591. {input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},
  592. {input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},
  593. {input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},
  594. //commands with argument
  595. {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},
  596. {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},
  597. {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},
  598. {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},
  599. {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},
  600. {input:"overset", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},
  601. {input:"underset", tag:"munder", output:"stackrel", tex:null, ttype:BINARY},
  602. {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},
  603. {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},
  604. {input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true},
  605. {input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true},
  606. {input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true},
  607. {input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true},
  608. {input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true},
  609. {input:"overarc", tag:"mover", output:"\u23DC", tex:"overparen", ttype:UNARY, acc:true},
  610. {input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true},
  611. {input:"ubrace", tag:"munder", output:"\u23DF", tex:"underbrace", ttype:UNARYUNDEROVER, acc:true},
  612. {input:"obrace", tag:"mover", output:"\u23DE", tex:"overbrace", ttype:UNARYUNDEROVER, acc:true},
  613. {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},
  614. {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT},
  615. {input:"color", tag:"mstyle", ttype:BINARY},
  616. {input:"id", tag:"mrow", ttype:BINARY},
  617. {input:"class", tag:"mrow", ttype:BINARY},
  618. {input:"cancel", tag:"menclose", output:"cancel", tex:null, ttype:UNARY},
  619. AMquote,
  620. {input:"bb", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"bb", tex:null, ttype:UNARY},
  621. {input:"mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", output:"mathbf", tex:null, ttype:UNARY},
  622. {input:"sf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY},
  623. {input:"mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY},
  624. {input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb},
  625. {input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb},
  626. {input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal},
  627. {input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal},
  628. {input:"tt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"tt", tex:null, ttype:UNARY},
  629. {input:"mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY},
  630. {input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk},
  631. {input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk}
  632. ];
  633. function compareNames(s1,s2) {
  634. if (s1.input > s2.input) return 1
  635. else return -1;
  636. }
  637. var AMnames = []; //list of input symbols
  638. function initSymbols() {
  639. var i;
  640. var symlen = AMsymbols.length;
  641. for (i=0; i<symlen; i++) {
  642. if (AMsymbols[i].tex) {
  643. AMsymbols.push({input:AMsymbols[i].tex,
  644. tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype,
  645. acc:(AMsymbols[i].acc||false)});
  646. }
  647. }
  648. refreshSymbols();
  649. }
  650. function refreshSymbols(){
  651. var i;
  652. AMsymbols.sort(compareNames);
  653. for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;
  654. }
  655. function define(oldstr,newstr) {
  656. AMsymbols.push({input:oldstr, tag:"mo", output:newstr, tex:null, ttype:DEFINITION});
  657. refreshSymbols(); // this may be a problem if many symbols are defined!
  658. }
  659. function AMremoveCharsAndBlanks(str,n) {
  660. //remove n characters and any following blanks
  661. var st;
  662. if (str.charAt(n)=="\\" && str.charAt(n+1)!="\\" && str.charAt(n+1)!=" ")
  663. st = str.slice(n+1);
  664. else st = str.slice(n);
  665. for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);
  666. return st.slice(i);
  667. }
  668. function position(arr, str, n) {
  669. // return position >=n where str appears or would be inserted
  670. // assumes arr is sorted
  671. if (n==0) {
  672. var h,m;
  673. n = -1;
  674. h = arr.length;
  675. while (n+1<h) {
  676. m = (n+h) >> 1;
  677. if (arr[m]<str) n = m; else h = m;
  678. }
  679. return h;
  680. } else
  681. for (var i=n; i<arr.length && arr[i]<str; i++);
  682. return i; // i=arr.length || arr[i]>=str
  683. }
  684. function AMgetSymbol(str) {
  685. //return maximal initial substring of str that appears in names
  686. //return null if there is none
  687. var k = 0; //new pos
  688. var j = 0; //old pos
  689. var mk; //match pos
  690. var st;
  691. var tagst;
  692. var match = "";
  693. var more = true;
  694. for (var i=1; i<=str.length && more; i++) {
  695. st = str.slice(0,i); //initial substring of length i
  696. j = k;
  697. k = position(AMnames, st, j);
  698. if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){
  699. match = AMnames[k];
  700. mk = k;
  701. i = match.length;
  702. }
  703. more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];
  704. }
  705. AMpreviousSymbol=AMcurrentSymbol;
  706. if (match!=""){
  707. AMcurrentSymbol=AMsymbols[mk].ttype;
  708. return AMsymbols[mk];
  709. }
  710. // if str[0] is a digit or - return maxsubstring of digits.digits
  711. AMcurrentSymbol=CONST;
  712. k = 1;
  713. st = str.slice(0,1);
  714. var integ = true;
  715. while ("0"<=st && st<="9" && k<=str.length) {
  716. st = str.slice(k,k+1);
  717. k++;
  718. }
  719. if (st == decimalsign) {
  720. st = str.slice(k,k+1);
  721. if ("0"<=st && st<="9") {
  722. integ = false;
  723. k++;
  724. while ("0"<=st && st<="9" && k<=str.length) {
  725. st = str.slice(k,k+1);
  726. k++;
  727. }
  728. }
  729. }
  730. if ((integ && k>1) || k>2) {
  731. st = str.slice(0,k-1);
  732. tagst = "mn";
  733. } else {
  734. k = 2;
  735. st = str.slice(0,1); //take 1 character
  736. tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");
  737. }
  738. if (st=="-" && AMpreviousSymbol==INFIX) {
  739. AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse
  740. return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};
  741. }
  742. return {input:st, tag:tagst, output:st, ttype:CONST};
  743. }
  744. function AMremoveBrackets(node) {
  745. var st;
  746. if (!node.hasChildNodes()) { return; }
  747. if (node.firstChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) {
  748. st = node.firstChild.firstChild.nodeValue;
  749. if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild);
  750. }
  751. if (node.lastChild.hasChildNodes() && (node.nodeName=="mrow" || node.nodeName=="M:MROW")) {
  752. st = node.lastChild.firstChild.nodeValue;
  753. if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild);
  754. }
  755. }
  756. /*Parsing ASCII math expressions with the following grammar
  757. v ::= [A-Za-z] | greek letters | numbers | other constant symbols
  758. u ::= sqrt | text | bb | other unary symbols for font commands
  759. b ::= frac | root | stackrel binary symbols
  760. l ::= ( | [ | { | (: | {: left brackets
  761. r ::= ) | ] | } | :) | :} right brackets
  762. S ::= v | lEr | uS | bSS Simple expression
  763. I ::= S_S | S^S | S_S^S | S Intermediate expression
  764. E ::= IE | I/I Expression
  765. Each terminal symbol is translated into a corresponding mathml node.*/
  766. var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;
  767. function AMparseSexpr(str) { //parses str and returns [node,tailstr]
  768. var symbol, node, result, i, st,// rightvert = false,
  769. newFrag = document.createDocumentFragment();
  770. str = AMremoveCharsAndBlanks(str,0);
  771. symbol = AMgetSymbol(str); //either a token or a bracket or empty
  772. if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {
  773. return [null,str];
  774. }
  775. if (symbol.ttype == DEFINITION) {
  776. str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length);
  777. symbol = AMgetSymbol(str);
  778. }
  779. switch (symbol.ttype) { case UNDEROVER:
  780. case CONST:
  781. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  782. return [createMmlNode(symbol.tag, //its a constant
  783. document.createTextNode(symbol.output)),str];
  784. case LEFTBRACKET: //read (expr+)
  785. AMnestingDepth++;
  786. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  787. result = AMparseExpr(str,true);
  788. AMnestingDepth--;
  789. if (typeof symbol.invisible == "boolean" && symbol.invisible)
  790. node = createMmlNode("mrow",result[0]);
  791. else {
  792. node = createMmlNode("mo",document.createTextNode(symbol.output));
  793. node = createMmlNode("mrow",node);
  794. node.appendChild(result[0]);
  795. }
  796. return [node,result[1]];
  797. case TEXT:
  798. if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length);
  799. if (str.charAt(0)=="{") i=str.indexOf("}");
  800. else if (str.charAt(0)=="(") i=str.indexOf(")");
  801. else if (str.charAt(0)=="[") i=str.indexOf("]");
  802. else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1;
  803. else i = 0;
  804. if (i==-1) i = str.length;
  805. st = str.slice(1,i);
  806. if (st.charAt(0) == " ") {
  807. node = createMmlNode("mspace");
  808. node.setAttribute("width","1ex");
  809. newFrag.appendChild(node);
  810. }
  811. newFrag.appendChild(
  812. createMmlNode(symbol.tag,document.createTextNode(st)));
  813. if (st.charAt(st.length-1) == " ") {
  814. node = createMmlNode("mspace");
  815. node.setAttribute("width","1ex");
  816. newFrag.appendChild(node);
  817. }
  818. str = AMremoveCharsAndBlanks(str,i+1);
  819. return [createMmlNode("mrow",newFrag),str];
  820. case UNARYUNDEROVER:
  821. case UNARY:
  822. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  823. result = AMparseSexpr(str);
  824. if (result[0]==null) return [createMmlNode(symbol.tag,
  825. document.createTextNode(symbol.output)),str];
  826. if (typeof symbol.func == "boolean" && symbol.func) { // functions hack
  827. st = str.charAt(0);
  828. if (st=="^" || st=="_" || st=="/" || st=="|" || st=="," ||
  829. (symbol.input.length==1 && symbol.input.match(/\w/) && st!="(")) {
  830. return [createMmlNode(symbol.tag,
  831. document.createTextNode(symbol.output)),str];
  832. } else {
  833. node = createMmlNode("mrow",
  834. createMmlNode(symbol.tag,document.createTextNode(symbol.output)));
  835. node.appendChild(result[0]);
  836. return [node,result[1]];
  837. }
  838. }
  839. AMremoveBrackets(result[0]);
  840. if (symbol.input == "sqrt") { // sqrt
  841. return [createMmlNode(symbol.tag,result[0]),result[1]];
  842. } else if (typeof symbol.rewriteleftright != "undefined") { // abs, floor, ceil
  843. node = createMmlNode("mrow", createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[0])));
  844. node.appendChild(result[0]);
  845. node.appendChild(createMmlNode("mo",document.createTextNode(symbol.rewriteleftright[1])));
  846. return [node,result[1]];
  847. } else if (symbol.input == "cancel") { // cancel
  848. node = createMmlNode(symbol.tag,result[0]);
  849. node.setAttribute("notation","updiagonalstrike");
  850. return [node,result[1]];
  851. } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent
  852. node = createMmlNode(symbol.tag,result[0]);
  853. var accnode = createMmlNode("mo",document.createTextNode(symbol.output));
  854. if (symbol.input=="vec" && (
  855. (result[0].nodeName=="mrow" && result[0].childNodes.length==1
  856. && result[0].firstChild.firstChild.nodeValue !== null
  857. && result[0].firstChild.firstChild.nodeValue.length==1) ||
  858. (result[0].firstChild.nodeValue !== null
  859. && result[0].firstChild.nodeValue.length==1) )) {
  860. accnode.setAttribute("stretchy",false);
  861. }
  862. node.appendChild(accnode);
  863. return [node,result[1]];
  864. } else { // font change command
  865. if (!isIE && typeof symbol.codes != "undefined") {
  866. for (i=0; i<result[0].childNodes.length; i++)
  867. if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") {
  868. st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue:
  869. result[0].childNodes[i].firstChild.nodeValue);
  870. var newst = [];
  871. for (var j=0; j<st.length; j++)
  872. if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91)
  873. newst = newst + symbol.codes[st.charCodeAt(j)-65];
  874. else if (st.charCodeAt(j)>96 && st.charCodeAt(j)<123)
  875. newst = newst + symbol.codes[st.charCodeAt(j)-71];
  876. else newst = newst + st.charAt(j);
  877. if (result[0].nodeName=="mi")
  878. result[0]=createMmlNode("mo").
  879. appendChild(document.createTextNode(newst));
  880. else result[0].replaceChild(createMmlNode("mo").
  881. appendChild(document.createTextNode(newst)),
  882. result[0].childNodes[i]);
  883. }
  884. }
  885. node = createMmlNode(symbol.tag,result[0]);
  886. node.setAttribute(symbol.atname,symbol.atval);
  887. return [node,result[1]];
  888. }
  889. case BINARY:
  890. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  891. result = AMparseSexpr(str);
  892. if (result[0]==null) return [createMmlNode("mo",
  893. document.createTextNode(symbol.input)),str];
  894. AMremoveBrackets(result[0]);
  895. var result2 = AMparseSexpr(result[1]);
  896. if (result2[0]==null) return [createMmlNode("mo",
  897. document.createTextNode(symbol.input)),str];
  898. AMremoveBrackets(result2[0]);
  899. if (['color', 'class', 'id'].indexOf(symbol.input) >= 0) {
  900. // Get the second argument
  901. if (str.charAt(0)=="{") i=str.indexOf("}");
  902. else if (str.charAt(0)=="(") i=str.indexOf(")");
  903. else if (str.charAt(0)=="[") i=str.indexOf("]");
  904. st = str.slice(1,i);
  905. // Make a mathml node
  906. node = createMmlNode(symbol.tag,result2[0]);
  907. // Set the correct attribute
  908. if (symbol.input === "color") node.setAttribute("mathcolor", st)
  909. else if (symbol.input === "class") node.setAttribute("class", st)
  910. else if (symbol.input === "id") node.setAttribute("id", st)
  911. return [node,result2[1]];
  912. }
  913. if (symbol.input=="root" || symbol.output=="stackrel")
  914. newFrag.appendChild(result2[0]);
  915. newFrag.appendChild(result[0]);
  916. if (symbol.input=="frac") newFrag.appendChild(result2[0]);
  917. return [createMmlNode(symbol.tag,newFrag),result2[1]];
  918. case INFIX:
  919. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  920. return [createMmlNode("mo",document.createTextNode(symbol.output)),str];
  921. case SPACE:
  922. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  923. node = createMmlNode("mspace");
  924. node.setAttribute("width","1ex");
  925. newFrag.appendChild(node);
  926. newFrag.appendChild(
  927. createMmlNode(symbol.tag,document.createTextNode(symbol.output)));
  928. node = createMmlNode("mspace");
  929. node.setAttribute("width","1ex");
  930. newFrag.appendChild(node);
  931. return [createMmlNode("mrow",newFrag),str];
  932. case LEFTRIGHT:
  933. // if (rightvert) return [null,str]; else rightvert = true;
  934. AMnestingDepth++;
  935. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  936. result = AMparseExpr(str,false);
  937. AMnestingDepth--;
  938. st = "";
  939. if (result[0].lastChild!=null)
  940. st = result[0].lastChild.firstChild.nodeValue;
  941. if (st == "|" && str.charAt(0)!==",") { // its an absolute value subterm
  942. node = createMmlNode("mo",document.createTextNode(symbol.output));
  943. node = createMmlNode("mrow",node);
  944. node.appendChild(result[0]);
  945. return [node,result[1]];
  946. } else { // the "|" is a \mid so use unicode 2223 (divides) for spacing
  947. node = createMmlNode("mo",document.createTextNode("\u2223"));
  948. node = createMmlNode("mrow",node);
  949. return [node,str];
  950. }
  951. default:
  952. //alert("default");
  953. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  954. return [createMmlNode(symbol.tag, //its a constant
  955. document.createTextNode(symbol.output)),str];
  956. }
  957. }
  958. function AMparseIexpr(str) {
  959. var symbol, sym1, sym2, node, result, underover;
  960. str = AMremoveCharsAndBlanks(str,0);
  961. sym1 = AMgetSymbol(str);
  962. result = AMparseSexpr(str);
  963. node = result[0];
  964. str = result[1];
  965. symbol = AMgetSymbol(str);
  966. if (symbol.ttype == INFIX && symbol.input != "/") {
  967. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  968. // if (symbol.input == "/") result = AMparseIexpr(str); else ...
  969. result = AMparseSexpr(str);
  970. if (result[0] == null) // show box in place of missing argument
  971. result[0] = createMmlNode("mo",document.createTextNode("\u25A1"));
  972. else AMremoveBrackets(result[0]);
  973. str = result[1];
  974. // if (symbol.input == "/") AMremoveBrackets(node);
  975. underover = (sym1.ttype == UNDEROVER || sym1.ttype == UNARYUNDEROVER);
  976. if (symbol.input == "_") {
  977. sym2 = AMgetSymbol(str);
  978. if (sym2.input == "^") {
  979. str = AMremoveCharsAndBlanks(str,sym2.input.length);
  980. var res2 = AMparseSexpr(str);
  981. AMremoveBrackets(res2[0]);
  982. str = res2[1];
  983. node = createMmlNode((underover?"munderover":"msubsup"),node);
  984. node.appendChild(result[0]);
  985. node.appendChild(res2[0]);
  986. node = createMmlNode("mrow",node); // so sum does not stretch
  987. } else {
  988. node = createMmlNode((underover?"munder":"msub"),node);
  989. node.appendChild(result[0]);
  990. }
  991. } else if (symbol.input == "^" && underover) {
  992. node = createMmlNode("mover",node);
  993. node.appendChild(result[0]);
  994. } else {
  995. node = createMmlNode(symbol.tag,node);
  996. node.appendChild(result[0]);
  997. }
  998. if (typeof sym1.func != 'undefined' && sym1.func) {
  999. sym2 = AMgetSymbol(str);
  1000. if (sym2.ttype != INFIX && sym2.ttype != RIGHTBRACKET) {
  1001. result = AMparseIexpr(str);
  1002. node = createMmlNode("mrow",node);
  1003. node.appendChild(result[0]);
  1004. str = result[1];
  1005. }
  1006. }
  1007. }
  1008. return [node,str];
  1009. }
  1010. function AMparseExpr(str,rightbracket) {
  1011. var symbol, node, result, i,
  1012. newFrag = document.createDocumentFragment();
  1013. do {
  1014. str = AMremoveCharsAndBlanks(str,0);
  1015. result = AMparseIexpr(str);
  1016. node = result[0];
  1017. str = result[1];
  1018. symbol = AMgetSymbol(str);
  1019. if (symbol.ttype == INFIX && symbol.input == "/") {
  1020. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  1021. result = AMparseIexpr(str);
  1022. if (result[0] == null) // show box in place of missing argument
  1023. result[0] = createMmlNode("mo",document.createTextNode("\u25A1"));
  1024. else AMremoveBrackets(result[0]);
  1025. str = result[1];
  1026. AMremoveBrackets(node);
  1027. node = createMmlNode(symbol.tag,node);
  1028. node.appendChild(result[0]);
  1029. newFrag.appendChild(node);
  1030. symbol = AMgetSymbol(str);
  1031. }
  1032. else if (node!=undefined) newFrag.appendChild(node);
  1033. } while ((symbol.ttype != RIGHTBRACKET &&
  1034. (symbol.ttype != LEFTRIGHT || rightbracket)
  1035. || AMnestingDepth == 0) && symbol!=null && symbol.output!="");
  1036. if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {
  1037. // if (AMnestingDepth > 0) AMnestingDepth--;
  1038. var len = newFrag.childNodes.length;
  1039. if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow"
  1040. && newFrag.childNodes[len-1].lastChild
  1041. && newFrag.childNodes[len-1].lastChild.firstChild ) { //matrix
  1042. //removed to allow row vectors: //&& len>1 &&
  1043. //newFrag.childNodes[len-2].nodeName == "mo" &&
  1044. //newFrag.childNodes[len-2].firstChild.nodeValue == ","
  1045. var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue;
  1046. if (right==")" || right=="]") {
  1047. var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue;
  1048. if (left=="(" && right==")" && symbol.output != "}" ||
  1049. left=="[" && right=="]") {
  1050. var pos = []; // positions of commas
  1051. var matrix = true;
  1052. var m = newFrag.childNodes.length;
  1053. for (i=0; matrix && i<m; i=i+2) {
  1054. pos[i] = [];
  1055. node = newFrag.childNodes[i];
  1056. if (matrix) matrix = node.nodeName=="mrow" &&
  1057. (i==m-1 || node.nextSibling.nodeName=="mo" &&
  1058. node.nextSibling.firstChild.nodeValue==",")&&
  1059. node.firstChild.firstChild.nodeValue==left &&
  1060. node.lastChild.firstChild.nodeValue==right;
  1061. if (matrix)
  1062. for (var j=0; j<node.childNodes.length; j++)
  1063. if (node.childNodes[j].firstChild.nodeValue==",")
  1064. pos[i][pos[i].length]=j;
  1065. if (matrix && i>1) matrix = pos[i].length == pos[i-2].length;
  1066. }
  1067. matrix = matrix && (pos.length>1 || pos[0].length>0);
  1068. var columnlines = [];
  1069. if (matrix) {
  1070. var row, frag, n, k, table = document.createDocumentFragment();
  1071. for (i=0; i<m; i=i+2) {
  1072. row = document.createDocumentFragment();
  1073. frag = document.createDocumentFragment();
  1074. node = newFrag.firstChild; // <mrow>(-,-,...,-,-)</mrow>
  1075. n = node.childNodes.length;
  1076. k = 0;
  1077. node.removeChild(node.firstChild); //remove (
  1078. for (j=1; j<n-1; j++) {
  1079. if (typeof pos[i][k] != "undefined" && j==pos[i][k]){
  1080. node.removeChild(node.firstChild); //remove ,
  1081. if (node.firstChild.nodeName=="mrow" && node.firstChild.childNodes.length==1 &&
  1082. node.firstChild.firstChild.firstChild.nodeValue=="\u2223") {
  1083. //is columnline marker - skip it
  1084. if (i==0) { columnlines.push("solid"); }
  1085. node.removeChild(node.firstChild); //remove mrow
  1086. node.removeChild(node.firstChild); //remove ,
  1087. j+=2;
  1088. k++;
  1089. } else if (i==0) { columnlines.push("none"); }
  1090. row.appendChild(createMmlNode("mtd",frag));
  1091. k++;
  1092. } else frag.appendChild(node.firstChild);
  1093. }
  1094. row.appendChild(createMmlNode("mtd",frag));
  1095. if (i==0) { columnlines.push("none"); }
  1096. if (newFrag.childNodes.length>2) {
  1097. newFrag.removeChild(newFrag.firstChild); //remove <mrow>)</mrow>
  1098. newFrag.removeChild(newFrag.firstChild); //remove <mo>,</mo>
  1099. }
  1100. table.appendChild(createMmlNode("mtr",row));
  1101. }
  1102. node = createMmlNode("mtable",table);
  1103. node.setAttribute("columnlines", columnlines.join(" "));
  1104. if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left");
  1105. newFrag.replaceChild(node,newFrag.firstChild);
  1106. }
  1107. }
  1108. }
  1109. }
  1110. str = AMremoveCharsAndBlanks(str,symbol.input.length);
  1111. if (typeof symbol.invisible != "boolean" || !symbol.invisible) {
  1112. node = createMmlNode("mo",document.createTextNode(symbol.output));
  1113. newFrag.appendChild(node);
  1114. }
  1115. }
  1116. return [newFrag,str];
  1117. }
  1118. function parseMath(str,latex) {
  1119. var frag, node;
  1120. AMnestingDepth = 0;
  1121. //some basic cleanup for dealing with stuff editors like TinyMCE adds
  1122. str = str.replace(/&nbsp;/g,"");
  1123. str = str.replace(/&gt;/g,">");
  1124. str = str.replace(/&lt;/g,"<");
  1125. frag = AMparseExpr(str.replace(/^\s+/g,""),false)[0];
  1126. node = createMmlNode("mstyle",frag);
  1127. if (mathcolor != "") node.setAttribute("mathcolor",mathcolor);
  1128. if (mathfontsize != "") {
  1129. node.setAttribute("fontsize", mathfontsize);
  1130. node.setAttribute("mathsize", mathfontsize);
  1131. }
  1132. if (mathfontfamily != "") {
  1133. node.setAttribute("fontfamily", mathfontfamily);
  1134. node.setAttribute("mathvariant", mathfontfamily);
  1135. }
  1136. if (displaystyle) node.setAttribute("displaystyle","true");
  1137. node = createMmlNode("math",node);
  1138. if (showasciiformulaonhover) //fixed by djhsu so newline
  1139. node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko
  1140. return node;
  1141. }
  1142. /*
  1143. function strarr2docFrag(arr, linebreaks, latex) {
  1144. var newFrag=document.createDocumentFragment();
  1145. var expr = false;
  1146. for (var i=0; i<arr.length; i++) {
  1147. if (expr) newFrag.appendChild(parseMath(arr[i],latex));
  1148. else {
  1149. var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]);
  1150. newFrag.appendChild(createElementXHTML("span").
  1151. appendChild(document.createTextNode(arri[0])));
  1152. for (var j=1; j<arri.length; j++) {
  1153. newFrag.appendChild(createElementXHTML("p"));
  1154. newFrag.appendChild(createElementXHTML("span").
  1155. appendChild(document.createTextNode(arri[j])));
  1156. }
  1157. }
  1158. expr = !expr;
  1159. }
  1160. return newFrag;
  1161. }
  1162. function AMautomathrec(str) {
  1163. //formula is a space (or start of str) followed by a maximal sequence of *two* or more tokens, possibly separated by runs of digits and/or space.
  1164. //tokens are single letters (except a, A, I) and ASCIIMathML tokens
  1165. var texcommand = "\\\\[a-zA-Z]+|\\\\\\s|";
  1166. var ambigAMtoken = "\\b(?:oo|lim|ln|int|oint|del|grad|aleph|prod|prop|sinh|cosh|tanh|cos|sec|pi|tt|fr|sf|sube|supe|sub|sup|det|mod|gcd|lcm|min|max|vec|ddot|ul|chi|eta|nu|mu)(?![a-z])|";
  1167. var englishAMtoken = "\\b(?:sum|ox|log|sin|tan|dim|hat|bar|dot)(?![a-z])|";
  1168. var secondenglishAMtoken = "|\\bI\\b|\\bin\\b|\\btext\\b"; // took if and or not out
  1169. var simpleAMtoken = "NN|ZZ|QQ|RR|CC|TT|AA|EE|sqrt|dx|dy|dz|dt|xx|vv|uu|nn|bb|cc|csc|cot|alpha|beta|delta|Delta|epsilon|gamma|Gamma|kappa|lambda|Lambda|omega|phi|Phi|Pi|psi|Psi|rho|sigma|Sigma|tau|theta|Theta|xi|Xi|zeta"; // uuu nnn?
  1170. var letter = "[a-zA-HJ-Z](?=(?:[^a-zA-Z]|$|"+ambigAMtoken+englishAMtoken+simpleAMtoken+"))|";
  1171. var token = letter+texcommand+"\\d+|[-()[\\]{}+=*&^_%\\\@/<>,\\|!:;'~]|\\.(?!(?:\x20|$))|"+ambigAMtoken+englishAMtoken+simpleAMtoken;
  1172. var re = new RegExp("(^|\\s)((("+token+")\\s?)(("+token+secondenglishAMtoken+")\\s?)+)([,.?]?(?=\\s|$))","g");
  1173. str = str.replace(re," `$2`$7");
  1174. var arr = str.split(AMdelimiter1);
  1175. var re1 = new RegExp("(^|\\s)([b-zB-HJ-Z+*<>]|"+texcommand+ambigAMtoken+simpleAMtoken+")(\\s|\\n|$)","g");
  1176. var re2 = new RegExp("(^|\\s)([a-z]|"+texcommand+ambigAMtoken+simpleAMtoken+")([,.])","g"); // removed |\d+ for now
  1177. for (i=0; i<arr.length; i++) //single nonenglish tokens
  1178. if (i%2==0) {
  1179. arr[i] = arr[i].replace(re1," `$2`$3");
  1180. arr[i] = arr[i].replace(re2," `$2`$3");
  1181. arr[i] = arr[i].replace(/([{}[\]])/,"`$1`");
  1182. }
  1183. str = arr.join(AMdelimiter1);
  1184. str = str.replace(/((^|\s)\([a-zA-Z]{2,}.*?)\)`/g,"$1`)"); //fix parentheses
  1185. str = str.replace(/`(\((a\s|in\s))(.*?[a-zA-Z]{2,}\))/g,"$1`$3"); //fix parentheses
  1186. str = str.replace(/\sin`/g,"` in");
  1187. str = str.replace(/`(\(\w\)[,.]?(\s|\n|$))/g,"$1`");
  1188. str = str.replace(/`([0-9.]+|e.g|i.e)`(\.?)/gi,"$1$2");
  1189. str = str.replace(/`([0-9.]+:)`/g,"$1");
  1190. return str;
  1191. }
  1192. function processNodeR(n, linebreaks,latex) {
  1193. var mtch, str, arr, frg, i;
  1194. if (n.childNodes.length == 0) {
  1195. if ((n.nodeType!=8 || linebreaks) &&
  1196. n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" &&
  1197. n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA"
  1198. //&&
  1199. //n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE"
  1200. ) {
  1201. str = n.nodeValue;
  1202. if (!(str == null)) {
  1203. str = str.replace(/\r\n\r\n/g,"\n\n");
  1204. str = str.replace(/\x20+/g," ");
  1205. str = str.replace(/\s*\r\n/g," ");
  1206. if(latex) {
  1207. // DELIMITERS:
  1208. mtch = (str.indexOf("\$")==-1 ? false : true);
  1209. str = str.replace(/([^\\])\$/g,"$1 \$");
  1210. str = str.replace(/^\$/," \$"); // in case \$ at start of string
  1211. arr = str.split(" \$");
  1212. for (i=0; i<arr.length; i++)
  1213. arr[i]=arr[i].replace(/\\\$/g,"\$");
  1214. } else {
  1215. mtch = false;
  1216. str = str.replace(new RegExp(AMescape1, "g"),
  1217. function(){mtch = true; return "AMescape1"});
  1218. str = str.replace(/\\?end{?a?math}?/i,
  1219. function(){automathrecognize = false; mtch = true; return ""});
  1220. str = str.replace(/amath\b|\\begin{a?math}/i,
  1221. function(){automathrecognize = true; mtch = true; return ""});
  1222. arr = str.split(AMdelimiter1);
  1223. if (automathrecognize)
  1224. for (i=0; i<arr.length; i++)
  1225. if (i%2==0) arr[i] = AMautomathrec(arr[i]);
  1226. str = arr.join(AMdelimiter1);
  1227. arr = str.split(AMdelimiter1);
  1228. for (i=0; i<arr.length; i++) // this is a problem ************
  1229. arr[i]=arr[i].replace(/AMescape1/g,AMdelimiter1);
  1230. }
  1231. if (arr.length>1 || mtch) {
  1232. if (!noMathML) {
  1233. frg = strarr2docFrag(arr,n.nodeType==8,latex);
  1234. var len = frg.childNodes.length;
  1235. n.parentNode.replaceChild(frg,n);
  1236. return len-1;
  1237. } else return 0;
  1238. }
  1239. }
  1240. } else return 0;
  1241. } else if (n.nodeName!="math") {
  1242. for (i=0; i<n.childNodes.length; i++)
  1243. i += processNodeR(n.childNodes[i], linebreaks,latex);
  1244. }
  1245. return 0;
  1246. }
  1247. function AMprocessNode(n, linebreaks, spanclassAM) {
  1248. var frag,st;
  1249. if (spanclassAM!=null) {
  1250. frag = document.getElementsByTagName("span")
  1251. for (var i=0;i<frag.length;i++)
  1252. if (frag[i].className == "AM")
  1253. processNodeR(frag[i],linebreaks,false);
  1254. } else {
  1255. try {
  1256. st = n.innerHTML; // look for AMdelimiter on page
  1257. } catch(err) {}
  1258. //alert(st)
  1259. if (st==null || /amath\b|\\begin{a?math}/i.test(st) ||
  1260. st.indexOf(AMdelimiter1+" ")!=-1 || st.slice(-1)==AMdelimiter1 ||
  1261. st.indexOf(AMdelimiter1+"<")!=-1 || st.indexOf(AMdelimiter1+"\n")!=-1) {
  1262. processNodeR(n,linebreaks,false);
  1263. }
  1264. }
  1265. }
  1266. function generic(){
  1267. if(!init()) return;
  1268. if (translateOnLoad) {
  1269. translate();
  1270. }
  1271. };
  1272. //setup onload function
  1273. if(typeof window.addEventListener != 'undefined'){
  1274. //.. gecko, safari, konqueror and standard
  1275. window.addEventListener('load', generic, false);
  1276. }
  1277. else if(typeof document.addEventListener != 'undefined'){
  1278. //.. opera 7
  1279. document.addEventListener('load', generic, false);
  1280. }
  1281. else if(typeof window.attachEvent != 'undefined'){
  1282. //.. win/ie
  1283. window.attachEvent('onload', generic);
  1284. }else{
  1285. //.. mac/ie5 and anything else that gets this far
  1286. //if there's an existing onload function
  1287. if(typeof window.onload == 'function'){
  1288. //store it
  1289. var existing = onload;
  1290. //add new onload handler
  1291. window.onload = function(){
  1292. //call existing onload function
  1293. existing();
  1294. //call generic onload function
  1295. generic();
  1296. };
  1297. }else{
  1298. window.onload = generic;
  1299. }
  1300. }
  1301. //expose some functions to outside
  1302. asciimath.newcommand = newcommand;
  1303. asciimath.newsymbol = newsymbol;
  1304. asciimath.AMprocesssNode = AMprocessNode;
  1305. asciimath.parseMath = parseMath;
  1306. asciimath.translate = translate;
  1307. })();
  1308. */
  1309. /******************************************************************
  1310. *
  1311. * The previous section is ASCIIMathML.js Version 2.2
  1312. * (c) Peter Jipsen, used with permission.
  1313. *
  1314. ******************************************************************/
  1315. showasciiformulaonhover = false;
  1316. mathfontfamily = "";
  1317. mathcolor = "";
  1318. mathfontsize = "";
  1319. //
  1320. // Remove remapping of mathvariants to plane1 (MathJax handles that)
  1321. // Change functions to mi rather than mo (to get spacing right)
  1322. //
  1323. (function () {
  1324. for (var i = 0, m = AMsymbols.length; i < m; i++) {
  1325. if (AMsymbols[i].codes) {delete AMsymbols[i].codes}
  1326. if (AMsymbols[i].func) {AMsymbols[i].tag = "mi"}
  1327. }
  1328. })();
  1329. //
  1330. // Access to AsciiMath functions and values
  1331. //
  1332. ASCIIMATH.Augment({
  1333. AM: {
  1334. Init: function () {
  1335. displaystyle = ASCIIMATH.config.displaystyle;
  1336. // Old versions use the "decimal" option, so take it into account if it
  1337. // is defined by the user. See issue 384.
  1338. decimalsign = (ASCIIMATH.config.decimal || ASCIIMATH.config.decimalsign);
  1339. // unfix phi and varphi, if requested
  1340. if (!ASCIIMATH.config.fixphi) {
  1341. for (var i = 0, m = AMsymbols.length; i < m; i++) {
  1342. if (AMsymbols[i].input === "phi") {AMsymbols[i].output = "\u03C6"}
  1343. if (AMsymbols[i].input === "varphi") {AMsymbols[i].output = "\u03D5"; i = m}
  1344. }
  1345. }
  1346. INITASCIIMATH();
  1347. initSymbols();
  1348. },
  1349. Augment: function (def) {
  1350. for (var id in def) {if (def.hasOwnProperty(id)) {
  1351. switch (id) {
  1352. case "displaystyle": displaystyle = def[id]; break;
  1353. case "decimal": decimal = def[id]; break;
  1354. case "parseMath": parseMath = def[id]; break;
  1355. case "parseExpr": AMparseExpr = def[id]; break;
  1356. case "parseIexpr": AMparseIexpr = def[id]; break;
  1357. case "parseSexpr": AMparseSexpr = def[id]; break;
  1358. case "removeBrackets": AMremoveBrackets = def[id]; break;
  1359. case "getSymbol": AMgetSymbol = def[id]; break;
  1360. case "position": position = def[id]; break;
  1361. case "removeCharsAndBlanks": AMremoveCharsAndBlanks = def[id]; break;
  1362. case "createMmlNode": createMmlNode = def[id]; break;
  1363. case "createElementMathML": AMcreateElementMathML = def[id]; break;
  1364. case "createElementXHTML": createElementXHTML = def[id]; break;
  1365. case "initSymbols": initSymbols = def[id]; break;
  1366. case "refreshSymbols": refreshSymbols = def[id]; break;
  1367. case "compareNames": compareNames = def[id]; break;
  1368. };
  1369. this[id] = def[id];
  1370. }};
  1371. },
  1372. parseMath: parseMath,
  1373. parseExpr: AMparseExpr,
  1374. parseIexpr: AMparseIexpr,
  1375. parseSexr: AMparseSexpr,
  1376. removeBrackets: AMremoveBrackets,
  1377. getSymbol: AMgetSymbol,
  1378. position: position,
  1379. removeCharsAndBlanks: AMremoveCharsAndBlanks,
  1380. createMmlNode: createMmlNode,
  1381. createElementMathML: AMcreateElementMathML,
  1382. createElementXHTML: createElementXHTML,
  1383. initSymbols: initSymbols,
  1384. refreshSymbols: refreshSymbols,
  1385. compareNames: compareNames,
  1386. createDocumentFragment: DOCFRAG,
  1387. document: document,
  1388. define: define,
  1389. newcommand: newcommand,
  1390. newsymbol: newsymbol,
  1391. symbols: AMsymbols,
  1392. names: AMnames,
  1393. TOKEN: {
  1394. CONST:CONST, UNARY:UNARY, BINARY:BINARY, INFIX:INFIX,
  1395. LEFTBRACKET:LEFTBRACKET, RIGHTBRACKET:RIGHTBRACKET, SPACE:SPACE,
  1396. UNDEROVER:UNDEROVER, DEFINITION:DEFINITION, LEFTRIGHT:LEFTRIGHT, TEXT:TEXT,
  1397. UNARYUNDEROVER:UNARYUNDEROVER
  1398. }
  1399. }
  1400. });
  1401. //
  1402. // Make minimizer think these have been used
  1403. //
  1404. var junk = [window, navigator]; junk = null;
  1405. })(MathJax.InputJax.AsciiMath);
  1406. /************************************************************************/
  1407. (function (ASCIIMATH) {
  1408. var MML;
  1409. ASCIIMATH.Augment({
  1410. sourceMenuTitle: /*_(MathMenu)*/ ["AsciiMathInput","AsciiMath Input"],
  1411. annotationEncoding: "text/x-asciimath",
  1412. prefilterHooks: MathJax.Callback.Hooks(true), // hooks to run before processing AsciiMath
  1413. postfilterHooks: MathJax.Callback.Hooks(true), // hooks to run after processing AsciiMath
  1414. Translate: function (script) {
  1415. var mml, math = MathJax.HTML.getScript(script);
  1416. var data = {math:math, script:script};
  1417. var callback = this.prefilterHooks.Execute(data); if (callback) return callback;
  1418. math = data.math;
  1419. try {
  1420. mml = this.AM.parseMath(math);
  1421. } catch(err) {
  1422. if (!err.asciimathError) {throw err}
  1423. mml = this.formatError(err,math);
  1424. }
  1425. data.math = MML(mml); this.postfilterHooks.Execute(data);
  1426. return this.postfilterHooks.Execute(data) || data.math;
  1427. },
  1428. formatError: function (err,math,script) {
  1429. var message = err.message.replace(/\n.*/,"");
  1430. MathJax.Hub.signal.Post(["AsciiMath Jax - parse error",message,math,script]);
  1431. return MML.Error(message);
  1432. },
  1433. Error: function (message) {
  1434. throw MathJax.Hub.Insert(Error(message),{asciimathError: true});
  1435. },
  1436. //
  1437. // Initialize the MML variable and AsciiMath itself
  1438. //
  1439. Startup: function () {
  1440. MML = MathJax.ElementJax.mml;
  1441. this.AM.Init();
  1442. }
  1443. });
  1444. ASCIIMATH.loadComplete("jax.js");
  1445. })(MathJax.InputJax.AsciiMath);