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