Online editor: Preview tabs have been added to the dialogs for inserting video, flv-video, and YouTube video. (FS#2867)
Online editor: The audio plugin has been activated by default as an implementation of the "Insert audio / Audio properties" dialog. This new plugin is intended to replace the "MP3" plugin. (FS#2867)
Online editor: Configuration of the mimetex plugin has been reworked to gain simplicity. The procedure for configuration has been updated, see the related forum topic. (FS#2867)
+
Online editor: A new asciimath plugin for inserting mathematical formulas has been added. It is based on the ASCIIMathML.js library. (FS#2867)
Online editor: The toolbar icons have been upgraded to those from CKEditor 3.0. (FS#2867)
A solution has been implemented for fixing the "__flash__removeCallback" bug, which affects the media player on Internet Explorer browser. (FS#4378 and FS#2867)
Implement new sub-language feature by which language terms redefinition becomes possible through the admin section (FS#4321)
diff --git a/main/inc/global.inc.php b/main/inc/global.inc.php
index cf82f35b6e..1975614549 100644
--- a/main/inc/global.inc.php
+++ b/main/inc/global.inc.php
@@ -219,6 +219,7 @@ require_once($lib_path.'display.lib.php');
require_once($lib_path.'text.lib.php');
require_once($lib_path.'security.lib.php');
require_once($lib_path.'events.lib.inc.php');
+require_once($lib_path.'media.lib.php');
// @todo: this shouldn't be done here. It should be stored correctly during installation
if(empty($_configuration['statistics_database']) && $already_installed)
diff --git a/main/inc/lib/asciimath/ASCIIMathML.js b/main/inc/lib/asciimath/ASCIIMathML.js
new file mode 100644
index 0000000000..1086abcf61
--- /dev/null
+++ b/main/inc/lib/asciimath/ASCIIMathML.js
@@ -0,0 +1,3513 @@
+/*
+ASCIIMathML.js
+==============
+This file contains JavaScript functions to convert ASCII math notation
+and LaTeX to Presentation MathML. Simple graphics commands are also
+translated to SVG images. The conversion is done while the (X)HTML
+page loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet
+Explorer 6/7 + MathPlayer (http://www.dessci.com/en/products/mathplayer/) +
+Adobe SVGview 3.03 (http://www.adobe.com/svg/viewer/install/).
+
+Just add the next line to your (X)HTML page with this file in the same folder:
+
+
+
+(using the graphics in IE also requires the file "d.svg" in the same folder).
+This is a convenient and inexpensive solution for authoring MathML and SVG.
+
+Version 2.0.1 Sept 27, 2007, (c) Peter Jipsen http://www.chapman.edu/~jipsen
+This version extends ASCIIMathML.js with LaTeXMathML.js and ASCIIsvg.js.
+Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js
+If you use it on a webpage, please send the URL to jipsen@chapman.edu
+
+The LaTeXMathML modifications were made by Douglas Woodall, June 2006.
+(for details see header on the LaTeXMathML part in middle of file)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+(at http://www.gnu.org/licences/lgpl.html) for more details.
+*/
+
+var mathcolor = "blue"; // change it to "" (to inherit) or another color
+//var mathfontsize = "1em"; // change to e.g. 1.2em for larger math
+var mathfontsize = "1.2em"; // Modified by Ivan Tcholakov, 10-AUG-2009.
+var mathfontfamily = "serif"; // change to "" to inherit (works in IE)
+ // or another family (e.g. "arial")
+var automathrecognize = false; // writing "amath" on page makes this true
+var checkForMathML = true; // check if browser can display MathML
+var notifyIfNoMathML = true; // display note at top if no MathML capability
+var alertIfNoMathML = false; // show alert box if no MathML capability
+var translateOnLoad = true; // set to false to do call translators from js
+var translateLaTeX = true; // false to preserve $..$, $$..$$
+var translateLaTeXformatting = true; // false to preserve \emph,\begin{},\end{}
+var translateASCIIMath = true; // false to preserve `..`
+var translateASCIIsvg = true; // false to preserve agraph.., \begin{graph}..
+var avoidinnerHTML = false; // set true if assigning to innerHTML gives error
+var displaystyle = true; // puts limits above and below large operators
+var showasciiformulaonhover = true; // helps students learn ASCIIMath
+var decimalsign = "."; // change to "," if you like, beware of `(1,2)`!
+var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters
+var AMdocumentId = "wikitext" // PmWiki element containing math (default=body)
+var checkforprocessasciimathinmoodle = false; // true for systems like Moodle
+var dsvglocation = ""; // path to d.svg (blank if same as ASCIIMathML.js loc)
+
+var isIE = document.createElementNS==null;
+
+if (document.getElementById==null)
+ alert("This webpage requires a recent browser such as\
+\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer")
+
+// all further ASCIIMathML global variables start with "AM"
+
+function AMcreateElementXHTML(t) {
+ if (isIE) return document.createElement(t);
+ else return document.createElementNS("http://www.w3.org/1999/xhtml",t);
+}
+
+function AMnoMathMLNote() {
+ var nd = AMcreateElementXHTML("h3");
+ nd.setAttribute("align","center")
+ nd.appendChild(AMcreateElementXHTML("p"));
+ nd.appendChild(document.createTextNode("To view the "));
+ var an = AMcreateElementXHTML("a");
+ an.appendChild(document.createTextNode("ASCIIMathML"));
+ an.setAttribute("href","http://www.chapman.edu/~jipsen/asciimath.html");
+ nd.appendChild(an);
+ nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+"));
+ an = AMcreateElementXHTML("a");
+ an.appendChild(document.createTextNode("MathPlayer"));
+ an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");
+ nd.appendChild(an);
+ nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));
+ nd.appendChild(AMcreateElementXHTML("p"));
+ return nd;
+}
+
+function AMisMathMLavailable() {
+ if (navigator.appName.slice(0,8)=="Netscape")
+ if (navigator.appVersion.slice(0,1)>="5") return null;
+ else return AMnoMathMLNote();
+ else if (navigator.appName.slice(0,9)=="Microsoft")
+ try {
+ var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
+ return null;
+ } catch (e) {
+ return AMnoMathMLNote();
+ }
+ // Added by Ivan Tcholakov, 04-AUG-2009.
+ else if (navigator.appName=="Opera")
+ {
+ if ( parseFloat(navigator.appVersion, 10) >= 9.5 )
+ {
+ return null ;
+ }
+ else
+ {
+ return AMnoMathMLNote();
+ }
+ }
+ //
+ else return AMnoMathMLNote();
+}
+
+// character lists for Mozilla/Netscape fonts
+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];
+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];
+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];
+
+var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4,
+ RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8,
+ LEFTRIGHT = 9, TEXT = 10; // token types
+
+var AMsqrt = {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY},
+ AMroot = {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY},
+ AMfrac = {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY},
+ AMdiv = {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX},
+ AMover = {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY},
+ AMsub = {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX},
+ AMsup = {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX},
+ AMtext = {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT},
+ AMmbox = {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT},
+ AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT};
+
+var AMsymbols = [
+//some greek symbols
+{input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST},
+{input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST},
+{input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST},
+{input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST},
+{input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST},
+{input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST},
+{input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST},
+{input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST},
+{input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST},
+{input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST},
+{input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST},
+{input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST},
+{input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST},
+{input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST},
+{input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST},
+{input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST},
+{input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST},
+{input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST},
+{input:"phi", tag:"mi", output:"\u03C6", tex:null, ttype:CONST},
+{input:"varphi", tag:"mi", output:"\u03D5", tex:null, ttype:CONST},
+{input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST},
+{input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST},
+{input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST},
+{input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST},
+{input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST},
+{input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST},
+{input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST},
+{input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST},
+{input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST},
+{input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST},
+{input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST},
+{input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST},
+{input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST},
+{input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST},
+{input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST},
+{input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST},
+
+//binary operation symbols
+//{input:"-", tag:"mo", output:"\u0096", tex:null, ttype:CONST},
+{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST},
+{input:"**", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST},
+{input:"//", tag:"mo", output:"/", tex:null, ttype:CONST},
+{input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST},
+{input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST},
+{input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST},
+{input:"-:", tag:"mo", output:"\u00F7", tex:"divide", ttype:CONST},
+{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST},
+{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST},
+{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST},
+{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST},
+{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER},
+{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER},
+{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST},
+{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER},
+{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST},
+{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER},
+{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST},
+{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER},
+{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST},
+{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER},
+
+//binary relation symbols
+{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST},
+{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST},
+{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST},
+{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST},
+{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST},
+{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST},
+{input:"geq", tag:"mo", output:"\u2265", tex:null, ttype:CONST},
+{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST},
+{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST},
+{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST},
+{input:"-<=", tag:"mo", output:"\u2AAF", tex:"preceq", ttype:CONST},
+{input:">-=", tag:"mo", output:"\u2AB0", tex:"succeq", ttype:CONST},
+{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST},
+{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST},
+{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST},
+{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST},
+{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST},
+{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST},
+{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST},
+{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST},
+{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST},
+{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST},
+
+//logical symbols
+{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE},
+{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE},
+{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST},
+{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST},
+{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE},
+{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST},
+{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST},
+{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST},
+{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST},
+{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST},
+{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST},
+{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST},
+
+//grouping brackets
+{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET},
+{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET},
+{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET},
+{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET},
+{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET},
+{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET},
+{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT},
+//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT},
+{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET},
+{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET},
+{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET},
+{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET},
+{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true},
+{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true},
+
+//miscellaneous symbols
+{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST},
+{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION},
+{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION},
+{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION},
+{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION},
+{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST},
+{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST},
+{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST},
+{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST},
+{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST},
+{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST},
+{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST},
+{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST},
+{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST},
+{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST},
+{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST},
+{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST},
+{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST},
+{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST},
+{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST},
+{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST},
+{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST},
+{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST},
+{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST},
+{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST},
+{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST},
+{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST},
+{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST},
+{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST},
+{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST},
+{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST},
+{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST},
+{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true},
+{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true},
+
+//standard functions
+{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER},
+{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER},
+{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true},
+{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true},
+{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true},
+{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true},
+{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true},
+{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true},
+{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true},
+{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true},
+{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true},
+{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true},
+{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true},
+{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true},
+{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST},
+{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST},
+{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true},
+{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true},
+{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST},
+{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST},
+{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER},
+{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER},
+
+//arrows
+{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST},
+{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST},
+{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST},
+{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST},
+{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST},
+{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST},
+{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST},
+{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST},
+{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST},
+{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST},
+
+//commands with argument
+AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup,
+{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true},
+{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true},
+{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true},
+{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true},
+{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true},
+{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true},
+AMtext, AMmbox, AMquote,
+{input:"bb", tag:"mstyle", atname:"fontweight", atval:"bold", output:"bb", tex:null, ttype:UNARY},
+{input:"mathbf", tag:"mstyle", atname:"fontweight", atval:"bold", output:"mathbf", tex:null, ttype:UNARY},
+{input:"sf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY},
+{input:"mathsf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY},
+{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb},
+{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb},
+{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal},
+{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal},
+{input:"tt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"tt", tex:null, ttype:UNARY},
+{input:"mathtt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY},
+{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk},
+{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk}
+];
+
+function compareNames(s1,s2) {
+ if (s1.input > s2.input) return 1
+ else return -1;
+}
+
+var AMnames = []; //list of input symbols
+
+function AMinitSymbols() {
+ var texsymbols = [], i;
+ for (i=0; i=n where str appears or would be inserted
+// assumes arr is sorted
+ if (n==0) {
+ var h,m;
+ n = -1;
+ h = arr.length;
+ while (n+1> 1;
+ if (arr[m]=str
+}
+
+function AMgetSymbol(str) {
+//return maximal initial substring of str that appears in names
+//return null if there is none
+ var k = 0; //new pos
+ var j = 0; //old pos
+ var mk; //match pos
+ var st;
+ var tagst;
+ var match = "";
+ var more = true;
+ for (var i=1; i<=str.length && more; i++) {
+ st = str.slice(0,i); //initial substring of length i
+ j = k;
+ k = AMposition(AMnames, st, j);
+ if (k=AMnames[k];
+ }
+ AMpreviousSymbol=AMcurrentSymbol;
+ if (match!=""){
+ AMcurrentSymbol=AMsymbols[mk].ttype;
+ return AMsymbols[mk];
+ }
+// if str[0] is a digit or - return maxsubstring of digits.digits
+ AMcurrentSymbol=CONST;
+ k = 1;
+ st = str.slice(0,1);
+ var integ = true;
+ while ("0"<=st && st<="9" && k<=str.length) {
+ st = str.slice(k,k+1);
+ k++;
+ }
+ if (st == decimalsign) {
+ st = str.slice(k,k+1);
+ if ("0"<=st && st<="9") {
+ integ = false;
+ k++;
+ while ("0"<=st && st<="9" && k<=str.length) {
+ st = str.slice(k,k+1);
+ k++;
+ }
+ }
+ }
+ if ((integ && k>1) || k>2) {
+ st = str.slice(0,k-1);
+ tagst = "mn";
+ } else {
+ k = 2;
+ st = str.slice(0,1); //take 1 character
+ tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");
+ }
+ if (st=="-" && AMpreviousSymbol==INFIX) {
+ AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse
+ return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};
+ }
+ return {input:st, tag:tagst, output:st, ttype:CONST};
+}
+
+function AMremoveBrackets(node) {
+ var st;
+ if (node.nodeName=="mrow") {
+ st = node.firstChild.firstChild.nodeValue;
+ if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild);
+ }
+ if (node.nodeName=="mrow") {
+ st = node.lastChild.firstChild.nodeValue;
+ if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild);
+ }
+}
+
+/*Parsing ASCII math expressions with the following grammar
+v ::= [A-Za-z] | greek letters | numbers | other constant symbols
+u ::= sqrt | text | bb | other unary symbols for font commands
+b ::= frac | root | stackrel binary symbols
+l ::= ( | [ | { | (: | {: left brackets
+r ::= ) | ] | } | :) | :} right brackets
+S ::= v | lEr | uS | bSS Simple expression
+I ::= S_S | S^S | S_S^S | S Intermediate expression
+E ::= IE | I/I Expression
+Each terminal symbol is translated into a corresponding mathml node.*/
+
+var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol;
+
+function AMparseSexpr(str) { //parses str and returns [node,tailstr]
+ var symbol, node, result, i, st,// rightvert = false,
+ newFrag = document.createDocumentFragment();
+ str = AMremoveCharsAndBlanks(str,0);
+ symbol = AMgetSymbol(str); //either a token or a bracket or empty
+ if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) {
+ return [null,str];
+ }
+ if (symbol.ttype == DEFINITION) {
+ str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length);
+ symbol = AMgetSymbol(str);
+ }
+ switch (symbol.ttype) {
+ case UNDEROVER:
+ case CONST:
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ return [AMcreateMmlNode(symbol.tag, //its a constant
+ document.createTextNode(symbol.output)),str];
+ case LEFTBRACKET: //read (expr+)
+ AMnestingDepth++;
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ result = AMparseExpr(str,true);
+ AMnestingDepth--;
+ if (typeof symbol.invisible == "boolean" && symbol.invisible)
+ node = AMcreateMmlNode("mrow",result[0]);
+ else {
+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ node = AMcreateMmlNode("mrow",node);
+ node.appendChild(result[0]);
+ }
+ return [node,result[1]];
+ case TEXT:
+ if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ if (str.charAt(0)=="{") i=str.indexOf("}");
+ else if (str.charAt(0)=="(") i=str.indexOf(")");
+ else if (str.charAt(0)=="[") i=str.indexOf("]");
+ else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1;
+ else i = 0;
+ if (i==-1) i = str.length;
+ st = str.slice(1,i);
+ if (st.charAt(0) == " ") {
+ node = AMcreateElementMathML("mspace");
+ node.setAttribute("width","1ex");
+ newFrag.appendChild(node);
+ }
+ newFrag.appendChild(
+ AMcreateMmlNode(symbol.tag,document.createTextNode(st)));
+ if (st.charAt(st.length-1) == " ") {
+ node = AMcreateElementMathML("mspace");
+ node.setAttribute("width","1ex");
+ newFrag.appendChild(node);
+ }
+ str = AMremoveCharsAndBlanks(str,i+1);
+ return [AMcreateMmlNode("mrow",newFrag),str];
+ case UNARY:
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ result = AMparseSexpr(str);
+ if (result[0]==null) return [AMcreateMmlNode(symbol.tag,
+ document.createTextNode(symbol.output)),str];
+ if (typeof symbol.func == "boolean" && symbol.func) { // functions hack
+ st = str.charAt(0);
+ if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") {
+ return [AMcreateMmlNode(symbol.tag,
+ document.createTextNode(symbol.output)),str];
+ } else {
+ node = AMcreateMmlNode("mrow",
+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));
+ node.appendChild(result[0]);
+ return [node,result[1]];
+ }
+ }
+ AMremoveBrackets(result[0]);
+ if (symbol.input == "sqrt") { // sqrt
+ return [AMcreateMmlNode(symbol.tag,result[0]),result[1]];
+ } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent
+ node = AMcreateMmlNode(symbol.tag,result[0]);
+ node.appendChild(AMcreateMmlNode("mo",document.createTextNode(symbol.output)));
+ return [node,result[1]];
+ } else { // font change command
+ if (!isIE && typeof symbol.codes != "undefined") {
+ for (i=0; i64 && st.charCodeAt(j)<91) newst = newst +
+ String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);
+ else newst = newst + st.charAt(j);
+ if (result[0].nodeName=="mi")
+ result[0]=AMcreateElementMathML("mo").
+ appendChild(document.createTextNode(newst));
+ else result[0].replaceChild(AMcreateElementMathML("mo").
+ appendChild(document.createTextNode(newst)),result[0].childNodes[i]);
+ }
+ }
+ node = AMcreateMmlNode(symbol.tag,result[0]);
+ node.setAttribute(symbol.atname,symbol.atval);
+ return [node,result[1]];
+ }
+ case BINARY:
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ result = AMparseSexpr(str);
+ if (result[0]==null) return [AMcreateMmlNode("mo",
+ document.createTextNode(symbol.input)),str];
+ AMremoveBrackets(result[0]);
+ var result2 = AMparseSexpr(result[1]);
+ if (result2[0]==null) return [AMcreateMmlNode("mo",
+ document.createTextNode(symbol.input)),str];
+ AMremoveBrackets(result2[0]);
+ if (symbol.input=="root" || symbol.input=="stackrel")
+ newFrag.appendChild(result2[0]);
+ newFrag.appendChild(result[0]);
+ if (symbol.input=="frac") newFrag.appendChild(result2[0]);
+ return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]];
+ case INFIX:
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str];
+ case SPACE:
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ node = AMcreateElementMathML("mspace");
+ node.setAttribute("width","1ex");
+ newFrag.appendChild(node);
+ newFrag.appendChild(
+ AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));
+ node = AMcreateElementMathML("mspace");
+ node.setAttribute("width","1ex");
+ newFrag.appendChild(node);
+ return [AMcreateMmlNode("mrow",newFrag),str];
+ case LEFTRIGHT:
+// if (rightvert) return [null,str]; else rightvert = true;
+ AMnestingDepth++;
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ result = AMparseExpr(str,false);
+ AMnestingDepth--;
+ var st = "";
+ if (result[0].lastChild!=null)
+ st = result[0].lastChild.firstChild.nodeValue;
+ if (st == "|") { // its an absolute value subterm
+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ node = AMcreateMmlNode("mrow",node);
+ node.appendChild(result[0]);
+ return [node,result[1]];
+ } else { // the "|" is a \mid
+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ node = AMcreateMmlNode("mrow",node);
+ return [node,str];
+ }
+ default:
+//alert("default");
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ return [AMcreateMmlNode(symbol.tag, //its a constant
+ document.createTextNode(symbol.output)),str];
+ }
+}
+
+function AMparseIexpr(str) {
+ var symbol, sym1, sym2, node, result, underover;
+ str = AMremoveCharsAndBlanks(str,0);
+ sym1 = AMgetSymbol(str);
+ result = AMparseSexpr(str);
+ node = result[0];
+ str = result[1];
+ symbol = AMgetSymbol(str);
+ if (symbol.ttype == INFIX && symbol.input != "/") {
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+// if (symbol.input == "/") result = AMparseIexpr(str); else ...
+ result = AMparseSexpr(str);
+ if (result[0] == null) // show box in place of missing argument
+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));
+ else AMremoveBrackets(result[0]);
+ str = result[1];
+// if (symbol.input == "/") AMremoveBrackets(node);
+ if (symbol.input == "_") {
+ sym2 = AMgetSymbol(str);
+ underover = (sym1.ttype == UNDEROVER);
+ if (sym2.input == "^") {
+ str = AMremoveCharsAndBlanks(str,sym2.input.length);
+ var res2 = AMparseSexpr(str);
+ AMremoveBrackets(res2[0]);
+ str = res2[1];
+ node = AMcreateMmlNode((underover?"munderover":"msubsup"),node);
+ node.appendChild(result[0]);
+ node.appendChild(res2[0]);
+ node = AMcreateMmlNode("mrow",node); // so sum does not stretch
+ } else {
+ node = AMcreateMmlNode((underover?"munder":"msub"),node);
+ node.appendChild(result[0]);
+ }
+ } else {
+ node = AMcreateMmlNode(symbol.tag,node);
+ node.appendChild(result[0]);
+ }
+ }
+ return [node,str];
+}
+
+function AMparseExpr(str,rightbracket) {
+ var symbol, node, result, i, nodeList = [],
+ newFrag = document.createDocumentFragment();
+ do {
+ str = AMremoveCharsAndBlanks(str,0);
+ result = AMparseIexpr(str);
+ node = result[0];
+ str = result[1];
+ symbol = AMgetSymbol(str);
+ if (symbol.ttype == INFIX && symbol.input == "/") {
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ result = AMparseIexpr(str);
+ if (result[0] == null) // show box in place of missing argument
+ result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1"));
+ else AMremoveBrackets(result[0]);
+ str = result[1];
+ AMremoveBrackets(node);
+ node = AMcreateMmlNode(symbol.tag,node);
+ node.appendChild(result[0]);
+ newFrag.appendChild(node);
+ symbol = AMgetSymbol(str);
+ }
+ else if (node!=undefined) newFrag.appendChild(node);
+ } while ((symbol.ttype != RIGHTBRACKET &&
+ (symbol.ttype != LEFTRIGHT || rightbracket)
+ || AMnestingDepth == 0) && symbol!=null && symbol.output!="");
+ if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) {
+// if (AMnestingDepth > 0) AMnestingDepth--;
+ var len = newFrag.childNodes.length;
+ if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 &&
+ newFrag.childNodes[len-2].nodeName == "mo" &&
+ newFrag.childNodes[len-2].firstChild.nodeValue == ",") { //matrix
+ var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue;
+ if (right==")" || right=="]") {
+ var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue;
+ if (left=="(" && right==")" && symbol.output != "}" ||
+ left=="[" && right=="]") {
+ var pos = []; // positions of commas
+ var matrix = true;
+ var m = newFrag.childNodes.length;
+ for (i=0; matrix && i1) matrix = pos[i].length == pos[i-2].length;
+ }
+ if (matrix) {
+ var row, frag, n, k, table = document.createDocumentFragment();
+ for (i=0; i(-,-,...,-,-)
+ n = node.childNodes.length;
+ k = 0;
+ node.removeChild(node.firstChild); //remove (
+ for (j=1; j2) {
+ newFrag.removeChild(newFrag.firstChild); //remove )
+ newFrag.removeChild(newFrag.firstChild); //remove ,
+ }
+ table.appendChild(AMcreateMmlNode("mtr",row));
+ }
+ node = AMcreateMmlNode("mtable",table);
+ if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left");
+ newFrag.replaceChild(node,newFrag.firstChild);
+ }
+ }
+ }
+ }
+ str = AMremoveCharsAndBlanks(str,symbol.input.length);
+ if (typeof symbol.invisible != "boolean" || !symbol.invisible) {
+ node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ newFrag.appendChild(node);
+ }
+ }
+ return [newFrag,str];
+}
+
+function AMparseMath(str) {
+ var result, node = AMcreateElementMathML("mstyle");
+ if (mathcolor != "") node.setAttribute("mathcolor",mathcolor);
+ if (displaystyle) node.setAttribute("displaystyle","true");
+ if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily);
+ AMnestingDepth = 0;
+ node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false)[0]);
+ node = AMcreateMmlNode("math",node);
+ if (showasciiformulaonhover) //fixed by djhsu so newline
+ node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko
+ var fnode = AMcreateElementXHTML("span");
+ fnode.style.fontSize = mathfontsize;
+ if (mathfontfamily != "") fnode.style.fontFamily = mathfontfamily;
+ fnode.appendChild(node);
+ return fnode;
+}
+
+function AMstrarr2docFrag(arr, linebreaks) {
+ var newFrag=document.createDocumentFragment();
+ var expr = false;
+ for (var i=0; i,\\|!:;'~]|\\.(?!(?:\x20|$))|"+ambigAMtoken+englishAMtoken+simpleAMtoken;
+ var re = new RegExp("(^|\\s)((("+token+")\\s?)(("+token+secondenglishAMtoken+")\\s?)+)([,.?]?(?=\\s|$))","g");
+ str = str.replace(re," `$2`$7");
+ var arr = str.split(AMdelimiter1);
+ var re1 = new RegExp("(^|\\s)([b-zB-HJ-Z+*<>]|"+texcommand+ambigAMtoken+simpleAMtoken+")(\\s|\\n|$)","g");
+ var re2 = new RegExp("(^|\\s)([a-z]|"+texcommand+ambigAMtoken+simpleAMtoken+")([,.])","g"); // removed |\d+ for now
+ for (i=0; i1 || mtch) {
+ if (checkForMathML) {
+ checkForMathML = false;
+ var nd = AMisMathMLavailable();
+ AMnoMathML = nd != null;
+ if (AMnoMathML && notifyIfNoMathML)
+ if (alertIfNoMathML)
+ alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\
+ or Firefox/Mozilla/Netscape");
+ else AMbody.insertBefore(nd,AMbody.childNodes[0]);
+ }
+ if (!AMnoMathML) {
+ frg = AMstrarr2docFrag(arr,n.nodeType==8);
+ var len = frg.childNodes.length;
+ n.parentNode.replaceChild(frg,n);
+ return len-1;
+ } else return 0;
+ }
+ }
+ } else return 0;
+ } else if (n.nodeName!="math") {
+ for (i=0; i
+This is a convenient and inexpensive solution for authoring MathML.
+
+Version 1.4.7 Dec 15, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen
+Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js
+For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt
+If you use it on a webpage, please send the URL to jipsen@chapman.edu
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at
+your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+General Public License (at http://www.gnu.org/license/lgpl.html)
+for more details.
+
+LaTeXMathML.js (ctd)
+==============
+
+Content between $...$ and $$...$$ is converted by this part of the file
+*/
+
+var LMcheckForMathML = true; // check if browser can display MathML
+var LMnotifyIfNoMathML = true; // display note if no MathML capability
+var LMalertIfNoMathML = false; // show alert box if no MathML capability
+var LMmathcolor = ""; // "" (to inherit) or change to another color
+var LMmathfontfamily = "serif"; // change to "" to inherit (works in IE)
+ // or another family (e.g. "arial")
+var LMshowasciiformulaonhover = true; // helps students learn LaTeX
+
+// all further global variables start with "LM"
+
+function LMcreateElementXHTML(t) {
+ if (isIE) return document.createElement(t);
+ else return document.createElementNS("http://www.w3.org/1999/xhtml",t);
+}
+
+function LMnoMathMLNote() {
+ var nd = LMcreateElementXHTML("h3");
+ nd.setAttribute("align","center")
+ nd.appendChild(LMcreateElementXHTML("p"));
+ nd.appendChild(document.createTextNode("To view the "));
+ var an = LMcreateElementXHTML("a");
+ an.appendChild(document.createTextNode("LaTeXMathML"));
+ an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html");
+ nd.appendChild(an);
+ nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+"));
+ an = LMcreateElementXHTML("a");
+ an.appendChild(document.createTextNode("MathPlayer"));
+ an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm");
+ nd.appendChild(an);
+ nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));
+ nd.appendChild(LMcreateElementXHTML("p"));
+ return nd;
+}
+
+function LMisMathMLavailable() {
+ if (navigator.appName.slice(0,8)=="Netscape")
+ if (navigator.appVersion.slice(0,1)>="5") return null;
+ else return LMnoMathMLNote();
+ else if (navigator.appName.slice(0,9)=="Microsoft")
+ try {
+ var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
+ return null;
+ } catch (e) {
+ return LMnoMathMLNote();
+ }
+ else return LMnoMathMLNote();
+}
+
+// character lists for Mozilla/Netscape fonts
+var LMcal = [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];
+var LMfrk = [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];
+var LMbbb = [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];
+
+//var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4,
+// RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, TEXT = 10,
+var BIG = 11, LONG = 12, STRETCHY = 13, MATRIX = 14; // token types
+
+var LMsqrt = {input:"\\sqrt", tag:"msqrt", output:"sqrt", ttype:UNARY},
+ LMroot = {input:"\\root", tag:"mroot", output:"root", ttype:BINARY},
+ LMfrac = {input:"\\frac", tag:"mfrac", output:"/", ttype:BINARY},
+ LMover = {input:"\\stackrel", tag:"mover", output:"stackrel", ttype:BINARY},
+ LMatop = {input:"\\atop", tag:"mfrac", output:"", ttype:INFIX},
+ LMchoose = {input:"\\choose", tag:"mfrac", output:"", ttype:INFIX},
+ LMsub = {input:"_", tag:"msub", output:"_", ttype:INFIX},
+ LMsup = {input:"^", tag:"msup", output:"^", ttype:INFIX},
+ LMtext = {input:"\\mathrm", tag:"mtext", output:"text", ttype:TEXT},
+ LMmbox = {input:"\\mbox", tag:"mtext", output:"mbox", ttype:TEXT};
+
+// Commented out by DRW to prevent 1/2 turning into a 2-line fraction
+// LMdiv = {input:"/", tag:"mfrac", output:"/", ttype:INFIX},
+// Commented out by DRW so that " prints literally in equations
+// LMquote = {input:"\"", tag:"mtext", output:"mbox", ttype:TEXT};
+
+var LMsymbols = [
+//Greek letters
+{input:"\\alpha", tag:"mi", output:"\u03B1", ttype:CONST},
+{input:"\\beta", tag:"mi", output:"\u03B2", ttype:CONST},
+{input:"\\gamma", tag:"mi", output:"\u03B3", ttype:CONST},
+{input:"\\delta", tag:"mi", output:"\u03B4", ttype:CONST},
+{input:"\\epsilon", tag:"mi", output:"\u03B5", ttype:CONST},
+{input:"\\varepsilon", tag:"mi", output:"\u025B", ttype:CONST},
+{input:"\\zeta", tag:"mi", output:"\u03B6", ttype:CONST},
+{input:"\\eta", tag:"mi", output:"\u03B7", ttype:CONST},
+{input:"\\theta", tag:"mi", output:"\u03B8", ttype:CONST},
+{input:"\\vartheta", tag:"mi", output:"\u03D1", ttype:CONST},
+{input:"\\iota", tag:"mi", output:"\u03B9", ttype:CONST},
+{input:"\\kappa", tag:"mi", output:"\u03BA", ttype:CONST},
+{input:"\\lambda", tag:"mi", output:"\u03BB", ttype:CONST},
+{input:"\\mu", tag:"mi", output:"\u03BC", ttype:CONST},
+{input:"\\nu", tag:"mi", output:"\u03BD", ttype:CONST},
+{input:"\\xi", tag:"mi", output:"\u03BE", ttype:CONST},
+{input:"\\pi", tag:"mi", output:"\u03C0", ttype:CONST},
+{input:"\\varpi", tag:"mi", output:"\u03D6", ttype:CONST},
+{input:"\\rho", tag:"mi", output:"\u03C1", ttype:CONST},
+{input:"\\varrho", tag:"mi", output:"\u03F1", ttype:CONST},
+{input:"\\varsigma", tag:"mi", output:"\u03C2", ttype:CONST},
+{input:"\\sigma", tag:"mi", output:"\u03C3", ttype:CONST},
+{input:"\\tau", tag:"mi", output:"\u03C4", ttype:CONST},
+{input:"\\upsilon", tag:"mi", output:"\u03C5", ttype:CONST},
+{input:"\\phi", tag:"mi", output:"\u03C6", ttype:CONST},
+{input:"\\varphi", tag:"mi", output:"\u03D5", ttype:CONST},
+{input:"\\chi", tag:"mi", output:"\u03C7", ttype:CONST},
+{input:"\\psi", tag:"mi", output:"\u03C8", ttype:CONST},
+{input:"\\omega", tag:"mi", output:"\u03C9", ttype:CONST},
+{input:"\\Gamma", tag:"mo", output:"\u0393", ttype:CONST},
+{input:"\\Delta", tag:"mo", output:"\u0394", ttype:CONST},
+{input:"\\Theta", tag:"mo", output:"\u0398", ttype:CONST},
+{input:"\\Lambda", tag:"mo", output:"\u039B", ttype:CONST},
+{input:"\\Xi", tag:"mo", output:"\u039E", ttype:CONST},
+{input:"\\Pi", tag:"mo", output:"\u03A0", ttype:CONST},
+{input:"\\Sigma", tag:"mo", output:"\u03A3", ttype:CONST},
+{input:"\\Upsilon", tag:"mo", output:"\u03A5", ttype:CONST},
+{input:"\\Phi", tag:"mo", output:"\u03A6", ttype:CONST},
+{input:"\\Psi", tag:"mo", output:"\u03A8", ttype:CONST},
+{input:"\\Omega", tag:"mo", output:"\u03A9", ttype:CONST},
+
+//fractions
+{input:"\\frac12", tag:"mo", output:"\u00BD", ttype:CONST},
+{input:"\\frac14", tag:"mo", output:"\u00BC", ttype:CONST},
+{input:"\\frac34", tag:"mo", output:"\u00BE", ttype:CONST},
+{input:"\\frac13", tag:"mo", output:"\u2153", ttype:CONST},
+{input:"\\frac23", tag:"mo", output:"\u2154", ttype:CONST},
+{input:"\\frac15", tag:"mo", output:"\u2155", ttype:CONST},
+{input:"\\frac25", tag:"mo", output:"\u2156", ttype:CONST},
+{input:"\\frac35", tag:"mo", output:"\u2157", ttype:CONST},
+{input:"\\frac45", tag:"mo", output:"\u2158", ttype:CONST},
+{input:"\\frac16", tag:"mo", output:"\u2159", ttype:CONST},
+{input:"\\frac56", tag:"mo", output:"\u215A", ttype:CONST},
+{input:"\\frac18", tag:"mo", output:"\u215B", ttype:CONST},
+{input:"\\frac38", tag:"mo", output:"\u215C", ttype:CONST},
+{input:"\\frac58", tag:"mo", output:"\u215D", ttype:CONST},
+{input:"\\frac78", tag:"mo", output:"\u215E", ttype:CONST},
+
+//binary operation symbols
+{input:"\\pm", tag:"mo", output:"\u00B1", ttype:CONST},
+{input:"\\mp", tag:"mo", output:"\u2213", ttype:CONST},
+{input:"\\triangleleft",tag:"mo", output:"\u22B2", ttype:CONST},
+{input:"\\triangleright",tag:"mo",output:"\u22B3", ttype:CONST},
+{input:"\\cdot", tag:"mo", output:"\u22C5", ttype:CONST},
+{input:"\\star", tag:"mo", output:"\u22C6", ttype:CONST},
+{input:"\\ast", tag:"mo", output:"\u002A", ttype:CONST},
+{input:"\\times", tag:"mo", output:"\u00D7", ttype:CONST},
+{input:"\\div", tag:"mo", output:"\u00F7", ttype:CONST},
+{input:"\\circ", tag:"mo", output:"\u2218", ttype:CONST},
+//{input:"\\bullet", tag:"mo", output:"\u2219", ttype:CONST},
+{input:"\\bullet", tag:"mo", output:"\u2022", ttype:CONST},
+{input:"\\oplus", tag:"mo", output:"\u2295", ttype:CONST},
+{input:"\\ominus", tag:"mo", output:"\u2296", ttype:CONST},
+{input:"\\otimes", tag:"mo", output:"\u2297", ttype:CONST},
+{input:"\\bigcirc", tag:"mo", output:"\u25CB", ttype:CONST},
+{input:"\\oslash", tag:"mo", output:"\u2298", ttype:CONST},
+{input:"\\odot", tag:"mo", output:"\u2299", ttype:CONST},
+{input:"\\land", tag:"mo", output:"\u2227", ttype:CONST},
+{input:"\\wedge", tag:"mo", output:"\u2227", ttype:CONST},
+{input:"\\lor", tag:"mo", output:"\u2228", ttype:CONST},
+{input:"\\vee", tag:"mo", output:"\u2228", ttype:CONST},
+{input:"\\cap", tag:"mo", output:"\u2229", ttype:CONST},
+{input:"\\cup", tag:"mo", output:"\u222A", ttype:CONST},
+{input:"\\sqcap", tag:"mo", output:"\u2293", ttype:CONST},
+{input:"\\sqcup", tag:"mo", output:"\u2294", ttype:CONST},
+{input:"\\uplus", tag:"mo", output:"\u228E", ttype:CONST},
+{input:"\\amalg", tag:"mo", output:"\u2210", ttype:CONST},
+{input:"\\bigtriangleup",tag:"mo",output:"\u25B3", ttype:CONST},
+{input:"\\bigtriangledown",tag:"mo",output:"\u25BD", ttype:CONST},
+{input:"\\dag", tag:"mo", output:"\u2020", ttype:CONST},
+{input:"\\dagger", tag:"mo", output:"\u2020", ttype:CONST},
+{input:"\\ddag", tag:"mo", output:"\u2021", ttype:CONST},
+{input:"\\ddagger", tag:"mo", output:"\u2021", ttype:CONST},
+{input:"\\lhd", tag:"mo", output:"\u22B2", ttype:CONST},
+{input:"\\rhd", tag:"mo", output:"\u22B3", ttype:CONST},
+{input:"\\unlhd", tag:"mo", output:"\u22B4", ttype:CONST},
+{input:"\\unrhd", tag:"mo", output:"\u22B5", ttype:CONST},
+
+
+//BIG Operators
+{input:"\\sum", tag:"mo", output:"\u2211", ttype:UNDEROVER},
+{input:"\\prod", tag:"mo", output:"\u220F", ttype:UNDEROVER},
+{input:"\\bigcap", tag:"mo", output:"\u22C2", ttype:UNDEROVER},
+{input:"\\bigcup", tag:"mo", output:"\u22C3", ttype:UNDEROVER},
+{input:"\\bigwedge", tag:"mo", output:"\u22C0", ttype:UNDEROVER},
+{input:"\\bigvee", tag:"mo", output:"\u22C1", ttype:UNDEROVER},
+{input:"\\bigsqcap", tag:"mo", output:"\u2A05", ttype:UNDEROVER},
+{input:"\\bigsqcup", tag:"mo", output:"\u2A06", ttype:UNDEROVER},
+{input:"\\coprod", tag:"mo", output:"\u2210", ttype:UNDEROVER},
+{input:"\\bigoplus", tag:"mo", output:"\u2A01", ttype:UNDEROVER},
+{input:"\\bigotimes", tag:"mo", output:"\u2A02", ttype:UNDEROVER},
+{input:"\\bigodot", tag:"mo", output:"\u2A00", ttype:UNDEROVER},
+{input:"\\biguplus", tag:"mo", output:"\u2A04", ttype:UNDEROVER},
+{input:"\\int", tag:"mo", output:"\u222B", ttype:CONST},
+{input:"\\oint", tag:"mo", output:"\u222E", ttype:CONST},
+
+//binary relation symbols
+{input:":=", tag:"mo", output:":=", ttype:CONST},
+{input:"\\lt", tag:"mo", output:"<", ttype:CONST},
+{input:"\\gt", tag:"mo", output:">", ttype:CONST},
+{input:"\\ne", tag:"mo", output:"\u2260", ttype:CONST},
+{input:"\\neq", tag:"mo", output:"\u2260", ttype:CONST},
+{input:"\\le", tag:"mo", output:"\u2264", ttype:CONST},
+{input:"\\leq", tag:"mo", output:"\u2264", ttype:CONST},
+{input:"\\leqslant", tag:"mo", output:"\u2264", ttype:CONST},
+{input:"\\ge", tag:"mo", output:"\u2265", ttype:CONST},
+{input:"\\geq", tag:"mo", output:"\u2265", ttype:CONST},
+{input:"\\geqslant", tag:"mo", output:"\u2265", ttype:CONST},
+{input:"\\equiv", tag:"mo", output:"\u2261", ttype:CONST},
+{input:"\\ll", tag:"mo", output:"\u226A", ttype:CONST},
+{input:"\\gg", tag:"mo", output:"\u226B", ttype:CONST},
+{input:"\\doteq", tag:"mo", output:"\u2250", ttype:CONST},
+{input:"\\prec", tag:"mo", output:"\u227A", ttype:CONST},
+{input:"\\succ", tag:"mo", output:"\u227B", ttype:CONST},
+{input:"\\preceq", tag:"mo", output:"\u227C", ttype:CONST},
+{input:"\\succeq", tag:"mo", output:"\u227D", ttype:CONST},
+{input:"\\subset", tag:"mo", output:"\u2282", ttype:CONST},
+{input:"\\supset", tag:"mo", output:"\u2283", ttype:CONST},
+{input:"\\subseteq", tag:"mo", output:"\u2286", ttype:CONST},
+{input:"\\supseteq", tag:"mo", output:"\u2287", ttype:CONST},
+{input:"\\sqsubset", tag:"mo", output:"\u228F", ttype:CONST},
+{input:"\\sqsupset", tag:"mo", output:"\u2290", ttype:CONST},
+{input:"\\sqsubseteq", tag:"mo", output:"\u2291", ttype:CONST},
+{input:"\\sqsupseteq", tag:"mo", output:"\u2292", ttype:CONST},
+{input:"\\sim", tag:"mo", output:"\u223C", ttype:CONST},
+{input:"\\simeq", tag:"mo", output:"\u2243", ttype:CONST},
+{input:"\\approx", tag:"mo", output:"\u2248", ttype:CONST},
+{input:"\\cong", tag:"mo", output:"\u2245", ttype:CONST},
+{input:"\\Join", tag:"mo", output:"\u22C8", ttype:CONST},
+{input:"\\bowtie", tag:"mo", output:"\u22C8", ttype:CONST},
+{input:"\\in", tag:"mo", output:"\u2208", ttype:CONST},
+{input:"\\ni", tag:"mo", output:"\u220B", ttype:CONST},
+{input:"\\owns", tag:"mo", output:"\u220B", ttype:CONST},
+{input:"\\propto", tag:"mo", output:"\u221D", ttype:CONST},
+{input:"\\vdash", tag:"mo", output:"\u22A2", ttype:CONST},
+{input:"\\dashv", tag:"mo", output:"\u22A3", ttype:CONST},
+{input:"\\models", tag:"mo", output:"\u22A8", ttype:CONST},
+{input:"\\perp", tag:"mo", output:"\u22A5", ttype:CONST},
+{input:"\\smile", tag:"mo", output:"\u2323", ttype:CONST},
+{input:"\\frown", tag:"mo", output:"\u2322", ttype:CONST},
+{input:"\\asymp", tag:"mo", output:"\u224D", ttype:CONST},
+{input:"\\notin", tag:"mo", output:"\u2209", ttype:CONST},
+
+//matrices
+{input:"\\begin{eqnarray}", output:"X", ttype:MATRIX, invisible:true},
+{input:"\\begin{array}", output:"X", ttype:MATRIX, invisible:true},
+{input:"\\\\", output:"}&{", ttype:DEFINITION},
+{input:"\\end{eqnarray}", output:"}}", ttype:DEFINITION},
+{input:"\\end{array}", output:"}}", ttype:DEFINITION},
+
+//grouping and literal brackets -- ieval is for IE
+{input:"\\big", tag:"mo", output:"X", atval:"1.2", ieval:"2.2", ttype:BIG},
+{input:"\\Big", tag:"mo", output:"X", atval:"1.6", ieval:"2.6", ttype:BIG},
+{input:"\\bigg", tag:"mo", output:"X", atval:"2.2", ieval:"3.2", ttype:BIG},
+{input:"\\Bigg", tag:"mo", output:"X", atval:"2.9", ieval:"3.9", ttype:BIG},
+{input:"\\left", tag:"mo", output:"X", ttype:LEFTBRACKET},
+{input:"\\right", tag:"mo", output:"X", ttype:RIGHTBRACKET},
+{input:"{", output:"{", ttype:LEFTBRACKET, invisible:true},
+{input:"}", output:"}", ttype:RIGHTBRACKET, invisible:true},
+
+{input:"(", tag:"mo", output:"(", atval:"1", ttype:STRETCHY},
+{input:"[", tag:"mo", output:"[", atval:"1", ttype:STRETCHY},
+{input:"\\lbrack", tag:"mo", output:"[", atval:"1", ttype:STRETCHY},
+{input:"\\{", tag:"mo", output:"{", atval:"1", ttype:STRETCHY},
+{input:"\\lbrace", tag:"mo", output:"{", atval:"1", ttype:STRETCHY},
+{input:"\\langle", tag:"mo", output:"\u2329", atval:"1", ttype:STRETCHY},
+{input:"\\lfloor", tag:"mo", output:"\u230A", atval:"1", ttype:STRETCHY},
+{input:"\\lceil", tag:"mo", output:"\u2308", atval:"1", ttype:STRETCHY},
+
+// rtag:"mi" causes space to be inserted before a following sin, cos, etc.
+// (see function LMparseExpr() )
+{input:")", tag:"mo",output:")", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"]", tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\rbrack",tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\}", tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\rbrace",tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\rangle",tag:"mo",output:"\u232A", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\rfloor",tag:"mo",output:"\u230B", rtag:"mi",atval:"1",ttype:STRETCHY},
+{input:"\\rceil", tag:"mo",output:"\u2309", rtag:"mi",atval:"1",ttype:STRETCHY},
+
+// "|", "\\|", "\\vert" and "\\Vert" modified later: lspace = rspace = 0em
+{input:"|", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY},
+{input:"\\|", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY},
+{input:"\\vert", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY},
+{input:"\\Vert", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY},
+{input:"\\mid", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY},
+{input:"\\parallel", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY},
+{input:"/", tag:"mo", output:"/", atval:"1.01", ttype:STRETCHY},
+{input:"\\backslash", tag:"mo", output:"\u2216", atval:"1", ttype:STRETCHY},
+{input:"\\setminus", tag:"mo", output:"\\", ttype:CONST},
+
+//miscellaneous symbols
+{input:"\\!", tag:"mspace", atname:"width", atval:"-0.167em", ttype:SPACE},
+{input:"\\,", tag:"mspace", atname:"width", atval:"0.167em", ttype:SPACE},
+{input:"\\>", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE},
+{input:"\\:", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE},
+{input:"\\;", tag:"mspace", atname:"width", atval:"0.278em", ttype:SPACE},
+{input:"~", tag:"mspace", atname:"width", atval:"0.333em", ttype:SPACE},
+{input:"\\quad", tag:"mspace", atname:"width", atval:"1em", ttype:SPACE},
+{input:"\\qquad", tag:"mspace", atname:"width", atval:"2em", ttype:SPACE},
+//{input:"{}", tag:"mo", output:"\u200B", ttype:CONST}, // zero-width
+{input:"\\prime", tag:"mo", output:"\u2032", ttype:CONST},
+{input:"'", tag:"mo", output:"\u02B9", ttype:CONST},
+{input:"''", tag:"mo", output:"\u02BA", ttype:CONST},
+{input:"'''", tag:"mo", output:"\u2034", ttype:CONST},
+{input:"''''", tag:"mo", output:"\u2057", ttype:CONST},
+{input:"\\ldots", tag:"mo", output:"\u2026", ttype:CONST},
+{input:"\\cdots", tag:"mo", output:"\u22EF", ttype:CONST},
+{input:"\\vdots", tag:"mo", output:"\u22EE", ttype:CONST},
+{input:"\\ddots", tag:"mo", output:"\u22F1", ttype:CONST},
+{input:"\\forall", tag:"mo", output:"\u2200", ttype:CONST},
+{input:"\\exists", tag:"mo", output:"\u2203", ttype:CONST},
+{input:"\\Re", tag:"mo", output:"\u211C", ttype:CONST},
+{input:"\\Im", tag:"mo", output:"\u2111", ttype:CONST},
+{input:"\\aleph", tag:"mo", output:"\u2135", ttype:CONST},
+{input:"\\hbar", tag:"mo", output:"\u210F", ttype:CONST},
+{input:"\\ell", tag:"mo", output:"\u2113", ttype:CONST},
+{input:"\\wp", tag:"mo", output:"\u2118", ttype:CONST},
+{input:"\\emptyset", tag:"mo", output:"\u2205", ttype:CONST},
+{input:"\\infty", tag:"mo", output:"\u221E", ttype:CONST},
+{input:"\\surd", tag:"mo", output:"\\sqrt{}", ttype:DEFINITION},
+{input:"\\partial", tag:"mo", output:"\u2202", ttype:CONST},
+{input:"\\nabla", tag:"mo", output:"\u2207", ttype:CONST},
+{input:"\\triangle", tag:"mo", output:"\u25B3", ttype:CONST},
+{input:"\\therefore", tag:"mo", output:"\u2234", ttype:CONST},
+{input:"\\angle", tag:"mo", output:"\u2220", ttype:CONST},
+//{input:"\\\\ ", tag:"mo", output:"\u00A0", ttype:CONST},
+{input:"\\diamond", tag:"mo", output:"\u22C4", ttype:CONST},
+//{input:"\\Diamond", tag:"mo", output:"\u25CA", ttype:CONST},
+{input:"\\Diamond", tag:"mo", output:"\u25C7", ttype:CONST},
+{input:"\\neg", tag:"mo", output:"\u00AC", ttype:CONST},
+{input:"\\lnot", tag:"mo", output:"\u00AC", ttype:CONST},
+{input:"\\bot", tag:"mo", output:"\u22A5", ttype:CONST},
+{input:"\\top", tag:"mo", output:"\u22A4", ttype:CONST},
+{input:"\\square", tag:"mo", output:"\u25AB", ttype:CONST},
+{input:"\\Box", tag:"mo", output:"\u25A1", ttype:CONST},
+{input:"\\wr", tag:"mo", output:"\u2240", ttype:CONST},
+
+//standard functions
+//Note UNDEROVER *must* have tag:"mo" to work properly
+{input:"\\arccos", tag:"mi", output:"arccos", ttype:UNARY, func:true},
+{input:"\\arcsin", tag:"mi", output:"arcsin", ttype:UNARY, func:true},
+{input:"\\arctan", tag:"mi", output:"arctan", ttype:UNARY, func:true},
+{input:"\\arg", tag:"mi", output:"arg", ttype:UNARY, func:true},
+{input:"\\cos", tag:"mi", output:"cos", ttype:UNARY, func:true},
+{input:"\\cosh", tag:"mi", output:"cosh", ttype:UNARY, func:true},
+{input:"\\cot", tag:"mi", output:"cot", ttype:UNARY, func:true},
+{input:"\\coth", tag:"mi", output:"coth", ttype:UNARY, func:true},
+{input:"\\csc", tag:"mi", output:"csc", ttype:UNARY, func:true},
+{input:"\\deg", tag:"mi", output:"deg", ttype:UNARY, func:true},
+{input:"\\det", tag:"mi", output:"det", ttype:UNARY, func:true},
+{input:"\\dim", tag:"mi", output:"dim", ttype:UNARY, func:true}, //CONST?
+{input:"\\exp", tag:"mi", output:"exp", ttype:UNARY, func:true},
+{input:"\\gcd", tag:"mi", output:"gcd", ttype:UNARY, func:true}, //CONST?
+{input:"\\hom", tag:"mi", output:"hom", ttype:UNARY, func:true},
+{input:"\\inf", tag:"mo", output:"inf", ttype:UNDEROVER},
+{input:"\\ker", tag:"mi", output:"ker", ttype:UNARY, func:true},
+{input:"\\lg", tag:"mi", output:"lg", ttype:UNARY, func:true},
+{input:"\\lim", tag:"mo", output:"lim", ttype:UNDEROVER},
+{input:"\\liminf", tag:"mo", output:"liminf", ttype:UNDEROVER},
+{input:"\\limsup", tag:"mo", output:"limsup", ttype:UNDEROVER},
+{input:"\\ln", tag:"mi", output:"ln", ttype:UNARY, func:true},
+{input:"\\log", tag:"mi", output:"log", ttype:UNARY, func:true},
+{input:"\\max", tag:"mo", output:"max", ttype:UNDEROVER},
+{input:"\\min", tag:"mo", output:"min", ttype:UNDEROVER},
+{input:"\\Pr", tag:"mi", output:"Pr", ttype:UNARY, func:true},
+{input:"\\sec", tag:"mi", output:"sec", ttype:UNARY, func:true},
+{input:"\\sin", tag:"mi", output:"sin", ttype:UNARY, func:true},
+{input:"\\sinh", tag:"mi", output:"sinh", ttype:UNARY, func:true},
+{input:"\\sup", tag:"mo", output:"sup", ttype:UNDEROVER},
+{input:"\\tan", tag:"mi", output:"tan", ttype:UNARY, func:true},
+{input:"\\tanh", tag:"mi", output:"tanh", ttype:UNARY, func:true},
+
+//arrows
+{input:"\\gets", tag:"mo", output:"\u2190", ttype:CONST},
+{input:"\\leftarrow", tag:"mo", output:"\u2190", ttype:CONST},
+{input:"\\to", tag:"mo", output:"\u2192", ttype:CONST},
+{input:"\\rightarrow", tag:"mo", output:"\u2192", ttype:CONST},
+{input:"\\leftrightarrow", tag:"mo", output:"\u2194", ttype:CONST},
+{input:"\\uparrow", tag:"mo", output:"\u2191", ttype:CONST},
+{input:"\\downarrow", tag:"mo", output:"\u2193", ttype:CONST},
+{input:"\\updownarrow", tag:"mo", output:"\u2195", ttype:CONST},
+{input:"\\Leftarrow", tag:"mo", output:"\u21D0", ttype:CONST},
+{input:"\\Rightarrow", tag:"mo", output:"\u21D2", ttype:CONST},
+{input:"\\Leftrightarrow", tag:"mo", output:"\u21D4", ttype:CONST},
+{input:"\\iff", tag:"mo", output:"~\\Longleftrightarrow~", ttype:DEFINITION},
+{input:"\\Uparrow", tag:"mo", output:"\u21D1", ttype:CONST},
+{input:"\\Downarrow", tag:"mo", output:"\u21D3", ttype:CONST},
+{input:"\\Updownarrow", tag:"mo", output:"\u21D5", ttype:CONST},
+{input:"\\mapsto", tag:"mo", output:"\u21A6", ttype:CONST},
+{input:"\\longleftarrow", tag:"mo", output:"\u2190", ttype:LONG},
+{input:"\\longrightarrow", tag:"mo", output:"\u2192", ttype:LONG},
+{input:"\\longleftrightarrow", tag:"mo", output:"\u2194", ttype:LONG},
+{input:"\\Longleftarrow", tag:"mo", output:"\u21D0", ttype:LONG},
+{input:"\\Longrightarrow", tag:"mo", output:"\u21D2", ttype:LONG},
+{input:"\\Longleftrightarrow", tag:"mo", output:"\u21D4", ttype:LONG},
+{input:"\\longmapsto", tag:"mo", output:"\u21A6", ttype:CONST},
+ // disaster if LONG
+
+//commands with argument
+LMsqrt, LMroot, LMfrac, LMover, LMsub, LMsup, LMtext, LMmbox, LMatop, LMchoose,
+//LMdiv, LMquote,
+
+//diacritical marks
+{input:"\\acute", tag:"mover", output:"\u00B4", ttype:UNARY, acc:true},
+//{input:"\\acute", tag:"mover", output:"\u0317", ttype:UNARY, acc:true},
+//{input:"\\acute", tag:"mover", output:"\u0301", ttype:UNARY, acc:true},
+//{input:"\\grave", tag:"mover", output:"\u0300", ttype:UNARY, acc:true},
+//{input:"\\grave", tag:"mover", output:"\u0316", ttype:UNARY, acc:true},
+{input:"\\grave", tag:"mover", output:"\u0060", ttype:UNARY, acc:true},
+{input:"\\breve", tag:"mover", output:"\u02D8", ttype:UNARY, acc:true},
+{input:"\\check", tag:"mover", output:"\u02C7", ttype:UNARY, acc:true},
+{input:"\\dot", tag:"mover", output:".", ttype:UNARY, acc:true},
+{input:"\\ddot", tag:"mover", output:"..", ttype:UNARY, acc:true},
+//{input:"\\ddot", tag:"mover", output:"\u00A8", ttype:UNARY, acc:true},
+{input:"\\mathring", tag:"mover", output:"\u00B0", ttype:UNARY, acc:true},
+{input:"\\vec", tag:"mover", output:"\u20D7", ttype:UNARY, acc:true},
+{input:"\\overrightarrow",tag:"mover",output:"\u20D7", ttype:UNARY, acc:true},
+{input:"\\overleftarrow",tag:"mover", output:"\u20D6", ttype:UNARY, acc:true},
+{input:"\\hat", tag:"mover", output:"\u005E", ttype:UNARY, acc:true},
+{input:"\\widehat", tag:"mover", output:"\u0302", ttype:UNARY, acc:true},
+{input:"\\tilde", tag:"mover", output:"~", ttype:UNARY, acc:true},
+//{input:"\\tilde", tag:"mover", output:"\u0303", ttype:UNARY, acc:true},
+{input:"\\widetilde", tag:"mover", output:"\u02DC", ttype:UNARY, acc:true},
+{input:"\\bar", tag:"mover", output:"\u203E", ttype:UNARY, acc:true},
+{input:"\\overbrace", tag:"mover", output:"\u23B4", ttype:UNARY, acc:true},
+{input:"\\overline", tag:"mover", output:"\u00AF", ttype:UNARY, acc:true},
+{input:"\\underbrace", tag:"munder", output:"\u23B5", ttype:UNARY, acc:true},
+{input:"\\underline", tag:"munder", output:"\u00AF", ttype:UNARY, acc:true},
+//{input:"underline", tag:"munder", output:"\u0332", ttype:UNARY, acc:true},
+
+//typestyles and fonts
+{input:"\\displaystyle",tag:"mstyle",atname:"displaystyle",atval:"true", ttype:UNARY},
+{input:"\\textstyle",tag:"mstyle",atname:"displaystyle",atval:"false", ttype:UNARY},
+{input:"\\scriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"1", ttype:UNARY},
+{input:"\\scriptscriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"2", ttype:UNARY},
+{input:"\\textrm", tag:"mstyle", output:"\\mathrm", ttype: DEFINITION},
+{input:"\\mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY},
+{input:"\\textbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY},
+{input:"\\mathit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY},
+{input:"\\textit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY},
+{input:"\\mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY},
+{input:"\\texttt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY},
+{input:"\\mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", ttype:UNARY},
+{input:"\\mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", ttype:UNARY, codes:LMbbb},
+{input:"\\mathcal",tag:"mstyle", atname:"mathvariant", atval:"script", ttype:UNARY, codes:LMcal},
+{input:"\\mathfrak",tag:"mstyle",atname:"mathvariant", atval:"fraktur",ttype:UNARY, codes:LMfrk}
+];
+
+function compareNames(s1,s2) {
+ if (s1.input > s2.input) return 1
+ else return -1;
+}
+
+var LMnames = []; //list of input symbols
+
+function LMinitSymbols() {
+ LMsymbols.sort(compareNames);
+ for (i=0; i=n where str appears or would be inserted
+// assumes arr is sorted
+ if (n==0) {
+ var h,m;
+ n = -1;
+ h = arr.length;
+ while (n+1> 1;
+ if (arr[m]=str
+}
+
+function LMgetSymbol(str) {
+//return maximal initial substring of str that appears in names
+//return null if there is none
+ var k = 0; //new pos
+ var j = 0; //old pos
+ var mk; //match pos
+ var st;
+ var tagst;
+ var match = "";
+ var more = true;
+ for (var i=1; i<=str.length && more; i++) {
+ st = str.slice(0,i); //initial substring of length i
+ j = k;
+ k = LMposition(LMnames, st, j);
+ if (k=LMnames[k];
+ }
+ LMpreviousSymbol=LMcurrentSymbol;
+ if (match!=""){
+ LMcurrentSymbol=LMsymbols[mk].ttype;
+ return LMsymbols[mk];
+ }
+ LMcurrentSymbol=CONST;
+ k = 1;
+ st = str.slice(0,1); //take 1 character
+ if ("0"<=st && st<="9") tagst = "mn";
+ else tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi");
+/*
+// Commented out by DRW (not fully understood, but probably to do with
+// use of "/" as an INFIX version of "\\frac", which we don't want):
+//}
+//if (st=="-" && LMpreviousSymbol==INFIX) {
+// LMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse
+// return {input:st, tag:tagst, output:st, ttype:UNARY, func:true};
+//}
+*/
+ return {input:st, tag:tagst, output:st, ttype:CONST};
+}
+
+
+/*Parsing ASCII math expressions with the following grammar
+v ::= [A-Za-z] | greek letters | numbers | other constant symbols
+u ::= sqrt | text | bb | other unary symbols for font commands
+b ::= frac | root | stackrel binary symbols
+l ::= { | \left left brackets
+r ::= } | \right right brackets
+S ::= v | lEr | uS | bSS Simple expression
+I ::= S_S | S^S | S_S^S | S Intermediate expression
+E ::= IE | I/I Expression
+Each terminal symbol is translated into a corresponding mathml node.*/
+
+var LMpreviousSymbol,LMcurrentSymbol;
+
+function LMparseSexpr(str) { //parses str and returns [node,tailstr,(node)tag]
+ var symbol, node, result, result2, i, st,// rightvert = false,
+ newFrag = document.createDocumentFragment();
+ str = LMremoveCharsAndBlanks(str,0);
+ symbol = LMgetSymbol(str); //either a token or a bracket or empty
+ if (symbol == null || symbol.ttype == RIGHTBRACKET)
+ return [null,str,null];
+ if (symbol.ttype == DEFINITION) {
+ str = symbol.output+LMremoveCharsAndBlanks(str,symbol.input.length);
+ symbol = LMgetSymbol(str);
+ if (symbol == null || symbol.ttype == RIGHTBRACKET)
+ return [null,str,null];
+ }
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ switch (symbol.ttype) {
+ case SPACE:
+ node = LMcreateElementMathML(symbol.tag);
+ node.setAttribute(symbol.atname,symbol.atval);
+ return [node,str,symbol.tag];
+ case UNDEROVER:
+ if (isIE) {
+ if (symbol.input.substr(0,4) == "\\big") { // botch for missing symbols
+ str = "\\"+symbol.input.substr(4)+str; // make \bigcup = \cup etc.
+ symbol = LMgetSymbol(str);
+ symbol.ttype = UNDEROVER;
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ }
+ }
+ return [LMcreateMmlNode(symbol.tag,
+ document.createTextNode(symbol.output)),str,symbol.tag];
+ case CONST:
+ var output = symbol.output;
+ if (isIE) {
+ if (symbol.input == "'")
+ output = "\u2032";
+ else if (symbol.input == "''")
+ output = "\u2033";
+ else if (symbol.input == "'''")
+ output = "\u2033\u2032";
+ else if (symbol.input == "''''")
+ output = "\u2033\u2033";
+ else if (symbol.input == "\\square")
+ output = "\u25A1"; // same as \Box
+ else if (symbol.input.substr(0,5) == "\\frac") {
+ // botch for missing fractions
+ var denom = symbol.input.substr(6,1);
+ if (denom == "5" || denom == "6") {
+ str = symbol.input.replace(/\\frac/,"\\frac ")+str;
+ return [node,str,symbol.tag];
+ }
+ }
+ }
+ node = LMcreateMmlNode(symbol.tag,document.createTextNode(output));
+ return [node,str,symbol.tag];
+ case LONG: // added by DRW
+ node = LMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));
+ node.setAttribute("minsize","1.5");
+ node.setAttribute("maxsize","1.5");
+ node = LMcreateMmlNode("mover",node);
+ node.appendChild(LMcreateElementMathML("mspace"));
+ return [node,str,symbol.tag];
+ case STRETCHY: // added by DRW
+ if (isIE && symbol.input == "\\backslash")
+ symbol.output = "\\"; // doesn't expand, but then nor does "\u2216"
+ node = LMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));
+ if (symbol.input == "|" || symbol.input == "\\vert" ||
+ symbol.input == "\\|" || symbol.input == "\\Vert") {
+ node.setAttribute("lspace","0em");
+ node.setAttribute("rspace","0em");
+ }
+ node.setAttribute("maxsize",symbol.atval); // don't allow to stretch here
+ if (symbol.rtag != null)
+ return [node,str,symbol.rtag];
+ else
+ return [node,str,symbol.tag];
+ case BIG: // added by DRW
+ var atval = symbol.atval;
+ if (isIE)
+ atval = symbol.ieval;
+ symbol = LMgetSymbol(str);
+ if (symbol == null)
+ return [null,str,null];
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ node = LMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output));
+ if (isIE) { // to get brackets to expand
+ var space = LMcreateElementMathML("mspace");
+ space.setAttribute("height",atval+"ex");
+ node = LMcreateMmlNode("mrow",node);
+ node.appendChild(space);
+ } else { // ignored in IE
+ node.setAttribute("minsize",atval);
+ node.setAttribute("maxsize",atval);
+ }
+ return [node,str,symbol.tag];
+ case LEFTBRACKET: //read (expr+)
+ if (symbol.input == "\\left") { // left what?
+ symbol = LMgetSymbol(str);
+ if (symbol != null) {
+ if (symbol.input == ".")
+ symbol.invisible = true;
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ }
+ }
+ result = LMparseExpr(str,true,false);
+ if (symbol==null ||
+ (typeof symbol.invisible == "boolean" && symbol.invisible))
+ node = LMcreateMmlNode("mrow",result[0]);
+ else {
+ node = LMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ node = LMcreateMmlNode("mrow",node);
+ node.appendChild(result[0]);
+ }
+ return [node,result[1],result[2]];
+ case MATRIX: //read (expr+)
+ if (symbol.input == "\\begin{array}") {
+ var mask = "";
+ symbol = LMgetSymbol(str);
+ str = LMremoveCharsAndBlanks(str,0);
+ if (symbol == null)
+ mask = "l";
+ else {
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ if (symbol.input != "{")
+ mask = "l";
+ else do {
+ symbol = LMgetSymbol(str);
+ if (symbol != null) {
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ if (symbol.input != "}")
+ mask = mask+symbol.input;
+ }
+ } while (symbol != null && symbol.input != "" && symbol.input != "}");
+ }
+ result = LMparseExpr("{"+str,true,true);
+// if (result[0]==null) return [LMcreateMmlNode("mo",
+// document.createTextNode(symbol.input)),str];
+ node = LMcreateMmlNode("mtable",result[0]);
+ mask = mask.replace(/l/g,"left ");
+ mask = mask.replace(/r/g,"right ");
+ mask = mask.replace(/c/g,"center ");
+ node.setAttribute("columnalign",mask);
+ node.setAttribute("displaystyle","false");
+ if (isIE)
+ return [node,result[1],null];
+// trying to get a *little* bit of space around the array
+// (IE already includes it)
+ var lspace = LMcreateElementMathML("mspace");
+ lspace.setAttribute("width","0.167em");
+ var rspace = LMcreateElementMathML("mspace");
+ rspace.setAttribute("width","0.167em");
+ var node1 = LMcreateMmlNode("mrow",lspace);
+ node1.appendChild(node);
+ node1.appendChild(rspace);
+ return [node1,result[1],null];
+ } else { // eqnarray
+ result = LMparseExpr("{"+str,true,true);
+ node = LMcreateMmlNode("mtable",result[0]);
+ if (isIE)
+ node.setAttribute("columnspacing","0.25em"); // best in practice?
+ else
+ node.setAttribute("columnspacing","0.167em"); // correct (but ignored?)
+ node.setAttribute("columnalign","right center left");
+ node.setAttribute("displaystyle","true");
+ node = LMcreateMmlNode("mrow",node);
+ return [node,result[1],null];
+ }
+ case TEXT:
+ if (str.charAt(0)=="{") i=str.indexOf("}");
+ else i = 0;
+ if (i==-1)
+ i = str.length;
+ st = str.slice(1,i);
+ if (st.charAt(0) == " ") {
+ node = LMcreateElementMathML("mspace");
+ node.setAttribute("width","0.33em"); // was 1ex
+ newFrag.appendChild(node);
+ }
+ newFrag.appendChild(
+ LMcreateMmlNode(symbol.tag,document.createTextNode(st)));
+ if (st.charAt(st.length-1) == " ") {
+ node = LMcreateElementMathML("mspace");
+ node.setAttribute("width","0.33em"); // was 1ex
+ newFrag.appendChild(node);
+ }
+ str = LMremoveCharsAndBlanks(str,i+1);
+ return [LMcreateMmlNode("mrow",newFrag),str,null];
+ case UNARY:
+ result = LMparseSexpr(str);
+ if (result[0]==null) return [LMcreateMmlNode(symbol.tag,
+ document.createTextNode(symbol.output)),str];
+ if (typeof symbol.func == "boolean" && symbol.func) { // functions hack
+ st = str.charAt(0);
+// if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") {
+ if (st=="^" || st=="_" || st==",") {
+ return [LMcreateMmlNode(symbol.tag,
+ document.createTextNode(symbol.output)),str,symbol.tag];
+ } else {
+ node = LMcreateMmlNode("mrow",
+ LMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));
+ if (isIE) {
+ var space = LMcreateElementMathML("mspace");
+ space.setAttribute("width","0.167em");
+ node.appendChild(space);
+ }
+ node.appendChild(result[0]);
+ return [node,result[1],symbol.tag];
+ }
+ }
+ if (symbol.input == "\\sqrt") { // sqrt
+ if (isIE) { // set minsize, for \surd
+ var space = LMcreateElementMathML("mspace");
+ space.setAttribute("height","1.2ex");
+ space.setAttribute("width","0em"); // probably no effect
+ node = LMcreateMmlNode(symbol.tag,result[0])
+// node.setAttribute("minsize","1"); // ignored
+// node = LMcreateMmlNode("mrow",node); // hopefully unnecessary
+ node.appendChild(space);
+ return [node,result[1],symbol.tag];
+ } else
+ return [LMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag];
+ } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent
+ node = LMcreateMmlNode(symbol.tag,result[0]);
+ var output = symbol.output;
+ if (isIE) {
+ if (symbol.input == "\\hat")
+ output = "\u0302";
+ else if (symbol.input == "\\widehat")
+ output = "\u005E";
+ else if (symbol.input == "\\bar")
+ output = "\u00AF";
+ else if (symbol.input == "\\grave")
+ output = "\u0300";
+ else if (symbol.input == "\\tilde")
+ output = "\u0303";
+ }
+ var node1 = LMcreateMmlNode("mo",document.createTextNode(output));
+ if (symbol.input == "\\vec" || symbol.input == "\\check")
+ // don't allow to stretch
+ node1.setAttribute("maxsize","1.2");
+ // why doesn't "1" work? \vec nearly disappears in firefox
+ if (isIE && symbol.input == "\\bar")
+ node1.setAttribute("maxsize","0.5");
+ if (symbol.input == "\\underbrace" || symbol.input == "\\underline")
+ node1.setAttribute("accentunder","true");
+ else
+ node1.setAttribute("accent","true");
+ node.appendChild(node1);
+ if (symbol.input == "\\overbrace" || symbol.input == "\\underbrace")
+ node.ttype = UNDEROVER;
+ return [node,result[1],symbol.tag];
+ } else { // font change or displaystyle command
+ if (!isIE && typeof symbol.codes != "undefined") {
+ for (i=0; i64 && st.charCodeAt(j)<91) newst = newst +
+ String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]);
+ else newst = newst + st.charAt(j);
+ if (result[0].nodeName=="mi")
+ result[0]=LMcreateElementMathML("mo").
+ appendChild(document.createTextNode(newst));
+ else result[0].replaceChild(LMcreateElementMathML("mo").
+ appendChild(document.createTextNode(newst)),result[0].childNodes[i]);
+ }
+ }
+ node = LMcreateMmlNode(symbol.tag,result[0]);
+ node.setAttribute(symbol.atname,symbol.atval);
+ if (symbol.input == "\\scriptstyle" ||
+ symbol.input == "\\scriptscriptstyle")
+ node.setAttribute("displaystyle","false");
+ return [node,result[1],symbol.tag];
+ }
+ case BINARY:
+ result = LMparseSexpr(str);
+ if (result[0]==null) return [LMcreateMmlNode("mo",
+ document.createTextNode(symbol.input)),str,null];
+ result2 = LMparseSexpr(result[1]);
+ if (result2[0]==null) return [LMcreateMmlNode("mo",
+ document.createTextNode(symbol.input)),str,null];
+ if (symbol.input=="\\root" || symbol.input=="\\stackrel")
+ newFrag.appendChild(result2[0]);
+ newFrag.appendChild(result[0]);
+ if (symbol.input=="\\frac") newFrag.appendChild(result2[0]);
+ return [LMcreateMmlNode(symbol.tag,newFrag),result2[1],symbol.tag];
+ case INFIX:
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ return [LMcreateMmlNode("mo",document.createTextNode(symbol.output)),
+ str,symbol.tag];
+ default:
+ return [LMcreateMmlNode(symbol.tag, //its a constant
+ document.createTextNode(symbol.output)),str,symbol.tag];
+ }
+}
+
+function LMparseIexpr(str) {
+ var symbol, sym1, sym2, node, result, tag, underover;
+ str = LMremoveCharsAndBlanks(str,0);
+ sym1 = LMgetSymbol(str);
+ result = LMparseSexpr(str);
+ node = result[0];
+ str = result[1];
+ tag = result[2];
+ symbol = LMgetSymbol(str);
+ if (symbol.ttype == INFIX) {
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ result = LMparseSexpr(str);
+ if (result[0] == null) // show box in place of missing argument
+ result[0] = LMcreateMmlNode("mo",document.createTextNode("\u25A1"));
+ str = result[1];
+ tag = result[2];
+ if (symbol.input == "_" || symbol.input == "^") {
+ sym2 = LMgetSymbol(str);
+ tag = null; // no space between x^2 and a following sin, cos, etc.
+// This is for \underbrace and \overbrace
+ underover = ((sym1.ttype == UNDEROVER) || (node.ttype == UNDEROVER));
+// underover = (sym1.ttype == UNDEROVER);
+ if (symbol.input == "_" && sym2.input == "^") {
+ str = LMremoveCharsAndBlanks(str,sym2.input.length);
+ var res2 = LMparseSexpr(str);
+ str = res2[1];
+ tag = res2[2]; // leave space between x_1^2 and a following sin etc.
+ node = LMcreateMmlNode((underover?"munderover":"msubsup"),node);
+ node.appendChild(result[0]);
+ node.appendChild(res2[0]);
+ } else if (symbol.input == "_") {
+ node = LMcreateMmlNode((underover?"munder":"msub"),node);
+ node.appendChild(result[0]);
+ } else {
+ node = LMcreateMmlNode((underover?"mover":"msup"),node);
+ node.appendChild(result[0]);
+ }
+ node = LMcreateMmlNode("mrow",node); // so sum does not stretch
+ } else {
+ node = LMcreateMmlNode(symbol.tag,node);
+ if (symbol.input == "\\atop" || symbol.input == "\\choose")
+ node.setAttribute("linethickness","0ex");
+ node.appendChild(result[0]);
+ if (symbol.input == "\\choose")
+ node = LMcreateMmlNode("mfenced",node);
+ }
+ }
+ return [node,str,tag];
+}
+
+function LMparseExpr(str,rightbracket,matrix) {
+ var symbol, node, result, i, tag,
+ newFrag = document.createDocumentFragment();
+ do {
+ str = LMremoveCharsAndBlanks(str,0);
+ result = LMparseIexpr(str);
+ node = result[0];
+ str = result[1];
+ tag = result[2];
+ symbol = LMgetSymbol(str);
+ if (node!=undefined) {
+ if ((tag == "mn" || tag == "mi") && symbol!=null &&
+ typeof symbol.func == "boolean" && symbol.func) {
+ // Add space before \sin in 2\sin x or x\sin x
+ var space = LMcreateElementMathML("mspace");
+ space.setAttribute("width","0.167em");
+ node = LMcreateMmlNode("mrow",node);
+ node.appendChild(space);
+ }
+ newFrag.appendChild(node);
+ }
+ } while ((symbol.ttype != RIGHTBRACKET)
+ && symbol!=null && symbol.output!="");
+ tag = null;
+ if (symbol.ttype == RIGHTBRACKET) {
+ if (symbol.input == "\\right") { // right what?
+ str = LMremoveCharsAndBlanks(str,symbol.input.length);
+ symbol = LMgetSymbol(str);
+ if (symbol != null && symbol.input == ".")
+ symbol.invisible = true;
+ if (symbol != null)
+ tag = symbol.rtag;
+ }
+ if (symbol!=null)
+ str = LMremoveCharsAndBlanks(str,symbol.input.length); // ready to return
+ var len = newFrag.childNodes.length;
+ if (matrix &&
+ len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 &&
+ newFrag.childNodes[len-2].nodeName == "mo" &&
+ newFrag.childNodes[len-2].firstChild.nodeValue == "&") { //matrix
+ var pos = []; // positions of ampersands
+ var m = newFrag.childNodes.length;
+ for (i=0; matrix && i -&-&...&-&-
+ n = node.childNodes.length;
+ k = 0;
+ for (j=0; j2) {
+ newFrag.removeChild(newFrag.firstChild); //remove
+ newFrag.removeChild(newFrag.firstChild); //remove &
+ }
+ table.appendChild(LMcreateMmlNode("mtr",row));
+ }
+ return [table,str];
+ }
+ if (typeof symbol.invisible != "boolean" || !symbol.invisible) {
+ node = LMcreateMmlNode("mo",document.createTextNode(symbol.output));
+ newFrag.appendChild(node);
+ }
+ }
+ return [newFrag,str,tag];
+}
+
+function LMparseMath(str) {
+ var result, node = LMcreateElementMathML("mstyle");
+ if (LMmathcolor != "") node.setAttribute("mathcolor",LMmathcolor);
+ if (LMmathfontfamily != "") node.setAttribute("fontfamily",LMmathfontfamily);
+ node.appendChild(LMparseExpr(str.replace(/^\s+/g,""),false,false)[0]);
+ node = LMcreateMmlNode("math",node);
+ if (LMshowasciiformulaonhover) //fixed by djhsu so newline
+ node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko
+ var fnode = LMcreateElementXHTML("span");
+ fnode.style.fontSize = mathfontsize;
+ if (LMmathfontfamily != "") fnode.style.fontFamily = LMmathfontfamily;
+ fnode.appendChild(node);
+ return fnode;
+}
+
+function LMstrarr2docFrag(arr, linebreaks) {
+ var newFrag=document.createDocumentFragment();
+ var expr = false;
+ for (var i=0; i1 || mtch) {
+ if (LMcheckForMathML) {
+ LMcheckForMathML = false;
+ var nd = LMisMathMLavailable();
+ LMnoMathML = nd != null;
+ if (LMnoMathML && LMnotifyIfNoMathML)
+ if (LMalertIfNoMathML)
+ alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\
+ or Firefox/Mozilla/Netscape");
+ else LMbody.insertBefore(nd,LMbody.childNodes[0]);
+ }
+ if (!LMnoMathML) {
+ frg = LMstrarr2docFrag(arr,n.nodeType==8);
+ var len = frg.childNodes.length;
+ n.parentNode.replaceChild(frg,n);
+ return len-1;
+ } else return 0;
+ }
+ }
+ } else return 0;
+ } else if (n.nodeName!="math") {
+ for (i=0; i$\\displaystyle{$1}$
");
+ st = st.replace(/\\begin{(theorem|lemma|proposition|corollary)}((.|\n)*?)\\end{\1}/g,function(r,s,t){tcnt++; return ""+s.charAt(0).toUpperCase()+s.slice(1)+" "+tcnt+"."+t.replace(/^\s*<\/?\w+\/?>|\s*<\/?\w+\/?>$/g,"")+""});
+ st = st.replace(/\\begin{(definition|example|remark|problem|exercise|conjecture|solution)}((.|\n)*?)\\end{\1}/g,function(r,s,t){dcnt++; return ""+s.charAt(0).toUpperCase()+s.slice(1)+" "+dcnt+". "+t.replace(/^\s*<\/?\w+\/?>|\s*<\/?\w+\/?>$/g,"")});
+ st = st.replace(/\\begin{proof}((.|\n)*?)\\end{proof}/g,function(s,t){return "Proof: "+t.replace(/^\s*<\/?\w+\/?>|\s*<\/?\w+\/?>$/g,"")+" □"});
+ st = st.replace(/\\emph{(.*?)}/g,"$1");
+ st = st.replace(/\\textbf{(.*?)}/g,"$1");
+ st = st.replace(/\\cite{(.*?)}/g,"[$1]");
+ st = st.replace(/\\chapter{(.*?)}/g,"
$1
");
+ st = st.replace(/\\section{(.*?)}(\s*<\/?(br|p)\s?\/?>)?/g,"
$1
");
+ st = st.replace(/\\subsection{(.*?)}/g,"
$1
");
+ st = st.replace(/\\begin{itemize}(\s*<\/?(br|p)\s?\/?>)?/g,"
");
+ st = st.replace(/\\item\s((.|\n)*?)(?=(\\item|\\end))/g,"
$1
");
+ st = st.replace(/\\end{itemize}(\s*<\/?(br|p)\s?\/?>)?/g,"
");
+ st = st.replace(/\\begin{enumerate}(\s*<\/?(br|p)\s?\/?>)?/g,"");
+ st = st.replace(/\\end{enumerate}(\s*<\/?(br|p)\s?\/?>)?/g,"");
+ st = st.replace(/\\item\[(.*?)]{(.*?)}/g,"
$1
$2
");
+ st = st.replace(/\\begin{description}/g,"
");
+ st = st.replace(/\\end{description}/g,"
");
+ st = st.replace(/\\newline\b/g," ");
+ st = st.replace(/\\newpage\b/g," ");
+ st = st.replace(/\\par\b/g,"
");
+ st = st.replace(/\\bigskip/g,"
");
+ st = st.replace(/\\medskip/g,"
");
+ st = st.replace(/\\smallskip/g,"
");
+ st = st.replace(/\\begin{center}(.*?)\\end{center}/g,"