version 1.1, 2014/09/24 18:14:39
|
version 1.2, 2015/02/24 15:20:44
|
Line 18 through which recipients can access the
|
Line 18 through which recipients can access the
|
|
|
*/ |
*/ |
|
|
|
"use strict"; |
|
|
/** |
/** |
* Parsed tree node. ENode.toMathML(hcolors) contains the code for the transformation into MathML. |
* Parsed tree node. ENode.toMathML() contains the code for the transformation into MathML. |
* @constructor |
* @constructor |
* @param {number} type - ENode.UNKNOWN | NAME | NUMBER | OPERATOR | FUNCTION | VECTOR |
* @param {number} type - ENode.UNKNOWN | NAME | NUMBER | OPERATOR | FUNCTION | VECTOR | INTERVAL | SET | SUBSCRIPT |
* @param {Operator} op - The operator |
* @param {Operator} op - The operator |
* @param {string} value - Node value as a string, null for type VECTOR |
* @param {string} value - Node value as a string, null for type VECTOR |
* @param {Array.<ENode>} children - The children nodes, only for types OPERATOR, FUNCTION, VECTOR, SUBSCRIPT |
* @param {Array.<ENode>} children - The children nodes, only for types OPERATOR, FUNCTION, VECTOR, INTERVAL, SET, SUBSCRIPT |
|
* @param {number} [interval_type] - ENode.NOT_AN_INTERVAL | OPEN_OPEN | OPEN_CLOSED | CLOSED_OPEN | CLOSED_CLOSED |
*/ |
*/ |
function ENode(type, op, value, children) { |
function ENode(type, op, value, children, interval_type) { |
this.type = type; |
this.type = type; |
this.op = op; |
this.op = op; |
this.value = value; |
this.value = value; |
this.children = children; |
this.children = children; |
|
if (typeof interval_type == "undefined") |
|
this.interval_type = ENode.NOT_AN_INTERVAL; |
|
else |
|
this.interval_type = interval_type; |
} |
} |
|
|
ENode.UNKNOWN = 0; |
ENode.UNKNOWN = 0; |
Line 39 ENode.NUMBER = 2;
|
Line 46 ENode.NUMBER = 2;
|
ENode.OPERATOR = 3; |
ENode.OPERATOR = 3; |
ENode.FUNCTION = 4; |
ENode.FUNCTION = 4; |
ENode.VECTOR = 5; |
ENode.VECTOR = 5; |
ENode.SUBSCRIPT = 6; |
ENode.INTERVAL = 6; |
|
ENode.SET = 7; |
|
ENode.SUBSCRIPT = 8; |
ENode.COLORS = ["#E01010", "#0010FF", "#009000", "#FF00FF", "#00B0B0", "#F09000", |
ENode.COLORS = ["#E01010", "#0010FF", "#009000", "#FF00FF", "#00B0B0", "#F09000", |
"#800080", "#F080A0", "#6090F0", "#902000", "#70A050", "#A07060", |
"#800080", "#F080A0", "#6090F0", "#902000", "#70A050", "#A07060", |
"#5000FF", "#E06050", "#008080", "#808000"]; |
"#5000FF", "#E06050", "#008080", "#808000"]; |
|
|
|
ENode.NOT_AN_INTERVAL = 0; |
|
ENode.OPEN_OPEN = 1; |
|
ENode.OPEN_CLOSED = 2; |
|
ENode.CLOSED_OPEN = 3; |
|
ENode.CLOSED_CLOSED = 4; |
|
|
/** |
/** |
* Returns the node as a string, for debug |
* Returns the node as a string, for debug |
* @returns {string} |
* @returns {string} |
Line 69 ENode.prototype.toString = function() {
|
Line 84 ENode.prototype.toString = function() {
|
case ENode.VECTOR: |
case ENode.VECTOR: |
s += 'VECTOR'; |
s += 'VECTOR'; |
break; |
break; |
|
case ENode.INTERVAL: |
|
s += 'INTERVAL'; |
|
break; |
|
case ENode.SET: |
|
s += 'SET'; |
|
break; |
case ENode.SUBSCRIPT: |
case ENode.SUBSCRIPT: |
s += 'SUBSCRIPT'; |
s += 'SUBSCRIPT'; |
break; |
break; |
Line 86 ENode.prototype.toString = function() {
|
Line 107 ENode.prototype.toString = function() {
|
} |
} |
s += ']'; |
s += ']'; |
} |
} |
|
if (this.interval_type) { |
|
s += " " + this.interval_type; |
|
} |
s+= ')'; |
s+= ')'; |
return s; |
return s; |
}; |
}; |
Line 96 ENode.prototype.toString = function() {
|
Line 120 ENode.prototype.toString = function() {
|
* @param {Object.<string, string>} hcolors - hash identifier->color |
* @param {Object.<string, string>} hcolors - hash identifier->color |
* @returns {string} |
* @returns {string} |
*/ |
*/ |
ENode.prototype.getColorForIdentifier = function(name, hcolors) { |
ENode.prototype.getColorForIdentifier = function(name, context) { |
var res = hcolors[name]; |
var res = context.hcolors[name]; |
if (!res) { |
if (!res) { |
res = ENode.COLORS[Object.keys(hcolors).length % ENode.COLORS.length]; |
var colors; |
hcolors[name] = res; |
if (context.colors) |
|
colors = context.colors; |
|
else |
|
colors = ENode.COLORS; |
|
res = colors[Object.keys(context.hcolors).length % colors.length]; |
|
context.hcolors[name] = res; |
} |
} |
return res; |
return res; |
} |
} |
|
|
/** |
/** |
* Transforms this ENode into a MathML HTML DOM element. |
* Transforms this ENode into a MathML HTML DOM element. |
* @param {Object} [context] - display context (not needed for the root element) |
* @param {Array.<string>} [colors] - optional override for ENode.COLORS |
|
* @returns {Element} |
|
*/ |
|
ENode.prototype.toMathML = function(colors) { |
|
var context = { hcolors: {}, depth: 0 , colors: colors}; |
|
return(this._toMathML(context)); |
|
} |
|
|
|
/** |
|
* Transforms this ENode into a MathML HTML DOM element (internal function). |
|
* @param {Object} context - display context |
* @param {Object.<string, string>} context.hcolors - hash identifier->color |
* @param {Object.<string, string>} context.hcolors - hash identifier->color |
* @param {number} context.depth - Depth in parenthesis, used for coloring |
* @param {number} context.depth - Depth in parenthesis, used for coloring |
|
* @param {Array.<string>} context.colors - optional override for ENode.COLORS |
* @returns {Element} |
* @returns {Element} |
*/ |
*/ |
ENode.prototype.toMathML = function(context) { |
ENode.prototype._toMathML = function(context) { |
var c0, c1, c2, c3, c4, i, j, el, par, mrow, mo, mtable, mfrac, msub, msup; |
var c0, c1, c2, c3, c4, i, j, el, par, mrow, mo, mtable, mfrac, msub, msup, mrow2; |
if (typeof context == "undefined") |
|
context = { hcolors: {}, depth: 0 }; |
|
if (this.children != null && this.children.length > 0) |
if (this.children != null && this.children.length > 0) |
c0 = this.children[0]; |
c0 = this.children[0]; |
else |
else |
Line 153 ENode.prototype.toMathML = function(cont
|
Line 191 ENode.prototype.toMathML = function(cont
|
} else { |
} else { |
el = this.mi(this.value) |
el = this.mi(this.value) |
} |
} |
el.setAttribute("mathcolor", this.getColorForIdentifier(this.value, context.hcolors)); |
el.setAttribute("mathcolor", this.getColorForIdentifier(this.value, context)); |
|
if (this.value.indexOf('$') === 0) |
|
el.setAttribute("fontfamily", "monospace"); |
return(el); |
return(el); |
|
|
case ENode.NUMBER: |
case ENode.NUMBER: |
Line 175 ENode.prototype.toMathML = function(cont
|
Line 215 ENode.prototype.toMathML = function(cont
|
case ENode.OPERATOR: |
case ENode.OPERATOR: |
if (this.value == "/") { |
if (this.value == "/") { |
mfrac = document.createElement('mfrac'); |
mfrac = document.createElement('mfrac'); |
mfrac.appendChild(c0.toMathML(context)); |
mfrac.appendChild(c0._toMathML(context)); |
mfrac.appendChild(c1.toMathML(context)); |
mfrac.appendChild(c1._toMathML(context)); |
el = mfrac; |
el = mfrac; |
} else if (this.value == "^") { |
} else if (this.value == "^") { |
if (c0.type == ENode.FUNCTION) { |
if (c0.type == ENode.FUNCTION) { |
Line 193 ENode.prototype.toMathML = function(cont
|
Line 233 ENode.prototype.toMathML = function(cont
|
if (par) |
if (par) |
el.appendChild(this.addP(c0, context)); |
el.appendChild(this.addP(c0, context)); |
else |
else |
el.appendChild(c0.toMathML(context)); |
el.appendChild(c0._toMathML(context)); |
el.appendChild(c1.toMathML(context)); |
el.appendChild(c1._toMathML(context)); |
} else if (this.value == "*") { |
} else if (this.value == "*") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
mrow.appendChild(this.addP(c0, context)); |
mrow.appendChild(this.addP(c0, context)); |
else |
else |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
// should the x operator be visible ? We need to check if there is a number to the left of c1 |
// should the x operator be visible ? We need to check if there is a number to the left of c1 |
var firstinc1 = c1; |
var firstinc1 = c1; |
while (firstinc1.type == ENode.OPERATOR) { |
while (firstinc1.type == ENode.OPERATOR) { |
Line 213 ENode.prototype.toMathML = function(cont
|
Line 253 ENode.prototype.toMathML = function(cont
|
mrow.appendChild(this.mo("*")); |
mrow.appendChild(this.mo("*")); |
else if (firstinc1.type == ENode.NUMBER) |
else if (firstinc1.type == ENode.NUMBER) |
mrow.appendChild(this.mo("\u22C5")); |
mrow.appendChild(this.mo("\u22C5")); |
|
else if (context.units) |
|
mrow.appendChild(this.mo("\u22C5")); |
|
else |
|
mrow.appendChild(this.mo("\u2062")); // invisible multiplication |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (this.value == "-") { |
} else if (this.value == "-") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
if (this.children.length == 1) { |
if (this.children.length == 1) { |
mrow.appendChild(this.mo("-")); |
mrow.appendChild(this.mo("-")); |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
} else { |
} else { |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(this.mo("-")); |
mrow.appendChild(this.mo("-")); |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
} |
} |
el = mrow; |
el = mrow; |
} else if (this.value == "!") { |
} else if (this.value == "!") { |
Line 238 ENode.prototype.toMathML = function(cont
|
Line 282 ENode.prototype.toMathML = function(cont
|
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
mrow.appendChild(this.addP(c0, context)); |
mrow.appendChild(this.addP(c0, context)); |
else |
else |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
el = mrow; |
el = mrow; |
} else if (this.value == "+") { |
} else if (this.value == "+") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mo = this.mo(this.value); |
mo = this.mo(this.value); |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
// should we add parenthesis ? We need to check if there is a '-' to the left of c1 |
// should we add parenthesis ? We need to check if there is a '-' to the left of c1 |
par = false; |
par = false; |
Line 262 ENode.prototype.toMathML = function(cont
|
Line 306 ENode.prototype.toMathML = function(cont
|
if (par) |
if (par) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (this.value == ".") { |
} else if (this.value == ".") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
mrow.appendChild(this.addP(c0, context)); |
mrow.appendChild(this.addP(c0, context)); |
else |
else |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(this.mo("\u22C5")); |
mrow.appendChild(this.mo("\u22C5")); |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (this.value == "`") { |
} else if (this.value == "`") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
if (c0.type == ENode.OPERATOR && (c0.value == "+" || c0.value == "-")) |
mrow.appendChild(this.addP(c0, context)); |
mrow.appendChild(this.addP(c0, context)); |
else |
else |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
// the units should not be in italics |
// the units should not be in italics |
|
// unit multiplication should not be displayed with an invisible operator |
var mstyle = document.createElement("mstyle"); |
var mstyle = document.createElement("mstyle"); |
mstyle.setAttribute("fontstyle", "normal"); |
mstyle.setAttribute("fontstyle", "normal"); |
|
var units_context = {}; |
|
for (var prop in context) { |
|
if (context.hasOwnProperty(prop)) { |
|
units_context[prop] = context[prop]; |
|
} |
|
} |
|
units_context.units = true; |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mstyle.appendChild(this.addP(c1, context)); |
mstyle.appendChild(this.addP(c1, units_context)); |
else |
else |
mstyle.appendChild(c1.toMathML(context)); |
mstyle.appendChild(c1._toMathML(units_context)); |
mrow.appendChild(mstyle); |
mrow.appendChild(mstyle); |
el = mrow; |
el = mrow; |
} else { |
} else { |
// relational operators |
// relational operators |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mo = this.mo(this.value); |
mo = this.mo(this.value); |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} |
} |
return(el); |
return(el); |
Line 306 ENode.prototype.toMathML = function(cont
|
Line 358 ENode.prototype.toMathML = function(cont
|
// c0 contains the function name |
// c0 contains the function name |
if (c0.value == "sqrt" && c1 != null) { |
if (c0.value == "sqrt" && c1 != null) { |
el = document.createElement('msqrt'); |
el = document.createElement('msqrt'); |
el.appendChild(c1.toMathML(context)); |
el.appendChild(c1._toMathML(context)); |
} else if (c0.value == "abs" && c1 != null) { |
} else if (c0.value == "abs" && c1 != null) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mrow.appendChild(this.mo("|")); |
mrow.appendChild(this.mo("|")); |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
mrow.appendChild(this.mo("|")); |
mrow.appendChild(this.mo("|")); |
el = mrow; |
el = mrow; |
} else if (c0.value == "exp" && c1 != null) { |
} else if (c0.value == "exp" && c1 != null) { |
el = document.createElement('msup'); |
el = document.createElement('msup'); |
el.appendChild(this.mi("e")); |
el.appendChild(this.mi("e")); |
el.appendChild(c1.toMathML(context)); |
el.appendChild(c1._toMathML(context)); |
} else if (c0.value == "factorial") { |
} else if (c0.value == "factorial") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mo = this.mo("!"); |
mo = this.mo("!"); |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
el = mrow; |
el = mrow; |
} else if (c0.value == "diff" && this.children != null && this.children.length == 3) { |
} else if (c0.value == "diff" && this.children != null && this.children.length == 3) { |
Line 338 ENode.prototype.toMathML = function(cont
|
Line 390 ENode.prototype.toMathML = function(cont
|
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "diff" && this.children != null && this.children.length == 4) { |
} else if (c0.value == "diff" && this.children != null && this.children.length == 4) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mfrac = document.createElement('mfrac'); |
mfrac = document.createElement('mfrac'); |
msup = document.createElement('msup'); |
msup = document.createElement('msup'); |
msup.appendChild(this.mi("d")); |
msup.appendChild(this.mi("d")); |
msup.appendChild(c3.toMathML(context)); |
msup.appendChild(c3._toMathML(context)); |
mfrac.appendChild(msup); |
mfrac.appendChild(msup); |
var f2 = document.createElement('mrow'); |
var f2 = document.createElement('mrow'); |
f2.appendChild(this.mi("d")); |
f2.appendChild(this.mi("d")); |
msup = document.createElement('msup'); |
msup = document.createElement('msup'); |
msup.appendChild(c2.toMathML(context)); |
msup.appendChild(c2._toMathML(context)); |
msup.appendChild(c3.toMathML(context)); |
msup.appendChild(c3._toMathML(context)); |
f2.appendChild(msup); |
f2.appendChild(msup); |
mfrac.appendChild(f2); |
mfrac.appendChild(f2); |
mrow.appendChild(mfrac); |
mrow.appendChild(mfrac); |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
if (c1.type == ENode.OPERATOR && (c1.value == "+" || c1.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "integrate" && this.children != null && this.children.length == 3) { |
} else if (c0.value == "integrate" && this.children != null && this.children.length == 3) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
Line 368 ENode.prototype.toMathML = function(cont
|
Line 420 ENode.prototype.toMathML = function(cont
|
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
mrow.appendChild(this.mi("d")); |
mrow.appendChild(this.mi("d")); |
mrow.appendChild(c2.toMathML(context)); |
mrow.appendChild(c2._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "integrate" && this.children != null && this.children.length == 5) { |
} else if (c0.value == "integrate" && this.children != null && this.children.length == 5) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
Line 378 ENode.prototype.toMathML = function(cont
|
Line 430 ENode.prototype.toMathML = function(cont
|
var mo = this.mo("\u222B"); |
var mo = this.mo("\u222B"); |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
msubsup.appendChild(mo); |
msubsup.appendChild(mo); |
msubsup.appendChild(c3.toMathML(context)); |
msubsup.appendChild(c3._toMathML(context)); |
msubsup.appendChild(c4.toMathML(context)); |
msubsup.appendChild(c4._toMathML(context)); |
mrow.appendChild(msubsup); |
mrow.appendChild(msubsup); |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
mrow.appendChild(this.mi("d")); |
mrow.appendChild(this.mi("d")); |
mrow.appendChild(c2.toMathML(context)); |
mrow.appendChild(c2._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "sum" && this.children != null && this.children.length == 5) { |
} else if (c0.value == "sum" && this.children != null && this.children.length == 5) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
Line 394 ENode.prototype.toMathML = function(cont
|
Line 446 ENode.prototype.toMathML = function(cont
|
var mo = this.mo("\u2211"); |
var mo = this.mo("\u2211"); |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
munderover.appendChild(mo); |
munderover.appendChild(mo); |
var mrow2 = document.createElement('mrow'); |
mrow2 = document.createElement('mrow'); |
mrow2.appendChild(c2.toMathML(context)); |
mrow2.appendChild(c2._toMathML(context)); |
mrow2.appendChild(this.mo("=")); |
mrow2.appendChild(this.mo("=")); |
mrow2.appendChild(c3.toMathML(context)); |
mrow2.appendChild(c3._toMathML(context)); |
munderover.appendChild(mrow2); |
munderover.appendChild(mrow2); |
munderover.appendChild(c4.toMathML(context)); |
munderover.appendChild(c4._toMathML(context)); |
mrow.appendChild(munderover); |
mrow.appendChild(munderover); |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "product" && this.children != null && this.children.length == 5) { |
} else if (c0.value == "product" && this.children != null && this.children.length == 5) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
Line 412 ENode.prototype.toMathML = function(cont
|
Line 464 ENode.prototype.toMathML = function(cont
|
var mo = this.mo("\u220F"); |
var mo = this.mo("\u220F"); |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
mo.setAttribute("stretchy", "true"); // doesn't work with MathJax |
munderover.appendChild(mo); |
munderover.appendChild(mo); |
var mrow2 = document.createElement('mrow'); |
mrow2 = document.createElement('mrow'); |
mrow2.appendChild(c2.toMathML(context)); |
mrow2.appendChild(c2._toMathML(context)); |
mrow2.appendChild(this.mo("=")); |
mrow2.appendChild(this.mo("=")); |
mrow2.appendChild(c3.toMathML(context)); |
mrow2.appendChild(c3._toMathML(context)); |
munderover.appendChild(mrow2); |
munderover.appendChild(mrow2); |
munderover.appendChild(c4.toMathML(context)); |
munderover.appendChild(c4._toMathML(context)); |
mrow.appendChild(munderover); |
mrow.appendChild(munderover); |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
if (c2.type == ENode.OPERATOR && (c2.value == "+" || c2.value == "-")) |
mrow.appendChild(this.addP(c1, context)); |
mrow.appendChild(this.addP(c1, context)); |
else |
else |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "limit") { |
} else if (c0.value == "limit") { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
Line 432 ENode.prototype.toMathML = function(cont
|
Line 484 ENode.prototype.toMathML = function(cont
|
var munder = document.createElement('munder'); |
var munder = document.createElement('munder'); |
munder.appendChild(this.mo("lim")); |
munder.appendChild(this.mo("lim")); |
var mrowunder = document.createElement('mrow'); |
var mrowunder = document.createElement('mrow'); |
mrowunder.appendChild(c2.toMathML(context)); |
mrowunder.appendChild(c2._toMathML(context)); |
mrowunder.appendChild(this.mo("\u2192")); |
mrowunder.appendChild(this.mo("\u2192")); |
mrowunder.appendChild(c3.toMathML(context)); |
mrowunder.appendChild(c3._toMathML(context)); |
if (c4 != null) { |
if (c4 != null) { |
if (c4.value == "plus") |
if (c4.value == "plus") |
mrowunder.appendChild(this.mo("+")); |
mrowunder.appendChild(this.mo("+")); |
Line 444 ENode.prototype.toMathML = function(cont
|
Line 496 ENode.prototype.toMathML = function(cont
|
munder.appendChild(mrowunder); |
munder.appendChild(mrowunder); |
mrow.appendChild(munder); |
mrow.appendChild(munder); |
} |
} |
mrow.appendChild(c1.toMathML(context)); |
mrow.appendChild(c1._toMathML(context)); |
el = mrow; |
el = mrow; |
} else if (c0.value == "binomial") { |
} else if (c0.value == "binomial") { |
// displayed like a vector |
// displayed like a vector |
Line 453 ENode.prototype.toMathML = function(cont
|
Line 505 ENode.prototype.toMathML = function(cont
|
mtable = document.createElement('mtable'); |
mtable = document.createElement('mtable'); |
for (i=1; i<this.children.length; i++) { |
for (i=1; i<this.children.length; i++) { |
var mtr = document.createElement('mtr'); |
var mtr = document.createElement('mtr'); |
mtr.appendChild(this.children[i].toMathML(context)); |
mtr.appendChild(this.children[i]._toMathML(context)); |
mtable.appendChild(mtr); |
mtable.appendChild(mtr); |
} |
} |
mrow.appendChild(mtable); |
mrow.appendChild(mtable); |
Line 474 ENode.prototype.toMathML = function(cont
|
Line 526 ENode.prototype.toMathML = function(cont
|
for (i=1; i<this.children.length; i++) { |
for (i=1; i<this.children.length; i++) { |
var mtr = document.createElement('mtr'); |
var mtr = document.createElement('mtr'); |
for (j=0; j<this.children[i].children.length; j++) { |
for (j=0; j<this.children[i].children.length; j++) { |
mtr.appendChild(this.children[i].children[j].toMathML(context)); |
mtr.appendChild(this.children[i].children[j]._toMathML(context)); |
} |
} |
mtable.appendChild(mtr); |
mtable.appendChild(mtr); |
} |
} |
mrow.appendChild(mtable); |
mrow.appendChild(mtable); |
mrow.appendChild(this.mo(")")); |
mrow.appendChild(this.mo(")")); |
el = mrow; |
el = mrow; |
|
} else if (c0.value == "union" && this.children.length == 3) { |
|
for (i=1; i<this.children.length; i++) { |
|
// check that all children are intervals or sets |
|
if (this.children[i].type !== ENode.INTERVAL && this.children[i].type !== ENode.SET) { |
|
el = document.createElement('mtext'); |
|
el.appendChild(document.createTextNode("???")); |
|
return(el); |
|
} |
|
} |
|
mrow = document.createElement('mrow'); |
|
mrow.appendChild(c1._toMathML(context)); |
|
mrow.appendChild(this.mo("\u222A")); |
|
mrow.appendChild(c2._toMathML(context)); |
|
el = mrow; |
|
} else if (c0.value == "intersection" && this.children.length == 3) { |
|
for (i=1; i<this.children.length; i++) { |
|
// check that all children are intervals or sets |
|
if (this.children[i].type !== ENode.INTERVAL && this.children[i].type !== ENode.SET) { |
|
el = document.createElement('mtext'); |
|
el.appendChild(document.createTextNode("???")); |
|
return(el); |
|
} |
|
} |
|
mrow = document.createElement('mrow'); |
|
mrow.appendChild(c1._toMathML(context)); |
|
mrow.appendChild(this.mo("\u2229")); |
|
mrow.appendChild(c2._toMathML(context)); |
|
el = mrow; |
} else { |
} else { |
// default display for a function |
// default display for a function |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mrow.appendChild(c0.toMathML(context)); |
mrow.appendChild(c0._toMathML(context)); |
mrow.appendChild(this.mo("(")); |
mrow.appendChild(this.mo("(")); |
for (i=1; i<this.children.length; i++) { |
for (i=1; i<this.children.length; i++) { |
mrow.appendChild(this.children[i].toMathML(context)); |
mrow.appendChild(this.children[i]._toMathML(context)); |
if (i < this.children.length - 1) |
if (i < this.children.length - 1) |
mrow.appendChild(this.mo(Definitions.ARG_SEPARATOR)); |
mrow.appendChild(this.mo(Definitions.ARG_SEPARATOR)); |
} |
} |
Line 509 ENode.prototype.toMathML = function(cont
|
Line 589 ENode.prototype.toMathML = function(cont
|
var mtr = document.createElement('mtr'); |
var mtr = document.createElement('mtr'); |
if (is_matrix) { |
if (is_matrix) { |
for (j=0; j<this.children[i].children.length; j++) { |
for (j=0; j<this.children[i].children.length; j++) { |
mtr.appendChild(this.children[i].children[j].toMathML(context)); |
mtr.appendChild(this.children[i].children[j]._toMathML(context)); |
} |
} |
} else { |
} else { |
mtr.appendChild(this.children[i].toMathML(context)); |
mtr.appendChild(this.children[i]._toMathML(context)); |
} |
} |
mtable.appendChild(mtr); |
mtable.appendChild(mtr); |
} |
} |
mrow.appendChild(mtable); |
mrow.appendChild(mtable); |
mrow.appendChild(this.mo(")")); |
mrow.appendChild(this.mo(")")); |
return(mrow); |
return(mrow); |
|
|
|
case ENode.INTERVAL: |
|
mrow = document.createElement('mrow'); |
|
if (this.interval_type == ENode.OPEN_OPEN || this.interval_type == ENode.OPEN_CLOSED) { |
|
mo = this.mo("("); |
|
} else { |
|
mo = this.mo("["); |
|
} |
|
mrow.appendChild(mo); |
|
mrow2 = document.createElement('mrow'); |
|
mrow2.appendChild(this.children[0]._toMathML(context)); |
|
mrow2.appendChild(this.mo(":")); |
|
mrow2.appendChild(this.children[1]._toMathML(context)); |
|
mrow.appendChild(mrow2); |
|
if (this.interval_type == ENode.OPEN_OPEN || this.interval_type == ENode.CLOSED_OPEN) { |
|
mo = this.mo(")"); |
|
} else { |
|
mo = this.mo("]"); |
|
} |
|
mrow.appendChild(mo); |
|
return(mrow); |
|
|
|
case ENode.SET: |
|
mrow = document.createElement('mrow'); |
|
mrow.appendChild(this.mo("{")); |
|
mrow2 = document.createElement('mrow'); |
|
for (i=0; i<this.children.length; i++) { |
|
if (i > 0) |
|
mrow2.appendChild(this.mo(";")); |
|
mrow2.appendChild(this.children[i]._toMathML(context)); |
|
} |
|
mrow.appendChild(mrow2); |
|
mrow.appendChild(this.mo("}")); |
|
return(mrow); |
|
|
case ENode.SUBSCRIPT: |
case ENode.SUBSCRIPT: |
msub = document.createElement('msub'); |
msub = document.createElement('msub'); |
msub.appendChild(c0.toMathML(context)); |
msub.appendChild(c0._toMathML(context)); |
if (this.children.length > 2) { |
if (this.children.length > 2) { |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
for (i=1; i<this.children.length; i++) { |
for (i=1; i<this.children.length; i++) { |
mrow.appendChild(this.children[i].toMathML(context)); |
mrow.appendChild(this.children[i]._toMathML(context)); |
if (i < this.children.length - 1) |
if (i < this.children.length - 1) |
mrow.appendChild(this.mo(Definitions.ARG_SEPARATOR)); |
mrow.appendChild(this.mo(Definitions.ARG_SEPARATOR)); |
} |
} |
msub.appendChild(mrow); |
msub.appendChild(mrow); |
} else { |
} else { |
msub.appendChild(c1.toMathML(context)); |
msub.appendChild(c1._toMathML(context)); |
} |
} |
return(msub); |
return(msub); |
|
|
} |
} |
}; |
}; |
|
|
Line 587 ENode.prototype.addP = function(en, cont
|
Line 702 ENode.prototype.addP = function(en, cont
|
var mrow, mo; |
var mrow, mo; |
mrow = document.createElement('mrow'); |
mrow = document.createElement('mrow'); |
mo = this.mo("("); |
mo = this.mo("("); |
mo.setAttribute("mathcolor", ENode.COLORS[context.depth % ENode.COLORS.length]); |
var colors; |
|
if (context.colors) |
|
colors = context.colors; |
|
else |
|
colors = ENode.COLORS; |
|
mo.setAttribute("mathcolor", colors[context.depth % colors.length]); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
context.depth++; |
context.depth++; |
mrow.appendChild(en.toMathML(context)); |
mrow.appendChild(en._toMathML(context)); |
context.depth--; |
context.depth--; |
mo = this.mo(")"); |
mo = this.mo(")"); |
mo.setAttribute("mathcolor", ENode.COLORS[context.depth % ENode.COLORS.length]); |
mo.setAttribute("mathcolor", colors[context.depth % colors.length]); |
mrow.appendChild(mo); |
mrow.appendChild(mo); |
return mrow; |
return mrow; |
}; |
}; |