1/* 2ASCIIMathML.js 3============== 4This file contains JavaScript functions to convert ASCII math notation 5to Presentation MathML. The conversion is done while the (X)HTML page 6loads, and should work with Firefox/Mozilla/Netscape 7+ and Internet 7Explorer 6+MathPlayer (http://www.dessci.com/en/products/mathplayer/). 8Just add the next line to your (X)HTML page with this file in the same folder: 9<script type="text/javascript" src="ASCIIMathML.js"></script> 10This is a convenient and inexpensive solution for authoring MathML. 11 12Version 1.4.7 Aug 14, 2005, (c) Peter Jipsen http://www.chapman.edu/~jipsen 13Latest version at http://www.chapman.edu/~jipsen/mathml/ASCIIMathML.js 14For changes see http://www.chapman.edu/~jipsen/mathml/asciimathchanges.txt 15If you use it on a webpage, please send the URL to jipsen@chapman.edu 16 17This program is free software; you can redistribute it and/or modify 18it under the terms of the GNU General Public License as published by 19the Free Software Foundation; either version 2 of the License, or (at 20your option) any later version. 21 22This program is distributed in the hope that it will be useful, 23but WITHOUT ANY WARRANTY; without even the implied warranty of 24MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25General Public License (at http://www.gnu.org/copyleft/gpl.html) 26for more details. 27*/ 28 29var checkForMathML = true; // check if browser can display MathML 30var notifyIfNoMathML = true; // put note at top of page if no MathML capability 31var mathcolor = " "; // change it to "" (to inherit) or any other color 32var mathfontfamily = "arial"; // change to "" to inherit (works in IE) 33 // or another family (e.g. "arial") 34var displaystyle = true; // puts limits above and below large operators 35var showasciiformulaonhover = true; // helps students learn ASCIIMath 36var decimalsign = "."; // change to "," if you like, beware of `(1,2)`! 37var AMdelimiter1 = "$$", AMescape1 = "\\\\$"; // was $$ can use other characters 38var AMdelimiter2 = "```", AMescape2 = "\\\\\\`", AMdelimiter2regexp = "\\`"; 39var doubleblankmathdelimiter = false; // if true, x+1 is equal to `x+1` 40 // for IE this works only in <!-- --> 41//var separatetokens;// has been removed (email me if this is a problem) 42var isIE = document.createElementNS==null; 43 44if (document.getElementById==null) 45 alert("This webpage requires a recent browser such as\ 46\nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer") 47 48// all further global variables start with "AM" 49 50function AMcreateElementXHTML(t) { 51 if (isIE) return document.createElement(t); 52 else return document.createElementNS("http://www.w3.org/1999/xhtml",t); 53} 54 55function AMnoMathMLNote() { 56 var nd = AMcreateElementXHTML("h3"); 57 nd.setAttribute("align","center") 58 nd.appendChild(AMcreateElementXHTML("p")); 59 nd.appendChild(document.createTextNode("To view the ")); 60 var an = AMcreateElementXHTML("a"); 61 an.appendChild(document.createTextNode("ASCIIMathML")); 62 an.setAttribute("href","http://www.chapman.edu/~jipsen/asciimath.html"); 63 nd.appendChild(an); 64 nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); 65 an = AMcreateElementXHTML("a"); 66 an.appendChild(document.createTextNode("MathPlayer")); 67 an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm"); 68 nd.appendChild(an); 69 nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox")); 70 nd.appendChild(AMcreateElementXHTML("p")); 71 return nd; 72} 73 74function AMisMathMLavailable() { 75 if (navigator.appName.slice(0,8)=="Netscape") 76 if (navigator.appVersion.slice(0,1)>="5") return null; 77 else return AMnoMathMLNote(); 78 else if (navigator.appName.slice(0,9)=="Microsoft") 79 try { 80 var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); 81 return null; 82 } catch (e) { 83 return AMnoMathMLNote(); 84 } 85 else return AMnoMathMLNote(); 86} 87 88// character lists for Mozilla/Netscape fonts 89var 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]; 90var 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]; 91var 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]; 92 93var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, 94 RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, 95 LEFTRIGHT = 9, TEXT = 10; // token types 96 97var AMsqrt = {input:"sqrt", tag:"msqrt", output:"sqrt", tex:null, ttype:UNARY}, 98 AMroot = {input:"root", tag:"mroot", output:"root", tex:null, ttype:BINARY}, 99 AMfrac = {input:"frac", tag:"mfrac", output:"/", tex:null, ttype:BINARY}, 100 AMdiv = {input:"/", tag:"mfrac", output:"/", tex:null, ttype:INFIX}, 101 AMover = {input:"stackrel", tag:"mover", output:"stackrel", tex:null, ttype:BINARY}, 102 AMsub = {input:"_", tag:"msub", output:"_", tex:null, ttype:INFIX}, 103 AMsup = {input:"^", tag:"msup", output:"^", tex:null, ttype:INFIX}, 104 AMtext = {input:"text", tag:"mtext", output:"text", tex:null, ttype:TEXT}, 105 AMmbox = {input:"mbox", tag:"mtext", output:"mbox", tex:null, ttype:TEXT}, 106 AMquote = {input:"\"", tag:"mtext", output:"mbox", tex:null, ttype:TEXT}; 107 108var AMsymbols = [ 109//some greek symbols 110{input:"alpha", tag:"mi", output:"\u03B1", tex:null, ttype:CONST}, 111{input:"beta", tag:"mi", output:"\u03B2", tex:null, ttype:CONST}, 112{input:"chi", tag:"mi", output:"\u03C7", tex:null, ttype:CONST}, 113{input:"delta", tag:"mi", output:"\u03B4", tex:null, ttype:CONST}, 114{input:"Delta", tag:"mo", output:"\u0394", tex:null, ttype:CONST}, 115{input:"epsi", tag:"mi", output:"\u03B5", tex:"epsilon", ttype:CONST}, 116{input:"varepsilon", tag:"mi", output:"\u025B", tex:null, ttype:CONST}, 117{input:"eta", tag:"mi", output:"\u03B7", tex:null, ttype:CONST}, 118{input:"gamma", tag:"mi", output:"\u03B3", tex:null, ttype:CONST}, 119{input:"Gamma", tag:"mo", output:"\u0393", tex:null, ttype:CONST}, 120{input:"iota", tag:"mi", output:"\u03B9", tex:null, ttype:CONST}, 121{input:"kappa", tag:"mi", output:"\u03BA", tex:null, ttype:CONST}, 122{input:"lambda", tag:"mi", output:"\u03BB", tex:null, ttype:CONST}, 123{input:"Lambda", tag:"mo", output:"\u039B", tex:null, ttype:CONST}, 124{input:"mu", tag:"mi", output:"\u03BC", tex:null, ttype:CONST}, 125{input:"nu", tag:"mi", output:"\u03BD", tex:null, ttype:CONST}, 126{input:"omega", tag:"mi", output:"\u03C9", tex:null, ttype:CONST}, 127{input:"Omega", tag:"mo", output:"\u03A9", tex:null, ttype:CONST}, 128{input:"phi", tag:"mi", output:"\u03C6", tex:null, ttype:CONST}, 129{input:"varphi", tag:"mi", output:"\u03D5", tex:null, ttype:CONST}, 130{input:"Phi", tag:"mo", output:"\u03A6", tex:null, ttype:CONST}, 131{input:"pi", tag:"mi", output:"\u03C0", tex:null, ttype:CONST}, 132{input:"Pi", tag:"mo", output:"\u03A0", tex:null, ttype:CONST}, 133{input:"psi", tag:"mi", output:"\u03C8", tex:null, ttype:CONST}, 134{input:"Psi", tag:"mi", output:"\u03A8", tex:null, ttype:CONST}, 135{input:"rho", tag:"mi", output:"\u03C1", tex:null, ttype:CONST}, 136{input:"sigma", tag:"mi", output:"\u03C3", tex:null, ttype:CONST}, 137{input:"Sigma", tag:"mo", output:"\u03A3", tex:null, ttype:CONST}, 138{input:"tau", tag:"mi", output:"\u03C4", tex:null, ttype:CONST}, 139{input:"theta", tag:"mi", output:"\u03B8", tex:null, ttype:CONST}, 140{input:"vartheta", tag:"mi", output:"\u03D1", tex:null, ttype:CONST}, 141{input:"Theta", tag:"mo", output:"\u0398", tex:null, ttype:CONST}, 142{input:"upsilon", tag:"mi", output:"\u03C5", tex:null, ttype:CONST}, 143{input:"xi", tag:"mi", output:"\u03BE", tex:null, ttype:CONST}, 144{input:"Xi", tag:"mo", output:"\u039E", tex:null, ttype:CONST}, 145{input:"zeta", tag:"mi", output:"\u03B6", tex:null, ttype:CONST}, 146 147//binary operation symbols 148{input:"*", tag:"mo", output:"\u22C5", tex:"cdot", ttype:CONST}, 149{input:"**", tag:"mo", output:"\u22C6", tex:"star", ttype:CONST}, 150{input:"//", tag:"mo", output:"/", tex:null, ttype:CONST}, 151{input:"\\\\", tag:"mo", output:"\\", tex:"backslash", ttype:CONST}, 152{input:"setminus", tag:"mo", output:"\\", tex:null, ttype:CONST}, 153{input:"xx", tag:"mo", output:"\u00D7", tex:"times", ttype:CONST}, 154{input:"-:", tag:"mo", output:"\u00F7", tex:"divide", ttype:CONST}, 155{input:"@", tag:"mo", output:"\u2218", tex:"circ", ttype:CONST}, 156{input:"o+", tag:"mo", output:"\u2295", tex:"oplus", ttype:CONST}, 157{input:"ox", tag:"mo", output:"\u2297", tex:"otimes", ttype:CONST}, 158{input:"o.", tag:"mo", output:"\u2299", tex:"odot", ttype:CONST}, 159{input:"sum", tag:"mo", output:"\u2211", tex:null, ttype:UNDEROVER}, 160{input:"prod", tag:"mo", output:"\u220F", tex:null, ttype:UNDEROVER}, 161{input:"^^", tag:"mo", output:"\u2227", tex:"wedge", ttype:CONST}, 162{input:"^^^", tag:"mo", output:"\u22C0", tex:"bigwedge", ttype:UNDEROVER}, 163{input:"vv", tag:"mo", output:"\u2228", tex:"vee", ttype:CONST}, 164{input:"vvv", tag:"mo", output:"\u22C1", tex:"bigvee", ttype:UNDEROVER}, 165{input:"nn", tag:"mo", output:"\u2229", tex:"cap", ttype:CONST}, 166{input:"nnn", tag:"mo", output:"\u22C2", tex:"bigcap", ttype:UNDEROVER}, 167{input:"uu", tag:"mo", output:"\u222A", tex:"cup", ttype:CONST}, 168{input:"uuu", tag:"mo", output:"\u22C3", tex:"bigcup", ttype:UNDEROVER}, 169 170//binary relation symbols 171{input:"!=", tag:"mo", output:"\u2260", tex:"ne", ttype:CONST}, 172{input:":=", tag:"mo", output:":=", tex:null, ttype:CONST}, 173{input:"lt", tag:"mo", output:"<", tex:null, ttype:CONST}, 174{input:"<=", tag:"mo", output:"\u2264", tex:"le", ttype:CONST}, 175{input:"lt=", tag:"mo", output:"\u2264", tex:"leq", ttype:CONST}, 176{input:">=", tag:"mo", output:"\u2265", tex:"ge", ttype:CONST}, 177{input:"geq", tag:"mo", output:"\u2265", tex:null, ttype:CONST}, 178{input:"-<", tag:"mo", output:"\u227A", tex:"prec", ttype:CONST}, 179{input:"-lt", tag:"mo", output:"\u227A", tex:null, ttype:CONST}, 180{input:">-", tag:"mo", output:"\u227B", tex:"succ", ttype:CONST}, 181{input:"in", tag:"mo", output:"\u2208", tex:null, ttype:CONST}, 182{input:"!in", tag:"mo", output:"\u2209", tex:"notin", ttype:CONST}, 183{input:"sub", tag:"mo", output:"\u2282", tex:"subset", ttype:CONST}, 184{input:"sup", tag:"mo", output:"\u2283", tex:"supset", ttype:CONST}, 185{input:"sube", tag:"mo", output:"\u2286", tex:"subseteq", ttype:CONST}, 186{input:"supe", tag:"mo", output:"\u2287", tex:"supseteq", ttype:CONST}, 187{input:"-=", tag:"mo", output:"\u2261", tex:"equiv", ttype:CONST}, 188{input:"~=", tag:"mo", output:"\u2245", tex:"cong", ttype:CONST}, 189{input:"~~", tag:"mo", output:"\u2248", tex:"approx", ttype:CONST}, 190{input:"prop", tag:"mo", output:"\u221D", tex:"propto", ttype:CONST}, 191 192//logical symbols 193{input:"and", tag:"mtext", output:"and", tex:null, ttype:SPACE}, 194{input:"or", tag:"mtext", output:"or", tex:null, ttype:SPACE}, 195{input:"not", tag:"mo", output:"\u00AC", tex:"neg", ttype:CONST}, 196{input:"=>", tag:"mo", output:"\u21D2", tex:"implies", ttype:CONST}, 197{input:"if", tag:"mo", output:"if", tex:null, ttype:SPACE}, 198{input:"<=>", tag:"mo", output:"\u21D4", tex:"iff", ttype:CONST}, 199{input:"AA", tag:"mo", output:"\u2200", tex:"forall", ttype:CONST}, 200{input:"EE", tag:"mo", output:"\u2203", tex:"exists", ttype:CONST}, 201{input:"_|_", tag:"mo", output:"\u22A5", tex:"bot", ttype:CONST}, 202{input:"TT", tag:"mo", output:"\u22A4", tex:"top", ttype:CONST}, 203{input:"|--", tag:"mo", output:"\u22A2", tex:"vdash", ttype:CONST}, 204{input:"|==", tag:"mo", output:"\u22A8", tex:"models", ttype:CONST}, 205 206//grouping brackets 207{input:"(", tag:"mo", output:"(", tex:null, ttype:LEFTBRACKET}, 208{input:")", tag:"mo", output:")", tex:null, ttype:RIGHTBRACKET}, 209{input:"[", tag:"mo", output:"[", tex:null, ttype:LEFTBRACKET}, 210{input:"]", tag:"mo", output:"]", tex:null, ttype:RIGHTBRACKET}, 211{input:"{", tag:"mo", output:"{", tex:null, ttype:LEFTBRACKET}, 212{input:"}", tag:"mo", output:"}", tex:null, ttype:RIGHTBRACKET}, 213{input:"|", tag:"mo", output:"|", tex:null, ttype:LEFTRIGHT}, 214//{input:"||", tag:"mo", output:"||", tex:null, ttype:LEFTRIGHT}, 215{input:"(:", tag:"mo", output:"\u2329", tex:"langle", ttype:LEFTBRACKET}, 216{input:":)", tag:"mo", output:"\u232A", tex:"rangle", ttype:RIGHTBRACKET}, 217{input:"<<", tag:"mo", output:"\u2329", tex:null, ttype:LEFTBRACKET}, 218{input:">>", tag:"mo", output:"\u232A", tex:null, ttype:RIGHTBRACKET}, 219{input:"{:", tag:"mo", output:"{:", tex:null, ttype:LEFTBRACKET, invisible:true}, 220{input:":}", tag:"mo", output:":}", tex:null, ttype:RIGHTBRACKET, invisible:true}, 221 222//miscellaneous symbols 223{input:"int", tag:"mo", output:"\u222B", tex:null, ttype:CONST}, 224{input:"dx", tag:"mi", output:"{:d x:}", tex:null, ttype:DEFINITION}, 225{input:"dy", tag:"mi", output:"{:d y:}", tex:null, ttype:DEFINITION}, 226{input:"dz", tag:"mi", output:"{:d z:}", tex:null, ttype:DEFINITION}, 227{input:"dt", tag:"mi", output:"{:d t:}", tex:null, ttype:DEFINITION}, 228{input:"oint", tag:"mo", output:"\u222E", tex:null, ttype:CONST}, 229{input:"del", tag:"mo", output:"\u2202", tex:"partial", ttype:CONST}, 230{input:"grad", tag:"mo", output:"\u2207", tex:"nabla", ttype:CONST}, 231{input:"+-", tag:"mo", output:"\u00B1", tex:"pm", ttype:CONST}, 232{input:"O/", tag:"mo", output:"\u2205", tex:"emptyset", ttype:CONST}, 233{input:"oo", tag:"mo", output:"\u221E", tex:"infty", ttype:CONST}, 234{input:"aleph", tag:"mo", output:"\u2135", tex:null, ttype:CONST}, 235{input:"...", tag:"mo", output:"...", tex:"ldots", ttype:CONST}, 236{input:":.", tag:"mo", output:"\u2234", tex:"therefore", ttype:CONST}, 237{input:"/_", tag:"mo", output:"\u2220", tex:"angle", ttype:CONST}, 238{input:"\\ ", tag:"mo", output:"\u00A0", tex:null, ttype:CONST}, 239{input:"quad", tag:"mo", output:"\u00A0\u00A0", tex:null, ttype:CONST}, 240{input:"qquad", tag:"mo", output:"\u00A0\u00A0\u00A0\u00A0", tex:null, ttype:CONST}, 241{input:"cdots", tag:"mo", output:"\u22EF", tex:null, ttype:CONST}, 242{input:"vdots", tag:"mo", output:"\u22EE", tex:null, ttype:CONST}, 243{input:"ddots", tag:"mo", output:"\u22F1", tex:null, ttype:CONST}, 244{input:"diamond", tag:"mo", output:"\u22C4", tex:null, ttype:CONST}, 245{input:"square", tag:"mo", output:"\u25A1", tex:null, ttype:CONST}, 246{input:"|__", tag:"mo", output:"\u230A", tex:"lfloor", ttype:CONST}, 247{input:"__|", tag:"mo", output:"\u230B", tex:"rfloor", ttype:CONST}, 248{input:"|~", tag:"mo", output:"\u2308", tex:"lceiling", ttype:CONST}, 249{input:"~|", tag:"mo", output:"\u2309", tex:"rceiling", ttype:CONST}, 250{input:"CC", tag:"mo", output:"\u2102", tex:null, ttype:CONST}, 251{input:"NN", tag:"mo", output:"\u2115", tex:null, ttype:CONST}, 252{input:"QQ", tag:"mo", output:"\u211A", tex:null, ttype:CONST}, 253{input:"RR", tag:"mo", output:"\u211D", tex:null, ttype:CONST}, 254{input:"ZZ", tag:"mo", output:"\u2124", tex:null, ttype:CONST}, 255{input:"f", tag:"mi", output:"f", tex:null, ttype:UNARY, func:true}, 256{input:"g", tag:"mi", output:"g", tex:null, ttype:UNARY, func:true}, 257 258//standard functions 259{input:"lim", tag:"mo", output:"lim", tex:null, ttype:UNDEROVER}, 260{input:"Lim", tag:"mo", output:"Lim", tex:null, ttype:UNDEROVER}, 261{input:"sin", tag:"mo", output:"sin", tex:null, ttype:UNARY, func:true}, 262{input:"cos", tag:"mo", output:"cos", tex:null, ttype:UNARY, func:true}, 263{input:"tan", tag:"mo", output:"tan", tex:null, ttype:UNARY, func:true}, 264{input:"sinh", tag:"mo", output:"sinh", tex:null, ttype:UNARY, func:true}, 265{input:"cosh", tag:"mo", output:"cosh", tex:null, ttype:UNARY, func:true}, 266{input:"tanh", tag:"mo", output:"tanh", tex:null, ttype:UNARY, func:true}, 267{input:"cot", tag:"mo", output:"cot", tex:null, ttype:UNARY, func:true}, 268{input:"sec", tag:"mo", output:"sec", tex:null, ttype:UNARY, func:true}, 269{input:"csc", tag:"mo", output:"csc", tex:null, ttype:UNARY, func:true}, 270{input:"log", tag:"mo", output:"log", tex:null, ttype:UNARY, func:true}, 271{input:"ln", tag:"mo", output:"ln", tex:null, ttype:UNARY, func:true}, 272{input:"det", tag:"mo", output:"det", tex:null, ttype:UNARY, func:true}, 273{input:"dim", tag:"mo", output:"dim", tex:null, ttype:CONST}, 274{input:"mod", tag:"mo", output:"mod", tex:null, ttype:CONST}, 275{input:"gcd", tag:"mo", output:"gcd", tex:null, ttype:UNARY, func:true}, 276{input:"lcm", tag:"mo", output:"lcm", tex:null, ttype:UNARY, func:true}, 277{input:"lub", tag:"mo", output:"lub", tex:null, ttype:CONST}, 278{input:"glb", tag:"mo", output:"glb", tex:null, ttype:CONST}, 279{input:"min", tag:"mo", output:"min", tex:null, ttype:UNDEROVER}, 280{input:"max", tag:"mo", output:"max", tex:null, ttype:UNDEROVER}, 281 282//arrows 283{input:"uarr", tag:"mo", output:"\u2191", tex:"uparrow", ttype:CONST}, 284{input:"darr", tag:"mo", output:"\u2193", tex:"downarrow", ttype:CONST}, 285{input:"rarr", tag:"mo", output:"\u2192", tex:"rightarrow", ttype:CONST}, 286{input:"->", tag:"mo", output:"\u2192", tex:"to", ttype:CONST}, 287{input:"|->", tag:"mo", output:"\u21A6", tex:"mapsto", ttype:CONST}, 288{input:"larr", tag:"mo", output:"\u2190", tex:"leftarrow", ttype:CONST}, 289{input:"harr", tag:"mo", output:"\u2194", tex:"leftrightarrow", ttype:CONST}, 290{input:"rArr", tag:"mo", output:"\u21D2", tex:"Rightarrow", ttype:CONST}, 291{input:"lArr", tag:"mo", output:"\u21D0", tex:"Leftarrow", ttype:CONST}, 292{input:"hArr", tag:"mo", output:"\u21D4", tex:"Leftrightarrow", ttype:CONST}, 293 294//commands with argument 295AMsqrt, AMroot, AMfrac, AMdiv, AMover, AMsub, AMsup, 296{input:"hat", tag:"mover", output:"\u005E", tex:null, ttype:UNARY, acc:true}, 297{input:"bar", tag:"mover", output:"\u00AF", tex:"overline", ttype:UNARY, acc:true}, 298{input:"vec", tag:"mover", output:"\u2192", tex:null, ttype:UNARY, acc:true}, 299{input:"dot", tag:"mover", output:".", tex:null, ttype:UNARY, acc:true}, 300{input:"ddot", tag:"mover", output:"..", tex:null, ttype:UNARY, acc:true}, 301{input:"ul", tag:"munder", output:"\u0332", tex:"underline", ttype:UNARY, acc:true}, 302AMtext, AMmbox, AMquote, 303{input:"bb", tag:"mstyle", atname:"fontweight", atval:"bold", output:"bb", tex:null, ttype:UNARY}, 304{input:"mathbf", tag:"mstyle", atname:"fontweight", atval:"bold", output:"mathbf", tex:null, ttype:UNARY}, 305{input:"sf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"sf", tex:null, ttype:UNARY}, 306{input:"mathsf", tag:"mstyle", atname:"fontfamily", atval:"sans-serif", output:"mathsf", tex:null, ttype:UNARY}, 307{input:"bbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"bbb", tex:null, ttype:UNARY, codes:AMbbb}, 308{input:"mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", output:"mathbb", tex:null, ttype:UNARY, codes:AMbbb}, 309{input:"cc", tag:"mstyle", atname:"mathvariant", atval:"script", output:"cc", tex:null, ttype:UNARY, codes:AMcal}, 310{input:"mathcal", tag:"mstyle", atname:"mathvariant", atval:"script", output:"mathcal", tex:null, ttype:UNARY, codes:AMcal}, 311{input:"tt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"tt", tex:null, ttype:UNARY}, 312{input:"mathtt", tag:"mstyle", atname:"fontfamily", atval:"monospace", output:"mathtt", tex:null, ttype:UNARY}, 313{input:"fr", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"fr", tex:null, ttype:UNARY, codes:AMfrk}, 314{input:"mathfrak", tag:"mstyle", atname:"mathvariant", atval:"fraktur", output:"mathfrak", tex:null, ttype:UNARY, codes:AMfrk} 315]; 316 317function compareNames(s1,s2) { 318 if (s1.input > s2.input) return 1 319 else return -1; 320} 321 322var AMnames = []; //list of input symbols 323 324function AMinitSymbols() { 325 var texsymbols = [], i; 326 for (i=0; i<AMsymbols.length; i++) 327 if (AMsymbols[i].tex) 328 texsymbols[texsymbols.length] = {input:AMsymbols[i].tex, 329 tag:AMsymbols[i].tag, output:AMsymbols[i].output, ttype:AMsymbols[i].ttype}; 330 AMsymbols = AMsymbols.concat(texsymbols); 331 AMsymbols.sort(compareNames); 332 for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input; 333} 334 335var AMmathml = "http://www.w3.org/1998/Math/MathML"; 336 337function AMcreateElementMathML(t) { 338 if (isIE) return document.createElement("m:"+t); 339 else return document.createElementNS(AMmathml,t); 340} 341 342function AMcreateMmlNode(t,frag) { 343// var node = AMcreateElementMathML(name); 344 if (isIE) var node = document.createElement("m:"+t); 345 else var node = document.createElementNS(AMmathml,t); 346 node.appendChild(frag); 347 return node; 348} 349 350function newcommand(oldstr,newstr) { 351 AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, 352 tex:null, ttype:DEFINITION}]); 353} 354 355function AMremoveCharsAndBlanks(str,n) { 356//remove n characters and any following blanks 357 var st; 358 if (str.charAt(n)=="\\" && str.charAt(n+1)!="\\" && str.charAt(n+1)!=" ") 359 st = str.slice(n+1); 360 else st = str.slice(n); 361 for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1); 362 return st.slice(i); 363} 364 365function AMposition(arr, str, n) { 366// return position >=n where str appears or would be inserted 367// assumes arr is sorted 368 if (n==0) { 369 var h,m; 370 n = -1; 371 h = arr.length; 372 while (n+1<h) { 373 m = (n+h) >> 1; 374 if (arr[m]<str) n = m; else h = m; 375 } 376 return h; 377 } else 378 for (var i=n; i<arr.length && arr[i]<str; i++); 379 return i; // i=arr.length || arr[i]>=str 380} 381 382function AMgetSymbol(str) { 383//return maximal initial substring of str that appears in names 384//return null if there is none 385 var k = 0; //new pos 386 var j = 0; //old pos 387 var mk; //match pos 388 var st; 389 var tagst; 390 var match = ""; 391 var more = true; 392 for (var i=1; i<=str.length && more; i++) { 393 st = str.slice(0,i); //initial substring of length i 394 j = k; 395 k = AMposition(AMnames, st, j); 396 if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){ 397 match = AMnames[k]; 398 mk = k; 399 i = match.length; 400 } 401 more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k]; 402 } 403 AMpreviousSymbol=AMcurrentSymbol; 404 if (match!=""){ 405 AMcurrentSymbol=AMsymbols[mk].ttype; 406 return AMsymbols[mk]; 407 } 408// if str[0] is a digit or - return maxsubstring of digits.digits 409 AMcurrentSymbol=CONST; 410 k = 1; 411 st = str.slice(0,1); 412 var integ = true; 413 while ("0"<=st && st<="9" && k<=str.length) { 414 st = str.slice(k,k+1); 415 k++; 416 } 417 if (st == decimalsign) { 418 st = str.slice(k,k+1); 419 if ("0"<=st && st<="9") { 420 integ = false; 421 k++; 422 while ("0"<=st && st<="9" && k<=str.length) { 423 st = str.slice(k,k+1); 424 k++; 425 } 426 } 427 } 428 if ((integ && k>1) || k>2) { 429 st = str.slice(0,k-1); 430 tagst = "mn"; 431 } else { 432 k = 2; 433 st = str.slice(0,1); //take 1 character 434 tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi"); 435 } 436 if (st=="-" && AMpreviousSymbol==INFIX) 437 return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; 438 return {input:st, tag:tagst, output:st, ttype:CONST}; 439} 440 441function AMremoveBrackets(node) { 442 var st; 443 if (node.nodeName=="mrow") { 444 st = node.firstChild.firstChild.nodeValue; 445 if (st=="(" || st=="[" || st=="{") node.removeChild(node.firstChild); 446 } 447 if (node.nodeName=="mrow") { 448 st = node.lastChild.firstChild.nodeValue; 449 if (st==")" || st=="]" || st=="}") node.removeChild(node.lastChild); 450 } 451} 452 453/*Parsing ASCII math expressions with the following grammar 454v ::= [A-Za-z] | greek letters | numbers | other constant symbols 455u ::= sqrt | text | bb | other unary symbols for font commands 456b ::= frac | root | stackrel binary symbols 457l ::= ( | [ | { | (: | {: left brackets 458r ::= ) | ] | } | :) | :} right brackets 459S ::= v | lEr | uS | bSS Simple expression 460I ::= S_S | S^S | S_S^S | S Intermediate expression 461E ::= IE | I/I Expression 462Each terminal symbol is translated into a corresponding mathml node.*/ 463 464var AMnestingDepth,AMpreviousSymbol,AMcurrentSymbol; 465 466function AMparseSexpr(str) { //parses str and returns [node,tailstr] 467 var symbol, node, result, i, st,// rightvert = false, 468 newFrag = document.createDocumentFragment(); 469 str = AMremoveCharsAndBlanks(str,0); 470 symbol = AMgetSymbol(str); //either a token or a bracket or empty 471 if (symbol == null || symbol.ttype == RIGHTBRACKET && AMnestingDepth > 0) { 472 return [null,str]; 473 } 474 if (symbol.ttype == DEFINITION) { 475 str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); 476 symbol = AMgetSymbol(str); 477 } 478 switch (symbol.ttype) { 479 case UNDEROVER: 480 case CONST: 481 str = AMremoveCharsAndBlanks(str,symbol.input.length); 482 return [AMcreateMmlNode(symbol.tag, //its a constant 483 document.createTextNode(symbol.output)),str]; 484 case LEFTBRACKET: //read (expr+) 485 AMnestingDepth++; 486 str = AMremoveCharsAndBlanks(str,symbol.input.length); 487 result = AMparseExpr(str,true); 488 AMnestingDepth--; 489 if (typeof symbol.invisible == "boolean" && symbol.invisible) 490 node = AMcreateMmlNode("mrow",result[0]); 491 else { 492 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 493 node = AMcreateMmlNode("mrow",node); 494 node.appendChild(result[0]); 495 } 496 return [node,result[1]]; 497 case TEXT: 498 if (symbol!=AMquote) str = AMremoveCharsAndBlanks(str,symbol.input.length); 499 if (str.charAt(0)=="{") i=str.indexOf("}"); 500 else if (str.charAt(0)=="(") i=str.indexOf(")"); 501 else if (str.charAt(0)=="[") i=str.indexOf("]"); 502 else if (symbol==AMquote) i=str.slice(1).indexOf("\"")+1; 503 else i = 0; 504 if (i==-1) i = str.length; 505 st = str.slice(1,i); 506 if (st.charAt(0) == " ") { 507 node = AMcreateElementMathML("mspace"); 508 node.setAttribute("width","1ex"); 509 newFrag.appendChild(node); 510 } 511 newFrag.appendChild( 512 AMcreateMmlNode(symbol.tag,document.createTextNode(st))); 513 if (st.charAt(st.length-1) == " ") { 514 node = AMcreateElementMathML("mspace"); 515 node.setAttribute("width","1ex"); 516 newFrag.appendChild(node); 517 } 518 str = AMremoveCharsAndBlanks(str,i+1); 519 return [AMcreateMmlNode("mrow",newFrag),str]; 520 case UNARY: 521 str = AMremoveCharsAndBlanks(str,symbol.input.length); 522 result = AMparseSexpr(str); 523 if (result[0]==null) return [AMcreateMmlNode(symbol.tag, 524 document.createTextNode(symbol.output)),str]; 525 if (typeof symbol.func == "boolean" && symbol.func) { // functions hack 526 st = str.charAt(0); 527 if (st=="^" || st=="_" || st=="/" || st=="|") { 528 return [AMcreateMmlNode(symbol.tag, 529 document.createTextNode(symbol.output)),str]; 530 } else { 531 node = AMcreateMmlNode("mrow", 532 AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); 533 node.appendChild(result[0]); 534 return [node,result[1]]; 535 } 536 } 537 AMremoveBrackets(result[0]); 538 if (symbol.input == "sqrt") { // sqrt 539 return [AMcreateMmlNode(symbol.tag,result[0]),result[1]]; 540 } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent 541 node = AMcreateMmlNode(symbol.tag,result[0]); 542 node.appendChild(AMcreateMmlNode("mo",document.createTextNode(symbol.output))); 543 return [node,result[1]]; 544 } else { // font change command 545 if (!isIE && typeof symbol.codes != "undefined") { 546 for (i=0; i<result[0].childNodes.length; i++) 547 if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") { 548 st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue: 549 result[0].childNodes[i].firstChild.nodeValue); 550 var newst = []; 551 for (var j=0; j<st.length; j++) 552 if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) newst = newst + 553 String.fromCharCode(symbol.codes[st.charCodeAt(j)-65]); 554 else newst = newst + st.charAt(j); 555 if (result[0].nodeName=="mi") 556 result[0]=AMcreateElementMathML("mo"). 557 appendChild(document.createTextNode(newst)); 558 else result[0].replaceChild(AMcreateElementMathML("mo"). 559 appendChild(document.createTextNode(newst)),result[0].childNodes[i]); 560 } 561 } 562 node = AMcreateMmlNode(symbol.tag,result[0]); 563 node.setAttribute(symbol.atname,symbol.atval); 564 return [node,result[1]]; 565 } 566 case BINARY: 567 str = AMremoveCharsAndBlanks(str,symbol.input.length); 568 result = AMparseSexpr(str); 569 if (result[0]==null) return [AMcreateMmlNode("mo", 570 document.createTextNode(symbol.input)),str]; 571 AMremoveBrackets(result[0]); 572 var result2 = AMparseSexpr(result[1]); 573 if (result2[0]==null) return [AMcreateMmlNode("mo", 574 document.createTextNode(symbol.input)),str]; 575 AMremoveBrackets(result2[0]); 576 if (symbol.input=="root" || symbol.input=="stackrel") 577 newFrag.appendChild(result2[0]); 578 newFrag.appendChild(result[0]); 579 if (symbol.input=="frac") newFrag.appendChild(result2[0]); 580 return [AMcreateMmlNode(symbol.tag,newFrag),result2[1]]; 581 case INFIX: 582 str = AMremoveCharsAndBlanks(str,symbol.input.length); 583 return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),str]; 584 case SPACE: 585 str = AMremoveCharsAndBlanks(str,symbol.input.length); 586 node = AMcreateElementMathML("mspace"); 587 node.setAttribute("width","1ex"); 588 newFrag.appendChild(node); 589 newFrag.appendChild( 590 AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); 591 node = AMcreateElementMathML("mspace"); 592 node.setAttribute("width","1ex"); 593 newFrag.appendChild(node); 594 return [AMcreateMmlNode("mrow",newFrag),str]; 595 case LEFTRIGHT: 596// if (rightvert) return [null,str]; else rightvert = true; 597 AMnestingDepth++; 598 str = AMremoveCharsAndBlanks(str,symbol.input.length); 599 result = AMparseExpr(str,false); 600 AMnestingDepth--; 601 var st = ""; 602 if (result[0].lastChild!=null) 603 st = result[0].lastChild.firstChild.nodeValue; 604//alert(result[0].lastChild+"***"+st); 605 if (st == "|") { // its an absolute value subterm 606 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 607 node = AMcreateMmlNode("mrow",node); 608 node.appendChild(result[0]); 609 return [node,result[1]]; 610 } else { // the "|" is a \mid 611 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 612 node = AMcreateMmlNode("mrow",node); 613 return [node,str]; 614 } 615 default: 616//alert("default"); 617 str = AMremoveCharsAndBlanks(str,symbol.input.length); 618 return [AMcreateMmlNode(symbol.tag, //its a constant 619 document.createTextNode(symbol.output)),str]; 620 } 621} 622 623function AMparseIexpr(str) { 624 var symbol, sym1, sym2, node, result, underover; 625 str = AMremoveCharsAndBlanks(str,0); 626 sym1 = AMgetSymbol(str); 627 result = AMparseSexpr(str); 628 node = result[0]; 629 str = result[1]; 630 symbol = AMgetSymbol(str); 631 if (symbol.ttype == INFIX && symbol.input != "/") { 632 str = AMremoveCharsAndBlanks(str,symbol.input.length); 633// if (symbol.input == "/") result = AMparseIexpr(str); else ... 634 result = AMparseSexpr(str); 635 if (result[0] == null) // show box in place of missing argument 636 result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); 637 else AMremoveBrackets(result[0]); 638 str = result[1]; 639// if (symbol.input == "/") AMremoveBrackets(node); 640 if (symbol.input == "_") { 641 sym2 = AMgetSymbol(str); 642 underover = (sym1.ttype == UNDEROVER); 643 if (sym2.input == "^") { 644 str = AMremoveCharsAndBlanks(str,sym2.input.length); 645 var res2 = AMparseSexpr(str); 646 AMremoveBrackets(res2[0]); 647 str = res2[1]; 648 node = AMcreateMmlNode((underover?"munderover":"msubsup"),node); 649 node.appendChild(result[0]); 650 node.appendChild(res2[0]); 651 node = AMcreateMmlNode("mrow",node); // so sum does not stretch 652 } else { 653 node = AMcreateMmlNode((underover?"munder":"msub"),node); 654 node.appendChild(result[0]); 655 } 656 } else { 657 node = AMcreateMmlNode(symbol.tag,node); 658 node.appendChild(result[0]); 659 } 660 } 661 return [node,str]; 662} 663 664function AMparseExpr(str,rightbracket) { 665 var symbol, node, result, i, nodeList = [], 666 newFrag = document.createDocumentFragment(); 667 do { 668 str = AMremoveCharsAndBlanks(str,0); 669 result = AMparseIexpr(str); 670 node = result[0]; 671 str = result[1]; 672 symbol = AMgetSymbol(str); 673 if (symbol.ttype == INFIX && symbol.input == "/") { 674 str = AMremoveCharsAndBlanks(str,symbol.input.length); 675 result = AMparseIexpr(str); 676 if (result[0] == null) // show box in place of missing argument 677 result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); 678 else AMremoveBrackets(result[0]); 679 str = result[1]; 680 AMremoveBrackets(node); 681 node = AMcreateMmlNode(symbol.tag,node); 682 node.appendChild(result[0]); 683 newFrag.appendChild(node); 684 symbol = AMgetSymbol(str); 685 } 686 else if (node!=undefined) newFrag.appendChild(node); 687 } while ((symbol.ttype != RIGHTBRACKET && 688 (symbol.ttype != LEFTRIGHT || rightbracket) 689 || AMnestingDepth == 0) && symbol!=null && symbol.output!=""); 690 if (symbol.ttype == RIGHTBRACKET || symbol.ttype == LEFTRIGHT) { 691// if (AMnestingDepth > 0) AMnestingDepth--; 692 var len = newFrag.childNodes.length; 693 if (len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 && 694 newFrag.childNodes[len-2].nodeName == "mo" && 695 newFrag.childNodes[len-2].firstChild.nodeValue == ",") { //matrix 696 var right = newFrag.childNodes[len-1].lastChild.firstChild.nodeValue; 697 if (right==")" || right=="]") { 698 var left = newFrag.childNodes[len-1].firstChild.firstChild.nodeValue; 699 if (left=="(" && right==")" && symbol.output != "}" || 700 left=="[" && right=="]") { 701 var pos = []; // positions of commas 702 var matrix = true; 703 var m = newFrag.childNodes.length; 704 for (i=0; matrix && i<m; i=i+2) { 705 pos[i] = []; 706 node = newFrag.childNodes[i]; 707 if (matrix) matrix = node.nodeName=="mrow" && 708 (i==m-1 || node.nextSibling.nodeName=="mo" && 709 node.nextSibling.firstChild.nodeValue==",")&& 710 node.firstChild.firstChild.nodeValue==left && 711 node.lastChild.firstChild.nodeValue==right; 712 if (matrix) 713 for (var j=0; j<node.childNodes.length; j++) 714 if (node.childNodes[j].firstChild.nodeValue==",") 715 pos[i][pos[i].length]=j; 716 if (matrix && i>1) matrix = pos[i].length == pos[i-2].length; 717 } 718 if (matrix) { 719 var row, frag, n, k, table = document.createDocumentFragment(); 720 for (i=0; i<m; i=i+2) { 721 row = document.createDocumentFragment(); 722 frag = document.createDocumentFragment(); 723 node = newFrag.firstChild; // <mrow>(-,-,...,-,-)</mrow> 724 n = node.childNodes.length; 725 k = 0; 726 node.removeChild(node.firstChild); //remove ( 727 for (j=1; j<n-1; j++) { 728 if (typeof pos[i][k] != "undefined" && j==pos[i][k]){ 729 node.removeChild(node.firstChild); //remove , 730 row.appendChild(AMcreateMmlNode("mtd",frag)); 731 k++; 732 } else frag.appendChild(node.firstChild); 733 } 734 row.appendChild(AMcreateMmlNode("mtd",frag)); 735 if (newFrag.childNodes.length>2) { 736 newFrag.removeChild(newFrag.firstChild); //remove <mrow>)</mrow> 737 newFrag.removeChild(newFrag.firstChild); //remove <mo>,</mo> 738 } 739 table.appendChild(AMcreateMmlNode("mtr",row)); 740 } 741 node = AMcreateMmlNode("mtable",table); 742 if (typeof symbol.invisible == "boolean" && symbol.invisible) node.setAttribute("columnalign","left"); 743 newFrag.replaceChild(node,newFrag.firstChild); 744 } 745 } 746 } 747 } 748 str = AMremoveCharsAndBlanks(str,symbol.input.length); 749 if (typeof symbol.invisible != "boolean" || !symbol.invisible) { 750 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 751 newFrag.appendChild(node); 752 } 753 } 754 return [newFrag,str]; 755} 756 757function AMparseMath(str) { 758 var result, node = AMcreateElementMathML("mstyle"); 759 if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); 760 if (displaystyle) node.setAttribute("displaystyle","true"); 761 if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); 762 AMnestingDepth = 0; 763 node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false)[0]); 764 node = AMcreateMmlNode("math",node); 765 if (showasciiformulaonhover) //fixed by djhsu so newline 766 node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko 767 if (mathfontfamily != "" && (isIE || mathfontfamily != "serif")) { 768 var fnode = AMcreateElementXHTML("font"); 769 fnode.setAttribute("face",mathfontfamily); 770 fnode.appendChild(node); 771 return fnode; 772 } 773 return node; 774} 775 776function AMstrarr2docFrag(arr, linebreaks) { 777 var newFrag=document.createDocumentFragment(); 778 var expr = false; 779 for (var i=0; i<arr.length; i++) { 780 if (expr) newFrag.appendChild(AMparseMath(arr[i])); 781 else { 782 var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]); 783 newFrag.appendChild(AMcreateElementXHTML("span"). 784 appendChild(document.createTextNode(arri[0]))); 785 for (var j=1; j<arri.length; j++) { 786 newFrag.appendChild(AMcreateElementXHTML("p")); 787 newFrag.appendChild(AMcreateElementXHTML("span"). 788 appendChild(document.createTextNode(arri[j]))); 789 } 790 } 791 expr = !expr; 792 } 793 return newFrag; 794} 795 796function AMprocessNodeR(n, linebreaks) { 797 var mtch, str, arr, frg, i; 798 if (n.childNodes.length == 0) { 799 if ((n.nodeType!=8 || linebreaks) && 800 n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" && 801 n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA" && 802 n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE") { 803 str = n.nodeValue; 804 if (!(str == null)) { 805 str = str.replace(/\r\n\r\n/g,"\n\n"); 806 if (doubleblankmathdelimiter) { 807 str = str.replace(/\x20\x20\./g," "+AMdelimiter1+"."); 808 str = str.replace(/\x20\x20,/g," "+AMdelimiter1+","); 809 str = str.replace(/\x20\x20/g," "+AMdelimiter1+" "); 810 } 811 str = str.replace(/\x20+/g," "); 812 str = str.replace(/\s*\r\n/g," "); 813 mtch = false; 814 str = str.replace(new RegExp(AMescape2, "g"), 815 function(st){mtch=true;return "AMescape2"}); 816 str = str.replace(new RegExp(AMescape1, "g"), 817 function(st){mtch=true;return "AMescape1"}); 818 str = str.replace(new RegExp(AMdelimiter2regexp, "g"),AMdelimiter1); 819 arr = str.split(AMdelimiter1); 820 for (i=0; i<arr.length; i++) 821 arr[i]=arr[i].replace(/AMescape2/g,AMdelimiter2). 822 replace(/AMescape1/g,AMdelimiter1); 823 if (arr.length>1 || mtch) { 824 if (checkForMathML) { 825 checkForMathML = false; 826 var nd = AMisMathMLavailable(); 827 AMnoMathML = nd != null 828 if (AMnoMathML && notifyIfNoMathML) 829 AMbody.insertBefore(nd,AMbody.childNodes[0]); 830 } 831 if (!AMnoMathML) { 832 frg = AMstrarr2docFrag(arr,n.nodeType==8); 833 var len = frg.childNodes.length; 834 n.parentNode.replaceChild(frg,n); 835 return len-1; 836 } else return 0; 837 } 838 } 839 } else return 0; 840 } else if (n.nodeName!="math") { 841 for (i=0; i<n.childNodes.length; i++) 842 i += AMprocessNodeR(n.childNodes[i], linebreaks); 843 } 844 return 0; 845} 846 847function AMprocessNode(n, linebreaks, spanclassAM) { 848 var frag,st; 849 if (spanclassAM!=null) { 850 frag = document.getElementsByTagName("span") 851 for (var i=0;i<frag.length;i++) 852 if (frag[i].className == "AM") 853 AMprocessNodeR(frag[i],linebreaks); 854 } else { 855 try { 856 st = n.innerHTML; 857 } catch(err) {} 858 if (st==null || 859 st.indexOf(AMdelimiter1)!=-1 || st.indexOf(AMdelimiter2)!=-1) 860 AMprocessNodeR(n,linebreaks); 861 } 862 if (isIE) { //needed to match size and font of formula to surrounding text 863 frag = document.getElementsByTagName('math'); 864 for (var i=0;i<frag.length;i++) frag[i].update() 865 } 866} 867 868var AMbody; 869var AMnoMathML = false, AMtranslated = false; 870 871function translate(spanclassAM) { 872 if (!AMtranslated) { // run this only once 873 AMtranslated = true; 874 AMinitSymbols(); 875 AMbody = document.getElementsByTagName("body")[0]; 876 AMprocessNode(AMbody, false, spanclassAM); 877 } 878} 879 880if (isIE) { // avoid adding MathPlayer info explicitly to each webpage 881 document.write("<object id=\"mathplayer\"\ 882 classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>"); 883 document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>"); 884} 885 886// GO1.1 Generic onload by Brothercake 887// http://www.brothercake.com/ 888//onload function (replaces the onload="translate()" in the <body> tag) 889function generic() 890{ 891 translate(); 892}; 893//setup onload function 894if(typeof window.addEventListener != 'undefined') 895{ 896 //.. gecko, safari, konqueror and standard 897 window.addEventListener('load', generic, false); 898} 899else if(typeof document.addEventListener != 'undefined') 900{ 901 //.. opera 7 902 document.addEventListener('load', generic, false); 903} 904else if(typeof window.attachEvent != 'undefined') 905{ 906 //.. win/ie 907 window.attachEvent('onload', generic); 908} 909//** remove this condition to degrade older browsers 910else 911{ 912 //.. mac/ie5 and anything else that gets this far 913 //if there's an existing onload function 914 if(typeof window.onload == 'function') 915 { 916 //store it 917 var existing = onload; 918 //add new onload handler 919 window.onload = function() 920 { 921 //call existing onload function 922 existing(); 923 //call generic onload function 924 generic(); 925 }; 926 } 927 else 928 { 929 //setup onload function 930 window.onload = generic; 931 } 932} 933