PageRenderTime 55ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/talk2/mathjax/unpacked/jax/input/TeX/jax.js

https://github.com/williamstein/mazur-explicit-formula
JavaScript | 2095 lines | 1812 code | 147 blank | 136 comment | 343 complexity | c24e204f5491d4128de12342506cce71 MD5 | raw file
Possible License(s): Apache-2.0, GPL-2.0, MIT

Large files files are truncated, but you can click here to view the full file

  1. /*************************************************************
  2. *
  3. * MathJax/jax/input/TeX/jax.js
  4. *
  5. * Implements the TeX InputJax that reads mathematics in
  6. * TeX and LaTeX format and converts it to the MML ElementJax
  7. * internal format.
  8. *
  9. * ---------------------------------------------------------------------
  10. *
  11. * Copyright (c) 2009-2012 Design Science, Inc.
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the "License");
  14. * you may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. */
  25. (function (TEX,HUB,AJAX) {
  26. var MML, NBSP = "\u00A0";
  27. var STACK = MathJax.Object.Subclass({
  28. Init: function (env,inner) {
  29. this.global = {isInner: inner};
  30. this.data = [STACKITEM.start(this.global)];
  31. if (env) {this.data[0].env = env}
  32. this.env = this.data[0].env;
  33. },
  34. Push: function () {
  35. var i, m, item, top;
  36. for (i = 0, m = arguments.length; i < m; i++) {
  37. item = arguments[i];
  38. if (item instanceof MML.mbase) {item = STACKITEM.mml(item)}
  39. item.global = this.global;
  40. top = (this.data.length ? this.Top().checkItem(item) : true);
  41. if (top instanceof Array) {this.Pop(); this.Push.apply(this,top)}
  42. else if (top instanceof STACKITEM) {this.Pop(); this.Push(top)}
  43. else if (top) {
  44. this.data.push(item);
  45. if (item.env) {
  46. for (var id in this.env)
  47. {if (this.env.hasOwnProperty(id)) {item.env[id] = this.env[id]}}
  48. this.env = item.env;
  49. } else {item.env = this.env}
  50. }
  51. }
  52. },
  53. Pop: function () {
  54. var item = this.data.pop(); if (!item.isOpen) {delete item.env}
  55. this.env = (this.data.length ? this.Top().env : {});
  56. return item;
  57. },
  58. Top: function (n) {
  59. if (n == null) {n = 1}
  60. if (this.data.length < n) {return null}
  61. return this.data[this.data.length-n];
  62. },
  63. Prev: function (noPop) {
  64. var top = this.Top();
  65. if (noPop) {return top.data[top.data.length-1]}
  66. else {return top.Pop()}
  67. },
  68. toString: function () {return "stack[\n "+this.data.join("\n ")+"\n]"}
  69. });
  70. var STACKITEM = STACK.Item = MathJax.Object.Subclass({
  71. type: "base",
  72. closeError: "Extra close brace or missing open brace",
  73. rightError: "Missing \\left or extra \\right",
  74. Init: function () {
  75. if (this.isOpen) {this.env = {}}
  76. this.data = [];
  77. this.Push.apply(this,arguments);
  78. },
  79. Push: function () {this.data.push.apply(this.data,arguments)},
  80. Pop: function () {return this.data.pop()},
  81. mmlData: function (inferred,forceRow) {
  82. if (inferred == null) {inferred = true}
  83. if (this.data.length === 1 && !forceRow) {return this.data[0]}
  84. return MML.mrow.apply(MML,this.data).With((inferred ? {inferred: true}: {}));
  85. },
  86. checkItem: function (item) {
  87. if (item.type === "over" && this.isOpen) {item.num = this.mmlData(false); this.data = []}
  88. if (item.type === "cell" && this.isOpen) {
  89. if (item.linebreak) {return false}
  90. TEX.Error("Misplaced "+item.name);
  91. }
  92. if (item.isClose && this[item.type+"Error"]) {TEX.Error(this[item.type+"Error"])}
  93. if (!item.isNotStack) {return true}
  94. this.Push(item.data[0]); return false;
  95. },
  96. With: function (def) {
  97. for (var id in def) {if (def.hasOwnProperty(id)) {this[id] = def[id]}}
  98. return this;
  99. },
  100. toString: function () {return this.type+"["+this.data.join("; ")+"]"}
  101. });
  102. STACKITEM.start = STACKITEM.Subclass({
  103. type: "start", isOpen: true,
  104. Init: function (global) {
  105. this.SUPER(arguments).Init.call(this);
  106. this.global = global;
  107. },
  108. checkItem: function (item) {
  109. if (item.type === "stop") {return STACKITEM.mml(this.mmlData())}
  110. return this.SUPER(arguments).checkItem.call(this,item);
  111. }
  112. });
  113. STACKITEM.stop = STACKITEM.Subclass({
  114. type: "stop", isClose: true
  115. });
  116. STACKITEM.open = STACKITEM.Subclass({
  117. type: "open", isOpen: true,
  118. stopError: "Extra open brace or missing close brace",
  119. checkItem: function (item) {
  120. if (item.type === "close") {
  121. var mml = this.mmlData(); // this.mmlData(true,true); // force row
  122. return STACKITEM.mml(MML.TeXAtom(mml)); // TeXAtom make it an ORD to prevent spacing (FIXME: should be another way)
  123. }
  124. return this.SUPER(arguments).checkItem.call(this,item);
  125. }
  126. });
  127. STACKITEM.close = STACKITEM.Subclass({
  128. type: "close", isClose: true
  129. });
  130. STACKITEM.prime = STACKITEM.Subclass({
  131. type: "prime",
  132. checkItem: function (item) {
  133. if (this.data[0].type !== "msubsup")
  134. {return [MML.msup(this.data[0],this.data[1]),item]}
  135. this.data[0].SetData(this.data[0].sup,this.data[1]);
  136. return [this.data[0],item];
  137. }
  138. });
  139. STACKITEM.subsup = STACKITEM.Subclass({
  140. type: "subsup",
  141. stopError: "Missing superscript or subscript argument",
  142. checkItem: function (item) {
  143. var script = ["","subscript","superscript"][this.position];
  144. if (item.type === "open" || item.type === "left") {return true}
  145. if (item.type === "mml") {
  146. if (this.primes) {
  147. if (this.position !== 2) {this.data[0].SetData(2,this.primes)}
  148. else {item.data[0] = MML.mrow(this.primes.With({variantForm:true}),item.data[0])}
  149. }
  150. this.data[0].SetData(this.position,item.data[0]);
  151. return STACKITEM.mml(this.data[0]);
  152. }
  153. if (this.SUPER(arguments).checkItem.call(this,item))
  154. {TEX.Error("Missing open brace for "+script)}
  155. },
  156. Pop: function () {}
  157. });
  158. STACKITEM.over = STACKITEM.Subclass({
  159. type: "over", isClose: true, name: "\\over",
  160. checkItem: function (item,stack) {
  161. if (item.type === "over") {TEX.Error("Ambiguous use of "+item.name)}
  162. if (item.isClose) {
  163. var mml = MML.mfrac(this.num,this.mmlData(false));
  164. if (this.thickness != null) {mml.linethickness = this.thickness}
  165. if (this.open || this.close) {
  166. mml.texClass = MML.TEXCLASS.INNER;
  167. mml.texWithDelims = true;
  168. mml = MML.mfenced(mml).With({open: this.open, close: this.close});
  169. }
  170. return [STACKITEM.mml(mml), item];
  171. }
  172. return this.SUPER(arguments).checkItem.call(this,item);
  173. },
  174. toString: function () {return "over["+this.num+" / "+this.data.join("; ")+"]"}
  175. });
  176. STACKITEM.left = STACKITEM.Subclass({
  177. type: "left", isOpen: true, delim: '(',
  178. stopError: "Extra \\left or missing \\right",
  179. checkItem: function (item) {
  180. if (item.type === "right") {
  181. var mml = MML.mfenced(this.data.length === 1 ? this.data[0] : MML.mrow.apply(MML,this.data));
  182. return STACKITEM.mml(mml.With({open: this.delim, close: item.delim}));
  183. }
  184. return this.SUPER(arguments).checkItem.call(this,item);
  185. }
  186. });
  187. STACKITEM.right = STACKITEM.Subclass({
  188. type: "right", isClose: true, delim: ')'
  189. });
  190. STACKITEM.begin = STACKITEM.Subclass({
  191. type: "begin", isOpen: true,
  192. checkItem: function (item) {
  193. if (item.type === "end") {
  194. if (item.name !== this.name)
  195. {TEX.Error("\\begin{"+this.name+"} ended with \\end{"+item.name+"}")}
  196. if (!this.end) {return STACKITEM.mml(this.mmlData())}
  197. return this.parse[this.end].call(this.parse,this,this.data);
  198. }
  199. if (item.type === "stop") {TEX.Error("Missing \\end{"+this.name+"}")}
  200. return this.SUPER(arguments).checkItem.call(this,item);
  201. }
  202. });
  203. STACKITEM.end = STACKITEM.Subclass({
  204. type: "end", isClose: true
  205. });
  206. STACKITEM.style = STACKITEM.Subclass({
  207. type: "style",
  208. checkItem: function (item) {
  209. if (!item.isClose) {return this.SUPER(arguments).checkItem.call(this,item)}
  210. var mml = MML.mstyle.apply(MML,this.data).With(this.styles);
  211. return [STACKITEM.mml(mml),item];
  212. }
  213. });
  214. STACKITEM.position = STACKITEM.Subclass({
  215. type: "position",
  216. checkItem: function (item) {
  217. if (item.isClose) {TEX.Error("Missing box for "+this.name)}
  218. if (item.isNotStack) {
  219. var mml = item.mmlData();
  220. switch (this.move) {
  221. case 'vertical':
  222. mml = MML.mpadded(mml).With({height: this.dh, depth: this.dd, voffset: this.dh});
  223. return [STACKITEM.mml(mml)];
  224. case 'horizontal':
  225. return [STACKITEM.mml(this.left),item,STACKITEM.mml(this.right)];
  226. }
  227. }
  228. return this.SUPER(arguments).checkItem.call(this,item);
  229. }
  230. });
  231. STACKITEM.array = STACKITEM.Subclass({
  232. type: "array", isOpen: true, arraydef: {},
  233. Init: function () {
  234. this.table = []; this.row = []; this.env = {}; this.frame = []
  235. this.SUPER(arguments).Init.apply(this,arguments);
  236. },
  237. checkItem: function (item) {
  238. if (item.isClose && item.type !== "over") {
  239. if (item.isEntry) {this.EndEntry(); this.clearEnv(); return false}
  240. if (item.isCR) {this.EndEntry(); this.EndRow(); this.clearEnv(); return false}
  241. this.EndTable(); this.clearEnv();
  242. var mml = MML.mtable.apply(MML,this.table).With(this.arraydef);
  243. if (this.frame.length === 4) {
  244. mml.frame = (this.frame.dashed ? "dashed" : "solid");
  245. } else if (this.frame.length) {
  246. mml.hasFrame = true;
  247. if (this.arraydef.rowlines) {this.arraydef.rowlines = this.arraydef.rowlines.replace(/none( none)+$/,"none")}
  248. mml = MML.menclose(mml).With({notation: this.frame.join(" "), isFrame: true});
  249. if ((this.arraydef.columnlines||"none") != "none" ||
  250. (this.arraydef.rowlines||"none") != "none") {mml.padding = 0} // HTML-CSS jax implements this
  251. }
  252. if (this.open || this.close) {
  253. mml = MML.mfenced(mml).With({open: this.open, close: this.close});
  254. }
  255. mml = STACKITEM.mml(mml);
  256. if (this.requireClose) {
  257. if (item.type === 'close') {return mml}
  258. TEX.Error("Missing close brace");
  259. }
  260. return [mml,item];
  261. }
  262. return this.SUPER(arguments).checkItem.call(this,item);
  263. },
  264. EndEntry: function () {this.row.push(MML.mtd.apply(MML,this.data)); this.data = []},
  265. EndRow: function () {this.table.push(MML.mtr.apply(MML,this.row)); this.row = []},
  266. EndTable: function () {
  267. if (this.data.length || this.row.length) {this.EndEntry(); this.EndRow()}
  268. this.checkLines();
  269. },
  270. checkLines: function () {
  271. if (this.arraydef.rowlines) {
  272. var lines = this.arraydef.rowlines.split(/ /);
  273. if (lines.length === this.table.length) {
  274. this.frame.push("bottom"); lines.pop();
  275. this.arraydef.rowlines = lines.join(' ');
  276. } else if (lines.length < this.table.length-1) {
  277. this.arraydef.rowlines += " none";
  278. }
  279. }
  280. if (this.rowspacing) {
  281. var rows = this.arraydef.rowspacing.split(/ /);
  282. while (rows.length < this.table.length) {rows.push(this.rowspacing+"em")}
  283. this.arraydef.rowspacing = rows.join(' ');
  284. }
  285. },
  286. clearEnv: function () {
  287. for (var id in this.env) {if (this.env.hasOwnProperty(id)) {delete this.env[id]}}
  288. }
  289. });
  290. STACKITEM.cell = STACKITEM.Subclass({
  291. type: "cell", isClose: true
  292. });
  293. STACKITEM.mml = STACKITEM.Subclass({
  294. type: "mml", isNotStack: true,
  295. Add: function () {this.data.push.apply(this.data,arguments); return this}
  296. });
  297. STACKITEM.fn = STACKITEM.Subclass({
  298. type: "fn",
  299. checkItem: function (item) {
  300. if (this.data[0]) {
  301. if (item.type !== "mml" || !item.data[0]) {return [this.data[0],item]}
  302. if (item.data[0].isa(MML.mspace)) {return [this.data[0],item]}
  303. var mml = item.data[0]; if (mml.isEmbellished()) {mml = mml.CoreMO()}
  304. if ([0,0,1,1,0,1,1,0,0,0][mml.Get("texClass")]) {return [this.data[0],item]}
  305. return [this.data[0],MML.mo(MML.entity("#x2061")).With({texClass:MML.TEXCLASS.NONE}),item];
  306. }
  307. return this.SUPER(arguments).checkItem.apply(this,arguments);
  308. }
  309. });
  310. STACKITEM.not = STACKITEM.Subclass({
  311. type: "not",
  312. checkItem: function (item) {
  313. var mml, c;
  314. if (item.type === "open" || item.type === "left") {return true}
  315. if (item.type === "mml" && item.data[0].type.match(/^(mo|mi|mtext)$/)) {
  316. mml = item.data[0], c = mml.data.join("");
  317. if (c.length === 1 && !mml.movesupsub) {
  318. c = STACKITEM.not.remap[c.charCodeAt(0)];
  319. if (c) {mml.SetData(0,MML.chars(String.fromCharCode(c)))}
  320. else {mml.Append(MML.chars("\u0338"))}
  321. return item;
  322. }
  323. }
  324. // \mathrel{\rlap{\notChar}}
  325. mml = MML.mpadded(MML.mtext("\u29F8")).With({width:0});
  326. mml = MML.TeXAtom(mml).With({texClass:MML.TEXCLASS.REL});
  327. return [mml,item];
  328. }
  329. });
  330. STACKITEM.not.remap = {
  331. 0x2190:0x219A, 0x2192:0x219B, 0x2194:0x21AE,
  332. 0x21D0:0x21CD, 0x21D2:0x21CF, 0x21D4:0x21CE,
  333. 0x2208:0x2209, 0x220B:0x220C, 0x2223:0x2224, 0x2225:0x2226,
  334. 0x223C:0x2241, 0x007E:0x2241, 0x2243:0x2244, 0x2245:0x2247,
  335. 0x2248:0x2249, 0x224D:0x226D, 0x003D:0x2260, 0x2261:0x2262,
  336. 0x003C:0x226E, 0x003E:0x226F, 0x2264:0x2270, 0x2265:0x2271,
  337. 0x2272:0x2274, 0x2273:0x2275, 0x2276:0x2278, 0x2277:0x2279,
  338. 0x227A:0x2280, 0x227B:0x2281, 0x2282:0x2284, 0x2283:0x2285,
  339. 0x2286:0x2288, 0x2287:0x2289, 0x22A2:0x22AC, 0x22A8:0x22AD,
  340. 0x22A9:0x22AE, 0x22AB:0x22AF, 0x227C:0x22E0, 0x227D:0x22E1,
  341. 0x2291:0x22E2, 0x2292:0x22E3, 0x22B2:0x22EA, 0x22B3:0x22EB,
  342. 0x22B4:0x22EC, 0x22B5:0x22ED, 0x2203:0x2204
  343. };
  344. STACKITEM.dots = STACKITEM.Subclass({
  345. type: "dots",
  346. checkItem: function (item) {
  347. if (item.type === "open" || item.type === "left") {return true}
  348. var dots = this.ldots;
  349. if (item.type === "mml" && item.data[0].isEmbellished()) {
  350. var tclass = item.data[0].CoreMO().Get("texClass");
  351. if (tclass === MML.TEXCLASS.BIN || tclass === MML.TEXCLASS.REL) {dots = this.cdots}
  352. }
  353. return [dots,item];
  354. }
  355. });
  356. var TEXDEF = {
  357. //
  358. // Add new definitions without overriding user-defined ones
  359. //
  360. Add: function (src,dst,nouser) {
  361. if (!dst) {dst = this}
  362. for (var id in src) {if (src.hasOwnProperty(id)) {
  363. if (typeof src[id] === 'object' && !(src[id] instanceof Array) &&
  364. (typeof dst[id] === 'object' || typeof dst[id] === 'function'))
  365. {this.Add(src[id],dst[id],src[id],nouser)}
  366. else if (!dst[id] || !dst[id].isUser || !nouser) {dst[id] = src[id]}
  367. }}
  368. return dst;
  369. }
  370. };
  371. var STARTUP = function () {
  372. MML = MathJax.ElementJax.mml;
  373. HUB.Insert(TEXDEF,{
  374. // patterns for letters and numbers
  375. letter: /[a-z]/i,
  376. digit: /[0-9.]/,
  377. number: /^(?:[0-9]+(?:\{,\}[0-9]{3})*(?:\.[0-9]*)*|\.[0-9]+)/,
  378. special: {
  379. '\\': 'ControlSequence',
  380. '{': 'Open',
  381. '}': 'Close',
  382. '~': 'Tilde',
  383. '^': 'Superscript',
  384. '_': 'Subscript',
  385. ' ': 'Space',
  386. "\t": 'Space',
  387. "\r": 'Space',
  388. "\n": 'Space',
  389. "'": 'Prime',
  390. '%': 'Comment',
  391. '&': 'Entry',
  392. '#': 'Hash',
  393. '\u2019': 'Prime'
  394. },
  395. remap: {
  396. '-': '2212',
  397. '*': '2217'
  398. },
  399. mathchar0mi: {
  400. // Lower-case greek
  401. alpha: '03B1',
  402. beta: '03B2',
  403. gamma: '03B3',
  404. delta: '03B4',
  405. epsilon: '03F5',
  406. zeta: '03B6',
  407. eta: '03B7',
  408. theta: '03B8',
  409. iota: '03B9',
  410. kappa: '03BA',
  411. lambda: '03BB',
  412. mu: '03BC',
  413. nu: '03BD',
  414. xi: '03BE',
  415. omicron: '03BF', // added for completeness
  416. pi: '03C0',
  417. rho: '03C1',
  418. sigma: '03C3',
  419. tau: '03C4',
  420. upsilon: '03C5',
  421. phi: '03D5',
  422. chi: '03C7',
  423. psi: '03C8',
  424. omega: '03C9',
  425. varepsilon: '03B5',
  426. vartheta: '03D1',
  427. varpi: '03D6',
  428. varrho: '03F1',
  429. varsigma: '03C2',
  430. varphi: '03C6',
  431. // Ord symbols
  432. S: ['00A7',{mathvariant: MML.VARIANT.NORMAL}],
  433. aleph: ['2135',{mathvariant: MML.VARIANT.NORMAL}],
  434. hbar: ['210F',{variantForm:true}],
  435. imath: '0131',
  436. jmath: '0237',
  437. ell: '2113',
  438. wp: ['2118',{mathvariant: MML.VARIANT.NORMAL}],
  439. Re: ['211C',{mathvariant: MML.VARIANT.NORMAL}],
  440. Im: ['2111',{mathvariant: MML.VARIANT.NORMAL}],
  441. partial: ['2202',{mathvariant: MML.VARIANT.NORMAL}],
  442. infty: ['221E',{mathvariant: MML.VARIANT.NORMAL}],
  443. prime: ['2032',{mathvariant: MML.VARIANT.NORMAL, variantForm:true}],
  444. emptyset: ['2205',{mathvariant: MML.VARIANT.NORMAL}],
  445. nabla: ['2207',{mathvariant: MML.VARIANT.NORMAL}],
  446. top: ['22A4',{mathvariant: MML.VARIANT.NORMAL}],
  447. bot: ['22A5',{mathvariant: MML.VARIANT.NORMAL}],
  448. angle: ['2220',{mathvariant: MML.VARIANT.NORMAL}],
  449. triangle: ['25B3',{mathvariant: MML.VARIANT.NORMAL}],
  450. backslash: ['2216',{mathvariant: MML.VARIANT.NORMAL, variantForm:true}],
  451. forall: ['2200',{mathvariant: MML.VARIANT.NORMAL}],
  452. exists: ['2203',{mathvariant: MML.VARIANT.NORMAL}],
  453. neg: ['00AC',{mathvariant: MML.VARIANT.NORMAL}],
  454. lnot: ['00AC',{mathvariant: MML.VARIANT.NORMAL}],
  455. flat: ['266D',{mathvariant: MML.VARIANT.NORMAL}],
  456. natural: ['266E',{mathvariant: MML.VARIANT.NORMAL}],
  457. sharp: ['266F',{mathvariant: MML.VARIANT.NORMAL}],
  458. clubsuit: ['2663',{mathvariant: MML.VARIANT.NORMAL}],
  459. diamondsuit: ['2662',{mathvariant: MML.VARIANT.NORMAL}],
  460. heartsuit: ['2661',{mathvariant: MML.VARIANT.NORMAL}],
  461. spadesuit: ['2660',{mathvariant: MML.VARIANT.NORMAL}]
  462. },
  463. mathchar0mo: {
  464. surd: '221A',
  465. // big ops
  466. coprod: ['2210',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  467. bigvee: ['22C1',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  468. bigwedge: ['22C0',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  469. biguplus: ['2A04',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  470. bigcap: ['22C2',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  471. bigcup: ['22C3',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  472. 'int': ['222B',{texClass: MML.TEXCLASS.OP}],
  473. intop: ['222B',{texClass: MML.TEXCLASS.OP, movesupsub:true, movablelimits:true}],
  474. iint: ['222C',{texClass: MML.TEXCLASS.OP}],
  475. iiint: ['222D',{texClass: MML.TEXCLASS.OP}],
  476. prod: ['220F',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  477. sum: ['2211',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  478. bigotimes: ['2A02',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  479. bigoplus: ['2A01',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  480. bigodot: ['2A00',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  481. oint: ['222E',{texClass: MML.TEXCLASS.OP}],
  482. bigsqcup: ['2A06',{texClass: MML.TEXCLASS.OP, movesupsub:true}],
  483. smallint: ['222B',{largeop:false}],
  484. // binary operations
  485. triangleleft: '25C3',
  486. triangleright: '25B9',
  487. bigtriangleup: '25B3',
  488. bigtriangledown: '25BD',
  489. wedge: '2227',
  490. land: '2227',
  491. vee: '2228',
  492. lor: '2228',
  493. cap: '2229',
  494. cup: '222A',
  495. ddagger: '2021',
  496. dagger: '2020',
  497. sqcap: '2293',
  498. sqcup: '2294',
  499. uplus: '228E',
  500. amalg: '2A3F',
  501. diamond: '22C4',
  502. bullet: '2219',
  503. wr: '2240',
  504. div: '00F7',
  505. odot: ['2299',{largeop: false}],
  506. oslash: ['2298',{largeop: false}],
  507. otimes: ['2297',{largeop: false}],
  508. ominus: ['2296',{largeop: false}],
  509. oplus: ['2295',{largeop: false}],
  510. mp: '2213',
  511. pm: '00B1',
  512. circ: '2218',
  513. bigcirc: '25EF',
  514. setminus: ['2216',{variantForm:true}],
  515. cdot: '22C5',
  516. ast: '2217',
  517. times: '00D7',
  518. star: '22C6',
  519. // Relations
  520. propto: '221D',
  521. sqsubseteq: '2291',
  522. sqsupseteq: '2292',
  523. parallel: '2225',
  524. mid: '2223',
  525. dashv: '22A3',
  526. vdash: '22A2',
  527. leq: '2264',
  528. le: '2264',
  529. geq: '2265',
  530. ge: '2265',
  531. lt: '003C',
  532. gt: '003E',
  533. succ: '227B',
  534. prec: '227A',
  535. approx: '2248',
  536. succeq: '2AB0', // or '227C',
  537. preceq: '2AAF', // or '227D',
  538. supset: '2283',
  539. subset: '2282',
  540. supseteq: '2287',
  541. subseteq: '2286',
  542. 'in': '2208',
  543. ni: '220B',
  544. notin: '2209',
  545. owns: '220B',
  546. gg: '226B',
  547. ll: '226A',
  548. sim: '223C',
  549. simeq: '2243',
  550. perp: '22A5',
  551. equiv: '2261',
  552. asymp: '224D',
  553. smile: '2323',
  554. frown: '2322',
  555. ne: '2260',
  556. neq: '2260',
  557. cong: '2245',
  558. doteq: '2250',
  559. bowtie: '22C8',
  560. models: '22A8',
  561. notChar: '29F8',
  562. // Arrows
  563. Leftrightarrow: '21D4',
  564. Leftarrow: '21D0',
  565. Rightarrow: '21D2',
  566. leftrightarrow: '2194',
  567. leftarrow: '2190',
  568. gets: '2190',
  569. rightarrow: '2192',
  570. to: '2192',
  571. mapsto: '21A6',
  572. leftharpoonup: '21BC',
  573. leftharpoondown: '21BD',
  574. rightharpoonup: '21C0',
  575. rightharpoondown: '21C1',
  576. nearrow: '2197',
  577. searrow: '2198',
  578. nwarrow: '2196',
  579. swarrow: '2199',
  580. rightleftharpoons: '21CC',
  581. hookrightarrow: '21AA',
  582. hookleftarrow: '21A9',
  583. longleftarrow: '27F5',
  584. Longleftarrow: '27F8',
  585. longrightarrow: '27F6',
  586. Longrightarrow: '27F9',
  587. Longleftrightarrow: '27FA',
  588. longleftrightarrow: '27F7',
  589. longmapsto: '27FC',
  590. // Misc.
  591. ldots: '2026',
  592. cdots: '22EF',
  593. vdots: '22EE',
  594. ddots: '22F1',
  595. dotsc: '2026', // dots with commas
  596. dotsb: '22EF', // dots with binary ops and relations
  597. dotsm: '22EF', // dots with multiplication
  598. dotsi: '22EF', // dots with integrals
  599. dotso: '2026', // other dots
  600. ldotp: ['002E', {texClass: MML.TEXCLASS.PUNCT}],
  601. cdotp: ['22C5', {texClass: MML.TEXCLASS.PUNCT}],
  602. colon: ['003A', {texClass: MML.TEXCLASS.PUNCT}]
  603. },
  604. mathchar7: {
  605. Gamma: '0393',
  606. Delta: '0394',
  607. Theta: '0398',
  608. Lambda: '039B',
  609. Xi: '039E',
  610. Pi: '03A0',
  611. Sigma: '03A3',
  612. Upsilon: '03A5',
  613. Phi: '03A6',
  614. Psi: '03A8',
  615. Omega: '03A9',
  616. '_': '005F',
  617. '#': '0023',
  618. '$': '0024',
  619. '%': '0025',
  620. '&': '0026',
  621. And: '0026'
  622. },
  623. delimiter: {
  624. '(': '(',
  625. ')': ')',
  626. '[': '[',
  627. ']': ']',
  628. '<': '27E8',
  629. '>': '27E9',
  630. '\\lt': '27E8',
  631. '\\gt': '27E9',
  632. '/': '/',
  633. '|': ['|',{texClass:MML.TEXCLASS.ORD}],
  634. '.': '',
  635. '\\\\': '\\',
  636. '\\lmoustache': '23B0', // non-standard
  637. '\\rmoustache': '23B1', // non-standard
  638. '\\lgroup': '27EE', // non-standard
  639. '\\rgroup': '27EF', // non-standard
  640. '\\arrowvert': '23D0',
  641. '\\Arrowvert': '2016',
  642. '\\bracevert': '23AA', // non-standard
  643. '\\Vert': ['2225',{texClass:MML.TEXCLASS.ORD}],
  644. '\\|': ['2225',{texClass:MML.TEXCLASS.ORD}],
  645. '\\vert': ['|',{texClass:MML.TEXCLASS.ORD}],
  646. '\\uparrow': '2191',
  647. '\\downarrow': '2193',
  648. '\\updownarrow': '2195',
  649. '\\Uparrow': '21D1',
  650. '\\Downarrow': '21D3',
  651. '\\Updownarrow': '21D5',
  652. '\\backslash': '\\',
  653. '\\rangle': '27E9',
  654. '\\langle': '27E8',
  655. '\\rbrace': '}',
  656. '\\lbrace': '{',
  657. '\\}': '}',
  658. '\\{': '{',
  659. '\\rceil': '2309',
  660. '\\lceil': '2308',
  661. '\\rfloor': '230B',
  662. '\\lfloor': '230A',
  663. '\\lbrack': '[',
  664. '\\rbrack': ']'
  665. },
  666. macros: {
  667. displaystyle: ['SetStyle','D',true,0],
  668. textstyle: ['SetStyle','T',false,0],
  669. scriptstyle: ['SetStyle','S',false,1],
  670. scriptscriptstyle: ['SetStyle','SS',false,2],
  671. rm: ['SetFont',MML.VARIANT.NORMAL],
  672. mit: ['SetFont',MML.VARIANT.ITALIC],
  673. oldstyle: ['SetFont',MML.VARIANT.OLDSTYLE],
  674. cal: ['SetFont',MML.VARIANT.CALIGRAPHIC],
  675. it: ['SetFont',"-tex-mathit"], // needs special handling
  676. bf: ['SetFont',MML.VARIANT.BOLD],
  677. bbFont: ['SetFont',MML.VARIANT.DOUBLESTRUCK],
  678. scr: ['SetFont',MML.VARIANT.SCRIPT],
  679. frak: ['SetFont',MML.VARIANT.FRAKTUR],
  680. sf: ['SetFont',MML.VARIANT.SANSSERIF],
  681. tt: ['SetFont',MML.VARIANT.MONOSPACE],
  682. // font:
  683. tiny: ['SetSize',0.5],
  684. Tiny: ['SetSize',0.6], // non-standard
  685. scriptsize: ['SetSize',0.7],
  686. small: ['SetSize',0.85],
  687. normalsize: ['SetSize',1.0],
  688. large: ['SetSize',1.2],
  689. Large: ['SetSize',1.44],
  690. LARGE: ['SetSize',1.73],
  691. huge: ['SetSize',2.07],
  692. Huge: ['SetSize',2.49],
  693. arcsin: ['NamedFn'],
  694. arccos: ['NamedFn'],
  695. arctan: ['NamedFn'],
  696. arg: ['NamedFn'],
  697. cos: ['NamedFn'],
  698. cosh: ['NamedFn'],
  699. cot: ['NamedFn'],
  700. coth: ['NamedFn'],
  701. csc: ['NamedFn'],
  702. deg: ['NamedFn'],
  703. det: 'NamedOp',
  704. dim: ['NamedFn'],
  705. exp: ['NamedFn'],
  706. gcd: 'NamedOp',
  707. hom: ['NamedFn'],
  708. inf: 'NamedOp',
  709. ker: ['NamedFn'],
  710. lg: ['NamedFn'],
  711. lim: 'NamedOp',
  712. liminf: ['NamedOp','lim&thinsp;inf'],
  713. limsup: ['NamedOp','lim&thinsp;sup'],
  714. ln: ['NamedFn'],
  715. log: ['NamedFn'],
  716. max: 'NamedOp',
  717. min: 'NamedOp',
  718. Pr: 'NamedOp',
  719. sec: ['NamedFn'],
  720. sin: ['NamedFn'],
  721. sinh: ['NamedFn'],
  722. sup: 'NamedOp',
  723. tan: ['NamedFn'],
  724. tanh: ['NamedFn'],
  725. limits: ['Limits',1],
  726. nolimits: ['Limits',0],
  727. overline: ['UnderOver','00AF'],
  728. underline: ['UnderOver','005F'],
  729. overbrace: ['UnderOver','23DE',1],
  730. underbrace: ['UnderOver','23DF',1],
  731. overrightarrow: ['UnderOver','2192'],
  732. underrightarrow: ['UnderOver','2192'],
  733. overleftarrow: ['UnderOver','2190'],
  734. underleftarrow: ['UnderOver','2190'],
  735. overleftrightarrow: ['UnderOver','2194'],
  736. underleftrightarrow: ['UnderOver','2194'],
  737. overset: 'Overset',
  738. underset: 'Underset',
  739. stackrel: ['Macro','\\mathrel{\\mathop{#2}\\limits^{#1}}',2],
  740. over: 'Over',
  741. overwithdelims: 'Over',
  742. atop: 'Over',
  743. atopwithdelims: 'Over',
  744. above: 'Over',
  745. abovewithdelims: 'Over',
  746. brace: ['Over','{','}'],
  747. brack: ['Over','[',']'],
  748. choose: ['Over','(',')'],
  749. frac: 'Frac',
  750. sqrt: 'Sqrt',
  751. root: 'Root',
  752. uproot: ['MoveRoot','upRoot'],
  753. leftroot: ['MoveRoot','leftRoot'],
  754. left: 'LeftRight',
  755. right: 'LeftRight',
  756. middle: 'Middle',
  757. llap: 'Lap',
  758. rlap: 'Lap',
  759. raise: 'RaiseLower',
  760. lower: 'RaiseLower',
  761. moveleft: 'MoveLeftRight',
  762. moveright: 'MoveLeftRight',
  763. ',': ['Spacer',MML.LENGTH.THINMATHSPACE],
  764. ':': ['Spacer',MML.LENGTH.MEDIUMMATHSPACE], // for LaTeX
  765. '>': ['Spacer',MML.LENGTH.MEDIUMMATHSPACE],
  766. ';': ['Spacer',MML.LENGTH.THICKMATHSPACE],
  767. '!': ['Spacer',MML.LENGTH.NEGATIVETHINMATHSPACE],
  768. enspace: ['Spacer',".5em"],
  769. quad: ['Spacer',"1em"],
  770. qquad: ['Spacer',"2em"],
  771. thinspace: ['Spacer',MML.LENGTH.THINMATHSPACE],
  772. negthinspace: ['Spacer',MML.LENGTH.NEGATIVETHINMATHSPACE],
  773. hskip: 'Hskip',
  774. hspace: 'Hskip',
  775. kern: 'Hskip',
  776. mskip: 'Hskip',
  777. mspace: 'Hskip',
  778. mkern: 'Hskip',
  779. Rule: ['Rule'],
  780. Space: ['Rule','blank'],
  781. big: ['MakeBig',MML.TEXCLASS.ORD,0.85],
  782. Big: ['MakeBig',MML.TEXCLASS.ORD,1.15],
  783. bigg: ['MakeBig',MML.TEXCLASS.ORD,1.45],
  784. Bigg: ['MakeBig',MML.TEXCLASS.ORD,1.75],
  785. bigl: ['MakeBig',MML.TEXCLASS.OPEN,0.85],
  786. Bigl: ['MakeBig',MML.TEXCLASS.OPEN,1.15],
  787. biggl: ['MakeBig',MML.TEXCLASS.OPEN,1.45],
  788. Biggl: ['MakeBig',MML.TEXCLASS.OPEN,1.75],
  789. bigr: ['MakeBig',MML.TEXCLASS.CLOSE,0.85],
  790. Bigr: ['MakeBig',MML.TEXCLASS.CLOSE,1.15],
  791. biggr: ['MakeBig',MML.TEXCLASS.CLOSE,1.45],
  792. Biggr: ['MakeBig',MML.TEXCLASS.CLOSE,1.75],
  793. bigm: ['MakeBig',MML.TEXCLASS.REL,0.85],
  794. Bigm: ['MakeBig',MML.TEXCLASS.REL,1.15],
  795. biggm: ['MakeBig',MML.TEXCLASS.REL,1.45],
  796. Biggm: ['MakeBig',MML.TEXCLASS.REL,1.75],
  797. mathord: ['TeXAtom',MML.TEXCLASS.ORD],
  798. mathop: ['TeXAtom',MML.TEXCLASS.OP],
  799. mathopen: ['TeXAtom',MML.TEXCLASS.OPEN],
  800. mathclose: ['TeXAtom',MML.TEXCLASS.CLOSE],
  801. mathbin: ['TeXAtom',MML.TEXCLASS.BIN],
  802. mathrel: ['TeXAtom',MML.TEXCLASS.REL],
  803. mathpunct: ['TeXAtom',MML.TEXCLASS.PUNCT],
  804. mathinner: ['TeXAtom',MML.TEXCLASS.INNER],
  805. vcenter: ['TeXAtom',MML.TEXCLASS.VCENTER],
  806. mathchoice: ['Extension','mathchoice'],
  807. buildrel: 'BuildRel',
  808. hbox: ['HBox',0],
  809. text: 'HBox',
  810. mbox: ['HBox',0],
  811. fbox: 'FBox',
  812. strut: 'Strut',
  813. mathstrut: ['Macro','\\vphantom{(}'],
  814. phantom: 'Phantom',
  815. vphantom: ['Phantom',1,0],
  816. hphantom: ['Phantom',0,1],
  817. smash: 'Smash',
  818. acute: ['Accent', "00B4"], // or 0301 or 02CA
  819. grave: ['Accent', "0060"], // or 0300 or 02CB
  820. ddot: ['Accent', "00A8"], // or 0308
  821. tilde: ['Accent', "007E"], // or 0303 or 02DC
  822. bar: ['Accent', "00AF"], // or 0304 or 02C9
  823. breve: ['Accent', "02D8"], // or 0306
  824. check: ['Accent', "02C7"], // or 030C
  825. hat: ['Accent', "005E"], // or 0302 or 02C6
  826. vec: ['Accent', "2192"], // or 20D7
  827. dot: ['Accent', "02D9"], // or 0307
  828. widetilde: ['Accent', "007E",1], // or 0303 or 02DC
  829. widehat: ['Accent', "005E",1], // or 0302 or 02C6
  830. matrix: 'Matrix',
  831. array: 'Matrix',
  832. pmatrix: ['Matrix','(',')'],
  833. cases: ['Matrix','{','',"left left",null,".1em",null,true],
  834. eqalign: ['Matrix',null,null,"right left",MML.LENGTH.THICKMATHSPACE,".5em",'D'],
  835. displaylines: ['Matrix',null,null,"center",null,".5em",'D'],
  836. cr: 'Cr',
  837. '\\': 'CrLaTeX',
  838. newline: 'Cr',
  839. hline: ['HLine','solid'],
  840. hdashline: ['HLine','dashed'],
  841. // noalign: 'HandleNoAlign',
  842. eqalignno: ['Matrix',null,null,"right left right",MML.LENGTH.THICKMATHSPACE+" 3em",".5em",'D'],
  843. leqalignno: ['Matrix',null,null,"right left right",MML.LENGTH.THICKMATHSPACE+" 3em",".5em",'D'],
  844. // TeX substitution macros
  845. bmod: ['Macro','\\mathbin{\\mmlToken{mo}{mod}}'],
  846. pmod: ['Macro','\\pod{\\mmlToken{mi}{mod}\\kern 6mu #1}',1],
  847. mod: ['Macro','\\mathchoice{\\kern18mu}{\\kern12mu}{\\kern12mu}{\\kern12mu}\\mmlToken{mi}{mod}\\,\\,#1',1],
  848. pod: ['Macro','\\mathchoice{\\kern18mu}{\\kern8mu}{\\kern8mu}{\\kern8mu}(#1)',1],
  849. iff: ['Macro','\\;\\Longleftrightarrow\\;'],
  850. skew: ['Macro','{{#2{#3\\mkern#1mu}\\mkern-#1mu}{}}',3],
  851. mathcal: ['Macro','{\\cal #1}',1],
  852. mathscr: ['Macro','{\\scr #1}',1],
  853. mathrm: ['Macro','{\\rm #1}',1],
  854. mathbf: ['Macro','{\\bf #1}',1],
  855. mathbb: ['Macro','{\\bbFont #1}',1],
  856. Bbb: ['Macro','{\\bbFont #1}',1],
  857. mathit: ['Macro','{\\it #1}',1],
  858. mathfrak: ['Macro','{\\frak #1}',1],
  859. mathsf: ['Macro','{\\sf #1}',1],
  860. mathtt: ['Macro','{\\tt #1}',1],
  861. textrm: ['Macro','\\mathord{\\rm\\text{#1}}',1],
  862. textit: ['Macro','\\mathord{\\it{\\text{#1}}}',1],
  863. textbf: ['Macro','\\mathord{\\bf{\\text{#1}}}',1],
  864. pmb: ['Macro','\\rlap{#1}\\kern1px{#1}',1],
  865. TeX: ['Macro','T\\kern-.14em\\lower.5ex{E}\\kern-.115em X'],
  866. LaTeX: ['Macro','L\\kern-.325em\\raise.21em{\\scriptstyle{A}}\\kern-.17em\\TeX'],
  867. ' ': ['Macro','\\text{ }'],
  868. // Specially handled
  869. not: 'Not',
  870. dots: 'Dots',
  871. space: 'Tilde',
  872. // LaTeX
  873. begin: 'Begin',
  874. end: 'End',
  875. newcommand: ['Extension','newcommand'],
  876. renewcommand: ['Extension','newcommand'],
  877. newenvironment: ['Extension','newcommand'],
  878. renewenvironment: ['Extension','newcommand'],
  879. def: ['Extension','newcommand'],
  880. let: ['Extension','newcommand'],
  881. verb: ['Extension','verb'],
  882. boldsymbol: ['Extension','boldsymbol'],
  883. tag: ['Extension','AMSmath'],
  884. notag: ['Extension','AMSmath'],
  885. label: ['Extension','AMSmath'],
  886. ref: ['Extension','AMSmath'],
  887. eqref: ['Extension','AMSmath'],
  888. nonumber: ['Macro','\\notag'],
  889. // Extensions to TeX
  890. unicode: ['Extension','unicode'],
  891. color: 'Color',
  892. href: ['Extension','HTML'],
  893. 'class': ['Extension','HTML'],
  894. style: ['Extension','HTML'],
  895. cssId: ['Extension','HTML'],
  896. bbox: ['Extension','bbox'],
  897. mmlToken: 'MmlToken',
  898. require: 'Require'
  899. },
  900. environment: {
  901. array: ['AlignedArray'],
  902. matrix: ['Array',null,null,null,'c'],
  903. pmatrix: ['Array',null,'(',')','c'],
  904. bmatrix: ['Array',null,'[',']','c'],
  905. Bmatrix: ['Array',null,'\\{','\\}','c'],
  906. vmatrix: ['Array',null,'\\vert','\\vert','c'],
  907. Vmatrix: ['Array',null,'\\Vert','\\Vert','c'],
  908. cases: ['Array',null,'\\{','.','ll',null,".1em"],
  909. equation: [null,'Equation'],
  910. 'equation*': [null,'Equation'],
  911. eqnarray: ['ExtensionEnv',null,'AMSmath'],
  912. 'eqnarray*': ['ExtensionEnv',null,'AMSmath'],
  913. align: ['ExtensionEnv',null,'AMSmath'],
  914. 'align*': ['ExtensionEnv',null,'AMSmath'],
  915. aligned: ['ExtensionEnv',null,'AMSmath'],
  916. multline: ['ExtensionEnv',null,'AMSmath'],
  917. 'multline*': ['ExtensionEnv',null,'AMSmath'],
  918. split: ['ExtensionEnv',null,'AMSmath'],
  919. gather: ['ExtensionEnv',null,'AMSmath'],
  920. 'gather*': ['ExtensionEnv',null,'AMSmath'],
  921. gathered: ['ExtensionEnv',null,'AMSmath'],
  922. alignat: ['ExtensionEnv',null,'AMSmath'],
  923. 'alignat*': ['ExtensionEnv',null,'AMSmath'],
  924. alignedat: ['ExtensionEnv',null,'AMSmath']
  925. },
  926. p_height: 1.2 / .85 // cmex10 height plus depth over .85
  927. });
  928. //
  929. // Add macros defined in the configuration
  930. //
  931. if (this.config.Macros) {
  932. var MACROS = this.config.Macros;
  933. for (var id in MACROS) {if (MACROS.hasOwnProperty(id)) {
  934. if (typeof(MACROS[id]) === "string") {TEXDEF.macros[id] = ['Macro',MACROS[id]]}
  935. else {TEXDEF.macros[id] = ["Macro"].concat(MACROS[id])}
  936. TEXDEF.macros[id].isUser = true;
  937. }}
  938. }
  939. };
  940. /************************************************************************/
  941. /*
  942. * The TeX Parser
  943. */
  944. var PARSE = MathJax.Object.Subclass({
  945. Init: function (string,env) {
  946. this.string = string; this.i = 0; this.macroCount = 0;
  947. var ENV; if (env) {ENV = {}; for (var id in env) {if (env.hasOwnProperty(id)) {ENV[id] = env[id]}}}
  948. this.stack = TEX.Stack(ENV,!!env);
  949. this.Parse(); this.Push(STACKITEM.stop());
  950. },
  951. Parse: function () {
  952. var c, n;
  953. while (this.i < this.string.length) {
  954. c = this.string.charAt(this.i++); n = c.charCodeAt(0);
  955. if (n >= 0xD800 && n < 0xDC00) {c += this.string.charAt(this.i++)}
  956. if (TEXDEF.special[c]) {this[TEXDEF.special[c]](c)}
  957. else if (TEXDEF.letter.test(c)) {this.Variable(c)}
  958. else if (TEXDEF.digit.test(c)) {this.Number(c)}
  959. else {this.Other(c)}
  960. }
  961. },
  962. Push: function () {this.stack.Push.apply(this.stack,arguments)},
  963. mml: function () {
  964. if (this.stack.Top().type !== "mml") {return null}
  965. return this.stack.Top().data[0];
  966. },
  967. mmlToken: function (token) {return token}, // used by boldsymbol extension
  968. /************************************************************************/
  969. /*
  970. * Handle various token classes
  971. */
  972. /*
  973. * Lookup a control-sequence and process it
  974. */
  975. ControlSequence: function (c) {
  976. var name = this.GetCS(), macro = this.csFindMacro(name);
  977. if (macro) {
  978. if (!(macro instanceof Array)) {macro = [macro]}
  979. var fn = macro[0]; if (!(fn instanceof Function)) {fn = this[fn]}
  980. fn.apply(this,[c+name].concat(macro.slice(1)));
  981. } else if (TEXDEF.mathchar0mi[name]) {this.csMathchar0mi(name,TEXDEF.mathchar0mi[name])}
  982. else if (TEXDEF.mathchar0mo[name]) {this.csMathchar0mo(name,TEXDEF.mathchar0mo[name])}
  983. else if (TEXDEF.mathchar7[name]) {this.csMathchar7(name,TEXDEF.mathchar7[name])}
  984. else if (TEXDEF.delimiter["\\"+name] != null) {this.csDelimiter(name,TEXDEF.delimiter["\\"+name])}
  985. else {this.csUndefined(c+name)}
  986. },
  987. //
  988. // Look up a macro in the macros list
  989. // (overridden in begingroup extension)
  990. //
  991. csFindMacro: function (name) {return TEXDEF.macros[name]},
  992. //
  993. // Handle normal mathchar (as an mi)
  994. //
  995. csMathchar0mi: function (name,mchar) {
  996. var def = {mathvariant: MML.VARIANT.ITALIC};
  997. if (mchar instanceof Array) {def = mchar[1]; mchar = mchar[0]}
  998. this.Push(this.mmlToken(MML.mi(MML.entity("#x"+mchar)).With(def)));
  999. },
  1000. //
  1001. // Handle normal mathchar (as an mo)
  1002. //
  1003. csMathchar0mo: function (name,mchar) {
  1004. var def = {stretchy: false};
  1005. if (mchar instanceof Array) {def = mchar[1]; def.stretchy = false; mchar = mchar[0]}
  1006. this.Push(this.mmlToken(MML.mo(MML.entity("#x"+mchar)).With(def)));
  1007. },
  1008. //
  1009. // Handle mathchar in current family
  1010. //
  1011. csMathchar7: function (name,mchar) {
  1012. var def = {mathvariant: MML.VARIANT.NORMAL};
  1013. if (mchar instanceof Array) {def = mchar[1]; mchar = mchar[0]}
  1014. if (this.stack.env.font) {def.mathvariant = this.stack.env.font}
  1015. this.Push(this.mmlToken(MML.mi(MML.entity("#x"+mchar)).With(def)));
  1016. },
  1017. //
  1018. // Handle delimiter
  1019. //
  1020. csDelimiter: function (name,delim) {
  1021. var def = {};
  1022. if (delim instanceof Array) {def = delim[1]; delim = delim[0]}
  1023. if (delim.length === 4) {delim = MML.entity('#x'+delim)} else {delim = MML.chars(delim)}
  1024. this.Push(this.mmlToken(MML.mo(delim).With({fence: false, stretchy: false}).With(def)));
  1025. },
  1026. //
  1027. // Handle undefined control sequence
  1028. // (overridden in noUndefined extension)
  1029. //
  1030. csUndefined: function (name) {
  1031. TEX.Error("Undefined control sequence "+name);
  1032. },
  1033. /*
  1034. * Handle a variable (a single letter)
  1035. */
  1036. Variable: function (c) {
  1037. var def = {}; if (this.stack.env.font) {def.mathvariant = this.stack.env.font}
  1038. this.Push(this.mmlToken(MML.mi(MML.chars(c)).With(def)));
  1039. },
  1040. /*
  1041. * Determine the extent of a number (pattern may need work)
  1042. */
  1043. Number: function (c) {
  1044. var mml, n = this.string.slice(this.i-1).match(TEXDEF.number);
  1045. if (n) {mml = MML.mn(n[0].replace(/[{}]/g,"")); this.i += n[0].length - 1}
  1046. else {mml = MML.mo(MML.chars(c))}
  1047. if (this.stack.env.font) {mml.mathvariant = this.stack.env.font}
  1048. this.Push(this.mmlToken(mml));
  1049. },
  1050. /*
  1051. * Handle { and }
  1052. */
  1053. Open: function (c) {this.Push(STACKITEM.open())},
  1054. Close: function (c) {this.Push(STACKITEM.close())},
  1055. /*
  1056. * Handle tilde and spaces
  1057. */
  1058. Tilde: function (c) {this.Push(MML.mtext(MML.chars(NBSP)))},
  1059. Space: function (c) {},
  1060. /*
  1061. * Handle ^, _, and '
  1062. */
  1063. Superscript: function (c) {
  1064. if (this.GetNext().match(/\d/)) // don't treat numbers as a unit
  1065. {this.string = this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)}
  1066. var position, primes, base, top = this.stack.Top();
  1067. if (top.type === "prime") {base = top.data[0]; primes = top.data[1]; this.stack.Pop()}
  1068. else {base = this.stack.Prev(); if (!base) {base = MML.mi("")}}
  1069. if (base.isEmbellishedWrapper) {base = base.data[0].data[0]}
  1070. if (base.type === "msubsup") {
  1071. if (base.data[base.sup]) {TEX.Error("Double exponent: use braces to clarify")}
  1072. position = base.sup;
  1073. } else if (base.movesupsub) {
  1074. if (base.type !== "munderover" || base.data[base.over]) {
  1075. if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)}
  1076. base = MML.munderover(base,null,null).With({movesupsub:true})
  1077. }
  1078. position = base.over;
  1079. } else {
  1080. base = MML.msubsup(base,null,null);
  1081. position = base.sup;
  1082. }
  1083. this.Push(STACKITEM.subsup(base).With({position: position, primes: primes}));
  1084. },
  1085. Subscript: function (c) {
  1086. if (this.GetNext().match(/\d/)) // don't treat numbers as a unit
  1087. {this.string = this.string.substr(0,this.i+1)+" "+this.string.substr(this.i+1)}
  1088. var position, primes, base, top = this.stack.Top();
  1089. if (top.type === "prime") {base = top.data[0]; primes = top.data[1]; this.stack.Pop()}
  1090. else {base = this.stack.Prev(); if (!base) {base = MML.mi("")}}
  1091. if (base.isEmbellishedWrapper) {base = base.data[0].data[0]}
  1092. if (base.type === "msubsup") {
  1093. if (base.data[base.sub]) {TEX.Error("Double subscripts: use braces to clarify")}
  1094. position = base.sub;
  1095. } else if (base.movesupsub) {
  1096. if (base.type !== "munderover" || base.data[base.under]) {
  1097. if (base.movablelimits && base.isa(MML.mi)) {base = this.mi2mo(base)}
  1098. base = MML.munderover(base,null,null).With({movesupsub:true})
  1099. }
  1100. position = base.under;
  1101. } else {
  1102. base = MML.msubsup(base,null,null);
  1103. position = base.sub;
  1104. }
  1105. this.Push(STACKITEM.subsup(base).With({position: position, primes: primes}));
  1106. },
  1107. PRIME: "\u2032", SMARTQUOTE: "\u2019",
  1108. Prime: function (c) {
  1109. var base = this.stack.Prev(); if (!base) {base = MML.mi()}
  1110. if (base.type === "msubsup" && base.data[base.sup])
  1111. {TEX.Error("Prime causes double exponent: use braces to clarify")}
  1112. var sup = ""; this.i--;
  1113. do {sup += this.PRIME; this.i++, c = this.GetNext()}
  1114. while (c === "'" || c === this.SMARTQUOTE);
  1115. sup = ["","\u2032","\u2033","\u2034","\u2057"][sup.length] || sup;
  1116. this.Push(STACKITEM.prime(base,this.mmlToken(MML.mo(sup))));
  1117. },
  1118. mi2mo: function (mi) {
  1119. var mo = MML.mo(); mo.Append.apply(mo,mi.data); var id;
  1120. for (id in mo.defaults)
  1121. {if (mo.defaults.hasOwnProperty(id) && mi[id] != null) {mo[id] = mi[id]}}
  1122. for (id in MML.copyAttributes)
  1123. {if (MML.copyAttributes.hasOwnProperty(id) && mi[id] != null) {mo[id] = mi[id]}}
  1124. return mo;
  1125. },
  1126. /*
  1127. * Handle comments
  1128. */
  1129. Comment: function (c) {
  1130. while (this.i < this.string.length && this.string.charAt(this.i) != "\n") {this.i++}
  1131. },
  1132. /*
  1133. * Handle hash marks outside of definitions
  1134. */
  1135. Hash: function (c) {
  1136. TEX.Error("You can't use 'macro parameter character #' in math mode");
  1137. },
  1138. /*
  1139. * Handle other characters (as <mo> elements)
  1140. */
  1141. Other: function (c) {
  1142. var def = {stretchy: false}, mo;
  1143. if (this.stack.env.font) {def.mathvariant = this.stack.env.font}
  1144. if (TEXDEF.remap[c]) {
  1145. c = TEXDEF.remap[c];
  1146. if (c instanceof Array) {def = c[1]; c = c[0]}
  1147. mo = MML.mo(MML.entity('#x'+c)).With(def);
  1148. } else {
  1149. mo = MML.mo(c).With(def);
  1150. }
  1151. if (mo.autoDefault("texClass",true) == "") {mo = MML.TeXAtom(mo)}
  1152. this.Push(this.mmlToken(mo));
  1153. },
  1154. /************************************************************************/
  1155. /*
  1156. * Macros
  1157. */
  1158. SetFont: function (name,font) {this.stack.env.font = font},
  1159. SetStyle: function (name,texStyle,style,level) {
  1160. this.stack.env.style = texStyle; this.stack.env.level = level;
  1161. this.Push(STACKITEM.style().With({styles: {displaystyle: style, scriptlevel: level}}));
  1162. },
  1163. SetSize: function (name,size) {
  1164. this.stack.env.size = size;
  1165. this.Push(STACKITEM.style().With({styles: {mathsize: size+"em"}})); // convert to absolute?
  1166. },
  1167. Color: function (name) {
  1168. var color = this.GetArgument(name);
  1169. var old = this.stack.env.color; this.stack.env.color = color;
  1170. var math = this.ParseArg(name);
  1171. if (old) {this.stack.env.color} else {delete this.stack.env.color}
  1172. this.Push(MML.mstyle(math).With({mathcolor: color}));
  1173. },
  1174. Spacer: function (name,space) {
  1175. this.Pu

Large files files are truncated, but you can click here to view the full file