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