jax.js 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818
  1. /* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
  2. /* vim: set ts=2 et sw=2 tw=80: */
  3. /*************************************************************
  4. *
  5. * MathJax/jax/element/mml/jax.js
  6. *
  7. * Implements the MML ElementJax that holds the internal represetation
  8. * of the mathematics on the page. Various InputJax will produce this
  9. * format, and the OutputJax will display it in various formats.
  10. *
  11. * ---------------------------------------------------------------------
  12. *
  13. * Copyright (c) 2009-2017 The MathJax Consortium
  14. *
  15. * Licensed under the Apache License, Version 2.0 (the "License");
  16. * you may not use this file except in compliance with the License.
  17. * You may obtain a copy of the License at
  18. *
  19. * http://www.apache.org/licenses/LICENSE-2.0
  20. *
  21. * Unless required by applicable law or agreed to in writing, software
  22. * distributed under the License is distributed on an "AS IS" BASIS,
  23. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  24. * See the License for the specific language governing permissions and
  25. * limitations under the License.
  26. */
  27. MathJax.ElementJax.mml = MathJax.ElementJax({
  28. mimeType: "jax/mml"
  29. },{
  30. id: "mml",
  31. version: "2.7.2",
  32. directory: MathJax.ElementJax.directory + "/mml",
  33. extensionDir: MathJax.ElementJax.extensionDir + "/mml",
  34. optableDir: MathJax.ElementJax.directory + "/mml/optable"
  35. });
  36. MathJax.ElementJax.mml.Augment({
  37. Init: function () {
  38. if (arguments.length === 1 && arguments[0].type === "math") {this.root = arguments[0]}
  39. else {this.root = MathJax.ElementJax.mml.math.apply(this,arguments)}
  40. if (this.root.attr && this.root.attr.mode) {
  41. if (!this.root.display && this.root.attr.mode === "display") {
  42. this.root.display = "block";
  43. this.root.attrNames.push("display");
  44. }
  45. delete this.root.attr.mode;
  46. for (var i = 0, m = this.root.attrNames.length; i < m; i++) {
  47. if (this.root.attrNames[i] === "mode") {this.root.attrNames.splice(i,1); break}
  48. }
  49. }
  50. }
  51. },{
  52. INHERIT: "_inherit_",
  53. AUTO: "_auto_",
  54. SIZE: {
  55. INFINITY: "infinity",
  56. SMALL: "small",
  57. NORMAL: "normal",
  58. BIG: "big"
  59. },
  60. COLOR: {
  61. TRANSPARENT: "transparent"
  62. },
  63. VARIANT: {
  64. NORMAL: "normal",
  65. BOLD: "bold",
  66. ITALIC: "italic",
  67. BOLDITALIC: "bold-italic",
  68. DOUBLESTRUCK: "double-struck",
  69. FRAKTUR: "fraktur",
  70. BOLDFRAKTUR: "bold-fraktur",
  71. SCRIPT: "script",
  72. BOLDSCRIPT: "bold-script",
  73. SANSSERIF: "sans-serif",
  74. BOLDSANSSERIF: "bold-sans-serif",
  75. SANSSERIFITALIC: "sans-serif-italic",
  76. SANSSERIFBOLDITALIC: "sans-serif-bold-italic",
  77. MONOSPACE: "monospace",
  78. INITIAL: "inital",
  79. TAILED: "tailed",
  80. LOOPED: "looped",
  81. STRETCHED: "stretched",
  82. CALIGRAPHIC: "-tex-caligraphic",
  83. OLDSTYLE: "-tex-oldstyle"
  84. },
  85. FORM: {
  86. PREFIX: "prefix",
  87. INFIX: "infix",
  88. POSTFIX: "postfix"
  89. },
  90. LINEBREAK: {
  91. AUTO: "auto",
  92. NEWLINE: "newline",
  93. NOBREAK: "nobreak",
  94. GOODBREAK: "goodbreak",
  95. BADBREAK: "badbreak"
  96. },
  97. LINEBREAKSTYLE: {
  98. BEFORE: "before",
  99. AFTER: "after",
  100. DUPLICATE: "duplicate",
  101. INFIXLINBREAKSTYLE: "infixlinebreakstyle"
  102. },
  103. INDENTALIGN: {
  104. LEFT: "left",
  105. CENTER: "center",
  106. RIGHT: "right",
  107. AUTO: "auto",
  108. ID: "id",
  109. INDENTALIGN: "indentalign"
  110. },
  111. INDENTSHIFT: {
  112. INDENTSHIFT: "indentshift"
  113. },
  114. LINETHICKNESS: {
  115. THIN: "thin",
  116. MEDIUM: "medium",
  117. THICK: "thick"
  118. },
  119. NOTATION: {
  120. LONGDIV: "longdiv",
  121. ACTUARIAL: "actuarial",
  122. RADICAL: "radical",
  123. BOX: "box",
  124. ROUNDEDBOX: "roundedbox",
  125. CIRCLE: "circle",
  126. LEFT: "left",
  127. RIGHT: "right",
  128. TOP: "top",
  129. BOTTOM: "bottom",
  130. UPDIAGONALSTRIKE: "updiagonalstrike",
  131. DOWNDIAGONALSTRIKE: "downdiagonalstrike",
  132. UPDIAGONALARROW: "updiagonalarrow",
  133. VERTICALSTRIKE: "verticalstrike",
  134. HORIZONTALSTRIKE: "horizontalstrike",
  135. PHASORANGLE: "phasorangle",
  136. MADRUWB: "madruwb"
  137. },
  138. ALIGN: {
  139. TOP: "top",
  140. BOTTOM: "bottom",
  141. CENTER: "center",
  142. BASELINE: "baseline",
  143. AXIS: "axis",
  144. LEFT: "left",
  145. RIGHT: "right"
  146. },
  147. LINES: {
  148. NONE: "none",
  149. SOLID: "solid",
  150. DASHED: "dashed"
  151. },
  152. SIDE: {
  153. LEFT: "left",
  154. RIGHT: "right",
  155. LEFTOVERLAP: "leftoverlap",
  156. RIGHTOVERLAP: "rightoverlap"
  157. },
  158. WIDTH: {
  159. AUTO: "auto",
  160. FIT: "fit"
  161. },
  162. ACTIONTYPE: {
  163. TOGGLE: "toggle",
  164. STATUSLINE: "statusline",
  165. TOOLTIP: "tooltip",
  166. INPUT: "input"
  167. },
  168. LENGTH: {
  169. VERYVERYTHINMATHSPACE: "veryverythinmathspace",
  170. VERYTHINMATHSPACE: "verythinmathspace",
  171. THINMATHSPACE: "thinmathspace",
  172. MEDIUMMATHSPACE: "mediummathspace",
  173. THICKMATHSPACE: "thickmathspace",
  174. VERYTHICKMATHSPACE: "verythickmathspace",
  175. VERYVERYTHICKMATHSPACE: "veryverythickmathspace",
  176. NEGATIVEVERYVERYTHINMATHSPACE: "negativeveryverythinmathspace",
  177. NEGATIVEVERYTHINMATHSPACE: "negativeverythinmathspace",
  178. NEGATIVETHINMATHSPACE: "negativethinmathspace",
  179. NEGATIVEMEDIUMMATHSPACE: "negativemediummathspace",
  180. NEGATIVETHICKMATHSPACE: "negativethickmathspace",
  181. NEGATIVEVERYTHICKMATHSPACE: "negativeverythickmathspace",
  182. NEGATIVEVERYVERYTHICKMATHSPACE: "negativeveryverythickmathspace"
  183. },
  184. OVERFLOW: {
  185. LINBREAK: "linebreak",
  186. SCROLL: "scroll",
  187. ELIDE: "elide",
  188. TRUNCATE: "truncate",
  189. SCALE: "scale"
  190. },
  191. UNIT: {
  192. EM: "em",
  193. EX: "ex",
  194. PX: "px",
  195. IN: "in",
  196. CM: "cm",
  197. MM: "mm",
  198. PT: "pt",
  199. PC: "pc"
  200. },
  201. TEXCLASS: {
  202. ORD: 0,
  203. OP: 1,
  204. BIN: 2,
  205. REL: 3,
  206. OPEN: 4,
  207. CLOSE: 5,
  208. PUNCT: 6,
  209. INNER: 7,
  210. VCENTER: 8,
  211. NONE: -1
  212. },
  213. TEXCLASSNAMES: ["ORD", "OP", "BIN", "REL", "OPEN", "CLOSE", "PUNCT", "INNER", "VCENTER"],
  214. skipAttributes: {
  215. texClass:true, useHeight:true, texprimestyle:true
  216. },
  217. copyAttributes: {
  218. displaystyle:1, scriptlevel:1, open:1, close:1, form:1,
  219. actiontype: 1,
  220. fontfamily:true, fontsize:true, fontweight:true, fontstyle:true,
  221. color:true, background:true,
  222. id:true, "class":1, href:true, style:true
  223. },
  224. copyAttributeNames: [
  225. "displaystyle", "scriptlevel", "open", "close", "form", // force these to be copied
  226. "actiontype",
  227. "fontfamily", "fontsize", "fontweight", "fontstyle",
  228. "color", "background",
  229. "id", "class", "href", "style"
  230. ],
  231. nocopyAttributes: {
  232. fontfamily: true, fontsize: true, fontweight: true, fontstyle: true,
  233. color: true, background: true,
  234. id: true, 'class': true, href: true, style: true,
  235. xmlns: true
  236. },
  237. Error: function (message,def) {
  238. var mml = this.merror(message),
  239. dir = MathJax.Localization.fontDirection(),
  240. font = MathJax.Localization.fontFamily();
  241. if (def) {mml = mml.With(def)}
  242. if (dir || font) {
  243. mml = this.mstyle(mml);
  244. if (dir) {mml.dir = dir}
  245. if (font) {mml.style.fontFamily = "font-family: "+font}
  246. }
  247. return mml;
  248. }
  249. });
  250. (function (MML) {
  251. MML.mbase = MathJax.Object.Subclass({
  252. type: "base", isToken: false,
  253. defaults: {
  254. mathbackground: MML.INHERIT,
  255. mathcolor: MML.INHERIT,
  256. dir: MML.INHERIT
  257. },
  258. noInherit: {},
  259. noInheritAttribute: {
  260. texClass: true
  261. },
  262. getRemoved: {},
  263. linebreakContainer: false,
  264. Init: function () {
  265. this.data = [];
  266. if (this.inferRow && !(arguments.length === 1 && arguments[0].inferred))
  267. {this.Append(MML.mrow().With({inferred: true, notParent: true}))}
  268. this.Append.apply(this,arguments);
  269. },
  270. With: function (def) {
  271. for (var id in def) {if (def.hasOwnProperty(id)) {this[id] = def[id]}}
  272. return this;
  273. },
  274. Append: function () {
  275. if (this.inferRow && this.data.length) {
  276. this.data[0].Append.apply(this.data[0],arguments);
  277. } else {
  278. for (var i = 0, m = arguments.length; i < m; i++)
  279. {this.SetData(this.data.length,arguments[i])}
  280. }
  281. },
  282. SetData: function (i,item) {
  283. if (item != null) {
  284. if (!(item instanceof MML.mbase))
  285. {item = (this.isToken || this.isChars ? MML.chars(item) : MML.mtext(item))}
  286. item.parent = this;
  287. item.setInherit(this.inheritFromMe ? this : this.inherit);
  288. }
  289. this.data[i] = item;
  290. },
  291. Parent: function () {
  292. var parent = this.parent;
  293. while (parent && parent.notParent) {parent = parent.parent}
  294. return parent;
  295. },
  296. Get: function (name,nodefault,noself) {
  297. if (!noself) {
  298. if (this[name] != null) {return this[name]}
  299. if (this.attr && this.attr[name] != null) {return this.attr[name]}
  300. }
  301. // FIXME: should cache these values and get from cache
  302. // (clear cache when appended to a new object?)
  303. var parent = this.Parent();
  304. if (parent && parent["adjustChild_"+name] != null) {
  305. return (parent["adjustChild_"+name])(this.childPosition(),nodefault);
  306. }
  307. var obj = this.inherit; var root = obj;
  308. while (obj) {
  309. var value = obj[name]; if (value == null && obj.attr) {value = obj.attr[name]}
  310. if (obj.removedStyles && obj.getRemoved[name] && value == null) value = obj.removedStyles[obj.getRemoved[name]];
  311. if (value != null && obj.noInheritAttribute && !obj.noInheritAttribute[name]) {
  312. var noInherit = obj.noInherit[this.type];
  313. if (!(noInherit && noInherit[name])) {return value}
  314. }
  315. root = obj; obj = obj.inherit;
  316. }
  317. if (!nodefault) {
  318. if (this.defaults[name] === MML.AUTO) {return this.autoDefault(name)}
  319. if (this.defaults[name] !== MML.INHERIT && this.defaults[name] != null)
  320. {return this.defaults[name]}
  321. if (root) {return root.defaults[name]}
  322. }
  323. return null;
  324. },
  325. hasValue: function (name) {return (this.Get(name,true) != null)},
  326. getValues: function () {
  327. var values = {};
  328. for (var i = 0, m = arguments.length; i < m; i++)
  329. {values[arguments[i]] = this.Get(arguments[i])}
  330. return values;
  331. },
  332. adjustChild_scriptlevel: function (i,nodef) {return this.Get("scriptlevel",nodef)}, // always inherit from parent
  333. adjustChild_displaystyle: function (i,nodef) {return this.Get("displaystyle",nodef)}, // always inherit from parent
  334. adjustChild_texprimestyle: function (i,nodef) {return this.Get("texprimestyle",nodef)}, // always inherit from parent
  335. childPosition: function () {
  336. var child = this, parent = child.parent;
  337. while (parent.notParent) {child = parent; parent = child.parent}
  338. for (var i = 0, m = parent.data.length; i < m; i++) {if (parent.data[i] === child) {return i}}
  339. return null;
  340. },
  341. setInherit: function (obj) {
  342. if (obj !== this.inherit && this.inherit == null) {
  343. this.inherit = obj;
  344. for (var i = 0, m = this.data.length; i < m; i++) {
  345. if (this.data[i] && this.data[i].setInherit) {this.data[i].setInherit(obj)}
  346. }
  347. }
  348. },
  349. setTeXclass: function (prev) {
  350. this.getPrevClass(prev);
  351. return (typeof(this.texClass) !== "undefined" ? this : prev);
  352. },
  353. getPrevClass: function (prev) {
  354. if (prev) {
  355. this.prevClass = prev.Get("texClass");
  356. this.prevLevel = prev.Get("scriptlevel");
  357. }
  358. },
  359. updateTeXclass: function (core) {
  360. if (core) {
  361. this.prevClass = core.prevClass; delete core.prevClass;
  362. this.prevLevel = core.prevLevel; delete core.prevLevel;
  363. this.texClass = core.Get("texClass");
  364. }
  365. },
  366. texSpacing: function () {
  367. var prev = (this.prevClass != null ? this.prevClass : MML.TEXCLASS.NONE);
  368. var tex = (this.Get("texClass") || MML.TEXCLASS.ORD);
  369. if (prev === MML.TEXCLASS.NONE || tex === MML.TEXCLASS.NONE) {return ""}
  370. if (prev === MML.TEXCLASS.VCENTER) {prev = MML.TEXCLASS.ORD}
  371. if (tex === MML.TEXCLASS.VCENTER) {tex = MML.TEXCLASS.ORD}
  372. var space = this.TEXSPACE[prev][tex];
  373. if ((this.prevLevel > 0 || this.Get("scriptlevel") > 0) && space >= 0) {return ""}
  374. return this.TEXSPACELENGTH[Math.abs(space)];
  375. },
  376. TEXSPACELENGTH:[
  377. "",
  378. MML.LENGTH.THINMATHSPACE,
  379. MML.LENGTH.MEDIUMMATHSPACE,
  380. MML.LENGTH.THICKMATHSPACE
  381. ],
  382. // See TeXBook Chapter 18 (p. 170)
  383. TEXSPACE: [
  384. [ 0,-1, 2, 3, 0, 0, 0, 1], // ORD
  385. [-1,-1, 0, 3, 0, 0, 0, 1], // OP
  386. [ 2, 2, 0, 0, 2, 0, 0, 2], // BIN
  387. [ 3, 3, 0, 0, 3, 0, 0, 3], // REL
  388. [ 0, 0, 0, 0, 0, 0, 0, 0], // OPEN
  389. [ 0,-1, 2, 3, 0, 0, 0, 1], // CLOSE
  390. [ 1, 1, 0, 1, 1, 1, 1, 1], // PUNCT
  391. [ 1,-1, 2, 3, 1, 0, 1, 1] // INNER
  392. ],
  393. autoDefault: function (name) {return ""},
  394. isSpacelike: function () {return false},
  395. isEmbellished: function () {return false},
  396. Core: function () {return this},
  397. CoreMO: function () {return this},
  398. childIndex: function(child) {
  399. if (child == null) return;
  400. for (var i = 0, m = this.data.length; i < m; i++) if (child === this.data[i]) return i;
  401. },
  402. CoreIndex: function () {
  403. return (this.inferRow ? this.data[0]||this : this).childIndex(this.Core());
  404. },
  405. hasNewline: function () {
  406. if (this.isEmbellished()) {return this.CoreMO().hasNewline()}
  407. if (this.isToken || this.linebreakContainer) {return false}
  408. for (var i = 0, m = this.data.length; i < m; i++) {
  409. if (this.data[i] && this.data[i].hasNewline()) {return true}
  410. }
  411. return false;
  412. },
  413. array: function () {if (this.inferred) {return this.data} else {return [this]}},
  414. toString: function () {return this.type+"("+this.data.join(",")+")"},
  415. getAnnotation: function () {return null}
  416. },{
  417. childrenSpacelike: function () {
  418. for (var i = 0, m = this.data.length; i < m; i++)
  419. {if (!this.data[i].isSpacelike()) {return false}}
  420. return true;
  421. },
  422. childEmbellished: function () {
  423. return (this.data[0] && this.data[0].isEmbellished());
  424. },
  425. childCore: function () {return (this.inferRow && this.data[0] ? this.data[0].Core() : this.data[0])},
  426. childCoreMO: function () {return (this.data[0] ? this.data[0].CoreMO() : null)},
  427. setChildTeXclass: function (prev) {
  428. if (this.data[0]) {
  429. prev = this.data[0].setTeXclass(prev);
  430. this.updateTeXclass(this.data[0]);
  431. }
  432. return prev;
  433. },
  434. setBaseTeXclasses: function (prev) {
  435. this.getPrevClass(prev); this.texClass = null;
  436. if (this.data[0]) {
  437. if (this.isEmbellished() || this.data[0].isa(MML.mi)) {
  438. prev = this.data[0].setTeXclass(prev);
  439. this.updateTeXclass(this.Core());
  440. } else {this.data[0].setTeXclass(); prev = this}
  441. } else {prev = this}
  442. for (var i = 1, m = this.data.length; i < m; i++)
  443. {if (this.data[i]) {this.data[i].setTeXclass()}}
  444. return prev;
  445. },
  446. setSeparateTeXclasses: function (prev) {
  447. this.getPrevClass(prev);
  448. for (var i = 0, m = this.data.length; i < m; i++)
  449. {if (this.data[i]) {this.data[i].setTeXclass()}}
  450. if (this.isEmbellished()) {this.updateTeXclass(this.Core())}
  451. return this;
  452. }
  453. });
  454. MML.mi = MML.mbase.Subclass({
  455. type: "mi", isToken: true,
  456. texClass: MML.TEXCLASS.ORD,
  457. defaults: {
  458. mathvariant: MML.AUTO,
  459. mathsize: MML.INHERIT,
  460. mathbackground: MML.INHERIT,
  461. mathcolor: MML.INHERIT,
  462. dir: MML.INHERIT
  463. },
  464. autoDefault: function (name) {
  465. if (name === "mathvariant") {
  466. var mi = (this.data[0]||"").toString();
  467. return (mi.length === 1 ||
  468. (mi.length === 2 && mi.charCodeAt(0) >= 0xD800 && mi.charCodeAt(0) < 0xDC00) ?
  469. MML.VARIANT.ITALIC : MML.VARIANT.NORMAL);
  470. }
  471. return "";
  472. },
  473. setTeXclass: function (prev) {
  474. this.getPrevClass(prev);
  475. var name = this.data.join("");
  476. if (name.length > 1 && name.match(/^[a-z][a-z0-9]*$/i) &&
  477. this.texClass === MML.TEXCLASS.ORD) {
  478. this.texClass = MML.TEXCLASS.OP;
  479. this.autoOP = true;
  480. }
  481. return this;
  482. }
  483. });
  484. MML.mn = MML.mbase.Subclass({
  485. type: "mn", isToken: true,
  486. texClass: MML.TEXCLASS.ORD,
  487. defaults: {
  488. mathvariant: MML.INHERIT,
  489. mathsize: MML.INHERIT,
  490. mathbackground: MML.INHERIT,
  491. mathcolor: MML.INHERIT,
  492. dir: MML.INHERIT
  493. }
  494. });
  495. MML.mo = MML.mbase.Subclass({
  496. type: "mo", isToken: true,
  497. defaults: {
  498. mathvariant: MML.INHERIT,
  499. mathsize: MML.INHERIT,
  500. mathbackground: MML.INHERIT,
  501. mathcolor: MML.INHERIT,
  502. dir: MML.INHERIT,
  503. form: MML.AUTO,
  504. fence: MML.AUTO,
  505. separator: MML.AUTO,
  506. lspace: MML.AUTO,
  507. rspace: MML.AUTO,
  508. stretchy: MML.AUTO,
  509. symmetric: MML.AUTO,
  510. maxsize: MML.AUTO,
  511. minsize: MML.AUTO,
  512. largeop: MML.AUTO,
  513. movablelimits: MML.AUTO,
  514. accent: MML.AUTO,
  515. linebreak: MML.LINEBREAK.AUTO,
  516. lineleading: MML.INHERIT,
  517. linebreakstyle: MML.AUTO,
  518. linebreakmultchar: MML.INHERIT,
  519. indentalign: MML.INHERIT,
  520. indentshift: MML.INHERIT,
  521. indenttarget: MML.INHERIT,
  522. indentalignfirst: MML.INHERIT,
  523. indentshiftfirst: MML.INHERIT,
  524. indentalignlast: MML.INHERIT,
  525. indentshiftlast: MML.INHERIT,
  526. texClass: MML.AUTO
  527. },
  528. defaultDef: {
  529. form: MML.FORM.INFIX,
  530. fence: false,
  531. separator: false,
  532. lspace: MML.LENGTH.THICKMATHSPACE,
  533. rspace: MML.LENGTH.THICKMATHSPACE,
  534. stretchy: false,
  535. symmetric: false,
  536. maxsize: MML.SIZE.INFINITY,
  537. minsize: '0em', //'1em',
  538. largeop: false,
  539. movablelimits: false,
  540. accent: false,
  541. linebreak: MML.LINEBREAK.AUTO,
  542. lineleading: "1ex",
  543. linebreakstyle: "before",
  544. indentalign: MML.INDENTALIGN.AUTO,
  545. indentshift: "0",
  546. indenttarget: "",
  547. indentalignfirst: MML.INDENTALIGN.INDENTALIGN,
  548. indentshiftfirst: MML.INDENTSHIFT.INDENTSHIFT,
  549. indentalignlast: MML.INDENTALIGN.INDENTALIGN,
  550. indentshiftlast: MML.INDENTSHIFT.INDENTSHIFT,
  551. texClass: MML.TEXCLASS.REL // for MML, but TeX sets ORD explicitly
  552. },
  553. SPACE_ATTR: {lspace: 0x01, rspace: 0x02, form: 0x04},
  554. useMMLspacing: 0x07,
  555. autoDefault: function (name,nodefault) {
  556. var def = this.def;
  557. if (!def) {
  558. if (name === "form") {this.useMMLspacing &= ~this.SPACE_ATTR.form; return this.getForm()}
  559. var mo = this.data.join("");
  560. var forms = [this.Get("form"),MML.FORM.INFIX,MML.FORM.POSTFIX,MML.FORM.PREFIX];
  561. for (var i = 0, m = forms.length; i < m; i++) {
  562. var data = this.OPTABLE[forms[i]][mo];
  563. if (data) {def = this.makeDef(data); break}
  564. }
  565. if (!def) {def = this.CheckRange(mo)}
  566. if (!def && nodefault) {def = {}} else {
  567. if (!def) {def = MathJax.Hub.Insert({},this.defaultDef)}
  568. if (this.parent) {this.def = def} else {def = MathJax.Hub.Insert({},def)}
  569. def.form = forms[0];
  570. }
  571. }
  572. this.useMMLspacing &= ~(this.SPACE_ATTR[name] || 0);
  573. if (def[name] != null) {return def[name]}
  574. else if (!nodefault) {return this.defaultDef[name]}
  575. return "";
  576. },
  577. CheckRange: function (mo) {
  578. var n = mo.charCodeAt(0);
  579. if (n >= 0xD800 && n < 0xDC00) {n = (((n-0xD800)<<10)+(mo.charCodeAt(1)-0xDC00))+0x10000}
  580. for (var i = 0, m = this.RANGES.length; i < m && this.RANGES[i][0] <= n; i++) {
  581. if (n <= this.RANGES[i][1]) {
  582. if (this.RANGES[i][3]) {
  583. var file = MML.optableDir+"/"+this.RANGES[i][3]+".js";
  584. this.RANGES[i][3] = null;
  585. MathJax.Hub.RestartAfter(MathJax.Ajax.Require(file));
  586. }
  587. var data = MML.TEXCLASSNAMES[this.RANGES[i][2]];
  588. data = this.OPTABLE.infix[mo] = MML.mo.OPTYPES[data === "BIN" ? "BIN3" : data];
  589. return this.makeDef(data);
  590. }
  591. }
  592. return null;
  593. },
  594. makeDef: function (data) {
  595. if (data[2] == null) {data[2] = this.defaultDef.texClass}
  596. if (!data[3]) {data[3] = {}}
  597. var def = MathJax.Hub.Insert({},data[3]);
  598. def.lspace = this.SPACE[data[0]]; def.rspace = this.SPACE[data[1]];
  599. def.texClass = data[2];
  600. if (def.texClass === MML.TEXCLASS.REL &&
  601. (this.movablelimits || this.data.join("").match(/^[a-z]+$/i)))
  602. {def.texClass = MML.TEXCLASS.OP} // mark named operators as OP
  603. return def;
  604. },
  605. getForm: function () {
  606. var core = this, parent = this.parent, Parent = this.Parent();
  607. while (Parent && Parent.isEmbellished())
  608. {core = parent; parent = Parent.parent; Parent = Parent.Parent()}
  609. if (parent && parent.type === "mrow" && parent.NonSpaceLength() !== 1) {
  610. if (parent.FirstNonSpace() === core) {return MML.FORM.PREFIX}
  611. if (parent.LastNonSpace() === core) {return MML.FORM.POSTFIX}
  612. }
  613. return MML.FORM.INFIX;
  614. },
  615. isEmbellished: function () {return true},
  616. hasNewline: function () {return (this.Get("linebreak") === MML.LINEBREAK.NEWLINE)},
  617. CoreParent: function () {
  618. var parent = this;
  619. while (parent && parent.isEmbellished() &&
  620. parent.CoreMO() === this && !parent.isa(MML.math)) {parent = parent.Parent()}
  621. return parent;
  622. },
  623. CoreText: function (parent) {
  624. if (!parent) {return ""}
  625. if (parent.isEmbellished()) {return parent.CoreMO().data.join("")}
  626. while ((((parent.isa(MML.mrow) || parent.isa(MML.TeXAtom) ||
  627. parent.isa(MML.mstyle) || parent.isa(MML.mphantom)) &&
  628. parent.data.length === 1) || parent.isa(MML.munderover)) &&
  629. parent.data[0]) {parent = parent.data[0]}
  630. if (!parent.isToken) {return ""} else {return parent.data.join("")}
  631. },
  632. remapChars: {
  633. '*':"\u2217",
  634. '"':"\u2033",
  635. "\u00B0":"\u2218",
  636. "\u00B2":"2",
  637. "\u00B3":"3",
  638. "\u00B4":"\u2032",
  639. "\u00B9":"1"
  640. },
  641. remap: function (text,map) {
  642. text = text.replace(/-/g,"\u2212");
  643. if (map) {
  644. text = text.replace(/'/g,"\u2032").replace(/`/g,"\u2035");
  645. if (text.length === 1) {text = map[text]||text}
  646. }
  647. return text;
  648. },
  649. setTeXclass: function (prev) {
  650. var values = this.getValues("form","lspace","rspace","fence"); // sets useMMLspacing
  651. if (this.useMMLspacing) {this.texClass = MML.TEXCLASS.NONE; return this}
  652. if (values.fence && !this.texClass) {
  653. if (values.form === MML.FORM.PREFIX) {this.texClass = MML.TEXCLASS.OPEN}
  654. if (values.form === MML.FORM.POSTFIX) {this.texClass = MML.TEXCLASS.CLOSE}
  655. }
  656. this.texClass = this.Get("texClass");
  657. if (this.data.join("") === "\u2061") {
  658. // force previous node to be texClass OP, and skip this node
  659. if (prev) {prev.texClass = MML.TEXCLASS.OP; prev.fnOP = true}
  660. this.texClass = this.prevClass = MML.TEXCLASS.NONE;
  661. return prev;
  662. }
  663. return this.adjustTeXclass(prev);
  664. },
  665. adjustTeXclass: function (prev) {
  666. if (this.texClass === MML.TEXCLASS.NONE) {return prev}
  667. if (prev) {
  668. if (prev.autoOP && (this.texClass === MML.TEXCLASS.BIN ||
  669. this.texClass === MML.TEXCLASS.REL))
  670. {prev.texClass = MML.TEXCLASS.ORD}
  671. this.prevClass = prev.texClass || MML.TEXCLASS.ORD;
  672. this.prevLevel = prev.Get("scriptlevel")
  673. } else {this.prevClass = MML.TEXCLASS.NONE}
  674. if (this.texClass === MML.TEXCLASS.BIN &&
  675. (this.prevClass === MML.TEXCLASS.NONE ||
  676. this.prevClass === MML.TEXCLASS.BIN ||
  677. this.prevClass === MML.TEXCLASS.OP ||
  678. this.prevClass === MML.TEXCLASS.REL ||
  679. this.prevClass === MML.TEXCLASS.OPEN ||
  680. this.prevClass === MML.TEXCLASS.PUNCT)) {
  681. this.texClass = MML.TEXCLASS.ORD;
  682. } else if (this.prevClass === MML.TEXCLASS.BIN &&
  683. (this.texClass === MML.TEXCLASS.REL ||
  684. this.texClass === MML.TEXCLASS.CLOSE ||
  685. this.texClass === MML.TEXCLASS.PUNCT)) {
  686. prev.texClass = this.prevClass = MML.TEXCLASS.ORD;
  687. } else if (this.texClass === MML.TEXCLASS.BIN) {
  688. //
  689. // Check if node is the last one in its container since the rule
  690. // above only takes effect if there is a node that follows.
  691. //
  692. var child = this, parent = this.parent;
  693. while (parent && parent.parent && parent.isEmbellished() &&
  694. (parent.data.length === 1 ||
  695. (parent.type !== "mrow" && parent.Core() === child))) // handles msubsup and munderover
  696. {child = parent; parent = parent.parent}
  697. if (parent.data[parent.data.length-1] === child) this.texClass = MML.TEXCLASS.ORD;
  698. }
  699. return this;
  700. }
  701. });
  702. MML.mtext = MML.mbase.Subclass({
  703. type: "mtext", isToken: true,
  704. isSpacelike: function () {return true},
  705. texClass: MML.TEXCLASS.ORD,
  706. defaults: {
  707. mathvariant: MML.INHERIT,
  708. mathsize: MML.INHERIT,
  709. mathbackground: MML.INHERIT,
  710. mathcolor: MML.INHERIT,
  711. dir: MML.INHERIT
  712. }
  713. });
  714. MML.mspace = MML.mbase.Subclass({
  715. type: "mspace", isToken: true,
  716. isSpacelike: function () {return true},
  717. defaults: {
  718. mathbackground: MML.INHERIT,
  719. mathcolor: MML.INHERIT,
  720. width: "0em",
  721. height: "0ex",
  722. depth: "0ex",
  723. linebreak: MML.LINEBREAK.AUTO
  724. },
  725. hasDimAttr: function () {
  726. return (this.hasValue("width") || this.hasValue("height") ||
  727. this.hasValue("depth"));
  728. },
  729. hasNewline: function () {
  730. // The MathML spec says that the linebreak attribute should be ignored
  731. // if any dimensional attribute is set.
  732. return (!this.hasDimAttr() &&
  733. this.Get("linebreak") === MML.LINEBREAK.NEWLINE);
  734. }
  735. });
  736. MML.ms = MML.mbase.Subclass({
  737. type: "ms", isToken: true,
  738. texClass: MML.TEXCLASS.ORD,
  739. defaults: {
  740. mathvariant: MML.INHERIT,
  741. mathsize: MML.INHERIT,
  742. mathbackground: MML.INHERIT,
  743. mathcolor: MML.INHERIT,
  744. dir: MML.INHERIT,
  745. lquote: '"',
  746. rquote: '"'
  747. }
  748. });
  749. MML.mglyph = MML.mbase.Subclass({
  750. type: "mglyph", isToken: true,
  751. texClass: MML.TEXCLASS.ORD,
  752. defaults: {
  753. mathbackground: MML.INHERIT,
  754. mathcolor: MML.INHERIT,
  755. alt: "",
  756. src: "",
  757. width: MML.AUTO,
  758. height: MML.AUTO,
  759. valign: "0em"
  760. }
  761. });
  762. MML.mrow = MML.mbase.Subclass({
  763. type: "mrow",
  764. isSpacelike: MML.mbase.childrenSpacelike,
  765. inferred: false, notParent: false,
  766. isEmbellished: function () {
  767. var isEmbellished = false;
  768. for (var i = 0, m = this.data.length; i < m; i++) {
  769. if (this.data[i] == null) continue;
  770. if (this.data[i].isEmbellished()) {
  771. if (isEmbellished) {return false}
  772. isEmbellished = true; this.core = i;
  773. } else if (!this.data[i].isSpacelike()) {return false}
  774. }
  775. return isEmbellished;
  776. },
  777. NonSpaceLength: function () {
  778. var n = 0;
  779. for (var i = 0, m = this.data.length; i < m; i++)
  780. {if (this.data[i] && !this.data[i].isSpacelike()) {n++}}
  781. return n;
  782. },
  783. FirstNonSpace: function () {
  784. for (var i = 0, m = this.data.length; i < m; i++)
  785. {if (this.data[i] && !this.data[i].isSpacelike()) {return this.data[i]}}
  786. return null;
  787. },
  788. LastNonSpace: function () {
  789. for (var i = this.data.length-1; i >= 0; i--)
  790. {if (this.data[0] && !this.data[i].isSpacelike()) {return this.data[i]}}
  791. return null;
  792. },
  793. Core: function () {
  794. if (!(this.isEmbellished()) || typeof(this.core) === "undefined") {return this}
  795. return this.data[this.core];
  796. },
  797. CoreMO: function () {
  798. if (!(this.isEmbellished()) || typeof(this.core) === "undefined") {return this}
  799. return this.data[this.core].CoreMO();
  800. },
  801. toString: function () {
  802. if (this.inferred) {return '[' + this.data.join(',') + ']'}
  803. return this.SUPER(arguments).toString.call(this);
  804. },
  805. setTeXclass: function (prev) {
  806. var i, m = this.data.length;
  807. if ((this.open || this.close) && (!prev || !prev.fnOP)) {
  808. //
  809. // <mrow> came from \left...\right
  810. // so treat as subexpression (tex class INNER)
  811. //
  812. this.getPrevClass(prev); prev = null;
  813. for (i = 0; i < m; i++)
  814. {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}}
  815. if (!this.hasOwnProperty("texClass")) this.texClass = MML.TEXCLASS.INNER;
  816. return this;
  817. } else {
  818. //
  819. // Normal <mrow>, so treat as
  820. // thorugh mrow is not there
  821. //
  822. for (i = 0; i < m; i++)
  823. {if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}}
  824. if (this.data[0]) {this.updateTeXclass(this.data[0])}
  825. return prev;
  826. }
  827. },
  828. getAnnotation: function (name) {
  829. if (this.data.length != 1) return null;
  830. return this.data[0].getAnnotation(name);
  831. }
  832. });
  833. MML.mfrac = MML.mbase.Subclass({
  834. type: "mfrac", num: 0, den: 1,
  835. linebreakContainer: true,
  836. isEmbellished: MML.mbase.childEmbellished,
  837. Core: MML.mbase.childCore,
  838. CoreMO: MML.mbase.childCoreMO,
  839. defaults: {
  840. mathbackground: MML.INHERIT,
  841. mathcolor: MML.INHERIT,
  842. linethickness: MML.LINETHICKNESS.MEDIUM,
  843. numalign: MML.ALIGN.CENTER,
  844. denomalign: MML.ALIGN.CENTER,
  845. bevelled: false
  846. },
  847. adjustChild_displaystyle: function (n) {return false},
  848. adjustChild_scriptlevel: function (n) {
  849. var level = this.Get("scriptlevel");
  850. if (!this.Get("displaystyle") || level > 0) {level++}
  851. return level;
  852. },
  853. adjustChild_texprimestyle: function (n) {
  854. if (n == this.den) {return true}
  855. return this.Get("texprimestyle");
  856. },
  857. setTeXclass: MML.mbase.setSeparateTeXclasses
  858. });
  859. MML.msqrt = MML.mbase.Subclass({
  860. type: "msqrt",
  861. inferRow: true,
  862. linebreakContainer: true,
  863. texClass: MML.TEXCLASS.ORD,
  864. setTeXclass: MML.mbase.setSeparateTeXclasses,
  865. adjustChild_texprimestyle: function (n) {return true}
  866. });
  867. MML.mroot = MML.mbase.Subclass({
  868. type: "mroot",
  869. linebreakContainer: true,
  870. texClass: MML.TEXCLASS.ORD,
  871. adjustChild_displaystyle: function (n) {
  872. if (n === 1) {return false}
  873. return this.Get("displaystyle");
  874. },
  875. adjustChild_scriptlevel: function (n) {
  876. var level = this.Get("scriptlevel");
  877. if (n === 1) {level += 2}
  878. return level;
  879. },
  880. adjustChild_texprimestyle: function (n) {
  881. if (n === 0) {return true};
  882. return this.Get("texprimestyle");
  883. },
  884. setTeXclass: MML.mbase.setSeparateTeXclasses
  885. });
  886. MML.mstyle = MML.mbase.Subclass({
  887. type: "mstyle",
  888. isSpacelike: MML.mbase.childrenSpacelike,
  889. isEmbellished: MML.mbase.childEmbellished,
  890. Core: MML.mbase.childCore,
  891. CoreMO: MML.mbase.childCoreMO,
  892. inferRow: true,
  893. defaults: {
  894. scriptlevel: MML.INHERIT,
  895. displaystyle: MML.INHERIT,
  896. scriptsizemultiplier: Math.sqrt(1/2),
  897. scriptminsize: "8pt",
  898. mathbackground: MML.INHERIT,
  899. mathcolor: MML.INHERIT,
  900. dir: MML.INHERIT,
  901. infixlinebreakstyle: MML.LINEBREAKSTYLE.BEFORE,
  902. decimalseparator: "."
  903. },
  904. adjustChild_scriptlevel: function (n) {
  905. var level = this.scriptlevel;
  906. if (level == null) {
  907. level = this.Get("scriptlevel");
  908. } else if (String(level).match(/^ *[-+]/)) {
  909. var LEVEL = this.Get("scriptlevel",null,true);
  910. level = LEVEL + parseInt(level);
  911. }
  912. return level;
  913. },
  914. inheritFromMe: true,
  915. noInherit: {
  916. mpadded: {width: true, height: true, depth: true, lspace: true, voffset: true},
  917. mtable: {width: true, height: true, depth: true, align: true}
  918. },
  919. getRemoved: {fontfamily:"fontFamily", fontweight:"fontWeight", fontstyle:"fontStyle", fontsize:"fontSize"},
  920. setTeXclass: MML.mbase.setChildTeXclass
  921. });
  922. MML.merror = MML.mbase.Subclass({
  923. type: "merror",
  924. inferRow: true,
  925. linebreakContainer: true,
  926. texClass: MML.TEXCLASS.ORD
  927. });
  928. MML.mpadded = MML.mbase.Subclass({
  929. type: "mpadded",
  930. inferRow: true,
  931. isSpacelike: MML.mbase.childrenSpacelike,
  932. isEmbellished: MML.mbase.childEmbellished,
  933. Core: MML.mbase.childCore,
  934. CoreMO: MML.mbase.childCoreMO,
  935. defaults: {
  936. mathbackground: MML.INHERIT,
  937. mathcolor: MML.INHERIT,
  938. width: "",
  939. height: "",
  940. depth: "",
  941. lspace: 0,
  942. voffset: 0
  943. },
  944. setTeXclass: MML.mbase.setChildTeXclass
  945. });
  946. MML.mphantom = MML.mbase.Subclass({
  947. type: "mphantom",
  948. texClass: MML.TEXCLASS.ORD,
  949. inferRow: true,
  950. isSpacelike: MML.mbase.childrenSpacelike,
  951. isEmbellished: MML.mbase.childEmbellished,
  952. Core: MML.mbase.childCore,
  953. CoreMO: MML.mbase.childCoreMO,
  954. setTeXclass: MML.mbase.setChildTeXclass
  955. });
  956. MML.mfenced = MML.mbase.Subclass({
  957. type: "mfenced",
  958. defaults: {
  959. mathbackground: MML.INHERIT,
  960. mathcolor: MML.INHERIT,
  961. open: '(',
  962. close: ')',
  963. separators: ','
  964. },
  965. addFakeNodes: function () {
  966. var values = this.getValues("open","close","separators");
  967. values.open = values.open.replace(/[ \t\n\r]/g,"");
  968. values.close = values.close.replace(/[ \t\n\r]/g,"");
  969. values.separators = values.separators.replace(/[ \t\n\r]/g,"");
  970. //
  971. // Create a fake node for the open item
  972. //
  973. if (values.open !== "") {
  974. this.SetData("open",MML.mo(values.open).With({
  975. fence:true, form:MML.FORM.PREFIX, texClass:MML.TEXCLASS.OPEN
  976. }));
  977. //
  978. // Clear flag for using MML spacing even though form is specified
  979. //
  980. this.data.open.useMMLspacing = 0;
  981. }
  982. //
  983. // Create fake nodes for the separators
  984. //
  985. if (values.separators !== "") {
  986. while (values.separators.length < this.data.length)
  987. {values.separators += values.separators.charAt(values.separators.length-1)}
  988. for (var i = 1, m = this.data.length; i < m; i++) {
  989. if (this.data[i]) {
  990. this.SetData("sep"+i,MML.mo(values.separators.charAt(i-1)).With({separator:true}))
  991. this.data["sep"+i].useMMLspacing = 0;
  992. }
  993. }
  994. }
  995. //
  996. // Create fake node for the close item
  997. //
  998. if (values.close !== "") {
  999. this.SetData("close",MML.mo(values.close).With({
  1000. fence:true, form:MML.FORM.POSTFIX, texClass:MML.TEXCLASS.CLOSE
  1001. }));
  1002. //
  1003. // Clear flag for using MML spacing even though form is specified
  1004. //
  1005. this.data.close.useMMLspacing = 0;
  1006. }
  1007. },
  1008. texClass: MML.TEXCLASS.OPEN,
  1009. setTeXclass: function (prev) {
  1010. this.addFakeNodes();
  1011. this.getPrevClass(prev);
  1012. if (this.data.open) {prev = this.data.open.setTeXclass(prev)}
  1013. if (this.data[0]) {prev = this.data[0].setTeXclass(prev)}
  1014. for (var i = 1, m = this.data.length; i < m; i++) {
  1015. if (this.data["sep"+i]) {prev = this.data["sep"+i].setTeXclass(prev)}
  1016. if (this.data[i]) {prev = this.data[i].setTeXclass(prev)}
  1017. }
  1018. if (this.data.close) {prev = this.data.close.setTeXclass(prev)}
  1019. this.updateTeXclass(this.data.open);
  1020. this.texClass = MML.TEXCLASS.INNER;
  1021. return prev;
  1022. }
  1023. });
  1024. MML.menclose = MML.mbase.Subclass({
  1025. type: "menclose",
  1026. inferRow: true,
  1027. linebreakContainer: true,
  1028. defaults: {
  1029. mathbackground: MML.INHERIT,
  1030. mathcolor: MML.INHERIT,
  1031. notation: MML.NOTATION.LONGDIV,
  1032. texClass: MML.TEXCLASS.ORD
  1033. },
  1034. setTeXclass: MML.mbase.setSeparateTeXclasses
  1035. });
  1036. MML.msubsup = MML.mbase.Subclass({
  1037. type: "msubsup", base: 0, sub: 1, sup: 2,
  1038. isEmbellished: MML.mbase.childEmbellished,
  1039. Core: MML.mbase.childCore,
  1040. CoreMO: MML.mbase.childCoreMO,
  1041. defaults: {
  1042. mathbackground: MML.INHERIT,
  1043. mathcolor: MML.INHERIT,
  1044. subscriptshift: "",
  1045. superscriptshift: "",
  1046. texClass: MML.AUTO
  1047. },
  1048. autoDefault: function (name) {
  1049. if (name === "texClass")
  1050. {return (this.isEmbellished() ? this.CoreMO().Get(name) : MML.TEXCLASS.ORD)}
  1051. return 0;
  1052. },
  1053. adjustChild_displaystyle: function (n) {
  1054. if (n > 0) {return false}
  1055. return this.Get("displaystyle");
  1056. },
  1057. adjustChild_scriptlevel: function (n) {
  1058. var level = this.Get("scriptlevel");
  1059. if (n > 0) {level++}
  1060. return level;
  1061. },
  1062. adjustChild_texprimestyle: function (n) {
  1063. if (n === this.sub) {return true}
  1064. return this.Get("texprimestyle");
  1065. },
  1066. setTeXclass: MML.mbase.setBaseTeXclasses
  1067. });
  1068. MML.msub = MML.msubsup.Subclass({type: "msub"});
  1069. MML.msup = MML.msubsup.Subclass({type: "msup", sub:2, sup:1});
  1070. MML.mmultiscripts = MML.msubsup.Subclass({
  1071. type: "mmultiscripts",
  1072. adjustChild_texprimestyle: function (n) {
  1073. if (n % 2 === 1) {return true}
  1074. return this.Get("texprimestyle");
  1075. }
  1076. });
  1077. MML.mprescripts = MML.mbase.Subclass({type: "mprescripts"});
  1078. MML.none = MML.mbase.Subclass({type: "none"});
  1079. MML.munderover = MML.mbase.Subclass({
  1080. type: "munderover",
  1081. base: 0, under: 1, over: 2, sub: 1, sup: 2,
  1082. ACCENTS: ["", "accentunder", "accent"],
  1083. linebreakContainer: true,
  1084. isEmbellished: MML.mbase.childEmbellished,
  1085. Core: MML.mbase.childCore,
  1086. CoreMO: MML.mbase.childCoreMO,
  1087. defaults: {
  1088. mathbackground: MML.INHERIT,
  1089. mathcolor: MML.INHERIT,
  1090. accent: MML.AUTO,
  1091. accentunder: MML.AUTO,
  1092. align: MML.ALIGN.CENTER,
  1093. texClass: MML.AUTO,
  1094. subscriptshift: "", // when converted to msubsup by moveablelimits
  1095. superscriptshift: "" // when converted to msubsup by moveablelimits
  1096. },
  1097. autoDefault: function (name) {
  1098. if (name === "texClass")
  1099. {return (this.isEmbellished() ? this.CoreMO().Get(name) : MML.TEXCLASS.ORD)}
  1100. if (name === "accent" && this.data[this.over]) {return this.data[this.over].CoreMO().Get("accent")}
  1101. if (name === "accentunder" && this.data[this.under]) {return this.data[this.under].CoreMO().Get("accent")}
  1102. return false;
  1103. },
  1104. adjustChild_displaystyle: function (n) {
  1105. if (n > 0) {return false}
  1106. return this.Get("displaystyle");
  1107. },
  1108. adjustChild_scriptlevel: function (n) {
  1109. var level = this.Get("scriptlevel");
  1110. var force = (this.data[this.base] && !this.Get("displaystyle") &&
  1111. this.data[this.base].CoreMO().Get("movablelimits"));
  1112. if (n == this.under && (force || !this.Get("accentunder"))) {level++}
  1113. if (n == this.over && (force || !this.Get("accent"))) {level++}
  1114. return level;
  1115. },
  1116. adjustChild_texprimestyle: function (n) {
  1117. if (n === this.base && this.data[this.over]) {return true}
  1118. return this.Get("texprimestyle");
  1119. },
  1120. setTeXclass: MML.mbase.setBaseTeXclasses
  1121. });
  1122. MML.munder = MML.munderover.Subclass({type: "munder"});
  1123. MML.mover = MML.munderover.Subclass({
  1124. type: "mover", over: 1, under: 2, sup: 1, sub: 2,
  1125. ACCENTS: ["", "accent", "accentunder"]
  1126. });
  1127. MML.mtable = MML.mbase.Subclass({
  1128. type: "mtable",
  1129. defaults: {
  1130. mathbackground: MML.INHERIT,
  1131. mathcolor: MML.INHERIT,
  1132. align: MML.ALIGN.AXIS,
  1133. rowalign: MML.ALIGN.BASELINE,
  1134. columnalign: MML.ALIGN.CENTER,
  1135. groupalign: "{left}",
  1136. alignmentscope: true,
  1137. columnwidth: MML.WIDTH.AUTO,
  1138. width: MML.WIDTH.AUTO,
  1139. rowspacing: "1ex",
  1140. columnspacing: ".8em",
  1141. rowlines: MML.LINES.NONE,
  1142. columnlines: MML.LINES.NONE,
  1143. frame: MML.LINES.NONE,
  1144. framespacing: "0.4em 0.5ex",
  1145. equalrows: false,
  1146. equalcolumns: false,
  1147. displaystyle: false,
  1148. side: MML.SIDE.RIGHT,
  1149. minlabelspacing: "0.8em",
  1150. texClass: MML.TEXCLASS.ORD,
  1151. useHeight: 1
  1152. },
  1153. adjustChild_displaystyle: function () {
  1154. return (this.displaystyle != null ? this.displaystyle : this.defaults.displaystyle);
  1155. },
  1156. inheritFromMe: true,
  1157. noInherit: {
  1158. mover: {align: true},
  1159. munder: {align: true},
  1160. munderover: {align: true},
  1161. mtable: {
  1162. align: true, rowalign: true, columnalign: true, groupalign: true,
  1163. alignmentscope: true, columnwidth: true, width: true, rowspacing: true,
  1164. columnspacing: true, rowlines: true, columnlines: true, frame: true,
  1165. framespacing: true, equalrows: true, equalcolumns: true, displaystyle: true,
  1166. side: true, minlabelspacing: true, texClass: true, useHeight: 1
  1167. }
  1168. },
  1169. linebreakContainer: true,
  1170. Append: function () {
  1171. for (var i = 0, m = arguments.length; i < m; i++) {
  1172. if (!((arguments[i] instanceof MML.mtr) ||
  1173. (arguments[i] instanceof MML.mlabeledtr))) {arguments[i] = MML.mtr(arguments[i])}
  1174. }
  1175. this.SUPER(arguments).Append.apply(this,arguments);
  1176. },
  1177. setTeXclass: MML.mbase.setSeparateTeXclasses
  1178. });
  1179. MML.mtr = MML.mbase.Subclass({
  1180. type: "mtr",
  1181. defaults: {
  1182. mathbackground: MML.INHERIT,
  1183. mathcolor: MML.INHERIT,
  1184. rowalign: MML.INHERIT,
  1185. columnalign: MML.INHERIT,
  1186. groupalign: MML.INHERIT
  1187. },
  1188. inheritFromMe: true,
  1189. noInherit: {
  1190. mrow: {rowalign: true, columnalign: true, groupalign: true},
  1191. mtable: {rowalign: true, columnalign: true, groupalign: true}
  1192. },
  1193. linebreakContainer: true,
  1194. Append: function () {
  1195. for (var i = 0, m = arguments.length; i < m; i++) {
  1196. if (!(arguments[i] instanceof MML.mtd)) {arguments[i] = MML.mtd(arguments[i])}
  1197. }
  1198. this.SUPER(arguments).Append.apply(this,arguments);
  1199. },
  1200. setTeXclass: MML.mbase.setSeparateTeXclasses
  1201. });
  1202. MML.mtd = MML.mbase.Subclass({
  1203. type: "mtd",
  1204. inferRow: true,
  1205. linebreakContainer: true,
  1206. isEmbellished: MML.mbase.childEmbellished,
  1207. Core: MML.mbase.childCore,
  1208. CoreMO: MML.mbase.childCoreMO,
  1209. defaults: {
  1210. mathbackground: MML.INHERIT,
  1211. mathcolor: MML.INHERIT,
  1212. rowspan: 1,
  1213. columnspan: 1,
  1214. rowalign: MML.INHERIT,
  1215. columnalign: MML.INHERIT,
  1216. groupalign: MML.INHERIT
  1217. },
  1218. setTeXclass: MML.mbase.setSeparateTeXclasses
  1219. });
  1220. MML.maligngroup = MML.mbase.Subclass({
  1221. type: "maligngroup",
  1222. isSpacelike: function () {return true},
  1223. defaults: {
  1224. mathbackground: MML.INHERIT,
  1225. mathcolor: MML.INHERIT,
  1226. groupalign: MML.INHERIT
  1227. },
  1228. inheritFromMe: true,
  1229. noInherit: {
  1230. mrow: {groupalign: true},
  1231. mtable: {groupalign: true}
  1232. }
  1233. });
  1234. MML.malignmark = MML.mbase.Subclass({
  1235. type: "malignmark",
  1236. defaults: {
  1237. mathbackground: MML.INHERIT,
  1238. mathcolor: MML.INHERIT,
  1239. edge: MML.SIDE.LEFT
  1240. },
  1241. isSpacelike: function () {return true}
  1242. });
  1243. MML.mlabeledtr = MML.mtr.Subclass({
  1244. type: "mlabeledtr"
  1245. });
  1246. MML.maction = MML.mbase.Subclass({
  1247. type: "maction",
  1248. defaults: {
  1249. mathbackground: MML.INHERIT,
  1250. mathcolor: MML.INHERIT,
  1251. actiontype: MML.ACTIONTYPE.TOGGLE,
  1252. selection: 1
  1253. },
  1254. selected: function () {return this.data[this.Get("selection")-1] || MML.NULL},
  1255. isEmbellished: function () {return this.selected().isEmbellished()},
  1256. isSpacelike: function () {return this.selected().isSpacelike()},
  1257. Core: function () {return this.selected().Core()},
  1258. CoreMO: function () {return this.selected().CoreMO()},
  1259. setTeXclass: function (prev) {
  1260. if (this.Get("actiontype") === MML.ACTIONTYPE.TOOLTIP && this.data[1]) {
  1261. // Make sure tooltip has proper spacing when typeset (see issue #412)
  1262. this.data[1].setTeXclass();
  1263. }
  1264. var selected = this.selected();
  1265. prev = selected.setTeXclass(prev);
  1266. this.updateTeXclass(selected);
  1267. return prev;
  1268. }
  1269. });
  1270. MML.semantics = MML.mbase.Subclass({
  1271. type: "semantics", notParent: true,
  1272. isEmbellished: MML.mbase.childEmbellished,
  1273. Core: MML.mbase.childCore,
  1274. CoreMO: MML.mbase.childCoreMO,
  1275. defaults: {
  1276. definitionURL: null,
  1277. encoding: null
  1278. },
  1279. setTeXclass: MML.mbase.setChildTeXclass,
  1280. getAnnotation: function (name) {
  1281. var encodingList = MathJax.Hub.config.MathMenu.semanticsAnnotations[name];
  1282. if (encodingList) {
  1283. for (var i = 0, m = this.data.length; i < m; i++) {
  1284. var encoding = this.data[i].Get("encoding");
  1285. if (encoding) {
  1286. for (var j = 0, n = encodingList.length; j < n; j++) {
  1287. if (encodingList[j] === encoding) return this.data[i];
  1288. }
  1289. }
  1290. }
  1291. }
  1292. return null;
  1293. }
  1294. });
  1295. MML.annotation = MML.mbase.Subclass({
  1296. type: "annotation", isChars: true,
  1297. linebreakContainer: true,
  1298. defaults: {
  1299. definitionURL: null,
  1300. encoding: null,
  1301. cd: "mathmlkeys",
  1302. name: "",
  1303. src: null
  1304. }
  1305. });
  1306. MML["annotation-xml"] = MML.mbase.Subclass({
  1307. type: "annotation-xml",
  1308. linebreakContainer: true,
  1309. defaults: {
  1310. definitionURL: null,
  1311. encoding: null,
  1312. cd: "mathmlkeys",
  1313. name: "",
  1314. src: null
  1315. }
  1316. });
  1317. MML.math = MML.mstyle.Subclass({
  1318. type: "math",
  1319. defaults: {
  1320. mathvariant: MML.VARIANT.NORMAL,
  1321. mathsize: MML.SIZE.NORMAL,
  1322. mathcolor: "", // should be "black", but allow it to inherit from surrounding text
  1323. mathbackground: MML.COLOR.TRANSPARENT,
  1324. dir: "ltr",
  1325. scriptlevel: 0,
  1326. displaystyle: MML.AUTO,
  1327. display: "inline",
  1328. maxwidth: "",
  1329. overflow: MML.OVERFLOW.LINEBREAK,
  1330. altimg: "",
  1331. 'altimg-width': "",
  1332. 'altimg-height': "",
  1333. 'altimg-valign': "",
  1334. alttext: "",
  1335. cdgroup: "",
  1336. scriptsizemultiplier: Math.sqrt(1/2),
  1337. scriptminsize: "8px", // should be 8pt, but that's too big
  1338. infixlinebreakstyle: MML.LINEBREAKSTYLE.BEFORE,
  1339. lineleading: "1ex",
  1340. indentshift: "auto", // use user configuration
  1341. indentalign: MML.INDENTALIGN.AUTO,
  1342. indentalignfirst: MML.INDENTALIGN.INDENTALIGN,
  1343. indentshiftfirst: MML.INDENTSHIFT.INDENTSHIFT,
  1344. indentalignlast: MML.INDENTALIGN.INDENTALIGN,
  1345. indentshiftlast: MML.INDENTSHIFT.INDENTSHIFT,
  1346. decimalseparator: ".",
  1347. texprimestyle: false // is it in TeX's C' style?
  1348. },
  1349. autoDefault: function (name) {
  1350. if (name === "displaystyle") {return this.Get("display") === "block"}
  1351. return "";
  1352. },
  1353. linebreakContainer: true,
  1354. setTeXclass: MML.mbase.setChildTeXclass,
  1355. getAnnotation: function (name) {
  1356. if (this.data.length != 1) return null;
  1357. return this.data[0].getAnnotation(name);
  1358. }
  1359. });
  1360. MML.chars = MML.mbase.Subclass({
  1361. type: "chars",
  1362. Append: function () {this.data.push.apply(this.data,arguments)},
  1363. value: function () {return this.data.join("")},
  1364. toString: function () {return this.data.join("")}
  1365. });
  1366. MML.entity = MML.mbase.Subclass({
  1367. type: "entity",
  1368. Append: function () {this.data.push.apply(this.data,arguments)},
  1369. value: function () {
  1370. if (this.data[0].substr(0,2) === "#x") {return parseInt(this.data[0].substr(2),16)}
  1371. else if (this.data[0].substr(0,1) === "#") {return parseInt(this.data[0].substr(1))}
  1372. else {return 0} // FIXME: look up named entities from table
  1373. },
  1374. toString: function () {
  1375. var n = this.value();
  1376. if (n <= 0xFFFF) {return String.fromCharCode(n)}
  1377. n -= 0x10000;
  1378. return String.fromCharCode((n>>10)+0xD800)
  1379. + String.fromCharCode((n&0x3FF)+0xDC00);
  1380. }
  1381. });
  1382. MML.xml = MML.mbase.Subclass({
  1383. type: "xml",
  1384. Init: function () {
  1385. this.div = document.createElement("div");
  1386. return this.SUPER(arguments).Init.apply(this,arguments);
  1387. },
  1388. Append: function () {
  1389. for (var i = 0, m = arguments.length; i < m; i++) {
  1390. var node = this.Import(arguments[i]);
  1391. this.data.push(node);
  1392. this.div.appendChild(node);
  1393. }
  1394. },
  1395. Import: function (node) {
  1396. if (document.importNode) {return document.importNode(node,true)}
  1397. //
  1398. // IE < 9 doesn't have importNode, so fake it.
  1399. //
  1400. var nNode, i, m;
  1401. if (node.nodeType === 1) { // ELEMENT_NODE
  1402. nNode = document.createElement(node.nodeName);
  1403. for (i = 0, m = node.attributes.length; i < m; i++) {
  1404. var attribute = node.attributes[i];
  1405. if (attribute.specified && attribute.nodeValue != null && attribute.nodeValue != '')
  1406. {nNode.setAttribute(attribute.nodeName,attribute.nodeValue)}
  1407. if (attribute.nodeName === "style") {nNode.style.cssText = attribute.nodeValue}
  1408. }
  1409. if (node.className) {nNode.className = node.className}
  1410. } else if (node.nodeType === 3 || node.nodeType === 4) { // TEXT_NODE or CDATA_SECTION_NODE
  1411. nNode = document.createTextNode(node.nodeValue);
  1412. } else if (node.nodeType === 8) { // COMMENT_NODE
  1413. nNode = document.createComment(node.nodeValue);
  1414. } else {
  1415. return document.createTextNode('');
  1416. }
  1417. for (i = 0, m = node.childNodes.length; i < m; i++)
  1418. {nNode.appendChild(this.Import(node.childNodes[i]))}
  1419. return nNode;
  1420. },
  1421. value: function () {return this.div},
  1422. toString: function () {return this.div.innerHTML}
  1423. });
  1424. MML.TeXAtom = MML.mbase.Subclass({
  1425. type: "texatom",
  1426. linebreakContainer: true,
  1427. inferRow: true, notParent: true,
  1428. texClass: MML.TEXCLASS.ORD,
  1429. Core: MML.mbase.childCore,
  1430. CoreMO: MML.mbase.childCoreMO,
  1431. isEmbellished: MML.mbase.childEmbellished,
  1432. setTeXclass: function (prev) {
  1433. this.data[0].setTeXclass();
  1434. return this.adjustTeXclass(prev);
  1435. },
  1436. adjustTeXclass: MML.mo.prototype.adjustTeXclass
  1437. });
  1438. MML.NULL = MML.mbase().With({type:"null"});
  1439. var TEXCLASS = MML.TEXCLASS;
  1440. var MO = {
  1441. ORD: [0,0,TEXCLASS.ORD],
  1442. ORD11: [1,1,TEXCLASS.ORD],
  1443. ORD21: [2,1,TEXCLASS.ORD],
  1444. ORD02: [0,2,TEXCLASS.ORD],
  1445. ORD55: [5,5,TEXCLASS.ORD],
  1446. OP: [1,2,TEXCLASS.OP,{largeop: true, movablelimits: true, symmetric: true}],
  1447. OPFIXED: [1,2,TEXCLASS.OP,{largeop: true, movablelimits: true}],
  1448. INTEGRAL: [0,1,TEXCLASS.OP,{largeop: true, symmetric: true}],
  1449. INTEGRAL2: [1,2,TEXCLASS.OP,{largeop: true, symmetric: true}],
  1450. BIN3: [3,3,TEXCLASS.BIN],
  1451. BIN4: [4,4,TEXCLASS.BIN],
  1452. BIN01: [0,1,TEXCLASS.BIN],
  1453. BIN5: [5,5,TEXCLASS.BIN],
  1454. TALLBIN: [4,4,TEXCLASS.BIN,{stretchy: true}],
  1455. BINOP: [4,4,TEXCLASS.BIN,{largeop: true, movablelimits: true}],
  1456. REL: [5,5,TEXCLASS.REL],
  1457. REL1: [1,1,TEXCLASS.REL,{stretchy: true}],
  1458. REL4: [4,4,TEXCLASS.REL],
  1459. RELSTRETCH: [5,5,TEXCLASS.REL,{stretchy: true}],
  1460. RELACCENT: [5,5,TEXCLASS.REL,{accent: true}],
  1461. WIDEREL: [5,5,TEXCLASS.REL,{accent: true, stretchy: true}],
  1462. OPEN: [0,0,TEXCLASS.OPEN,{fence: true, stretchy: true, symmetric: true}],
  1463. CLOSE: [0,0,TEXCLASS.CLOSE,{fence: true, stretchy: true, symmetric: true}],
  1464. INNER: [0,0,TEXCLASS.INNER],
  1465. PUNCT: [0,3,TEXCLASS.PUNCT],
  1466. ACCENT: [0,0,TEXCLASS.ORD,{accent: true}],
  1467. WIDEACCENT: [0,0,TEXCLASS.ORD,{accent: true, stretchy: true}]
  1468. };
  1469. MML.mo.Augment({
  1470. SPACE: [
  1471. '0em',
  1472. '0.1111em',
  1473. '0.1667em',
  1474. '0.2222em',
  1475. '0.2667em',
  1476. '0.3333em'
  1477. ],
  1478. RANGES: [
  1479. [0x20,0x7F,TEXCLASS.REL,"BasicLatin"],
  1480. [0xA0,0xFF,TEXCLASS.ORD,"Latin1Supplement"],
  1481. [0x100,0x17F,TEXCLASS.ORD],
  1482. [0x180,0x24F,TEXCLASS.ORD],
  1483. [0x2B0,0x2FF,TEXCLASS.ORD,"SpacingModLetters"],
  1484. [0x300,0x36F,TEXCLASS.ORD,"CombDiacritMarks"],
  1485. [0x370,0x3FF,TEXCLASS.ORD,"GreekAndCoptic"],
  1486. [0x1E00,0x1EFF,TEXCLASS.ORD],
  1487. [0x2000,0x206F,TEXCLASS.PUNCT,"GeneralPunctuation"],
  1488. [0x2070,0x209F,TEXCLASS.ORD],
  1489. [0x20A0,0x20CF,TEXCLASS.ORD],
  1490. [0x20D0,0x20FF,TEXCLASS.ORD,"CombDiactForSymbols"],
  1491. [0x2100,0x214F,TEXCLASS.ORD,"LetterlikeSymbols"],
  1492. [0x2150,0x218F,TEXCLASS.ORD],
  1493. [0x2190,0x21FF,TEXCLASS.REL,"Arrows"],
  1494. [0x2200,0x22FF,TEXCLASS.BIN,"MathOperators"],
  1495. [0x2300,0x23FF,TEXCLASS.ORD,"MiscTechnical"],
  1496. [0x2460,0x24FF,TEXCLASS.ORD],
  1497. [0x2500,0x259F,TEXCLASS.ORD],
  1498. [0x25A0,0x25FF,TEXCLASS.ORD,"GeometricShapes"],
  1499. [0x2700,0x27BF,TEXCLASS.ORD,"Dingbats"],
  1500. [0x27C0,0x27EF,TEXCLASS.ORD,"MiscMathSymbolsA"],
  1501. [0x27F0,0x27FF,TEXCLASS.REL,"SupplementalArrowsA"],
  1502. [0x2900,0x297F,TEXCLASS.REL,"SupplementalArrowsB"],
  1503. [0x2980,0x29FF,TEXCLASS.ORD,"MiscMathSymbolsB"],
  1504. [0x2A00,0x2AFF,TEXCLASS.BIN,"SuppMathOperators"],
  1505. [0x2B00,0x2BFF,TEXCLASS.ORD,"MiscSymbolsAndArrows"],
  1506. [0x1D400,0x1D7FF,TEXCLASS.ORD]
  1507. ],
  1508. OPTABLE: {
  1509. prefix: {
  1510. '\u2200': MO.ORD21, // for all
  1511. '\u2202': MO.ORD21, // partial differential
  1512. '\u2203': MO.ORD21, // there exists
  1513. '\u2207': MO.ORD21, // nabla
  1514. '\u220F': MO.OP, // n-ary product
  1515. '\u2210': MO.OP, // n-ary coproduct
  1516. '\u2211': MO.OP, // n-ary summation
  1517. '\u2212': MO.BIN01, // minus sign
  1518. '\u2213': MO.BIN01, // minus-or-plus sign
  1519. '\u221A': [1,1,TEXCLASS.ORD,{stretchy: true}], // square root
  1520. '\u2220': MO.ORD, // angle
  1521. '\u222B': MO.INTEGRAL, // integral
  1522. '\u222E': MO.INTEGRAL, // contour integral
  1523. '\u22C0': MO.OP, // n-ary logical and
  1524. '\u22C1': MO.OP, // n-ary logical or
  1525. '\u22C2': MO.OP, // n-ary intersection
  1526. '\u22C3': MO.OP, // n-ary union
  1527. '\u2308': MO.OPEN, // left ceiling
  1528. '\u230A': MO.OPEN, // left floor
  1529. '\u27E8': MO.OPEN, // mathematical left angle bracket
  1530. '\u27EE': MO.OPEN, // mathematical left flattened parenthesis
  1531. '\u2A00': MO.OP, // n-ary circled dot operator
  1532. '\u2A01': MO.OP, // n-ary circled plus operator
  1533. '\u2A02': MO.OP, // n-ary circled times operator
  1534. '\u2A04': MO.OP, // n-ary union operator with plus
  1535. '\u2A06': MO.OP, // n-ary square union operator
  1536. '\u00AC': MO.ORD21, // not sign
  1537. '\u00B1': MO.BIN01, // plus-minus sign
  1538. '(': MO.OPEN, // left parenthesis
  1539. '+': MO.BIN01, // plus sign
  1540. '-': MO.BIN01, // hyphen-minus
  1541. '[': MO.OPEN, // left square bracket
  1542. '{': MO.OPEN, // left curly bracket
  1543. '|': MO.OPEN // vertical line
  1544. },
  1545. postfix: {
  1546. '!': [1,0,TEXCLASS.CLOSE], // exclamation mark
  1547. '&': MO.ORD, // ampersand
  1548. '\u2032': MO.ORD02, // prime
  1549. '\u203E': MO.WIDEACCENT, // overline
  1550. '\u2309': MO.CLOSE, // right ceiling
  1551. '\u230B': MO.CLOSE, // right floor
  1552. '\u23DE': MO.WIDEACCENT, // top curly bracket
  1553. '\u23DF': MO.WIDEACCENT, // bottom curly bracket
  1554. '\u266D': MO.ORD02, // music flat sign
  1555. '\u266E': MO.ORD02, // music natural sign
  1556. '\u266F': MO.ORD02, // music sharp sign
  1557. '\u27E9': MO.CLOSE, // mathematical right angle bracket
  1558. '\u27EF': MO.CLOSE, // mathematical right flattened parenthesis
  1559. '\u02C6': MO.WIDEACCENT, // modifier letter circumflex accent
  1560. '\u02C7': MO.WIDEACCENT, // caron
  1561. '\u02C9': MO.WIDEACCENT, // modifier letter macron
  1562. '\u02CA': MO.ACCENT, // modifier letter acute accent
  1563. '\u02CB': MO.ACCENT, // modifier letter grave accent
  1564. '\u02D8': MO.ACCENT, // breve
  1565. '\u02D9': MO.ACCENT, // dot above
  1566. '\u02DC': MO.WIDEACCENT, // small tilde
  1567. '\u0302': MO.WIDEACCENT, // combining circumflex accent
  1568. '\u00A8': MO.ACCENT, // diaeresis
  1569. '\u00AF': MO.WIDEACCENT, // macron
  1570. ')': MO.CLOSE, // right parenthesis
  1571. ']': MO.CLOSE, // right square bracket
  1572. '^': MO.WIDEACCENT, // circumflex accent
  1573. '_': MO.WIDEACCENT, // low line
  1574. '`': MO.ACCENT, // grave accent
  1575. '|': MO.CLOSE, // vertical line
  1576. '}': MO.CLOSE, // right curly bracket
  1577. '~': MO.WIDEACCENT // tilde
  1578. },
  1579. infix: {
  1580. '': MO.ORD, // empty <mo>
  1581. '%': [3,3,TEXCLASS.ORD], // percent sign
  1582. '\u2022': MO.BIN4, // bullet
  1583. '\u2026': MO.INNER, // horizontal ellipsis
  1584. '\u2044': MO.TALLBIN, // fraction slash
  1585. '\u2061': MO.ORD, // function application
  1586. '\u2062': MO.ORD, // invisible times
  1587. '\u2063': [0,0,TEXCLASS.ORD,{linebreakstyle:"after", separator: true}], // invisible separator
  1588. '\u2064': MO.ORD, // invisible plus
  1589. '\u2190': MO.WIDEREL, // leftwards arrow
  1590. '\u2191': MO.RELSTRETCH, // upwards arrow
  1591. '\u2192': MO.WIDEREL, // rightwards arrow
  1592. '\u2193': MO.RELSTRETCH, // downwards arrow
  1593. '\u2194': MO.WIDEREL, // left right arrow
  1594. '\u2195': MO.RELSTRETCH, // up down arrow
  1595. '\u2196': MO.RELSTRETCH, // north west arrow
  1596. '\u2197': MO.RELSTRETCH, // north east arrow
  1597. '\u2198': MO.RELSTRETCH, // south east arrow
  1598. '\u2199': MO.RELSTRETCH, // south west arrow
  1599. '\u21A6': MO.WIDEREL, // rightwards arrow from bar
  1600. '\u21A9': MO.WIDEREL, // leftwards arrow with hook
  1601. '\u21AA': MO.WIDEREL, // rightwards arrow with hook
  1602. '\u21BC': MO.WIDEREL, // leftwards harpoon with barb upwards
  1603. '\u21BD': MO.WIDEREL, // leftwards harpoon with barb downwards
  1604. '\u21C0': MO.WIDEREL, // rightwards harpoon with barb upwards
  1605. '\u21C1': MO.WIDEREL, // rightwards harpoon with barb downwards
  1606. '\u21CC': MO.WIDEREL, // rightwards harpoon over leftwards harpoon
  1607. '\u21D0': MO.WIDEREL, // leftwards double arrow
  1608. '\u21D1': MO.RELSTRETCH, // upwards double arrow
  1609. '\u21D2': MO.WIDEREL, // rightwards double arrow
  1610. '\u21D3': MO.RELSTRETCH, // downwards double arrow
  1611. '\u21D4': MO.WIDEREL, // left right double arrow
  1612. '\u21D5': MO.RELSTRETCH, // up down double arrow
  1613. '\u2208': MO.REL, // element of
  1614. '\u2209': MO.REL, // not an element of
  1615. '\u220B': MO.REL, // contains as member
  1616. '\u2212': MO.BIN4, // minus sign
  1617. '\u2213': MO.BIN4, // minus-or-plus sign
  1618. '\u2215': MO.TALLBIN, // division slash
  1619. '\u2216': MO.BIN4, // set minus
  1620. '\u2217': MO.BIN4, // asterisk operator
  1621. '\u2218': MO.BIN4, // ring operator
  1622. '\u2219': MO.BIN4, // bullet operator
  1623. '\u221D': MO.REL, // proportional to
  1624. '\u2223': MO.REL, // divides
  1625. '\u2225': MO.REL, // parallel to
  1626. '\u2227': MO.BIN4, // logical and
  1627. '\u2228': MO.BIN4, // logical or
  1628. '\u2229': MO.BIN4, // intersection
  1629. '\u222A': MO.BIN4, // union
  1630. '\u223C': MO.REL, // tilde operator
  1631. '\u2240': MO.BIN4, // wreath product
  1632. '\u2243': MO.REL, // asymptotically equal to
  1633. '\u2245': MO.REL, // approximately equal to
  1634. '\u2248': MO.REL, // almost equal to
  1635. '\u224D': MO.REL, // equivalent to
  1636. '\u2250': MO.REL, // approaches the limit
  1637. '\u2260': MO.REL, // not equal to
  1638. '\u2261': MO.REL, // identical to
  1639. '\u2264': MO.REL, // less-than or equal to
  1640. '\u2265': MO.REL, // greater-than or equal to
  1641. '\u226A': MO.REL, // much less-than
  1642. '\u226B': MO.REL, // much greater-than
  1643. '\u227A': MO.REL, // precedes
  1644. '\u227B': MO.REL, // succeeds
  1645. '\u2282': MO.REL, // subset of
  1646. '\u2283': MO.REL, // superset of
  1647. '\u2286': MO.REL, // subset of or equal to
  1648. '\u2287': MO.REL, // superset of or equal to
  1649. '\u228E': MO.BIN4, // multiset union
  1650. '\u2291': MO.REL, // square image of or equal to
  1651. '\u2292': MO.REL, // square original of or equal to
  1652. '\u2293': MO.BIN4, // square cap
  1653. '\u2294': MO.BIN4, // square cup
  1654. '\u2295': MO.BIN4, // circled plus
  1655. '\u2296': MO.BIN4, // circled minus
  1656. '\u2297': MO.BIN4, // circled times
  1657. '\u2298': MO.BIN4, // circled division slash
  1658. '\u2299': MO.BIN4, // circled dot operator
  1659. '\u22A2': MO.REL, // right tack
  1660. '\u22A3': MO.REL, // left tack
  1661. '\u22A4': MO.ORD55, // down tack
  1662. '\u22A5': MO.REL, // up tack
  1663. '\u22A8': MO.REL, // true
  1664. '\u22C4': MO.BIN4, // diamond operator
  1665. '\u22C5': MO.BIN4, // dot operator
  1666. '\u22C6': MO.BIN4, // star operator
  1667. '\u22C8': MO.REL, // bowtie
  1668. '\u22EE': MO.ORD55, // vertical ellipsis
  1669. '\u22EF': MO.INNER, // midline horizontal ellipsis
  1670. '\u22F1': [5,5,TEXCLASS.INNER], // down right diagonal ellipsis
  1671. '\u25B3': MO.BIN4, // white up-pointing triangle
  1672. '\u25B5': MO.BIN4, // white up-pointing small triangle
  1673. '\u25B9': MO.BIN4, // white right-pointing small triangle
  1674. '\u25BD': MO.BIN4, // white down-pointing triangle
  1675. '\u25BF': MO.BIN4, // white down-pointing small triangle
  1676. '\u25C3': MO.BIN4, // white left-pointing small triangle
  1677. '\u2758': MO.REL, // light vertical bar
  1678. '\u27F5': MO.WIDEREL, // long leftwards arrow
  1679. '\u27F6': MO.WIDEREL, // long rightwards arrow
  1680. '\u27F7': MO.WIDEREL, // long left right arrow
  1681. '\u27F8': MO.WIDEREL, // long leftwards double arrow
  1682. '\u27F9': MO.WIDEREL, // long rightwards double arrow
  1683. '\u27FA': MO.WIDEREL, // long left right double arrow
  1684. '\u27FC': MO.WIDEREL, // long rightwards arrow from bar
  1685. '\u2A2F': MO.BIN4, // vector or cross product
  1686. '\u2A3F': MO.BIN4, // amalgamation or coproduct
  1687. '\u2AAF': MO.REL, // precedes above single-line equals sign
  1688. '\u2AB0': MO.REL, // succeeds above single-line equals sign
  1689. '\u00B1': MO.BIN4, // plus-minus sign
  1690. '\u00B7': MO.BIN4, // middle dot
  1691. '\u00D7': MO.BIN4, // multiplication sign
  1692. '\u00F7': MO.BIN4, // division sign
  1693. '*': MO.BIN3, // asterisk
  1694. '+': MO.BIN4, // plus sign
  1695. ',': [0,3,TEXCLASS.PUNCT,{linebreakstyle:"after", separator: true}], // comma
  1696. '-': MO.BIN4, // hyphen-minus
  1697. '.': [3,3,TEXCLASS.ORD], // full stop
  1698. '/': MO.ORD11, // solidus
  1699. ':': [1,2,TEXCLASS.REL], // colon
  1700. ';': [0,3,TEXCLASS.PUNCT,{linebreakstyle:"after", separator: true}], // semicolon
  1701. '<': MO.REL, // less-than sign
  1702. '=': MO.REL, // equals sign
  1703. '>': MO.REL, // greater-than sign
  1704. '?': [1,1,TEXCLASS.CLOSE], // question mark
  1705. '\\': MO.ORD, // reverse solidus
  1706. '^': MO.ORD11, // circumflex accent
  1707. '_': MO.ORD11, // low line
  1708. '|': [2,2,TEXCLASS.ORD,{fence: true, stretchy: true, symmetric: true}], // vertical line
  1709. '#': MO.ORD, // #
  1710. '$': MO.ORD, // $
  1711. '\u002E': [0,3,TEXCLASS.PUNCT,{separator: true}], // \ldotp
  1712. '\u02B9': MO.ORD, // prime
  1713. '\u0300': MO.ACCENT, // \grave
  1714. '\u0301': MO.ACCENT, // \acute
  1715. '\u0303': MO.WIDEACCENT, // \tilde
  1716. '\u0304': MO.ACCENT, // \bar
  1717. '\u0306': MO.ACCENT, // \breve
  1718. '\u0307': MO.ACCENT, // \dot
  1719. '\u0308': MO.ACCENT, // \ddot
  1720. '\u030C': MO.ACCENT, // \check
  1721. '\u0332': MO.WIDEACCENT, // horizontal line
  1722. '\u0338': MO.REL4, // \not
  1723. '\u2015': [0,0,TEXCLASS.ORD,{stretchy: true}], // horizontal line
  1724. '\u2017': [0,0,TEXCLASS.ORD,{stretchy: true}], // horizontal line
  1725. '\u2020': MO.BIN3, // \dagger
  1726. '\u2021': MO.BIN3, // \ddagger
  1727. '\u20D7': MO.ACCENT, // \vec
  1728. '\u2111': MO.ORD, // \Im
  1729. '\u2113': MO.ORD, // \ell
  1730. '\u2118': MO.ORD, // \wp
  1731. '\u211C': MO.ORD, // \Re
  1732. '\u2205': MO.ORD, // \emptyset
  1733. '\u221E': MO.ORD, // \infty
  1734. '\u2305': MO.BIN3, // barwedge
  1735. '\u2306': MO.BIN3, // doublebarwedge
  1736. '\u2322': MO.REL4, // \frown
  1737. '\u2323': MO.REL4, // \smile
  1738. '\u2329': MO.OPEN, // langle
  1739. '\u232A': MO.CLOSE, // rangle
  1740. '\u23AA': MO.ORD, // \bracevert
  1741. '\u23AF': [0,0,TEXCLASS.ORD,{stretchy: true}], // \underline
  1742. '\u23B0': MO.OPEN, // \lmoustache
  1743. '\u23B1': MO.CLOSE, // \rmoustache
  1744. '\u2500': MO.ORD, // horizontal line
  1745. '\u25EF': MO.BIN3, // \bigcirc
  1746. '\u2660': MO.ORD, // \spadesuit
  1747. '\u2661': MO.ORD, // \heartsuit
  1748. '\u2662': MO.ORD, // \diamondsuit
  1749. '\u2663': MO.ORD, // \clubsuit
  1750. '\u3008': MO.OPEN, // langle
  1751. '\u3009': MO.CLOSE, // rangle
  1752. '\uFE37': MO.WIDEACCENT, // horizontal brace down
  1753. '\uFE38': MO.WIDEACCENT // horizontal brace up
  1754. }
  1755. }
  1756. },{
  1757. OPTYPES: MO
  1758. });
  1759. //
  1760. // These are not in the W3C table, but FF works this way,
  1761. // and it makes sense, so add it here
  1762. //
  1763. var OPTABLE = MML.mo.prototype.OPTABLE;
  1764. OPTABLE.infix["^"] = MO.WIDEREL;
  1765. OPTABLE.infix["_"] = MO.WIDEREL;
  1766. OPTABLE.prefix["\u2223"] = MO.OPEN;
  1767. OPTABLE.prefix["\u2225"] = MO.OPEN;
  1768. OPTABLE.postfix["\u2223"] = MO.CLOSE;
  1769. OPTABLE.postfix["\u2225"] = MO.CLOSE;
  1770. })(MathJax.ElementJax.mml);
  1771. MathJax.ElementJax.mml.loadComplete("jax.js");