/* LaTeXMathML.js ============== This file, in this form, is due to Douglas Woodall, June 2006. It contains JavaScript functions to convert (most simple) LaTeX math notation to Presentation MathML. It was obtained by downloading the file ASCIIMathML.js from http://www1.chapman.edu/~jipsen/mathml/asciimathdownload/ and modifying it so that it carries out ONLY those conversions that would be carried out in LaTeX. A description of the original file, with examples, can be found at www1.chapman.edu/~jipsen/mathml/asciimath.html ASCIIMathML: Math on the web for everyone Here is the header notice from the original file: ASCIIMathML.js ============== This file contains JavaScript functions to convert ASCII math notation to Presentation MathML. The conversion is done while the (X)HTML page loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/). Just add the next line to your (X)HTML page with this file in the same folder: 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 General Public License as published by the Free Software Foundation; either version 2 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 General Public License (at http://www.gnu.org/copyleft/gpl.html) for more details. LaTeXMathML.js (ctd) ============== The instructions for use are the same as for the original ASCIIMathML.js, except that of course the line you add to your file should be Or use absolute path names if the file is not in the same folder as your (X)HTML page. */ var checkForMathML = true; // check if browser can display MathML var notifyIfNoMathML = true; // display note if no MathML capability var alertIfNoMathML = false; // show alert box if no MathML capability // was "red": var mathcolor = ""; // change it to "" (to inherit) or any other color // was "serif": var mathfontfamily = ""; // change to "" to inherit (works in IE) // or another family (e.g. "arial") var showasciiformulaonhover = true; // helps students learn ASCIIMath /* // Commented out by DRW -- not now used -- see DELIMITERS (twice) near the end var displaystyle = false; // puts limits above and below large operators var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$"; var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1` // for IE this works only in //var separatetokens;// has been removed (email me if this is a problem) */ 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 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("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 = 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(); } else return AMnoMathMLNote(); } // character lists for Mozilla/Netscape fonts var AMcal = ["\uD835\uDC9C", "\uD835\uDC9D", "\uD835\uDC9E", "\uD835\uDC9F", "\uD835\uDCA0", "\uD835\uDCA1", "\uD835\uDCA2", "\uD835\uDCA3", "\uD835\uDCA4", "\uD835\uDCA5", "\uD835\uDCA6", "\uD835\uDCA7", "\uD835\uDCA8", "\uD835\uDCA9", "\uD835\uDCAA", "\uD835\uDCAB", "\uD835\uDCAC", "\uD835\uDCAD", "\uD835\uDCAE", "\uD835\uDCAF", "\uD835\uDCB0", "\uD835\uDCB1", "\uD835\uDCB2", "\uD835\uDCB3", "\uD835\uDCB4", "\uD835\uDCB5"]; var AMfrk = ["\uD835\uDD04", "\uD835\uDD05", "\uD835\uDD06", "\uD835\uDD07", "\uD835\uDD08", "\uD835\uDD09", "\uD835\uDD0A", "\uD835\uDD0B", "\uD835\uDD0C", "\uD835\uDD0D", "\uD835\uDD0E", "\uD835\uDD0F", "\uD835\uDD10", "\uD835\uDD11", "\uD835\uDD12", "\uD835\uDD13", "\uD835\uDD14", "\uD835\uDD15", "\uD835\uDD16", "\uD835\uDD17", "\uD835\uDD18", "\uD835\uDD19", "\uD835\uDD1A", "\uD835\uDD1B", "\uD835\uDD1C", "\uD835\uDD1D"]; var AMbbb = ["\uD835\uDD38", "\uD835\uDD39", "\uD835\uDD3A", "\uD835\uDD3B", "\uD835\uDD3C", "\uD835\uDD3D", "\uD835\uDD3E", "\uD835\uDD3F", "\uD835\uDD40", "\uD835\uDD41", "\uD835\uDD42", "\uD835\uDD43", "\uD835\uDD44", "\uD835\uDD45", "\uD835\uDD46", "\uD835\uDD47", "\uD835\uDD48", "\uD835\uDD49", "\uD835\uDD4A", "\uD835\uDD4B", "\uD835\uDD4C", "\uD835\uDD4D", "\uD835\uDD4E", "\uD835\uDD4F", "\uD835\uDD50", "\uD835\uDD51"]; var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, TEXT = 9, BIG = 10, LONG = 11, STRETCHY = 12, MATRIX = 13; // token types var AMsqrt = {input:"\\sqrt", tag:"msqrt", output:"sqrt", ttype:UNARY}, AMnot = {input:"\\not", tag:"mnot", output:"not", ttype:UNARY}, AMroot = {input:"\\root", tag:"mroot", output:"root", ttype:BINARY}, AMfrac = {input:"\\frac", tag:"mfrac", output:"/", ttype:BINARY}, AMover = {input:"\\stackrel", tag:"mover", output:"stackrel", ttype:BINARY}, AMatop = {input:"\\atop", tag:"mfrac", output:"", ttype:INFIX}, AMchoose = {input:"\\choose", tag:"mfrac", output:"", ttype:INFIX}, AMsub = {input:"_", tag:"msub", output:"_", ttype:INFIX}, AMsup = {input:"^", tag:"msup", output:"^", ttype:INFIX}, AMtext = {input:"\\mathrm", tag:"mtext", output:"text", ttype:TEXT}, AMmbox = {input:"\\mbox", tag:"mtext", output:"mbox", ttype:TEXT}; // Commented out by DRW to prevent 1/2 turning into a 2-line fraction // AMdiv = {input:"/", tag:"mfrac", output:"/", ttype:INFIX}, // Commented out by DRW so that " prints literally in equations // AMquote = {input:"\"", tag:"mtext", output:"mbox", ttype:TEXT}; // List of negations obtained from http://frodo.elon.edu/tutorial/tutorial.pdf var AMRelationNegations = { "\u003C":"\u226E", "\u003E":"\u226F", "\u2264":"\u2270", "\u2265":"\u2271", "\u003D":"\u2260", "\u2261":"\u2262", "\u227A":"\u2280", "\u227B":"\u2281", "\u227C":"\u22E0", "\u227D":"\u22E1", "\u223C":"\u2241", "\u2243":"\u2244", "\u2282":"\u2284", "\u2283":"\u2285", "\u2286":"\u2288", "\u2287":"\u2289", "\u2248":"\u2249", "\u2245":"\u2247", "\u2291":"\u22E2", "\u2292":"\u22E3", "\u224D":"\u226D" } var AMsymbols = [ //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:"\\subsetneq", tag:"mo", output:"\u228A", ttype:CONST}, {input:"\\supsetneq", tag:"mo", output:"\u228B", 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 AMparseExpr() ) {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 AMsqrt, AMnot, AMroot, AMfrac, AMover, AMsub, AMsup, AMtext, AMmbox, AMatop, AMchoose, //AMdiv, AMquote, //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:"\uFE37", ttype:UNARY, acc:true}, //Changed unicode overbrace {input:"\\overbracket", tag:"mover", output:"\u23B4", ttype:UNARY, acc:true}, //old overbrace = overbracket {input:"\\overline", tag:"mover", output:"\u00AF", ttype:UNARY, acc:true}, {input:"\\underbrace", tag:"munder", output:"\uFE38", ttype:UNARY, acc:true}, //Changed unicode underbrace {input:"\\underbracket",tag:"munder", output:"\u23B5", ttype:UNARY, acc:true}, //old underbrace = underbracket {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:AMbbb}, {input:"\\mathcal",tag:"mstyle", atname:"mathvariant", atval:"script", ttype:UNARY, codes:AMcal}, {input:"\\mathfrak",tag:"mstyle",atname:"mathvariant", atval:"fraktur",ttype:UNARY, codes:AMfrk}, {input:"\\textcolor",tag:"mstyle",atname:"mathvariant", atval:"mathcolor", ttype:BINARY}, {input:"\\colorbox",tag:"mstyle",atname:"mathvariant", atval:"background", ttype:BINARY} ]; function compareNames(s1,s2) { if (s1.input > s2.input) return 1 else return -1; } var AMnames = []; //list of input symbols function AMinitSymbols() { AMsymbols.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 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]; } AMcurrentSymbol=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=="-" && 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}; } /*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 AMpreviousSymbol,AMcurrentSymbol; function AMparseSexpr(str) { //parses str and returns [node,tailstr,(node)tag] var symbol, node, result, result2, 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) return [null,str,null]; if (symbol.ttype == DEFINITION) { str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); symbol = AMgetSymbol(str); if (symbol == null || symbol.ttype == RIGHTBRACKET) return [null,str,null]; } str = AMremoveCharsAndBlanks(str,symbol.input.length); switch (symbol.ttype) { case SPACE: node = AMcreateElementMathML(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 = AMgetSymbol(str); symbol.ttype = UNDEROVER; str = AMremoveCharsAndBlanks(str,symbol.input.length); } } return [AMcreateMmlNode(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 = AMcreateMmlNode(symbol.tag,document.createTextNode(output)); return [node,str,symbol.tag]; case LONG: // added by DRW node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); node.setAttribute("minsize","1.5"); node.setAttribute("maxsize","1.5"); node = AMcreateMmlNode("mover",node); node.appendChild(AMcreateElementMathML("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 = AMcreateMmlNode(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 = AMgetSymbol(str); if (symbol == null) return [null,str,null]; str = AMremoveCharsAndBlanks(str,symbol.input.length); node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); if (isIE) { // to get brackets to expand var space = AMcreateElementMathML("mspace"); space.setAttribute("height",atval+"ex"); node = AMcreateMmlNode("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 = AMgetSymbol(str); if (symbol != null) { if (symbol.input == ".") symbol.invisible = true; str = AMremoveCharsAndBlanks(str,symbol.input.length); } } result = AMparseExpr(str,true,false); if (symbol==null || (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],result[2]]; case MATRIX: //read (expr+) if (symbol.input == "\\begin{array}") { var mask = ""; symbol = AMgetSymbol(str); str = AMremoveCharsAndBlanks(str,0); if (symbol == null) mask = "l"; else { str = AMremoveCharsAndBlanks(str,symbol.input.length); if (symbol.input != "{") mask = "l"; else do { symbol = AMgetSymbol(str); if (symbol != null) { str = AMremoveCharsAndBlanks(str,symbol.input.length); if (symbol.input != "}") mask = mask+symbol.input; } } while (symbol != null && symbol.input != "" && symbol.input != "}"); } result = AMparseExpr("{"+str,true,true); // if (result[0]==null) return [AMcreateMmlNode("mo", // document.createTextNode(symbol.input)),str]; node = AMcreateMmlNode("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 = AMcreateElementMathML("mspace"); lspace.setAttribute("width","0.167em"); var rspace = AMcreateElementMathML("mspace"); rspace.setAttribute("width","0.167em"); var node1 = AMcreateMmlNode("mrow",lspace); node1.appendChild(node); node1.appendChild(rspace); return [node1,result[1],null]; } else { // eqnarray result = AMparseExpr("{"+str,true,true); node = AMcreateMmlNode("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 = AMcreateMmlNode("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 = AMcreateElementMathML("mspace"); node.setAttribute("width","0.33em"); // was 1ex newFrag.appendChild(node); } newFrag.appendChild( AMcreateMmlNode(symbol.tag,document.createTextNode(st))); if (st.charAt(st.length-1) == " ") { node = AMcreateElementMathML("mspace"); node.setAttribute("width","0.33em"); // was 1ex newFrag.appendChild(node); } str = AMremoveCharsAndBlanks(str,i+1); return [AMcreateMmlNode("mrow",newFrag),str,null]; case UNARY: 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==",") { if (st=="^" || st=="_" || st==",") { return [AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag]; } else { node = AMcreateMmlNode("mrow",AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); if (isIE) { var space = AMcreateElementMathML("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 = AMcreateElementMathML("mspace"); space.setAttribute("height","1.2ex"); space.setAttribute("width","0em"); // probably no effect node = AMcreateMmlNode(symbol.tag,result[0]) // node.setAttribute("minsize","1"); // ignored // node = AMcreateMmlNode("mrow",node); // hopefully unnecessary node.appendChild(space); return [node,result[1],symbol.tag]; } else return [AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag]; } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent node = AMcreateMmlNode(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 = AMcreateMmlNode("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 if (symbol.input == "\\not") { // not // added by infinity0 on 2009-12-15 to implement \not command text = result[0].childNodes[0].nodeValue; if (typeof text == "string" && text.length == 1 && text in AMRelationNegations) { result[0].childNodes[0].nodeValue = AMRelationNegations[text]; return [AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag]; } return [AMcreateMmlNode("mo",document.createTextNode("\\")),"not " + str,symbol.tag]; } else { // font change or displaystyle command if (!isIE && typeof symbol.codes != "undefined") { for (i=0; i64 && st.charCodeAt(j)<91) { newst = newst + symbol.codes[st.charCodeAt(j)-65] } // String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]); alert(newst); } 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); if (symbol.input == "\\scriptstyle" || symbol.input == "\\scriptscriptstyle") node.setAttribute("displaystyle","false"); return [node,result[1],symbol.tag]; } case BINARY: result = AMparseSexpr(str); if (result[0]==null) return [AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null]; result2 = AMparseSexpr(result[1]); if (result2[0]==null) return [AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null]; //added by J. Knisley to allow \textcolor and \colorbox within equations if (symbol.input=="\\textcolor" || symbol.input=="\\colorbox") { var tclr = str.match(/\{\s*([#\w]+)\s*\}/); //get's color from beginning of str str = str.replace(/\{\s*[#\w]+\s*\}/,""); if(tclr!=null) { if(IsColorName.test(tclr[1].toLowerCase())) { tclr=LaTeXColor[tclr[1].toLowerCase()]; } else { tclr=tclr[1]; // no checking for valid color!! } node = AMcreateElementMathML("mstyle"); node.setAttribute(symbol.atval,tclr); node.appendChild(result2[0]); return [node,result2[1],symbol.tag]; } } 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],symbol.tag]; case INFIX: str = AMremoveCharsAndBlanks(str,symbol.input.length); return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)), str,symbol.tag]; default: return [AMcreateMmlNode(symbol.tag, //its a constant document.createTextNode(symbol.output)),str,symbol.tag]; } } function AMparseIexpr(str) { var symbol, sym1, sym2, node, result, tag, underover; str = AMremoveCharsAndBlanks(str,0); sym1 = AMgetSymbol(str); result = AMparseSexpr(str); node = result[0]; str = result[1]; tag = result[2]; symbol = AMgetSymbol(str); if (symbol.ttype == INFIX) { str = AMremoveCharsAndBlanks(str,symbol.input.length); result = AMparseSexpr(str); if (result[0] == null) // show box in place of missing argument result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); str = result[1]; tag = result[2]; if (symbol.input == "_" || symbol.input == "^") { sym2 = AMgetSymbol(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 = AMremoveCharsAndBlanks(str,sym2.input.length); var res2 = AMparseSexpr(str); str = res2[1]; tag = res2[2]; // leave space between x_1^2 and a following sin etc. node = AMcreateMmlNode((underover?"munderover":"msubsup"),node); node.appendChild(result[0]); node.appendChild(res2[0]); } else if (symbol.input == "_") { node = AMcreateMmlNode((underover?"munder":"msub"),node); node.appendChild(result[0]); } else { node = AMcreateMmlNode((underover?"mover":"msup"),node); node.appendChild(result[0]); } node = AMcreateMmlNode("mrow",node); // so sum does not stretch } else { node = AMcreateMmlNode(symbol.tag,node); if (symbol.input == "\\atop" || symbol.input == "\\choose") node.setAttribute("linethickness","0ex"); node.appendChild(result[0]); if (symbol.input == "\\choose") node = AMcreateMmlNode("mfenced",node); } } return [node,str,tag]; } function AMparseExpr(str,rightbracket,matrix) { var symbol, node, result, i, tag, newFrag = document.createDocumentFragment(); do { str = AMremoveCharsAndBlanks(str,0); result = AMparseIexpr(str); node = result[0]; str = result[1]; tag = result[2]; symbol = AMgetSymbol(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 = AMcreateElementMathML("mspace"); space.setAttribute("width","0.167em"); node = AMcreateMmlNode("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 = AMremoveCharsAndBlanks(str,symbol.input.length); symbol = AMgetSymbol(str); if (symbol != null && symbol.input == ".") symbol.invisible = true; if (symbol != null) tag = symbol.rtag; } if (symbol!=null) str = AMremoveCharsAndBlanks(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(AMcreateMmlNode("mtr",row)); } return [table,str]; } if (typeof symbol.invisible != "boolean" || !symbol.invisible) { node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); newFrag.appendChild(node); } } return [newFrag,str,tag]; } function AMparseMath(str) { var result, node = AMcreateElementMathML("mstyle"); //added by J. Knisley to allow limited implementation of \color var cclr = str.match(/\\color\s*\{\s*([#\w]+)\s*\}/); str = str.replace(/\\color\s*\{\s*[#\w]+\s*\}/g,""); if(cclr!=null) { if(IsColorName.test(cclr[1].toLowerCase())) { cclr=LaTeXColor[cclr[1].toLowerCase()]; } else { cclr=cclr[1]; // no checking for valid color!! } node.setAttribute("mathcolor",cclr); } else { if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); }; if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false,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 if (false ) { //&& mathfontfamily != "" && (isIE || mathfontfamily != "serif")) { var fnode = AMcreateElementXHTML("font"); fnode.setAttribute("face",mathfontfamily); fnode.appendChild(node); return fnode; } return node; } function AMstrarr2docFrag(arr, linebreaks) { var newFrag=document.createDocumentFragment(); var expr = false; for (var 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 0) { if(inAppendix) { return "A"+sectionCntr+"."+cntr; } else { return sectionCntr+"."+cntr; } } else { return ""+cntr; } }; function LaTeXpreProcess(thebody) { var TheBody = thebody; if(TheBody.hasChildNodes()) { if(!(IsLaTeXElement.test(TheBody.className))) { for(var i=0; i"); // % sign str = str.replace(/%[^\n]*(?=\n)/g,""); str = str.replace(/%[^\r]*(?=\r)/g,""); //Used by Explorer str = str.replace(/%[^\n]*$/,"") // End of text segment comment if(isIE && str.match(/%/g) != null && IEcommentWarning) { alert("Comments may not have parsed properly. Try putting in
 stuff
            //and to identify non-display math content (sections, etc).  
             
            str = str.split("");
            // var ntype = TheBody.nodeType;
            var newFrag = document.createDocumentFragment();
	     
            for(var i=0;i
		          if(isIE) {
		             str[i] = str[i].replace(/\r/g," ");  // replace \r by a space to aid spacing!
		          }

		  
		          //items and appendix
		          str[i] = str[i].replace(/\\bibitem\s*([^\{]*\{\s*\w*\s*\})/g," \\[bibitem\\]$1\\[ ");
                  str[i] = str[i].replace(/\\bibitem\s*/g," \\[bibitem\\] \\[ ");
		          str[i] = str[i].replace(/\\item\s*\[\s*(\w+)\s*\]/g," \\[alistitem\\]$1\\[ ");
		          str[i] = str[i].replace(/\\item\s*/g," \\[alistitem\\] \\[ ");
  		          str[i] = str[i].replace(/\\appendix/g," \\[appendix\\] \\[ ");


                  // \includegraphics[][]{image} -- no processing of options.  This treatment is DANGEROUS.  It assumes no html will be
		          // placed within the \begin{figure} ... \end{figure} structure, and the [\s\S] character class could lead to strange matches
	              str[i] = str[i].replace(/\\begin\s*\{\s*figure\s*\}([\s\S]+?)\\end\s*\{\s*figure\s*\}/g," \\[figure\\]$1\\[ ");
                  str[i] = str[i].replace(/\\begin\s*\{\s*table\s*\}([\s\S]+?)\\end\s*\{\s*table\s*\}/g," \\[table\\]$1\\[ ");
		          //str[i] = str[i].replace(/\\begin\s*\{\s*array\s*\}([\s\S]+?)\\end\s*\{\s*array\s*\}/g," \\[array\\]$1\\[ ");
                  //goal is to protect array \\ from being converted into linebreaks
                  
                  //This construction allows css classes for divs for these elements, but the CSS will have to be supplied through a 
                  //css file or  in the header.  (It makes sense to me that style files in LaTeX should correspond
                  //to css and/or xslt when translating to mathml, but \ref's are a problem).
                  str[i] = str[i].replace(/\\begin\s*\{\s*theorem\s*\}/g," \\[theorem\\]Theorem \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*theorem\s*\}/g," \\[endtheorem\\] \\[ ");

                  str[i] = str[i].replace(/\\begin\s*\{\s*definition\s*\}/g," \\[definition\\]Definition \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*definition\s*\}/g," \\[enddefinition\\] \\[ ");
           
                  str[i] = str[i].replace(/\\begin\s*\{\s*lemma\s*\}/g," \\[lemma\\]Lemma \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*lemma\s*\}/g," \\[endlemma\\] \\[ ");

                  str[i] = str[i].replace(/\\begin\s*\{\s*corollary\s*\}/g," \\[corollary\\]Corollary \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*corollary\s*\}/g," \\[endcorollary\\] \\[ ");
          
                  str[i] = str[i].replace(/\\begin\s*\{\s*proposition\s*\}/g," \\[proposition\\]Proposition \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*proposition\s*\}/g," \\[endproposition\\] \\[ ");

                  str[i] = str[i].replace(/\\begin\s*\{\s*example\s*\}/g," \\[example\\]Example \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*example\s*\}/g," \\[endexample\\] \\[ ");
	           
                  str[i] = str[i].replace(/\\begin\s*\{\s*exercise\s*\}/g," \\[exercise\\]Exercise \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*exercise\s*\}/g," \\[endexercise\\] \\[ ");

                  str[i] = str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}\s*\{\s*\w+\s*\}/g," \\[thebibliography\\]References \\[ "); 
                  str[i] = str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}/g," \\[thebibliography\\]References \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*thebibliography\s*\}/g," \\[endthebibliography\\]References \\[ ");
		  

                  str[i] = str[i].replace(/\\begin\s*\{\s*proof\s*\}/g," \\[proof\\]Proof: \\[ "); 
                  if(isIE) {  //IE is just so weird
                     str[i] = str[i].replace(/\\end\s*\{\s*proof\s*\}/g,"\u220E \\[endproof\\] \\[ ");
                  } else { 
                     str[i] = str[i].replace(/\\end\s*\{\s*proof\s*\}/g," \\[endproof\\] \\[ ");
                  }
		  
                  //The frontmatter -- all translated to div's to be handled by CSS
                  str[i] = str[i].replace(/\\title\s*\{\s*([^\}]+)\}/g," \\[title\\] \\[$1 \\[endtitle\\] \\[ ");
                  str[i] = str[i].replace(/\\author\s*\{\s*([^\}]+)\}/g," \\[author\\] \\[$1 \\[endauthor\\] \\[ ");
                  str[i] = str[i].replace(/\\address\s*\{\s*([^\}]+)\}/g," \\[address\\] \\[$1 \\[endaddress\\] \\[ ");
                  str[i] = str[i].replace(/\\date\s*\{\s*([^\}]+)\}/g," \\[date\\] \\[$1 \\[enddate\\] \\[ ");
                  str[i] = str[i].replace(/\\begin\s*\{\s*keyword\s*\}/g," \\[keyword\\] \\[ "); 
                  str[i] = str[i].replace(/\\end\s*\{\s*keyword\s*\}/g," \\[endkeyword\\] \\[ ");
                  str[i] = str[i].replace(/\\begin\s*\{\s*abstract\s*\}/g," \\[abstract\\] \\[ "); 
	              str[i] = str[i].replace(/\\end\s*\{\s*abstract\s*\}/g," \\[endabstract\\] \\[ ");
		  
                  //The rest of the environments -- Users can even "make up their own" -- but it avoids the array and tabular environments
                  str[i] = str[i].replace(/\\begin\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[$1\\] \\[ ");
                  str[i] = str[i].replace(/\\end\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[end$1\\] \\[ ");

                  //Next, we look at section--subsection stuff.  This is nested -- this would be so much better if LaTeX used 
                  //some type of \begin{sectionhead}...\end{sectionhead} structure
                  var sectionIndex = str[i].search(/\\section\s*\{\s*[\s\S]+\}/); 
		  
                  while(sectionIndex >= 0) { 
                     str[i] = str[i].replace(/\\section\s*\{/ ," \\[section\\]");
                     var delimcnt = 1;
                     for(var ii=sectionIndex;ii= 0) { 
                     str[i] = str[i].replace(/\\subsection\s*\{/ ," \\[subsection\\]");
                     var delimcnt = 1;
                     for(var ii=sectionIndex;ii= 0) { 
                     str[i] = str[i].replace(/\\subsubsection\s*\{/ ," \\[subsubsection\\]");
                     var delimcnt = 1;
                     for(var ii=sectionIndex;ii= 0) { // caption may contain other {  } structures -- but not displaymath!!
                                 var tmp = strtmparray[1];
                                 var delimcnt = 0;
                              	 var capstart = -1;
                                 for(var pos=capIndex;pos0) { 
                                       capend = pos-1; 
                                       FIGcap = tmp.substring(capstart,pos);
                                       break 
                                    }
                                 }
                              }
                                                   
                              var FIGtr2 = document.createElement("tr");
                              var FIGtd2  = document.createElement("td");
                              FIGtd2.className="caption";
                  
                               
                              var FIGanchor = document.createElement("a");
                              FIGanchor.className = "figure";
                              if(FIGlbl!=null) {  FIGanchor.id = FIGlbl[1]; }
                              LaTeXCounter["figure"]++;
                              var fignmbr = makeNumberString(LaTeXCounter["figure"]);
                              var anchorSpan = document.createElement("span");
                              anchorSpan.className = "figure";
                              anchorSpan.style.display = "none";
                              anchorSpan.appendChild(document.createTextNode(fignmbr));  
                              FIGanchor.appendChild(anchorSpan); 			     
                              FIGtd2.appendChild(FIGanchor);
			      
                              var FIGspan = document.createElement("span");
                              FIGspan.className = "figure"; //For CSS counters, comment this line
                              FIGspan.appendChild(document.createTextNode("Figure "+fignmbr+". " ) );
                              FIGtd2.appendChild(FIGspan);
                              FIGtd2.appendChild(document.createTextNode(""+FIGcap));
                              FIGtr2.appendChild(FIGtd2);
                              FIGtbody.appendChild(FIGtr2);
                              var IsSpecial = false;
			      
                              var FIGinfo = strtmparray[1].match(/\\includegraphics\s*\{([^\}]+)\}/);
                              if(FIGinfo==null) { //options not processed, for now
                                 FIGinfo = strtmparray[1].match(/\\includegraphics\s*\[[^\]]*\]\s*\{\s*([^\}]+)\s*\}/);
                              }
                              if(FIGinfo==null) {
                                 FIGinfo = strtmparray[1].match(/\\special\s*\{\s*([^\}]+)\}/);
                                 IsSpecial=true //Hook: Later can include "special" graphics commands
                              };
                         
                              if(FIGinfo!=null) { //Caption will be above the image
                                 var FIGtr1 = document.createElement("tr");
                                 var FIGtd1  = document.createElement("td");
                                 FIGtd1.className="image";
                                 var FIGimg = document.createElement("img");
                                 var FIGsrc = FIGinfo[1]; //options not processed, for now
                                 FIGimg.src = FIGsrc;
                                 FIGimg.alt = "Figure "+FIGsrc+" did not load";
                                 FIGimg.title = "Figure "+fignmbr+". "+FIGcap;
                                 FIGimg.id = "figure"+fignmbr;
                                 FIGtd1.appendChild(FIGimg);
                                 FIGtr1.appendChild(FIGtd1);
                                 FIGtbody.appendChild(FIGtr1);
                              }
                              nodeTmp.appendChild(FIGtbody);
                              newFrag.appendChild(nodeTmp); 		      
                           break;
                           case "table": 
                              var nodeTmp = document.createElement("table");
                              if(strtmparray[1].search(/\\centering/) >= 0) {
                                 nodeTmp.className = 'LaTeXtable centered';
                                 nodeTmp.align = "center";
                              } else {
                                 nodeTmp.className = 'LaTeXtable'; 
                              };
                              tableid++;
                              nodeTmp.id = "LaTeXtable"+tableid; //unique id for each table
                              
                              var TABlbl = strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);
                              strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");	
			      
                              var capIndex = strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);  
                              var TABcap = "";
			      
                              if(capIndex >= 0) { // caption may contain other {  } structures -- but not displaymath!!
                                 var tmp = strtmparray[1]; 
                                 var delimcnt = 0;
                                 var capstart = -1;
                                 for(var pos=capIndex;pos0) { 
	                                   capend = pos-1; 
                           		       TABcap = tmp.substring(capstart,pos);
								       break 
								    }
								 }
			  				  }
                                                   
                              if(TABcap!="") {
                                 var TABtbody = document.createElement("tbody");
                                 var TABcaption = document.createElement("caption");
                                 TABcaption.className="LaTeXtable centered";
                                 var TABanchor = document.createElement("a");
   			        			 TABanchor.className = "LaTeXtable";
                                 if(TABlbl!=null) {  TABanchor.id = TABlbl[1]; }
                                 LaTeXCounter["table"]++;
	   					         var tabnmbr = makeNumberString(LaTeXCounter["table"]);
						         var anchorSpan = document.createElement("span");
						         anchorSpan.className = "LaTeXtable";
						         anchorSpan.style.display = "none";
						         anchorSpan.appendChild(document.createTextNode(tabnmbr));  
                                 TABanchor.appendChild(anchorSpan); 			     
						         TABcaption.appendChild(TABanchor);
			      
						         var TABspan = document.createElement("span");
                                 TABspan.className = "LaTeXtable"; //For CSS counters, comment this line
                                 TABspan.appendChild(document.createTextNode("Table "+tabnmbr+". " ) );
						         TABcaption.appendChild(TABspan);
						         TABcaption.appendChild(document.createTextNode(""+TABcap));
                                 nodeTmp.appendChild(TABcaption);
						      }
                              var TABinfo = strtmparray[1].match(/\\begin\s*\{\s*tabular\s*\}([\s\S]+)\\end\s*\{\s*tabular\s*\}/);
						      if(TABinfo!=null) { 
								 var TABtbody = document.createElement('tbody');
								 var TABrow = null;
								 var TABcell = null;
								 var row=0;
								 var col=0;
				 
								 var TABalign = TABinfo[1].match(/^\s*\{([^\}]+)\}/);
								 TABinfo = TABinfo[1].replace(/^\s*\{[^\}]+\}/,"");
								 TABinfo = TABinfo.replace(/\\hline/g,""); //no horizontal bars
								 TABalign[1] = TABalign[1].replace(/\|/g,""); //no vertical bars
								 TABalign[1] = TABalign[1].replace(/\s/g,""); 
								 TABinfo = TABinfo.split("\\\\"); // into rows
								 for(row=0;row -- access it with \cite, thus allowing appropriate labels!
						      if(strtmparray[1]!="") {
								 nodeSpan.appendChild(document.createTextNode(strtmparray[1]));
                              } else { 
                                 nodeSpan.appendChild(document.createTextNode("["+bibcntr+"]"));
                              }
						      nodeTmp.appendChild(nodeSpan);
						      newFrag.appendChild(nodeTmp);
                           break;
                           case "cite":
                              var nodeTmp = document.createElement("a");
                              nodeTmp.className = 'cite'; 
                              nodeTmp.name = 'cite';
                              nodeTmp.href = "#"+strtmparray[1];
                              newFrag.appendChild(nodeTmp);                                                                                                                  
                           break;
                           case "ref":
                              var nodeTmp = document.createElement("a"); 
                              nodeTmp.className = 'ref'; 
                              nodeTmp.name = 'ref';
                              nodeTmp.href = "#"+strtmparray[1];
                              newFrag.appendChild(nodeTmp);                                                                                      
                           break;
                           default : 
                              var nodeTmp = document.createElement("div");
                              nodeTmp.className = strtmparray[0]; 
                              if( IsCounter.test(strtmparray[0]) ) { 
								 LaTeXCounter[strtmparray[0]]++;
                                 var nodeAnchor = document.createElement("a");
                                 nodeAnchor.className = strtmparray[0];
								 var divnum = makeNumberString(LaTeXCounter[strtmparray[0]]);
				 				 var anchorSpan = document.createElement("span");
								 anchorSpan.className = strtmparray[0];
								 anchorSpan.appendChild(document.createTextNode(divnum));
								 anchorSpan.style.display="none";
								 nodeAnchor.appendChild(anchorSpan);
								 nodeTmp.appendChild(nodeAnchor);
				 
								 var nodeSpan = document.createElement("span");
                                 nodeSpan.className = strtmparray[0];
								 nodeSpan.appendChild(document.createTextNode(strtmparray[1]+" "+divnum+". "));
                                 nodeTmp.appendChild(nodeSpan);
                              }
						      if(isIE) { //remove if IE supports :before and :after
								 if(strtmparray[0]==("thebibliography"||"abstract"||"keyword"||"proof")) {
                                    var nodeSpan = document.createElement("span");
                                    nodeSpan.className = strtmparray[0];
								    nodeSpan.appendChild(document.createTextNode(strtmparray[1]));
                                    nodeTmp.appendChild(nodeSpan);
                                 }
                              } //end of IE :before and :after fixes
			    			  if(strtmparray[0]=="endenumerate" || strtmparray[0]=="enditemize" || strtmparray[0]=="enddescription") {
                                 var endDiv = document.createElement("div");
                                 endDiv.className = "endlistitem";
								 newFrag.appendChild(endDiv);
                              }
                              newFrag.appendChild(nodeTmp);
			    			  if(strtmparray[0]=="enumerate" || strtmparray[0]=="itemize" || strtmparray[0]=="description") {
                                 var endDiv = document.createElement("div");
                                 endDiv.className = "listitem";
								 newFrag.appendChild(endDiv);
                              }
                         }
                      } else { 
                      	 //even = text, labels, bf, and italics, and linebreaks, and math -- we now remove the math
                         strtmp[j] = strtmp[j].replace(/\\\$/g,"");
                         strtmp[j] = strtmp[j].replace(/\$([^\$]+)\$/g," \\[$1\\[ ");
                         strtmp[j] = strtmp[j].replace(//g,"\\$");
                         strtmp[j] = strtmp[j].replace(/\\begin\s*\{\s*math\s*\}([\s\S]+?)\\end\s*\{\s*math\s*\}/g," \\[$1\\[ ");

						 var strtmptmp = strtmp[j].split("\\[");
                         
                         for(var jjj=0;jjj-1) {
		      			 	       if(/^\\textcolor/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))) { 
		      			 	          strtmptmp[jjj] = strtmptmp[jjj].replace(/\\textcolor\s*\{\s*(\w+)\s*\}\s*/," \\[textcolor\\]$1\\]|");
		      			 	       } else { 
		      			 	          if(/^\\colorbox/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))) { 
		      			 	             strtmptmp[jjj] = strtmptmp[jjj].replace(/\\colorbox\s*\{\s*(\w+)\s*\}\s*/," \\[colorbox\\]$1\\]|");
		      			 	          } else {
		      			 	             strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).replace(/\\\s*(\w+)\s*/," \\[$1\\]|");
		      			 	          }
		      			 	       }
		      			 	       TagIndex +=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\|/);
		      			 	       TagIndex++;
		      			 	       strtmptmp[jjj] = strtmptmp[jjj].replace(/\\\]\|/,"\\] ");
		      			 	       if(strtmptmp[jjj].charAt(TagIndex) == "{") {
		      			 	          strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length); 
		      			 	          var delimcnt = 1;
		      			 	          for(var kk = TagIndex;kk=0;i--) {
      EndDivClass = AllDivs[i].className.match(/end\w+/ ); 
      if(EndDivClass!=null) {
         EndDivClass = EndDivClass[0]; 
	 var DivClass = EndDivClass.substring(3,EndDivClass.length);
         var EndDivNode = AllDivs[i];
         break; 
      } 
   }  
   while(EndDivClass!=null) {
      // TrackBack to Beginning, appending to newfrag as we go
      var newFrag = document.createDocumentFragment();
      var RootNode = EndDivNode.parentNode;
      var ClassCount = 1; // because of EndDivNode
      while(EndDivNode.previousSibling!=null && ClassCount>0) {
	 switch(EndDivNode.previousSibling.className) {
	    case EndDivClass:	 
	       ClassCount++;
	       newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
	       break;
	    case DivClass: 
	       if(EndDivNode.previousSibling.nodeName=="DIV") { 
	          ClassCount-- ;
		  //Must check to see if we need a label here!
		 if(lbl2id !="" ) { 
		    EndDivNode.previousSibling.id = lbl2id;
		    lbl2id = "" 
		 }
		 if(ClassCount==0) { 
	             RootNode = EndDivNode.previousSibling; 
		  } else {
	             newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
		  }
	       };
	       break;
           case 'LaTeXMathMLlabel':
               lbl2id = EndDivNode.previousSibling.id; 
	          EndDivNode.parentNode.removeChild(EndDivNode.previousSibling);
	       break;
	    default:
	       newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
            }
      }
      RootNode.appendChild(newFrag);
      EndDivNode.parentNode.removeChild(EndDivNode);
      
      //Look for more end div items
      AllDivs = TheBody.getElementsByTagName("DIV");
      for(i=AllDivs.length-1;i>=0;i--) {
         EndDivClass = AllDivs[i].className.match(/end\w+/ );
         if(EndDivClass!=null) {
	    ClassCount = 0;
            EndDivClass = EndDivClass[0]; 
	    DivClass = EndDivClass.substring(3,EndDivClass.length);
            EndDivNode = AllDivs[i];
	    RootNode = EndDivNode.parentNode;
            break; 
         } 
       }     
   } // end while!
   
   

   
   var AllDivs = TheBody.getElementsByTagName("div"); //Convert itemize and enumerate to html lists:
   var DIV2LI = null;
   
   for(var i=0;i0) { 
        for(var m=0;m");
  document.write("");
}

// GO1.1 Generic onload by Brothercake
// http://www.brothercake.com/
//onload function (replaces the onload="translate()" in the  tag)
function generic()
{
  translate();
};
//setup onload function
if(typeof window.addEventListener != 'undefined')
{
  //.. gecko, safari, konqueror and standard
  window.addEventListener('load', generic, false);
}
else if(typeof document.addEventListener != 'undefined')
{
  //.. opera 7
  document.addEventListener('load', generic, false);
}
else if(typeof window.attachEvent != 'undefined')
{
  //.. win/ie
  window.attachEvent('onload', generic);
}
//** remove this condition to degrade older browsers
else
{
  //.. mac/ie5 and anything else that gets this far
  //if there's an existing onload function
  if(typeof window.onload == 'function')
  {
    //store it
    var existing = onload;
    //add new onload handler
    window.onload = function()
    {
      //call existing onload function
      existing();
      //call generic onload function
      generic();
    };
  }
  else
  {
    //setup onload function
    window.onload = generic;
  }
}