content-mathml.js 62 KB

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