Add limit operators
Summary: Add support for all of the other operators, including the ones with symbols and limits. This also fixes the bug where subscripts were shifted the same amount as subscripts. To accomplish this, the domTree.textNode has been repurposed into symbolNode which is no longer an actual text node, but instead represents an element with a single symbol in it. This lets us access properties like the italic correction of a symbol in a reasonable manner without having to recursively look through children of spans. Depends on D13082 Fixes #8 Test Plan: - Make sure tests work - Make sure huxley screenshots didn't change much, and new screenshot looks good Reviewers: alpert Reviewed By: alpert Differential Revision: http://phabricator.khanacademy.org/D13122
This commit is contained in:
parent
29b00ee6b7
commit
f52c84c187
|
@ -2,40 +2,41 @@ var domTree = require("./domTree");
|
||||||
var fontMetrics = require("./fontMetrics");
|
var fontMetrics = require("./fontMetrics");
|
||||||
var symbols = require("./symbols");
|
var symbols = require("./symbols");
|
||||||
|
|
||||||
var makeText = function(value, style, mode) {
|
var makeSymbol = function(value, style, mode, color, classes) {
|
||||||
if (symbols[mode][value] && symbols[mode][value].replace) {
|
if (symbols[mode][value] && symbols[mode][value].replace) {
|
||||||
value = symbols[mode][value].replace;
|
value = symbols[mode][value].replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
var metrics = fontMetrics.getCharacterMetrics(value, style);
|
var metrics = fontMetrics.getCharacterMetrics(value, style);
|
||||||
|
|
||||||
|
var symbolNode;
|
||||||
if (metrics) {
|
if (metrics) {
|
||||||
var textNode = new domTree.textNode(value, metrics.height,
|
symbolNode = new domTree.symbolNode(
|
||||||
metrics.depth);
|
value, metrics.height, metrics.depth, metrics.italic, classes);
|
||||||
if (metrics.italic > 0) {
|
|
||||||
var span = makeSpan([], [textNode]);
|
|
||||||
span.style.marginRight = metrics.italic + "em";
|
|
||||||
|
|
||||||
return span;
|
|
||||||
} else {
|
|
||||||
return textNode;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console && console.warn("No character metrics for '" + value +
|
console && console.warn("No character metrics for '" + value +
|
||||||
"' in style '" + style + "'");
|
"' in style '" + style + "'");
|
||||||
return new domTree.textNode(value, 0, 0);
|
symbolNode = new domTree.symbolNode(value, 0, 0, 0, classes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (color) {
|
||||||
|
symbolNode.style.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
return symbolNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
var mathit = function(value, mode) {
|
var mathit = function(value, mode, color, classes) {
|
||||||
return makeSpan(["mathit"], [makeText(value, "Math-Italic", mode)]);
|
return makeSymbol(
|
||||||
|
value, "Math-Italic", mode, color, classes.concat(["mathit"]));
|
||||||
};
|
};
|
||||||
|
|
||||||
var mathrm = function(value, mode) {
|
var mathrm = function(value, mode, color, classes) {
|
||||||
if (symbols[mode][value].font === "main") {
|
if (symbols[mode][value].font === "main") {
|
||||||
return makeText(value, "Main-Regular", mode);
|
return makeSymbol(value, "Main-Regular", mode, color, classes);
|
||||||
} else {
|
} else {
|
||||||
return makeSpan(["amsrm"], [makeText(value, "AMS-Regular", mode)]);
|
return makeSymbol(
|
||||||
|
value, "AMS-Regular", mode, color, classes.concat(["amsrm"]));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ var makeFragment = function(children) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeFontSizer = function(options, fontSize) {
|
var makeFontSizer = function(options, fontSize) {
|
||||||
var fontSizeInner = makeSpan([], [new domTree.textNode("\u200b")]);
|
var fontSizeInner = makeSpan([], [new domTree.symbolNode("\u200b")]);
|
||||||
fontSizeInner.style.fontSize = (fontSize / options.style.sizeMultiplier) + "em";
|
fontSizeInner.style.fontSize = (fontSize / options.style.sizeMultiplier) + "em";
|
||||||
|
|
||||||
var fontSizer = makeSpan(
|
var fontSizer = makeSpan(
|
||||||
|
@ -210,7 +211,7 @@ var makeVList = function(children, positionType, positionData, options) {
|
||||||
// Add in an element at the end with no offset to fix the calculation of
|
// Add in an element at the end with no offset to fix the calculation of
|
||||||
// baselines in some browsers (namely IE, sometimes safari)
|
// baselines in some browsers (namely IE, sometimes safari)
|
||||||
var baselineFix = makeSpan(
|
var baselineFix = makeSpan(
|
||||||
["baseline-fix"], [fontSizer, new domTree.textNode("\u00a0")]);
|
["baseline-fix"], [fontSizer, new domTree.symbolNode("\u200b")]);
|
||||||
realChildren.push(baselineFix);
|
realChildren.push(baselineFix);
|
||||||
|
|
||||||
var vlist = makeSpan(["vlist"], realChildren);
|
var vlist = makeSpan(["vlist"], realChildren);
|
||||||
|
@ -222,7 +223,7 @@ var makeVList = function(children, positionType, positionData, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
makeText: makeText,
|
makeSymbol: makeSymbol,
|
||||||
mathit: mathit,
|
mathit: mathit,
|
||||||
mathrm: mathrm,
|
mathrm: mathrm,
|
||||||
makeSpan: makeSpan,
|
makeSpan: makeSpan,
|
||||||
|
|
205
buildTree.js
205
buildTree.js
|
@ -34,7 +34,7 @@ var groupToType = {
|
||||||
spacing: "mord",
|
spacing: "mord",
|
||||||
punct: "mpunct",
|
punct: "mpunct",
|
||||||
ordgroup: "mord",
|
ordgroup: "mord",
|
||||||
namedfn: "mop",
|
op: "mop",
|
||||||
katex: "mord",
|
katex: "mord",
|
||||||
overline: "mord",
|
overline: "mord",
|
||||||
rule: "mord",
|
rule: "mord",
|
||||||
|
@ -81,21 +81,25 @@ var isCharacterBox = function(group) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var shouldHandleSupSub = function(group, options) {
|
||||||
|
if (group == null) {
|
||||||
|
return false;
|
||||||
|
} else if (group.type === "op") {
|
||||||
|
return group.value.limits && options.style.id === Style.DISPLAY.id;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var groupTypes = {
|
var groupTypes = {
|
||||||
mathord: function(group, options, prev) {
|
mathord: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathit(
|
||||||
["mord"],
|
group.value, group.mode, options.getColor(), ["mord"]);
|
||||||
[buildCommon.mathit(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
textord: function(group, options, prev) {
|
textord: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathrm(
|
||||||
["mord"],
|
group.value, group.mode, options.getColor(), ["mord"]);
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
bin: function(group, options, prev) {
|
bin: function(group, options, prev) {
|
||||||
|
@ -110,27 +114,28 @@ var groupTypes = {
|
||||||
group.type = "ord";
|
group.type = "ord";
|
||||||
className = "mord";
|
className = "mord";
|
||||||
}
|
}
|
||||||
return makeSpan(
|
|
||||||
[className],
|
return buildCommon.mathrm(
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
group.value, group.mode, options.getColor(), [className]);
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
rel: function(group, options, prev) {
|
rel: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathrm(
|
||||||
["mrel"],
|
group.value, group.mode, options.getColor(), ["mrel"]);
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
text: function(group, options, prev) {
|
text: function(group, options, prev) {
|
||||||
return makeSpan(["text mord", options.style.cls()],
|
return makeSpan(["text", "mord", options.style.cls()],
|
||||||
buildExpression(group.value.body, options.reset()));
|
buildExpression(group.value.body, options.reset()));
|
||||||
},
|
},
|
||||||
|
|
||||||
supsub: function(group, options, prev) {
|
supsub: function(group, options, prev) {
|
||||||
|
var baseGroup = group.value.base;
|
||||||
|
|
||||||
|
if (shouldHandleSupSub(group.value.base, options)) {
|
||||||
|
return groupTypes[group.value.base.type](group, options, prev);
|
||||||
|
}
|
||||||
|
|
||||||
var base = buildGroup(group.value.base, options.reset());
|
var base = buildGroup(group.value.base, options.reset());
|
||||||
|
|
||||||
if (group.value.sup) {
|
if (group.value.sup) {
|
||||||
|
@ -181,6 +186,10 @@ var groupTypes = {
|
||||||
], "shift", v, options);
|
], "shift", v, options);
|
||||||
|
|
||||||
supsub.children[0].style.marginRight = scriptspace;
|
supsub.children[0].style.marginRight = scriptspace;
|
||||||
|
|
||||||
|
if (base instanceof domTree.symbolNode) {
|
||||||
|
supsub.children[0].style.marginLeft = -base.italic + "em";
|
||||||
|
}
|
||||||
} else if (!group.value.sub) {
|
} else if (!group.value.sub) {
|
||||||
u = Math.max(u, p,
|
u = Math.max(u, p,
|
||||||
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
|
sup.depth + 0.25 * fontMetrics.metrics.xHeight);
|
||||||
|
@ -211,6 +220,11 @@ var groupTypes = {
|
||||||
{type: "elem", elem: supmid, shift: -u}
|
{type: "elem", elem: supmid, shift: -u}
|
||||||
], "individualShift", null, options);
|
], "individualShift", null, options);
|
||||||
|
|
||||||
|
if (base instanceof domTree.symbolNode) {
|
||||||
|
supsub.children[1].style.marginLeft = base.italic + "em";
|
||||||
|
base.italic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
supsub.children[0].style.marginRight = scriptspace;
|
supsub.children[0].style.marginRight = scriptspace;
|
||||||
supsub.children[1].style.marginRight = scriptspace;
|
supsub.children[1].style.marginRight = scriptspace;
|
||||||
}
|
}
|
||||||
|
@ -220,19 +234,13 @@ var groupTypes = {
|
||||||
},
|
},
|
||||||
|
|
||||||
open: function(group, options, prev) {
|
open: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathrm(
|
||||||
["mopen"],
|
group.value, group.mode, options.getColor(), ["mopen"]);
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
close: function(group, options, prev) {
|
close: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathrm(
|
||||||
["mclose"],
|
group.value, group.mode, options.getColor(), ["mclose"]);
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
frac: function(group, options, prev) {
|
frac: function(group, options, prev) {
|
||||||
|
@ -344,11 +352,8 @@ var groupTypes = {
|
||||||
},
|
},
|
||||||
|
|
||||||
punct: function(group, options, prev) {
|
punct: function(group, options, prev) {
|
||||||
return makeSpan(
|
return buildCommon.mathrm(
|
||||||
["mpunct"],
|
group.value, group.mode, options.getColor(), ["mpunct"]);
|
||||||
[buildCommon.mathrm(group.value, group.mode)],
|
|
||||||
options.getColor()
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
ordgroup: function(group, options, prev) {
|
ordgroup: function(group, options, prev) {
|
||||||
|
@ -358,13 +363,129 @@ var groupTypes = {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
namedfn: function(group, options, prev) {
|
op: function(group, options, prev) {
|
||||||
var chars = [];
|
var supGroup;
|
||||||
for (var i = 1; i < group.value.body.length; i++) {
|
var subGroup;
|
||||||
chars.push(buildCommon.mathrm(group.value.body[i], group.mode));
|
var hasLimits = false;
|
||||||
|
if (group.type === "supsub" ) {
|
||||||
|
supGroup = group.value.sup;
|
||||||
|
subGroup = group.value.sub;
|
||||||
|
group = group.value.base;
|
||||||
|
hasLimits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return makeSpan(["mop"], chars, options.getColor());
|
// Most operators have a large successor symbol, but these don't.
|
||||||
|
var noSuccessor = [
|
||||||
|
"\\smallint"
|
||||||
|
];
|
||||||
|
|
||||||
|
var large = false;
|
||||||
|
|
||||||
|
if (options.style.id === Style.DISPLAY.id &&
|
||||||
|
group.value.symbol &&
|
||||||
|
!utils.contains(noSuccessor, group.value.body)) {
|
||||||
|
|
||||||
|
// Make symbols larger in displaystyle, except for smallint
|
||||||
|
large = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var base;
|
||||||
|
var baseShift = 0;
|
||||||
|
var delta = 0;
|
||||||
|
if (group.value.symbol) {
|
||||||
|
var style = large ? "Size2-Regular" : "Size1-Regular";
|
||||||
|
base = buildCommon.makeSymbol(
|
||||||
|
group.value.body, style, "math", options.getColor(),
|
||||||
|
["op-symbol", large ? "large-op" : "small-op", "mop"]);
|
||||||
|
|
||||||
|
baseShift = (base.height - base.depth) / 2 -
|
||||||
|
fontMetrics.metrics.axisHeight *
|
||||||
|
options.style.sizeMultiplier;
|
||||||
|
delta = base.italic;
|
||||||
|
} else {
|
||||||
|
var output = [];
|
||||||
|
for (var i = 1; i < group.value.body.length; i++) {
|
||||||
|
output.push(buildCommon.mathrm(group.value.body[i], group.mode));
|
||||||
|
}
|
||||||
|
base = makeSpan(["mop"], output, options.getColor());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasLimits) {
|
||||||
|
if (supGroup) {
|
||||||
|
var sup = buildGroup(supGroup,
|
||||||
|
options.withStyle(options.style.sup()));
|
||||||
|
var supmid = makeSpan(
|
||||||
|
[options.style.reset(), options.style.sup().cls()], [sup]);
|
||||||
|
|
||||||
|
var supKern = Math.max(
|
||||||
|
fontMetrics.metrics.bigOpSpacing1,
|
||||||
|
fontMetrics.metrics.bigOpSpacing3 - sup.depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subGroup) {
|
||||||
|
var sub = buildGroup(subGroup,
|
||||||
|
options.withStyle(options.style.sub()));
|
||||||
|
var submid = makeSpan(
|
||||||
|
[options.style.reset(), options.style.sub().cls()], [sub]);
|
||||||
|
|
||||||
|
var subKern = Math.max(
|
||||||
|
fontMetrics.metrics.bigOpSpacing2,
|
||||||
|
fontMetrics.metrics.bigOpSpacing4 - sub.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
var finalGroup;
|
||||||
|
if (!supGroup) {
|
||||||
|
var top = base.height - baseShift;
|
||||||
|
|
||||||
|
finalGroup = buildCommon.makeVList([
|
||||||
|
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
||||||
|
{type: "elem", elem: submid},
|
||||||
|
{type: "kern", size: subKern},
|
||||||
|
{type: "elem", elem: base}
|
||||||
|
], "top", top, options);
|
||||||
|
|
||||||
|
finalGroup.children[0].style.marginLeft = -delta + "em";
|
||||||
|
} else if (!subGroup) {
|
||||||
|
var bottom = base.depth + baseShift;
|
||||||
|
|
||||||
|
finalGroup = buildCommon.makeVList([
|
||||||
|
{type: "elem", elem: base},
|
||||||
|
{type: "kern", size: supKern},
|
||||||
|
{type: "elem", elem: supmid},
|
||||||
|
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5}
|
||||||
|
], "bottom", bottom, options);
|
||||||
|
|
||||||
|
finalGroup.children[1].style.marginLeft = delta + "em";
|
||||||
|
} else if (!supGroup && !subGroup) {
|
||||||
|
return base;
|
||||||
|
} else {
|
||||||
|
var bottom = fontMetrics.metrics.bigOpSpacing5 +
|
||||||
|
submid.height + submid.depth +
|
||||||
|
subKern +
|
||||||
|
base.depth + baseShift;
|
||||||
|
|
||||||
|
finalGroup = buildCommon.makeVList([
|
||||||
|
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5},
|
||||||
|
{type: "elem", elem: submid},
|
||||||
|
{type: "kern", size: subKern},
|
||||||
|
{type: "elem", elem: base},
|
||||||
|
{type: "kern", size: supKern},
|
||||||
|
{type: "elem", elem: supmid},
|
||||||
|
{type: "kern", size: fontMetrics.metrics.bigOpSpacing5}
|
||||||
|
], "bottom", bottom, options);
|
||||||
|
|
||||||
|
finalGroup.children[0].style.marginLeft = -delta + "em";
|
||||||
|
finalGroup.children[2].style.marginLeft = delta + "em";
|
||||||
|
}
|
||||||
|
|
||||||
|
return makeSpan(["mop", "op-limits"], [finalGroup]);
|
||||||
|
} else {
|
||||||
|
if (group.value.symbol) {
|
||||||
|
base.style.top = baseShift + "em";
|
||||||
|
}
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
katex: function(group, options, prev) {
|
katex: function(group, options, prev) {
|
||||||
|
|
|
@ -23,7 +23,7 @@ var getMetrics = function(symbol, font) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var mathrmSize = function(value, size, mode) {
|
var mathrmSize = function(value, size, mode) {
|
||||||
return buildCommon.makeText(value, "Size" + size + "-Regular", mode);
|
return buildCommon.makeSymbol(value, "Size" + size + "-Regular", mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
var styleWrap = function(delim, toStyle, options) {
|
var styleWrap = function(delim, toStyle, options) {
|
||||||
|
@ -39,7 +39,7 @@ var styleWrap = function(delim, toStyle, options) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeSmallDelim = function(delim, style, center, options, mode) {
|
var makeSmallDelim = function(delim, style, center, options, mode) {
|
||||||
var text = buildCommon.makeText(delim, "Main-Regular", mode);
|
var text = buildCommon.makeSymbol(delim, "Main-Regular", mode);
|
||||||
|
|
||||||
var span = styleWrap(text, style, options);
|
var span = styleWrap(text, style, options);
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ var makeInner = function(symbol, font, mode) {
|
||||||
|
|
||||||
var inner = makeSpan(
|
var inner = makeSpan(
|
||||||
["delimsizinginner", sizeClass],
|
["delimsizinginner", sizeClass],
|
||||||
[makeSpan([], [buildCommon.makeText(symbol, font, mode)])]);
|
[makeSpan([], [buildCommon.makeSymbol(symbol, font, mode)])]);
|
||||||
|
|
||||||
return {type: "elem", elem: inner};
|
return {type: "elem", elem: inner};
|
||||||
};
|
};
|
||||||
|
|
56
domTree.js
56
domTree.js
|
@ -3,6 +3,17 @@
|
||||||
// function. They are useful for both storing extra properties on the nodes, as
|
// function. They are useful for both storing extra properties on the nodes, as
|
||||||
// well as providing a way to easily work with the DOM.
|
// well as providing a way to easily work with the DOM.
|
||||||
|
|
||||||
|
var createClass = function(classes) {
|
||||||
|
classes = classes.slice();
|
||||||
|
for (var i = classes.length - 1; i >= 0; i--) {
|
||||||
|
if (!classes[i]) {
|
||||||
|
classes.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return classes.join(" ");
|
||||||
|
};
|
||||||
|
|
||||||
function span(classes, children, height, depth, maxFontSize, style) {
|
function span(classes, children, height, depth, maxFontSize, style) {
|
||||||
this.classes = classes || [];
|
this.classes = classes || [];
|
||||||
this.children = children || [];
|
this.children = children || [];
|
||||||
|
@ -15,14 +26,7 @@ function span(classes, children, height, depth, maxFontSize, style) {
|
||||||
span.prototype.toDOM = function() {
|
span.prototype.toDOM = function() {
|
||||||
var span = document.createElement("span");
|
var span = document.createElement("span");
|
||||||
|
|
||||||
var classes = this.classes.slice();
|
span.className = createClass(this.classes);
|
||||||
for (var i = classes.length - 1; i >= 0; i--) {
|
|
||||||
if (!classes[i]) {
|
|
||||||
classes.splice(i, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span.className = classes.join(" ");
|
|
||||||
|
|
||||||
for (var style in this.style) {
|
for (var style in this.style) {
|
||||||
if (this.style.hasOwnProperty(style)) {
|
if (this.style.hasOwnProperty(style)) {
|
||||||
|
@ -54,18 +58,46 @@ documentFragment.prototype.toDOM = function() {
|
||||||
return frag;
|
return frag;
|
||||||
};
|
};
|
||||||
|
|
||||||
function textNode(value, height, depth) {
|
function symbolNode(value, height, depth, italic, classes, style) {
|
||||||
this.value = value || "";
|
this.value = value || "";
|
||||||
this.height = height || 0;
|
this.height = height || 0;
|
||||||
this.depth = depth || 0;
|
this.depth = depth || 0;
|
||||||
|
this.italic = italic || 0;
|
||||||
|
this.classes = classes || [];
|
||||||
|
this.style = style || {};
|
||||||
}
|
}
|
||||||
|
|
||||||
textNode.prototype.toDOM = function() {
|
symbolNode.prototype.toDOM = function() {
|
||||||
return document.createTextNode(this.value);
|
var node = document.createTextNode(this.value);
|
||||||
|
var span = null;
|
||||||
|
|
||||||
|
if (this.italic > 0) {
|
||||||
|
span = document.createElement("span");
|
||||||
|
span.style.marginRight = this.italic + "em";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.classes.length > 0) {
|
||||||
|
span = span || document.createElement("span");
|
||||||
|
span.className = createClass(this.classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var style in this.style) {
|
||||||
|
if (this.style.hasOwnProperty(style)) {
|
||||||
|
span = span || document.createElement("span");
|
||||||
|
span.style[style] = this.style[style];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (span) {
|
||||||
|
span.appendChild(node);
|
||||||
|
return span;
|
||||||
|
} else {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
span: span,
|
span: span,
|
||||||
documentFragment: documentFragment,
|
documentFragment: documentFragment,
|
||||||
textNode: textNode
|
symbolNode: symbolNode
|
||||||
};
|
};
|
||||||
|
|
67
functions.js
67
functions.js
|
@ -221,7 +221,11 @@ var duplicatedFunctions = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// No-argument mathy operators
|
// There are 2 flags for operators; whether they produce limits in
|
||||||
|
// displaystyle, and whether they are symbols and should grow in
|
||||||
|
// displaystyle. These four groups cover the four possible choices.
|
||||||
|
|
||||||
|
// No limits, not symbols
|
||||||
{
|
{
|
||||||
funcs: [
|
funcs: [
|
||||||
"\\arcsin", "\\arccos", "\\arctan", "\\arg", "\\cos", "\\cosh",
|
"\\arcsin", "\\arccos", "\\arctan", "\\arg", "\\cos", "\\cosh",
|
||||||
|
@ -233,7 +237,66 @@ var duplicatedFunctions = [
|
||||||
numArgs: 0,
|
numArgs: 0,
|
||||||
handler: function(func) {
|
handler: function(func) {
|
||||||
return {
|
return {
|
||||||
type: "namedfn",
|
type: "op",
|
||||||
|
limits: false,
|
||||||
|
symbol: false,
|
||||||
|
body: func
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Limits, not symbols
|
||||||
|
{
|
||||||
|
funcs: [
|
||||||
|
"\\det", "\\gcd", "\\inf", "\\lim", "\\liminf", "\\limsup", "\\max",
|
||||||
|
"\\min", "\\Pr", "\\sup"
|
||||||
|
],
|
||||||
|
data: {
|
||||||
|
numArgs: 0,
|
||||||
|
handler: function(func) {
|
||||||
|
return {
|
||||||
|
type: "op",
|
||||||
|
limits: true,
|
||||||
|
symbol: false,
|
||||||
|
body: func
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// No limits, symbols
|
||||||
|
{
|
||||||
|
funcs: [
|
||||||
|
"\\int", "\\iint", "\\iiint", "\\oint"
|
||||||
|
],
|
||||||
|
data: {
|
||||||
|
numArgs: 0,
|
||||||
|
handler: function(func) {
|
||||||
|
return {
|
||||||
|
type: "op",
|
||||||
|
limits: false,
|
||||||
|
symbol: true,
|
||||||
|
body: func
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Limits, symbols
|
||||||
|
{
|
||||||
|
funcs: [
|
||||||
|
"\\coprod", "\\bigvee", "\\bigwedge", "\\biguplus", "\\bigcap",
|
||||||
|
"\\bigcup", "\\intop", "\\prod", "\\sum", "\\bigotimes",
|
||||||
|
"\\bigoplus", "\\bigodot", "\\bigsqcup", "\\smallint"
|
||||||
|
],
|
||||||
|
data: {
|
||||||
|
numArgs: 0,
|
||||||
|
handler: function(func) {
|
||||||
|
return {
|
||||||
|
type: "op",
|
||||||
|
limits: true,
|
||||||
|
symbol: true,
|
||||||
body: func
|
body: func
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,10 +385,10 @@ big parens
|
||||||
|
|
||||||
&.mult {
|
&.mult {
|
||||||
.delim-size1 > span {
|
.delim-size1 > span {
|
||||||
font-family: Katex_Size1;
|
font-family: KaTeX_Size1;
|
||||||
}
|
}
|
||||||
.delim-size4 > span {
|
.delim-size4 > span {
|
||||||
font-family: Katex_Size4;
|
font-family: KaTeX_Size4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,4 +397,21 @@ big parens
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: @nulldelimiterspace;
|
width: @nulldelimiterspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.op-symbol {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.small-op {
|
||||||
|
font-family: KaTeX_Size1;
|
||||||
|
}
|
||||||
|
&.large-op {
|
||||||
|
font-family: KaTeX_Size2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.op-limits {
|
||||||
|
> .vlist > span {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
90
symbols.js
90
symbols.js
|
@ -673,6 +673,96 @@ var symbols = {
|
||||||
font: "main",
|
font: "main",
|
||||||
group: "textord",
|
group: "textord",
|
||||||
replace: "\u21d5"
|
replace: "\u21d5"
|
||||||
|
},
|
||||||
|
"\\coprod": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2210"
|
||||||
|
},
|
||||||
|
"\\bigvee": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u22c1"
|
||||||
|
},
|
||||||
|
"\\bigwedge": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u22c0"
|
||||||
|
},
|
||||||
|
"\\biguplus": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2a04"
|
||||||
|
},
|
||||||
|
"\\bigcap": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u22c2"
|
||||||
|
},
|
||||||
|
"\\bigcup": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u22c3"
|
||||||
|
},
|
||||||
|
"\\int": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222b"
|
||||||
|
},
|
||||||
|
"\\intop": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222b"
|
||||||
|
},
|
||||||
|
"\\iint": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222c"
|
||||||
|
},
|
||||||
|
"\\iiint": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222d"
|
||||||
|
},
|
||||||
|
"\\prod": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u220f"
|
||||||
|
},
|
||||||
|
"\\sum": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2211"
|
||||||
|
},
|
||||||
|
"\\bigotimes": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2a02"
|
||||||
|
},
|
||||||
|
"\\bigoplus": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2a01"
|
||||||
|
},
|
||||||
|
"\\bigodot": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2a00"
|
||||||
|
},
|
||||||
|
"\\oint": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222e"
|
||||||
|
},
|
||||||
|
"\\bigsqcup": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u2a06"
|
||||||
|
},
|
||||||
|
"\\smallint": {
|
||||||
|
font: "math",
|
||||||
|
group: "op",
|
||||||
|
replace: "\u222b"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"text": {
|
"text": {
|
||||||
|
|
|
@ -165,5 +165,17 @@
|
||||||
"name": "DisplayStyle",
|
"name": "DisplayStyle",
|
||||||
"screenSize": [1024, 768],
|
"screenSize": [1024, 768],
|
||||||
"url": "http://localhost:7936/test/huxley/test.html?m={\\displaystyle\\sqrt{x}}{\\sqrt{x}}{\\displaystyle \\frac12}{\\frac12}{\\displaystyle x^1_2}{x^1_2}"
|
"url": "http://localhost:7936/test/huxley/test.html?m={\\displaystyle\\sqrt{x}}{\\sqrt{x}}{\\displaystyle \\frac12}{\\frac12}{\\displaystyle x^1_2}{x^1_2}"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "OpLimits",
|
||||||
|
"screenSize": [1024, 768],
|
||||||
|
"url": "http://localhost:7936/test/huxley/test.html?m={\\sin_2^2 \\lim_2^2 \\int_2^2 \\sum_2^2}{\\displaystyle \\lim_2^2 \\int_2^2 \\intop_2^2 \\sum_2^2}"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "SupSubOffsets",
|
||||||
|
"screenSize": [1024, 768],
|
||||||
|
"url": "http://localhost:7936/test/huxley/test.html?m=\\displaystyle \\int_{2+3}x f^{2+3}+3\\lim_{2+3+4+5}f"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
BIN
test/huxley/OpLimits.hux/firefox-1.png
Normal file
BIN
test/huxley/OpLimits.hux/firefox-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
5
test/huxley/OpLimits.hux/record.json
Normal file
5
test/huxley/OpLimits.hux/record.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "screenshot"
|
||||||
|
}
|
||||||
|
]
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
test/huxley/SupSubOffsets.hux/firefox-1.png
Normal file
BIN
test/huxley/SupSubOffsets.hux/firefox-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
5
test/huxley/SupSubOffsets.hux/record.json
Normal file
5
test/huxley/SupSubOffsets.hux/record.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "screenshot"
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user