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
16 Here is the header notice from the original file:
\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
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
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
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
44 LaTeXMathML.js (ctd)
\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
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
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
59 var mathcolor = ""; // change it to "" (to inherit) or any other color
\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
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
74 var isIE = document.createElementNS==null;
\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
79 // all further global variables start with "AM"
\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
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
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
100 nd.appendChild(document.createTextNode(" or Netscape/Mozilla/Firefox"));
\r
101 nd.appendChild(AMcreateElementXHTML("p"));
\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
111 var ActiveX = new ActiveXObject("MathPlayer.Factory.1");
\r
114 return AMnoMathMLNote();
\r
116 else return AMnoMathMLNote();
\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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
478 //commands with argument
\r
479 AMsqrt, AMnot, AMroot, AMfrac, AMover, AMsub, AMsup, AMtext, AMmbox, AMatop, AMchoose,
\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
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
533 function compareNames(s1,s2) {
\r
534 if (s1.input > s2.input) return 1
\r
538 var AMnames = []; //list of input symbols
\r
540 function AMinitSymbols() {
\r
541 AMsymbols.sort(compareNames);
\r
542 for (i=0; i<AMsymbols.length; i++) AMnames[i] = AMsymbols[i].input;
\r
545 var AMmathml = "http://www.w3.org/1998/Math/MathML";
\r
547 function AMcreateElementMathML(t) {
\r
548 if (isIE) return document.createElement("m:"+t);
\r
549 else return document.createElementNS(AMmathml,t);
\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
560 function newcommand(oldstr,newstr) {
\r
561 AMsymbols = AMsymbols.concat([{input:oldstr, tag:"mo", output:newstr,
\r
562 ttype:DEFINITION}]);
\r
565 function AMremoveCharsAndBlanks(str,n) {
\r
566 //remove n characters and any following blanks
\r
569 for (var i=0; i<st.length && st.charCodeAt(i)<=32; i=i+1);
\r
570 return st.slice(i);
\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
582 if (arr[m]<str) n = m; else h = m;
\r
586 for (var i=n; i<arr.length && arr[i]<str; i++);
\r
587 return i; // i=arr.length || arr[i]>=str
\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
600 for (var i=1; i<=str.length && more; i++) {
\r
601 st = str.slice(0,i); //initial substring of length i
\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
609 more = k<AMnames.length && str.slice(0,AMnames[k].length)>=AMnames[k];
\r
611 AMpreviousSymbol=AMcurrentSymbol;
\r
613 AMcurrentSymbol=AMsymbols[mk].ttype;
\r
614 return AMsymbols[mk];
\r
616 AMcurrentSymbol=CONST;
\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
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
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
630 return {input:st, tag:tagst, output:st, ttype:CONST};
\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
645 var AMpreviousSymbol,AMcurrentSymbol;
\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
660 str = AMremoveCharsAndBlanks(str,symbol.input.length);
\r
661 switch (symbol.ttype) {
\r
663 node = AMcreateElementMathML(symbol.tag);
\r
664 node.setAttribute(symbol.atname,symbol.atval);
\r
665 return [node,str,symbol.tag];
\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
675 return [AMcreateMmlNode(symbol.tag,
\r
676 document.createTextNode(symbol.output)),str,symbol.tag];
\r
678 var output = symbol.output;
\r
680 if (symbol.input == "'")
\r
682 else if (symbol.input == "''")
\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
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
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
721 return [node,str,symbol.tag];
\r
722 case BIG: // added by DRW
\r
723 var atval = symbol.atval;
\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
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
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
755 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
\r
756 node = AMcreateMmlNode("mrow",node);
\r
757 node.appendChild(result[0]);
\r
759 return [node,result[1],result[2]];
\r
760 case MATRIX: //read (expr+)
\r
761 if (symbol.input == "\\begin{array}") {
\r
763 symbol = AMgetSymbol(str);
\r
764 str = AMremoveCharsAndBlanks(str,0);
\r
765 if (symbol == null)
\r
768 str = AMremoveCharsAndBlanks(str,symbol.input.length);
\r
769 if (symbol.input != "{")
\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
778 } while (symbol != null && symbol.input != "" && symbol.input != "}");
\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
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
805 node.setAttribute("columnspacing","0.25em"); // best in practice?
\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
814 if (str.charAt(0)=="{") i=str.indexOf("}");
\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
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
831 str = AMremoveCharsAndBlanks(str,i+1);
\r
832 return [AMcreateMmlNode("mrow",newFrag),str,null];
\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
842 node = AMcreateMmlNode("mrow",AMcreateMmlNode(symbol.tag,document.createTextNode(symbol.output)));
\r
844 var space = AMcreateElementMathML("mspace");
\r
845 space.setAttribute("width","0.167em");
\r
846 node.appendChild(space);
\r
848 node.appendChild(result[0]);
\r
849 return [node,result[1],symbol.tag];
\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
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
868 if (symbol.input == "\\hat")
\r
870 else if (symbol.input == "\\widehat")
\r
872 else if (symbol.input == "\\bar")
\r
874 else if (symbol.input == "\\grave")
\r
876 else if (symbol.input == "\\tilde")
\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
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
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
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
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
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
938 if(IsColorName.test(tclr[1].toLowerCase())) {
\r
939 tclr=LaTeXColor[tclr[1].toLowerCase()];
\r
941 tclr=tclr[1]; // no checking for valid color!!
\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
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
954 str = AMremoveCharsAndBlanks(str,symbol.input.length);
\r
955 return [AMcreateMmlNode("mo",document.createTextNode(symbol.output)),
\r
958 return [AMcreateMmlNode(symbol.tag, //its a constant
\r
959 document.createTextNode(symbol.output)),str,symbol.tag];
\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
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
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
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
997 node = AMcreateMmlNode((underover?"mover":"msup"),node);
\r
998 node.appendChild(result[0]);
\r
1000 node = AMcreateMmlNode("mrow",node); // so sum does not stretch
\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
1010 return [node,str,tag];
\r
1013 function AMparseExpr(str,rightbracket,matrix) {
\r
1014 var symbol, node, result, i, tag,
\r
1015 newFrag = document.createDocumentFragment();
\r
1017 str = AMremoveCharsAndBlanks(str,0);
\r
1018 result = AMparseIexpr(str);
\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
1032 newFrag.appendChild(node);
\r
1034 } while ((symbol.ttype != RIGHTBRACKET)
\r
1035 && symbol!=null && symbol.output!="");
\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
1047 str = AMremoveCharsAndBlanks(str,symbol.input.length); // ready to return
\r
1048 var len = newFrag.childNodes.length;
\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
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
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
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
1074 } else frag.appendChild(node.firstChild);
\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
1081 table.appendChild(AMcreateMmlNode("mtr",row));
\r
1083 return [table,str];
\r
1085 if (typeof symbol.invisible != "boolean" || !symbol.invisible) {
\r
1086 node = AMcreateMmlNode("mo",document.createTextNode(symbol.output));
\r
1087 newFrag.appendChild(node);
\r
1090 return [newFrag,str,tag];
\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
1099 if(IsColorName.test(cclr[1].toLowerCase())) {
\r
1100 cclr=LaTeXColor[cclr[1].toLowerCase()];
\r
1102 cclr=cclr[1]; // no checking for valid color!!
\r
1104 node.setAttribute("mathcolor",cclr);
\r
1106 if (mathcolor != "") node.setAttribute("mathcolor",mathcolor);
\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
1122 function AMstrarr2docFrag(arr, linebreaks) {
\r
1123 var newFrag=document.createDocumentFragment();
\r
1125 for (var i=0; i<arr.length; i++) {
\r
1126 if (expr) newFrag.appendChild(AMparseMath(arr[i]));
\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
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
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
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
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
1188 function AMprocessNode(n, linebreaks, spanclassAM) {
\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
1200 if (st==null || st.indexOf("\$")!=-1)
\r
1201 AMprocessNodeR(n,linebreaks);
\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
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
1215 var inAppendix = false;
\r
1216 var sectionCntr = 0;
\r
1217 var IEcommentWarning = true;
\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
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
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
1313 function makeNumberString(cntr) {
\r
1314 if(sectionCntr > 0) {
\r
1316 return "A"+sectionCntr+"."+cntr;
\r
1318 return sectionCntr+"."+cntr;
\r
1326 function LaTeXpreProcess(thebody) {
\r
1327 var TheBody = thebody;
\r
1328 if(TheBody.hasChildNodes()) {
\r
1329 if(!(IsLaTeXElement.test(TheBody.className)))
\r
1331 for(var i=0; i<TheBody.childNodes.length; i++) {
\r
1332 LaTeXpreProcess(TheBody.childNodes[i]) }
\r
1336 if( TheBody.nodeType==3 &&
\r
1337 !(IsTextOnlyArea.test(TheBody.parentNode.nodeName) ) )
\r
1339 var str = TheBody.nodeValue;
\r
1340 if( !(str==null)) {
\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
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
1351 str = str.replace(/<per>/g,"%");
\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
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
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
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
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
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
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
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
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
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
1406 //now parse to translate <DEQ> structures to <table class = 'dispeq'> stuff
\r
1407 //and to identify non-display math content (sections, etc).
\r
1409 str = str.split("<DEQ>");
\r
1410 // var ntype = TheBody.nodeType;
\r
1411 var newFrag = document.createDocumentFragment();
\r
1413 for(var i=0;i<str.length;i++) {
\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
1420 var DEQtr = document.createElement("tr");
\r
1421 var DEQtdeq = document.createElement("td");
\r
1422 DEQtdeq.className='eq';
\r
1424 // AfterFix to repair for $$...$$
\r
1425 str[i] = str[i].replace(/\$\}\$/g,"$\\displaystyle{");
\r
1426 str[i] = str[i].replace(/\$\{\$/g,"}");
\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
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
1438 str[i] = str[i].replace(/\\nonumber/g,"");
\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
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
1461 DEQtbody.appendChild(DEQtr);
\r
1462 DEQtable.appendChild(DEQtbody);
\r
1463 newFrag.appendChild(DEQtable);
\r
1466 //even = this is text, where we may have sections, labels, subsections, and so on
\r
1468 // AfterFix to repair for $$...$$
\r
1469 str[i] = str[i].replace(/\$\}\$/g,"");
\r
1470 str[i] = str[i].replace(/\$\{\$/g,"");
\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
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
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
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
1501 str[i] = str[i].replace(/\r/g," "); // replace \r by a space to aid spacing!
\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
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
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
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
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
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
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
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
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
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
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
1553 str[i] = str[i].replace(/\\end\s*\{\s*proof\s*\}/g," \\[endproof\\] \\[ ");
\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
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
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
1574 while(sectionIndex >= 0) {
\r
1575 str[i] = str[i].replace(/\\section\s*\{/ ," \\[section\\]");
\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
1585 sectionIndex = str[i].search(/\\section\s*\{\s*[\s\S]+\}/); //look for next
\r
1588 sectionIndex = str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/);
\r
1590 while(sectionIndex >= 0) {
\r
1591 str[i] = str[i].replace(/\\subsection\s*\{/ ," \\[subsection\\]");
\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
1601 sectionIndex = str[i].search(/\\subsection\s*\{\s*[\s\S]+\}/); //look for next
\r
1604 sectionIndex = str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/);
\r
1606 while(sectionIndex >= 0) {
\r
1607 str[i] = str[i].replace(/\\subsubsection\s*\{/ ," \\[subsubsection\\]");
\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
1617 sectionIndex = str[i].search(/\\subsubsection\s*\{\s*[\s\S]+\}/); //look for next
\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
1625 for(var j=0;j<strtmp.length;j++) {
\r
1627 //odd = split on \\]
\r
1628 var strtmparray = strtmp[j].split("\\]");
\r
1629 switch (strtmparray[0]) {
\r
1631 var nodeTmp = document.createElement("H2");
\r
1632 nodeTmp.className = 'section';
\r
1635 for (var div in LaTeXCounter) { LaTeXCounter[div] = 0 };
\r
1636 //Create Title of section
\r
1637 var nodeAnchor = document.createElement("a");
\r
1639 nodeAnchor.className='appendixsection';
\r
1641 nodeAnchor.className='section';
\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
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
1658 case "subsection":
\r
1659 var nodeTmp = document.createElement("H3");
\r
1660 nodeTmp.className = 'subsection';
\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
1681 case "subsubsection":
\r
1682 var nodeTmp = document.createElement("H4");
\r
1683 nodeTmp.className = 'subsubsection';
\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
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
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
1718 var nodeTmp = document.createElement("table");
\r
1719 nodeTmp.className = 'figure';
\r
1720 var FIGtbody = document.createElement("tbody");
\r
1722 var FIGlbl = strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);
\r
1723 strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");
\r
1725 var capIndex = strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);
\r
1728 if(capIndex >= 0) { // caption may contain other { } structures -- but not displaymath!!
\r
1729 var tmp = strtmparray[1];
\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
1738 FIGcap = tmp.substring(capstart,pos);
\r
1744 var FIGtr2 = document.createElement("tr");
\r
1745 var FIGtd2 = document.createElement("td");
\r
1746 FIGtd2.className="caption";
\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
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
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
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
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
1793 nodeTmp.appendChild(FIGtbody);
\r
1794 newFrag.appendChild(nodeTmp);
\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
1802 nodeTmp.className = 'LaTeXtable';
\r
1805 nodeTmp.id = "LaTeXtable"+tableid; //unique id for each table
\r
1807 var TABlbl = strtmparray[1].match(/\\label\s*\{\s*(\w+)\s*\}/);
\r
1808 strtmparray[1]=strtmparray[1].replace(/\\label\s*\{\w+\}/g,"");
\r
1810 var capIndex = strtmparray[1].search(/\\caption\s*\{[\s\S]+\}/);
\r
1813 if(capIndex >= 0) { // caption may contain other { } structures -- but not displaymath!!
\r
1814 var tmp = strtmparray[1];
\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
1823 TABcap = tmp.substring(capstart,pos);
\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
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
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
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
1873 TABcell.style.textAlign = "left";
\r
1876 TABcell.style.textAlign = "center";
\r
1879 TABcell.style.textAlign = "right";
\r
1882 TABcell.style.textAlign = "left";
\r
1884 TABcell.appendChild(document.createTextNode(TABinfo[row][col]));
\r
1885 TABrow.appendChild(TABcell);
\r
1887 TABtbody.appendChild(TABrow);
\r
1889 nodeTmp.appendChild(TABtbody);
\r
1891 newFrag.appendChild(nodeTmp);
\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
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
1917 newFrag.appendChild(BegDiv);
\r
1920 newFrag.appendChild(document.createElement("br"));
\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
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
1938 biblist[bibcntr] = "bibitem"+bibcntr
\r
1940 biblist[bibcntr] = lbl[1];
\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
1948 nodeSpan.appendChild(document.createTextNode("["+bibcntr+"]"));
\r
1950 nodeTmp.appendChild(nodeSpan);
\r
1951 newFrag.appendChild(nodeTmp);
\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
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
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
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
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
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
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
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
2014 var strtmptmp = strtmp[j].split("\\[");
\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
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
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
2034 strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).replace(/\\\s*(\w+)\s*/," \\[$1\\]|");
\r
2037 TagIndex +=strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\|/);
\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
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
2048 strtmptmp[jjj] = strtmptmp[jjj].substring(0,kk)+"\\[ "+strtmptmp[jjj].substring(kk+1,strtmptmp[jjj].length);
\r
2051 strtmptmp[jjj] = strtmptmp[jjj].substring(0,TagIndex)+"\\[ "+strtmptmp[jjj].substring(TagIndex+1,strtmptmp[jjj].length);
\r
2052 TagIndex = TagIndex + 3;
\r
2054 if(TagIndex<strtmptmp[jjj].length) {
\r
2055 tmpIndex = strtmptmp[jjj].substring(TagIndex,strtmptmp[jjj].length).search(/\\\w+/);
\r
2059 TagIndex += tmpIndex;
\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
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
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
2078 nodeTmp.style.color=strtmparray[1];
\r
2080 nodeTmp.appendChild(document.createTextNode(strtmparray[2]));
\r
2081 newFrag.appendChild(nodeTmp);
\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
2089 nodeTmp.style.background=strtmparray[1];
\r
2091 nodeTmp.appendChild(document.createTextNode(strtmparray[2]));
\r
2092 newFrag.appendChild(nodeTmp);
\r
2095 newFrag.appendChild(document.createElement("br"));
\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
2104 LaTeXCounter['label']++;
\r
2105 var lblnum = makeNumberString(LaTeXCounter['label']);
\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
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
2121 newFrag.appendChild(document.createTextNode(strlbls[jj]));
\r
2126 } // end else for even splits of strtmp
\r
2129 }; //else sections and labels
\r
2130 TheBody.parentNode.replaceChild(newFrag,TheBody);
\r
2131 } //str nodevalue is not empty
\r
2133 } // split off recursion
\r
2137 function LaTeXDivsAndRefs(thebody) {
\r
2138 var TheBody = thebody;
\r
2140 var EndDivClass = null;
\r
2141 var AllDivs = TheBody.getElementsByTagName("div");
\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
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
2162 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
\r
2165 if(EndDivNode.previousSibling.nodeName=="DIV") {
\r
2167 //Must check to see if we need a label here!
\r
2168 if(lbl2id !="" ) {
\r
2169 EndDivNode.previousSibling.id = lbl2id;
\r
2172 if(ClassCount==0) {
\r
2173 RootNode = EndDivNode.previousSibling;
\r
2175 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
\r
2179 case 'LaTeXMathMLlabel':
\r
2180 lbl2id = EndDivNode.previousSibling.id;
\r
2181 EndDivNode.parentNode.removeChild(EndDivNode.previousSibling);
\r
2184 newFrag.insertBefore(EndDivNode.previousSibling,newFrag.firstChild);
\r
2187 RootNode.appendChild(newFrag);
\r
2188 EndDivNode.parentNode.removeChild(EndDivNode);
\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
2196 EndDivClass = EndDivClass[0];
\r
2197 DivClass = EndDivClass.substring(3,EndDivClass.length);
\r
2198 EndDivNode = AllDivs[i];
\r
2199 RootNode = EndDivNode.parentNode;
\r
2208 var AllDivs = TheBody.getElementsByTagName("div"); //Convert itemize and enumerate to html lists:
\r
2209 var DIV2LI = null;
\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
2216 RootNode = document.createElement("OL");
\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
2226 if(DIV2LI.firstChild.className=="listitemmarker") {
\r
2227 DIV2LI.style.listStyleType = "none";
\r
2229 RootNode.appendChild(DIV2LI)
\r
2231 AllDivs[i].removeChild(AllDivs[i].firstChild);
\r
2233 AllDivs[i].appendChild(RootNode);
\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
2257 } // end for AllAnchors
\r
2259 // Eventually: Collapsible Sections
\r
2265 var AMnoMathML = false, AMtranslated = false;
\r
2267 function translate(spanclassAM) {
\r
2268 if (!AMtranslated) { // run this only once
\r
2269 AMtranslated = true;
\r
2271 var LaTeXContainers = [];
\r
2272 var AllContainers = document.getElementsByTagName('*');
\r
2273 var ExtendName = "";
\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
2282 if(LaTeXContainers.length>0) {
\r
2283 for(var m=0;m<LaTeXContainers.length;m++) {
\r
2284 AMbody = LaTeXContainers[m];
\r
2286 AMbody = LaTeXDivsAndRefs(LaTeXpreProcess(AMbody)); //
\r
2288 alert("Unknown Error: Defaulting to Original LaTeXMathML");
\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
2296 PreChilds.appendChild(DivChilds);
\r
2297 AMbody.parentNode.replaceChild(PreChilds,AMbody);
\r
2298 AMbody = DivChilds; //Leaves empty pre -- may be useful??
\r
2301 AMprocessNode(AMbody, false, spanclassAM);
\r
2303 } else { //Default to entire page
\r
2304 AMbody = document.getElementsByTagName("body")[0];
\r
2306 AMbody = LaTeXDivsAndRefs(LaTeXpreProcess(AMbody)); //
\r
2308 alert("Unknown Error: Defaulting to Original LaTeXMathML");
\r
2310 AMprocessNode(AMbody, false, spanclassAM);
\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
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
2329 //setup onload function
\r
2330 if(typeof window.addEventListener != 'undefined')
\r
2332 //.. gecko, safari, konqueror and standard
\r
2333 window.addEventListener('load', generic, false);
\r
2335 else if(typeof document.addEventListener != 'undefined')
\r
2338 document.addEventListener('load', generic, false);
\r
2340 else if(typeof window.attachEvent != 'undefined')
\r
2343 window.attachEvent('onload', generic);
\r
2345 //** remove this condition to degrade older browsers
\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
2353 var existing = onload;
\r
2354 //add new onload handler
\r
2355 window.onload = function()
\r
2357 //call existing onload function
\r
2359 //call generic onload function
\r
2365 //setup onload function
\r
2366 window.onload = generic;
\r