1/* 2LaTeXMathML.js 3============== 4 5This file, in this form, is due to Douglas Woodall, June 2006. 6It contains JavaScript functions to convert (most simple) LaTeX 7math notation to Presentation MathML. It was obtained by 8downloading the file ASCIIMathML.js from 9 http://www1.chapman.edu/~jipsen/mathml/asciimathdownload/ 10and modifying it so that it carries out ONLY those conversions 11that would be carried out in LaTeX. A description of the original 12file, with examples, can be found at 13 www1.chapman.edu/~jipsen/mathml/asciimath.html 14 ASCIIMathML: Math on the web for everyone 15 16Here is the header notice from the original file: 17 18ASCIIMathML.js 19============== 20This file contains JavaScript functions to convert ASCII math notation 21to Presentation MathML. The conversion is done while the (X)HTML page 22loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet 23Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/). 24Just add the next line to your (X)HTML page with this file in the same folder: 25<script type="text/javascript" src="ASCIIMathML.js"></script> 26This is a convenient and inexpensive solution for authoring MathML. 27 28Version 1.4.7 Dec 15, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen 29Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js 30For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt 31If you use it on a webpage, please send the URL to [email protected] 32 33This program is free software; you can redistribute it and/or modify 34it under the terms of the GNU General Public License as published by 35the Free Software Foundation; either version 2 of the License, or (at 36your option) any later version. 37 38This program is distributed in the hope that it will be useful, 39but WITHOUT ANY WARRANTY; without even the implied warranty of 40MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41General Public License (at http://www.gnu.org/copyleft/gpl.html) 42for more details. 43 44LaTeXMathML.js (ctd) 45============== 46 47The instructions for use are the same as for the original 48ASCIIMathML.js, except that of course the line you add to your 49file should be 50<script type="text/javascript" src="LaTeXMathML.js"></script> 51Or use absolute path names if the file is not in the same folder 52as your (X)HTML page. 53*/ 54 55var checkForMathML = true; // check if browser can display MathML 56var notifyIfNoMathML = true; // display note if no MathML capability 57var alertIfNoMathML = false; // show alert box if no MathML capability 58// was "red": 59var mathcolor = ""; // change it to "" (to inherit) or any other color 60// was "serif": 61var mathfontfamily = ""; // change to "" to inherit (works in IE) 62 // or another family (e.g. "arial") 63var showasciiformulaonhover = true; // helps students learn ASCIIMath 64/* 65// Commented out by DRW -- not now used -- see DELIMITERS (twice) near the end 66var displaystyle = false; // puts limits above and below large operators 67var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! 68var AMdelimiter1 = "`", AMescape1 = "\\\\`"; // can use other characters 69var AMdelimiter2 = "$", AMescape2 = "\\\\\\$", AMdelimiter2regexp = "\\$"; 70var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1` 71 // for IE this works only in <!-- --> 72//var separatetokens;// has been removed (email me if this is a problem) 73*/ 74var isIE = document.createElementNS==null; 75 76if (document.getElementById==null) 77 alert("This webpage requires a recent browser such as\ 78\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer") 79 80// all further global variables start with "AM" 81 82function AMcreateElementXHTML(t) { 83 if (isIE) return document.createElement(t); 84 else return document.createElementNS("http://www.w3.org/1999/xhtml",t); 85} 86 87function AMnoMathMLNote() { 88 var nd = AMcreateElementXHTML("h3"); 89 nd.setAttribute("align","center") 90 nd.appendChild(AMcreateElementXHTML("p")); 91 nd.appendChild(document.createTextNode("To view the ")); 92 var an = AMcreateElementXHTML("a"); 93 an.appendChild(document.createTextNode("LaTeXMathML"));
94 an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html"); 95 nd.appendChild(an); 96 nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); 97 an = AMcreateElementXHTML("a"); 98 an.appendChild(document.createTextNode("MathPlayer")); 99 an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm"); 100 nd.appendChild(an); 101 nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox")); 102 nd.appendChild(AMcreateElementXHTML("p")); 103 return nd; 104} 105 106function AMisMathMLavailable() { 107 if (navigator.appName.slice(0,8)=="Netscape") 108 if (navigator.appVersion.slice(0,1)>="5") return null; 109 else return AMnoMathMLNote(); 110 else if (navigator.appName.slice(0,9)=="Microsoft") 111 try { 112 var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); 113 return null; 114 } catch (e) { 115 return AMnoMathMLNote(); 116 } 117 else return AMnoMathMLNote(); 118} 119 120// character lists for Mozilla/Netscape fonts 121var 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]; 122var 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]; 123var 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]; 124 125var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, 126 RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, 127 TEXT = 9, BIG = 10, LONG = 11, STRETCHY = 12, MATRIX = 13; // token types 128 129var AMsqrt = {input:"\\sqrt", tag:"msqrt", output:"sqrt", ttype:UNARY}, 130 AMroot = {input:"\\root", tag:"mroot", output:"root", ttype:BINARY}, 131 AMfrac = {input:"\\frac", tag:"mfrac", output:"/", ttype:BINARY}, 132 AMover = {input:"\\stackrel", tag:"mover", output:"stackrel", ttype:BINARY}, 133 AMatop = {input:"\\atop", tag:"mfrac", output:"", ttype:INFIX}, 134 AMchoose = {input:"\\choose", tag:"mfrac", output:"", ttype:INFIX}, 135 AMsub = {input:"_", tag:"msub", output:"_", ttype:INFIX}, 136 AMsup = {input:"^", tag:"msup", output:"^", ttype:INFIX}, 137 AMtext = {input:"\\mathrm", tag:"mtext", output:"text", ttype:TEXT}, 138 AMmbox = {input:"\\mbox", tag:"mtext", output:"mbox", ttype:TEXT}; 139 140// Commented out by DRW to prevent 1/2 turning into a 2-line fraction 141// AMdiv = {input:"/", tag:"mfrac", output:"/", ttype:INFIX}, 142// Commented out by DRW so that " prints literally in equations 143// AMquote = {input:"\"", tag:"mtext", output:"mbox", ttype:TEXT}; 144 145var AMsymbols = [ 146//Greek letters 147{input:"\\alpha", tag:"mi", output:"\u03B1", ttype:CONST}, 148{input:"\\beta", tag:"mi", output:"\u03B2", ttype:CONST}, 149{input:"\\gamma", tag:"mi", output:"\u03B3", ttype:CONST}, 150{input:"\\delta", tag:"mi", output:"\u03B4", ttype:CONST}, 151{input:"\\epsilon", tag:"mi", output:"\u03B5", ttype:CONST}, 152{input:"\\varepsilon", tag:"mi", output:"\u025B", ttype:CONST}, 153{input:"\\zeta", tag:"mi", output:"\u03B6", ttype:CONST}, 154{input:"\\eta", tag:"mi", output:"\u03B7", ttype:CONST}, 155{input:"\\theta", tag:"mi", output:"\u03B8", ttype:CONST}, 156{input:"\\vartheta", tag:"mi", output:"\u03D1", ttype:CONST}, 157{input:"\\iota", tag:"mi", output:"\u03B9", ttype:CONST}, 158{input:"\\kappa", tag:"mi", output:"\u03BA", ttype:CONST}, 159{input:"\\lambda", tag:"mi", output:"\u03BB", ttype:CONST}, 160{input:"\\mu", tag:"mi", output:"\u03BC", ttype:CONST}, 161{input:"\\nu", tag:"mi", output:"\u03BD", ttype:CONST}, 162{input:"\\xi", tag:"mi", output:"\u03BE", ttype:CONST}, 163{input:"\\pi", tag:"mi", output:"\u03C0", ttype:CONST}, 164{input:"\\varpi", tag:"mi", output:"\u03D6", ttype:CONST}, 165{input:"\\rho", tag:"mi", output:"\u03C1", ttype:CONST}, 166{input:"\\varrho", tag:"mi", output:"\u03F1", ttype:CONST}, 167{input:"\\varsigma", tag:"mi", output:"\u03C2", ttype:CONST}, 168{input:"\\sigma", tag:"mi", output:"\u03C3", ttype:CONST}, 169{input:"\\tau", tag:"mi", output:"\u03C4", ttype:CONST}, 170{input:"\\upsilon", tag:"mi", output:"\u03C5", ttype:CONST}, 171{input:"\\phi", tag:"mi", output:"\u03C6", ttype:CONST}, 172{input:"\\varphi", tag:"mi", output:"\u03D5", ttype:CONST}, 173{input:"\\chi", tag:"mi", output:"\u03C7", ttype:CONST}, 174{input:"\\psi", tag:"mi", output:"\u03C8", ttype:CONST}, 175{input:"\\omega", tag:"mi", output:"\u03C9", ttype:CONST}, 176{input:"\\Gamma", tag:"mo", output:"\u0393", ttype:CONST}, 177{input:"\\Delta", tag:"mo", output:"\u0394", ttype:CONST}, 178{input:"\\Theta", tag:"mo", output:"\u0398", ttype:CONST}, 179{input:"\\Lambda", tag:"mo", output:"\u039B", ttype:CONST}, 180{input:"\\Xi", tag:"mo", output:"\u039E", ttype:CONST}, 181{input:"\\Pi", tag:"mo", output:"\u03A0", ttype:CONST}, 182{input:"\\Sigma", tag:"mo", output:"\u03A3", ttype:CONST}, 183{input:"\\Upsilon", tag:"mo", output:"\u03A5", ttype:CONST}, 184{input:"\\Phi", tag:"mo", output:"\u03A6", ttype:CONST}, 185{input:"\\Psi", tag:"mo", output:"\u03A8", ttype:CONST}, 186{input:"\\Omega", tag:"mo", output:"\u03A9", ttype:CONST}, 187 188//fractions 189{input:"\\frac12", tag:"mo", output:"\u00BD", ttype:CONST}, 190{input:"\\frac14", tag:"mo", output:"\u00BC", ttype:CONST}, 191{input:"\\frac34", tag:"mo", output:"\u00BE", ttype:CONST}, 192{input:"\\frac13", tag:"mo", output:"\u2153", ttype:CONST}, 193{input:"\\frac23", tag:"mo", output:"\u2154", ttype:CONST}, 194{input:"\\frac15", tag:"mo", output:"\u2155", ttype:CONST}, 195{input:"\\frac25", tag:"mo", output:"\u2156", ttype:CONST}, 196{input:"\\frac35", tag:"mo", output:"\u2157", ttype:CONST}, 197{input:"\\frac45", tag:"mo", output:"\u2158", ttype:CONST}, 198{input:"\\frac16", tag:"mo", output:"\u2159", ttype:CONST}, 199{input:"\\frac56", tag:"mo", output:"\u215A", ttype:CONST}, 200{input:"\\frac18", tag:"mo", output:"\u215B", ttype:CONST}, 201{input:"\\frac38", tag:"mo", output:"\u215C", ttype:CONST}, 202{input:"\\frac58", tag:"mo", output:"\u215D", ttype:CONST}, 203{input:"\\frac78", tag:"mo", output:"\u215E", ttype:CONST}, 204 205//binary operation symbols 206{input:"\\pm", tag:"mo", output:"\u00B1", ttype:CONST}, 207{input:"\\mp", tag:"mo", output:"\u2213", ttype:CONST}, 208{input:"\\triangleleft",tag:"mo", output:"\u22B2", ttype:CONST}, 209{input:"\\triangleright",tag:"mo",output:"\u22B3", ttype:CONST}, 210{input:"\\cdot", tag:"mo", output:"\u22C5", ttype:CONST}, 211{input:"\\star", tag:"mo", output:"\u22C6", ttype:CONST}, 212{input:"\\ast", tag:"mo", output:"\u002A", ttype:CONST}, 213{input:"\\times", tag:"mo", output:"\u00D7", ttype:CONST}, 214{input:"\\div", tag:"mo", output:"\u00F7", ttype:CONST}, 215{input:"\\circ", tag:"mo", output:"\u2218", ttype:CONST}, 216//{input:"\\bullet", tag:"mo", output:"\u2219", ttype:CONST}, 217{input:"\\bullet", tag:"mo", output:"\u2022", ttype:CONST}, 218{input:"\\oplus", tag:"mo", output:"\u2295", ttype:CONST}, 219{input:"\\ominus", tag:"mo", output:"\u2296", ttype:CONST}, 220{input:"\\otimes", tag:"mo", output:"\u2297", ttype:CONST}, 221{input:"\\bigcirc", tag:"mo", output:"\u25CB", ttype:CONST}, 222{input:"\\oslash", tag:"mo", output:"\u2298", ttype:CONST}, 223{input:"\\odot", tag:"mo", output:"\u2299", ttype:CONST}, 224{input:"\\land", tag:"mo", output:"\u2227", ttype:CONST}, 225{input:"\\wedge", tag:"mo", output:"\u2227", ttype:CONST}, 226{input:"\\lor", tag:"mo", output:"\u2228", ttype:CONST}, 227{input:"\\vee", tag:"mo", output:"\u2228", ttype:CONST}, 228{input:"\\cap", tag:"mo", output:"\u2229", ttype:CONST}, 229{input:"\\cup", tag:"mo", output:"\u222A", ttype:CONST}, 230{input:"\\sqcap", tag:"mo", output:"\u2293", ttype:CONST}, 231{input:"\\sqcup", tag:"mo", output:"\u2294", ttype:CONST}, 232{input:"\\uplus", tag:"mo", output:"\u228E", ttype:CONST}, 233{input:"\\amalg", tag:"mo", output:"\u2210", ttype:CONST},
234{input:"\\bigtriangleup",tag:"mo",output:"\u25B3", ttype:CONST}, 235{input:"\\bigtriangledown",tag:"mo",output:"\u25BD", ttype:CONST}, 236{input:"\\dag", tag:"mo", output:"\u2020", ttype:CONST}, 237{input:"\\dagger", tag:"mo", output:"\u2020", ttype:CONST}, 238{input:"\\ddag", tag:"mo", output:"\u2021", ttype:CONST}, 239{input:"\\ddagger", tag:"mo", output:"\u2021", ttype:CONST}, 240{input:"\\lhd", tag:"mo", output:"\u22B2", ttype:CONST}, 241{input:"\\rhd", tag:"mo", output:"\u22B3", ttype:CONST}, 242{input:"\\unlhd", tag:"mo", output:"\u22B4", ttype:CONST}, 243{input:"\\unrhd", tag:"mo", output:"\u22B5", ttype:CONST}, 244 245 246//BIG Operators 247{input:"\\sum", tag:"mo", output:"\u2211", ttype:UNDEROVER}, 248{input:"\\prod", tag:"mo", output:"\u220F", ttype:UNDEROVER}, 249{input:"\\bigcap", tag:"mo", output:"\u22C2", ttype:UNDEROVER}, 250{input:"\\bigcup", tag:"mo", output:"\u22C3", ttype:UNDEROVER}, 251{input:"\\bigwedge", tag:"mo", output:"\u22C0", ttype:UNDEROVER}, 252{input:"\\bigvee", tag:"mo", output:"\u22C1", ttype:UNDEROVER}, 253{input:"\\bigsqcap", tag:"mo", output:"\u2A05", ttype:UNDEROVER}, 254{input:"\\bigsqcup", tag:"mo", output:"\u2A06", ttype:UNDEROVER}, 255{input:"\\coprod", tag:"mo", output:"\u2210", ttype:UNDEROVER}, 256{input:"\\bigoplus", tag:"mo", output:"\u2A01", ttype:UNDEROVER}, 257{input:"\\bigotimes", tag:"mo", output:"\u2A02", ttype:UNDEROVER}, 258{input:"\\bigodot", tag:"mo", output:"\u2A00", ttype:UNDEROVER}, 259{input:"\\biguplus", tag:"mo", output:"\u2A04", ttype:UNDEROVER}, 260{input:"\\int", tag:"mo", output:"\u222B", ttype:CONST}, 261{input:"\\oint", tag:"mo", output:"\u222E", ttype:CONST}, 262 263//binary relation symbols 264{input:":=", tag:"mo", output:":=", ttype:CONST}, 265{input:"\\lt", tag:"mo", output:"<", ttype:CONST}, 266{input:"\\gt", tag:"mo", output:">", ttype:CONST}, 267{input:"\\ne", tag:"mo", output:"\u2260", ttype:CONST}, 268{input:"\\neq", tag:"mo", output:"\u2260", ttype:CONST}, 269{input:"\\le", tag:"mo", output:"\u2264", ttype:CONST}, 270{input:"\\leq", tag:"mo", output:"\u2264", ttype:CONST}, 271{input:"\\leqslant", tag:"mo", output:"\u2264", ttype:CONST}, 272{input:"\\ge", tag:"mo", output:"\u2265", ttype:CONST}, 273{input:"\\geq", tag:"mo", output:"\u2265", ttype:CONST}, 274{input:"\\geqslant", tag:"mo", output:"\u2265", ttype:CONST}, 275{input:"\\equiv", tag:"mo", output:"\u2261", ttype:CONST}, 276{input:"\\ll", tag:"mo", output:"\u226A", ttype:CONST}, 277{input:"\\gg", tag:"mo", output:"\u226B", ttype:CONST}, 278{input:"\\doteq", tag:"mo", output:"\u2250", ttype:CONST}, 279{input:"\\prec", tag:"mo", output:"\u227A", ttype:CONST}, 280{input:"\\succ", tag:"mo", output:"\u227B", ttype:CONST}, 281{input:"\\preceq", tag:"mo", output:"\u227C", ttype:CONST}, 282{input:"\\succeq", tag:"mo", output:"\u227D", ttype:CONST}, 283{input:"\\subset", tag:"mo", output:"\u2282", ttype:CONST}, 284{input:"\\supset", tag:"mo", output:"\u2283", ttype:CONST}, 285{input:"\\subseteq", tag:"mo", output:"\u2286", ttype:CONST}, 286{input:"\\supseteq", tag:"mo", output:"\u2287", ttype:CONST}, 287{input:"\\sqsubset", tag:"mo", output:"\u228F", ttype:CONST}, 288{input:"\\sqsupset", tag:"mo", output:"\u2290", ttype:CONST}, 289{input:"\\sqsubseteq", tag:"mo", output:"\u2291", ttype:CONST}, 290{input:"\\sqsupseteq", tag:"mo", output:"\u2292", ttype:CONST}, 291{input:"\\sim", tag:"mo", output:"\u223C", ttype:CONST}, 292{input:"\\simeq", tag:"mo", output:"\u2243", ttype:CONST}, 293{input:"\\approx", tag:"mo", output:"\u2248", ttype:CONST}, 294{input:"\\cong", tag:"mo", output:"\u2245", ttype:CONST}, 295{input:"\\Join", tag:"mo", output:"\u22C8", ttype:CONST}, 296{input:"\\bowtie", tag:"mo", output:"\u22C8", ttype:CONST}, 297{input:"\\in", tag:"mo", output:"\u2208", ttype:CONST}, 298{input:"\\ni", tag:"mo", output:"\u220B", ttype:CONST}, 299{input:"\\owns", tag:"mo", output:"\u220B", ttype:CONST}, 300{input:"\\propto", tag:"mo", output:"\u221D", ttype:CONST}, 301{input:"\\vdash", tag:"mo", output:"\u22A2", ttype:CONST}, 302{input:"\\dashv", tag:"mo", output:"\u22A3", ttype:CONST}, 303{input:"\\models", tag:"mo", output:"\u22A8", ttype:CONST}, 304{input:"\\perp", tag:"mo", output:"\u22A5", ttype:CONST}, 305{input:"\\smile", tag:"mo", output:"\u2323", ttype:CONST}, 306{input:"\\frown", tag:"mo", output:"\u2322", ttype:CONST}, 307{input:"\\asymp", tag:"mo", output:"\u224D", ttype:CONST}, 308{input:"\\notin", tag:"mo", output:"\u2209", ttype:CONST}, 309 310//matrices 311{input:"\\begin{eqnarray}", output:"X", ttype:MATRIX, invisible:true}, 312{input:"\\begin{array}", output:"X", ttype:MATRIX, invisible:true}, 313{input:"\\\\", output:"}&{", ttype:DEFINITION}, 314{input:"\\end{eqnarray}", output:"}}", ttype:DEFINITION}, 315{input:"\\end{array}", output:"}}", ttype:DEFINITION}, 316 317//grouping and literal brackets -- ieval is for IE 318{input:"\\big", tag:"mo", output:"X", atval:"1.2", ieval:"2.2", ttype:BIG}, 319{input:"\\Big", tag:"mo", output:"X", atval:"1.6", ieval:"2.6", ttype:BIG}, 320{input:"\\bigg", tag:"mo", output:"X", atval:"2.2", ieval:"3.2", ttype:BIG}, 321{input:"\\Bigg", tag:"mo", output:"X", atval:"2.9", ieval:"3.9", ttype:BIG}, 322{input:"\\left", tag:"mo", output:"X", ttype:LEFTBRACKET}, 323{input:"\\right", tag:"mo", output:"X", ttype:RIGHTBRACKET}, 324{input:"{", output:"{", ttype:LEFTBRACKET, invisible:true}, 325{input:"}", output:"}", ttype:RIGHTBRACKET, invisible:true}, 326 327{input:"(", tag:"mo", output:"(", atval:"1", ttype:STRETCHY}, 328{input:"[", tag:"mo", output:"[", atval:"1", ttype:STRETCHY}, 329{input:"\\lbrack", tag:"mo", output:"[", atval:"1", ttype:STRETCHY}, 330{input:"\\{", tag:"mo", output:"{", atval:"1", ttype:STRETCHY}, 331{input:"\\lbrace", tag:"mo", output:"{", atval:"1", ttype:STRETCHY}, 332{input:"\\langle", tag:"mo", output:"\u2329", atval:"1", ttype:STRETCHY}, 333{input:"\\lfloor", tag:"mo", output:"\u230A", atval:"1", ttype:STRETCHY}, 334{input:"\\lceil", tag:"mo", output:"\u2308", atval:"1", ttype:STRETCHY}, 335 336// rtag:"mi" causes space to be inserted before a following sin, cos, etc. 337// (see function AMparseExpr() ) 338{input:")", tag:"mo",output:")", rtag:"mi",atval:"1",ttype:STRETCHY}, 339{input:"]", tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY}, 340{input:"\\rbrack",tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY}, 341{input:"\\}", tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY}, 342{input:"\\rbrace",tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY}, 343{input:"\\rangle",tag:"mo",output:"\u232A", rtag:"mi",atval:"1",ttype:STRETCHY}, 344{input:"\\rfloor",tag:"mo",output:"\u230B", rtag:"mi",atval:"1",ttype:STRETCHY}, 345{input:"\\rceil", tag:"mo",output:"\u2309", rtag:"mi",atval:"1",ttype:STRETCHY}, 346 347// "|", "\\|", "\\vert" and "\\Vert" modified later: lspace = rspace = 0em 348{input:"|", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 349{input:"\\|", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 350{input:"\\vert", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 351{input:"\\Vert", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 352{input:"\\mid", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 353{input:"\\parallel", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 354{input:"/", tag:"mo", output:"/", atval:"1.01", ttype:STRETCHY}, 355{input:"\\backslash", tag:"mo", output:"\u2216", atval:"1", ttype:STRETCHY}, 356{input:"\\setminus", tag:"mo", output:"\\", ttype:CONST}, 357 358//miscellaneous symbols 359{input:"\\!", tag:"mspace", atname:"width", atval:"-0.167em", ttype:SPACE}, 360{input:"\\,", tag:"mspace", atname:"width", atval:"0.167em", ttype:SPACE}, 361{input:"\\>", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE}, 362{input:"\\:", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE}, 363{input:"\\;", tag:"mspace", atname:"width", atval:"0.278em", ttype:SPACE}, 364{input:"~", tag:"mspace", atname:"width", atval:"0.333em", ttype:SPACE}, 365{input:"\\quad", tag:"mspace", atname:"width", atval:"1em", ttype:SPACE}, 366{input:"\\qquad", tag:"mspace", atname:"width", atval:"2em", ttype:SPACE}, 367//{input:"{}", tag:"mo", output:"\u200B", ttype:CONST}, // zero-width 368{input:"\\prime", tag:"mo", output:"\u2032", ttype:CONST}, 369{input:"'", tag:"mo", output:"\u02B9", ttype:CONST}, 370{input:"''", tag:"mo", output:"\u02BA", ttype:CONST}, 371{input:"'''", tag:"mo", output:"\u2034", ttype:CONST}, 372{input:"''''", tag:"mo", output:"\u2057", ttype:CONST}, 373{input:"\\ldots", tag:"mo", output:"\u2026", ttype:CONST}, 374{input:"\\cdots", tag:"mo", output:"\u22EF", ttype:CONST}, 375{input:"\\vdots", tag:"mo", output:"\u22EE", ttype:CONST}, 376{input:"\\ddots", tag:"mo", output:"\u22F1", ttype:CONST}, 377{input:"\\forall", tag:"mo", output:"\u2200", ttype:CONST}, 378{input:"\\exists", tag:"mo", output:"\u2203", ttype:CONST}, 379{input:"\\Re", tag:"mo", output:"\u211C", ttype:CONST}, 380{input:"\\Im", tag:"mo", output:"\u2111", ttype:CONST}, 381{input:"\\aleph", tag:"mo", output:"\u2135", ttype:CONST}, 382{input:"\\hbar", tag:"mo", output:"\u210F", ttype:CONST}, 383{input:"\\ell", tag:"mo", output:"\u2113", ttype:CONST}, 384{input:"\\wp", tag:"mo", output:"\u2118", ttype:CONST}, 385{input:"\\emptyset", tag:"mo", output:"\u2205", ttype:CONST}, 386{input:"\\infty", tag:"mo", output:"\u221E", ttype:CONST}, 387{input:"\\surd", tag:"mo", output:"\\sqrt{}", ttype:DEFINITION}, 388{input:"\\partial", tag:"mo", output:"\u2202", ttype:CONST}, 389{input:"\\nabla", tag:"mo", output:"\u2207", ttype:CONST}, 390{input:"\\triangle", tag:"mo", output:"\u25B3", ttype:CONST}, 391{input:"\\therefore", tag:"mo", output:"\u2234", ttype:CONST}, 392{input:"\\angle", tag:"mo", output:"\u2220", ttype:CONST}, 393//{input:"\\\\ ", tag:"mo", output:"\u00A0", ttype:CONST}, 394{input:"\\diamond", tag:"mo", output:"\u22C4", ttype:CONST}, 395//{input:"\\Diamond", tag:"mo", output:"\u25CA", ttype:CONST}, 396{input:"\\Diamond", tag:"mo", output:"\u25C7", ttype:CONST}, 397{input:"\\neg", tag:"mo", output:"\u00AC", ttype:CONST}, 398{input:"\\lnot", tag:"mo", output:"\u00AC", ttype:CONST}, 399{input:"\\bot", tag:"mo", output:"\u22A5", ttype:CONST}, 400{input:"\\top", tag:"mo", output:"\u22A4", ttype:CONST}, 401{input:"\\square", tag:"mo", output:"\u25AB", ttype:CONST}, 402{input:"\\Box", tag:"mo", output:"\u25A1", ttype:CONST}, 403{input:"\\wr", tag:"mo", output:"\u2240", ttype:CONST}, 404 405//standard functions 406//Note UNDEROVER *must* have tag:"mo" to work properly 407{input:"\\arccos", tag:"mi", output:"arccos", ttype:UNARY, func:true}, 408{input:"\\arcsin", tag:"mi", output:"arcsin", ttype:UNARY, func:true}, 409{input:"\\arctan", tag:"mi", output:"arctan", ttype:UNARY, func:true}, 410{input:"\\arg", tag:"mi", output:"arg", ttype:UNARY, func:true}, 411{input:"\\cos", tag:"mi", output:"cos", ttype:UNARY, func:true}, 412{input:"\\cosh", tag:"mi", output:"cosh", ttype:UNARY, func:true}, 413{input:"\\cot", tag:"mi", output:"cot", ttype:UNARY, func:true}, 414{input:"\\coth", tag:"mi", output:"coth", ttype:UNARY, func:true}, 415{input:"\\csc", tag:"mi", output:"csc", ttype:UNARY, func:true}, 416{input:"\\deg", tag:"mi", output:"deg", ttype:UNARY, func:true}, 417{input:"\\det", tag:"mi", output:"det", ttype:UNARY, func:true}, 418{input:"\\dim", tag:"mi", output:"dim", ttype:UNARY, func:true}, //CONST? 419{input:"\\exp", tag:"mi", output:"exp", ttype:UNARY, func:true}, 420{input:"\\gcd", tag:"mi", output:"gcd", ttype:UNARY, func:true}, //CONST? 421{input:"\\hom", tag:"mi", output:"hom", ttype:UNARY, func:true}, 422{input:"\\inf", tag:"mo", output:"inf", ttype:UNDEROVER}, 423{input:"\\ker", tag:"mi", output:"ker", ttype:UNARY, func:true}, 424{input:"\\lg", tag:"mi", output:"lg", ttype:UNARY, func:true}, 425{input:"\\lim", tag:"mo", output:"lim", ttype:UNDEROVER}, 426{input:"\\liminf", tag:"mo", output:"liminf", ttype:UNDEROVER}, 427{input:"\\limsup", tag:"mo", output:"limsup", ttype:UNDEROVER}, 428{input:"\\ln", tag:"mi", output:"ln", ttype:UNARY, func:true}, 429{input:"\\log", tag:"mi", output:"log", ttype:UNARY, func:true}, 430{input:"\\max", tag:"mo", output:"max", ttype:UNDEROVER}, 431{input:"\\min", tag:"mo", output:"min", ttype:UNDEROVER}, 432{input:"\\Pr", tag:"mi", output:"Pr", ttype:UNARY, func:true}, 433{input:"\\sec", tag:"mi", output:"sec", ttype:UNARY, func:true}, 434{input:"\\sin", tag:"mi", output:"sin", ttype:UNARY, func:true}, 435{input:"\\sinh", tag:"mi", output:"sinh", ttype:UNARY, func:true}, 436{input:"\\sup", tag:"mo", output:"sup", ttype:UNDEROVER}, 437{input:"\\tan", tag:"mi", output:"tan", ttype:UNARY, func:true}, 438{input:"\\tanh", tag:"mi", output:"tanh", ttype:UNARY, func:true}, 439 440//arrows 441{input:"\\gets", tag:"mo", output:"\u2190", ttype:CONST}, 442{input:"\\leftarrow", tag:"mo", output:"\u2190", ttype:CONST}, 443{input:"\\to", tag:"mo", output:"\u2192", ttype:CONST}, 444{input:"\\rightarrow", tag:"mo", output:"\u2192", ttype:CONST}, 445{input:"\\leftrightarrow", tag:"mo", output:"\u2194", ttype:CONST}, 446{input:"\\uparrow", tag:"mo", output:"\u2191", ttype:CONST}, 447{input:"\\downarrow", tag:"mo", output:"\u2193", ttype:CONST}, 448{input:"\\updownarrow", tag:"mo", output:"\u2195", ttype:CONST}, 449{input:"\\Leftarrow", tag:"mo", output:"\u21D0", ttype:CONST}, 450{input:"\\Rightarrow", tag:"mo", output:"\u21D2", ttype:CONST}, 451{input:"\\Leftrightarrow", tag:"mo", output:"\u21D4", ttype:CONST}, 452{input:"\\iff", tag:"mo", output:"~\\Longleftrightarrow~", ttype:DEFINITION}, 453{input:"\\Uparrow", tag:"mo", output:"\u21D1", ttype:CONST}, 454{input:"\\Downarrow", tag:"mo", output:"\u21D3", ttype:CONST}, 455{input:"\\Updownarrow", tag:"mo", output:"\u21D5", ttype:CONST}, 456{input:"\\mapsto", tag:"mo", output:"\u21A6", ttype:CONST}, 457{input:"\\longleftarrow", tag:"mo", output:"\u2190", ttype:LONG}, 458{input:"\\longrightarrow", tag:"mo", output:"\u2192", ttype:LONG}, 459{input:"\\longleftrightarrow", tag:"mo", output:"\u2194", ttype:LONG}, 460{input:"\\Longleftarrow", tag:"mo", output:"\u21D0", ttype:LONG}, 461{input:"\\Longrightarrow", tag:"mo", output:"\u21D2", ttype:LONG}, 462{input:"\\Longleftrightarrow", tag:"mo", output:"\u21D4", ttype:LONG}, 463{input:"\\longmapsto", tag:"mo", output:"\u21A6", ttype:CONST}, 464 // disaster if LONG 465 466//commands with argument 467AMsqrt, AMroot, AMfrac, AMover, AMsub, AMsup, AMtext, AMmbox, AMatop, AMchoose, 468//AMdiv, AMquote, 469 470//diacritical marks 471{input:"\\acute", tag:"mover", output:"\u00B4", ttype:UNARY, acc:true}, 472//{input:"\\acute", tag:"mover", output:"\u0317", ttype:UNARY, acc:true}, 473//{input:"\\acute", tag:"mover", output:"\u0301", ttype:UNARY, acc:true}, 474//{input:"\\grave", tag:"mover", output:"\u0300", ttype:UNARY, acc:true}, 475//{input:"\\grave", tag:"mover", output:"\u0316", ttype:UNARY, acc:true}, 476{input:"\\grave", tag:"mover", output:"\u0060", ttype:UNARY, acc:true}, 477{input:"\\breve", tag:"mover", output:"\u02D8", ttype:UNARY, acc:true}, 478{input:"\\check", tag:"mover", output:"\u02C7", ttype:UNARY, acc:true}, 479{input:"\\dot", tag:"mover", output:".", ttype:UNARY, acc:true}, 480{input:"\\ddot", tag:"mover", output:"..", ttype:UNARY, acc:true}, 481//{input:"\\ddot", tag:"mover", output:"\u00A8", ttype:UNARY, acc:true}, 482{input:"\\mathring", tag:"mover", output:"\u00B0", ttype:UNARY, acc:true}, 483{input:"\\vec", tag:"mover", output:"\u20D7", ttype:UNARY, acc:true}, 484{input:"\\overrightarrow",tag:"mover",output:"\u20D7", ttype:UNARY, acc:true}, 485{input:"\\overleftarrow",tag:"mover", output:"\u20D6", ttype:UNARY, acc:true}, 486{input:"\\hat", tag:"mover", output:"\u005E", ttype:UNARY, acc:true}, 487{input:"\\widehat", tag:"mover", output:"\u0302", ttype:UNARY, acc:true}, 488{input:"\\tilde", tag:"mover", output:"~", ttype:UNARY, acc:true}, 489//{input:"\\tilde", tag:"mover", output:"\u0303", ttype:UNARY, acc:true}, 490{input:"\\widetilde", tag:"mover", output:"\u02DC", ttype:UNARY, acc:true}, 491{input:"\\bar", tag:"mover", output:"\u203E", ttype:UNARY, acc:true}, 492{input:"\\overbrace", tag:"mover", output:"\u23B4", ttype:UNARY, acc:true}, 493{input:"\\overline", tag:"mover", output:"\u00AF", ttype:UNARY, acc:true}, 494{input:"\\underbrace", tag:"munder", output:"\u23B5", ttype:UNARY, acc:true}, 495{input:"\\underline", tag:"munder", output:"\u00AF", ttype:UNARY, acc:true}, 496//{input:"underline", tag:"munder", output:"\u0332", ttype:UNARY, acc:true}, 497 498//typestyles and fonts 499{input:"\\displaystyle",tag:"mstyle",atname:"displaystyle",atval:"true", ttype:UNARY}, 500{input:"\\textstyle",tag:"mstyle",atname:"displaystyle",atval:"false", ttype:UNARY}, 501{input:"\\scriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"1", ttype:UNARY}, 502{input:"\\scriptscriptstyle",tag:"mstyle",atname:"scriptlevel",a
502tval:"2", ttype:UNARY}, 503{input:"\\textrm", tag:"mstyle", output:"\\mathrm", ttype: DEFINITION}, 504{input:"\\mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY}, 505{input:"\\textbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY}, 506{input:"\\mathit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY}, 507{input:"\\textit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY}, 508{input:"\\mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY}, 509{input:"\\texttt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY}, 510{input:"\\mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", ttype:UNARY}, 511{input:"\\mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", ttype:UNARY, codes:AMbbb}, 512{input:"\\mathcal",tag:"mstyle", atname:"mathvariant", atval:"script", ttype:UNARY, codes:AMcal}, 513{input:"\\mathfrak",tag:"mstyle",atname:"mathvariant", atval:"fraktur",ttype:UNARY, codes:AMfrk} 514]; 515 516function compareNames(s1,s2) { 517 if (s1.input > s2.input) return 1 518 else return -1; 519} 520 521var AMnames = []; //list of input symbols 522 523function AMinitSymbols() { 524 AMsymbols.sort(compareNames); 525 for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input; 526} 527 528var AMmathml = "http://www.w3.org/1998/Math/MathML"; 529 530function AMcreateElementMathML(t) { 531 if (isIE) return document.createElement("m:"+t); 532 else return document.createElementNS(AMmathml,t); 533} 534 535function AMcreateMmlNode(t,frag) { 536// var node = AMcreateElementMathML(name); 537 if (isIE) var node = document.createElement("m:"+t); 538 else var node = document.createElementNS(AMmathml,t); 539 node.appendChild(frag); 540 return node; 541} 542 543function newcommand(oldstr,newstr) { 544 AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, 545 ttype:DEFINITION}]); 546} 547 548function AMremoveCharsAndBlanks(str,n) { 549//remove n characters and any following blanks 550 var st; 551 st = str.slice(n); 552 for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1); 553 return st.slice(i); 554} 555 556function AMposition(arr, str, n) { 557// return position >=n where str appears or would be inserted 558// assumes arr is sorted 559 if (n==0) { 560 var h,m; 561 n = -1; 562 h = arr.length; 563 while (n+1<h) { 564 m = (n+h) >> 1; 565 if (arr[m]<str) n = m; else h = m; 566 } 567 return h; 568 } else 569 for (var i=n; i<arr.length && arr[i]<str; i++); 570 return i; // i=arr.length || arr[i]>=str 571} 572 573function AMgetSymbol(str) { 574//return maximal initial substring of str that appears in names 575//return null if there is none 576 var k = 0; //new pos 577 var j = 0; //old pos 578 var mk; //match pos 579 var st; 580 var tagst; 581 var match = ""; 582 var more = true; 583 for (var i=1; i<=str.length && more; i++) { 584 st = str.slice(0,i); //initial substring of length i 585 j = k; 586 k = AMposition(AMnames, st, j); 587 if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){ 588 match = AMnames[k]; 589 mk = k; 590 i = match.length; 591 } 592 more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k]; 593 } 594 AMpreviousSymbol=AMcurrentSymbol; 595 if (match!=""){ 596 AMcurrentSymbol=AMsymbols[mk].ttype; 597 return AMsymbols[mk]; 598 } 599 AMcurrentSymbol=CONST; 600 k = 1; 601 st = str.slice(0,1); //take 1 character 602 if ("0"<=st && st<="9") tagst = "mn"; 603 else tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi"); 604/* 605// Commented out by DRW (not fully understood, but probably to do with 606// use of "/" as an INFIX version of "\\frac", which we don't want): 607//} 608//if (st=="-" && AMpreviousSymbol==INFIX) { 609// AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse 610// return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; 611//} 612*/ 613 return {input:st, tag:tagst, output:st, ttype:CONST}; 614} 615 616 617/*Parsing ASCII math expressions with the following grammar 618v ::= [A-Za-z] | greek letters | numbers | other constant symbols 619u ::= sqrt | text | bb | other unary symbols for font commands 620b ::= frac | root | stackrel binary symbols 621l ::= { | \left left brackets 622r ::= } | \right right brackets 623S ::= v | lEr | uS | bSS Simple expression 624I ::= S_S | S^S | S_S^S | S Intermediate expression
625E ::= IE | I/I Expression 626Each terminal symbol is translated into a corresponding mathml node.*/ 627 628var AMpreviousSymbol,AMcurrentSymbol; 629 630function AMparseSexpr(str) { //parses str and returns [node,tailstr,(node)tag] 631 var symbol, node, result, result2, i, st,// rightvert = false, 632 newFrag = document.createDocumentFragment(); 633 str = AMremoveCharsAndBlanks(str,0); 634 symbol = AMgetSymbol(str); //either a token or a bracket or empty 635 if (symbol == null || symbol.ttype == RIGHTBRACKET) 636 return [null,str,null]; 637 if (symbol.ttype == DEFINITION) { 638 str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); 639 symbol = AMgetSymbol(str); 640 if (symbol == null || symbol.ttype == RIGHTBRACKET) 641 return [null,str,null]; 642 } 643 str = AMremoveCharsAndBlanks(str,symbol.input.length); 644 switch (symbol.ttype) { 645 case SPACE: 646 node = AMcreateElementMathML(symbol.tag); 647 node.setAttribute(symbol.atname,symbol.atval); 648 return [node,str,symbol.tag]; 649 case UNDEROVER: 650 if (isIE) { 651 if (symbol.input.substr(0,4) == "\\big") { // botch for missing symbols 652 str = "\\"+symbol.input.substr(4)+str; // make \bigcup = \cup etc. 653 symbol = AMgetSymbol(str); 654 symbol.ttype = UNDEROVER; 655 str = AMremoveCharsAndBlanks(str,symbol.input.length); 656 } 657 } 658 return [AMcreateMmlNode(symbol.tag, 659 document.createTextNode(symbol.output)),str,symbol.tag]; 660 case CONST: 661 var output = symbol.output; 662 if (isIE) { 663 if (symbol.input == "'") 664 output = "\u2032"; 665 else if (symbol.input == "''") 666 output = "\u2033"; 667 else if (symbol.input == "'''") 668 output = "\u2033\u2032"; 669 else if (symbol.input == "''''") 670 output = "\u2033\u2033"; 671 else if (symbol.input == "\\square") 672 output = "\u25A1"; // same as \Box 673 else if (symbol.input.substr(0,5) == "\\frac") { 674 // botch for missing fractions 675 var denom = symbol.input.substr(6,1); 676 if (denom == "5" || denom == "6") { 677 str = symbol.input.replace(/\\frac/,"\\frac ")+str; 678 return [node,str,symbol.tag]; 679 } 680 } 681 } 682 node = AMcreateMmlNode(symbol.tag,document.createTextNode(output)); 683 return [node,str,symbol.tag]; 684 case LONG: // added by DRW 685 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 686 node.setAttribute("minsize","1.5"); 687 node.setAttribute("maxsize","1.5"); 688 node = AMcreateMmlNode("mover",node); 689 node.appendChild(AMcreateElementMathML("mspace")); 690 return [node,str,symbol.tag]; 691 case STRETCHY: // added by DRW 692 if (isIE && symbol.input == "\\backslash") 693 symbol.output = "\\"; // doesn't expand, but then nor does "\u2216" 694 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 695 if (symbol.input == "|" || symbol.input == "\\vert" || 696 symbol.input == "\\|" || symbol.input == "\\Vert") { 697 node.setAttribute("lspace","0em"); 698 node.setAttribute("rspace","0em"); 699 } 700 node.setAttribute("maxsize",symbol.atval); // don't allow to stretch here 701 if (symbol.rtag != null) 702 return [node,str,symbol.rtag]; 703 else 704 return [node,str,symbol.tag]; 705 case BIG: // added by DRW 706 var atval = symbol.atval; 707 if (isIE) 708 atval = symbol.ieval; 709 symbol = AMgetSymbol(str); 710 if (symbol == null) 711 return [null,str,null]; 712 str = AMremoveCharsAndBlanks(str,symbol.input.length); 713 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 714 if (isIE) { // to get brackets to expand 715 var space = AMcreateElementMathML("mspace"); 716 space.setAttribute("height",atval+"ex"); 717 node = AMcreateMmlNode("mrow",node); 718 node.appendChild(space); 719 } else { // ignored in IE 720 node.setAttribute("minsize",atval); 721 node.setAttribute("maxsize",atval); 722 } 723 return [node,str,symbol.tag]; 724 case LEFTBRACKET: //read (expr+) 725 if (symbol.input == "\\left") { // left what? 726 symbol = AMgetSymbol(str); 727 if (symbol != null) { 728 if (symbol.input == ".") 729 symbol.invisible = true; 730 str = AMremoveCharsAndBlanks(str,symbol.input.length); 731 } 732 } 733 result = AMparseExpr(str,true,false); 734 if (symbol==null || 735 (typeof symbol.invisible == "boolean" && symbol.invisible)) 736 node = AMcreateMmlNode("mrow",result[0]); 737 else { 738 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
739 node = AMcreateMmlNode("mrow",node); 740 node.appendChild(result[0]); 741 } 742 return [node,result[1],result[2]]; 743 case MATRIX: //read (expr+) 744 if (symbol.input == "\\begin{array}") { 745 var mask = ""; 746 symbol = AMgetSymbol(str); 747 str = AMremoveCharsAndBlanks(str,0); 748 if (symbol == null) 749 mask = "l"; 750 else { 751 str = AMremoveCharsAndBlanks(str,symbol.input.length); 752 if (symbol.input != "{") 753 mask = "l"; 754 else do { 755 symbol = AMgetSymbol(str); 756 if (symbol != null) { 757 str = AMremoveCharsAndBlanks(str,symbol.input.length); 758 if (symbol.input != "}") 759 mask = mask+symbol.input; 760 } 761 } while (symbol != null && symbol.input != "" && symbol.input != "}"); 762 } 763 result = AMparseExpr("{"+str,true,true); 764// if (result[0]==null) return [AMcreateMmlNode("mo", 765// document.createTextNode(symbol.input)),str]; 766 node = AMcreateMmlNode("mtable",result[0]); 767 mask = mask.replace(/l/g,"left "); 768 mask = mask.replace(/r/g,"right "); 769 mask = mask.replace(/c/g,"center "); 770 node.setAttribute("columnalign",mask); 771 node.setAttribute("displaystyle","false"); 772 if (isIE) 773 return [node,result[1],null]; 774// trying to get a *little* bit of space around the array 775// (IE already includes it) 776 var lspace = AMcreateElementMathML("mspace"); 777 lspace.setAttribute("width","0.167em"); 778 var rspace = AMcreateElementMathML("mspace"); 779 rspace.setAttribute("width","0.167em"); 780 var node1 = AMcreateMmlNode("mrow",lspace); 781 node1.appendChild(node); 782 node1.appendChild(rspace); 783 return [node1,result[1],null]; 784 } else { // eqnarray 785 result = AMparseExpr("{"+str,true,true); 786 node = AMcreateMmlNode("mtable",result[0]); 787 if (isIE) 788 node.setAttribute("columnspacing","0.25em"); // best in practice? 789 else 790 node.setAttribute("columnspacing","0.167em"); // correct (but ignored?) 791 node.setAttribute("columnalign","right center left"); 792 node.setAttribute("displaystyle","true"); 793 node = AMcreateMmlNode("mrow",node); 794 return [node,result[1],null]; 795 } 796 case TEXT: 797 if (str.charAt(0)=="{") i=str.indexOf("}"); 798 else i = 0; 799 if (i==-1) 800 i = str.length; 801 st = str.slice(1,i); 802 if (st.charAt(0) == " ") { 803 node = AMcreateElementMathML("mspace"); 804 node.setAttribute("width","0.33em"); // was 1ex 805 newFrag.appendChild(node); 806 } 807 newFrag.appendChild( 808 AMcreateMmlNode(symbol.tag,document.createTextNode(st))); 809 if (st.charAt(st.length-1) == " ") { 810 node = AMcreateElementMathML("mspace"); 811 node.setAttribute("width","0.33em"); // was 1ex 812 newFrag.appendChild(node); 813 } 814 str = AMremoveCharsAndBlanks(str,i+1); 815 return [AMcreateMmlNode("mrow",newFrag),str,null]; 816 case UNARY: 817 result = AMparseSexpr(str); 818 if (result[0]==null) return [AMcreateMmlNode(symbol.tag, 819 document.createTextNode(symbol.output)),str]; 820 if (typeof symbol.func == "boolean" && symbol.func) { // functions hack 821 st = str.charAt(0); 822// if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") { 823 if (st=="^" || st=="_" || st==",") { 824 return [AMcreateMmlNode(symbol.tag, 825 document.createTextNode(symbol.output)),str,symbol.tag]; 826 } else { 827 node = AMcreateMmlNode("mrow", 828 AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); 829 if (isIE) { 830 var space = AMcreateElementMathML("mspace"); 831 space.setAttribute("width","0.167em"); 832 node.appendChild(space); 833 } 834 node.appendChild(result[0]); 835 return [node,result[1],symbol.tag]; 836 } 837 } 838 if (symbol.input == "\\sqrt") { // sqrt 839 if (isIE) { // set minsize, for \surd 840 var space = AMcreateElementMathML("mspace"); 841 space.setAttribute("height","1.2ex"); 842 space.setAttribute("width","0em"); // probably no effect 843 node = AMcreateMmlNode(symbol.tag,result[0]) 844// node.setAttribute("minsize","1"); // ignored 845// node = AMcreateMmlNode("mrow",node); // hopefully unnecessary 846 node.appendChild(space); 847 return [node,result[1],symbol.tag]; 848 } else 849 return [AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag]; 850 } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent 851 node = AMcreateMmlNode(symbol.tag,result[0]); 852 var output = symbol.output; 853 if (isIE) { 854 if (symbol.input == "\\hat") 855 output = "\u0302"; 856 else if (symbol.input == "\\widehat") 857 output = "\u005E"; 858 else if (symbol.input == "\\bar") 859 output = "\u00AF"; 860 else if (symbol.input == "\\grave") 861 output = "\u0300"; 862 else if (symbol.input == "\\tilde") 863 output = "\u0303"; 864 } 865 var node1 = AMcreateMmlNode("mo",document.createTextNode(output)); 866 if (symbol.input == "\\vec" || symbol.input == "\\check") 867 // don't allow to stretch 868 node1.setAttribute("maxsize","1.2"); 869 // why doesn't "1" work? \vec nearly disappears in firefox 870 if (isIE && symbol.input == "\\bar") 871 node1.setAttribute("maxsize","0.5"); 872 if (symbol.input == "\\underbrace" || symbol.input == "\\underline") 873 node1.setAttribute("accentunder","true"); 874 else 875 node1.setAttribute("accent","true"); 876 node.appendChild(node1); 877 if (symbol.input == "\\overbrace" || symbol.input == "\\underbrace") 878 node.ttype = UNDEROVER; 879 return [node,result[1],symbol.tag]; 880 } else { // font change or displaystyle command 881 if (!isIE && typeof symbol.codes != "undefined") { 882 for (i=0; i<result[0].childNodes.length; i++) 883 if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") { 884 st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue: 885 result[0].childNodes[i].firstChild.nodeValue); 886 var newst = []; 887 for (var j=0; j<st.length; j++) 888 if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) newst = newst + 889 String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]); 890 else newst = newst + st.charAt(j); 891 if (result[0].nodeName=="mi") 892 result[0]=AMcreateElementMathML("mo"). 893 appendChild(document.createTextNode(newst)); 894 else result[0].replaceChild(AMcreateElementMathML("mo"). 895 appendChild(document.createTextNode(newst)),result[0].childNodes[i]); 896 } 897 } 898 node = AMcreateMmlNode(symbol.tag,result[0]); 899 node.setAttribute(symbol.atname,symbol.atval); 900 if (symbol.input == "\\scriptstyle" || 901 symbol.input == "\\scriptscriptstyle") 902 node.setAttribute("displaystyle","false"); 903 return [node,result[1],symbol.tag]; 904 } 905 case BINARY: 906 result = AMparseSexpr(str); 907 if (result[0]==null) return [AMcreateMmlNode("mo", 908 document.createTextNode(symbol.input)),str,null]; 909 result2 = AMparseSexpr(result[1]); 910 if (result2[0]==null) return [AMcreateMmlNode("mo", 911 document.createTextNode(symbol.input)),str,null];
912 if (symbol.input=="\\root" || symbol.input=="\\stackrel") 913 newFrag.appendChild(result2[0]); 914 newFrag.appendChild(result[0]); 915 if (symbol.input=="\\frac") newFrag.appendChild(result2[0]); 916 return [AMcreateMmlNode(symbol.tag,newFrag),result2[1],symbol.tag]; 917 case INFIX: 918 str = AMremoveCharsAndBlanks(str,symbol.input.length); 919 return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)), 920 str,symbol.tag]; 921 default: 922 return [AMcreateMmlNode(symbol.tag, //its a constant 923 document.createTextNode(symbol.output)),str,symbol.tag]; 924 } 925} 926 927function AMparseIexpr(str) { 928 var symbol, sym1, sym2, node, result, tag, underover; 929 str = AMremoveCharsAndBlanks(str,0); 930 sym1 = AMgetSymbol(str); 931 result = AMparseSexpr(str); 932 node = result[0]; 933 str = result[1]; 934 tag = result[2]; 935 symbol = AMgetSymbol(str); 936 if (symbol.ttype == INFIX) { 937 str = AMremoveCharsAndBlanks(str,symbol.input.length); 938 result = AMparseSexpr(str); 939 if (result[0] == null) // show box in place of missing argument 940 result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); 941 str = result[1]; 942 tag = result[2]; 943 if (symbol.input == "_" || symbol.input == "^") { 944 sym2 = AMgetSymbol(str); 945 tag = null; // no space between x^2 and a following sin, cos, etc. 946// This is for \underbrace and \overbrace 947 underover = ((sym1.ttype == UNDEROVER) || (node.ttype == UNDEROVER)); 948// underover = (sym1.ttype == UNDEROVER); 949 if (symbol.input == "_" && sym2.input == "^") { 950 str = AMremoveCharsAndBlanks(str,sym2.input.length); 951 var res2 = AMparseSexpr(str); 952 str = res2[1]; 953 tag = res2[2]; // leave space between x_1^2 and a following sin etc. 954 node = AMcreateMmlNode((underover?"munderover":"msubsup"),node); 955 node.appendChild(result[0]); 956 node.appendChild(res2[0]); 957 } else if (symbol.input == "_") { 958 node = AMcreateMmlNode((underover?"munder":"msub"),node); 959 node.appendChild(result[0]); 960 } else { 961 node = AMcreateMmlNode((underover?"mover":"msup"),node); 962 node.appendChild(result[0]); 963 } 964 node = AMcreateMmlNode("mrow",node); // so sum does not stretch 965 } else { 966 node = AMcreateMmlNode(symbol.tag,node); 967 if (symbol.input == "\\atop" || symbol.input == "\\choose") 968 node.setAttribute("linethickness","0ex"); 969 node.appendChild(result[0]); 970 if (symbol.input == "\\choose") 971 node = AMcreateMmlNode("mfenced",node); 972 } 973 } 974 return [node,str,tag]; 975} 976 977function AMparseExpr(str,rightbracket,matrix) { 978 var symbol, node, result, i, tag, 979 newFrag = document.createDocumentFragment(); 980 do { 981 str = AMremoveCharsAndBlanks(str,0); 982 result = AMparseIexpr(str); 983 node = result[0]; 984 str = result[1]; 985 tag = result[2]; 986 symbol = AMgetSymbol(str); 987 if (node!=undefined) { 988 if ((tag == "mn" || tag == "mi") && symbol!=null && 989 typeof symbol.func == "boolean" && symbol.func) { 990 // Add space before \sin in 2\sin x or x\sin x 991 var space = AMcreateElementMathML("mspace"); 992 space.setAttribute("width","0.167em"); 993 node = AMcreateMmlNode("mrow",node); 994 node.appendChild(space); 995 } 996 newFrag.appendChild(node); 997 } 998 } while ((symbol.ttype != RIGHTBRACKET) 999 && symbol!=null && symbol.output!=""); 1000 tag = null; 1001 if (symbol.ttype == RIGHTBRACKET) { 1002 if (symbol.input == "\\right") { // right what? 1003 str = AMremoveCharsAndBlanks(str,symbol.input.length); 1004 symbol = AMgetSymbol(str); 1005 if (symbol != null && symbol.input == ".") 1006 symbol.invisible = true; 1007 if (symbol != null) 1008 tag = symbol.rtag; 1009 } 1010 if (symbol!=null) 1011 str = AMremoveCharsAndBlanks(str,symbol.input.length); // ready to return 1012 var len = newFrag.childNodes.length; 1013 if (matrix && 1014 len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 && 1015 newFrag.childNodes[len-2].nodeName == "mo" && 1016 newFrag.childNodes[len-2].firstChild.nodeValue == "&") { //matrix 1017 var pos = []; // positions of ampersands 1018 var m = newFrag.childNodes.length; 1019 for (i=0; matrix && i<m; i=i+2) { 1020 pos[i] = []; 1021 node = newFrag.childNodes[i]; 1022 for (var j=0; j<node.childNodes.length; j++) 1023 if (node.childNodes[j].firstChild.nodeValue=="&") 1024 pos[i][pos[i].length]=j; 1025 } 1026 var row, frag, n, k, table = document.createDocumentFragment(); 1027 for (i=0; i<m; i=i+2) { 1028 row = document.createDocumentFragment(); 1029 frag = document.createDocumentFragment(); 1030 node = newFrag.firstChild; // <mrow> -&-&...&-&- </mrow>
1030 1031 n = node.childNodes.length; 1032 k = 0; 1033 for (j=0; j<n; j++) { 1034 if (typeof pos[i][k] != "undefined" && j==pos[i][k]){ 1035 node.removeChild(node.firstChild); //remove & 1036 row.appendChild(AMcreateMmlNode("mtd",frag)); 1037 k++; 1038 } else frag.appendChild(node.firstChild); 1039 } 1040 row.appendChild(AMcreateMmlNode("mtd",frag)); 1041 if (newFrag.childNodes.length>2) { 1042 newFrag.removeChild(newFrag.firstChild); //remove <mrow> </mrow> 1043 newFrag.removeChild(newFrag.firstChild); //remove <mo>&</mo> 1044 } 1045 table.appendChild(AMcreateMmlNode("mtr",row)); 1046 } 1047 return [table,str]; 1048 } 1049 if (typeof symbol.invisible != "boolean" || !symbol.invisible) { 1050 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 1051 newFrag.appendChild(node); 1052 } 1053 } 1054 return [newFrag,str,tag]; 1055} 1056 1057function AMparseMath(str) { 1058 var result, node = AMcreateElementMathML("mstyle"); 1059 if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); 1060 if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); 1061 node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false,false)[0]); 1062 node = AMcreateMmlNode("math",node); 1063 if (showasciiformulaonhover) //fixed by djhsu so newline 1064 node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko 1065 if (mathfontfamily != "" && (isIE || mathfontfamily != "serif")) { 1066 var fnode = AMcreateElementXHTML("font"); 1067 fnode.setAttribute("face",mathfontfamily); 1068 fnode.appendChild(node); 1069 return fnode; 1070 } 1071 return node; 1072} 1073 1074function AMstrarr2docFrag(arr, linebreaks) { 1075 var newFrag=document.createDocumentFragment(); 1076 var expr = false; 1077 for (var i=0; i<arr.length; i++) { 1078 if (expr) newFrag.appendChild(AMparseMath(arr[i])); 1079 else { 1080 var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]); 1081 newFrag.appendChild(AMcreateElementXHTML("span"). 1082 appendChild(document.createTextNode(arri[0]))); 1083 for (var j=1; j<arri.length; j++) { 1084 newFrag.appendChild(AMcreateElementXHTML("p")); 1085 newFrag.appendChild(AMcreateElementXHTML("span"). 1086 appendChild(document.createTextNode(arri[j]))); 1087 } 1088 } 1089 expr = !expr; 1090 } 1091 return newFrag; 1092} 1093 1094function AMprocessNodeR(n, linebreaks) { 1095 var mtch, str, arr, frg, i; 1096 if (n.childNodes.length == 0) { 1097 if ((n.nodeType!=8 || linebreaks) && 1098 n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" && 1099 n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA" && 1100 n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE") { 1101 str = n.nodeValue; 1102 if (!(str == null)) { 1103 str = str.replace(/\r\n\r\n/g,"\n\n"); 1104 str = str.replace(/\x20+/g," "); 1105 str = str.replace(/\s*\r\n/g," "); 1106// DELIMITERS: 1107 mtch = (str.indexOf("\$")==-1 ? false : true); 1108 str = str.replace(/([^\\])\$/g,"$1 \$"); 1109 str = str.replace(/^\$/," \$"); // in case \$ at start of string 1110 arr = str.split(" \$"); 1111 for (i=0; i<arr.length; i++) 1112 arr[i]=arr[i].replace(/\\\$/g,"\$"); 1113 if (arr.length>1 || mtch) { 1114 if (checkForMathML) { 1115 checkForMathML = false; 1116 var nd = AMisMathMLavailable(); 1117 AMnoMathML = nd != null; 1118 if (AMnoMathML && notifyIfNoMathML) 1119 if (alertIfNoMathML) 1120 alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\ 1121 or Firefox/Mozilla/Netscape"); 1122 else AMbody.insertBefore(nd,AMbody.childNodes[0]); 1123 } 1124 if (!AMnoMathML) { 1125 frg = AMstrarr2docFrag(arr,n.nodeType==8); 1126 var len = frg.childNodes.length; 1127 n.parentNode.replaceChild(frg,n); 1128 return len-1; 1129 } else return 0; 1130 } 1131 } 1132 } else return 0; 1133 } else if (n.nodeName!="math") { 1134 for (i=0; i<n.childNodes.length; i++) 1135 i += AMprocessNodeR(n.childNodes[i], linebreaks); 1136 } 1137 return 0; 1138} 1139 1140function AMprocessNode(n, linebreaks, spanclassAM) { 1141 var frag,st; 1142 if (spanclassAM!=null) { 1143 frag = document.getElementsByTagName("span") 1144 for (var i=0;i<frag.length;i++) 1145 if (frag[i].className == "AM") 1146 AMprocessNodeR(frag[i],linebreaks); 1147 } else { 1148 try { 1149 st = n.innerHTML; 1150 } catch(err) {} 1151// DELIMITERS: 1152 if (st==null || st.indexOf("\$")!=-1) 1153 AMprocessNodeR(n,linebreaks); 1154 } 1155 if (isIE) { //needed to match size and font of formula to surrounding text 1156 frag = document.getElementsByTagName('math'); 1157 for (var i=0;i<frag.length;i++) frag[i].update() 1158 } 1159} 1160 1161var AMbody; 1162var AMnoMathML = false, AMtranslated = false;
1163 1164function translate(spanclassAM) { 1165 if (!AMtranslated) { // run this only once 1166 AMtranslated = true; 1167 AMinitSymbols(); 1168 AMbody = document.getElementsByTagName("body")[0]; 1169 AMprocessNode(AMbody, false, spanclassAM); 1170 } 1171} 1172 1173if (isIE) { // avoid adding MathPlayer info explicitly to each webpage 1174 document.write("<object id=\"mathplayer\"\ 1175 classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>"); 1176 document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>"); 1177} 1178 1179// GO1.1 Generic onload by Brothercake 1180// http://www.brothercake.com/ 1181//onload function (replaces the onload="translate()" in the <body> tag) 1182function generic() 1183{ 1184 translate(); 1185}; 1186//setup onload function 1187if(typeof window.addEventListener != 'undefined') 1188{ 1189 //.. gecko, safari, konqueror and standard 1190 window.addEventListener('load', generic, false); 1191} 1192else if(typeof document.addEventListener != 'undefined') 1193{ 1194 //.. opera 7 1195 document.addEventListener('load', generic, false); 1196} 1197else if(typeof window.attachEvent != 'undefined') 1198{ 1199 //.. win/ie 1200 window.attachEvent('onload', generic); 1201} 1202//** remove this condition to degrade older browsers 1203else 1204{ 1205 //.. mac/ie5 and anything else that gets this far 1206 //if there's an existing onload function 1207 if(typeof window.onload == 'function') 1208 { 1209 //store it 1210 var existing = onload; 1211 //add new onload handler 1212 window.onload = function() 1213 { 1214 //call existing onload function 1215 existing(); 1216 //call generic onload function 1217 generic(); 1218 }; 1219 } 1220 else 1221 { 1222 //setup onload function 1223 window.onload = generic; 1224 } 1225}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.