Save user-provided attributes in a separate object (to avoid collision with internal values); change property names in toMathML to have a prefix; allow known attributes in \mmlToken macro; only remove mlabeledtr in FF8 and before.

This commit is contained in:
Davide P. Cervone 2012-01-10 14:10:48 -05:00
parent 10812462e6
commit a013dd823f
18 changed files with 124 additions and 83 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -12,5 +12,5 @@
* http://www.apache.org/licenses/LICENSE-2.0
*/
MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function(){var b="1.1.3";var a=MathJax.ElementJax.mml;a.mbase.Augment({toMathML:function(k){var g=(this.inferred&&this.parent.inferRow);if(k==null){k=""}var e=this.type,d=this.MathMLattributes();if(e==="mspace"){return k+"<"+e+d+" />"}var j=[];var h=(this.isToken?"":k+(g?"":" "));for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){j.push(this.data[f].toMathML(h))}else{if(!this.isToken){j.push(h+"<mrow />")}}}if(this.isToken){return k+"<"+e+d+">"+j.join("")+"</"+e+">"}if(g){return j.join("\n")}if(j.length===0||(j.length===1&&j[0]==="")){return k+"<"+e+d+" />"}return k+"<"+e+d+">\n"+j.join("\n")+"\n"+k+"</"+e+">"},MathMLattributes:function(){var j=[],g=this.defaults;var c=(this.mmlAttributes||this.copyAttributes),l=this.skipAttributes;if(this.type==="math"){j.push('xmlns="http://www.w3.org/1998/Math/MathML"')}if(!this.mmlAttributes){if(this.type==="mstyle"){g=a.math.prototype.defaults}for(var d in g){if(!l[d]&&g.hasOwnProperty(d)){var e=(d==="open"||d==="close");if(this[d]!=null&&(e||this[d]!==g[d])){var k=this[d];delete this[d];if(e||this.Get(d)!==k){j.push(d+'="'+this.formatAttr(k)+'"')}this[d]=k}}}}for(var h=0,f=c.length;h<f;h++){if(this[c[h]]!=null){j.push(c[h]+'="'+this.quoteHTML(this[c[h]])+'"')}}if(j.length){return" "+j.join(" ")}else{return""}},copyAttributes:["fontfamily","fontsize","fontweight","fontstyle","color","background","id","class","href","style"],skipAttributes:{texClass:1,useHeight:1,texprimestyle:1},formatAttr:function(c){if(typeof(c)==="string"&&c.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)){return((1/18)*RegExp.$1).toFixed(3).replace(/\.?0+$/,"")+"em"}else{if(c==="-tex-caligraphic"){return"script"}else{if(c==="-tex-oldstyle"){return"normal"}else{if(c==="-tex-mathit"){return"italic"}}}}return this.quoteHTML(c)},quoteHTML:function(e){e=String(e).split("");for(var f=0,d=e.length;f<d;f++){var h=e[f].charCodeAt(0);if(h<32||h>126){e[f]="&#x"+h.toString(16).toUpperCase()+";"}else{var g={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[e[f]];if(g){e[f]=g}}}return e.join("")}});a.msubsup.Augment({toMathML:function(h){var e=this.type;if(this.data[this.sup]==null){e="msub"}if(this.data[this.sub]==null){e="msup"}var d=this.MathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){g.push(this.data[f].toMathML(h+" "))}}return h+"<"+e+d+">\n"+g.join("\n")+"\n"+h+"</"+e+">"}});a.munderover.Augment({toMathML:function(h){var e=this.type;if(this.data[this.under]==null){e="mover"}if(this.data[this.over]==null){e="munder"}var d=this.MathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){g.push(this.data[f].toMathML(h+" "))}}return h+"<"+e+d+">\n"+g.join("\n")+"\n"+h+"</"+e+">"}});a.TeXAtom.Augment({toMathML:function(c){return c+"<mrow>\n"+this.data[0].toMathML(c+" ")+"\n"+c+"</mrow>"}});a.chars.Augment({toMathML:function(c){return(c||"")+this.quoteHTML(this.toString())}});a.entity.Augment({toMathML:function(c){return(c||"")+"&"+this.data[0]+";<!-- "+this.toString()+" -->"}});a.xml.Augment({toMathML:function(c){return(c||"")+this.toString()}});MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function(){a.TeXmathchoice.Augment({toMathML:function(c){return this.Core().toMathML(c)}})});MathJax.Hub.Startup.signal.Post("toMathML Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/toMathML.js");
MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function(){var b="1.1.3";var a=MathJax.ElementJax.mml;a.mbase.Augment({toMathML:function(k){var g=(this.inferred&&this.parent.inferRow);if(k==null){k=""}var e=this.type,d=this.toMathMLattributes();if(e==="mspace"){return k+"<"+e+d+" />"}var j=[];var h=(this.isToken?"":k+(g?"":" "));for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){j.push(this.data[f].toMathML(h))}else{if(!this.isToken){j.push(h+"<mrow />")}}}if(this.isToken){return k+"<"+e+d+">"+j.join("")+"</"+e+">"}if(g){return j.join("\n")}if(j.length===0||(j.length===1&&j[0]==="")){return k+"<"+e+d+" />"}return k+"<"+e+d+">\n"+j.join("\n")+"\n"+k+"</"+e+">"},toMathMLattributes:function(){var j=[],g=this.defaults;var c=(this.attrNames||this.toMathMLcopyAttributes),l=this.toMathMLskipAttributes;if(this.type==="math"){j.push('xmlns="http://www.w3.org/1998/Math/MathML"')}if(!this.attrNames){if(this.type==="mstyle"){g=a.math.prototype.defaults}for(var d in g){if(!l[d]&&g.hasOwnProperty(d)){var e=(d==="open"||d==="close");if(this[d]!=null&&(e||this[d]!==g[d])){var k=this[d];delete this[d];if(e||this.Get(d)!==k){j.push(d+'="'+this.toMathMLattribute(k)+'"')}this[d]=k}}}}for(var h=0,f=c.length;h<f;h++){k=(this.attr||{})[c[h]];if(k==null){k=this[c[h]]}if(k!=null){j.push(c[h]+'="'+this.toMathMLquote(k)+'"')}}if(j.length){return" "+j.join(" ")}else{return""}},toMathMLcopyAttributes:["fontfamily","fontsize","fontweight","fontstyle","color","background","id","class","href","style"],toMathMLskipAttributes:{texClass:1,useHeight:1,texprimestyle:1},toMathMLattribute:function(c){if(typeof(c)==="string"&&c.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)){return((1/18)*RegExp.$1).toFixed(3).replace(/\.?0+$/,"")+"em"}else{if(c==="-tex-caligraphic"){return"script"}else{if(c==="-tex-oldstyle"){return"normal"}else{if(c==="-tex-mathit"){return"italic"}}}}return this.toMathMLquote(c)},toMathMLquote:function(e){e=String(e).split("");for(var f=0,d=e.length;f<d;f++){var h=e[f].charCodeAt(0);if(h<32||h>126){e[f]="&#x"+h.toString(16).toUpperCase()+";"}else{var g={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[e[f]];if(g){e[f]=g}}}return e.join("")}});a.msubsup.Augment({toMathML:function(h){var e=this.type;if(this.data[this.sup]==null){e="msub"}if(this.data[this.sub]==null){e="msup"}var d=this.toMathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){g.push(this.data[f].toMathML(h+" "))}}return h+"<"+e+d+">\n"+g.join("\n")+"\n"+h+"</"+e+">"}});a.munderover.Augment({toMathML:function(h){var e=this.type;if(this.data[this.under]==null){e="mover"}if(this.data[this.over]==null){e="munder"}var d=this.toMathMLattributes();delete this.data[0].inferred;var g=[];for(var f=0,c=this.data.length;f<c;f++){if(this.data[f]){g.push(this.data[f].toMathML(h+" "))}}return h+"<"+e+d+">\n"+g.join("\n")+"\n"+h+"</"+e+">"}});a.TeXAtom.Augment({toMathML:function(c){return c+"<mrow>\n"+this.data[0].toMathML(c+" ")+"\n"+c+"</mrow>"}});a.chars.Augment({toMathML:function(c){return(c||"")+this.toMathMLquote(this.toString())}});a.entity.Augment({toMathML:function(c){return(c||"")+"&"+this.data[0]+";<!-- "+this.toString()+" -->"}});a.xml.Augment({toMathML:function(c){return(c||"")+this.toString()}});MathJax.Hub.Register.StartupHook("TeX mathchoice Ready",function(){a.TeXmathchoice.Augment({toMathML:function(c){return this.Core().toMathML(c)}})});MathJax.Hub.Startup.signal.Post("toMathML Ready")});MathJax.Ajax.loadComplete("[MathJax]/extensions/toMathML.js");

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,7 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
toMathML: function (space) {
var inferred = (this.inferred && this.parent.inferRow);
if (space == null) {space = ""}
var tag = this.type, attr = this.MathMLattributes();
var tag = this.type, attr = this.toMathMLattributes();
if (tag === "mspace") {return space + "<"+tag+attr+" />"}
var data = []; var SPACE = (this.isToken ? "" : space+(inferred ? "" : " "));
for (var i = 0, m = this.data.length; i < m; i++) {
@ -46,36 +46,38 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
return space + "<"+tag+attr+">\n"+data.join("\n")+"\n"+ space +"</"+tag+">";
},
MathMLattributes: function () {
toMathMLattributes: function () {
var attr = [], defaults = this.defaults;
var copy = (this.mmlAttributes||this.copyAttributes),
skip = this.skipAttributes;
var copy = (this.attrNames||this.toMathMLcopyAttributes),
skip = this.toMathMLskipAttributes;
if (this.type === "math") {attr.push('xmlns="http://www.w3.org/1998/Math/MathML"')}
if (!this.mmlAttributes) {
if (!this.attrNames) {
if (this.type === "mstyle") {defaults = MML.math.prototype.defaults}
for (var id in defaults) {if (!skip[id] && defaults.hasOwnProperty(id)) {
var force = (id === "open" || id === "close");
if (this[id] != null && (force || this[id] !== defaults[id])) {
var value = this[id]; delete this[id];
if (force || this.Get(id) !== value) {attr.push(id+'="'+this.formatAttr(value)+'"')}
if (force || this.Get(id) !== value)
{attr.push(id+'="'+this.toMathMLattribute(value)+'"')}
this[id] = value;
}
}}
}
for (var i = 0, m = copy.length; i < m; i++) {
if (this[copy[i]] != null) {attr.push(copy[i]+'="'+this.quoteHTML(this[copy[i]])+'"')}
value = (this.attr||{})[copy[i]]; if (value == null) {value = this[copy[i]]}
if (value != null) {attr.push(copy[i]+'="'+this.toMathMLquote(value)+'"')}
}
if (attr.length) {return " "+attr.join(" ")} else {return ""}
},
copyAttributes: [
toMathMLcopyAttributes: [
"fontfamily","fontsize","fontweight","fontstyle",
"color","background",
"id","class","href","style"
],
skipAttributes: {texClass: 1, useHeight: 1, texprimestyle: 1},
toMathMLskipAttributes: {texClass: 1, useHeight: 1, texprimestyle: 1},
formatAttr: function (value) {
toMathMLattribute: function (value) {
if (typeof(value) === "string" &&
value.replace(/ /g,"").match(/^(([-+])?(\d+(\.\d*)?|\.\d+))mu$/)) {
// FIXME: should take scriptlevel into account
@ -85,10 +87,10 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
else if (value === "-tex-caligraphic") {return "script"}
else if (value === "-tex-oldstyle") {return "normal"}
else if (value === "-tex-mathit") {return "italic"}
return this.quoteHTML(value);
return this.toMathMLquote(value);
},
quoteHTML: function (string) {
toMathMLquote: function (string) {
string = String(string).split("");
for (var i = 0, m = string.length; i < m; i++) {
var n = string[i].charCodeAt(0);
@ -108,7 +110,7 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
var tag = this.type;
if (this.data[this.sup] == null) {tag = "msub"}
if (this.data[this.sub] == null) {tag = "msup"}
var attr = this.MathMLattributes();
var attr = this.toMathMLattributes();
delete this.data[0].inferred;
var data = [];
for (var i = 0, m = this.data.length; i < m; i++)
@ -122,7 +124,7 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
var tag = this.type;
if (this.data[this.under] == null) {tag = "mover"}
if (this.data[this.over] == null) {tag = "munder"}
var attr = this.MathMLattributes();
var attr = this.toMathMLattributes();
delete this.data[0].inferred;
var data = [];
for (var i = 0, m = this.data.length; i < m; i++)
@ -139,7 +141,7 @@ MathJax.Hub.Register.LoadHook("[MathJax]/jax/element/mml/jax.js",function () {
});
MML.chars.Augment({
toMathML: function (space) {return (space||"") + this.quoteHTML(this.toString())}
toMathML: function (space) {return (space||"") + this.toMathMLquote(this.toString())}
});
MML.entity.Augment({

View File

@ -253,7 +253,8 @@ MathJax.ElementJax.mml.Augment({
return parent;
},
Get: function (name,nodefault) {
if (typeof(this[name]) !== "undefined") {return this[name]}
if (this[name] != null) {return this[name]}
if (this.attr && this.attr[name] != null) {return this.attr[name]}
// FIXME: should cache these values and get from cache
// (clear cache when appended to a new object?)
var parent = this.Parent();
@ -261,9 +262,10 @@ MathJax.ElementJax.mml.Augment({
{return (parent["adjustChild_"+name])(parent.childPosition(this))}
var obj = this.inherit; var root = obj;
while (obj) {
if (typeof(obj[name]) !== "undefined" && !obj.noInheritAttribute[name]) {
var value = obj[name]; if (value == null && obj.attr) {value = obj.attr[name]}
if (value != null && !obj.noInheritAttribute[name]) {
var noInherit = obj.noInherit[this.type];
if (!(noInherit && noInherit[name])) {return obj[name]}
if (!(noInherit && noInherit[name])) {return value}
}
root = obj; obj = obj.inherit;
}

View File

@ -26,6 +26,12 @@
(function (MATHML,BROWSER) {
var MML;
var copyAttributes = {
fontfamily:1, fontsize:1, fontweight:1, fontstyle:1,
color:1, background:1,
id:1, "class":1, href:1, style:1
};
MATHML.Parse = MathJax.Object.Subclass({
Init: function (string) {this.Parse(string)},
@ -77,8 +83,11 @@
return mml;
},
//
// Add the attributes to the mml node
//
AddAttributes: function (mml,node) {
mml.mmlAttributes = [];
mml.attr = {}; mml.attrNames = [];
for (var i = 0, m = node.attributes.length; i < m; i++) {
var name = node.attributes[i].name;
if (name == "xlink:href") {name = "href"}
@ -86,10 +95,19 @@
var value = node.attributes[i].value;
if (value.toLowerCase() === "true") {value = true}
else if (value.toLowerCase() === "false") {value = false}
mml[name] = value; mml.mmlAttributes.push(name);
if (mml.defaults[name] != null || this.copyAttributes[name])
{mml[name] = value} else {mml.attr[name] = value}
mml.attrNames.push(name);
}
},
//
// The non-MathML attributes to store outside of the attr property
//
copyAttributes: copyAttributes,
//
// Create the children for the mml node
//
AddChildren: function (mml,node) {
for (var i = 0, m = node.childNodes.length; i < m; i++) {
var child = node.childNodes[i];
@ -114,6 +132,9 @@
}
},
//
// Remove attribute whitespace
//
trimSpace: function (string) {
return string.replace(/[\t\n\r]/g," ") // whitespace to spaces
.replace(/^ +/,"") // initial whitespace
@ -121,6 +142,10 @@
.replace(/ +/g," "); // internal multiple whitespace
},
//
// Replace a named entity by its value
// (look up from external files if necessary)
//
replaceEntity: function (match,entity) {
if (entity.match(/^(lt|amp|quot)$/)) {return match} // these mess up attribute parsing
if (MATHML.Parse.Entity[entity]) {return MATHML.Parse.Entity[entity]}
@ -133,14 +158,18 @@
}
return match;
},
//
// Characters to remap to better unicode values when they are
// single-character <mo> elements
//
Remap: {
'\u0027': '\u2032', // '
'\u002A': '\u2217', // *
'\u002D': '\u2212' // -
}
}, {
loaded: []
loaded: [] // the entity files that are loaded
});
/************************************************************************/

View File

@ -8,7 +8,7 @@
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2009-2011 Design Science, Inc.
* Copyright (c) 2009-2012 Design Science, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -1317,18 +1317,24 @@
var type = this.GetArgument(name),
attr = this.GetBrackets(name,"").replace(/^\s+/,""),
data = this.GetArgument(name),
def = {mmlAttributes:[]}, match;
def = {attrNames:[]}, match;
if (!MML[type] || !MML[type].prototype.isToken) {TEX.Error(type+" is not a token element")}
while (attr !== "") {
match = attr.match(/^([a-z]+)\s*=\s*('[^']*'|"[^"]*"|[^ ]*)\s*/i);
if (!match) {TEX.Error("Invalid MathML attribute: "+attr)}
if (!MML[type].prototype.defaults[match[1]]) {TEX.Error(match[1]+" is not a recognized attribute for "+type)}
if (!MML[type].prototype.defaults[match[1]] && !this.MmlTokenAllow[match[1]])
{TEX.Error(match[1]+" is not a recognized attribute for "+type)}
def[match[1]] = match[2].replace(/^(['"])(.*)\1$/,"$2");
def.mmlAttributes.push(match[1]);
def.attrNames.push(match[1]);
attr = attr.substr(match[0].length);
}
this.Push(this.mmlToken(MML[type](data).With(def)));
},
MmlTokenAllow: {
fontfamily:1, fontsize:1, fontweight:1, fontstyle:1,
color:1, background:1,
id:1, "class":1, href:1, style:1
},
Strut: function (name) {
this.Push(MML.mpadded(MML.mrow()).With({height: "8.6pt", depth: "3pt", width: 0}));

View File

@ -7,7 +7,7 @@
*
* ---------------------------------------------------------------------
*
* Copyright (c) 2010-2011 Design Science, Inc.
* Copyright (c) 2010-2012 Design Science, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -348,17 +348,17 @@
//
NativeMMLattributes: function (tag) {
var defaults = this.defaults;
var copy = (this.mmlAttributes||this.NativeMMLcopyAttributes),
var copy = (this.attrNames||this.NativeMMLcopyAttributes),
skip = this.NativeMMLskipAttributes;
if (!this.mmlAttributes) {
if (!this.attrNames) {
if (this.type === "mstyle") {defaults = MML.math.prototype.defaults}
for (var id in defaults) {if (!skip[id] && defaults.hasOwnProperty(id)) {
if (this[id] != null) {tag.setAttribute(id,this.NativeMMLattribute(id,this[id]))}
}}
}
for (var i = 0, m = copy.length; i < m; i++) {
if (this[copy[i]] != null)
{tag.setAttribute(copy[i],this.NativeMMLattribute(copy[i],this[copy[i]]))}
var value = (this.attr||{})[copy[i]]; if (value == null) {value = this[copy[i]]}
if (value != null) {tag.setAttribute(copy[i],this.NativeMMLattribute(value))}
}
},
NativeMMLcopyAttributes: [
@ -367,9 +367,9 @@
"id","class","href","style"
],
NativeMMLskipAttributes: {texClass: 1, useHeight: 1, texprimestyle: 1},
NativeMMLattribute: function (id,value) {
NativeMMLattribute: function (value) {
value = String(value);
if (nMML.NAMEDSPACE[value]) {value = nMML.NAMEDSPACE[value]} // MP doesn't do negative spaes
if (nMML.NAMEDSPACE[value]) {value = nMML.NAMEDSPACE[value]} // MP doesn't do negative spaces
else if (value.match(/^\s*(([-+])?(\d+(\.\d*)?|\.\d+))\s*mu\s*$/))
{value = ((1/18)*RegExp.$1).toFixed(3).replace(/\.?0+$/,"")+"em"} // FIXME: should take scriptlevel into account
else if (value === "-tex-caligraphic") {value = "script"} // FIXME: add a class?
@ -454,20 +454,22 @@
this.SUPER(arguments).toNativeMML.call(this,parent);
}
});
MML.mlabeledtr.Augment({
toNativeMML: function (parent) {
//
// FF doesn't handle mlabeledtr, so remove the label
//
var tag = this.NativeMMLelement("mtr");
this.NativeMMLattributes(tag);
for (var i = 1, m = this.data.length; i < m; i++) {
if (this.data[i]) {this.data[i].toNativeMML(tag)}
else {tag.appendChild(this.NativeMMLelement("mrow"))}
}
parent.appendChild(tag);
}
});
if (!HUB.Browser.versionAtLeast("9.0")) {
MML.mlabeledtr.Augment({
toNativeMML: function (parent) {
//
// FF doesn't handle mlabeledtr, so remove the label
//
var tag = this.NativeMMLelement("mtr");
this.NativeMMLattributes(tag);
for (var i = 1, m = this.data.length; i < m; i++) {
if (this.data[i]) {this.data[i].toNativeMML(tag)}
else {tag.appendChild(this.NativeMMLelement("mrow"))}
}
parent.appendChild(tag);
}
});
}
var fontDir = MathJax.OutputJax.fontDir + "/HTML-CSS/TeX/otf";