content-mathml.js 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743
  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/extensions/MathML/content-mathml.js
  6. *
  7. * This file provides methods to convert Content-MathML to
  8. * Presentation MathML for processing by MathJax. The transform is
  9. * performed in a DOM filter for the MathML input jax, so that the
  10. * Show Math As menu will still show the Original MathML as Content MathML,
  11. * but the Presentation MathML can be obtained from the main MathML menu.
  12. *
  13. * To load it, include
  14. *
  15. * MathML: {
  16. * extensions: ["content-mathml.js"]
  17. * }
  18. *
  19. * in your configuration.
  20. *
  21. * A portion of this file is taken from ctop.js which is
  22. * Copyright (c) David Carlisle 2001, 2002, 2008, 2009, 2013,
  23. * and is used by permission of David Carlisle, who has agreed to allow us
  24. * to release it under the Apache2 license (see below). That portion is
  25. * indicated via comments.
  26. *
  27. * The remainder falls under the copyright that follows.
  28. * ---------------------------------------------------------------------
  29. *
  30. * Copyright (c) 2013-2017 The MathJax Consortium
  31. *
  32. * Licensed under the Apache License, Version 2.0 (the "License");
  33. * you may not use this file except in compliance with the License.
  34. * You may obtain a copy of the License at
  35. *
  36. * http://www.apache.org/licenses/LICENSE-2.0
  37. *
  38. * Unless required by applicable law or agreed to in writing, software
  39. * distributed under the License is distributed on an "AS IS" BASIS,
  40. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  41. * See the License for the specific language governing permissions and
  42. * limitations under the License.
  43. */
  44. MathJax.Extension["MathML/content-mathml"] = (function(HUB) {
  45. /*
  46. * Content MathML to Presentation MathML conversion
  47. *
  48. * based on David Carlisle's ctop.js - https://web-xslt.googlecode.com/svn/trunk/ctop/ctop.js
  49. *
  50. */
  51. var isMSIE = HUB.Browser.isMSIE;
  52. if (isMSIE) {
  53. try {document.namespaces.add("m","http://www.w3.org/1998/Math/MathML")} catch (err) {}
  54. }
  55. var CONFIG = HUB.CombineConfig("MathML.content-mathml",{
  56. // render `a+(-b)` as `a-b`?
  57. collapsePlusMinus: true,
  58. /* mathvariant to use with corresponding <ci> type attribute */
  59. cistyles: {
  60. vector: 'bold-italic',
  61. matrix: 'bold-upright'
  62. },
  63. /* Symbol names to translate to characters
  64. */
  65. symbols: {
  66. gamma: '\u03B3'
  67. }
  68. });
  69. var CToP = {
  70. version: "2.7.2",
  71. settings: CONFIG,
  72. /* Transform the given <math> elements from Content MathML to Presentation MathML and replace the original elements
  73. */
  74. transformElements: function(elements) {
  75. for (var i = 0, l = elements.length; i<l; i++ ) {
  76. var mathNode = CToP.transformElement(elements[i]);
  77. elements[i].parentNode.replaceChild(mathNode,elements[i]);
  78. }
  79. },
  80. /* Transform a Content MathML element into Presentation MathML, and return the new element
  81. */
  82. transformElement: function(element) {
  83. if (element.nodeName.indexOf(":") >= 0) element = CToP.cloneNode(element,true); // removes namespaces
  84. var mathNode = CToP.cloneNode(element);
  85. for (var j = 0, l = element.childNodes.length; j<l; j++ ) {
  86. CToP.applyTransform(mathNode,element.childNodes[j],0);
  87. }
  88. return mathNode;
  89. },
  90. getTextContent: function(element) {
  91. return element.text !== undefined ? element.text : element.innerText !== undefined ? element.innerText : element.textContent;
  92. },
  93. setTextContent: function(element,textContent) {
  94. for (var i = 0, l = element.childNodes.length; i<l; i++) {
  95. if (element.childNodes[i].nodeType === 3) {
  96. element.removeChild(element.childNodes[i]);
  97. i--;
  98. l--;
  99. }
  100. }
  101. element.appendChild(document.createTextNode(textContent));
  102. },
  103. cloneNode: function(element,deep) {
  104. var clone, i, l;
  105. if (element.nodeType === 1) {
  106. clone = CToP.createElement(element.nodeName);
  107. for (i = 0, l = element.attributes.length; i<l; i++ ) {
  108. clone.setAttribute(element.attributes[i].nodeName,element.attributes[i].nodeValue);
  109. }
  110. if (deep) {
  111. for (i = 0, l = element.childNodes.length; i<l; i++ ) {
  112. var clonedChild = CToP.cloneNode(element.childNodes[i],true);
  113. clone.appendChild(clonedChild);
  114. }
  115. }
  116. } else if (element.nodeType === 3) {
  117. clone = document.createTextNode(element.nodeValue);
  118. }
  119. return clone;
  120. },
  121. /* Create an element with given name, belonging to the MathML namespace
  122. */
  123. createElement: function(name) {
  124. name = name.replace(/^.*:/,""); // remove namespace
  125. return (document.createElementNS ?
  126. document.createElementNS("http://www.w3.org/1998/Math/MathML",name) :
  127. document.createElement("m:"+name));
  128. },
  129. /* Get node's children
  130. */
  131. getChildren: function(node) {
  132. var children = [];
  133. for (var j = 0, l = node.childNodes.length; j<l; j++ ) {
  134. if (node.childNodes[j].nodeType === 1) {
  135. children.push(node.childNodes[j]);
  136. }
  137. }
  138. return children;
  139. },
  140. /* Classify node's children as argumentss, variable bindings, or qualifiers
  141. */
  142. classifyChildren: function(contentMMLNode) {
  143. var args = [], bvars = [], qualifiers = [];
  144. for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) {
  145. if (contentMMLNode.childNodes[j].nodeType === 1) {
  146. var childNode = contentMMLNode.childNodes[j], name = childNode.nodeName;
  147. if (name === 'bvar') {
  148. bvars.push(childNode);
  149. } else if (name === 'condition'||
  150. name === 'degree'||
  151. name === 'momentabout'||
  152. name === 'logbase'||
  153. name === 'lowlimit'||
  154. name === 'uplimit'||
  155. (name === 'interval' && args.length<2)||
  156. name === 'domainofapplication') {
  157. qualifiers.push(childNode);
  158. } else {
  159. args.push(childNode);
  160. }
  161. }
  162. }
  163. return {
  164. args:args,
  165. bvars:bvars,
  166. qualifiers:qualifiers
  167. };
  168. },
  169. /* Add an element with given name and text content
  170. */
  171. appendToken: function(parentNode,name,textContent) {
  172. var element = CToP.createElement(name);
  173. textContent = textContent.replace(/^\s+/,"").replace(/\s+$/,"");
  174. if (name === 'mn' && textContent.substr(0,1) === "-") {
  175. //
  176. // use <mrow><mo>&#x2212;</mo><mn>n</mn></mrow> instead of <mn>-n</mn>
  177. //
  178. element.appendChild(document.createTextNode(textContent.substr(1)));
  179. var mrow = CToP.createElement('mrow');
  180. CToP.appendToken(mrow,'mo','\u2212');
  181. mrow.appendChild(element);
  182. element = mrow;
  183. } else {
  184. element.appendChild(document.createTextNode(textContent));
  185. }
  186. parentNode.appendChild(element);
  187. return element;
  188. },
  189. /* Transform a Content MathML node to Presentation MathML node(s), and attach it to the parent
  190. */
  191. applyTransform: function(parentNode,contentMMLNode,precedence) {
  192. if (!contentMMLNode) {
  193. var merror = CToP.createElement('merror');
  194. CToP.appendToken(merror,'mtext','Missing child node');
  195. parentNode.appendChild(merror);
  196. return;
  197. }
  198. var nodeName = contentMMLNode.nodeName.replace(/.*:/,'');
  199. if (contentMMLNode.nodeType === 1) {
  200. if (CToP.tokens[nodeName]) {
  201. CToP.tokens[nodeName](parentNode,contentMMLNode,precedence);
  202. } else if (contentMMLNode.childNodes.length === 0) {
  203. var mml = CToP.MML[nodeName];
  204. if (mml && mml.isa && mml.isa(CToP.mbase)) {
  205. parentNode.appendChild(CToP.cloneNode(contentMMLNode));
  206. } else {
  207. CToP.appendToken(parentNode,'mi',nodeName);
  208. }
  209. } else {
  210. var clonedChild = CToP.cloneNode(contentMMLNode);
  211. parentNode.appendChild(clonedChild);
  212. for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) {
  213. CToP.applyTransform(clonedChild,contentMMLNode.childNodes[j],precedence);
  214. }
  215. }
  216. } else if (contentMMLNode.nodeType === 3) {
  217. parentNode.appendChild(CToP.cloneNode(contentMMLNode));
  218. }
  219. },
  220. /* Make an mfenced environment
  221. */
  222. createmfenced: function(children,open,close) {
  223. var mf = CToP.createElement('mfenced');
  224. mf.setAttribute('open',open);
  225. mf.setAttribute('close',close);
  226. for (var j = 0, l = children.length; j<l; j++ ) {
  227. CToP.applyTransform(mf,children[j],0);
  228. }
  229. return mf;
  230. },
  231. transforms: {
  232. /* Transform an identifier symbol
  233. */
  234. identifier: function(textContent) {
  235. return function(parentNode,contentMMLNode,precedence) {
  236. CToP.appendToken(parentNode,'mi',textContent);
  237. }
  238. },
  239. /* Transform a set or set-like notation
  240. */
  241. set: function(open,close) {
  242. var bindSet = CToP.transforms.bind('',',','|');
  243. return function(parentNode,contentMMLNode) {
  244. var children = CToP.classifyChildren(contentMMLNode);
  245. var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers;
  246. if (bvars.length) {
  247. var firstArg = children.args[0];
  248. args = args.slice(1);
  249. var mfenced = CToP.createElement('mfenced');
  250. mfenced.setAttribute('open',open);
  251. mfenced.setAttribute('close',close);
  252. bindSet(mfenced,contentMMLNode,firstArg,args,bvars,qualifiers,0);
  253. parentNode.appendChild(mfenced);
  254. } else {
  255. parentNode.appendChild(CToP.createmfenced(args,open,close));
  256. }
  257. }
  258. },
  259. /* Transform a content token to a presentation token
  260. *
  261. * (function factory)
  262. * @param {string} name - name of the corresponding presentation MML tag
  263. */
  264. token: function(name) {
  265. return function(parentNode,contentMMLNode) {
  266. if (contentMMLNode.childNodes.length === 1 && contentMMLNode.childNodes[0].nodeType === 3) {
  267. CToP.appendToken(parentNode,name,CToP.getTextContent(contentMMLNode));
  268. } else {
  269. var mrow = CToP.createElement('mrow');
  270. for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) {
  271. if (contentMMLNode.childNodes[j].nodeType === 3) {
  272. CToP.appendToken(parentNode,name,CToP.getTextContent(contentMMLNode.childNodes[j]));
  273. }else{
  274. CToP.applyTransform(mrow,contentMMLNode.childNodes[j],0);
  275. }
  276. }
  277. if (mrow.childNodes.length) {
  278. parentNode.appendChild(mrow);
  279. }
  280. }
  281. }
  282. },
  283. /* Transform a binary operation
  284. *
  285. * (function factory)
  286. */
  287. binary: function(name,tokenPrecedence) {
  288. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  289. var mrow = CToP.createElement('mrow');
  290. var needsBrackets = tokenPrecedence<precedence || (tokenPrecedence == precedence && name === "-");
  291. if (needsBrackets) {
  292. CToP.appendToken(mrow,'mo','(');
  293. }
  294. if (args.length>1) {
  295. CToP.applyTransform(mrow,args[0],tokenPrecedence);
  296. }
  297. CToP.appendToken(mrow,'mo',name);
  298. if (args.length>0) {
  299. var z = args[(args.length === 1)?0:1];
  300. CToP.applyTransform(mrow,z,tokenPrecedence);
  301. }
  302. if (needsBrackets) {
  303. CToP.appendToken(mrow,'mo',')');
  304. }
  305. parentNode.appendChild(mrow);
  306. }
  307. },
  308. /* Transform an infix operator
  309. *
  310. * (function factory)
  311. */
  312. infix: function(name,tokenPrecedence) {
  313. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  314. var mrow = CToP.createElement('mrow');
  315. var needsBrackets = precedence>tokenPrecedence;
  316. if (needsBrackets) {
  317. CToP.appendToken(mrow,'mo','(');
  318. }
  319. for (var j = 0, l = args.length; j<l; j++ ) {
  320. if (j>0) {
  321. CToP.appendToken(mrow,'mo',name);
  322. }
  323. CToP.applyTransform(mrow,args[j],tokenPrecedence);
  324. }
  325. if (needsBrackets) {
  326. CToP.appendToken(mrow,'mo',')');
  327. }
  328. parentNode.appendChild(mrow);
  329. }
  330. },
  331. /* Transform an iterated operation, e.g. summation
  332. *
  333. * (function factory
  334. */
  335. iteration: function(name,limitSymbol) {
  336. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  337. var mrow = CToP.createElement('mrow');
  338. var mo = CToP.createElement('mo');
  339. CToP.setTextContent(mo,name);
  340. var munderover = CToP.createElement('munderover');
  341. munderover.appendChild(mo);
  342. var mrow1 = CToP.createElement('mrow');
  343. var i, j, num_qualifiers, num_bvars, children, bvar, num_children, num_args;
  344. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  345. if (qualifiers[i].nodeName === 'lowlimit'||
  346. qualifiers[i].nodeName === 'condition'||
  347. qualifiers[i].nodeName === 'domainofapplication')
  348. {
  349. if (qualifiers[i].nodeName === 'lowlimit') {
  350. for (j = 0, num_bvars = bvars.length; j<num_bvars; j++ ) {
  351. bvar = bvars[j];
  352. children = CToP.getChildren(bvar);
  353. if (children.length) {
  354. CToP.applyTransform(mrow1,children[0],0);
  355. }
  356. }
  357. if (bvars.length) {
  358. CToP.appendToken(mrow1,"mo",limitSymbol);
  359. }
  360. }
  361. children = CToP.getChildren(qualifiers[i]);
  362. for (j = 0;j<children.length;j++) {
  363. CToP.applyTransform(mrow1,children[j],0);
  364. }
  365. } else {
  366. children = CToP.getChildren(qualifiers[i]);
  367. if (qualifiers[i].nodeName === 'interval' && children.length === 2) {
  368. for (j = 0, num_bvars = bvars.length; j<num_bvars; j++ ) {
  369. bvar = bvars[j];
  370. children = CToP.getChildren(bvar);
  371. if (children.length) {
  372. CToP.applyTransform(mrow1,children[0],0);
  373. }
  374. }
  375. if (bvars.length) {
  376. CToP.appendToken(mrow1,"mo","=");
  377. }
  378. CToP.applyTransform(mrow1,CToP.getChildren(qualifiers[i])[0],0);
  379. }
  380. }
  381. }
  382. munderover.appendChild(mrow1);
  383. var mjrow = CToP.createElement('mrow');
  384. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  385. if (qualifiers[i].nodeName === 'uplimit' ||qualifiers[i].nodeName === 'interval' )
  386. {
  387. children = CToP.getChildren(qualifiers[i]);
  388. for (j = 0, num_children = children.length; j<num_children; j++ ) {
  389. CToP.applyTransform(mjrow,children[j],0);
  390. }
  391. }
  392. }
  393. munderover.appendChild(mjrow);
  394. mrow.appendChild(munderover);
  395. for (i = 0, num_args = args.length; i<num_args; i++ ) {
  396. CToP.applyTransform(mrow,args[i],precedence);
  397. }
  398. parentNode.appendChild(mrow);
  399. }
  400. },
  401. /* Transform something which binds a variable, e.g. forall or lambda
  402. *
  403. * (function factory)
  404. */
  405. bind: function(name,argSeparator,conditionSeparator) {
  406. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  407. var mrow = CToP.createElement('mrow');
  408. var children, i, j, l, num_qualifiers, num_children;
  409. if (name) {
  410. CToP.appendToken(mrow,'mo',name);
  411. }
  412. for (j = 0, l = bvars.length; j<l; j++ ) {
  413. var bvar = bvars[j];
  414. if (j>0) {
  415. CToP.appendToken(mrow,'mo',',');
  416. }
  417. children = CToP.getChildren(bvar);
  418. if (children.length) {
  419. CToP.applyTransform(mrow,children[0],0);
  420. }
  421. }
  422. var conditions_mrow = CToP.createElement('mrow');
  423. var conditions = false;
  424. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  425. if (qualifiers[i].nodeName === 'condition') {
  426. conditions = true;
  427. children = CToP.getChildren(qualifiers[i]);
  428. for (j = 0, num_children = children.length; j<num_children; j++ ) {
  429. CToP.applyTransform(conditions_mrow,children[j],0);
  430. }
  431. }
  432. }
  433. if (conditions) {
  434. CToP.appendToken(mrow,'mo',conditionSeparator);
  435. }
  436. mrow.appendChild(conditions_mrow);
  437. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  438. if (qualifiers[i].nodeName != 'condition') {
  439. CToP.appendToken(mrow,'mo','\u2208');
  440. children = CToP.getChildren(qualifiers[i]);
  441. for (j = 0, num_children = children.length; j<num_children; j++ ) {
  442. CToP.applyTransform(mrow,children[j],0);
  443. }
  444. }
  445. }
  446. if (args.length && (bvars.length||children.length)) {
  447. CToP.appendToken(mrow,'mo',argSeparator);
  448. }
  449. for (i = 0, l = args.length; i<l; i++ ) {
  450. CToP.applyTransform(mrow,args[i],0);
  451. }
  452. parentNode.appendChild(mrow);
  453. }
  454. },
  455. /** Transform a function application
  456. *
  457. * i.e. something which ends up looking like `f(x,y,z)`, where `f` is a string
  458. *
  459. * (function factory)
  460. */
  461. fn: function(name) {
  462. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  463. var mrow = CToP.createElement('mrow');
  464. if (firstArg.childNodes.length) {
  465. CToP.applyTransform(mrow,firstArg,1);
  466. } else {
  467. CToP.appendToken(mrow,'mi',name);
  468. }
  469. CToP.appendToken(mrow,'mo','\u2061');
  470. mrow.appendChild(CToP.createmfenced(args,'(',')'));
  471. parentNode.appendChild(mrow);
  472. }
  473. },
  474. /** Transform a min/max operation
  475. *
  476. * (function factory)
  477. */
  478. minmax: function(name) {
  479. return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  480. var mrow = CToP.createElement('mrow');
  481. CToP.appendToken(mrow,'mi',name);
  482. var mrow2 = CToP.createElement('mrow');
  483. CToP.appendToken(mrow2,'mo','{');
  484. for (var i = 0, l = args.length; i<l; i++ ) {
  485. if (i>0) {
  486. CToP.appendToken(mrow2,'mo',',');
  487. }
  488. CToP.applyTransform(mrow2,args[i],0);
  489. }
  490. if (qualifiers.length) {
  491. CToP.appendToken(mrow2,'mo','|');
  492. for (i = 0, l = qualifiers.length; i<l; i++ ) {
  493. CToP.applyTransform(mrow2,qualifiers[i],0);
  494. }
  495. }
  496. CToP.appendToken(mrow2,'mo','}');
  497. mrow.appendChild(mrow2);
  498. parentNode.appendChild(mrow);
  499. }
  500. }
  501. }
  502. }
  503. /* Functions to transform variable/atom tokens
  504. */
  505. CToP.tokens = {
  506. ci: function(parentNode,contentMMLNode,precedence) {
  507. if (contentMMLNode.childNodes.length === 1 && contentMMLNode.childNodes[0].nodeType === 3) {
  508. var mi = CToP.appendToken(parentNode,'mi',CToP.getTextContent(contentMMLNode));
  509. var type = contentMMLNode.getAttribute('type');
  510. if (type in CToP.settings.cistyles) {
  511. mi.setAttribute('mathvariant',CToP.settings.cistyles[type]);
  512. }
  513. } else {
  514. CToP.transforms.token('mi')(parentNode,contentMMLNode,precedence);
  515. }
  516. },
  517. cs: CToP.transforms.token('ms'),
  518. csymbol: function(parentNode,contentMMLNode,precedence) {
  519. var cd = contentMMLNode.getAttribute('cd');
  520. if (cd && CToP.contentDictionaries[cd]) {
  521. CToP.contentDictionaries[cd](parentNode,contentMMLNode,precedence);
  522. } else if (CToP.settings.symbols[name]) {
  523. CToP.appendToken(parentNode,'mi',CToP.settings.symbols[name]);
  524. } else {
  525. CToP.tokens.ci(parentNode,contentMMLNode);
  526. }
  527. },
  528. fn: function(parentNode,contentMMLNode,precedence) {
  529. CToP.applyTransform(parentNode,CToP.getChildren(contentMMLNode)[0],precedence);
  530. },
  531. naturalnumbers: CToP.transforms.identifier('\u2115'),
  532. integers: CToP.transforms.identifier('\u2124'),
  533. reals: CToP.transforms.identifier('\u211D'),
  534. rationals: CToP.transforms.identifier('\u211A'),
  535. complexes: CToP.transforms.identifier('\u2102'),
  536. primes: CToP.transforms.identifier('\u2119'),
  537. exponentiale: CToP.transforms.identifier('e'),
  538. imaginaryi: CToP.transforms.identifier('i'),
  539. notanumber: CToP.transforms.identifier('NaN'),
  540. eulergamma: CToP.transforms.identifier('\u03B3'),
  541. gamma: CToP.transforms.identifier('\u0263'),
  542. pi: CToP.transforms.identifier('\u03C0'),
  543. infinity: CToP.transforms.identifier('\u221E'),
  544. emptyset: CToP.transforms.identifier('\u2205'),
  545. "true": CToP.transforms.identifier('true'),
  546. "false": CToP.transforms.identifier('false'),
  547. set: CToP.transforms.set('{','}'),
  548. list: CToP.transforms.set('(',')'),
  549. interval: function(parentNode,contentMMLNode,precedence) {
  550. var closure = contentMMLNode.getAttribute('closure');
  551. var open, close;
  552. switch(closure) {
  553. case 'open':
  554. open = '(';
  555. close = ')';
  556. break;
  557. case 'open-closed':
  558. open = '(';
  559. close = ']';
  560. break;
  561. case 'closed-open':
  562. open = '[';
  563. close = ')';
  564. break;
  565. case 'closed':
  566. default:
  567. open = '[';
  568. close = ']';
  569. }
  570. parentNode.appendChild(CToP.createmfenced(CToP.getChildren(contentMMLNode),open,close));
  571. },
  572. apply: function(parentNode,contentMMLNode,precedence) {
  573. var children = CToP.classifyChildren(contentMMLNode);
  574. var firstArg = children.args[0];
  575. var args = children.args.slice(1), bvars = children.bvars, qualifiers = children.qualifiers;
  576. if (firstArg) {
  577. var name = firstArg.nodeName;
  578. name = (name === "csymbol") ? CToP.getTextContent(firstArg).toLowerCase() : name;
  579. if (CToP.applyTokens[name]) {
  580. CToP.applyTokens[name](parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  581. } else {
  582. CToP.transforms.fn(name)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  583. }
  584. } else {
  585. parentNode.appendChild(CToP.createElement('mrow'));
  586. }
  587. },
  588. cn: function(parentNode,contentMMLNode,precedence) {
  589. var type = contentMMLNode.getAttribute("type");
  590. var base = contentMMLNode.getAttribute("base");
  591. if (type || base) {
  592. if (base) {
  593. type = 'based-integer';
  594. }
  595. switch(type) {
  596. case 'integer':
  597. case 'real':
  598. case 'double':
  599. case 'constant':
  600. CToP.transforms.token('mn')(parentNode,contentMMLNode);
  601. break;
  602. case 'hexdouble':
  603. CToP.appendToken(parentNode,'mn','0x'+CToP.getTextContent(contentMMLNode));
  604. break;
  605. default:
  606. var apply = CToP.createElement('apply');
  607. var mrow = CToP.createElement('mrow');
  608. var c = CToP.createElement(type);
  609. apply.appendChild(c);
  610. if (base) {
  611. CToP.appendToken(apply,'mn',base);
  612. }
  613. for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) {
  614. if (contentMMLNode.childNodes[j].nodeType === 3) {
  615. CToP.appendToken(mrow,'cn',CToP.getTextContent(contentMMLNode.childNodes[j]));
  616. }else if (contentMMLNode.childNodes[j].nodeName === 'sep') {
  617. apply.appendChild(mrow);
  618. mrow = CToP.createElement('mrow');
  619. } else {
  620. mrow.appendChild(CToP.cloneNode(contentMMLNode.childNodes[j],true));
  621. }
  622. }
  623. apply.appendChild(mrow);
  624. CToP.applyTransform(parentNode,apply,0);
  625. }
  626. } else {
  627. CToP.transforms.token('mn')(parentNode,contentMMLNode);
  628. }
  629. },
  630. vector: function(parentNode,contentMMLNode,precedence) {
  631. var mrow = CToP.createElement('mrow');
  632. CToP.appendToken(mrow,'mo','(');
  633. var mtable = CToP.createElement('mtable');
  634. var children = CToP.getChildren(contentMMLNode);
  635. for (var i = 0, l = children.length; i<l; i++ ) {
  636. var mtr = CToP.createElement('mtr');
  637. var mtd = CToP.createElement('mtd');
  638. CToP.applyTransform(mtd,children[i],0);
  639. mtr.appendChild(mtd);
  640. mtable.appendChild(mtr);
  641. }
  642. mrow.appendChild(mtable);
  643. CToP.appendToken(mrow,'mo',')');
  644. parentNode.appendChild(mrow);
  645. },
  646. piecewise: function(parentNode,contentMMLNode,precedence) {
  647. var mrow = CToP.createElement('mrow');
  648. CToP.appendToken(mrow,'mo','{');
  649. var mtable = CToP.createElement('mtable');
  650. mrow.appendChild(mtable);
  651. var children = CToP.getChildren(contentMMLNode);
  652. for (var i = 0, l = children.length; i<l; i++ ) {
  653. CToP.applyTransform(mtable,children[i],0);
  654. }
  655. parentNode.appendChild(mrow);
  656. },
  657. piece: function(parentNode,contentMMLNode,precedence) {
  658. var mtr = CToP.createElement('mtr');
  659. var children = CToP.getChildren(contentMMLNode);
  660. for (var i = 0, l = children.length; i<l; i++ ) {
  661. var mtd = CToP.createElement('mtd');
  662. mtr.appendChild(mtd);
  663. CToP.applyTransform(mtd,children[i],0);
  664. if (i === 0) {
  665. mtd = CToP.createElement('mtd');
  666. CToP.appendToken(mtd,"mtext","\u00A0if\u00A0");
  667. mtr.appendChild(mtd);
  668. }
  669. }
  670. parentNode.appendChild(mtr);
  671. },
  672. otherwise: function(parentNode,contentMMLNode,precedence) {
  673. var mtr = CToP.createElement('mtr');
  674. var children = CToP.getChildren(contentMMLNode);
  675. if (children.length) {
  676. var mtd = CToP.createElement('mtd');
  677. mtr.appendChild(mtd);
  678. CToP.applyTransform(mtd,children[0],0);
  679. mtd = CToP.createElement('mtd');
  680. mtd.setAttribute('columnspan','2');
  681. CToP.appendToken(mtd,"mtext","\u00A0otherwise");
  682. mtr.appendChild(mtd);
  683. }
  684. parentNode.appendChild(mtr);
  685. },
  686. matrix: function(parentNode,contentMMLNode,precedence) {
  687. var children = CToP.classifyChildren(contentMMLNode);
  688. var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers;
  689. if (bvars.length || qualifiers.length) {
  690. var mrow = CToP.createElement('mrow');
  691. CToP.appendToken(mrow,"mo","[");
  692. var msub = CToP.createElement('msub');
  693. CToP.appendToken(msub,'mi','m');
  694. var mrow2 = CToP.createElement('mrow');
  695. for (var i = 0, l = bvars.length; i<l; i++ ) {
  696. if (i != 0) {
  697. CToP.appendToken(mrow2,'mo',',');
  698. }
  699. CToP.applyTransform(mrow2,bvars[i].childNodes[0],0);
  700. }
  701. msub.appendChild(mrow2);
  702. mrow.appendChild(msub);
  703. var msub2 = CToP.cloneNode(msub,true);
  704. CToP.appendToken(mrow,'mo','|');
  705. mrow.appendChild(msub2);
  706. CToP.appendToken(mrow,'mo','=');
  707. for (i = 0, l = args.length; i<l; i++ ) {
  708. if (i != 0) {
  709. CToP.appendToken(mrow,'mo',',');
  710. }
  711. CToP.applyTransform(mrow,args[i],0);
  712. }
  713. CToP.appendToken(mrow,'mo',';');
  714. for (i = 0, l = qualifiers.length; i<l; i++) {
  715. if (i != 0) {
  716. CToP.appendToken(mrow,'mo',',');
  717. }
  718. CToP.applyTransform(mrow,qualifiers[i],0);
  719. }
  720. CToP.appendToken(mrow,'mo',']');
  721. parentNode.appendChild(mrow);
  722. } else {
  723. var mfenced = CToP.createElement('mfenced');
  724. var mtable = CToP.createElement('mtable');
  725. for (i = 0, l = args.length; i<l; i++ ) {
  726. CToP.applyTransform(mtable,args[i],0);
  727. }
  728. mfenced.appendChild(mtable);
  729. parentNode.appendChild(mfenced);
  730. }
  731. },
  732. matrixrow: function(parentNode,contentMMLNode,precedence) {
  733. var mtr = CToP.createElement('mtr');
  734. var children = CToP.getChildren(contentMMLNode);
  735. for (var i = 0, l = children.length; i<l; i++ ) {
  736. var mtd = CToP.createElement('mtd');
  737. CToP.applyTransform(mtd,children[i],0);
  738. mtr.appendChild(mtd);
  739. }
  740. parentNode.appendChild(mtr);
  741. },
  742. condition: function(parentNode,contentMMLNode,precedence) {
  743. var mrow = CToP.createElement('mrow');
  744. var children = CToP.getChildren(contentMMLNode);
  745. for (var i = 0, l = children.length; i<l; i++ ) {
  746. CToP.applyTransform(mrow,children[i],0);
  747. }
  748. parentNode.appendChild(mrow);
  749. },
  750. lambda: function(parentNode,contentMMLNode,precedence) {
  751. var firstArg = CToP.createElement('lambda');
  752. var children = CToP.classifyChildren(contentMMLNode);
  753. var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers;
  754. var i, l, num_qualifiers;
  755. if (bvars.length) {
  756. CToP.applyTokens.lambda(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  757. } else {
  758. var mrow = CToP.createElement('mrow');
  759. for (i = 0, l = args.length; i<l; i++ ) {
  760. CToP.applyTransform(mrow,args[i],0);
  761. }
  762. if (qualifiers.length) {
  763. var msub = CToP.createElement('msub');
  764. CToP.appendToken(msub,'mo','|');
  765. var mrow2 = CToP.createElement('mrow');
  766. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  767. children = CToP.getChildren(qualifiers[i]);
  768. for (var j = 0, num_children = children.length; j<num_children; j++ ) {
  769. CToP.applyTransform(mrow2,children[j],0);
  770. }
  771. }
  772. msub.appendChild(mrow2);
  773. mrow.appendChild(msub);
  774. }
  775. parentNode.appendChild(mrow);
  776. }
  777. },
  778. ident: function(parentNode,contentMMLNode,precedence) {
  779. CToP.appendToken(parentNode,"mi","id")
  780. },
  781. domainofapplication: function(parentNode,contentMMLNode,precedence) {
  782. var merror = CToP.createElement('merror');
  783. CToP.appendToken(merror,'mtext','unexpected domainofapplication');
  784. parentNode.appendChild(merror);
  785. },
  786. share: function(parentNode,contentMMLNode,precedence) {
  787. var mi = CToP.createElement('mi');
  788. mi.setAttribute('href',contentMMLNode.getAttribute('href'));
  789. CToP.setTextContent(mi,"Share " + contentMMLNode.getAttribute('href'));
  790. parentNode.appendChild(mi);
  791. },
  792. cerror: function(parentNode,contentMMLNode,precedence) {
  793. var merror = CToP.createElement('merror');
  794. var children = CToP.getChildren(contentMMLNode);
  795. for (var i = 0, l = children.length; i<l; i++ ) {
  796. CToP.applyTransform(merror,children[i],0);
  797. }
  798. parentNode.appendChild(merror);
  799. },
  800. semantics: function(parentNode,contentMMLNode,precedence) {
  801. var mrow = CToP.createElement('mrow');
  802. var children = CToP.getChildren(contentMMLNode);
  803. if (children.length) {
  804. var z = children[0];
  805. for (var i = 0, l = children.length; i<l; i++ ) {
  806. if (children[i].nodeName === 'annotation-xml' && children[i].getAttribute('encoding') === 'MathML-Presentation') {
  807. z = children[i];
  808. break;
  809. }
  810. }
  811. CToP.applyTransform(mrow,z,0);
  812. }
  813. parentNode.appendChild(mrow);
  814. },
  815. "annotation-xml": function(parentNode,contentMMLNode,precedence) {
  816. var mrow = CToP.createElement('mrow');
  817. var children = CToP.getChildren(contentMMLNode);
  818. for (var i = 0, l = children.length; i<l; i++ ) {
  819. CToP.applyTransform(mrow,children[i],0);
  820. }
  821. parentNode.appendChild(mrow);
  822. }
  823. };
  824. CToP.tokens.reln = CToP.tokens.bind = CToP.tokens.apply;
  825. CToP.contentDictionaries = {
  826. "setname1": function(parentNode,contentMMLNode,precedence) {
  827. var sets = {
  828. C: '\u2102',
  829. N: '\u2115',
  830. P: '\u2119',
  831. Q: '\u211A',
  832. R: '\u211D',
  833. Z: '\u2124'
  834. }
  835. var name = CToP.getTextContent(contentMMLNode);
  836. CToP.appendToken(parentNode,'mi',sets[name]);
  837. },
  838. aritherror: function(parentNode,contentMMLNode,precedence) {
  839. var name = CToP.getTextContent(contentMMLNode);
  840. CToP.appendToken(parentNode,'mi',name+':');
  841. }
  842. }
  843. /* Functions to transform function/operation application tokens
  844. */
  845. CToP.applyTokens = {
  846. rem: CToP.transforms.binary('mod',3),
  847. divide: CToP.transforms.binary('/',3),
  848. remainder: CToP.transforms.binary('mod',3),
  849. implies: CToP.transforms.binary('\u21D2',3),
  850. factorof: CToP.transforms.binary('|',3),
  851. "in": CToP.transforms.binary('\u2208',3),
  852. notin: CToP.transforms.binary('\u2209',3),
  853. notsubset: CToP.transforms.binary('\u2288',2),
  854. notprsubset: CToP.transforms.binary('\u2284',2),
  855. setdiff: CToP.transforms.binary('\u2216',2),
  856. eq: CToP.transforms.infix('=',1),
  857. compose: CToP.transforms.infix('\u2218',0),
  858. "left_compose": CToP.transforms.infix('\u2218',1),
  859. xor: CToP.transforms.infix('xor',3),
  860. neq: CToP.transforms.infix('\u2260',1),
  861. gt: CToP.transforms.infix('>',1),
  862. lt: CToP.transforms.infix('<',1),
  863. geq: CToP.transforms.infix('\u2265',1),
  864. leq: CToP.transforms.infix('\u2264',1),
  865. equivalent: CToP.transforms.infix('\u2261',1),
  866. approx: CToP.transforms.infix('\u2248',1),
  867. subset: CToP.transforms.infix('\u2286',2),
  868. prsubset: CToP.transforms.infix('\u2282',2),
  869. cartesianproduct: CToP.transforms.infix('\u00D7',2),
  870. "cartesian_product": CToP.transforms.infix('\u00D7',2),
  871. vectorproduct: CToP.transforms.infix('\u00D7',2),
  872. scalarproduct: CToP.transforms.infix('.',2),
  873. outerproduct: CToP.transforms.infix('\u2297',2),
  874. sum: CToP.transforms.iteration('\u2211','='),
  875. product: CToP.transforms.iteration('\u220F','='),
  876. forall: CToP.transforms.bind('\u2200','.',','),
  877. exists: CToP.transforms.bind('\u2203','.',','),
  878. lambda: CToP.transforms.bind('\u03BB','.',','),
  879. limit: CToP.transforms.iteration('lim','\u2192'),
  880. sdev: CToP.transforms.fn('\u03c3'),
  881. determinant: CToP.transforms.fn('det'),
  882. max: CToP.transforms.minmax('max'),
  883. min: CToP.transforms.minmax('min'),
  884. real: CToP.transforms.fn('\u211b'),
  885. imaginary: CToP.transforms.fn('\u2111'),
  886. set: CToP.transforms.set('{','}'),
  887. list: CToP.transforms.set('(',')'),
  888. exp: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  889. var msup = CToP.createElement('msup');
  890. CToP.appendToken(msup,'mi','e');
  891. CToP.applyTransform(msup,args[0],0);
  892. parentNode.appendChild(msup);
  893. },
  894. union: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  895. if (bvars.length) {
  896. CToP.transforms.iteration('\u22C3','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  897. } else {
  898. CToP.transforms.infix('\u222A',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  899. }
  900. },
  901. intersect: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  902. if (bvars.length) {
  903. CToP.transforms.iteration('\u22C2','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  904. } else {
  905. var mrow = CToP.createElement('mrow');
  906. var needsBrackets = precedence>2;
  907. if (needsBrackets) {
  908. CToP.appendToken(mrow,'mo','(');
  909. }
  910. for (var j = 0, l = args.length; j<l; j++ ) {
  911. var argBrackets = false;
  912. if (j>0) {
  913. CToP.appendToken(mrow,'mo','\u2229');
  914. if (args[j].nodeName === 'apply') {
  915. var child = CToP.getChildren(args[j])[0];
  916. argBrackets = child.nodeName === 'union';
  917. }
  918. }
  919. if (argBrackets) {
  920. CToP.appendToken(mrow,'mo','(');
  921. }
  922. CToP.applyTransform(mrow,args[j],2);
  923. if (argBrackets) {
  924. CToP.appendToken(mrow,'mo',')');
  925. }
  926. }
  927. if (needsBrackets) {
  928. CToP.appendToken(mrow,'mo',')');
  929. }
  930. parentNode.appendChild(mrow);
  931. }
  932. },
  933. floor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  934. var mrow = CToP.createElement('mrow');
  935. CToP.appendToken(mrow,'mo','\u230a');
  936. CToP.applyTransform(mrow,args[0],0);
  937. CToP.appendToken(mrow,'mo','\u230b');
  938. parentNode.appendChild(mrow);
  939. },
  940. conjugate: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  941. var mover = CToP.createElement('mover');
  942. CToP.applyTransform(mover,args[0],0);
  943. CToP.appendToken(mover,'mo','\u00af');
  944. parentNode.appendChild(mover);
  945. },
  946. abs: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  947. var mrow = CToP.createElement('mrow');
  948. CToP.appendToken(mrow,'mo','|');
  949. CToP.applyTransform(mrow,args[0],0);
  950. CToP.appendToken(mrow,'mo','|');
  951. parentNode.appendChild(mrow);
  952. },
  953. and: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  954. if (bvars.length || qualifiers.length) {
  955. CToP.transforms.iteration('\u22c0','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4);
  956. } else {
  957. CToP.transforms.infix('\u2227',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  958. }
  959. },
  960. or: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  961. if (bvars.length || qualifiers.length) {
  962. CToP.transforms.iteration('\u22c1','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4);
  963. } else {
  964. CToP.transforms.infix('\u2228',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  965. }
  966. },
  967. xor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  968. if (bvars.length || qualifiers.length) {
  969. CToP.transforms.iteration('xor','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4);
  970. } else {
  971. CToP.transforms.infix('xor',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  972. }
  973. },
  974. card: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  975. var mrow = CToP.createElement('mrow');
  976. CToP.appendToken(mrow,'mo','|');
  977. CToP.applyTransform(mrow,args[0],0);
  978. CToP.appendToken(mrow,'mo','|');
  979. parentNode.appendChild(mrow);
  980. },
  981. mean: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  982. if (args.length === 1) {
  983. var mover = CToP.createElement('mover');
  984. CToP.applyTransform(mover,args[0],0);
  985. CToP.appendToken(mover,'mo','\u00af');
  986. parentNode.appendChild(mover);
  987. } else {
  988. parentNode.appendChild(CToP.createmfenced(args,'\u27e8','\u27e9'));
  989. }
  990. },
  991. moment: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  992. var degree, momentabout, children, i, j, l;
  993. for (i = 0, l = qualifiers.length; i<l; i++ ) {
  994. if (qualifiers[i].nodeName === 'degree') {
  995. degree = qualifiers[i];
  996. } else if (qualifiers[i].nodeName === 'momentabout') {
  997. momentabout = qualifiers[i];
  998. }
  999. }
  1000. var mrow = CToP.createElement('mrow');
  1001. CToP.appendToken(mrow,'mo','\u27e8');
  1002. var argrow = CToP.createElement('mrow');
  1003. if (args.length>1) {
  1004. argrow.appendChild(CToP.createmfenced(args,'(',')'));
  1005. } else {
  1006. CToP.applyTransform(argrow,args[0],0);
  1007. }
  1008. if (degree) {
  1009. var msup = CToP.createElement('msup');
  1010. msup.appendChild(argrow);
  1011. children = CToP.getChildren(degree);
  1012. for (j = 0, l = children.length; j<l; j++ ) {
  1013. CToP.applyTransform(msup,children[j],0);
  1014. }
  1015. mrow.appendChild(msup);
  1016. } else {
  1017. mrow.appendChild(argrow);
  1018. }
  1019. CToP.appendToken(mrow,'mo','\u27e9');
  1020. if (momentabout) {
  1021. var msub = CToP.createElement('msub');
  1022. msub.appendChild(mrow);
  1023. children = CToP.getChildren(momentabout);
  1024. for (j = 0, l = children.length; j<l; j++ ) {
  1025. CToP.applyTransform(msub,children[j],0);
  1026. }
  1027. parentNode.appendChild(msub);
  1028. } else {
  1029. parentNode.appendChild(mrow);
  1030. }
  1031. },
  1032. variance: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1033. var mrow = CToP.createElement('mrow');
  1034. var msup = CToP.createElement('msup');
  1035. CToP.appendToken(msup,'mo','\u03c3');
  1036. CToP.appendToken(msup,'mn','2');
  1037. mrow.appendChild(msup);
  1038. CToP.appendToken(mrow,'mo','\u2061');
  1039. mrow.appendChild(CToP.createmfenced(args,'(',')'));
  1040. parentNode.appendChild(mrow);
  1041. },
  1042. grad: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1043. var mrow = CToP.createElement('mrow');
  1044. CToP.appendToken(mrow,'mo','\u2207');
  1045. CToP.appendToken(mrow,'mo','\u2061');
  1046. mrow.appendChild(CToP.createmfenced(args,'(',')'));
  1047. parentNode.appendChild(mrow);
  1048. },
  1049. laplacian: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1050. var mrow = CToP.createElement('mrow');
  1051. var msup = CToP.createElement('msup');
  1052. CToP.appendToken(msup,'mo','\u2207');
  1053. CToP.appendToken(msup,'mn','2');
  1054. mrow.appendChild(msup);
  1055. CToP.appendToken(mrow,'mo','\u2061');
  1056. mrow.appendChild(CToP.createmfenced(args,'(',')'));
  1057. parentNode.appendChild(mrow);
  1058. },
  1059. curl: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1060. var mrow = CToP.createElement('mrow');
  1061. CToP.appendToken(mrow,'mo','\u2207');
  1062. CToP.appendToken(mrow,'mo','\u00d7');
  1063. var needsBrackets = args[0].nodeName === 'apply';
  1064. if (needsBrackets) {
  1065. mrow.appendChild(CToP.createmfenced(args,'(', ')'));
  1066. }
  1067. else {
  1068. CToP.applyTransform(mrow,args[0],precedence);
  1069. }
  1070. parentNode.appendChild(mrow);
  1071. },
  1072. divergence: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1073. var mrow = CToP.createElement('mrow');
  1074. CToP.appendToken(mrow,'mo','\u2207');
  1075. CToP.appendToken(mrow,'mo','\u22c5');
  1076. var needsBrackets = args[0].nodeName === 'apply';
  1077. if (needsBrackets) {
  1078. mrow.appendChild(CToP.createmfenced(args,'(', ')'));
  1079. }
  1080. else {
  1081. CToP.applyTransform(mrow,args[0],precedence);
  1082. }
  1083. parentNode.appendChild(mrow);
  1084. },
  1085. not: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1086. var mrow = CToP.createElement('mrow');
  1087. CToP.appendToken(mrow,'mo','\u00ac');
  1088. var needsBrackets = args[0].nodeName === 'apply' || args[0].nodeName === 'bind';
  1089. if (needsBrackets) {
  1090. CToP.appendToken(mrow,'mo','(');
  1091. }
  1092. CToP.applyTransform(mrow,args[0],precedence);
  1093. if (needsBrackets) {
  1094. CToP.appendToken(mrow,'mo',')');
  1095. }
  1096. parentNode.appendChild(mrow)
  1097. },
  1098. divide: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1099. var mfrac = CToP.createElement('mfrac');
  1100. CToP.applyTransform(mfrac,args[0],0);
  1101. CToP.applyTransform(mfrac,args[1],0);
  1102. parentNode.appendChild(mfrac);
  1103. },
  1104. tendsto: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1105. var type;
  1106. if (firstArg.nodeName === 'tendsto') {
  1107. type = firstArg.getAttribute('type');
  1108. } else {
  1109. type = CToP.getTextContent(args[0]);
  1110. args = args.slice(1);
  1111. }
  1112. var name = (type === 'above')? '\u2198' :
  1113. (type === 'below') ? '\u2197' : '\u2192' ;
  1114. CToP.transforms.binary(name,2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence);
  1115. },
  1116. minus: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1117. var tokenPrecedence = args.length === 1 ? 5 : 2;
  1118. var mrow = CToP.createElement('mrow');
  1119. var needsBrackets = tokenPrecedence<precedence;
  1120. if (needsBrackets) {
  1121. CToP.appendToken(mrow,'mo','(');
  1122. }
  1123. if (args.length === 1) {
  1124. CToP.appendToken(mrow,'mo','-');
  1125. CToP.applyTransform(mrow,args[0],tokenPrecedence);
  1126. } else {
  1127. CToP.applyTransform(mrow,args[0],tokenPrecedence);
  1128. CToP.appendToken(mrow,'mo','-');
  1129. var bracketArg;
  1130. if (args[1].nodeName === 'apply') {
  1131. var argOp = CToP.getChildren(args[1])[0];
  1132. bracketArg = argOp.nodeName === 'plus' || argOp.nodeName === 'minus';
  1133. }
  1134. if (bracketArg) {
  1135. CToP.appendToken(mrow,'mo','(');
  1136. }
  1137. CToP.applyTransform(mrow,args[1],tokenPrecedence);
  1138. if (bracketArg) {
  1139. CToP.appendToken(mrow,'mo',')');
  1140. }
  1141. }
  1142. if (needsBrackets) {
  1143. CToP.appendToken(mrow,'mo',')');
  1144. }
  1145. parentNode.appendChild(mrow);
  1146. },
  1147. "complex-cartesian": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1148. var mrow = CToP.createElement('mrow');
  1149. CToP.applyTransform(mrow,args[0],0);
  1150. CToP.appendToken(mrow,'mo','+');
  1151. CToP.applyTransform(mrow,args[1],0);
  1152. CToP.appendToken(mrow,'mo','\u2062');
  1153. CToP.appendToken(mrow,'mi','i');
  1154. parentNode.appendChild(mrow);
  1155. },
  1156. "complex-polar": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1157. var mrow = CToP.createElement('mrow');
  1158. CToP.applyTransform(mrow,args[0],0);
  1159. CToP.appendToken(mrow,'mo','\u2062');
  1160. var msup = CToP.createElement('msup');
  1161. CToP.appendToken(msup,'mi','e');
  1162. var exponent = CToP.createElement('mrow');
  1163. CToP.applyTransform(exponent,args[1],0);
  1164. CToP.appendToken(exponent,'mo','\u2062');
  1165. CToP.appendToken(exponent,'mi','i');
  1166. msup.appendChild(exponent);
  1167. mrow.appendChild(msup);
  1168. parentNode.appendChild(mrow);
  1169. },
  1170. integer: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1171. CToP.applyTransform(parentNode,args[0],0);
  1172. },
  1173. "based-integer": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1174. var msub = CToP.createElement('msub');
  1175. CToP.applyTransform(msub,args[1],0);
  1176. CToP.applyTransform(msub,args[0],0);
  1177. parentNode.appendChild(msub);
  1178. },
  1179. rational: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1180. var mfrac = CToP.createElement('mfrac');
  1181. CToP.applyTransform(mfrac,args[0],0);
  1182. CToP.applyTransform(mfrac,args[1],0);
  1183. parentNode.appendChild(mfrac);
  1184. },
  1185. times: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1186. var mrow = CToP.createElement('mrow');
  1187. var needsBrackets = precedence>3;
  1188. if (needsBrackets) {
  1189. CToP.appendToken(mrow,'mo','(');
  1190. }
  1191. for (var j = 0, l = args.length; j<l; j++ ) {
  1192. if (j>0) {
  1193. CToP.appendToken(mrow,'mo',(args[j].nodeName === 'cn') ? "\u00D7" :"\u2062");
  1194. }
  1195. CToP.applyTransform(mrow,args[j],3);
  1196. }
  1197. if (needsBrackets) {
  1198. CToP.appendToken(mrow,'mo',')');
  1199. }
  1200. parentNode.appendChild(mrow);
  1201. },
  1202. plus: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1203. var mrow = CToP.createElement('mrow');
  1204. var needsBrackets = precedence>2;
  1205. if (needsBrackets) {
  1206. CToP.appendToken(mrow,'mo','(');
  1207. }
  1208. for (var j = 0, l = args.length; j<l; j++ ) {
  1209. var arg = args[j];
  1210. var children = CToP.getChildren(arg);
  1211. if (j>0) {
  1212. var n;
  1213. if (CToP.settings.collapsePlusMinus) {
  1214. if (arg.nodeName === 'cn' && !(children.length) && (n = Number(CToP.getTextContent(arg))) <0) {
  1215. CToP.appendToken(mrow,'mo','\u2212');
  1216. CToP.appendToken(mrow,'mn', -n);
  1217. } else if (arg.nodeName === 'apply' && children.length === 2 && children[0].nodeName === 'minus') {
  1218. CToP.appendToken(mrow,'mo','\u2212');
  1219. CToP.applyTransform(mrow,children[1],2);
  1220. } else if (arg.nodeName === 'apply' && children.length>2 && children[0].nodeName === 'times' && children[1].nodeName === 'cn' && (n = Number(CToP.getTextContent(children[1]))) < 0) {
  1221. CToP.appendToken(mrow,'mo','\u2212');
  1222. children[1].textContent = -n; // OK to change MathML since it is being discarded afterward
  1223. CToP.applyTransform(mrow,arg,2);
  1224. } else{
  1225. CToP.appendToken(mrow,'mo','+');
  1226. CToP.applyTransform(mrow,arg,2);
  1227. }
  1228. } else {
  1229. CToP.appendToken(mrow,'mo','+');
  1230. CToP.applyTransform(mrow,arg,2);
  1231. }
  1232. } else {
  1233. CToP.applyTransform(mrow,arg,2);
  1234. }
  1235. }
  1236. if (needsBrackets) {
  1237. CToP.appendToken(mrow,'mo',')');
  1238. }
  1239. parentNode.appendChild(mrow);
  1240. },
  1241. transpose: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1242. var msup = CToP.createElement('msup');
  1243. CToP.applyTransform(msup,args[0],precedence);
  1244. CToP.appendToken(msup,'mi','T');
  1245. parentNode.appendChild(msup);
  1246. },
  1247. power: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1248. var msup = CToP.createElement('msup');
  1249. CToP.applyTransform(msup,args[0],3);
  1250. CToP.applyTransform(msup,args[1],precedence);
  1251. parentNode.appendChild(msup);
  1252. },
  1253. selector: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1254. var msub = CToP.createElement('msub');
  1255. var mrow = args ? args[0]: CToP.createElement('mrow');
  1256. CToP.applyTransform(msub,mrow,0);
  1257. var mrow2 = CToP.createElement('mrow');
  1258. for (var i = 1, l = args.length; i<l; i++ ) {
  1259. if (i != 1) {
  1260. CToP.appendToken(mrow2,'mo',',');
  1261. }
  1262. CToP.applyTransform(mrow2,args[i],0);
  1263. }
  1264. msub.appendChild(mrow2);
  1265. parentNode.appendChild(msub);
  1266. },
  1267. log: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1268. var mrow = CToP.createElement('mrow');
  1269. var mi = CToP.createElement('mi');
  1270. CToP.setTextContent(mi,'log');
  1271. if (qualifiers.length && qualifiers[0].nodeName === 'logbase') {
  1272. var msub = CToP.createElement('msub');
  1273. msub.appendChild(mi);
  1274. CToP.applyTransform(msub,CToP.getChildren(qualifiers[0])[0],0);
  1275. mrow.appendChild(msub);
  1276. } else {
  1277. mrow.appendChild(mi);
  1278. }
  1279. CToP.applyTransform(mrow,args[0],7);
  1280. parentNode.appendChild(mrow);
  1281. },
  1282. "int": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1283. var mrow = CToP.createElement('mrow');
  1284. var mo = CToP.createElement('mo');
  1285. CToP.setTextContent(mo,'\u222B');
  1286. var msubsup = CToP.createElement('msubsup');
  1287. msubsup.appendChild(mo);
  1288. var mrow1 = CToP.createElement('mrow');
  1289. var children, i, j, l, num_qualifiers, num_children;
  1290. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  1291. if (qualifiers[i].nodeName === 'lowlimit'||
  1292. qualifiers[i].nodeName === 'condition'||
  1293. qualifiers[i].nodeName === 'domainofapplication')
  1294. {
  1295. children = CToP.getChildren(qualifiers[i]);
  1296. for (j = 0, num_children = children.length; j<num_children; j++ ) {
  1297. CToP.applyTransform(mrow1,children[j],0);
  1298. }
  1299. } else {
  1300. children = CToP.getChildren(qualifiers[i]);
  1301. if (qualifiers[i].nodeName === 'interval' && children.length === 2) {
  1302. CToP.applyTransform(mrow1,children[0],0);
  1303. }
  1304. }
  1305. }
  1306. msubsup.appendChild(mrow1);
  1307. var mrow2 = CToP.createElement('mrow');
  1308. for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) {
  1309. if (qualifiers[i].nodeName === 'uplimit') {
  1310. children = CToP.getChildren(qualifiers[i]);
  1311. for (j = 0, num_children = children.length; j<num_children; j++ ) {
  1312. CToP.applyTransform(mrow2,children[j],0);
  1313. }
  1314. break;
  1315. } else if (qualifiers[i].nodeName === 'interval' ) {
  1316. children = CToP.getChildren(qualifiers[i]);
  1317. CToP.applyTransform(mrow2,children[children.length-1],0);
  1318. break;
  1319. }
  1320. }
  1321. msubsup.appendChild(mrow2);
  1322. mrow.appendChild(msubsup);
  1323. for (i = 0, l = args.length; i<l; i++ ) {
  1324. CToP.applyTransform(mrow,args[i],0);
  1325. }
  1326. for (i = 0, l = bvars.length; i<l; i++ ) {
  1327. var bvar = bvars[i];
  1328. children = CToP.getChildren(bvar);
  1329. if (children.length) {
  1330. var mrow3 = CToP.createElement("mrow");
  1331. CToP.appendToken(mrow3,'mi','d');
  1332. CToP.applyTransform(mrow3,children[0],0);
  1333. mrow.appendChild(mrow3);
  1334. }
  1335. }
  1336. parentNode.appendChild(mrow);
  1337. },
  1338. inverse: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1339. var msup = CToP.createElement('msup');
  1340. var arg = (args.length) ? args[0] : CToP.createElement('mrow');
  1341. CToP.applyTransform(msup,arg,precedence);
  1342. var mfenced = CToP.createElement('mfenced');
  1343. CToP.appendToken(mfenced,'mn','-1');
  1344. msup.appendChild(mfenced);
  1345. parentNode.appendChild(msup);
  1346. },
  1347. quotient: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1348. var mrow = CToP.createElement('mrow');
  1349. CToP.appendToken(mrow,'mo','\u230A');
  1350. if (args.length) {
  1351. CToP.applyTransform(mrow,args[0],0);
  1352. CToP.appendToken(mrow,'mo','/');
  1353. if (args.length>1) {
  1354. CToP.applyTransform(mrow,args[1],0);
  1355. }
  1356. }
  1357. CToP.appendToken(mrow,'mo','\u230B');
  1358. parentNode.appendChild(mrow);
  1359. },
  1360. factorial: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1361. var mrow = CToP.createElement('mrow');
  1362. CToP.applyTransform(mrow,args[0],4);
  1363. CToP.appendToken(mrow,'mo','!');
  1364. parentNode.appendChild(mrow);
  1365. },
  1366. root: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1367. var mr;
  1368. if (firstArg.nodeName === 'root' && (qualifiers.length === 0 || (qualifiers[0].nodeName === 'degree' && CToP.getTextContent(qualifiers[0]) === '2'))) {
  1369. mr = CToP.createElement('msqrt');
  1370. for (var i = 0, l = args.length; i<l; i++ ) {
  1371. CToP.applyTransform(mr,args[i],0);
  1372. }
  1373. } else {
  1374. mr = CToP.createElement('mroot');
  1375. CToP.applyTransform(mr,args[0],0);
  1376. var arg = (firstArg.nodeName === 'root') ? qualifiers[0].childNodes[0] : args[1];
  1377. CToP.applyTransform(mr,arg,0);
  1378. }
  1379. parentNode.appendChild(mr);
  1380. },
  1381. diff: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1382. if (bvars.length) { // d/dx form
  1383. var outNode;
  1384. var mfrac = CToP.createElement('mfrac');
  1385. var toprow = CToP.createElement('mrow');
  1386. var bottomrow = CToP.createElement('mrow');
  1387. mfrac.appendChild(toprow);
  1388. mfrac.appendChild(bottomrow);
  1389. var bvar, degreeNode, msup, mrow;
  1390. var d = CToP.createElement('mi');
  1391. CToP.setTextContent(d,'d');
  1392. var children = CToP.getChildren(bvars[0]);
  1393. for (var j = 0, l = children.length; j<l; j++ ) {
  1394. if (children[j].nodeName === 'degree') {
  1395. var childNode = CToP.getChildren(children[j])[0];
  1396. if (CToP.getTextContent(childNode) != '1') {
  1397. degreeNode = childNode;
  1398. msup = CToP.createElement('msup');
  1399. msup.appendChild(d);
  1400. d = msup;
  1401. CToP.applyTransform(d,degreeNode,0);
  1402. }
  1403. } else {
  1404. bvar = children[j];
  1405. }
  1406. }
  1407. toprow.appendChild(d);
  1408. if (args.length) {
  1409. switch(args[0].nodeName) {
  1410. case 'apply':
  1411. case 'bind':
  1412. case 'reln':
  1413. mrow = CToP.createElement('mrow');
  1414. mrow.appendChild(mfrac);
  1415. CToP.applyTransform(mrow,args[0],3);
  1416. outNode = mrow;
  1417. break;
  1418. default:
  1419. CToP.applyTransform(toprow,args[0],0);
  1420. outNode = mfrac;
  1421. }
  1422. }
  1423. CToP.appendToken(bottomrow,'mi','d');
  1424. if (degreeNode) {
  1425. var msup2 = CToP.createElement('msup');
  1426. CToP.applyTransform(msup2,bvar,0);
  1427. CToP.applyTransform(msup2,degreeNode,0);
  1428. bottomrow.appendChild(msup2);
  1429. } else {
  1430. CToP.applyTransform(bottomrow,bvar,0);
  1431. }
  1432. parentNode.appendChild(outNode);
  1433. } else { // f' form
  1434. msup = CToP.createElement('msup');
  1435. mrow = CToP.createElement('mrow');
  1436. msup.appendChild(mrow);
  1437. CToP.applyTransform(mrow,args[0],0);
  1438. CToP.appendToken(msup,'mo','\u2032'); // tick
  1439. parentNode.appendChild(msup);
  1440. }
  1441. },
  1442. partialdiff: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) {
  1443. var msup, msub, mrow;
  1444. var mfrac = CToP.createElement('mfrac');
  1445. var toprow = CToP.createElement('mrow');
  1446. var bottomrow = CToP.createElement('mrow');
  1447. mfrac.appendChild(toprow);
  1448. mfrac.appendChild(bottomrow);
  1449. var differendNode, degree, children;
  1450. if (bvars.length === 0 && args.length === 2 && args[0].nodeName === 'list') {
  1451. if (args[1].nodeName === 'lambda') { // `d^(n+m)/(dx^n dy^m) f` form, through a lambda
  1452. degree = CToP.getChildren(args[0]).length;
  1453. if (degree != 1) {
  1454. msup = CToP.createElement('msup');
  1455. CToP.appendToken(msup,'mo','\u2202'); // curly d
  1456. CToP.appendToken(msup,'mn',degree);
  1457. toprow.appendChild(msup);
  1458. } else {
  1459. CToP.appendToken(toprow,'mo','\u2202');
  1460. }
  1461. children = CToP.getChildren(args[1]);
  1462. differendNode = children[children.length - 1]; // thing being differentiated
  1463. var bvarNames = [];
  1464. var lambdaChildren = CToP.getChildren(args[1]); // names of bound variables
  1465. var lambdaSequence = CToP.getChildren(args[0]); // indices of bound variable names, in order
  1466. for (var i = 0, l = lambdaChildren.length; i<l; i++ ) {
  1467. if (lambdaChildren[i].nodeName === 'bvar') {
  1468. bvarNames.push(CToP.getChildren(lambdaChildren[i])[0]);
  1469. }
  1470. }
  1471. var lastN = null;
  1472. degree = 0;
  1473. function addDiff(n,degree) {
  1474. CToP.appendToken(bottomrow,'mo','\u2202');
  1475. var bvar = bvarNames[n];
  1476. if (degree>1) {
  1477. var msup = CToP.createElement('msup');
  1478. CToP.applyTransform(msup,bvar,0);
  1479. CToP.appendToken(msup,'mn',degree);
  1480. bottomrow.appendChild(msup);
  1481. } else {
  1482. CToP.applyTransform(bottomrow,bvar,0);
  1483. }
  1484. }
  1485. for (i = 0, l = lambdaSequence.length; i<l; i++ ) {
  1486. var n = Number(CToP.getTextContent(lambdaSequence[i]))-1;
  1487. if (lastN !== null && n != lastN) {
  1488. addDiff(lastN,degree);
  1489. degree = 0;
  1490. }
  1491. lastN = n;
  1492. degree += 1;
  1493. }
  1494. if (lastN) {
  1495. addDiff(lastN,degree);
  1496. }
  1497. } else { // `D_i_j f` form
  1498. mrow = CToP.createElement('mrow');
  1499. msub = CToP.createElement('msub');
  1500. CToP.appendToken(msub,'mi','D');
  1501. var bvar = CToP.getChildren(args[0]);
  1502. msub.appendChild(CToP.createmfenced(bvar,'',''));
  1503. mrow.appendChild(msub);
  1504. CToP.applyTransform(mrow,args[1],0);
  1505. parentNode.appendChild(mrow);
  1506. return;
  1507. }
  1508. } else { // `d^(n+m)/(dx^n dy^m) f` form, with bvars
  1509. msup = CToP.createElement('msup');
  1510. toprow.appendChild(msup);
  1511. CToP.appendToken(msup,'mo','\u2202');
  1512. var degreeRow = CToP.createElement('mrow');
  1513. msup.appendChild(degreeRow);
  1514. var qualifier;
  1515. if (qualifiers.length && qualifiers[0].nodeName === 'degree' && CToP.getChildren(qualifiers[0]).length) {
  1516. qualifier = CToP.getChildren(qualifiers[0])[0];
  1517. CToP.applyTransform(degreeRow,qualifier,0);
  1518. } else {
  1519. degree = 0;
  1520. var hadFirst = false;
  1521. for (i = 0, l = bvars.length; i<l; i++ ) {
  1522. children = CToP.getChildren(bvars[i]);
  1523. if (children.length === 2) {
  1524. for (var j = 0;j<2;j++) {
  1525. if (children[j].nodeName === 'degree') {
  1526. if (/^\s*\d+\s*$/.test(CToP.getTextContent(children[j]))) {
  1527. degree += Number(CToP.getTextContent(children[j]));
  1528. } else {
  1529. if (hadFirst) {
  1530. CToP.appendToken(degreeRow,'mo','+');
  1531. }
  1532. hadFirst = true;
  1533. CToP.applyTransform(degreeRow,CToP.getChildren(children[j])[0],0);
  1534. }
  1535. }
  1536. }
  1537. } else {
  1538. degree++;
  1539. }
  1540. }
  1541. if (degree>0) {
  1542. if (hadFirst) {
  1543. CToP.appendToken(degreeRow,'mo','+');
  1544. }
  1545. CToP.appendToken(degreeRow,'mn',degree);
  1546. }
  1547. }
  1548. if (args.length) {
  1549. differendNode = args[0];
  1550. }
  1551. for (i = 0, l = bvars.length; i<l; i++ ) {
  1552. CToP.appendToken(bottomrow,'mo','\u2202');
  1553. children = CToP.getChildren(bvars[i]);
  1554. if (children.length === 2) {
  1555. for (j = 0;j<2;j++) {
  1556. if (children[j].nodeName === 'degree') {
  1557. var msup2 = CToP.createElement('msup');
  1558. CToP.applyTransform(msup2,children[1-j],0);
  1559. var bvarDegreeNode = CToP.getChildren(children[j])[0];
  1560. CToP.applyTransform(msup2,bvarDegreeNode,0);
  1561. bottomrow.appendChild(msup2);
  1562. }
  1563. }
  1564. } else if (children.length === 1) {
  1565. CToP.applyTransform(bottomrow,children[0],0);
  1566. }
  1567. }
  1568. }
  1569. if (differendNode) {
  1570. switch(differendNode.nodeName) {
  1571. case 'apply':
  1572. case 'bind':
  1573. case 'reln':
  1574. mrow = CToP.createElement('mrow');
  1575. mrow.appendChild(mfrac);
  1576. CToP.applyTransform(mrow,differendNode,3);
  1577. outNode = mrow;
  1578. break;
  1579. default:
  1580. CToP.applyTransform(toprow,differendNode,0);
  1581. outNode = mfrac;
  1582. }
  1583. } else {
  1584. outNode = mfrac;
  1585. }
  1586. parentNode.appendChild(outNode);
  1587. }
  1588. };
  1589. CToP.applyTokens.size = CToP.applyTokens.card;
  1590. return CToP;
  1591. })(MathJax.Hub);
  1592. MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () {
  1593. var MATHML = MathJax.InputJax.MathML;
  1594. var CToP = MathJax.Extension["MathML/content-mathml"];
  1595. CToP.mbase = MathJax.ElementJax.mml.mbase;
  1596. CToP.MML = MathJax.ElementJax.mml;
  1597. MATHML.DOMfilterHooks.Add(function (data) {
  1598. data.math = CToP.transformElement(data.math);
  1599. });
  1600. MathJax.Hub.Startup.signal.Post("MathML/content-mathml Ready");
  1601. });
  1602. MathJax.Ajax.loadComplete("[MathJax]/extensions/MathML/content-mathml.js");