diff options
Diffstat (limited to 'js/mathjax/extensions/MathML')
-rw-r--r-- | js/mathjax/extensions/MathML/content-mathml.js | 1745 | ||||
-rw-r--r-- | js/mathjax/extensions/MathML/mml3.js | 786 |
2 files changed, 2531 insertions, 0 deletions
diff --git a/js/mathjax/extensions/MathML/content-mathml.js b/js/mathjax/extensions/MathML/content-mathml.js new file mode 100644 index 0000000..250ce43 --- /dev/null +++ b/js/mathjax/extensions/MathML/content-mathml.js @@ -0,0 +1,1745 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ + +/************************************************************* + * + * MathJax/extensions/MathML/content-mathml.js + * + * This file provides methods to convert Content-MathML to + * Presentation MathML for processing by MathJax. The transform is + * performed in a DOM filter for the MathML input jax, so that the + * Show Math As menu will still show the Original MathML as Content MathML, + * but the Presentation MathML can be obtained from the main MathML menu. + * + * To load it, include + * + * MathML: { + * extensions: ["content-mathml.js"] + * } + * + * in your configuration. + * + * A portion of this file is taken from ctop.js which is + * Copyright (c) David Carlisle 2001, 2002, 2008, 2009, 2013, + * and is used by permission of David Carlisle, who has agreed to allow us + * to release it under the Apache2 license (see below). That portion is + * indicated via comments. + * + * The remainder falls under the copyright that follows. + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2020 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +MathJax.Extension["MathML/content-mathml"] = (function(HUB) { + /* + * Content MathML to Presentation MathML conversion + * + * based on David Carlisle's ctop.js - https://web-xslt.googlecode.com/svn/trunk/ctop/ctop.js + * + */ + + + var isMSIE = HUB.Browser.isMSIE; + + if (isMSIE) { + try {document.namespaces.add("m","http://www.w3.org/1998/Math/MathML")} catch (err) {} + } + + var CONFIG = HUB.CombineConfig("MathML.content-mathml",{ + // render `a+(-b)` as `a-b`? + collapsePlusMinus: true, + + /* mathvariant to use with corresponding <ci> type attribute */ + cistyles: { + vector: 'bold-italic', + matrix: 'bold-upright' + }, + + /* Symbol names to translate to characters + */ + symbols: { + gamma: '\u03B3' + } + + }); + + var CToP = { + version: "2.7.9", + settings: CONFIG, + + /* Transform the given <math> elements from Content MathML to Presentation MathML and replace the original elements + */ + transformElements: function(elements) { + for (var i = 0, l = elements.length; i<l; i++ ) { + var mathNode = CToP.transformElement(elements[i]); + elements[i].parentNode.replaceChild(mathNode,elements[i]); + } + }, + + /* Transform a Content MathML element into Presentation MathML, and return the new element + */ + transformElement: function(element) { + if (element.nodeName.indexOf(":") >= 0) element = CToP.cloneNode(element,true); // removes namespaces + var mathNode = CToP.cloneNode(element); + for (var j = 0, l = element.childNodes.length; j<l; j++ ) { + CToP.applyTransform(mathNode,element.childNodes[j],0); + } + return mathNode; + }, + + getTextContent: function(element) { + return element.text !== undefined ? element.text : element.innerText !== undefined ? element.innerText : element.textContent; + }, + + setTextContent: function(element,textContent) { + for (var i = 0, l = element.childNodes.length; i<l; i++) { + if (element.childNodes[i].nodeType === 3) { + element.removeChild(element.childNodes[i]); + i--; + l--; + } + } + element.appendChild(document.createTextNode(textContent)); + }, + + cloneNode: function(element,deep) { + var clone, i, l; + if (element.nodeType === 1) { + clone = CToP.createElement(element.nodeName); + for (i = 0, l = element.attributes.length; i<l; i++ ) { + clone.setAttribute(element.attributes[i].nodeName,element.attributes[i].nodeValue); + } + if (deep) { + for (i = 0, l = element.childNodes.length; i<l; i++ ) { + var clonedChild = CToP.cloneNode(element.childNodes[i],true); + clone.appendChild(clonedChild); + } + } + } else if (element.nodeType === 3) { + clone = document.createTextNode(element.nodeValue); + } + return clone; + }, + + /* Create an element with given name, belonging to the MathML namespace + */ + createElement: function(name) { + name = name.replace(/^.*:/,""); // remove namespace + return (document.createElementNS ? + document.createElementNS("http://www.w3.org/1998/Math/MathML",name) : + document.createElement("m:"+name)); + }, + + /* Get node's children + */ + getChildren: function(node) { + var children = []; + for (var j = 0, l = node.childNodes.length; j<l; j++ ) { + if (node.childNodes[j].nodeType === 1) { + children.push(node.childNodes[j]); + } + } + return children; + }, + + /* Classify node's children as argumentss, variable bindings, or qualifiers + */ + classifyChildren: function(contentMMLNode) { + var args = [], bvars = [], qualifiers = []; + for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) { + if (contentMMLNode.childNodes[j].nodeType === 1) { + var childNode = contentMMLNode.childNodes[j], name = childNode.nodeName; + if (name === 'bvar') { + bvars.push(childNode); + } else if (name === 'condition'|| + name === 'degree'|| + name === 'momentabout'|| + name === 'logbase'|| + name === 'lowlimit'|| + name === 'uplimit'|| + (name === 'interval' && args.length<2)|| + name === 'domainofapplication') { + qualifiers.push(childNode); + } else { + args.push(childNode); + } + } + } + return { + args:args, + bvars:bvars, + qualifiers:qualifiers + }; + }, + + /* Add an element with given name and text content + */ + appendToken: function(parentNode,name,textContent) { + var element = CToP.createElement(name); + textContent = textContent.replace(/^\s+/,"").replace(/\s+$/,""); + if (name === 'mn' && textContent.substr(0,1) === "-") { + // + // use <mrow><mo>−</mo><mn>n</mn></mrow> instead of <mn>-n</mn> + // + element.appendChild(document.createTextNode(textContent.substr(1))); + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u2212'); + mrow.appendChild(element); + element = mrow; + } else { + element.appendChild(document.createTextNode(textContent)); + } + parentNode.appendChild(element); + return element; + }, + + /* Transform a Content MathML node to Presentation MathML node(s), and attach it to the parent + */ + applyTransform: function(parentNode,contentMMLNode,precedence) { + if (!contentMMLNode) { + var merror = CToP.createElement('merror'); + CToP.appendToken(merror,'mtext','Missing child node'); + parentNode.appendChild(merror); + return; + } + var nodeName = contentMMLNode.nodeName.replace(/.*:/,''); + if (contentMMLNode.nodeType === 1) { + if (CToP.tokens[nodeName]) { + CToP.tokens[nodeName](parentNode,contentMMLNode,precedence); + } else if (contentMMLNode.childNodes.length === 0) { + var mml = CToP.MML[nodeName]; + if (mml && mml.isa && mml.isa(CToP.mbase)) { + parentNode.appendChild(CToP.cloneNode(contentMMLNode)); + } else { + CToP.appendToken(parentNode,'mi',nodeName); + } + } else { + var clonedChild = CToP.cloneNode(contentMMLNode); + parentNode.appendChild(clonedChild); + for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) { + CToP.applyTransform(clonedChild,contentMMLNode.childNodes[j],precedence); + } + } + } else if (contentMMLNode.nodeType === 3) { + parentNode.appendChild(CToP.cloneNode(contentMMLNode)); + } + }, + + /* Make an mfenced environment + */ + createmfenced: function(children,open,close) { + var mf = CToP.createElement('mfenced'); + mf.setAttribute('open',open); + mf.setAttribute('close',close); + for (var j = 0, l = children.length; j<l; j++ ) { + CToP.applyTransform(mf,children[j],0); + } + return mf; + }, + + transforms: { + + /* Transform an identifier symbol + */ + identifier: function(textContent) { + return function(parentNode,contentMMLNode,precedence) { + CToP.appendToken(parentNode,'mi',textContent); + } + }, + + /* Transform a set or set-like notation + */ + set: function(open,close) { + var bindSet = CToP.transforms.bind('',',','|'); + return function(parentNode,contentMMLNode) { + var children = CToP.classifyChildren(contentMMLNode); + + var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers; + if (bvars.length) { + var firstArg = children.args[0]; + args = args.slice(1); + var mfenced = CToP.createElement('mfenced'); + mfenced.setAttribute('open',open); + mfenced.setAttribute('close',close); + bindSet(mfenced,contentMMLNode,firstArg,args,bvars,qualifiers,0); + parentNode.appendChild(mfenced); + } else { + parentNode.appendChild(CToP.createmfenced(args,open,close)); + } + } + }, + + /* Transform a content token to a presentation token + * + * (function factory) + * @param {string} name - name of the corresponding presentation MML tag + */ + token: function(name) { + return function(parentNode,contentMMLNode) { + if (contentMMLNode.childNodes.length === 1 && contentMMLNode.childNodes[0].nodeType === 3) { + CToP.appendToken(parentNode,name,CToP.getTextContent(contentMMLNode)); + } else { + var mrow = CToP.createElement('mrow'); + for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) { + if (contentMMLNode.childNodes[j].nodeType === 3) { + CToP.appendToken(parentNode,name,CToP.getTextContent(contentMMLNode.childNodes[j])); + }else{ + CToP.applyTransform(mrow,contentMMLNode.childNodes[j],0); + } + } + if (mrow.childNodes.length) { + parentNode.appendChild(mrow); + } + } + } + }, + + /* Transform a binary operation + * + * (function factory) + */ + binary: function(name,tokenPrecedence) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = tokenPrecedence<precedence || (tokenPrecedence == precedence && name === "-"); + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + if (args.length>1) { + CToP.applyTransform(mrow,args[0],tokenPrecedence); + } + CToP.appendToken(mrow,'mo',name); + if (args.length>0) { + var z = args[(args.length === 1)?0:1]; + CToP.applyTransform(mrow,z,tokenPrecedence); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + /* Transform an infix operator + * + * (function factory) + */ + infix: function(name,tokenPrecedence) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>tokenPrecedence; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j<l; j++ ) { + if (j>0) { + CToP.appendToken(mrow,'mo',name); + } + CToP.applyTransform(mrow,args[j],tokenPrecedence); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + /* Transform an iterated operation, e.g. summation + * + * (function factory + */ + iteration: function(name,limitSymbol) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var mo = CToP.createElement('mo'); + CToP.setTextContent(mo,name); + var munderover = CToP.createElement('munderover'); + munderover.appendChild(mo); + var mrow1 = CToP.createElement('mrow'); + var i, j, num_qualifiers, num_bvars, children, bvar, num_children, num_args; + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName === 'lowlimit'|| + qualifiers[i].nodeName === 'condition'|| + qualifiers[i].nodeName === 'domainofapplication') + { + if (qualifiers[i].nodeName === 'lowlimit') { + for (j = 0, num_bvars = bvars.length; j<num_bvars; j++ ) { + bvar = bvars[j]; + children = CToP.getChildren(bvar); + if (children.length) { + CToP.applyTransform(mrow1,children[0],0); + } + } + if (bvars.length) { + CToP.appendToken(mrow1,"mo",limitSymbol); + } + } + children = CToP.getChildren(qualifiers[i]); + for (j = 0;j<children.length;j++) { + CToP.applyTransform(mrow1,children[j],0); + } + } else { + children = CToP.getChildren(qualifiers[i]); + if (qualifiers[i].nodeName === 'interval' && children.length === 2) { + for (j = 0, num_bvars = bvars.length; j<num_bvars; j++ ) { + bvar = bvars[j]; + children = CToP.getChildren(bvar); + if (children.length) { + CToP.applyTransform(mrow1,children[0],0); + } + } + if (bvars.length) { + CToP.appendToken(mrow1,"mo","="); + } + CToP.applyTransform(mrow1,CToP.getChildren(qualifiers[i])[0],0); + } + } + } + munderover.appendChild(mrow1); + var mjrow = CToP.createElement('mrow'); + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName === 'uplimit' ||qualifiers[i].nodeName === 'interval' ) + { + children = CToP.getChildren(qualifiers[i]); + for (j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(mjrow,children[j],0); + } + } + } + munderover.appendChild(mjrow); + mrow.appendChild(munderover); + + for (i = 0, num_args = args.length; i<num_args; i++ ) { + CToP.applyTransform(mrow,args[i],precedence); + } + + parentNode.appendChild(mrow); + } + }, + + /* Transform something which binds a variable, e.g. forall or lambda + * + * (function factory) + */ + bind: function(name,argSeparator,conditionSeparator) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var children, i, j, l, num_qualifiers, num_children; + if (name) { + CToP.appendToken(mrow,'mo',name); + } + for (j = 0, l = bvars.length; j<l; j++ ) { + var bvar = bvars[j]; + if (j>0) { + CToP.appendToken(mrow,'mo',','); + } + children = CToP.getChildren(bvar); + if (children.length) { + CToP.applyTransform(mrow,children[0],0); + } + } + + var conditions_mrow = CToP.createElement('mrow'); + var conditions = false; + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName === 'condition') { + conditions = true; + children = CToP.getChildren(qualifiers[i]); + for (j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(conditions_mrow,children[j],0); + } + } + } + if (conditions) { + CToP.appendToken(mrow,'mo',conditionSeparator); + } + mrow.appendChild(conditions_mrow); + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName != 'condition') { + CToP.appendToken(mrow,'mo','\u2208'); + children = CToP.getChildren(qualifiers[i]); + for (j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(mrow,children[j],0); + } + } + } + if (args.length && (bvars.length||children.length)) { + CToP.appendToken(mrow,'mo',argSeparator); + } + for (i = 0, l = args.length; i<l; i++ ) { + CToP.applyTransform(mrow,args[i],0); + } + parentNode.appendChild(mrow); + } + }, + + /** Transform a function application + * + * i.e. something which ends up looking like `f(x,y,z)`, where `f` is a string + * + * (function factory) + */ + fn: function(name) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + if (firstArg.childNodes.length) { + CToP.applyTransform(mrow,firstArg,1); + } else { + CToP.appendToken(mrow,'mi',name); + } + CToP.appendToken(mrow,'mo','\u2061'); + mrow.appendChild(CToP.createmfenced(args,'(',')')); + parentNode.appendChild(mrow); + } + }, + + /** Transform a min/max operation + * + * (function factory) + */ + minmax: function(name) { + return function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mi',name); + var mrow2 = CToP.createElement('mrow'); + CToP.appendToken(mrow2,'mo','{'); + for (var i = 0, l = args.length; i<l; i++ ) { + if (i>0) { + CToP.appendToken(mrow2,'mo',','); + } + CToP.applyTransform(mrow2,args[i],0); + } + if (qualifiers.length) { + CToP.appendToken(mrow2,'mo','|'); + for (i = 0, l = qualifiers.length; i<l; i++ ) { + CToP.applyTransform(mrow2,qualifiers[i],0); + } + } + CToP.appendToken(mrow2,'mo','}'); + mrow.appendChild(mrow2); + parentNode.appendChild(mrow); + } + } + } + } + + /* Functions to transform variable/atom tokens + */ + CToP.tokens = { + ci: function(parentNode,contentMMLNode,precedence) { + if (contentMMLNode.childNodes.length === 1 && contentMMLNode.childNodes[0].nodeType === 3) { + var mi = CToP.appendToken(parentNode,'mi',CToP.getTextContent(contentMMLNode)); + var type = contentMMLNode.getAttribute('type'); + if (type in CToP.settings.cistyles) { + mi.setAttribute('mathvariant',CToP.settings.cistyles[type]); + } + } else { + CToP.transforms.token('mi')(parentNode,contentMMLNode,precedence); + } + }, + cs: CToP.transforms.token('ms'), + + csymbol: function(parentNode,contentMMLNode,precedence) { + var cd = contentMMLNode.getAttribute('cd'); + if (cd && CToP.contentDictionaries[cd]) { + CToP.contentDictionaries[cd](parentNode,contentMMLNode,precedence); + } else if (CToP.settings.symbols[name]) { + CToP.appendToken(parentNode,'mi',CToP.settings.symbols[name]); + } else { + CToP.tokens.ci(parentNode,contentMMLNode); + } + }, + fn: function(parentNode,contentMMLNode,precedence) { + CToP.applyTransform(parentNode,CToP.getChildren(contentMMLNode)[0],precedence); + }, + + naturalnumbers: CToP.transforms.identifier('\u2115'), + integers: CToP.transforms.identifier('\u2124'), + reals: CToP.transforms.identifier('\u211D'), + rationals: CToP.transforms.identifier('\u211A'), + complexes: CToP.transforms.identifier('\u2102'), + primes: CToP.transforms.identifier('\u2119'), + exponentiale: CToP.transforms.identifier('e'), + imaginaryi: CToP.transforms.identifier('i'), + notanumber: CToP.transforms.identifier('NaN'), + eulergamma: CToP.transforms.identifier('\u03B3'), + gamma: CToP.transforms.identifier('\u0263'), + pi: CToP.transforms.identifier('\u03C0'), + infinity: CToP.transforms.identifier('\u221E'), + emptyset: CToP.transforms.identifier('\u2205'), + "true": CToP.transforms.identifier('true'), + "false": CToP.transforms.identifier('false'), + set: CToP.transforms.set('{','}'), + list: CToP.transforms.set('(',')'), + + interval: function(parentNode,contentMMLNode,precedence) { + var closure = contentMMLNode.getAttribute('closure'); + + var open, close; + switch(closure) { + case 'open': + open = '('; + close = ')'; + break; + case 'open-closed': + open = '('; + close = ']'; + break; + case 'closed-open': + open = '['; + close = ')'; + break; + case 'closed': + default: + open = '['; + close = ']'; + } + + parentNode.appendChild(CToP.createmfenced(CToP.getChildren(contentMMLNode),open,close)); + }, + + apply: function(parentNode,contentMMLNode,precedence) { + var children = CToP.classifyChildren(contentMMLNode); + + var firstArg = children.args[0]; + var args = children.args.slice(1), bvars = children.bvars, qualifiers = children.qualifiers; + + if (firstArg) { + var name = firstArg.nodeName; + name = (name === "csymbol") ? CToP.getTextContent(firstArg).toLowerCase() : name; + if (CToP.applyTokens[name]) { + CToP.applyTokens[name](parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + CToP.transforms.fn(name)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + } else { + parentNode.appendChild(CToP.createElement('mrow')); + } + }, + + cn: function(parentNode,contentMMLNode,precedence) { + var type = contentMMLNode.getAttribute("type"); + var base = contentMMLNode.getAttribute("base"); + if (type || base) { + if (base) { + type = 'based-integer'; + } + switch(type) { + case 'integer': + case 'real': + case 'double': + case 'constant': + CToP.transforms.token('mn')(parentNode,contentMMLNode); + break; + case 'hexdouble': + CToP.appendToken(parentNode,'mn','0x'+CToP.getTextContent(contentMMLNode)); + break; + default: + var apply = CToP.createElement('apply'); + var mrow = CToP.createElement('mrow'); + var c = CToP.createElement(type); + apply.appendChild(c); + if (base) { + CToP.appendToken(apply,'mn',base); + } + for (var j = 0, l = contentMMLNode.childNodes.length; j<l; j++ ) { + if (contentMMLNode.childNodes[j].nodeType === 3) { + CToP.appendToken(mrow,'cn',CToP.getTextContent(contentMMLNode.childNodes[j])); + }else if (contentMMLNode.childNodes[j].nodeName === 'sep') { + apply.appendChild(mrow); + mrow = CToP.createElement('mrow'); + } else { + mrow.appendChild(CToP.cloneNode(contentMMLNode.childNodes[j],true)); + } + } + apply.appendChild(mrow); + CToP.applyTransform(parentNode,apply,0); + } + } else { + CToP.transforms.token('mn')(parentNode,contentMMLNode); + } + }, + + vector: function(parentNode,contentMMLNode,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','('); + + var mtable = CToP.createElement('mtable'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + var mtr = CToP.createElement('mtr'); + var mtd = CToP.createElement('mtd'); + CToP.applyTransform(mtd,children[i],0); + mtr.appendChild(mtd); + mtable.appendChild(mtr); + } + + mrow.appendChild(mtable); + CToP.appendToken(mrow,'mo',')'); + parentNode.appendChild(mrow); + }, + + piecewise: function(parentNode,contentMMLNode,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','{'); + var mtable = CToP.createElement('mtable'); + mrow.appendChild(mtable); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + CToP.applyTransform(mtable,children[i],0); + } + parentNode.appendChild(mrow); + }, + + piece: function(parentNode,contentMMLNode,precedence) { + var mtr = CToP.createElement('mtr'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + var mtd = CToP.createElement('mtd'); + mtr.appendChild(mtd); + CToP.applyTransform(mtd,children[i],0); + if (i === 0) { + mtd = CToP.createElement('mtd'); + CToP.appendToken(mtd,"mtext","\u00A0if\u00A0"); + mtr.appendChild(mtd); + } + } + parentNode.appendChild(mtr); + }, + + otherwise: function(parentNode,contentMMLNode,precedence) { + var mtr = CToP.createElement('mtr'); + var children = CToP.getChildren(contentMMLNode); + if (children.length) { + var mtd = CToP.createElement('mtd'); + mtr.appendChild(mtd); + CToP.applyTransform(mtd,children[0],0); + mtd = CToP.createElement('mtd'); + mtd.setAttribute('columnspan','2'); + CToP.appendToken(mtd,"mtext","\u00A0otherwise"); + mtr.appendChild(mtd); + } + parentNode.appendChild(mtr); + }, + + matrix: function(parentNode,contentMMLNode,precedence) { + var children = CToP.classifyChildren(contentMMLNode); + var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers; + + if (bvars.length || qualifiers.length) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,"mo","["); + var msub = CToP.createElement('msub'); + CToP.appendToken(msub,'mi','m'); + var mrow2 = CToP.createElement('mrow'); + for (var i = 0, l = bvars.length; i<l; i++ ) { + if (i != 0) { + CToP.appendToken(mrow2,'mo',','); + } + CToP.applyTransform(mrow2,bvars[i].childNodes[0],0); + } + msub.appendChild(mrow2); + mrow.appendChild(msub); + var msub2 = CToP.cloneNode(msub,true); + CToP.appendToken(mrow,'mo','|'); + mrow.appendChild(msub2); + CToP.appendToken(mrow,'mo','='); + for (i = 0, l = args.length; i<l; i++ ) { + if (i != 0) { + CToP.appendToken(mrow,'mo',','); + } + CToP.applyTransform(mrow,args[i],0); + } + CToP.appendToken(mrow,'mo',';'); + for (i = 0, l = qualifiers.length; i<l; i++) { + if (i != 0) { + CToP.appendToken(mrow,'mo',','); + } + CToP.applyTransform(mrow,qualifiers[i],0); + } + CToP.appendToken(mrow,'mo',']'); + parentNode.appendChild(mrow); + } else { + var mfenced = CToP.createElement('mfenced'); + var mtable = CToP.createElement('mtable'); + for (i = 0, l = args.length; i<l; i++ ) { + CToP.applyTransform(mtable,args[i],0); + } + mfenced.appendChild(mtable); + parentNode.appendChild(mfenced); + } + }, + + matrixrow: function(parentNode,contentMMLNode,precedence) { + var mtr = CToP.createElement('mtr'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + var mtd = CToP.createElement('mtd'); + CToP.applyTransform(mtd,children[i],0); + mtr.appendChild(mtd); + } + parentNode.appendChild(mtr); + }, + + condition: function(parentNode,contentMMLNode,precedence) { + var mrow = CToP.createElement('mrow'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + CToP.applyTransform(mrow,children[i],0); + } + parentNode.appendChild(mrow); + }, + + lambda: function(parentNode,contentMMLNode,precedence) { + var firstArg = CToP.createElement('lambda'); + var children = CToP.classifyChildren(contentMMLNode); + var args = children.args, bvars = children.bvars, qualifiers = children.qualifiers; + var i, l, num_qualifiers; + + if (bvars.length) { + CToP.applyTokens.lambda(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + var mrow = CToP.createElement('mrow'); + for (i = 0, l = args.length; i<l; i++ ) { + CToP.applyTransform(mrow,args[i],0); + } + if (qualifiers.length) { + var msub = CToP.createElement('msub'); + CToP.appendToken(msub,'mo','|'); + var mrow2 = CToP.createElement('mrow'); + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + children = CToP.getChildren(qualifiers[i]); + for (var j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(mrow2,children[j],0); + } + } + msub.appendChild(mrow2); + mrow.appendChild(msub); + } + parentNode.appendChild(mrow); + } + }, + + ident: function(parentNode,contentMMLNode,precedence) { + CToP.appendToken(parentNode,"mi","id") + }, + + domainofapplication: function(parentNode,contentMMLNode,precedence) { + var merror = CToP.createElement('merror'); + CToP.appendToken(merror,'mtext','unexpected domainofapplication'); + parentNode.appendChild(merror); + }, + + share: function(parentNode,contentMMLNode,precedence) { + var mi = CToP.createElement('mi'); + mi.setAttribute('href',contentMMLNode.getAttribute('href')); + CToP.setTextContent(mi,"Share " + contentMMLNode.getAttribute('href')); + parentNode.appendChild(mi); + }, + + cerror: function(parentNode,contentMMLNode,precedence) { + var merror = CToP.createElement('merror'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + CToP.applyTransform(merror,children[i],0); + } + parentNode.appendChild(merror); + }, + + semantics: function(parentNode,contentMMLNode,precedence) { + var mrow = CToP.createElement('mrow'); + var children = CToP.getChildren(contentMMLNode); + if (children.length) { + var z = children[0]; + for (var i = 0, l = children.length; i<l; i++ ) { + if (children[i].nodeName === 'annotation-xml' && children[i].getAttribute('encoding') === 'MathML-Presentation') { + z = children[i]; + break; + } + } + CToP.applyTransform(mrow,z,0); + } + parentNode.appendChild(mrow); + }, + + "annotation-xml": function(parentNode,contentMMLNode,precedence) { + var mrow = CToP.createElement('mrow'); + var children = CToP.getChildren(contentMMLNode); + for (var i = 0, l = children.length; i<l; i++ ) { + CToP.applyTransform(mrow,children[i],0); + } + parentNode.appendChild(mrow); + } + }; + + CToP.tokens.reln = CToP.tokens.bind = CToP.tokens.apply; + + CToP.contentDictionaries = { + "setname1": function(parentNode,contentMMLNode,precedence) { + var sets = { + C: '\u2102', + N: '\u2115', + P: '\u2119', + Q: '\u211A', + R: '\u211D', + Z: '\u2124' + } + var name = CToP.getTextContent(contentMMLNode); + CToP.appendToken(parentNode,'mi',sets[name]); + }, + aritherror: function(parentNode,contentMMLNode,precedence) { + var name = CToP.getTextContent(contentMMLNode); + CToP.appendToken(parentNode,'mi',name+':'); + } + } + + /* Functions to transform function/operation application tokens + */ + CToP.applyTokens = { + rem: CToP.transforms.binary('mod',3), + divide: CToP.transforms.binary('/',3), + remainder: CToP.transforms.binary('mod',3), + implies: CToP.transforms.binary('\u21D2',3), + factorof: CToP.transforms.binary('|',3), + "in": CToP.transforms.binary('\u2208',3), + notin: CToP.transforms.binary('\u2209',3), + notsubset: CToP.transforms.binary('\u2288',2), + notprsubset: CToP.transforms.binary('\u2284',2), + setdiff: CToP.transforms.binary('\u2216',2), + eq: CToP.transforms.infix('=',1), + compose: CToP.transforms.infix('\u2218',0), + "left_compose": CToP.transforms.infix('\u2218',1), + xor: CToP.transforms.infix('xor',3), + neq: CToP.transforms.infix('\u2260',1), + gt: CToP.transforms.infix('>',1), + lt: CToP.transforms.infix('<',1), + geq: CToP.transforms.infix('\u2265',1), + leq: CToP.transforms.infix('\u2264',1), + equivalent: CToP.transforms.infix('\u2261',1), + approx: CToP.transforms.infix('\u2248',1), + subset: CToP.transforms.infix('\u2286',2), + prsubset: CToP.transforms.infix('\u2282',2), + cartesianproduct: CToP.transforms.infix('\u00D7',2), + "cartesian_product": CToP.transforms.infix('\u00D7',2), + vectorproduct: CToP.transforms.infix('\u00D7',2), + scalarproduct: CToP.transforms.infix('.',2), + outerproduct: CToP.transforms.infix('\u2297',2), + sum: CToP.transforms.iteration('\u2211','='), + product: CToP.transforms.iteration('\u220F','='), + forall: CToP.transforms.bind('\u2200','.',','), + exists: CToP.transforms.bind('\u2203','.',','), + lambda: CToP.transforms.bind('\u03BB','.',','), + limit: CToP.transforms.iteration('lim','\u2192'), + sdev: CToP.transforms.fn('\u03c3'), + determinant: CToP.transforms.fn('det'), + max: CToP.transforms.minmax('max'), + min: CToP.transforms.minmax('min'), + real: CToP.transforms.fn('\u211b'), + imaginary: CToP.transforms.fn('\u2111'), + set: CToP.transforms.set('{','}'), + list: CToP.transforms.set('(',')'), + + exp: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mi','e'); + CToP.applyTransform(msup,args[0],0); + parentNode.appendChild(msup); + }, + + union: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length) { + CToP.transforms.iteration('\u22C3','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + CToP.transforms.infix('\u222A',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + intersect: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length) { + CToP.transforms.iteration('\u22C2','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } else { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>2; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j<l; j++ ) { + var argBrackets = false; + if (j>0) { + CToP.appendToken(mrow,'mo','\u2229'); + if (args[j].nodeName === 'apply') { + var child = CToP.getChildren(args[j])[0]; + argBrackets = child.nodeName === 'union'; + } + } + if (argBrackets) { + CToP.appendToken(mrow,'mo','('); + } + CToP.applyTransform(mrow,args[j],2); + if (argBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + } + }, + + floor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u230a'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','\u230b'); + parentNode.appendChild(mrow); + }, + + conjugate: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mover = CToP.createElement('mover'); + CToP.applyTransform(mover,args[0],0); + CToP.appendToken(mover,'mo','\u00af'); + parentNode.appendChild(mover); + }, + + abs: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','|'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','|'); + parentNode.appendChild(mrow); + }, + + and: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('\u22c0','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('\u2227',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + or: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('\u22c1','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('\u2228',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + xor: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length || qualifiers.length) { + CToP.transforms.iteration('xor','=')(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,4); + } else { + CToP.transforms.infix('xor',2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + } + }, + + card: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','|'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','|'); + parentNode.appendChild(mrow); + }, + + mean: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (args.length === 1) { + var mover = CToP.createElement('mover'); + CToP.applyTransform(mover,args[0],0); + CToP.appendToken(mover,'mo','\u00af'); + parentNode.appendChild(mover); + } else { + parentNode.appendChild(CToP.createmfenced(args,'\u27e8','\u27e9')); + } + }, + + moment: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var degree, momentabout, children, i, j, l; + + for (i = 0, l = qualifiers.length; i<l; i++ ) { + if (qualifiers[i].nodeName === 'degree') { + degree = qualifiers[i]; + } else if (qualifiers[i].nodeName === 'momentabout') { + momentabout = qualifiers[i]; + } + } + + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u27e8'); + var argrow = CToP.createElement('mrow'); + if (args.length>1) { + argrow.appendChild(CToP.createmfenced(args,'(',')')); + } else { + CToP.applyTransform(argrow,args[0],0); + } + if (degree) { + var msup = CToP.createElement('msup'); + msup.appendChild(argrow); + children = CToP.getChildren(degree); + for (j = 0, l = children.length; j<l; j++ ) { + CToP.applyTransform(msup,children[j],0); + } + mrow.appendChild(msup); + } else { + mrow.appendChild(argrow); + } + CToP.appendToken(mrow,'mo','\u27e9'); + + if (momentabout) { + var msub = CToP.createElement('msub'); + msub.appendChild(mrow); + children = CToP.getChildren(momentabout); + for (j = 0, l = children.length; j<l; j++ ) { + CToP.applyTransform(msub,children[j],0); + } + parentNode.appendChild(msub); + } else { + parentNode.appendChild(mrow); + } + }, + + variance: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mo','\u03c3'); + CToP.appendToken(msup,'mn','2'); + mrow.appendChild(msup); + CToP.appendToken(mrow,'mo','\u2061'); + mrow.appendChild(CToP.createmfenced(args,'(',')')); + parentNode.appendChild(mrow); + }, + + grad: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u2207'); + CToP.appendToken(mrow,'mo','\u2061'); + mrow.appendChild(CToP.createmfenced(args,'(',')')); + parentNode.appendChild(mrow); + }, + + laplacian: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mo','\u2207'); + CToP.appendToken(msup,'mn','2'); + mrow.appendChild(msup); + CToP.appendToken(mrow,'mo','\u2061'); + mrow.appendChild(CToP.createmfenced(args,'(',')')); + parentNode.appendChild(mrow); + }, + + curl: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u2207'); + CToP.appendToken(mrow,'mo','\u00d7'); + var needsBrackets = args[0].nodeName === 'apply'; + if (needsBrackets) { + mrow.appendChild(CToP.createmfenced(args,'(', ')')); + } + else { + CToP.applyTransform(mrow,args[0],precedence); + } + parentNode.appendChild(mrow); + }, + + divergence: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u2207'); + CToP.appendToken(mrow,'mo','\u22c5'); + var needsBrackets = args[0].nodeName === 'apply'; + if (needsBrackets) { + mrow.appendChild(CToP.createmfenced(args,'(', ')')); + } + else { + CToP.applyTransform(mrow,args[0],precedence); + } + parentNode.appendChild(mrow); + }, + + not: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u00ac'); + var needsBrackets = args[0].nodeName === 'apply' || args[0].nodeName === 'bind'; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + CToP.applyTransform(mrow,args[0],precedence); + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow) + }, + + divide: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mfrac = CToP.createElement('mfrac'); + CToP.applyTransform(mfrac,args[0],0); + CToP.applyTransform(mfrac,args[1],0); + parentNode.appendChild(mfrac); + }, + + tendsto: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var type; + if (firstArg.nodeName === 'tendsto') { + type = firstArg.getAttribute('type'); + } else { + type = CToP.getTextContent(args[0]); + args = args.slice(1); + } + var name = (type === 'above')? '\u2198' : + (type === 'below') ? '\u2197' : '\u2192' ; + CToP.transforms.binary(name,2)(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence); + }, + + minus: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var tokenPrecedence = args.length === 1 ? 5 : 2; + + var mrow = CToP.createElement('mrow'); + var needsBrackets = tokenPrecedence<precedence; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + + if (args.length === 1) { + CToP.appendToken(mrow,'mo','-'); + CToP.applyTransform(mrow,args[0],tokenPrecedence); + } else { + CToP.applyTransform(mrow,args[0],tokenPrecedence); + CToP.appendToken(mrow,'mo','-'); + var bracketArg; + if (args[1].nodeName === 'apply') { + var argOp = CToP.getChildren(args[1])[0]; + bracketArg = argOp.nodeName === 'plus' || argOp.nodeName === 'minus'; + } + if (bracketArg) { + CToP.appendToken(mrow,'mo','('); + } + CToP.applyTransform(mrow,args[1],tokenPrecedence); + if (bracketArg) { + CToP.appendToken(mrow,'mo',')'); + } + } + + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + }, + + "complex-cartesian": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','+'); + CToP.applyTransform(mrow,args[1],0); + CToP.appendToken(mrow,'mo','\u2062'); + CToP.appendToken(mrow,'mi','i'); + parentNode.appendChild(mrow); + }, + + "complex-polar": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','\u2062'); + var msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mi','e'); + var exponent = CToP.createElement('mrow'); + CToP.applyTransform(exponent,args[1],0); + CToP.appendToken(exponent,'mo','\u2062'); + CToP.appendToken(exponent,'mi','i'); + msup.appendChild(exponent); + mrow.appendChild(msup); + parentNode.appendChild(mrow); + }, + + integer: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + CToP.applyTransform(parentNode,args[0],0); + }, + + "based-integer": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msub = CToP.createElement('msub'); + CToP.applyTransform(msub,args[1],0); + CToP.applyTransform(msub,args[0],0); + parentNode.appendChild(msub); + }, + + rational: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mfrac = CToP.createElement('mfrac'); + CToP.applyTransform(mfrac,args[0],0); + CToP.applyTransform(mfrac,args[1],0); + parentNode.appendChild(mfrac); + }, + + times: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>3; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j<l; j++ ) { + if (j>0) { + CToP.appendToken(mrow,'mo',(args[j].nodeName === 'cn') ? "\u00D7" :"\u2062"); + } + CToP.applyTransform(mrow,args[j],3); + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + }, + + plus: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var needsBrackets = precedence>2; + if (needsBrackets) { + CToP.appendToken(mrow,'mo','('); + } + for (var j = 0, l = args.length; j<l; j++ ) { + var arg = args[j]; + var children = CToP.getChildren(arg); + if (j>0) { + var n; + if (CToP.settings.collapsePlusMinus) { + if (arg.nodeName === 'cn' && !(children.length) && (n = Number(CToP.getTextContent(arg))) <0) { + CToP.appendToken(mrow,'mo','\u2212'); + CToP.appendToken(mrow,'mn', -n); + } else if (arg.nodeName === 'apply' && children.length === 2 && children[0].nodeName === 'minus') { + CToP.appendToken(mrow,'mo','\u2212'); + CToP.applyTransform(mrow,children[1],2); + } else if (arg.nodeName === 'apply' && children.length>2 && children[0].nodeName === 'times' && children[1].nodeName === 'cn' && (n = Number(CToP.getTextContent(children[1]))) < 0) { + CToP.appendToken(mrow,'mo','\u2212'); + children[1].textContent = -n; // OK to change MathML since it is being discarded afterward + CToP.applyTransform(mrow,arg,2); + } else{ + CToP.appendToken(mrow,'mo','+'); + CToP.applyTransform(mrow,arg,2); + } + } else { + CToP.appendToken(mrow,'mo','+'); + CToP.applyTransform(mrow,arg,2); + } + } else { + CToP.applyTransform(mrow,arg,2); + } + } + if (needsBrackets) { + CToP.appendToken(mrow,'mo',')'); + } + parentNode.appendChild(mrow); + }, + + transpose: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,args[0],precedence); + CToP.appendToken(msup,'mi','T'); + parentNode.appendChild(msup); + }, + + power: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,args[0],3); + CToP.applyTransform(msup,args[1],precedence); + parentNode.appendChild(msup); + }, + + selector: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msub = CToP.createElement('msub'); + var mrow = args ? args[0]: CToP.createElement('mrow'); + CToP.applyTransform(msub,mrow,0); + var mrow2 = CToP.createElement('mrow'); + for (var i = 1, l = args.length; i<l; i++ ) { + if (i != 1) { + CToP.appendToken(mrow2,'mo',','); + } + CToP.applyTransform(mrow2,args[i],0); + } + msub.appendChild(mrow2); + parentNode.appendChild(msub); + }, + + log: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var mi = CToP.createElement('mi'); + CToP.setTextContent(mi,'log'); + if (qualifiers.length && qualifiers[0].nodeName === 'logbase') { + var msub = CToP.createElement('msub'); + msub.appendChild(mi); + CToP.applyTransform(msub,CToP.getChildren(qualifiers[0])[0],0); + mrow.appendChild(msub); + } else { + mrow.appendChild(mi); + } + CToP.applyTransform(mrow,args[0],7); + parentNode.appendChild(mrow); + }, + + "int": function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + var mo = CToP.createElement('mo'); + CToP.setTextContent(mo,'\u222B'); + var msubsup = CToP.createElement('msubsup'); + msubsup.appendChild(mo); + var mrow1 = CToP.createElement('mrow'); + var children, i, j, l, num_qualifiers, num_children; + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName === 'lowlimit'|| + qualifiers[i].nodeName === 'condition'|| + qualifiers[i].nodeName === 'domainofapplication') + { + children = CToP.getChildren(qualifiers[i]); + for (j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(mrow1,children[j],0); + } + } else { + children = CToP.getChildren(qualifiers[i]); + if (qualifiers[i].nodeName === 'interval' && children.length === 2) { + CToP.applyTransform(mrow1,children[0],0); + } + } + } + msubsup.appendChild(mrow1); + var mrow2 = CToP.createElement('mrow'); + for (i = 0, num_qualifiers = qualifiers.length; i<num_qualifiers; i++ ) { + if (qualifiers[i].nodeName === 'uplimit') { + children = CToP.getChildren(qualifiers[i]); + for (j = 0, num_children = children.length; j<num_children; j++ ) { + CToP.applyTransform(mrow2,children[j],0); + } + break; + } else if (qualifiers[i].nodeName === 'interval' ) { + children = CToP.getChildren(qualifiers[i]); + CToP.applyTransform(mrow2,children[children.length-1],0); + break; + } + } + msubsup.appendChild(mrow2); + mrow.appendChild(msubsup); + for (i = 0, l = args.length; i<l; i++ ) { + CToP.applyTransform(mrow,args[i],0); + } + for (i = 0, l = bvars.length; i<l; i++ ) { + var bvar = bvars[i]; + children = CToP.getChildren(bvar); + if (children.length) { + var mrow3 = CToP.createElement("mrow"); + CToP.appendToken(mrow3,'mi','d'); + CToP.applyTransform(mrow3,children[0],0); + mrow.appendChild(mrow3); + } + } + parentNode.appendChild(mrow); + }, + + inverse: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup = CToP.createElement('msup'); + var arg = (args.length) ? args[0] : CToP.createElement('mrow'); + CToP.applyTransform(msup,arg,precedence); + var mfenced = CToP.createElement('mfenced'); + CToP.appendToken(mfenced,'mn','-1'); + msup.appendChild(mfenced); + parentNode.appendChild(msup); + }, + + quotient: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.appendToken(mrow,'mo','\u230A'); + if (args.length) { + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(mrow,'mo','/'); + if (args.length>1) { + CToP.applyTransform(mrow,args[1],0); + } + } + CToP.appendToken(mrow,'mo','\u230B'); + parentNode.appendChild(mrow); + }, + + factorial: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mrow = CToP.createElement('mrow'); + CToP.applyTransform(mrow,args[0],4); + CToP.appendToken(mrow,'mo','!'); + parentNode.appendChild(mrow); + }, + + root: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var mr; + if (firstArg.nodeName === 'root' && (qualifiers.length === 0 || (qualifiers[0].nodeName === 'degree' && CToP.getTextContent(qualifiers[0]) === '2'))) { + mr = CToP.createElement('msqrt'); + for (var i = 0, l = args.length; i<l; i++ ) { + CToP.applyTransform(mr,args[i],0); + } + } else { + mr = CToP.createElement('mroot'); + CToP.applyTransform(mr,args[0],0); + var arg = (firstArg.nodeName === 'root') ? qualifiers[0].childNodes[0] : args[1]; + CToP.applyTransform(mr,arg,0); + } + parentNode.appendChild(mr); + }, + + diff: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + if (bvars.length) { // d/dx form + var outNode; + var mfrac = CToP.createElement('mfrac'); + var toprow = CToP.createElement('mrow'); + var bottomrow = CToP.createElement('mrow'); + mfrac.appendChild(toprow); + mfrac.appendChild(bottomrow); + + var bvar, degreeNode, msup, mrow; + + var d = CToP.createElement('mi'); + CToP.setTextContent(d,'d'); + + var children = CToP.getChildren(bvars[0]); + for (var j = 0, l = children.length; j<l; j++ ) { + if (children[j].nodeName === 'degree') { + var childNode = CToP.getChildren(children[j])[0]; + if (CToP.getTextContent(childNode) != '1') { + degreeNode = childNode; + msup = CToP.createElement('msup'); + msup.appendChild(d); + d = msup; + CToP.applyTransform(d,degreeNode,0); + } + } else { + bvar = children[j]; + } + } + toprow.appendChild(d); + + if (args.length) { + switch(args[0].nodeName) { + case 'apply': + case 'bind': + case 'reln': + mrow = CToP.createElement('mrow'); + mrow.appendChild(mfrac); + CToP.applyTransform(mrow,args[0],3); + outNode = mrow; + break; + default: + CToP.applyTransform(toprow,args[0],0); + outNode = mfrac; + } + } + + CToP.appendToken(bottomrow,'mi','d'); + + if (degreeNode) { + var msup2 = CToP.createElement('msup'); + CToP.applyTransform(msup2,bvar,0); + CToP.applyTransform(msup2,degreeNode,0); + bottomrow.appendChild(msup2); + } else { + CToP.applyTransform(bottomrow,bvar,0); + } + + + parentNode.appendChild(outNode); + } else { // f' form + msup = CToP.createElement('msup'); + mrow = CToP.createElement('mrow'); + msup.appendChild(mrow); + CToP.applyTransform(mrow,args[0],0); + CToP.appendToken(msup,'mo','\u2032'); // tick + parentNode.appendChild(msup); + } + }, + + partialdiff: function(parentNode,contentMMLNode,firstArg,args,bvars,qualifiers,precedence) { + var msup, msub, mrow; + + var mfrac = CToP.createElement('mfrac'); + var toprow = CToP.createElement('mrow'); + var bottomrow = CToP.createElement('mrow'); + mfrac.appendChild(toprow); + mfrac.appendChild(bottomrow); + + var differendNode, degree, children; + + if (bvars.length === 0 && args.length === 2 && args[0].nodeName === 'list') { + if (args[1].nodeName === 'lambda') { // `d^(n+m)/(dx^n dy^m) f` form, through a lambda + degree = CToP.getChildren(args[0]).length; + if (degree != 1) { + msup = CToP.createElement('msup'); + CToP.appendToken(msup,'mo','\u2202'); // curly d + CToP.appendToken(msup,'mn',degree); + toprow.appendChild(msup); + } else { + CToP.appendToken(toprow,'mo','\u2202'); + } + + children = CToP.getChildren(args[1]); + + differendNode = children[children.length - 1]; // thing being differentiated + + var bvarNames = []; + var lambdaChildren = CToP.getChildren(args[1]); // names of bound variables + var lambdaSequence = CToP.getChildren(args[0]); // indices of bound variable names, in order + for (var i = 0, l = lambdaChildren.length; i<l; i++ ) { + if (lambdaChildren[i].nodeName === 'bvar') { + bvarNames.push(CToP.getChildren(lambdaChildren[i])[0]); + } + } + + var lastN = null; + degree = 0; + function addDiff(n,degree) { + CToP.appendToken(bottomrow,'mo','\u2202'); + var bvar = bvarNames[n]; + if (degree>1) { + var msup = CToP.createElement('msup'); + CToP.applyTransform(msup,bvar,0); + CToP.appendToken(msup,'mn',degree); + bottomrow.appendChild(msup); + } else { + CToP.applyTransform(bottomrow,bvar,0); + } + } + for (i = 0, l = lambdaSequence.length; i<l; i++ ) { + var n = Number(CToP.getTextContent(lambdaSequence[i]))-1; + if (lastN !== null && n != lastN) { + addDiff(lastN,degree); + degree = 0; + } + lastN = n; + degree += 1; + } + if (lastN) { + addDiff(lastN,degree); + } + } else { // `D_i_j f` form + mrow = CToP.createElement('mrow'); + msub = CToP.createElement('msub'); + CToP.appendToken(msub,'mi','D'); + var bvar = CToP.getChildren(args[0]); + msub.appendChild(CToP.createmfenced(bvar,'','')); + mrow.appendChild(msub); + CToP.applyTransform(mrow,args[1],0); + parentNode.appendChild(mrow); + return; + } + } else { // `d^(n+m)/(dx^n dy^m) f` form, with bvars + msup = CToP.createElement('msup'); + toprow.appendChild(msup); + CToP.appendToken(msup,'mo','\u2202'); + + var degreeRow = CToP.createElement('mrow'); + msup.appendChild(degreeRow); + + var qualifier; + + if (qualifiers.length && qualifiers[0].nodeName === 'degree' && CToP.getChildren(qualifiers[0]).length) { + qualifier = CToP.getChildren(qualifiers[0])[0]; + CToP.applyTransform(degreeRow,qualifier,0); + } else { + degree = 0; + var hadFirst = false; + for (i = 0, l = bvars.length; i<l; i++ ) { + children = CToP.getChildren(bvars[i]); + if (children.length === 2) { + for (var j = 0;j<2;j++) { + if (children[j].nodeName === 'degree') { + if (/^\s*\d+\s*$/.test(CToP.getTextContent(children[j]))) { + degree += Number(CToP.getTextContent(children[j])); + } else { + if (hadFirst) { + CToP.appendToken(degreeRow,'mo','+'); + } + hadFirst = true; + CToP.applyTransform(degreeRow,CToP.getChildren(children[j])[0],0); + } + } + } + } else { + degree++; + } + } + if (degree>0) { + if (hadFirst) { + CToP.appendToken(degreeRow,'mo','+'); + } + CToP.appendToken(degreeRow,'mn',degree); + } + } + + if (args.length) { + differendNode = args[0]; + } + + for (i = 0, l = bvars.length; i<l; i++ ) { + CToP.appendToken(bottomrow,'mo','\u2202'); + children = CToP.getChildren(bvars[i]); + + if (children.length === 2) { + for (j = 0;j<2;j++) { + if (children[j].nodeName === 'degree') { + var msup2 = CToP.createElement('msup'); + CToP.applyTransform(msup2,children[1-j],0); + var bvarDegreeNode = CToP.getChildren(children[j])[0]; + CToP.applyTransform(msup2,bvarDegreeNode,0); + bottomrow.appendChild(msup2); + } + } + } else if (children.length === 1) { + CToP.applyTransform(bottomrow,children[0],0); + } + } + } + if (differendNode) { + switch(differendNode.nodeName) { + case 'apply': + case 'bind': + case 'reln': + mrow = CToP.createElement('mrow'); + mrow.appendChild(mfrac); + CToP.applyTransform(mrow,differendNode,3); + outNode = mrow; + break; + default: + CToP.applyTransform(toprow,differendNode,0); + outNode = mfrac; + } + } else { + outNode = mfrac; + } + parentNode.appendChild(outNode); + } + }; + CToP.applyTokens.size = CToP.applyTokens.card; + + return CToP; +})(MathJax.Hub); + + +MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () { + + var MATHML = MathJax.InputJax.MathML; + + var CToP = MathJax.Extension["MathML/content-mathml"]; + CToP.mbase = MathJax.ElementJax.mml.mbase; + CToP.MML = MathJax.ElementJax.mml; + + MATHML.DOMfilterHooks.Add(function (data) { + data.math = CToP.transformElement(data.math); + }); + + MathJax.Hub.Startup.signal.Post("MathML/content-mathml Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/MathML/content-mathml.js"); +// @license-end diff --git a/js/mathjax/extensions/MathML/mml3.js b/js/mathjax/extensions/MathML/mml3.js new file mode 100644 index 0000000..cf74978 --- /dev/null +++ b/js/mathjax/extensions/MathML/mml3.js @@ -0,0 +1,786 @@ +// @license magnet:?xt=urn:btih:8e4f440f4c65981c5bf93c76d35135ba5064d8b7dn=apache-2.0.txt Apache-2.0 +/************************************************************* + * + * MathJax/extensions/MathML/mml3.js + * + * This file implements an XSLT transform to convert some MathML 3 + * constructs to constructs MathJax can render. The transform is + * performed in a pre-filter for the MathML input jax, so that the + * Show Math As menu will still show the Original MathML correctly, + * but the transformed MathML can be obtained from the regular MathML menu. + * + * To load it, include + * + * MathML: { + * extensions: ["mml3.js"] + * } + * + * in your configuration. + * + * A portion of this file is taken from mml3mj.xsl which is + * Copyright (c) David Carlisle 2008-2015 + * and is used by permission of David Carlisle, who has agreed to allow us + * to release it under the Apache2 license (see below). That portion is + * indicated via comments. + * + * The remainder falls under the copyright that follows. + * --------------------------------------------------------------------- + * + * Copyright (c) 2013-2020 The MathJax Consortium + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +MathJax.Extension["MathML/mml3"] = { + version: "2.7.9" +}; + +MathJax.Hub.Register.StartupHook("MathML Jax Ready",function () { + + var MATHML = MathJax.InputJax.MathML, + PARSE = MATHML.Parse.prototype; + + MATHML.prefilterHooks.Add(function (data) { + if (!MATHML.mml3XSLT) return; + + // Parse the <math> but use MATHML.Parse's preProcessMath to apply the normal preprocessing. + if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()} + var doc = MATHML.ParseXML(PARSE.preProcessMath(data.math)); + + // Now transform the <math> using the mml3 stylesheet. + var newdoc = MATHML.mml3XSLT.transformToDocument(doc); + + if ((typeof newdoc) === "string") { + // Internet Explorer returns a string, so just use it. + data.math = newdoc; + } else if (window.XMLSerializer) { + // Serialize the <math> again. We could directly provide the DOM content + // but other prefilterHooks may assume data.math is still a string. + var serializer = new XMLSerializer(); + data.math = serializer.serializeToString(newdoc.documentElement, doc); + } + }); + + /* + * The following is derived from mml3mj.xsl + * (https://github.com/davidcarlisle/web-xslt/blob/master/ctop/mml3mj.xsl) + * which is Copyright (c) David Carlisle 2008-2015. + * It is used by permission of David Carlisle, who has agreed to allow it to + * be released under the Apache License, Version 2.0. + */ + var BROWSER = MathJax.Hub.Browser; + var exslt = ''; + if (BROWSER.isEdge || BROWSER.isMSIE) { + exslt = 'urn:schemas-microsoft-com:xslt' + } else { + exslt = 'http://exslt.org/common'; + } + var mml3Stylesheet = + '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' + + ' xmlns:m="http://www.w3.org/1998/Math/MathML"' + + ' xmlns:c="' + exslt + '"' + + ' exclude-result-prefixes="m c">' + + '<xsl:output indent="yes" omit-xml-declaration="yes"/>' + + '<xsl:output indent="yes" omit-xml-declaration="yes"/><xsl:template match="*">' + + ' <xsl:copy>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:apply-templates/>' + + ' </xsl:copy>' + + '</xsl:template><xsl:template match="m:*[@dir=\'rtl\']" priority="10">' + + ' <xsl:apply-templates mode="rtl" select="."/>' + + '</xsl:template><xsl:template match="@*" mode="rtl">' + + ' <xsl:copy-of select="."/>' + + ' <xsl:attribute name="dir">ltr</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="*" mode="rtl">' + + ' <xsl:copy>' + + ' <xsl:apply-templates select="@*" mode="rtl"/>' + + ' <xsl:for-each select="node()">' + + ' <xsl:sort data-type="number" order="descending" select="position()"/>' + + ' <xsl:text> </xsl:text>' + + ' <xsl:apply-templates mode="rtl" select="."/>' + + ' </xsl:for-each>' + + ' </xsl:copy>' + + '</xsl:template><xsl:template match="@open" mode="rtl">' + + ' <xsl:attribute name="close"><xsl:value-of select="."/></xsl:attribute>' + + '</xsl:template><xsl:template match="@open[.=\'(\']" mode="rtl">' + + ' <xsl:attribute name="close">)</xsl:attribute>' + + '</xsl:template><xsl:template match="@open[.=\')\']" mode="rtl">' + + ' <xsl:attribute name="close">(</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@open[.=\'[\']" mode="rtl">' + + ' <xsl:attribute name="close">]</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@open[.=\']\']" mode="rtl">' + + ' <xsl:attribute name="close">[</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@open[.=\'{\']" mode="rtl">' + + ' <xsl:attribute name="close">}</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@open[.=\'}\']" mode="rtl">' + + ' <xsl:attribute name="close">{</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@close" mode="rtl">' + + ' <xsl:attribute name="open"><xsl:value-of select="."/></xsl:attribute>' + + '</xsl:template><xsl:template match="@close[.=\'(\']" mode="rtl">' + + ' <xsl:attribute name="open">)</xsl:attribute>' + + '</xsl:template><xsl:template match="@close[.=\')\']" mode="rtl">' + + ' <xsl:attribute name="open">(</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@close[.=\'[\']" mode="rtl">' + + ' <xsl:attribute name="open">]</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@close[.=\']\']" mode="rtl">' + + ' <xsl:attribute name="open">[</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@close[.=\'{\']" mode="rtl">' + + ' <xsl:attribute name="open">}</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="@close[.=\'}\']" mode="rtl">' + + ' <xsl:attribute name="open">{</xsl:attribute>' + + '</xsl:template><xsl:template match="m:mfrac[@bevelled=\'true\']" mode="rtl">' + + ' <m:mrow>' + + ' <m:msub><m:mi></m:mi><xsl:apply-templates select="*[2]" mode="rtl"/></m:msub>' + + ' <m:mo>\</m:mo>' + + ' <m:msup><m:mi></m:mi><xsl:apply-templates select="*[1]" mode="rtl"/></m:msup>' + + ' </m:mrow>' + + '</xsl:template><xsl:template match="m:mfrac" mode="rtl">' + + ' <xsl:copy>' + + ' <xsl:apply-templates mode="rtl" select="@*|*"/>' + + ' </xsl:copy>' + + '</xsl:template><xsl:template match="m:mroot" mode="rtl">' + + ' <m:msup>' + + ' <m:menclose notation="top right">' + + ' <xsl:apply-templates mode="rtl" select="@*|*[1]"/>' + + ' </m:menclose>' + + ' <xsl:apply-templates mode="rtl" select="*[2]"/>' + + ' </m:msup>' + + '</xsl:template>' + + '<xsl:template match="m:msqrt" mode="rtl">' + + ' <m:menclose notation="top right">' + + ' <xsl:apply-templates mode="rtl" select="@*|*[1]"/>' + + ' </m:menclose>' + + '</xsl:template><xsl:template match="m:mtable|m:munder|m:mover|m:munderover" mode="rtl" priority="2">' + + ' <xsl:copy>' + + ' <xsl:apply-templates select="@*" mode="rtl"/>' + + ' <xsl:apply-templates mode="rtl">' + + ' </xsl:apply-templates>' + + ' </xsl:copy>' + + '</xsl:template>' + + '<xsl:template match="m:msup" mode="rtl" priority="2">' + + ' <m:mmultiscripts>' + + ' <xsl:apply-templates select="*[1]" mode="rtl"/>' + + ' <m:mprescripts/>' + + ' <m:none/>' + + ' <xsl:apply-templates select="*[2]" mode="rtl"/>' + + ' </m:mmultiscripts>' + + '</xsl:template>' + + '<xsl:template match="m:msub" mode="rtl" priority="2">' + + ' <m:mmultiscripts>' + + ' <xsl:apply-templates select="*[1]" mode="rtl"/>' + + ' <m:mprescripts/>' + + ' <xsl:apply-templates select="*[2]" mode="rtl"/>' + + ' <m:none/>' + + ' </m:mmultiscripts>' + + '</xsl:template>' + + '<xsl:template match="m:msubsup" mode="rtl" priority="2">' + + ' <m:mmultiscripts>' + + ' <xsl:apply-templates select="*[1]" mode="rtl"/>' + + ' <m:mprescripts/>' + + ' <xsl:apply-templates select="*[2]" mode="rtl"/>' + + ' <xsl:apply-templates select="*[3]" mode="rtl"/>' + + ' </m:mmultiscripts>' + + '</xsl:template>' + + '<xsl:template match="m:mmultiscripts" mode="rtl" priority="2">' + + ' <m:mmultiscripts>' + + ' <xsl:apply-templates select="*[1]" mode="rtl"/>' + + ' <xsl:for-each select="m:mprescripts/following-sibling::*[position() mod 2 = 1]">' + + ' <xsl:sort data-type="number" order="descending" select="position()"/>' + + ' <xsl:apply-templates select="." mode="rtl"/>' + + ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' + + ' </xsl:for-each>' + + ' <m:mprescripts/>' + + ' <xsl:for-each select="m:mprescripts/preceding-sibling::*[position()!=last()][position() mod 2 = 0]">' + + ' <xsl:sort data-type="number" order="descending" select="position()"/>' + + ' <xsl:apply-templates select="." mode="rtl"/>' + + ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' + + ' </xsl:for-each>' + + ' </m:mmultiscripts>' + + '</xsl:template>' + + '<xsl:template match="m:mmultiscripts[not(m:mprescripts)]" mode="rtl" priority="3">' + + ' <m:mmultiscripts>' + + ' <xsl:apply-templates select="*[1]" mode="rtl"/>' + + ' <m:mprescripts/>' + + ' <xsl:for-each select="*[position() mod 2 = 0]">' + + ' <xsl:sort data-type="number" order="descending" select="position()"/>' + + ' <xsl:apply-templates select="." mode="rtl"/>' + + ' <xsl:apply-templates select="following-sibling::*[1]" mode="rtl"/>' + + ' </xsl:for-each>' + + ' </m:mmultiscripts>' + + '</xsl:template>' + + '<xsl:template match="text()[.=\'(\']" mode="rtl">)</xsl:template>' + + '<xsl:template match="text()[.=\')\']" mode="rtl">(</xsl:template>' + + '<xsl:template match="text()[.=\'{\']" mode="rtl">}</xsl:template>' + + '<xsl:template match="text()[.=\'}\']" mode="rtl">{</xsl:template>' + + '<xsl:template match="text()[.=\'<\']" mode="rtl">></xsl:template>' + + '<xsl:template match="text()[.=\'>\']" mode="rtl"><</xsl:template>' + + '<xsl:template match="text()[.=\'∈\']" mode="rtl">∋</xsl:template>' + + '<xsl:template match="text()[.=\'∋\']" mode="rtl">∈</xsl:template>' + + '<xsl:template match="@notation[.=\'radical\']" mode="rtl">' + + ' <xsl:attribute name="notation">top right</xsl:attribute>' + + '</xsl:template>' + + '<xsl:template match="m:mlongdiv|m:mstack" mode="rtl">' + + ' <m:mrow dir="ltr">' + + ' <xsl:apply-templates select="."/>' + + ' </m:mrow>' + + '</xsl:template>' + + '<xsl:template match="m:mstack" priority="11">' + + ' <xsl:variable name="m">' + + ' <m:mtable columnspacing="0em">' + + ' <xsl:copy-of select="@align"/>' + + ' <xsl:variable name="t">' + + ' <xsl:apply-templates select="*" mode="mstack1">' + + ' <xsl:with-param name="p" select="0"/>' + + ' </xsl:apply-templates>' + + ' </xsl:variable>' + + ' <xsl:variable name="maxl">' + + ' <xsl:for-each select="c:node-set($t)/*/@l">' + + ' <xsl:sort data-type="number" order="descending"/>' + + ' <xsl:if test="position()=1">' + + ' <xsl:value-of select="."/>' + + ' </xsl:if>' + + ' </xsl:for-each>' + + ' </xsl:variable>' + + ' <xsl:for-each select="c:node-set($t)/*[not(@class=\'mscarries\') or following-sibling::*[1]/@class=\'mscarries\']">' + + '<xsl:variable name="c" select="preceding-sibling::*[1][@class=\'mscarries\']"/>' + + ' <xsl:text> </xsl:text>' + + ' <m:mtr>' + + ' <xsl:copy-of select="@class[.=\'msline\']"/>' + + ' <xsl:variable name="offset" select="$maxl - @l"/>' + + ' <xsl:choose>' + + ' <xsl:when test="@class=\'msline\' and @l=\'*\'">' + + ' <xsl:variable name="msl" select="*[1]"/>' + + ' <xsl:for-each select="(//node())[position()<=$maxl]">' + + ' <xsl:copy-of select="$msl"/>' + + ' </xsl:for-each>' + + ' </xsl:when>' + + ' <xsl:when test="$c">' + + ' <xsl:variable name="ldiff" select="$c/@l - @l"/>' + + ' <xsl:variable name="loffset" select="$maxl - $c/@l"/>' + + ' <xsl:for-each select="(//*)[position()<= $offset]">' + + ' <xsl:variable name="pn" select="position()"/>' + + ' <xsl:variable name="cy" select="$c/*[position()=$pn - $loffset]"/>' + + ' <m:mtd>' + + ' <xsl:if test="$cy/*">' + + ' <m:mover><m:mphantom><m:mn>0</m:mn></m:mphantom><m:mpadded width="0em" lspace="-0.5width">' + + ' <xsl:copy-of select="$cy/*"/></m:mpadded></m:mover>' + + ' </xsl:if>' + + ' </m:mtd>' + + ' </xsl:for-each>' + + ' <xsl:for-each select="*">' + + ' <xsl:variable name="pn" select="position()"/>' + + ' <xsl:variable name="cy" select="$c/*[position()=$pn + $ldiff]"/>' + + ' <xsl:copy>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:variable name="b">' + + ' <xsl:choose>' + + ' <xsl:when test="not(string($cy/@crossout) or $cy/@crossout=\'none\')"><xsl:copy-of select="*"/></xsl:when>' + + ' <xsl:otherwise>' + + ' <m:menclose notation="{$cy/@crossout}"><xsl:copy-of select="*"/></m:menclose>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <xsl:choose>' + + ' <xsl:when test="$cy/m:none or not($cy/*)"><xsl:copy-of select="$b"/></xsl:when>' + + ' <xsl:when test="not(string($cy/@location)) or $cy/@location=\'n\'">' + + ' <m:mover>' + + ' <xsl:copy-of select="$b"/><m:mpadded width="0em" lspace="-0.5width">' + + ' <xsl:copy-of select="$cy/*"/>' + + ' </m:mpadded>' + + ' </m:mover>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'nw\'">' + + ' <m:mmultiscripts><xsl:copy-of select="$b"/><m:mprescripts/><m:none/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:mmultiscripts>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'s\'">' + + ' <m:munder><xsl:copy-of select="$b"/><m:mpadded width="0em" lspace="-0.5width"><xsl:copy-of select="$cy/*"/></m:mpadded></m:munder>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'sw\'">' + + ' <m:mmultiscripts><xsl:copy-of select="$b"/><m:mprescripts/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded><m:none/></m:mmultiscripts>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'ne\'">' + + ' <m:msup><xsl:copy-of select="$b"/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'se\'">' + + ' <m:msub><xsl:copy-of select="$b"/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msub>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'w\'">' + + ' <m:msup><m:mrow/><m:mpadded lspace="-1width" width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' + + ' <xsl:copy-of select="$b"/>' + + ' </xsl:when>' + + ' <xsl:when test="$cy/@location=\'e\'">' + + ' <xsl:copy-of select="$b"/>' + + ' <m:msup><m:mrow/><m:mpadded width="0em"><xsl:copy-of select="$cy/*"/></m:mpadded></m:msup>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:copy-of select="$b"/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:copy>' + + ' </xsl:for-each>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:for-each select="(//*)[position()<= $offset]"><m:mtd/></xsl:for-each>' + + ' <xsl:copy-of select="*"/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </m:mtr>' + + ' </xsl:for-each>' + + ' </m:mtable>' + + '</xsl:variable>' + + '<xsl:apply-templates mode="ml" select="c:node-set($m)"/>' + + '</xsl:template>' + + '<xsl:template match="*" mode="ml">' + + ' <xsl:copy>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:apply-templates mode="ml"/>' + + ' </xsl:copy>' + + '</xsl:template>' + + '<xsl:template mode="ml" match="m:mtr[following-sibling::*[1][@class=\'msline\']]">' + + ' <m:mtr>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:variable name="m" select="following-sibling::*[1]/m:mtd"/>' + + ' <xsl:for-each select="m:mtd">' + + ' <xsl:variable name="p" select="position()"/>' + + ' <m:mtd>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:choose>' + + ' <xsl:when test="$m[$p]/m:mpadded">' + + ' <m:menclose notation="bottom">' + + ' <m:mpadded depth=".1em" height="1em" width=".4em">' + + ' <xsl:copy-of select="*"/>' + + ' </m:mpadded>' + + ' </m:menclose>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:copy-of select="*"/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </m:mtd>' + + ' </xsl:for-each>' + + ' </m:mtr>' + + '</xsl:template><xsl:template mode="ml" match="m:mtr[not(preceding-sibling::*)][@class=\'msline\']" priority="3">' + + ' <m:mtr>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:for-each select="m:mtd">' + + ' <m:mtd>' + + ' <xsl:copy-of select="@*"/>' + + ' <xsl:if test="m:mpadded">' + + ' <m:menclose notation="bottom">' + + ' <m:mpadded depth=".1em" height="1em" width=".4em">' + + ' <m:mspace width=".2em"/>' + + ' </m:mpadded>' + + ' </m:menclose>' + + ' </xsl:if>' + + ' </m:mtd>' + + ' </xsl:for-each>' + + ' </m:mtr>' + + '</xsl:template><xsl:template mode="ml" match="m:mtr[@class=\'msline\']" priority="2"/>' + + '<xsl:template mode="mstack1" match="*">' + + ' <xsl:param name="p"/>' + + ' <xsl:param name="maxl" select="0"/>' + + ' <m:mtr l="{1 + $p}">' + + ' <xsl:if test="ancestor::mstack[1]/@stackalign=\'left\'">' + + ' <xsl:attribute name="l"><xsl:value-of select="$p"/></xsl:attribute>' + + ' </xsl:if>' + + ' <m:mtd><xsl:apply-templates select="."/></m:mtd>' + + ' </m:mtr>' + + '</xsl:template>' + + '<xsl:template mode="mstack1" match="m:msrow">' + + ' <xsl:param name="p"/>' + + ' <xsl:param name="maxl" select="0"/>' + + ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' + + ' <xsl:variable name="align">' + + ' <xsl:choose>' + + ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <xsl:variable name="row">' + + ' <xsl:apply-templates mode="mstack1" select="*">' + + ' <xsl:with-param name="p" select="0"/>' + + ' </xsl:apply-templates>' + + ' </xsl:variable>' + + ' <xsl:text> </xsl:text>' + + ' <xsl:variable name="l1">' + + ' <xsl:choose>' + + ' <xsl:when test="$align=\'decimalpoint\' and m:mn">' + + ' <xsl:for-each select="c:node-set($row)/m:mtr[m:mtd/m:mn][1]">' + + ' <xsl:value-of select="number(sum(@l))+count(preceding-sibling::*/@l)"/>' + + ' </xsl:for-each>' + + ' </xsl:when>' + + ' <xsl:when test="$align=\'right\' or $align=\'decimalpoint\'">' + + ' <xsl:value-of select="count(c:node-set($row)/m:mtr/m:mtd)"/>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:value-of select="0"/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <m:mtr class="msrow" l="{number($l1) + number(sum(@position)) +$p}">' + + ' <xsl:copy-of select="c:node-set($row)/m:mtr/*"/>' + + ' </m:mtr>' + + '</xsl:template><xsl:template mode="mstack1" match="m:mn">' + + ' <xsl:param name="p"/>' + + ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' + + ' <xsl:variable name="dp1" select="ancestor::*[@decimalpoint][1]/@decimalpoint"/>' + + ' <xsl:variable name="align">' + + ' <xsl:choose>' + + ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <xsl:variable name="dp">' + + ' <xsl:choose>' + + ' <xsl:when test="string($dp1)=\'\'">.</xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="$dp1"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <m:mtr l="$p">' + + ' <xsl:variable name="mn" select="normalize-space(.)"/>' + + ' <xsl:variable name="len" select="string-length($mn)"/>' + + ' <xsl:choose>' + + ' <xsl:when test="$align=\'right\' or ($align=\'decimalpoint\' and not(contains($mn,$dp)))">' + + ' <xsl:attribute name="l"><xsl:value-of select="$p + $len"/></xsl:attribute>' + + ' </xsl:when>' + + ' <xsl:when test="$align=\'center\'">' + + ' <xsl:attribute name="l"><xsl:value-of select="round(($p + $len) div 2)"/></xsl:attribute>' + + ' </xsl:when>' + + ' <xsl:when test="$align=\'decimalpoint\'">' + + ' <xsl:attribute name="l"><xsl:value-of select="$p + string-length(substring-before($mn,$dp))"/></xsl:attribute>' + + ' </xsl:when>' + + ' </xsl:choose> <xsl:for-each select="(//node())[position() <=$len]">' + + ' <xsl:variable name="pos" select="position()"/>' + + ' <m:mtd><m:mn><xsl:value-of select="substring($mn,$pos,1)"/></m:mn></m:mtd>' + + ' </xsl:for-each>' + + ' </m:mtr>' + + '</xsl:template>' + + '<xsl:template match="m:msgroup" mode="mstack1">' + + ' <xsl:param name="p"/>' + + ' <xsl:variable name="s" select="number(sum(@shift))"/>' + + ' <xsl:variable name="thisp" select="number(sum(@position))"/>' + + ' <xsl:for-each select="*">' + + ' <xsl:apply-templates mode="mstack1" select=".">' + + ' <xsl:with-param name="p" select="number($p)+$thisp+(position()-1)*$s"/>' + + ' </xsl:apply-templates>' + + ' </xsl:for-each>' + + '</xsl:template>' + + '<xsl:template match="m:msline" mode="mstack1">' + + ' <xsl:param name="p"/>' + + ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' + + ' <xsl:variable name="align">' + + ' <xsl:choose>' + + ' <xsl:when test="string($align1)=\'\'">decimalpoint</xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="$align1"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <m:mtr class="msline">' + + ' <xsl:attribute name="l">' + + ' <xsl:choose>' + + ' <xsl:when test="not(string(@length)) or @length=0">*</xsl:when>' + + ' <xsl:when test="string($align)=\'right\' or string($align)=\'decimalpoint\' "><xsl:value-of select="$p+ @length"/></xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="$p"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:attribute>' + + ' <xsl:variable name="w">' + + ' <xsl:choose>' + + ' <xsl:when test="@mslinethickness=\'thin\'">0.1em</xsl:when>' + + ' <xsl:when test="@mslinethickness=\'medium\'">0.15em</xsl:when>' + + ' <xsl:when test="@mslinethickness=\'thick\'">0.2em</xsl:when>' + + ' <xsl:when test="@mslinethickness"><xsl:value-of select="@mslinethickness"/></xsl:when>' + + ' <xsl:otherwise>0.15em</xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <xsl:choose>' + + ' <xsl:when test="not(string(@length)) or @length=0">' + + ' <m:mtd class="mslinemax">' + + ' <m:mpadded lspace="-0.2em" width="0em" height="0em">' + + ' <m:mfrac linethickness="{$w}">' + + ' <m:mspace width=".4em"/>' + + ' <m:mrow/>' + + ' </m:mfrac>' + + ' </m:mpadded>' + + ' </m:mtd>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:variable name="l" select="@length"/>' + + ' <xsl:for-each select="(//node())[position()<=$l]">' + + ' <m:mtd class="msline">' + + ' <m:mpadded lspace="-0.2em" width="0em" height="0em">' + + ' <m:mfrac linethickness="{$w}">' + + ' <m:mspace width=".4em"/>' + + ' <m:mrow/>' + + ' </m:mfrac>' + + ' </m:mpadded>' + + ' </m:mtd>' + + ' </xsl:for-each>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </m:mtr>' + + '</xsl:template>' + + '<xsl:template match="m:mscarries" mode="mstack1">' + + ' <xsl:param name="p"/>' + + ' <xsl:variable name="align1" select="ancestor::m:mstack[1]/@stackalign"/>' + + ' <xsl:variable name="l1">' + + ' <xsl:choose>' + + ' <xsl:when test="string($align1)=\'left\'">0</xsl:when>' + + ' <xsl:otherwise><xsl:value-of select="count(*)"/></xsl:otherwise>' + + ' </xsl:choose>' + + ' </xsl:variable>' + + ' <m:mtr class="mscarries" l="{$p + $l1 + sum(@position)}">' + + ' <xsl:apply-templates select="*" mode="msc"/>' + + ' </m:mtr>' + + '</xsl:template><xsl:template match="*" mode="msc">' + + ' <m:mtd>' + + ' <xsl:copy-of select="../@location|../@crossout"/>' + + ' <xsl:choose>' + + ' <xsl:when test="../@scriptsizemultiplier">' + + ' <m:mstyle mathsize="{round(../@scriptsizemultiplier div .007)}%">' + + ' <xsl:apply-templates select="."/>' + + ' </m:mstyle>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:apply-templates select="."/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </m:mtd>' + + '</xsl:template><xsl:template match="m:mscarry" mode="msc">' + + ' <m:mtd>' + + ' <xsl:copy-of select="@location|@crossout"/>' + + ' <xsl:choose>' + + ' <xsl:when test="../@scriptsizemultiplier">' + + ' <m:mstyle mathsize="{round(../@scriptsizemultiplier div .007)}%">' + + ' <xsl:apply-templates/>' + + ' </m:mstyle>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:apply-templates/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' </m:mtd>' + + '</xsl:template>' + + '<xsl:template match="m:mlongdiv" priority="11">' + + ' <xsl:variable name="ms">' + + ' <m:mstack>' + + ' <xsl:copy-of select="(ancestor-or-self::*/@decimalpoint)[last()]"/>' + + ' <xsl:choose>' + + ' <xsl:when test="@longdivstyle=\'left)(right\'">' + + ' <m:msrow>' + + ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' + + ' <m:mo>)</m:mo>' + + ' <xsl:copy-of select="*[3]"/>' + + ' <m:mo>(</m:mo>' + + ' <xsl:copy-of select="*[2]"/>' + + ' </m:msrow>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'left/\right\'">' + + ' <m:msrow>' + + ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' + + ' <m:mo>/</m:mo>' + + ' <xsl:copy-of select="*[3]"/>' + + ' <m:mo>\</m:mo>' + + ' <xsl:copy-of select="*[2]"/>' + + ' </m:msrow>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\':right=right\'">' + + ' <m:msrow>' + + ' <xsl:copy-of select="*[3]"/>' + + ' <m:mo>:</m:mo>' + + ' <xsl:copy-of select="*[1]"/>' + + ' <m:mo>=</m:mo>' + + ' <xsl:copy-of select="*[2]"/>' + + ' </m:msrow>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'stackedrightright\'' + + ' or @longdivstyle=\'mediumstackedrightright\'' + + ' or @longdivstyle=\'shortstackedrightright\'' + + ' or @longdivstyle=\'stackedleftleft\'' + + ' ">' + + ' <xsl:attribute name="align">top</xsl:attribute>' + + ' <xsl:copy-of select="*[3]"/>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'stackedleftlinetop\'">' + + ' <xsl:copy-of select="*[2]"/>' + + ' <m:msline length="{string-length(*[3])-1}"/>' + + ' <m:msrow>' + + ' <m:mrow>' + + ' <m:menclose notation="bottom right">' + + ' <xsl:copy-of select="*[1]"/>' + + ' </m:menclose>' + + ' </m:mrow>' + + ' <xsl:copy-of select="*[3]"/>' + + ' </m:msrow>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'righttop\'">' + + ' <xsl:copy-of select="*[2]"/>' + + ' <m:msline length="{string-length(*[3])}"/>' + + ' <m:msrow>' + + ' <xsl:copy-of select="*[3]"/>' + + ' <m:menclose notation="top left bottom">' + + ' <xsl:copy-of select="*[1]"/></m:menclose>' + + ' </m:msrow>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:copy-of select="*[2]"/>' + + ' <m:msline length="{string-length(*[3])}"/>' + + ' <m:msrow>' + + ' <m:mrow><xsl:copy-of select="*[1]"/></m:mrow>' + + ' <m:mo>)</m:mo>' + + ' <xsl:copy-of select="*[3]"/>' + + ' </m:msrow>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + ' <xsl:copy-of select="*[position()>3]"/>' + + ' </m:mstack>' + + ' </xsl:variable>' + + ' <xsl:choose>' + + ' <xsl:when test="@longdivstyle=\'stackedrightright\'">' + + ' <m:menclose notation="right">' + + ' <xsl:apply-templates select="c:node-set($ms)"/>' + + ' </m:menclose>' + + ' <m:mtable align="top">' + + ' <m:mtr>' + + ' <m:menclose notation="bottom">' + + ' <xsl:copy-of select="*[1]"/>' + + ' </m:menclose>' + + ' </m:mtr>' + + ' <m:mtr>' + + ' <mtd><xsl:copy-of select="*[2]"/></mtd>' + + ' </m:mtr>' + + ' </m:mtable>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'mediumstackedrightright\'">' + + ' <xsl:apply-templates select="c:node-set($ms)"/>' + + ' <m:menclose notation="left">' + + ' <m:mtable align="top">' + + ' <m:mtr>' + + ' <m:menclose notation="bottom">' + + ' <xsl:copy-of select="*[1]"/>' + + ' </m:menclose>' + + ' </m:mtr>' + + ' <m:mtr>' + + ' <mtd><xsl:copy-of select="*[2]"/></mtd>' + + ' </m:mtr>' + + ' </m:mtable>' + + ' </m:menclose>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'shortstackedrightright\'">' + + ' <xsl:apply-templates select="c:node-set($ms)"/>' + + ' <m:mtable align="top">' + + ' <m:mtr>' + + ' <m:menclose notation="left bottom">' + + ' <xsl:copy-of select="*[1]"/>' + + ' </m:menclose>' + + ' </m:mtr>' + + ' <m:mtr>' + + ' <mtd><xsl:copy-of select="*[2]"/></mtd>' + + ' </m:mtr>' + + ' </m:mtable>' + + ' </xsl:when>' + + ' <xsl:when test="@longdivstyle=\'stackedleftleft\'">' + + ' <m:mtable align="top">' + + ' <m:mtr>' + + ' <m:menclose notation="bottom">' + + ' <xsl:copy-of select="*[1]"/>' + + ' </m:menclose>' + + ' </m:mtr>' + + ' <m:mtr>' + + ' <mtd><xsl:copy-of select="*[2]"/></mtd>' + + ' </m:mtr>' + + ' </m:mtable>' + + ' <m:menclose notation="left">' + + ' <xsl:apply-templates select="c:node-set($ms)"/>' + + ' </m:menclose>' + + ' </xsl:when>' + + ' <xsl:otherwise>' + + ' <xsl:apply-templates select="c:node-set($ms)"/>' + + ' </xsl:otherwise>' + + ' </xsl:choose>' + + '</xsl:template>' + + '<xsl:template match="m:menclose[@notation=\'madruwb\']" mode="rtl">' + + ' <m:menclose notation="bottom right">' + + ' <xsl:apply-templates mode="rtl"/>' + + ' </m:menclose>' + + '</xsl:template></xsl:stylesheet>'; + + /* + * End of mml3mj.xsl material. + */ + + var mml3; + if (window.XSLTProcessor) { + // standard method: just use an XSLTProcessor and parse the stylesheet + if (!MATHML.ParseXML) {MATHML.ParseXML = MATHML.createParser()} + MATHML.mml3XSLT = new XSLTProcessor(); + MATHML.mml3XSLT.importStylesheet(MATHML.ParseXML(mml3Stylesheet)); + } else if (MathJax.Hub.Browser.isMSIE) { + // nonstandard methods for Internet Explorer + if (MathJax.Hub.Browser.versionAtLeast("9.0") || (document.documentMode||0) >= 9) { + // For Internet Explorer >= 9, use createProcessor + mml3 = new ActiveXObject("Msxml2.FreeThreadedDOMDocument"); + mml3.loadXML(mml3Stylesheet); + var xslt = new ActiveXObject("Msxml2.XSLTemplate"); + xslt.stylesheet = mml3; + MATHML.mml3XSLT = { + mml3: xslt.createProcessor(), + transformToDocument: function(doc) { + this.mml3.input = doc; + this.mml3.transform(); + return this.mml3.output; + } + } + } else { + // For Internet Explorer <= 8, use transformNode + mml3 = MATHML.createMSParser(); + mml3.async = false; + mml3.loadXML(mml3Stylesheet); + MATHML.mml3XSLT = { + mml3: mml3, + transformToDocument: function(doc) { + return doc.documentElement.transformNode(this.mml3); + } + } + } + } else { + // No XSLT support. Do not change the <math> content. + MATHML.mml3XSLT = null; + } + + // Tweak CSS to avoid some browsers rearranging HTML output + MathJax.Ajax.Styles({ + ".MathJax .mi, .MathJax .mo, .MathJax .mn, .MathJax .mtext": { + direction: "ltr", + display: "inline-block" + }, + ".MathJax .ms, .MathJax .mspace, .MathJax .mglyph": { + direction: "ltr", + display: "inline-block" + } + }); + + MathJax.Hub.Startup.signal.Post("MathML mml3.js Ready"); +}); + +MathJax.Ajax.loadComplete("[MathJax]/extensions/MathML/mml3.js"); +// @license-end |