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 \nMozilla/Netscape 7+ or Internet Explorer 6+MathPlayer") 78 79// all further global variables start with "AM" 80 81function AMcreateElementXHTML(t) { 82 if (isIE) return document.createElement(t); 83 else return document.createElementNS("http://www.w3.org/1999/xhtml",t); 84} 85 86function AMnoMathMLNote() { 87 var nd = AMcreateElementXHTML("h3"); 88 nd.setAttribute("align","center") 89 nd.appendChild(AMcreateElementXHTML("p")); 90 nd.appendChild(document.createTextNode("To view the ")); 91 var an = AMcreateElementXHTML("a"); 92 an.appendChild(document.createTextNode("LaTeXMathML"));
93 an.setAttribute("href","http://www.maths.nott.ac.uk/personal/drw/lm.html"); 94 nd.appendChild(an); 95 nd.appendChild(document.createTextNode(" notation use Internet Explorer 6+")); 96 an = AMcreateElementXHTML("a"); 97 an.appendChild(document.createTextNode("MathPlayer")); 98 an.setAttribute("href","http://www.dessci.com/en/products/mathplayer/download.htm"); 99 nd.appendChild(an); 100 nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox")); 101 nd.appendChild(AMcreateElementXHTML("p")); 102 return nd; 103} 104 105function AMisMathMLavailable() { 106 if (navigator.appName.slice(0,8)=="Netscape") 107 if (navigator.appVersion.slice(0,1)>="5") return null; 108 else return AMnoMathMLNote(); 109 else if (navigator.appName.slice(0,9)=="Microsoft") 110 try { 111 var ActiveX = new ActiveXObject("MathPlayer.Factory.1"); 112 return null; 113 } catch (e) { 114 return AMnoMathMLNote(); 115 } 116 else return AMnoMathMLNote(); 117} 118 119// character lists for Mozilla/Netscape fonts 120var AMcal = ["\uD835\uDC9C", "\uD835\uDC9D", "\uD835\uDC9E", "\uD835\uDC9F", "\uD835\uDCA0", "\uD835\uDCA1", "\uD835\uDCA2", "\uD835\uDCA3", "\uD835\uDCA4", "\uD835\uDCA5", "\uD835\uDCA6", "\uD835\uDCA7", "\uD835\uDCA8", "\uD835\uDCA9", "\uD835\uDCAA", "\uD835\uDCAB", "\uD835\uDCAC", "\uD835\uDCAD", "\uD835\uDCAE", "\uD835\uDCAF", "\uD835\uDCB0", "\uD835\uDCB1", "\uD835\uDCB2", "\uD835\uDCB3", "\uD835\uDCB4", "\uD835\uDCB5"]; 121var AMfrk = ["\uD835\uDD04", "\uD835\uDD05", "\uD835\uDD06", "\uD835\uDD07", "\uD835\uDD08", "\uD835\uDD09", "\uD835\uDD0A", "\uD835\uDD0B", "\uD835\uDD0C", "\uD835\uDD0D", "\uD835\uDD0E", "\uD835\uDD0F", "\uD835\uDD10", "\uD835\uDD11", "\uD835\uDD12", "\uD835\uDD13", "\uD835\uDD14", "\uD835\uDD15", "\uD835\uDD16", "\uD835\uDD17", "\uD835\uDD18", "\uD835\uDD19", "\uD835\uDD1A", "\uD835\uDD1B", "\uD835\uDD1C", "\uD835\uDD1D"]; 122var AMbbb = ["\uD835\uDD38", "\uD835\uDD39", "\uD835\uDD3A", "\uD835\uDD3B", "\uD835\uDD3C", "\uD835\uDD3D", "\uD835\uDD3E", "\uD835\uDD3F", "\uD835\uDD40", "\uD835\uDD41", "\uD835\uDD42", "\uD835\uDD43", "\uD835\uDD44", "\uD835\uDD45", "\uD835\uDD46", "\uD835\uDD47", "\uD835\uDD48", "\uD835\uDD49", "\uD835\uDD4A", "\uD835\uDD4B", "\uD835\uDD4C", "\uD835\uDD4D", "\uD835\uDD4E", "\uD835\uDD4F", "\uD835\uDD50", "\uD835\uDD51"]; 123 124var CONST = 0, UNARY = 1, BINARY = 2, INFIX = 3, LEFTBRACKET = 4, 125 RIGHTBRACKET = 5, SPACE = 6, UNDEROVER = 7, DEFINITION = 8, 126 TEXT = 9, BIG = 10, LONG = 11, STRETCHY = 12, MATRIX = 13; // token types 127 128var AMsqrt = {input:"\\sqrt", tag:"msqrt", output:"sqrt", ttype:UNARY}, 129 AMnot = {input:"\\not", tag:"mnot", output:"not", 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 145// List of negations obtained from http://frodo.elon.edu/tutorial/tutorial.pdf 146var AMRelationNegations = { 147 "\u003C":"\u226E", "\u003E":"\u226F", "\u2264":"\u2270", "\u2265":"\u2271", 148 "\u003D":"\u2260", "\u2261":"\u2262", "\u227A":"\u2280", "\u227B":"\u2281", 149 "\u227C":"\u22E0", "\u227D":"\u22E1", "\u223C":"\u2241", "\u2243":"\u2244", 150 "\u2282":"\u2284", "\u2283":"\u2285", "\u2286":"\u2288", "\u2287":"\u2289", 151 "\u2248":"\u2249", "\u2245":"\u2247", "\u2291":"\u22E2", "\u2292":"\u22E3", 152 "\u224D":"\u226D" 153} 154 155var AMsymbols = [ 156//Greek letters 157{input:"\\alpha", tag:"mi", output:"\u03B1", ttype:CONST}, 158{input:"\\beta", tag:"mi", output:"\u03B2", ttype:CONST}, 159{input:"\\gamma", tag:"mi", output:"\u03B3", ttype:CONST}, 160{input:"\\delta", tag:"mi", output:"\u03B4", ttype:CONST}, 161{input:"\\epsilon", tag:"mi", output:"\u03B5", ttype:CONST}, 162{input:"\\varepsilon", tag:"mi", output:"\u025B", ttype:CONST}, 163{input:"\\zeta", tag:"mi", output:"\u03B6", ttype:CONST}, 164{input:"\\eta", tag:"mi", output:"\u03B7", ttype:CONST}, 165{input:"\\theta", tag:"mi", output:"\u03B8", ttype:CONST}, 166{input:"\\vartheta", tag:"mi", output:"\u03D1", ttype:CONST}, 167{input:"\\iota", tag:"mi", output:"\u03B9", ttype:CONST}, 168{input:"\\kappa", tag:"mi", output:"\u03BA", ttype:CONST}, 169{input:"\\lambda", tag:"mi", output:"\u03BB", ttype:CONST}, 170{input:"\\mu", tag:"mi", output:"\u03BC", ttype:CONST}, 171{input:"\\nu", tag:"mi", output:"\u03BD", ttype:CONST}, 172{input:"\\xi", tag:"mi", output:"\u03BE", ttype:CONST}, 173{input:"\\pi", tag:"mi", output:"\u03C0", ttype:CONST}, 174{input:"\\varpi", tag:"mi", output:"\u03D6", ttype:CONST}, 175{input:"\\rho", tag:"mi", output:"\u03C1", ttype:CONST}, 176{input:"\\varrho", tag:"mi", output:"\u03F1", ttype:CONST}, 177{input:"\\varsigma", tag:"mi", output:"\u03C2", ttype:CONST}, 178{input:"\\sigma", tag:"mi", output:"\u03C3", ttype:CONST}, 179{input:"\\tau", tag:"mi", output:"\u03C4", ttype:CONST}, 180{input:"\\upsilon", tag:"mi", output:"\u03C5", ttype:CONST}, 181{input:"\\phi", tag:"mi", output:"\u03C6", ttype:CONST}, 182{input:"\\varphi", tag:"mi", output:"\u03D5", ttype:CONST}, 183{input:"\\chi", tag:"mi", output:"\u03C7", ttype:CONST}, 184{input:"\\psi", tag:"mi", output:"\u03C8", ttype:CONST}, 185{input:"\\omega", tag:"mi", output:"\u03C9", ttype:CONST}, 186{input:"\\Gamma", tag:"mo", output:"\u0393", ttype:CONST}, 187{input:"\\Delta", tag:"mo", output:"\u0394", ttype:CONST}, 188{input:"\\Theta", tag:"mo", output:"\u0398", ttype:CONST}, 189{input:"\\Lambda", tag:"mo", output:"\u039B", ttype:CONST}, 190{input:"\\Xi", tag:"mo", output:"\u039E", ttype:CONST}, 191{input:"\\Pi", tag:"mo", output:"\u03A0", ttype:CONST}, 192{input:"\\Sigma", tag:"mo", output:"\u03A3", ttype:CONST}, 193{input:"\\Upsilon", tag:"mo", output:"\u03A5", ttype:CONST}, 194{input:"\\Phi", tag:"mo", output:"\u03A6", ttype:CONST}, 195{input:"\\Psi", tag:"mo", output:"\u03A8", ttype:CONST}, 196{input:"\\Omega", tag:"mo", output:"\u03A9", ttype:CONST}, 197 198//fractions 199{input:"\\frac12", tag:"mo", output:"\u00BD", ttype:CONST}, 200{input:"\\frac14", tag:"mo", output:"\u00BC", ttype:CONST}, 201{input:"\\frac34", tag:"mo", output:"\u00BE", ttype:CONST}, 202{input:"\\frac13", tag:"mo", output:"\u2153", ttype:CONST}, 203{input:"\\frac23", tag:"mo", output:"\u2154", ttype:CONST}, 204{input:"\\frac15", tag:"mo", output:"\u2155", ttype:CONST}, 205{input:"\\frac25", tag:"mo", output:"\u2156", ttype:CONST}, 206{input:"\\frac35", tag:"mo", output:"\u2157", ttype:CONST}, 207{input:"\\frac45", tag:"mo", output:"\u2158", ttype:CONST}, 208{input:"\\frac16", tag:"mo", output:"\u2159", ttype:CONST}, 209{input:"\\frac56", tag:"mo", output:"\u215A", ttype:CONST}, 210{input:"\\frac18", tag:"mo", output:"\u215B", ttype:CONST}, 211{input:"\\frac38", tag:"mo", output:"\u215C", ttype:CONST}, 212{input:"\\frac58", tag:"mo", output:"\u215D", ttype:CONST}, 213{input:"\\frac78", tag:"mo", output:"\u215E", ttype:CONST}, 214 215//binary operation symbols 216{input:"\\pm", tag:"mo", output:"\u00B1", ttype:CONST}, 217{input:"\\mp", tag:"mo", output:"\u2213", ttype:CONST}, 218{input:"\\triangleleft",tag:"mo", output:"\u22B2", ttype:CONST}, 219{input:"\\triangleright",tag:"mo",output:"\u22B3", ttype:CONST}, 220{input:"\\cdot", tag:"mo", output:"\u22C5", ttype:CONST}, 221{input:"\\star", tag:"mo", output:"\u22C6", ttype:CONST}, 222{input:"\\ast", tag:"mo", output:"\u002A", ttype:CONST}, 223{input:"\\times", tag:"mo", output:"\u00D7", ttype:CONST}, 224{input:"\\div", tag:"mo", output:"\u00F7", ttype:CONST}, 225{input:"\\circ", tag:"mo", output:"\u2218", ttype:CONST}, 226//{input:"\\bullet", tag:"mo", output:"\u2219", ttype:CONST}, 227{input:"\\bullet", tag:"mo", output:"\u2022", ttype:CONST}, 228{input:"\\oplus", tag:"mo", output:"\u2295", ttype:CONST}, 229{input:"\\ominus", tag:"mo", output:"\u2296", ttype:CONST}, 230{input:"\\otimes", tag:"mo", output:"\u2297", ttype:CONST}, 231{input:"\\bigcirc", tag:"mo", output:"\u25CB", ttype:CONST}, 232{input:"\\oslash", tag:"mo", output:"\u2298", ttype:CONST}, 233{input:"\\odot", tag:"mo", output:"\u2299", ttype:CONST}, 234{input:"\\land", tag:"mo", output:"\u2227", ttype:CONST}, 235{input:"\\wedge", tag:"mo", output:"\u2227", ttype:CONST}, 236{input:"\\lor", tag:"mo", output:"\u2228", ttype:CONST}, 237{input:"\\vee", tag:"mo", output:"\u2228", ttype:CONST}, 238{input:"\\cap", tag:"mo", output:"\u2229", ttype:CONST}, 239{input:"\\cup", tag:"mo", output:"\u222A", ttype:CONST}, 240{input:"\\sqcap", tag:"mo", output:"\u2293", ttype:CONST}, 241{input:"\\sqcup", tag:"mo", output:"\u2294", ttype:CONST}, 242{input:"\\uplus", tag:"mo", output:"\u228E", ttype:CONST}, 243{input:"\\amalg", tag:"mo", output:"\u2210", ttype:CONST},
244{input:"\\bigtriangleup",tag:"mo",output:"\u25B3", ttype:CONST}, 245{input:"\\bigtriangledown",tag:"mo",output:"\u25BD", ttype:CONST}, 246{input:"\\dag", tag:"mo", output:"\u2020", ttype:CONST}, 247{input:"\\dagger", tag:"mo", output:"\u2020", ttype:CONST}, 248{input:"\\ddag", tag:"mo", output:"\u2021", ttype:CONST}, 249{input:"\\ddagger", tag:"mo", output:"\u2021", ttype:CONST}, 250{input:"\\lhd", tag:"mo", output:"\u22B2", ttype:CONST}, 251{input:"\\rhd", tag:"mo", output:"\u22B3", ttype:CONST}, 252{input:"\\unlhd", tag:"mo", output:"\u22B4", ttype:CONST}, 253{input:"\\unrhd", tag:"mo", output:"\u22B5", ttype:CONST}, 254 255 256//BIG Operators 257{input:"\\sum", tag:"mo", output:"\u2211", ttype:UNDEROVER}, 258{input:"\\prod", tag:"mo", output:"\u220F", ttype:UNDEROVER}, 259{input:"\\bigcap", tag:"mo", output:"\u22C2", ttype:UNDEROVER}, 260{input:"\\bigcup", tag:"mo", output:"\u22C3", ttype:UNDEROVER}, 261{input:"\\bigwedge", tag:"mo", output:"\u22C0", ttype:UNDEROVER}, 262{input:"\\bigvee", tag:"mo", output:"\u22C1", ttype:UNDEROVER}, 263{input:"\\bigsqcap", tag:"mo", output:"\u2A05", ttype:UNDEROVER}, 264{input:"\\bigsqcup", tag:"mo", output:"\u2A06", ttype:UNDEROVER}, 265{input:"\\coprod", tag:"mo", output:"\u2210", ttype:UNDEROVER}, 266{input:"\\bigoplus", tag:"mo", output:"\u2A01", ttype:UNDEROVER}, 267{input:"\\bigotimes", tag:"mo", output:"\u2A02", ttype:UNDEROVER}, 268{input:"\\bigodot", tag:"mo", output:"\u2A00", ttype:UNDEROVER}, 269{input:"\\biguplus", tag:"mo", output:"\u2A04", ttype:UNDEROVER}, 270{input:"\\int", tag:"mo", output:"\u222B", ttype:CONST}, 271{input:"\\oint", tag:"mo", output:"\u222E", ttype:CONST}, 272 273//binary relation symbols 274{input:":=", tag:"mo", output:":=", ttype:CONST}, 275{input:"\\lt", tag:"mo", output:"<", ttype:CONST}, 276{input:"\\gt", tag:"mo", output:">", ttype:CONST}, 277{input:"\\ne", tag:"mo", output:"\u2260", ttype:CONST}, 278{input:"\\neq", tag:"mo", output:"\u2260", ttype:CONST}, 279{input:"\\le", tag:"mo", output:"\u2264", ttype:CONST}, 280{input:"\\leq", tag:"mo", output:"\u2264", ttype:CONST}, 281{input:"\\leqslant", tag:"mo", output:"\u2264", ttype:CONST}, 282{input:"\\ge", tag:"mo", output:"\u2265", ttype:CONST}, 283{input:"\\geq", tag:"mo", output:"\u2265", ttype:CONST}, 284{input:"\\geqslant", tag:"mo", output:"\u2265", ttype:CONST}, 285{input:"\\equiv", tag:"mo", output:"\u2261", ttype:CONST}, 286{input:"\\ll", tag:"mo", output:"\u226A", ttype:CONST}, 287{input:"\\gg", tag:"mo", output:"\u226B", ttype:CONST}, 288{input:"\\doteq", tag:"mo", output:"\u2250", ttype:CONST}, 289{input:"\\prec", tag:"mo", output:"\u227A", ttype:CONST}, 290{input:"\\succ", tag:"mo", output:"\u227B", ttype:CONST}, 291{input:"\\preceq", tag:"mo", output:"\u227C", ttype:CONST}, 292{input:"\\succeq", tag:"mo", output:"\u227D", ttype:CONST}, 293{input:"\\subset", tag:"mo", output:"\u2282", ttype:CONST}, 294{input:"\\supset", tag:"mo", output:"\u2283", ttype:CONST}, 295{input:"\\subseteq", tag:"mo", output:"\u2286", ttype:CONST}, 296{input:"\\supseteq", tag:"mo", output:"\u2287", ttype:CONST}, 297{input:"\\subsetneq", tag:"mo", output:"\u228A", ttype:CONST}, 298{input:"\\supsetneq", tag:"mo", output:"\u228B", ttype:CONST}, 299{input:"\\sqsubset", tag:"mo", output:"\u228F", ttype:CONST}, 300{input:"\\sqsupset", tag:"mo", output:"\u2290", ttype:CONST}, 301{input:"\\sqsubseteq", tag:"mo", output:"\u2291", ttype:CONST}, 302{input:"\\sqsupseteq", tag:"mo", output:"\u2292", ttype:CONST}, 303{input:"\\sim", tag:"mo", output:"\u223C", ttype:CONST}, 304{input:"\\simeq", tag:"mo", output:"\u2243", ttype:CONST}, 305{input:"\\approx", tag:"mo", output:"\u2248", ttype:CONST}, 306{input:"\\cong", tag:"mo", output:"\u2245", ttype:CONST}, 307{input:"\\Join", tag:"mo", output:"\u22C8", ttype:CONST}, 308{input:"\\bowtie", tag:"mo", output:"\u22C8", ttype:CONST}, 309{input:"\\in", tag:"mo", output:"\u2208", ttype:CONST}, 310{input:"\\ni", tag:"mo", output:"\u220B", ttype:CONST}, 311{input:"\\owns", tag:"mo", output:"\u220B", ttype:CONST}, 312{input:"\\propto", tag:"mo", output:"\u221D", ttype:CONST}, 313{input:"\\vdash", tag:"mo", output:"\u22A2", ttype:CONST}, 314{input:"\\dashv", tag:"mo", output:"\u22A3", ttype:CONST}, 315{input:"\\models", tag:"mo", output:"\u22A8", ttype:CONST}, 316{input:"\\perp", tag:"mo", output:"\u22A5", ttype:CONST}, 317{input:"\\smile", tag:"mo", output:"\u2323", ttype:CONST}, 318{input:"\\frown", tag:"mo", output:"\u2322", ttype:CONST}, 319{input:"\\asymp", tag:"mo", output:"\u224D", ttype:CONST}, 320{input:"\\notin", tag:"mo", output:"\u2209", ttype:CONST}, 321 322//matrices 323{input:"\\begin{eqnarray}", output:"X", ttype:MATRIX, invisible:true}, 324{input:"\\begin{array}", output:"X", ttype:MATRIX, invisible:true}, 325{input:"\\\\", output:"}&{", ttype:DEFINITION}, 326{input:"\\end{eqnarray}", output:"}}", ttype:DEFINITION}, 327{input:"\\end{array}", output:"}}", ttype:DEFINITION}, 328 329//grouping and literal brackets -- ieval is for IE 330{input:"\\big", tag:"mo", output:"X", atval:"1.2", ieval:"2.2", ttype:BIG}, 331{input:"\\Big", tag:"mo", output:"X", atval:"1.6", ieval:"2.6", ttype:BIG}, 332{input:"\\bigg", tag:"mo", output:"X", atval:"2.2", ieval:"3.2", ttype:BIG}, 333{input:"\\Bigg", tag:"mo", output:"X", atval:"2.9", ieval:"3.9", ttype:BIG}, 334{input:"\\left", tag:"mo", output:"X", ttype:LEFTBRACKET}, 335{input:"\\right", tag:"mo", output:"X", ttype:RIGHTBRACKET}, 336{input:"{", output:"{", ttype:LEFTBRACKET, invisible:true}, 337{input:"}", output:"}", ttype:RIGHTBRACKET, invisible:true}, 338 339{input:"(", tag:"mo", output:"(", atval:"1", ttype:STRETCHY}, 340{input:"[", tag:"mo", output:"[", atval:"1", ttype:STRETCHY}, 341{input:"\\lbrack", tag:"mo", output:"[", atval:"1", ttype:STRETCHY}, 342{input:"\\{", tag:"mo", output:"{", atval:"1", ttype:STRETCHY}, 343{input:"\\lbrace", tag:"mo", output:"{", atval:"1", ttype:STRETCHY}, 344{input:"\\langle", tag:"mo", output:"\u2329", atval:"1", ttype:STRETCHY}, 345{input:"\\lfloor", tag:"mo", output:"\u230A", atval:"1", ttype:STRETCHY}, 346{input:"\\lceil", tag:"mo", output:"\u2308", atval:"1", ttype:STRETCHY}, 347 348// rtag:"mi" causes space to be inserted before a following sin, cos, etc. 349// (see function AMparseExpr() ) 350{input:")", tag:"mo",output:")", rtag:"mi",atval:"1",ttype:STRETCHY}, 351{input:"]", tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY}, 352{input:"\\rbrack",tag:"mo",output:"]", rtag:"mi",atval:"1",ttype:STRETCHY}, 353{input:"\\}", tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY}, 354{input:"\\rbrace",tag:"mo",output:"}", rtag:"mi",atval:"1",ttype:STRETCHY}, 355{input:"\\rangle",tag:"mo",output:"\u232A", rtag:"mi",atval:"1",ttype:STRETCHY}, 356{input:"\\rfloor",tag:"mo",output:"\u230B", rtag:"mi",atval:"1",ttype:STRETCHY}, 357{input:"\\rceil", tag:"mo",output:"\u2309", rtag:"mi",atval:"1",ttype:STRETCHY}, 358 359// "|", "\\|", "\\vert" and "\\Vert" modified later: lspace = rspace = 0em 360{input:"|", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 361{input:"\\|", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 362{input:"\\vert", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 363{input:"\\Vert", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 364{input:"\\mid", tag:"mo", output:"\u2223", atval:"1", ttype:STRETCHY}, 365{input:"\\parallel", tag:"mo", output:"\u2225", atval:"1", ttype:STRETCHY}, 366{input:"/", tag:"mo", output:"/", atval:"1.01", ttype:STRETCHY}, 367{input:"\\backslash", tag:"mo", output:"\u2216", atval:"1", ttype:STRETCHY}, 368{input:"\\setminus", tag:"mo", output:"\\", ttype:CONST}, 369 370//miscellaneous symbols 371{input:"\\!", tag:"mspace", atname:"width", atval:"-0.167em", ttype:SPACE}, 372{input:"\\,", tag:"mspace", atname:"width", atval:"0.167em", ttype:SPACE}, 373{input:"\\>", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE}, 374{input:"\\:", tag:"mspace", atname:"width", atval:"0.222em", ttype:SPACE}, 375{input:"\\;", tag:"mspace", atname:"width", atval:"0.278em", ttype:SPACE}, 376{input:"~", tag:"mspace", atname:"width", atval:"0.333em", ttype:SPACE}, 377{input:"\\quad", tag:"mspace", atname:"width", atval:"1em", ttype:SPACE}, 378{input:"\\qquad", tag:"mspace", atname:"width", atval:"2em", ttype:SPACE}, 379//{input:"{}", tag:"mo", output:"\u200B", ttype:CONST}, // zero-width 380{input:"\\prime", tag:"mo", output:"\u2032", ttype:CONST}, 381{input:"'", tag:"mo", output:"\u02B9", ttype:CONST}, 382{input:"''", tag:"mo", output:"\u02BA", ttype:CONST}, 383{input:"'''", tag:"mo", output:"\u2034", ttype:CONST}, 384{input:"''''", tag:"mo", output:"\u2057", ttype:CONST}, 385{input:"\\ldots", tag:"mo", output:"\u2026", ttype:CONST}, 386{input:"\\cdots", tag:"mo", output:"\u22EF", ttype:CONST}, 387{input:"\\vdots", tag:"mo", output:"\u22EE", ttype:CONST}, 388{input:"\\ddots", tag:"mo", output:"\u22F1", ttype:CONST}, 389{input:"\\forall", tag:"mo", output:"\u2200", ttype:CONST}, 390{input:"\\exists", tag:"mo", output:"\u2203", ttype:CONST}, 391{input:"\\Re", tag:"mo", output:"\u211C", ttype:CONST}, 392{input:"\\Im", tag:"mo", output:"\u2111", ttype:CONST}, 393{input:"\\aleph", tag:"mo", output:"\u2135", ttype:CONST}, 394{input:"\\hbar", tag:"mo", output:"\u210F", ttype:CONST}, 395{input:"\\ell", tag:"mo", output:"\u2113", ttype:CONST}, 396{input:"\\wp", tag:"mo", output:"\u2118", ttype:CONST}, 397{input:"\\emptyset", tag:"mo", output:"\u2205", ttype:CONST}, 398{input:"\\infty", tag:"mo", output:"\u221E", ttype:CONST}, 399{input:"\\surd", tag:"mo", output:"\\sqrt{}", ttype:DEFINITION}, 400{input:"\\partial", tag:"mo", output:"\u2202", ttype:CONST}, 401{input:"\\nabla", tag:"mo", output:"\u2207", ttype:CONST}, 402{input:"\\triangle", tag:"mo", output:"\u25B3", ttype:CONST}, 403{input:"\\therefore", tag:"mo", output:"\u2234", ttype:CONST}, 404{input:"\\angle", tag:"mo", output:"\u2220", ttype:CONST}, 405//{input:"\\\\ ", tag:"mo", output:"\u00A0", ttype:CONST}, 406{input:"\\diamond", tag:"mo", output:"\u22C4", ttype:CONST}, 407//{input:"\\Diamond", tag:"mo", output:"\u25CA", ttype:CONST}, 408{input:"\\Diamond", tag:"mo", output:"\u25C7", ttype:CONST}, 409{input:"\\neg", tag:"mo", output:"\u00AC", ttype:CONST}, 410{input:"\\lnot", tag:"mo", output:"\u00AC", ttype:CONST}, 411{input:"\\bot", tag:"mo", output:"\u22A5", ttype:CONST}, 412{input:"\\top", tag:"mo", output:"\u22A4", ttype:CONST}, 413{input:"\\square", tag:"mo", output:"\u25AB", ttype:CONST}, 414{input:"\\Box", tag:"mo", output:"\u25A1", ttype:CONST}, 415{input:"\\wr", tag:"mo", output:"\u2240", ttype:CONST}, 416 417//standard functions 418//Note UNDEROVER *must* have tag:"mo" to work properly 419{input:"\\arccos", tag:"mi", output:"arccos", ttype:UNARY, func:true}, 420{input:"\\arcsin", tag:"mi", output:"arcsin", ttype:UNARY, func:true}, 421{input:"\\arctan", tag:"mi", output:"arctan", ttype:UNARY, func:true}, 422{input:"\\arg", tag:"mi", output:"arg", ttype:UNARY, func:true}, 423{input:"\\cos", tag:"mi", output:"cos", ttype:UNARY, func:true}, 424{input:"\\cosh", tag:"mi", output:"cosh", ttype:UNARY, func:true}, 425{input:"\\cot", tag:"mi", output:"cot", ttype:UNARY, func:true}, 426{input:"\\coth", tag:"mi", output:"coth", ttype:UNARY, func:true}, 427{input:"\\csc", tag:"mi", output:"csc", ttype:UNARY, func:true}, 428{input:"\\deg", tag:"mi", output:"deg", ttype:UNARY, func:true}, 429{input:"\\det", tag:"mi", output:"det", ttype:UNARY, func:true}, 430{input:"\\dim", tag:"mi", output:"dim", ttype:UNARY, func:true}, //CONST? 431{input:"\\exp", tag:"mi", output:"exp", ttype:UNARY, func:true}, 432{input:"\\gcd", tag:"mi", output:"gcd", ttype:UNARY, func:true}, //CONST? 433{input:"\\hom", tag:"mi", output:"hom", ttype:UNARY, func:true}, 434{input:"\\inf", tag:"mo", output:"inf", ttype:UNDEROVER}, 435{input:"\\ker", tag:"mi", output:"ker", ttype:UNARY, func:true}, 436{input:"\\lg", tag:"mi", output:"lg", ttype:UNARY, func:true}, 437{input:"\\lim", tag:"mo", output:"lim", ttype:UNDEROVER}, 438{input:"\\liminf", tag:"mo", output:"liminf", ttype:UNDEROVER}, 439{input:"\\limsup", tag:"mo", output:"limsup", ttype:UNDEROVER}, 440{input:"\\ln", tag:"mi", output:"ln", ttype:UNARY, func:true}, 441{input:"\\log", tag:"mi", output:"log", ttype:UNARY, func:true}, 442{input:"\\max", tag:"mo", output:"max", ttype:UNDEROVER}, 443{input:"\\min", tag:"mo", output:"min", ttype:UNDEROVER}, 444{input:"\\Pr", tag:"mi", output:"Pr", ttype:UNARY, func:true}, 445{input:"\\sec", tag:"mi", output:"sec", ttype:UNARY, func:true}, 446{input:"\\sin", tag:"mi", output:"sin", ttype:UNARY, func:true}, 447{input:"\\sinh", tag:"mi", output:"sinh", ttype:UNARY, func:true}, 448{input:"\\sup", tag:"mo", output:"sup", ttype:UNDEROVER}, 449{input:"\\tan", tag:"mi", output:"tan", ttype:UNARY, func:true}, 450{input:"\\tanh", tag:"mi", output:"tanh", ttype:UNARY, func:true}, 451 452//arrows 453{input:"\\gets", tag:"mo", output:"\u2190", ttype:CONST}, 454{input:"\\leftarrow", tag:"mo", output:"\u2190", ttype:CONST}, 455{input:"\\to", tag:"mo", output:"\u2192", ttype:CONST}, 456{input:"\\rightarrow", tag:"mo", output:"\u2192", ttype:CONST}, 457{input:"\\leftrightarrow", tag:"mo", output:"\u2194", ttype:CONST}, 458{input:"\\uparrow", tag:"mo", output:"\u2191", ttype:CONST}, 459{input:"\\downarrow", tag:"mo", output:"\u2193", ttype:CONST}, 460{input:"\\updownarrow", tag:"mo", output:"\u2195", ttype:CONST}, 461{input:"\\Leftarrow", tag:"mo", output:"\u21D0", ttype:CONST}, 462{input:"\\Rightarrow", tag:"mo", output:"\u21D2", ttype:CONST}, 463{input:"\\Leftrightarrow", tag:"mo", output:"\u21D4", ttype:CONST}, 464{input:"\\iff", tag:"mo", output:"~\\Longleftrightarrow~", ttype:DEFINITION}, 465{input:"\\Uparrow", tag:"mo", output:"\u21D1", ttype:CONST}, 466{input:"\\Downarrow", tag:"mo", output:"\u21D3", ttype:CONST}, 467{input:"\\Updownarrow", tag:"mo", output:"\u21D5", ttype:CONST}, 468{input:"\\mapsto", tag:"mo", output:"\u21A6", ttype:CONST}, 469{input:"\\longleftarrow", tag:"mo", output:"\u2190", ttype:LONG}, 470{input:"\\longrightarrow", tag:"mo", output:"\u2192", ttype:LONG}, 471{input:"\\longleftrightarrow", tag:"mo", output:"\u2194", ttype:LONG}, 472{input:"\\Longleftarrow", tag:"mo", output:"\u21D0", ttype:LONG}, 473{input:"\\Longrightarrow", tag:"mo", output:"\u21D2", ttype:LONG}, 474{input:"\\Longleftrightarrow", tag:"mo", output:"\u21D4", ttype:LONG}, 475{input:"\\longmapsto", tag:"mo", output:"\u21A6", ttype:CONST}, 476 // disaster if LONG 477 478//commands with argument 479AMsqrt, AMnot, AMroot, AMfrac, AMover, AMsub, AMsup, AMtext, AMmbox, AMatop, AMchoose, 480 481//AMdiv, AMquote, 482 483//diacritical marks 484{input:"\\acute", tag:"mover", output:"\u00B4", ttype:UNARY, acc:true}, 485//{input:"\\acute", tag:"mover", output:"\u0317", ttype:UNARY, acc:true}, 486//{input:"\\acute", tag:"mover", output:"\u0301", ttype:UNARY, acc:true}, 487//{input:"\\grave", tag:"mover", output:"\u0300", ttype:UNARY, acc:true}, 488//{input:"\\grave", tag:"mover", output:"\u0316", ttype:UNARY, acc:true}, 489{input:"\\grave", tag:"mover", output:"\u0060", ttype:UNARY, acc:true}, 490{input:"\\breve", tag:"mover", output:"\u02D8", ttype:UNARY, acc:true}, 491{input:"\\check", tag:"mover", output:"\u02C7", ttype:UNARY, acc:true}, 492{input:"\\dot", tag:"mover", output:".", ttype:UNARY, acc:true}, 493{input:"\\ddot", tag:"mover", output:"..", ttype:UNARY, acc:true}, 494//{input:"\\ddot", tag:"mover", output:"\u00A8", ttype:UNARY, acc:true}, 495{input:"\\mathring", tag:"mover", output:"\u00B0", ttype:UNARY, acc:true}, 496{input:"\\vec", tag:"mover", output:"\u20D7", ttype:UNARY, acc:true}, 497{input:"\\overrightarrow",tag:"mover",output:"\u20D7", ttype:UNARY, acc:true}, 498{input:"\\overleftarrow",tag:"mover", output:"\u20D6", ttype:UNARY, acc:true}, 499{input:"\\hat", tag:"mover", output:"\u005E", ttype:UNARY, acc:true}, 500{input:"\\widehat", tag:"mover", output:"\u0302", ttype:UNARY, acc:true}, 501{input:"\\tilde", tag:"mover", output:"~", ttype:UNARY, acc:true}, 502//{input:"\\tilde", tag:"mover", output:"\u0303", ttype:UNARY, acc:true}, 503{input:"\\widetilde", tag:"mover", output:"\u02DC", ttype:UNARY, acc:true}, 504{input:"\\bar", tag:"mover", output:"\u203E", ttype:UNARY, acc:true}, 505{input:"\\overbrace", tag:"mover", output:"\uFE37", ttype:UNARY, acc:true}, //Changed unicode overbrace 506{input:"\\overbracket", tag:"mover", output:"\u23B4", ttype:UNARY, acc:true}, //old overbrace = overbracket 507{input:"\\overline", tag:"mover", output:"\u00AF", ttype:UNARY, acc:true}, 508{input:"\\underbrace", tag:"munder", output:"\uFE38", ttype:UNARY, acc:true}, //Changed unicode underbrace 509{input:"\\underbracket",tag:"munder", output:"\u23B5", ttype:UNARY, acc:true}, //old underbrace = underbracket 510{input:"\\underline", tag:"munder", output:"\u00AF", ttype:UNARY, acc:true}, 511//{input
511:"underline", tag:"munder", output:"\u0332", ttype:UNARY, acc:true}, 512 513//typestyles and fonts 514{input:"\\displaystyle",tag:"mstyle",atname:"displaystyle",atval:"true", ttype:UNARY}, 515{input:"\\textstyle",tag:"mstyle",atname:"displaystyle",atval:"false", ttype:UNARY}, 516{input:"\\scriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"1", ttype:UNARY}, 517{input:"\\scriptscriptstyle",tag:"mstyle",atname:"scriptlevel",atval:"2", ttype:UNARY}, 518{input:"\\textrm", tag:"mstyle", output:"\\mathrm", ttype: DEFINITION}, 519{input:"\\mathbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY}, 520{input:"\\textbf", tag:"mstyle", atname:"mathvariant", atval:"bold", ttype:UNARY}, 521{input:"\\mathit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY}, 522{input:"\\textit", tag:"mstyle", atname:"mathvariant", atval:"italic", ttype:UNARY}, 523{input:"\\mathtt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY}, 524{input:"\\texttt", tag:"mstyle", atname:"mathvariant", atval:"monospace", ttype:UNARY}, 525{input:"\\mathsf", tag:"mstyle", atname:"mathvariant", atval:"sans-serif", ttype:UNARY}, 526{input:"\\mathbb", tag:"mstyle", atname:"mathvariant", atval:"double-struck", ttype:UNARY, codes:AMbbb}, 527{input:"\\mathcal",tag:"mstyle", atname:"mathvariant", atval:"script", ttype:UNARY, codes:AMcal}, 528{input:"\\mathfrak",tag:"mstyle",atname:"mathvariant", atval:"fraktur",ttype:UNARY, codes:AMfrk}, 529{input:"\\textcolor",tag:"mstyle",atname:"mathvariant", atval:"mathcolor", ttype:BINARY}, 530{input:"\\colorbox",tag:"mstyle",atname:"mathvariant", atval:"background", ttype:BINARY} 531]; 532 533function compareNames(s1,s2) { 534 if (s1.input > s2.input) return 1 535 else return -1; 536} 537 538var AMnames = []; //list of input symbols 539 540function AMinitSymbols() { 541 AMsymbols.sort(compareNames); 542 for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input; 543} 544 545var AMmathml = "http://www.w3.org/1998/Math/MathML"; 546 547function AMcreateElementMathML(t) { 548 if (isIE) return document.createElement("m:"+t); 549 else return document.createElementNS(AMmathml,t); 550} 551 552function AMcreateMmlNode(t,frag) { 553// var node = AMcreateElementMathML(name); 554 if (isIE) var node = document.createElement("m:"+t); 555 else var node = document.createElementNS(AMmathml,t); 556 node.appendChild(frag); 557 return node; 558} 559 560function newcommand(oldstr,newstr) { 561 AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr, 562 ttype:DEFINITION}]); 563} 564 565function AMremoveCharsAndBlanks(str,n) { 566//remove n characters and any following blanks 567 var st; 568 st = str.slice(n); 569 for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1); 570 return st.slice(i); 571} 572 573function AMposition(arr, str, n) { 574// return position >=n where str appears or would be inserted 575// assumes arr is sorted 576 if (n==0) { 577 var h,m; 578 n = -1; 579 h = arr.length; 580 while (n+1<h) { 581 m = (n+h) >> 1; 582 if (arr[m]<str) n = m; else h = m; 583 } 584 return h; 585 } else 586 for (var i=n; i<arr.length && arr[i]<str; i++); 587 return i; // i=arr.length || arr[i]>=str 588} 589 590function AMgetSymbol(str) { 591//return maximal initial substring of str that appears in names 592//return null if there is none 593 var k = 0; //new pos 594 var j = 0; //old pos 595 var mk; //match pos 596 var st; 597 var tagst; 598 var match = ""; 599 var more = true; 600 for (var i=1; i<=str.length && more; i++) { 601 st = str.slice(0,i); //initial substring of length i 602 j = k; 603 k = AMposition(AMnames, st, j); 604 if (k<AMnames.length && str.slice(0,AMnames[k].length)==AMnames[k]){ 605 match = AMnames[k]; 606 mk = k; 607 i = match.length; 608 } 609 more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k]; 610 } 611 AMpreviousSymbol=AMcurrentSymbol; 612 if (match!=""){ 613 AMcurrentSymbol=AMsymbols[mk].ttype; 614 return AMsymbols[mk]; 615 } 616 AMcurrentSymbol=CONST; 617 k = 1; 618 st = str.slice(0,1); //take 1 character 619 if ("0"<=st && st<="9") tagst = "mn"; 620 else tagst = (("A">st || st>"Z") && ("a">st || st>"z")?"mo":"mi"); 621/* 622// Commented out by DRW (not fully understood, but probably to do with 623// use of "/" as an INFIX version of "\\frac", which we don't want): 624//} 625//if (st=="-" && AMpreviousSymbol==INFIX) { 626// AMcurrentSymbol = INFIX; //trick "/" into recognizing "-" on second parse
627// return {input:st, tag:tagst, output:st, ttype:UNARY, func:true}; 628//} 629*/ 630 return {input:st, tag:tagst, output:st, ttype:CONST}; 631} 632 633 634/*Parsing ASCII math expressions with the following grammar 635v ::= [A-Za-z] | greek letters | numbers | other constant symbols 636u ::= sqrt | text | bb | other unary symbols for font commands 637b ::= frac | root | stackrel binary symbols 638l ::= { | \left left brackets 639r ::= } | \right right brackets 640S ::= v | lEr | uS | bSS Simple expression 641I ::= S_S | S^S | S_S^S | S Intermediate expression 642E ::= IE | I/I Expression 643Each terminal symbol is translated into a corresponding mathml node.*/ 644 645var AMpreviousSymbol,AMcurrentSymbol; 646 647function AMparseSexpr(str) { //parses str and returns [node,tailstr,(node)tag] 648 var symbol, node, result, result2, i, st,// rightvert = false, 649 newFrag = document.createDocumentFragment(); 650 str = AMremoveCharsAndBlanks(str,0); 651 symbol = AMgetSymbol(str); //either a token or a bracket or empty 652 if (symbol == null || symbol.ttype == RIGHTBRACKET) 653 return [null,str,null]; 654 if (symbol.ttype == DEFINITION) { 655 str = symbol.output+AMremoveCharsAndBlanks(str,symbol.input.length); 656 symbol = AMgetSymbol(str); 657 if (symbol == null || symbol.ttype == RIGHTBRACKET) 658 return [null,str,null]; 659 } 660 str = AMremoveCharsAndBlanks(str,symbol.input.length); 661 switch (symbol.ttype) { 662 case SPACE: 663 node = AMcreateElementMathML(symbol.tag); 664 node.setAttribute(symbol.atname,symbol.atval); 665 return [node,str,symbol.tag]; 666 case UNDEROVER: 667 if (isIE) { 668 if (symbol.input.substr(0,4) == "\\big") { // botch for missing symbols 669 str = "\\"+symbol.input.substr(4)+str; // make \bigcup = \cup etc. 670 symbol = AMgetSymbol(str); 671 symbol.ttype = UNDEROVER; 672 str = AMremoveCharsAndBlanks(str,symbol.input.length); 673 } 674 } 675 return [AMcreateMmlNode(symbol.tag, 676 document.createTextNode(symbol.output)),str,symbol.tag]; 677 case CONST: 678 var output = symbol.output; 679 if (isIE) { 680 if (symbol.input == "'") 681 output = "\u2032"; 682 else if (symbol.input == "''") 683 output = "\u2033"; 684 else if (symbol.input == "'''") 685 output = "\u2033\u2032"; 686 else if (symbol.input == "''''") 687 output = "\u2033\u2033"; 688 else if (symbol.input == "\\square") 689 output = "\u25A1"; // same as \Box 690 else if (symbol.input.substr(0,5) == "\\frac") { 691 // botch for missing fractions 692 var denom = symbol.input.substr(6,1); 693 if (denom == "5" || denom == "6") { 694 str = symbol.input.replace(/\\frac/,"\\frac ")+str; 695 return [node,str,symbol.tag]; 696 } 697 } 698 } 699 node = AMcreateMmlNode(symbol.tag,document.createTextNode(output)); 700 return [node,str,symbol.tag]; 701 case LONG: // added by DRW 702 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 703 node.setAttribute("minsize","1.5"); 704 node.setAttribute("maxsize","1.5"); 705 node = AMcreateMmlNode("mover",node); 706 node.appendChild(AMcreateElementMathML("mspace")); 707 return [node,str,symbol.tag]; 708 case STRETCHY: // added by DRW 709 if (isIE && symbol.input == "\\backslash") 710 symbol.output = "\\"; // doesn't expand, but then nor does "\u2216" 711 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 712 if (symbol.input == "|" || symbol.input == "\\vert" || 713 symbol.input == "\\|" || symbol.input == "\\Vert") { 714 node.setAttribute("lspace","0em"); 715 node.setAttribute("rspace","0em"); 716 } 717 node.setAttribute("maxsize",symbol.atval); // don't allow to stretch here 718 if (symbol.rtag != null) 719 return [node,str,symbol.rtag]; 720 else 721 return [node,str,symbol.tag]; 722 case BIG: // added by DRW 723 var atval = symbol.atval; 724 if (isIE) 725 atval = symbol.ieval; 726 symbol = AMgetSymbol(str); 727 if (symbol == null) 728 return [null,str,null]; 729 str = AMremoveCharsAndBlanks(str,symbol.input.length); 730 node = AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)); 731 if (isIE) { // to get brackets to expand 732 var space = AMcreateElementMathML("mspace"); 733 space.setAttribute("height",atval+"ex");
734 node = AMcreateMmlNode("mrow",node); 735 node.appendChild(space); 736 } else { // ignored in IE 737 node.setAttribute("minsize",atval); 738 node.setAttribute("maxsize",atval); 739 } 740 return [node,str,symbol.tag]; 741 case LEFTBRACKET: //read (expr+) 742 if (symbol.input == "\\left") { // left what? 743 symbol = AMgetSymbol(str); 744 if (symbol != null) { 745 if (symbol.input == ".") 746 symbol.invisible = true; 747 str = AMremoveCharsAndBlanks(str,symbol.input.length); 748 } 749 } 750 result = AMparseExpr(str,true,false); 751 if (symbol==null || 752 (typeof symbol.invisible == "boolean" && symbol.invisible)) 753 node = AMcreateMmlNode("mrow",result[0]); 754 else { 755 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 756 node = AMcreateMmlNode("mrow",node); 757 node.appendChild(result[0]); 758 } 759 return [node,result[1],result[2]]; 760 case MATRIX: //read (expr+) 761 if (symbol.input == "\\begin{array}") { 762 var mask = ""; 763 symbol = AMgetSymbol(str); 764 str = AMremoveCharsAndBlanks(str,0); 765 if (symbol == null) 766 mask = "l"; 767 else { 768 str = AMremoveCharsAndBlanks(str,symbol.input.length); 769 if (symbol.input != "{") 770 mask = "l"; 771 else do { 772 symbol = AMgetSymbol(str); 773 if (symbol != null) { 774 str = AMremoveCharsAndBlanks(str,symbol.input.length); 775 if (symbol.input != "}") 776 mask = mask+symbol.input; 777 } 778 } while (symbol != null && symbol.input != "" && symbol.input != "}"); 779 } 780 result = AMparseExpr("{"+str,true,true); 781// if (result[0]==null) return [AMcreateMmlNode("mo", 782// document.createTextNode(symbol.input)),str]; 783 node = AMcreateMmlNode("mtable",result[0]); 784 mask = mask.replace(/l/g,"left "); 785 mask = mask.replace(/r/g,"right "); 786 mask = mask.replace(/c/g,"center "); 787 node.setAttribute("columnalign",mask); 788 node.setAttribute("displaystyle","false"); 789 if (isIE) 790 return [node,result[1],null]; 791// trying to get a *little* bit of space around the array 792// (IE already includes it) 793 var lspace = AMcreateElementMathML("mspace"); 794 lspace.setAttribute("width","0.167em"); 795 var rspace = AMcreateElementMathML("mspace"); 796 rspace.setAttribute("width","0.167em"); 797 var node1 = AMcreateMmlNode("mrow",lspace); 798 node1.appendChild(node); 799 node1.appendChild(rspace); 800 return [node1,result[1],null]; 801 } else { // eqnarray 802 result = AMparseExpr("{"+str,true,true); 803 node = AMcreateMmlNode("mtable",result[0]); 804 if (isIE) 805 node.setAttribute("columnspacing","0.25em"); // best in practice? 806 else 807 node.setAttribute("columnspacing","0.167em"); // correct (but ignored?) 808 node.setAttribute("columnalign","right center left"); 809 node.setAttribute("displaystyle","true"); 810 node = AMcreateMmlNode("mrow",node); 811 return [node,result[1],null]; 812 } 813 case TEXT: 814 if (str.charAt(0)=="{") i=str.indexOf("}"); 815 else i = 0; 816 if (i==-1) 817 i = str.length; 818 st = str.slice(1,i); 819 if (st.charAt(0) == " ") { 820 node = AMcreateElementMathML("mspace"); 821 node.setAttribute("width","0.33em"); // was 1ex 822 newFrag.appendChild(node); 823 } 824 newFrag.appendChild( 825 AMcreateMmlNode(symbol.tag,document.createTextNode(st))); 826 if (st.charAt(st.length-1) == " ") { 827 node = AMcreateElementMathML("mspace"); 828 node.setAttribute("width","0.33em"); // was 1ex 829 newFrag.appendChild(node); 830 } 831 str = AMremoveCharsAndBlanks(str,i+1); 832 return [AMcreateMmlNode("mrow",newFrag),str,null]; 833 case UNARY: 834 result = AMparseSexpr(str); 835 if (result[0]==null) return [AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str]; 836 if (typeof symbol.func == "boolean" && symbol.func) { // functions hack 837 st = str.charAt(0); 838// if (st=="^" || st=="_" || st=="/" || st=="|" || st==",") { 839 if (st=="^" || st=="_" || st==",") { 840 return [AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)),str,symbol.tag]; 841 } else { 842 node = AMcreateMmlNode("mrow",AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output))); 843 if (isIE) { 844 var space = AMcreateElementMathML("mspace"); 845 space.setAttribute("width","0.167em"); 846 node.appendChild(space); 847 } 848 node.appendChild(result[0]); 849 return [node,result[1],symbol.tag]; 850 } 851 } 852 if (symbol.input == "\\sqrt") { // sqrt 853 if (isIE) { // set minsize, for \surd 854 var space = AMcreateElementMathML("mspace"); 855 space.setAttribute("height","1.2ex"); 856 space.setAttribute("width","0em"); // probably no effect 857 node = AMcreateMmlNode(symbol.tag,result[0]) 858// node.setAttribute("minsize","1"); // ignored
859// node = AMcreateMmlNode("mrow",node); // hopefully unnecessary 860 node.appendChild(space); 861 return [node,result[1],symbol.tag]; 862 } else 863 return [AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag]; 864 } else if (typeof symbol.acc == "boolean" && symbol.acc) { // accent 865 node = AMcreateMmlNode(symbol.tag,result[0]); 866 var output = symbol.output; 867 if (isIE) { 868 if (symbol.input == "\\hat") 869 output = "\u0302"; 870 else if (symbol.input == "\\widehat") 871 output = "\u005E"; 872 else if (symbol.input == "\\bar") 873 output = "\u00AF"; 874 else if (symbol.input == "\\grave") 875 output = "\u0300"; 876 else if (symbol.input == "\\tilde") 877 output = "\u0303"; 878 } 879 var node1 = AMcreateMmlNode("mo",document.createTextNode(output)); 880 if (symbol.input == "\\vec" || symbol.input == "\\check") 881 // don't allow to stretch 882 node1.setAttribute("maxsize","1.2"); 883 // why doesn't "1" work? \vec nearly disappears in firefox 884 if (isIE && symbol.input == "\\bar") 885 node1.setAttribute("maxsize","0.5"); 886 if (symbol.input == "\\underbrace" || symbol.input == "\\underline") 887 node1.setAttribute("accentunder","true"); 888 else 889 node1.setAttribute("accent","true"); 890 node.appendChild(node1); 891 if (symbol.input == "\\overbrace" || symbol.input == "\\underbrace") 892 node.ttype = UNDEROVER; 893 return [node,result[1],symbol.tag]; 894 } else if (symbol.input == "\\not") { // not 895 // added by infinity0 on 2009-12-15 to implement \not command 896 text = result[0].childNodes[0].nodeValue; 897 if (typeof text == "string" && text.length == 1 && text in AMRelationNegations) { 898 result[0].childNodes[0].nodeValue = AMRelationNegations[text]; 899 return [AMcreateMmlNode(symbol.tag,result[0]),result[1],symbol.tag]; 900 } 901 return [AMcreateMmlNode("mo",document.createTextNode("\\")),"not " + str,symbol.tag]; 902 } else { // font change or displaystyle command 903 if (!isIE && typeof symbol.codes != "undefined") { 904 for (i=0; i<result[0].childNodes.length; i++) 905 if (result[0].childNodes[i].nodeName=="mi" || result[0].nodeName=="mi") { 906 st = (result[0].nodeName=="mi"?result[0].firstChild.nodeValue: 907 result[0].childNodes[i].firstChild.nodeValue); 908 var newst = []; 909 for (var j=0; j<st.length; j++) 910 if (st.charCodeAt(j)>64 && st.charCodeAt(j)<91) 911 { newst = newst + symbol.codes[st.charCodeAt(j)-65] } 912 // String.fromCharCode(symbol.internal[st.charCodeAt(j)-65]); alert(newst); } 913 else newst = newst + st.charAt(j); 914 if (result[0].nodeName=="mi") 915 result[0]=AMcreateElementMathML("mo"). 916 appendChild(document.createTextNode(newst)); 917 else result[0].replaceChild(AMcreateElementMathML("mo"). 918 appendChild(document.createTextNode(newst)),result[0].childNodes[i]); 919 } 920 } 921 node = AMcreateMmlNode(symbol.tag,result[0]); 922 node.setAttribute(symbol.atname,symbol.atval); 923 if (symbol.input == "\\scriptstyle" || 924 symbol.input == "\\scriptscriptstyle") 925 node.setAttribute("displaystyle","false"); 926 return [node,result[1],symbol.tag]; 927 } 928 case BINARY: 929 result = AMparseSexpr(str); 930 if (result[0]==null) return [AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null]; 931 result2 = AMparseSexpr(result[1]); 932 if (result2[0]==null) return [AMcreateMmlNode("mo",document.createTextNode(symbol.input)),str,null]; 933 //added by J. Knisley to allow \textcolor and \colorbox within equations 934 if (symbol.input=="\\textcolor" || symbol.input=="\\colorbox") { 935 var tclr = str.match(/\{\s*([#\w]+)\s*\}/); //get's color from beginning of str 936 str = str.replace(/\{\s*[#\w]+\s*\}/,""); 937 if(tclr!=null) { 938 if(IsColorName.test(tclr[1].toLowerCase())) { 939 tclr=LaTeXColor[tclr[1].toLowerCase()]; 940 } else { 941 tclr=tclr[1]; // no checking for valid color!! 942 } 943 node = AMcreateElementMathML("mstyle"); 944 node.setAttribute(symbol.atval,tclr); 945 node.appendChild(result2[0]); 946 return [node,result2[1],symbol.tag]; 947 } 948 }
949 if (symbol.input=="\\root" || symbol.input=="\\stackrel") newFrag.appendChild(result2[0]); 950 newFrag.appendChild(result[0]); 951 if (symbol.input=="\\frac") newFrag.appendChild(result2[0]); 952 return [AMcreateMmlNode(symbol.tag,newFrag),result2[1],symbol.tag]; 953 case INFIX: 954 str = AMremoveCharsAndBlanks(str,symbol.input.length); 955 return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)), 956 str,symbol.tag]; 957 default: 958 return [AMcreateMmlNode(symbol.tag, //its a constant 959 document.createTextNode(symbol.output)),str,symbol.tag]; 960 } 961} 962 963function AMparseIexpr(str) { 964 var symbol, sym1, sym2, node, result, tag, underover; 965 str = AMremoveCharsAndBlanks(str,0); 966 sym1 = AMgetSymbol(str); 967 result = AMparseSexpr(str); 968 node = result[0]; 969 str = result[1]; 970 tag = result[2]; 971 symbol = AMgetSymbol(str); 972 if (symbol.ttype == INFIX) { 973 str = AMremoveCharsAndBlanks(str,symbol.input.length); 974 result = AMparseSexpr(str); 975 if (result[0] == null) // show box in place of missing argument 976 result[0] = AMcreateMmlNode("mo",document.createTextNode("\u25A1")); 977 str = result[1]; 978 tag = result[2]; 979 if (symbol.input == "_" || symbol.input == "^") { 980 sym2 = AMgetSymbol(str); 981 tag = null; // no space between x^2 and a following sin, cos, etc. 982// This is for \underbrace and \overbrace 983 underover = ((sym1.ttype == UNDEROVER) || (node.ttype == UNDEROVER)); 984// underover = (sym1.ttype == UNDEROVER); 985 if (symbol.input == "_" && sym2.input == "^") { 986 str = AMremoveCharsAndBlanks(str,sym2.input.length); 987 var res2 = AMparseSexpr(str); 988 str = res2[1]; 989 tag = res2[2]; // leave space between x_1^2 and a following sin etc. 990 node = AMcreateMmlNode((underover?"munderover":"msubsup"),node); 991 node.appendChild(result[0]); 992 node.appendChild(res2[0]); 993 } else if (symbol.input == "_") { 994 node = AMcreateMmlNode((underover?"munder":"msub"),node); 995 node.appendChild(result[0]); 996 } else { 997 node = AMcreateMmlNode((underover?"mover":"msup"),node); 998 node.appendChild(result[0]); 999 } 1000 node = AMcreateMmlNode("mrow",node); // so sum does not stretch 1001 } else { 1002 node = AMcreateMmlNode(symbol.tag,node); 1003 if (symbol.input == "\\atop" || symbol.input == "\\choose") 1004 node.setAttribute("linethickness","0ex"); 1005 node.appendChild(result[0]); 1006 if (symbol.input == "\\choose") 1007 node = AMcreateMmlNode("mfenced",node); 1008 } 1009 } 1010 return [node,str,tag]; 1011} 1012 1013function AMparseExpr(str,rightbracket,matrix) { 1014 var symbol, node, result, i, tag, 1015 newFrag = document.createDocumentFragment(); 1016 do { 1017 str = AMremoveCharsAndBlanks(str,0); 1018 result = AMparseIexpr(str); 1019 node = result[0]; 1020 str = result[1]; 1021 tag = result[2]; 1022 symbol = AMgetSymbol(str); 1023 if (node!=undefined) { 1024 if ((tag == "mn" || tag == "mi") && symbol!=null && 1025 typeof symbol.func == "boolean" && symbol.func) { 1026 // Add space before \sin in 2\sin x or x\sin x 1027 var space = AMcreateElementMathML("mspace"); 1028 space.setAttribute("width","0.167em"); 1029 node = AMcreateMmlNode("mrow",node); 1030 node.appendChild(space); 1031 } 1032 newFrag.appendChild(node); 1033 } 1034 } while ((symbol.ttype != RIGHTBRACKET) 1035 && symbol!=null && symbol.output!=""); 1036 tag = null; 1037 if (symbol.ttype == RIGHTBRACKET) { 1038 if (symbol.input == "\\right") { // right what? 1039 str = AMremoveCharsAndBlanks(str,symbol.input.length); 1040 symbol = AMgetSymbol(str); 1041 if (symbol != null && symbol.input == ".") 1042 symbol.invisible = true; 1043 if (symbol != null) 1044 tag = symbol.rtag; 1045 } 1046 if (symbol!=null) 1047 str = AMremoveCharsAndBlanks(str,symbol.input.length); // ready to return 1048 var len = newFrag.childNodes.length; 1049 if (matrix && 1050 len>0 && newFrag.childNodes[len-1].nodeName == "mrow" && len>1 && 1051 newFrag.childNodes[len-2].nodeName == "mo" && 1052 newFrag.childNodes[len-2].firstChild.nodeValue == "&") { //matrix 1053 var pos = []; // positions of ampersands 1054 var m = newFrag.childNodes.length; 1055 for (i=0; matrix && i<m; i=i+2) { 1056 pos[i] = []; 1057 node = newFrag.childNodes[i]; 1058 for (var j=0; j<node.childNodes.length; j++) 1059 if (node.childNodes[j].firstChild.nodeValue=="&") 1060 pos[i][pos[i].length]=j; 1061 } 1062 var row, frag, n, k, table = document.createDocumentFragment(); 1063 for (i=0; i<m; i=i+2) { 1064 row = document.createDocumentFragment(); 1065 frag = document.createDocumentFragment(); 1066 node = newFrag.firstChild; // <mrow> -&-&...&-&- </mrow>
1066 1067 n = node.childNodes.length; 1068 k = 0; 1069 for (j=0; j<n; j++) { 1070 if (typeof pos[i][k] != "undefined" && j==pos[i][k]){ 1071 node.removeChild(node.firstChild); //remove & 1072 row.appendChild(AMcreateMmlNode("mtd",frag)); 1073 k++; 1074 } else frag.appendChild(node.firstChild); 1075 } 1076 row.appendChild(AMcreateMmlNode("mtd",frag)); 1077 if (newFrag.childNodes.length>2) { 1078 newFrag.removeChild(newFrag.firstChild); //remove <mrow> </mrow> 1079 newFrag.removeChild(newFrag.firstChild); //remove <mo>&</mo> 1080 } 1081 table.appendChild(AMcreateMmlNode("mtr",row)); 1082 } 1083 return [table,str]; 1084 } 1085 if (typeof symbol.invisible != "boolean" || !symbol.invisible) { 1086 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output)); 1087 newFrag.appendChild(node); 1088 } 1089 } 1090 return [newFrag,str,tag]; 1091} 1092 1093function AMparseMath(str) { 1094 var result, node = AMcreateElementMathML("mstyle"); 1095 //added by J. Knisley to allow limited implementation of \color 1096 var cclr = str.match(/\\color\s*\{\s*([#\w]+)\s*\}/); 1097 str = str.replace(/\\color\s*\{\s*[#\w]+\s*\}/g,""); 1098 if(cclr!=null) { 1099 if(IsColorName.test(cclr[1].toLowerCase())) { 1100 cclr=LaTeXColor[cclr[1].toLowerCase()]; 1101 } else { 1102 cclr=cclr[1]; // no checking for valid color!! 1103 } 1104 node.setAttribute("mathcolor",cclr); 1105 } else { 1106 if (mathcolor != "") node.setAttribute("mathcolor",mathcolor); 1107 }; 1108 if (mathfontfamily != "") node.setAttribute("fontfamily",mathfontfamily); 1109 node.appendChild(AMparseExpr(str.replace(/^\s+/g,""),false,false)[0]); 1110 node = AMcreateMmlNode("math",node); 1111 if (showasciiformulaonhover) //fixed by djhsu so newline 1112 node.setAttribute("title",str.replace(/\s+/g," "));//does not show in Gecko 1113 if (false ) { //&& mathfontfamily != "" && (isIE || mathfontfamily != "serif")) { 1114 var fnode = AMcreateElementXHTML("font"); 1115 fnode.setAttribute("face",mathfontfamily); 1116 fnode.appendChild(node); 1117 return fnode; 1118 } 1119 return node; 1120} 1121 1122function AMstrarr2docFrag(arr, linebreaks) { 1123 var newFrag=document.createDocumentFragment(); 1124 var expr = false; 1125 for (var i=0; i<arr.length; i++) { 1126 if (expr) newFrag.appendChild(AMparseMath(arr[i])); 1127 else { 1128 var arri = (linebreaks ? arr[i].split("\n\n") : [arr[i]]); 1129 newFrag.appendChild(AMcreateElementXHTML("span"). 1130 appendChild(document.createTextNode(arri[0]))); 1131 for (var j=1; j<arri.length; j++) { 1132 newFrag.appendChild(AMcreateElementXHTML("p")); 1133 newFrag.appendChild(AMcreateElementXHTML("span"). 1134 appendChild(document.createTextNode(arri[j]))); 1135 } 1136 } 1137 expr = !expr; 1138 } 1139 return newFrag; 1140} 1141 1142function AMprocessNodeR(n, linebreaks) { 1143 var mtch, str, arr, frg, i; 1144 if (n.childNodes.length == 0) { 1145 if ((n.nodeType!=8 || linebreaks) && 1146 n.parentNode.nodeName!="form" && n.parentNode.nodeName!="FORM" && 1147 n.parentNode.nodeName!="textarea" && n.parentNode.nodeName!="TEXTAREA" && 1148 n.parentNode.nodeName!="pre" && n.parentNode.nodeName!="PRE") { 1149 str = n.nodeValue; 1150 if (!(str == null)) { 1151 str = str.replace(/\r\n\r\n/g,"\n\n"); 1152 str = str.replace(/\x20+/g," "); 1153 str = str.replace(/\s*\r\n/g," "); 1154// DELIMITERS: 1155 mtch = (str.indexOf("\$")==-1 ? false : true); 1156 str = str.replace(/([^\\])\$/g,"$1 \$"); 1157 str = str.replace(/^\$/," \$"); // in case \$ at start of string 1158 arr = str.split(" \$"); 1159 for (i=0; i<arr.length; i++) 1160 arr[i]=arr[i].replace(/\\\$/g,"\$"); 1161 if (arr.length>1 || mtch) { 1162 if (checkForMathML) { 1163 checkForMathML = false; 1164 var nd = AMisMathMLavailable(); 1165 AMnoMathML = nd != null; 1166 if (AMnoMathML && notifyIfNoMathML) 1167 if (alertIfNoMathML) 1168 alert("To view the ASCIIMathML notation use Internet Explorer 6 +\nMathPlayer (free from www.dessci.com)\n\ 1169 or Firefox/Mozilla/Netscape"); 1170 else AMbody.insertBefore(nd,AMbody.childNodes[0]); 1171 } 1172 if (!AMnoMathML) { 1173 frg = AMstrarr2docFrag(arr,n.nodeType==8); 1174 var len = frg.childNodes.length; 1175 n.parentNode.replaceChild(frg,n); 1176 return len-1; 1177 } else return 0; 1178 } 1179 } 1180 } else return 0; 1181 } else if (n.nodeName!="math") { 1182 for (i=0; i<n.childNodes.length; i++) 1183 i += AMprocessNodeR(n.childNodes[i], linebreaks); 1184 } 1185 return 0; 1186} 1187 1188function AMprocessNode(n, linebreaks, spanclassAM) { 1189 var frag,st;
1190 if (spanclassAM!=null) { 1191 frag = document.getElementsByTagName("span") 1192 for (var i=0;i<frag.length;i++) 1193 if (frag[i].className == "AM") 1194 AMprocessNodeR(frag[i],linebreaks); 1195 } else { 1196 try { 1197 st = n.innerHTML; 1198 } catch(err) {} 1199// DELIMITERS: 1200 if (st==null || st.indexOf("\$")!=-1) 1201 AMprocessNodeR(n,linebreaks); 1202 } 1203 if (isIE) { //needed to match size and font of formula to surrounding text 1204 frag = document.getElementsByTagName('math'); 1205 for (var i=0;i<frag.length;i++) frag[i].update() 1206 } 1207} 1208 1209/* Below is LaTeX pre-processing to produce CSS supported */ 1210/* standard latex structures*/ 1211/* Jeff Knisley ([email protected]) 1212/* Supported in part by the Howard Hughes Medical Institute */ 1213/* as part of the Symbiosis Project: HHMI #52005872 */ 1214 1215var inAppendix = false; 1216var sectionCntr = 0; 1217var IEcommentWarning = true; 1218var biblist = []; 1219var bibcntr = 0; 1220 1221var LaTeXCounter = []; 1222LaTeXCounter["definition"] = 0; 1223LaTeXCounter["proposition"] = 0; 1224LaTeXCounter["lemma"] = 0; 1225LaTeXCounter["theorem"] = 0; 1226LaTeXCounter["corollary"] = 0; 1227LaTeXCounter["example"] = 0; 1228LaTeXCounter["exercise"] = 0; 1229LaTeXCounter["subsection"] = 0; 1230LaTeXCounter["subsubsection"] = 0; 1231LaTeXCounter["figure"] = 0; 1232LaTeXCounter["equation"] = 0; 1233LaTeXCounter["table"] = 0; 1234LaTeXCounter["label"] = 0; 1235 1236var LaTeXColor = []; 1237LaTeXColor["greenyellow"] = "#D9FF4F"; 1238LaTeXColor["yellow"] = "#FFFF00"; 1239LaTeXColor["goldenrod"] = "#FFE529"; 1240LaTeXColor["dandelion"] = "#FFB529"; 1241LaTeXColor["apricot"] = "#FFAD7A"; 1242LaTeXColor["peach"] = "#FF804D"; 1243LaTeXColor["melon"] = "#FF8A80"; 1244LaTeXColor["yelloworange"] = "#FF9400"; 1245LaTeXColor["orange"] = "#FF6321"; 1246LaTeXColor["burntorange"] = "#FF7D00"; 1247LaTeXColor["bittersweet"] = "#C20300"; 1248LaTeXColor["redorange"] = "#FF3B21"; 1249LaTeXColor["mahogany"] = "#A60000"; 1250LaTeXColor["maroon"] = "#AD0000"; 1251LaTeXColor["brickred"] = "#B80000"; 1252LaTeXColor["red"] = "#FF0000"; 1253LaTeXColor["orangered"] = "#FF0080"; 1254LaTeXColor["rubinered"] = "#FF00DE"; 1255LaTeXColor["wildstrawberry"] = "#FF0A9C"; 1256LaTeXColor["salmon"] = "#FF789E"; 1257LaTeXColor["carnationpink"] = "#FF5EFF"; 1258LaTeXColor["magenta"] = "#FF00FF"; 1259LaTeXColor["violetred"] = "#FF30FF"; 1260LaTeXColor["rhodamine"] = "#FF2EFF"; 1261LaTeXColor["mulberry"] = "#A314FA"; 1262LaTeXColor["redviolet"] = "#9600A8"; 1263LaTeXColor["fuchsia"] = "#7303EB"; 1264LaTeXColor["lavender"] = "#FF85FF"; 1265LaTeXColor["thistle"] = "#E069FF"; 1266LaTeXColor["orchid"] = "#AD5CFF"; 1267LaTeXColor["darkorchid"] = "#9933CC"; 1268LaTeXColor["purple"] = "#8C24FF"; 1269LaTeXColor["plum"] = "#8000FF"; 1270LaTeXColor["violet"] = "#361FFF"; 1271LaTeXColor["royalpurple"] = "#401AFF"; 1272LaTeXColor["blueviolet"] = "#1A0DF5"; 1273LaTeXColor["periwinkle"] = "#6E73FF"; 1274LaTeXColor["cadetblue"] = "#616EC4"; 1275LaTeXColor["cornflowerblue"] = "#59DEFF"; 1276LaTeXColor["midnightblue"] = "#007091"; 1277LaTeXColor["navyblue"] = "#0F75FF"; 1278LaTeXColor["royalblue"] = "#0080FF"; 1279LaTeXColor["blue"] = "#0000FF"; 1280LaTeXColor["cerulean"] = "#0FE3FF"; 1281LaTeXColor["cyan"] = "#00FFFF"; 1282LaTeXColor["processblue"] = "#0AFFFF"; 1283LaTeXColor["skyblue"] = "#61FFE0"; 1284LaTeXColor["turquoise"] = "#26FFCC"; 1285LaTeXColor["tealblue"] = "#1FFAA3"; 1286LaTeXColor["aquamarine"] = "#2EFFB2"; 1287LaTeXColor["bluegreen"] = "#26FFAB"; 1288LaTeXColor["emerald"] = "#00FF80"; 1289LaTeXColor["junglegreen"] = "#03FF7A"; 1290LaTeXColor["seagreen"] = "#4FFF80"; 1291LaTeXColor["green"] = "#00FF00"; 1292LaTeXColor["forestgreen"] = "#00E000"; 1293LaTeXColor["pinegreen"] = "#00BF29"; 1294LaTeXColor["limegreen"] = "#80FF00"; 1295LaTeXColor["yellowgreen"] = "#8FFF42"; 1296LaTeXColor["springgreen"] = "#BDFF3D"; 1297LaTeXColor["olivegreen"] = "#009900"; 1298LaTeXColor["rawsienna"] = "#8C0000"; 1299LaTeXColor["sepia"] = "#4D0000"; 1300LaTeXColor["brown"] = "#660000"; 1301LaTeXColor["tan"] = "#DB9470"; 1302LaTeXColor["gray"] = "#808080"; 1303LaTeXColor["grey"] = "#808080"; 1304LaTeXColor["black"] = "#000000"; 1305LaTeXColor["white"] = "#FFFFFF"; 1306 1307var IsColorName = /^(?:greenyellow|yellow|goldenrod|dandelion|apricot|peach|melon|yelloworange|orange|burntorange|bittersweet|redorange|mahogany|maroon|brickred|red|orangered|rubinered|wildstrawberry|salmon|carnationpink|magenta|violetred|rhodamine|mulberry|redviolet|fuchsia|lavender|thistle|orchid|darkorchid|purple|plum|violet|royalpurple|blueviolet|periwinkle|cadetblue|cornflowerblue|midnightblue|navyblue|royalblue|blue|cerulean|cyan|processblue|skyblue|turquoise|tealblue|aquamarine|bluegreen|emerald|junglegreen|seagreen|green|forestgreen|pinegreen|limegreen|yellowgreen|springgreen|olivegreen|rawsienna|sepia|brown|tan|gray|grey|black|white)$/; 1308var IsCounter = /^(?:definition|proposition|lemma|theorem|corollary|example|exercise|subsection|subsubsection|figure|equation|table)$/ ; 1309var IsLaTeXElement = /^(?:displayequation|title|author|address|date|abstract|keyword|section|subsection|subsubsection|ref|cite|thebibliography|definition|proposition|lemma|theorem|corollary|example|exercise|itemize|enumerate|enddefinition|endproposition|endlemma|endtheorem|endcorollary|endexample|endexercise|enditemize|endenumerate|LaTeXMathMLlabel|LaTeXMathML|smallskip|medskip|bigskip|quote|quotation|endquote|endquotation|center|endcenter|description|enddescription|inlinemath)$/; 1310var IsTextOnlyArea = /^(?:form|textarea|pre)$/i; 1311var tableid = 0; 1312 1313function makeNumberString(cntr) { 1314 if(sectionCntr > 0) { 1315 if(inAppendix) { 1316 return "A"+sectionCntr+"."+cntr; 1317 } else { 1318 return sectionCntr+"."+cntr; 1319 } 1320 } else { 1321 return ""+cntr; 1322 } 1323}; 1324 1325 1326function LaTeXpreProcess(thebody) { 1327 var TheBody = thebody; 1328 if(TheBody.hasChildNodes()) { 1329 if(!(IsLaTeXElement.test(TheBody.className))) 1330 { 1331 for(var i=0; i<TheBody.childNodes.length; i++) { 1332 LaTeXpreProcess(TheBody.childNodes[i]) } 1333 } 1334 } 1335 else { 1336 if( TheBody.nodeType==3 && 1337 !(IsTextOnlyArea.test(TheBody.parentNode.nodeName) ) ) 1338 { 1339 var str = TheBody.nodeValue;
1340 if( !(str==null)) { 1341 1342 str = str.replace(/\\%/g, "<per>"); // % sign 1343 str = str.replace(/%[^\n]*(?=\n)/g,""); 1344 str = str.replace(/%[^\r]*(?=\r)/g,""); //Used by Explorer 1345 str = str.replace(/%[^\n]*$/,"") // End of text segment comment 1346 1347 if(isIE && str.match(/%/g) != null && IEcommentWarning) { 1348 alert("Comments may not have parsed properly. Try putting in <pre class='LaTeX><div>..</div></pre> structure."); 1349 IEcommentWarning = false; 1350 } 1351 str = str.replace(/<per>/g,"%"); 1352 1353 //if(str.match(/XXX[\s\S]*/)!=null) { 1354 // var tmp = str.match(/XXX[\s\S]*/)[0]; 1355 // var tmpstr = tmp.charCodeAt(7)+"::"+tmp.charCodeAt(8)+"::"+tmp.charCodeAt(9)+"::"+tmp.charCodeAt(10)+"::"+tmp.charCodeAt(11)+"::"+tmp.charCodeAt(12)+"::"+tmp.charCodeAt(13); 1356 // alert(tmpstr); 1357 //} 1358 1359 //spacing that in LaTeXMathML may cause problems because of our approach. We use purely unicode 1360 // First we remove singleton / symbols 1361 str = str.replace(/([^\\])\\(\s)/g,"$1\u00A0$2"); // must be a space after \ for it to make an nbsp 1362 1363 str = str.replace(/\\quad/g,"\u2001"); 1364 str = str.replace(/\\qquad/g,"\u2001\u2001"); 1365 str = str.replace(/\\enspace/g,"\u2002"); 1366 str = str.replace(/\\;/g,"\u2004"); 1367 str = str.replace(/\\:/g,"\u2005"); 1368 str = str.replace(/\\,/g,"\u2006"); 1369 str = str.replace(/\\thinspace/g,"\u200A"); 1370 str = str.replace(/([^\\])~/g,"$1\u00A0"); 1371 str = str.replace(/\\~/g,"~"); 1372 1373 //Added \[ ... \] and $$..$$ functionality. 1374 str = str.replace(/\\\[/g," <DEQ> $\\displaystyle{"); 1375 str = str.replace(/\\\]/g,"}$ <DEQ> "); 1376 str = str.replace(/\$\$/g,"${$<DEQ>$}$"); 1377 1378 // Separate replacements for begin .. end to (eventually) allow LaTeX equations with html internal mixed in 1379 // (as is the case for theorem, etc. 1380 // all variations of spaces with \begin{array} .. \end{array} -- not displayed, however 1381 str = str.replace(/\\begin\s*\{\s*array\s*\}/g,"\\begin{array}"); 1382 str = str.replace(/\\end\s*\{\s*array\s*\}/g,"\\end{array}"); 1383 1384 // all variations of spaces with \begin{eqnarray} .. \end{eqnarray} 1385 str = str.replace(/\\begin\s*\{\s*eqnarray\s*\}/g," <DEQ>eqno$\\begin{eqnarray}"); 1386 str = str.replace(/\\end\s*\{\s*eqnarray\s*\}/g,"\\end{eqnarray}$<DEQ> "); 1387 1388 // all variations of spaces with \begin{eqnarray*} .. \end{eqnarray*} 1389 str = str.replace(/\\begin\s*\{\s*eqnarray\*\s*\}/g," <DEQ>$\\begin{eqnarray}"); 1390 str = str.replace(/\\end\s*\{\s*eqnarray\*\s*\}/g,"\\end{eqnarray}$<DEQ> "); 1391 1392 // all variations of spaces with \begin{displaymath} .. \end{displaymath} 1393 str = str.replace(/\\begin\s*\{\s*displaymath\s*\}/g," <DEQ> $\\displaystyle{"); 1394 str = str.replace(/\\end\s*\{\s*displaymath\s*\}/g,"}$ <DEQ> "); 1395 1396 // all variations of spaces with \begin{equation*} .. \end{equation*} 1397 str = str.replace(/\\begin\s*\{\s*equation\s*\*\s*\}/g," <DEQ> $\\displaystyle{"); 1398 str = str.replace(/\\end\s*\{\s*equation\s*\*\s*\}/g,"}$ <DEQ> "); 1399 1400 // all variations of spaces with \begin{equation} .. \end{equation} 1401 str = str.replace(/\\begin\s*\{\s*equation\s*\}/g," <DEQ>eqno$\\displaystyle{"); 1402 str = str.replace(/\\end\s*\{\s*equation\s*\}/g,"}$ <DEQ> "); 1403 1404 1405 1406 //now parse to translate <DEQ> structures to <table class = 'dispeq'> stuff 1407 //and to identify non-display math content (sections, etc). 1408 1409 str = str.split("<DEQ>"); 1410 // var ntype = TheBody.nodeType; 1411 var newFrag = document.createDocumentFragment(); 1412 1413 for(var i=0;i<str.length;i++) { 1414 if(i % 2) { 1415 //odd = table of type displayequation 1416 var DEQtable = document.createElement("table"); 1417 DEQtable.className='displayequation'; 1418 var DEQtbody = document.createElement("tbody"); 1419 1420 var DEQtr = document.createElement("tr"); 1421 var DEQtdeq = document.createElement("td"); 1422 DEQtdeq.className='eq'; 1423 1424 // AfterFix to repair for $$...$$ 1425 str[i] = str[i].replace(/\$\}\$/g,"$\\displaystyle{"); 1426 str[i] = str[i].replace(/\$\{\$/g,"}"); 1427 1428 //check for equation number via either label or eqno at beginning -- \nonumber is removed 1429 var lbl = str[i].match(/\\label\s*\{\s*(\w+)\s*\}/); 1430 var ISeqno = str[i].match(/^eqno/); 1431 1432 // append nodes into row 1433 str[i] = str[i].replace(/^eqno/," "); 1434 str[i] = str[i].replace(/\\label\s*\{\s*\w+\s*\}/," "); 1435 DEQtdeq.appendChild(document.createTextNode( str[i] ) ); 1436 DEQtr.appendChild(DEQtdeq); 1437 1438 str[i] = str[i].replace(/\\nonumber/g,""); 1439 1440 if(ISeqno!=null || lbl !=null) { 1441 var DEQtdno = document.createElement("td"); 1442 DEQtdno.className='eqno'; 1443 LaTeXCounter["equation"]++; 1444 var eqnoString = makeNumberString(LaTeXCounter["equation"]); 1445 1446 var DEQanchor = document.createElement("a"); 1447 if(lbl!=null) { DEQanchor.id = lbl[1] }; 1448 DEQanchor.className = "eqno"; 1449 var anchorSpan = document.createElement("span"); 1450 anchorSpan.className = "eqno"; 1451 anchorSpan.style.display = "none"; 1452 anchorSpan.appendChild(document.createTextNode(eqnoString));
1453 DEQanchor.appendChild(anchorSpan); 1454 DEQtdno.appendChild(DEQanchor); 1455 var DEQspan = document.createElement("span"); 1456 DEQspan.className = "eqno"; 1457 DEQspan.appendChild(document.createTextNode("("+eqnoString+")" )); 1458 DEQtdno.appendChild(DEQspan); 1459 DEQtr.appendChild(DEQtdno); 1460 } 1461 DEQtbody.appendChild(DEQtr); 1462 DEQtable.appendChild(DEQtbody); 1463 newFrag.appendChild(DEQtable); 1464 } 1465 else { 1466 //even = this is text, where we may have sections, labels, subsections, and so on 1467 1468 // AfterFix to repair for $$...$$ 1469 str[i] = str[i].replace(/\$\}\$/g,""); 1470 str[i] = str[i].replace(/\$\{\$/g,""); 1471 1472 //Some stuff we just want to remove 1473 str[i] = str[i].replace(/\\maketitle/g,""); 1474 str[i] = str[i].replace(/\\begin\s*\{\s*document\s*\}/g,""); 1475 str[i] = str[i].replace(/\\end\s*\{\s*document\s*\}/g,""); 1476 str[i] = str[i].replace(/\\documentclass[^\}]*?\}/g,""); 1477 str[i] = str[i].replace(/\\usepackage[^\}]*?\}/g,""); //ignores packages and their options 1478 str[i] = str[i].replace(/\\noindent/g,""); 1479 str[i] = str[i].replace(/\\notag/g,""); 1480 1481 //Next: labels, ref's, hrefs, urls, and cites 1482 str[i] = str[i].replace(/\\ref\s*\{\s*(\w+)\}/g," \\[ref\\]$1\\[ "); 1483 str[i] = str[i].replace (/\\url\s*\{\s*([^\}\n]+)\}/g," \\[url\\]$1\\[ "); 1484 str[i] = str[i].replace(/\\href\s*\{\s*([^\}]+)\}\s*\{\s*([^\}]+)\}/g," \\[href\\]$1\\]$2\\[ "); 1485 str[i] = str[i].replace(/\\cite\s*\{\s*(\w+)\}/g," \\[cite\\]$1\\[ "); 1486 1487 //Miscellaneous stuff!! 1488 str[i] = str[i].replace(/\\qed/g,"\u220E"); 1489 str[i] = str[i].replace(/\\endproof/g,"\u220E"); 1490 str[i] = str[i].replace(/\\proof/g,"\\textbf{Proof: }"); 1491 1492 //breaks and skips 1493 str[i] = str[i].replace(/\\n(?=\s)/g, " \\[br\\] \\[ "); 1494 str[i] = str[i].replace(/\\newline/g," \\[br\\] \\[ "); 1495 str[i] = str[i].replace(/\\linebreak/g," \\[br\\] \\[ "); 1496 str[i] = str[i].replace(/\\smallskip/g," \\[logicalbreak\\]smallskip\\[ "); 1497 str[i] = str[i].replace(/\\medskip/g," \\[logicalbreak\\]medskip\\[ "); 1498 str[i] = str[i].replace(/\\bigskip/g," \\[logicalbreak\\]bigskip\\[ "); 1499 str[i] = str[i].replace(/[\n\r]+[ \f\n\r\t\v\u2028\u2029]*[\n\r]+/g," \\[logicalbreak\\]LaTeXMathML\\[ "); // extra return replaced by <p> 1500 if(isIE) { 1501 str[i] = str[i].replace(/\r/g," "); // replace \r by a space to aid spacing! 1502 } 1503 1504 1505 //items and appendix 1506 str[i] = str[i].replace(/\\bibitem\s*([^\{]*\{\s*\w*\s*\})/g," \\[bibitem\\]$1\\[ "); 1507 str[i] = str[i].replace(/\\bibitem\s*/g," \\[bibitem\\] \\[ "); 1508 str[i] = str[i].replace(/\\item\s*\[\s*(\w+)\s*\]/g," \\[alistitem\\]$1\\[ "); 1509 str[i] = str[i].replace(/\\item\s*/g," \\[alistitem\\] \\[ "); 1510 str[i] = str[i].replace(/\\appendix/g," \\[appendix\\] \\[ "); 1511 1512 1513 // \includegraphics[][]{image} -- no processing of options. This treatment is DANGEROUS. It assumes no html will be 1514 // placed within the \begin{figure} ... \end{figure} structure, and the [\s\S] character class could lead to strange matches 1515 str[i] = str[i].replace(/\\begin\s*\{\s*figure\s*\}([\s\S]+?)\\end\s*\{\s*figure\s*\}/g," \\[figure\\]$1\\[ "); 1516 str[i] = str[i].replace(/\\begin\s*\{\s*table\s*\}([\s\S]+?)\\end\s*\{\s*table\s*\}/g," \\[table\\]$1\\[ "); 1517 //str[i] = str[i].replace(/\\begin\s*\{\s*array\s*\}([\s\S]+?)\\end\s*\{\s*array\s*\}/g," \\[array\\]$1\\[ "); 1518 //goal is to protect array \\ from being converted into linebreaks 1519 1520 //This construction allows css classes for divs for these elements, but the CSS will have to be supplied through a 1521 //css file or <script>
1521 .. </script> in the header. (It makes sense to me that style files in LaTeX should correspond 1522 //to css and/or xslt when translating to mathml, but \ref's are a problem). 1523 str[i] = str[i].replace(/\\begin\s*\{\s*theorem\s*\}/g," \\[theorem\\]Theorem \\[ "); 1524 str[i] = str[i].replace(/\\end\s*\{\s*theorem\s*\}/g," \\[endtheorem\\] \\[ "); 1525 1526 str[i] = str[i].replace(/\\begin\s*\{\s*definition\s*\}/g," \\[definition\\]Definition \\[ "); 1527 str[i] = str[i].replace(/\\end\s*\{\s*definition\s*\}/g," \\[enddefinition\\] \\[ "); 1528 1529 str[i] = str[i].replace(/\\begin\s*\{\s*lemma\s*\}/g," \\[lemma\\]Lemma \\[ "); 1530 str[i] = str[i].replace(/\\end\s*\{\s*lemma\s*\}/g," \\[endlemma\\] \\[ "); 1531 1532 str[i] = str[i].replace(/\\begin\s*\{\s*corollary\s*\}/g," \\[corollary\\]Corollary \\[ "); 1533 str[i] = str[i].replace(/\\end\s*\{\s*corollary\s*\}/g," \\[endcorollary\\] \\[ "); 1534 1535 str[i] = str[i].replace(/\\begin\s*\{\s*proposition\s*\}/g," \\[proposition\\]Proposition \\[ "); 1536 str[i] = str[i].replace(/\\end\s*\{\s*proposition\s*\}/g," \\[endproposition\\] \\[ "); 1537 1538 str[i] = str[i].replace(/\\begin\s*\{\s*example\s*\}/g," \\[example\\]Example \\[ "); 1539 str[i] = str[i].replace(/\\end\s*\{\s*example\s*\}/g," \\[endexample\\] \\[ "); 1540 1541 str[i] = str[i].replace(/\\begin\s*\{\s*exercise\s*\}/g," \\[exercise\\]Exercise \\[ "); 1542 str[i] = str[i].replace(/\\end\s*\{\s*exercise\s*\}/g," \\[endexercise\\] \\[ "); 1543 1544 str[i] = str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}\s*\{\s*\w+\s*\}/g," \\[thebibliography\\]References \\[ "); 1545 str[i] = str[i].replace(/\\begin\s*\{\s*thebibliography\s*\}/g," \\[thebibliography\\]References \\[ "); 1546 str[i] = str[i].replace(/\\end\s*\{\s*thebibliography\s*\}/g," \\[endthebibliography\\]References \\[ "); 1547 1548 1549 str[i] = str[i].replace(/\\begin\s*\{\s*proof\s*\}/g," \\[proof\\]Proof: \\[ "); 1550 if(isIE) { //IE is just so weird 1551 str[i] = str[i].replace(/\\end\s*\{\s*proof\s*\}/g,"\u220E \\[endproof\\] \\[ "); 1552 } else { 1553 str[i] = str[i].replace(/\\end\s*\{\s*proof\s*\}/g," \\[endproof\\] \\[ "); 1554 } 1555 1556 //The frontmatter -- all translated to div's to be handled by CSS 1557 str[i] = str[i].replace(/\\title\s*\{\s*([^\}]+)\}/g," \\[title\\] \\[$1 \\[endtitle\\] \\[ "); 1558 str[i] = str[i].replace(/\\author\s*\{\s*([^\}]+)\}/g," \\[author\\] \\[$1 \\[endauthor\\] \\[ "); 1559 str[i] = str[i].replace(/\\address\s*\{\s*([^\}]+)\}/g," \\[address\\] \\[$1 \\[endaddress\\] \\[ "); 1560 str[i] = str[i].replace(/\\date\s*\{\s*([^\}]+)\}/g," \\[date\\] \\[$1 \\[enddate\\] \\[ "); 1561 str[i] = str[i].replace(/\\begin\s*\{\s*keyword\s*\}/g," \\[keyword\\] \\[ "); 1562 str[i] = str[i].replace(/\\end\s*\{\s*keyword\s*\}/g," \\[endkeyword\\] \\[ "); 1563 str[i] = str[i].replace(/\\begin\s*\{\s*abstract\s*\}/g," \\[abstract\\] \\[ "); 1564 str[i] = str[i].replace(/\\end\s*\{\s*abstract\s*\}/g," \\[endabstract\\] \\[ "); 1565 1566 //The rest of the environments -- Users can even "make up their own" -- but it avoids the array and tabular environments 1567 str[i] = str[i].replace(/\\begin\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[$1\\] \\[ "); 1568 str[i] = str[i].replace(/\\end\s*\{\s*(?!array|tabular)(\w+)\s*\}/g," \\[end$1\\] \\[ "); 1569 1570 //Next, we look at section--subsection stuff. This is nested -- this would be so much better if LaTeX used 1571 //some type of \begin{sectionhead}...\end{sectionhead} structure 1572 var sectionIndex = str[i].search(/\\section\s*\{\s*[\s\S]+\}/); 1573 1574 while(sectionIndex >= 0) { 1575 str[i] = str[i].replace(/\\section\s*\{/ ," \\[section\\]"); 1576 var delimcnt = 1; 1577 for(var ii=sectionIndex;ii<str[i].length;ii++) { 1578 if(str[i].charAt(ii) == "{") { delimcnt++ }; 1579 if(str[i].charAt(ii) == "}") { delimcnt-- }; 1580 if(delimcnt == 0) { 1581 str[i] = str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length) ; 1582 break; 1583 } 1584 }; 1585 sectionIndex = str[i].search(/\\section\s*\{\s*[\s\S]+\}/); //look for next 1586 } 1587 1588 sectionIndex = str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/); 1589 1590 while(sectionIndex >= 0) { 1591 str[i] = str[i].replace(/\\subsection\s*\{/ ," \\[subsection\\]"); 1592 var delimcnt = 1; 1593 for(var ii=sectionIndex;ii<str[i].length;ii++) { 1594 if(str[i].charAt(ii) == "{") { delimcnt++ }; 1595 if(str[i].charAt(ii) == "}") { delimcnt-- }; 1596 if(delimcnt == 0) { 1597 str[i] = str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length) ; 1598 break; 1599 } 1600 }; 1601 sectionIndex = str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/); //look for next 1602 } 1603 1604 sectionIndex = str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/); 1605 1606 while(sectionIndex >= 0) { 1607 str[i] = str[i].replace(/\\subsubsection\s*\{/ ," \\[subsubsection\\]"); 1608 var delimcnt = 1; 1609 for(var ii=sectionIndex;ii<str[i].length;ii++) { 1610 if(str[i].charAt(ii) == "{") { delimcnt++ }; 1611 if(str[i].charAt(ii) == "}") { delimcnt-- }; 1612 if(delimcnt == 0) { 1613 str[i] = str[i].substring(0,ii)+"\\[ "+str[i].substring(ii+1,str[i].length) ; 1614 break; 1615 } 1616 }; 1617 sectionIndex = str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/); //look for next 1618 } 1619 1620 var CatToNextEven = ""; 1621 //split into alternating text elements and "marked" elements 1622 var strtmp = str[i].split("\\["); 1623 //document.write(strtmp[0]); 1624 1625 for(var j=0;j<strtmp.length;j++) { 1626 if(j % 2) { 1627 //odd = split on \\] 1628 var strtmparray = strtmp[j].split("\\]"); 1629 switch (strtmparray[0]) { 1630 case "section": 1631 var nodeTmp = document.createElement("H2"); 1632 nodeTmp.className = 'section'; 1633 //reset counters 1634 sectionCntr++; 1635 for (var div in LaTeXCounter) { LaTeXCounter[div] = 0 }; 1636 //Create Title of section 1637 var nodeAnchor = document.createElement("a"); 1638 if(inAppendix) { 1639 nodeAnchor.className='appendixsection'; 1640 } else { 1641 nodeAnchor.className='section'; 1642 } 1643 var nodeNumString = makeNumberString(""); 1644 var anchorSpan = document.createElement("span"); 1645 anchorSpan.className = "section"; 1646 anchorSpan.style.display = "none"; 1647 anchorSpan.appendChild(document.createTextNode(nodeNumString)); 1648 nodeAnchor.appendChild(anchorSpan); 1649 nodeTmp.appendChild(nodeAnchor); 1650 1651 var nodeSpan = document.createElement("span"); 1652 nodeSpan.className = 'section'; 1653 nodeSpan.appendChild(document.createTextNode(nodeNumString+" ")); 1654 nodeTmp.appendChild(nodeSpan); 1655 nodeTmp.appendChild(document.createTextNode( strtmparray[1] ) ); 1656 newFrag.appendChild(nodeTmp); 1657 break; 1658 case "subsection": 1659 var nodeTmp = document.createElement("H3"); 1660 nodeTmp.className = 'subsection'; 1661 //counters 1662 LaTeXCounter["subsection"]++; 1663 LaTeXCounter["subsubsection"]=0; 1664 //Create Title of section 1665 var nodeAnchor = document.createElement("a"); 1666 nodeAnchor.className = 'subsection'; 1667 var nodeNumString = makeNumberString(LaTeXCounter["subsection"]); 1668 var anchorSpan = document.createElement("span"); 1669 anchorSpan.className = "subsection"; 1670 anchorSpan.style.display = "none"; 1671 anchorSpan.appendChild(document.createTextNode(nodeNumString)); 1672 nodeAnchor.appendChild(anchorSpan); 1673 nodeTmp.appendChild(nodeAnchor); 1674 var nodeSpan = document.createElement("span"); 1675 nodeSpan.className = 'subsection'; 1676 nodeSpan.appendChild(document.createTextNode(nodeNumString+". ")); 1677 nodeTmp.appendChild(nodeSpan); 1678 nodeTmp.appendChild(document.createTextNode( strtmparray[1] ) ); 1679 newFrag.appendChild(nodeTmp); 1680 break; 1681 case "subsubsection": 1682 var nodeTmp = document.createElement("H4"); 1683 nodeTmp.className = 'subsubsection'; 1684 //counters 1685 LaTeXCounter["subsubsection"]++; 1686 //Create Title of section 1687 var nodeAnchor = document.createElement("a"); 1688 nodeAnchor.className = 'subsubsection'; 1689 var nodeNumString = makeNumberString(LaTeXCounter["subsection"]+"."+LaTeXCounter["subsubsection"]); 1690 var anchorSpan = document.createElement("span"); 1691 anchorSpan.className = "subsubsection"; 1692 anchorSpan.style.display = "none"; 1693 anchorSpan.appendChild(document.createTextNode(nodeNumString)); 1694 nodeAnchor.appendChild(anchorSpan); 1695 nodeTmp.appendChild(nodeAnchor); 1696 var nodeSpan = document.createElement("span"); 1697 nodeSpan.className = 'subsubsection'; 1698 nodeSpan.appendChild(document.createTextNode(nodeNumString+". ")); 1699 nodeTmp.appendChild(nodeSpan); 1700 nodeTmp.appendChild(document.createTextNode( strtmparray[1] ) ); 1701 newFrag.appendChild(nodeTmp); 1702 break; 1703 case "href": 1704 var nodeTmp = document.createElement("a"); 1705 nodeTmp.className = 'LaTeXMathML'; 1706 nodeTmp.href = strtmparray[1]; 1707 nodeTmp.appendChild(document.createTextNode( strtmparray[2])); 1708 newFrag.appendChild(nodeTmp); 1709 break; 1710 case "url": 1711 var nodeTmp = document.createElement("a"); 1712 nodeTmp.className = 'LaTeXMathML'; 1713 nodeTmp.href = strtmparray[1]; 1714 nodeTmp.appendChild(document.createTextNode( strtmparray[1])); 1715 newFrag.appendChild(nodeTmp); 1716 break; 1717 case "figure": 1718 var nodeTmp = document.createElement("table"); 1719 nodeTmp.className = 'figure'; 1720 var FIGtbody = document.createElement("tbody"); 1721 1722 var FIGlbl = strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/); 1723 strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,""); 1724 1725 var capIndex = strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/); 1726 var FIGcap = ""; 1727 1728 if(capIndex >= 0) { // caption may contain other { } structures -- but not displaymath!! 1729 var tmp = strtmparray[1]; 1730 var delimcnt = 0; 1731 var capstart = -1; 1732 for(var pos=capIndex;pos<tmp.length;pos++) { 1733 if(tmp.charAt(pos) == "{") { delimcnt++ }; 1734 if(tmp.charAt(pos) == "}") { delimcnt-- }; 1735 if(delimcnt == 1 && capstart<0) { capstart = pos+1 }; 1736 if(delimcnt == 0 && capstart>0) { 1737 capend = pos-1; 1738 FIGcap = tmp.substring(capstart,pos); 1739 break 1740 } 1741 } 1742 } 1743 1744 var FIGtr2 = document.createElement("tr"); 1745 var FIGtd2 = document.createElement("td");
1746 FIGtd2.className="caption"; 1747 1748 1749 var FIGanchor = document.createElement("a"); 1750 FIGanchor.className = "figure"; 1751 if(FIGlbl!=null) { FIGanchor.id = FIGlbl[1]; } 1752 LaTeXCounter["figure"]++; 1753 var fignmbr = makeNumberString(LaTeXCounter["figure"]); 1754 var anchorSpan = document.createElement("span"); 1755 anchorSpan.className = "figure"; 1756 anchorSpan.style.display = "none"; 1757 anchorSpan.appendChild(document.createTextNode(fignmbr)); 1758 FIGanchor.appendChild(anchorSpan); 1759 FIGtd2.appendChild(FIGanchor); 1760 1761 var FIGspan = document.createElement("span"); 1762 FIGspan.className = "figure"; //For CSS counters, comment this line 1763 FIGspan.appendChild(document.createTextNode("Figure "+fignmbr+". " ) ); 1764 FIGtd2.appendChild(FIGspan); 1765 FIGtd2.appendChild(document.createTextNode(""+FIGcap)); 1766 FIGtr2.appendChild(FIGtd2); 1767 FIGtbody.appendChild(FIGtr2); 1768 var IsSpecial = false;
1769 1770 var FIGinfo = strtmparray[1].match(/\\includegraphics\s*\{([^\}]+)\}/); 1771 if(FIGinfo==null) { //options not processed, for now 1772 FIGinfo = strtmparray[1].match(/\\includegraphics\s*\[[^\]]*\]\s*\{\s*([^\}]+)\s*\}/); 1773 } 1774 if(FIGinfo==null) { 1775 FIGinfo = strtmparray[1].match(/\\special\s*\{\s*([^\}]+)\}/); 1776 IsSpecial=true //Hook: Later can include "special" graphics commands 1777 }; 1778 1779 if(FIGinfo!=null) { //Caption will be above the image 1780 var FIGtr1 = document.createElement("tr"); 1781 var FIGtd1 = document.createElement("td"); 1782 FIGtd1.className="image"; 1783 var FIGimg = document.createElement("img"); 1784 var FIGsrc = FIGinfo[1]; //options not processed, for now 1785 FIGimg.src = FIGsrc; 1786 FIGimg.alt = "Figure "+FIGsrc+" did not load"; 1787 FIGimg.title = "Figure "+fignmbr+". "+FIGcap; 1788 FIGimg.id = "figure"+fignmbr; 1789 FIGtd1.appendChild(FIGimg); 1790 FIGtr1.appendChild(FIGtd1); 1791 FIGtbody.appendChild(FIGtr1); 1792 } 1793 nodeTmp.appendChild(FIGtbody); 1794 newFrag.appendChild(nodeTmp); 1795 break; 1796 case "table": 1797 var nodeTmp = document.createElement("table"); 1798 if(strtmparray[1].search(/\\centering/) >= 0) { 1799 nodeTmp.className = 'LaTeXtable centered'; 1800 nodeTmp.align = "center"; 1801 } else { 1802 nodeTmp.className = 'LaTeXtable'; 1803 }; 1804 tableid++; 1805 nodeTmp.id = "LaTeXtable"+tableid; //unique id for each table 1806 1807 var TABlbl = strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/); 1808 strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,""); 1809 1810 var capIndex = strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/); 1811 var TABcap = ""; 1812 1813 if(capIndex >= 0) { // caption may contain other { } structures -- but not displaymath!! 1814 var tmp = strtmparray[1]; 1815 var delimcnt = 0; 1816 var capstart = -1; 1817 for(var pos=capIndex;pos<tmp.length;pos++) { 1818 if(tmp.charAt(pos) == "{") { delimcnt++ }; 1819 if(tmp.charAt(pos) == "}") { delimcnt-- }; 1820 if(delimcnt == 1 && capstart<0) { capstart = pos+1 }; 1821 if(delimcnt == 0 && capstart>0) { 1822 capend = pos-1; 1823 TABcap = tmp.substring(capstart,pos); 1824 break 1825 } 1826 } 1827 } 1828 1829 if(TABcap!="") { 1830 var TABtbody = document.createElement("tbody"); 1831 var TABcaption = document.createElement("caption"); 1832 TABcaption.className="LaTeXtable centered"; 1833 var TABanchor = document.createElement("a"); 1834 TABanchor.className = "LaTeXtable"; 1835 if(TABlbl!=null) { TABanchor.id = TABlbl[1]; } 1836 LaTeXCounter["table"]++; 1837 var tabnmbr = makeNumberString(LaTeXCounter["table"]); 1838 var anchorSpan = document.createElement("span"); 1839 anchorSpan.className = "LaTeXtable"; 1840 anchorSpan.style.display = "none"; 1841 anchorSpan.appendChild(document.createTextNode(tabnmbr));
1842 TABanchor.appendChild(anchorSpan); 1843 TABcaption.appendChild(TABanchor); 1844 1845 var TABspan = document.createElement("span"); 1846 TABspan.className = "LaTeXtable"; //For CSS counters, comment this line 1847 TABspan.appendChild(document.createTextNode("Table "+tabnmbr+". " ) ); 1848 TABcaption.appendChild(TABspan); 1849 TABcaption.appendChild(document.createTextNode(""+TABcap)); 1850 nodeTmp.appendChild(TABcaption); 1851 } 1852 var TABinfo = strtmparray[1].match(/\\begin\s*\{\s*tabular\s*\}([\s\S]+)\\end\s*\{\s*tabular\s*\}/); 1853 if(TABinfo!=null) { 1854 var TABtbody = document.createElement('tbody'); 1855 var TABrow = null; 1856 var TABcell = null; 1857 var row=0; 1858 var col=0; 1859 1860 var TABalign = TABinfo[1].match(/^\s*\{([^\}]+)\}/); 1861 TABinfo = TABinfo[1].replace(/^\s*\{[^\}]+\}/,""); 1862 TABinfo = TABinfo.replace(/\\hline/g,""); //no horizontal bars 1863 TABalign[1] = TABalign[1].replace(/\|/g,""); //no vertical bars 1864 TABalign[1] = TABalign[1].replace(/\s/g,""); 1865 TABinfo = TABinfo.split("\\\\"); // into rows 1866 for(row=0;row<TABinfo.length;row++) { 1867 TABrow = document.createElement("tr"); 1868 TABinfo[row] = TABinfo[row].split("&"); 1869 for(col=0;col<TABinfo[row].length;col++) { 1870 TABcell = document.createElement("td"); 1871 switch (TABalign[1].charAt(col)) { 1872 case "l": 1873 TABcell.style.textAlign = "left"; 1874 break; 1875 case "c": 1876 TABcell.style.textAlign = "center"; 1877 break; 1878 case "r": 1879 TABcell.style.textAlign = "right"; 1880 break; 1881 default : 1882 TABcell.style.textAlign = "left"; 1883 }; 1884 TABcell.appendChild(document.createTextNode(TABinfo[row][col])); 1885 TABrow.appendChild(TABcell); 1886 } 1887 TABtbody.appendChild(TABrow); 1888 } 1889 nodeTmp.appendChild(TABtbody); 1890 } 1891 newFrag.appendChild(nodeTmp); 1892 break; 1893 case "logicalbreak": 1894 var nodeTmp = document.createElement("p"); 1895 nodeTmp.className = strtmparray[1]; 1896 nodeTmp.appendChild(document.createTextNode("\u00A0")); 1897 newFrag.appendChild(nodeTmp); 1898 break; 1899 case "appendix": 1900 inAppendix=true; 1901 sectionCntr=0; 1902 break; 1903 case "alistitem": 1904 var EndDiv = document.createElement("div"); 1905 EndDiv.className = "endlistitem"; 1906 newFrag.appendChild(EndDiv); 1907 var BegDiv = document.createElement("div"); 1908 BegDiv.className = "listitem"; 1909 if(strtmparray[1]!=" ") { 1910 var BegSpan = document.createElement("span"); 1911 BegSpan.className="listitemmarker"; 1912 var boldBegSpan = document.createElement("b"); 1913 boldBegSpan.appendChild(document.createTextNode(strtmparray[1]+" ")); 1914 BegSpan.appendChild(boldBegSpan); 1915 BegDiv.appendChild(BegSpan); 1916 } 1917 newFrag.appendChild(BegDiv); 1918 break; 1919 case "br": 1920 newFrag.appendChild(document.createElement("br")); 1921 break; 1922 case "bibitem": 1923 newFrag.appendChild(document.createElement("br")); 1924 var nodeTmp = document.createElement("a"); 1925 nodeTmp.className = 'bibitem'; 1926 var nodeSpan = document.createElement("span"); 1927 nodeSpan.className = 'bibitem'; 1928 1929 bibcntr++; 1930 1931 var lbl = strtmparray[1].match(/\{\s*(\w+)\s*\}/); 1932 strtmparray[1] = strtmparray[1].replace(/\s*\{\s*\w+\s*\}/g,""); 1933 strtmparray[1] = strtmparray[1].replace(/^\s*\[/,""); 1934 strtmparray[1] = strtmparray[1].replace(/\s*\]$/,""); 1935 strtmparray[1] = strtmparray[1].replace(/^\s+|\s+$/g,""); 1936 //We create a list of id's for the bibitems -- it seemed important at one time?? 1937 if(lbl==null) {
1938 biblist[bibcntr] = "bibitem"+bibcntr 1939 } else { 1940 biblist[bibcntr] = lbl[1]; 1941 }; 1942 nodeTmp.name = biblist[bibcntr]; 1943 nodeTmp.id = biblist[bibcntr]; 1944 // We place content into <a> -- access it with \cite, thus allowing appropriate labels! 1945 if(strtmparray[1]!="") { 1946 nodeSpan.appendChild(document.createTextNode(strtmparray[1])); 1947 } else { 1948 nodeSpan.appendChild(document.createTextNode("["+bibcntr+"]")); 1949 } 1950 nodeTmp.appendChild(nodeSpan); 1951 newFrag.appendChild(nodeTmp); 1952 break; 1953 case "cite": 1954 var nodeTmp = document.createElement("a"); 1955 nodeTmp.className = 'cite'; 1956 nodeTmp.name = 'cite'; 1957 nodeTmp.href = "#"+strtmparray[1]; 1958 newFrag.appendChild(nodeTmp); 1959 break; 1960 case "ref": 1961 var nodeTmp = document.createElement("a"); 1962 nodeTmp.className = 'ref'; 1963 nodeTmp.name = 'ref'; 1964 nodeTmp.href = "#"+strtmparray[1]; 1965 newFrag.appendChild(nodeTmp); 1966 break; 1967 default : 1968 var nodeTmp = document.createElement("div"); 1969 nodeTmp.className = strtmparray[0]; 1970 if( IsCounter.test(strtmparray[0]) ) { 1971 LaTeXCounter[strtmparray[0]]++; 1972 var nodeAnchor = document.createElement("a"); 1973 nodeAnchor.className = strtmparray[0]; 1974 var divnum = makeNumberString(LaTeXCounter[strtmparray[0]]); 1975 var anchorSpan = document.createElement("span"); 1976 anchorSpan.className = strtmparray[0]; 1977 anchorSpan.appendChild(document.createTextNode(divnum)); 1978 anchorSpan.style.display="none"; 1979 nodeAnchor.appendChild(anchorSpan); 1980 nodeTmp.appendChild(nodeAnchor); 1981 1982 var nodeSpan = document.createElement("span"); 1983 nodeSpan.className = strtmparray[0]; 1984 nodeSpan.appendChild(document.createTextNode(strtmparray[1]+" "+divnum+". ")); 1985 nodeTmp.appendChild(nodeSpan); 1986 } 1987 if(isIE) { //remove if IE supports :before and :after 1988 if(strtmparray[0]==("thebibliography"||"abstract"||"keyword"||"proof")) { 1989 var nodeSpan = document.createElement("span"); 1990 nodeSpan.className = strtmparray[0]; 1991 nodeSpan.appendChild(document.createTextNode(strtmparray[1])); 1992 nodeTmp.appendChild(nodeSpan); 1993 } 1994 } //end of IE :before and :after fixes 1995 if(strtmparray[0]=="endenumerate" || strtmparray[0]=="enditemize" || strtmparray[0]=="enddescription") { 1996 var endDiv = document.createElement("div"); 1997 endDiv.className = "endlistitem"; 1998 newFrag.appendChild(endDiv); 1999 } 2000 newFrag.appendChild(nodeTmp); 2001 if(strtmparray[0]=="enumerate" || strtmparray[0]=="itemize" || strtmparray[0]=="description") { 2002 var endDiv = document.createElement("div"); 2003 endDiv.className = "listitem"; 2004 newFrag.appendChild(endDiv); 2005 } 2006 } 2007 } else { 2008 //even = text, labels, bf, and italics, and linebreaks, and math -- we now remove the math 2009 strtmp[j] = strtmp[j].replace(/\\\$/g,"<per>"); 2010 strtmp[j] = strtmp[j].replace(/\$([^\$]+)\$/g," \\[$1\\[ "); 2011 strtmp[j] = strtmp[j].replace(/<per>/g,"\\$"); 2012 strtmp[j] = strtmp[j].replace(/\\begin\s*\{\s*math\s*\}([\s\S]+?)\\end\s*\{\s*math\s*\}/g," \\[$1\\[ "); 2013 2014 var strtmptmp = strtmp[j].split("\\["); 2015 2016 for(var jjj=0;jjj<strtmptmp.length;jjj++) { 2017 if(jjj % 2) { //odd = math 2018 var nodeTmp = document.createElement("span"); 2019 nodeTmp.className = 'inlinemath'; 2020 nodeTmp.appendChild(document.createTextNode("$"+strtmptmp[jjj]+"$")); 2021 newFrag.appendChild(nodeTmp); 2022 } else { 2023 //all other tags will be mapped to span's (most should be font-face tags) with class-names matching the tag name. 2024 //Exceptions will be textcolor, colorbox, textbf, textit, and emph. These cannot include any html tags. 2025 var TagIndex = strtmptmp[jjj].search(/\\\w+/); 2026 var tmpIndex = TagIndex; 2027 while(tmpIndex>-1) { 2028 if(/^\\textcolor/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))) { 2029 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\textcolor\s*\{\s*(\w+)\s*\}\s*/," \\[textcolor\\]$1\\]|"); 2030 } else { 2031 if(/^\\colorbox/.test(strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length))) { 2032 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\colorbox\s*\{\s*(\w+)\s*\}\s*/," \\[colorbox\\]$1\\]|"); 2033 } else { 2034 strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).replace(/\\\s*(\w+)\s*/," \\[$1\\]|"); 2035 } 2036 } 2037 TagIndex +=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\|/); 2038 TagIndex++; 2039 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\\]\|/,"\\] "); 2040 if(strtmptmp[jjj].charAt(TagIndex) == "{") { 2041 strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length); 2042 var delimcnt = 1; 2043 for(var kk = TagIndex;kk<strtmptmp[jjj].length;kk++) { 2044 if(strtmptmp[jjj].charAt(kk) == "{") { delimcnt++ }; 2045 if(strtmptmp[jjj].charAt(kk) == "}") { delimcnt-- }; 2046 if(delimcnt==0) { break; } 2047 } 2048 strtmptmp[jjj] = strtmptmp[jjj].substring(0,kk)+"\\[ "+strtmptmp[jjj].substring(kk+1,strtmptmp[jjj].length); 2049 TagIndex = kk+3; 2050 } else { 2051 strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+"\\[ "+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length); 2052 TagIndex = TagIndex + 3; 2053 } 2054 if(TagIndex<strtmptmp[jjj].length) { 2055 tmpIndex = strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\\\w+/); 2056 } 2057 else { 2058 tmpIndex = -1 }; 2059 TagIndex += tmpIndex; 2060 } 2061 2062 2063 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\\\\s*\\\\/g,"\\\\"); 2064 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\\\/g," \\[br\\] \\[ "); 2065 strtmptmp[jjj] = strtmptmp[jjj].replace(/\\label\s*\{\s*(\w+)\s*\}/g," \\[label\\]$1\\[ "); 2066 var strlbls = strtmptmp[jjj].split("\\["); 2067 2068 for(var jj=0;jj<strlbls.length;jj++) { 2069 if(jj % 2) { //odd = labels, boldface, and breaks 2070 var strtmparray = strlbls[jj].split("\\]"); 2071 switch(strtmparray[0]) { 2072 case "textcolor": 2073 var nodeTmp = document.createElement("span"); 2074 nodeTmp.className = 'LaTeXColor'; 2075 if(IsColorName.test(strtmparray[1].toLowerCase())) { 2076 nodeTmp.style.color=LaTeXColor[strtmparray[1].toLowerCase()]; 2077 } else { 2078 nodeTmp.style.color=strtmparray[1]; 2079 }; 2080 nodeTmp.appendChild(document.createTextNode(strtmparray[2])); 2081 newFrag.appendChild(nodeTmp); 2082 break; 2083 case "colorbox": 2084 var nodeTmp = document.createElement("span"); 2085 nodeTmp.className = 'LaTeXColor'; 2086 if(IsColorName.test(strtmparray[1].toLowerCase())) { 2087 nodeTmp.style.background=LaTeXColor[strtmparray[1].toLowerCase()]; 2088 } else { 2089 nodeTmp.style.background=strtmparray[1]; 2090 }; 2091 nodeTmp.appendChild(document.createTextNode(strtmparray[2])); 2092 newFrag.appendChild(nodeTmp); 2093 break; 2094 case "br": 2095 newFrag.appendChild(document.createElement("br")); 2096 break; 2097 case "label" : 2098 var nodeTmp = document.createElement("a"); 2099 nodeTmp.className = 'LaTeXMathMLlabel'; 2100 var lblid = strtmparray[1].match(/\s*(\w+)\s*/); 2101 if(lblid != null) { nodeTmp.id = lblid[1] }; 2102 nodeTmp.style.display = "none"; 2103 2104 LaTeXCounter['label']++; 2105 var lblnum = makeNumberString(LaTeXCounter['label']); 2106 2107 var anchorSpan = document.createElement("span"); 2108 anchorSpan.className = 'LaTeXMathMLlabel'; 2109 anchorSpan.appendChild(document.createTextNode(lblnum)); 2110 anchorSpan.style.display="none"; 2111 nodeTmp.appendChild(anchorSpan); 2112 newFrag.appendChild(nodeTmp); 2113 break; 2114 default : 2115 var nodeTmp = document.createElement("span"); 2116 nodeTmp.className = strtmparray[0]; 2117 nodeTmp.appendChild(document.createTextNode(strtmparray[1])) 2118 newFrag.appendChild(nodeTmp); 2119 } 2120 } else { 2121 newFrag.appendChild(document.createTextNode(strlbls[jj])); 2122 } 2123 } 2124 } 2125 } 2126 } // end else for even splits of strtmp 2127 } 2128 } 2129 }; //else sections and labels 2130 TheBody.parentNode.replaceChild(newFrag,TheBody); 2131 } //str nodevalue is not empty 2132 } 2133 } // split off recursion 2134 return TheBody; 2135} 2136 2137function LaTeXDivsAndRefs(thebody) { 2138 var TheBody = thebody; 2139 2140 var EndDivClass = null; 2141 var AllDivs = TheBody.getElementsByTagName("div"); 2142 var lbl2id = ""; 2143 var lblnode = null; 2144 for(var i=AllDivs.length-1;i>=0;i--) { 2145 EndDivClass = AllDivs[i].className.match(/end\w+/ ); 2146 if(EndDivClass!=null) { 2147 EndDivClass = EndDivClass[0]; 2148 var DivClass = EndDivClass.substring(3,EndDivClass.length); 2149 var EndDivNode = AllDivs[i]; 2150 break; 2151 } 2152 } 2153 while(EndDivClass!=null) { 2154 // TrackBack to Beginning, appending to newfrag as we go 2155 var newFrag = document.createDocumentFragment(); 2156 var RootNode = EndDivNode.parentNode; 2157 var ClassCount = 1; // because of EndDivNode 2158 while(EndDivNode.previousSibling!=null && ClassCount>0) { 2159 switch(EndDivNode.previousSibling.className) {
2160 case EndDivClass: 2161 ClassCount++; 2162 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild); 2163 break; 2164 case DivClass: 2165 if(EndDivNode.previousSibling.nodeName=="DIV") { 2166 ClassCount-- ; 2167 //Must check to see if we need a label here! 2168 if(lbl2id !="" ) { 2169 EndDivNode.previousSibling.id = lbl2id; 2170 lbl2id = "" 2171 } 2172 if(ClassCount==0) { 2173 RootNode = EndDivNode.previousSibling; 2174 } else { 2175 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild); 2176 } 2177 }; 2178 break; 2179 case 'LaTeXMathMLlabel': 2180 lbl2id = EndDivNode.previousSibling.id; 2181 EndDivNode.parentNode.removeChild(EndDivNode.previousSibling); 2182 break; 2183 default: 2184 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild); 2185 } 2186 } 2187 RootNode.appendChild(newFrag); 2188 EndDivNode.parentNode.removeChild(EndDivNode); 2189 2190 //Look for more end div items 2191 AllDivs = TheBody.getElementsByTagName("DIV"); 2192 for(i=AllDivs.length-1;i>=0;i--) { 2193 EndDivClass = AllDivs[i].className.match(/end\w+/ ); 2194 if(EndDivClass!=null) { 2195 ClassCount = 0; 2196 EndDivClass = EndDivClass[0]; 2197 DivClass = EndDivClass.substring(3,EndDivClass.length); 2198 EndDivNode = AllDivs[i]; 2199 RootNode = EndDivNode.parentNode; 2200 break; 2201 } 2202 } 2203 } // end while! 2204 2205 2206 2207 2208 var AllDivs = TheBody.getElementsByTagName("div"); //Convert itemize and enumerate to html lists: 2209 var DIV2LI = null; 2210 2211 for(var i=0;i<AllDivs.length;i++) { 2212 if( AllDivs[i].className=="itemize" || AllDivs[i].className=="enumerate" || AllDivs[i].className=="description") { 2213 if(AllDivs[i].className=="itemize") { 2214 RootNode = document.createElement("UL"); 2215 } else { 2216 RootNode = document.createElement("OL"); 2217 } 2218 RootNode.className = 'LaTeXMathML'; 2219 if(AllDivs[i].hasChildNodes()) { AllDivs[i].removeChild(AllDivs[i].firstChild) }; 2220 while(AllDivs[i].hasChildNodes()) { 2221 if(AllDivs[i].firstChild.hasChildNodes()) { 2222 DIV2LI = document.createElement("LI"); 2223 while(AllDivs[i].firstChild.hasChildNodes()) { 2224 DIV2LI.appendChild(AllDivs[i].firstChild.firstChild); 2225 } 2226 if(DIV2LI.firstChild.className=="listitemmarker") { 2227 DIV2LI.style.listStyleType = "none"; 2228 } 2229 RootNode.appendChild(DIV2LI) 2230 } 2231 AllDivs[i].removeChild(AllDivs[i].firstChild); 2232 } 2233 AllDivs[i].appendChild(RootNode); 2234 } 2235 } 2236 2237 // From here to 'end for AllAnchors is necessary only because CSS3 is not implemented yet. 2238 // Once CSS3 target-text is available, this can be done using CSS 2239 var AllAnchors = TheBody.getElementsByTagName("a"); 2240 for(var i=0;i<AllAnchors.length;i++) { 2241 if(AllAnchors[i].className == "ref" || AllAnchors[i].className == "cite" ) { 2242 var label = AllAnchors[i].href.match(/\#(\w+)/); 2243 if(label!=null) { 2244 var labelNode = document.getElementById(label[1]); 2245 if(labelNode!=null) { 2246 var TheSpans = labelNode.getElementsByTagName("SPAN"); 2247 if(TheSpans!=null) { 2248 var refNode = TheSpans[0].cloneNode(true); 2249 refNode.style.display="inline" 2250 refNode.className = AllAnchors[i].className; 2251 AllAnchors[i].appendChild(refNode); 2252 //break; 2253 } 2254 } 2255 } 2256 } 2257 } // end for AllAnchors 2258 2259 // Eventually: Collapsible Sections 2260 2261 return TheBody; 2262} 2263 2264var AMbody; 2265var AMnoMathML = false, AMtranslated = false; 2266 2267function translate(spanclassAM) { 2268 if (!AMtranslated) { // run this only once 2269 AMtranslated = true; 2270 AMinitSymbols(); 2271 var LaTeXContainers = []; 2272 var AllContainers = document.getElementsByTagName('*'); 2273 var ExtendName = ""; 2274 2275 for (var k = 0,l=0; k < AllContainers.length; k++) { 2276 ExtendName = " "+AllContainers[k].className+" "; 2277 if(ExtendName.match(/\sLaTeX\s/)!=null) { 2278 LaTeXContainers[l] = AllContainers[k]; 2279 l++; 2280 } 2281 }; 2282 if(LaTeXContainers.length>0) { 2283 for(var m=0;m<LaTeXContainers.length;m++) { 2284 AMbody = LaTeXContainers[m]; 2285 try { 2286 AMbody = LaTeXDivsAndRefs(LaTeXpreProcess(AMbody)); // 2287 } catch(err) { 2288 alert("Unknown Error: Defaulting to Original LaTeXMathML"); 2289 } 2290 if(AMbody.tagName=="PRE") { 2291 var PreChilds = document.createDocumentFragment(); 2292 var DivChilds = document.createElement("DIV"); 2293 while(AMbody.hasChildNodes()) { 2294 DivChilds.appendChild(AMbody.firstChild); 2295 } 2296 PreChilds.appendChild(DivChilds); 2297 AMbody.parentNode.replaceChild(PreChilds,AMbody); 2298 AMbody = DivChilds; //Leaves empty pre -- may be useful?? 2299 2300 } 2301 AMprocessNode(AMbody, false, spanclassAM); 2302 } 2303 } else { //Default to entire page 2304 AMbody = document.getElementsByTagName("body")[0]; 2305 try { 2306 AMbody = LaTeXDivsAndRefs(LaTeXpreProcess(AMbody)); // 2307 } catch(err) { 2308 alert("Unknown Error: Defaulting to Original LaTeXMathML"); 2309 } 2310 AMprocessNode(AMbody, false, spanclassAM); 2311 } 2312 } 2313} 2314 2315if (isIE) { 2316 // avoid adding MathPlayer info explicitly to each webpage 2317 document.write("<object id=\"mathplayer\"\ 2318 classid=\"clsid:32F66A20-7614-11D4-BD11-00104BD3F987\"></object>"); 2319 document.write("<?import namespace=\"m\" implementation=\"#mathplayer\"?>"); 2320} 2321 2322// GO1.1 Generic onload by Brothercake 2323// http://www.brothercake.com/ 2324//onload function (replaces the onload="translate()" in the <body> tag) 2325function generic() 2326{ 2327 translate(); 2328}; 2329//setup onload function 2330if(typeof window.addEventListener != 'undefined') 2331{ 2332 //.. gecko, safari, konqueror and standard 2333 window.addEventListener('load', generic, false); 2334} 2335else if(typeof document.addEventListener != 'undefined') 2336{ 2337 //.. opera 7 2338 document.addEventListener('load', generic, false); 2339} 2340else if(typeof window.attachEvent != 'undefined') 2341{ 2342 //.. win/ie 2343 window.attachEvent('onload', generic); 2344} 2345//** remove this condition to degrade older browsers 2346else 2347{ 2348 //.. mac/ie5 and anything else that gets this far 2349 //if there's an existing onload function 2350 if(typeof window.onload == 'function') 2351 { 2352 //store it 2353 var existing = onload; 2354 //add new onload handler 2355 window.onload = function() 2356 { 2357 //call existing onload function 2358 existing(); 2359 //call generic onload function 2360 generic(); 2361 }; 2362 } 2363 else 2364 { 2365 //setup onload function 2366 window.onload = generic; 2367 } 2368}
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.