Add delimiter sizing
Summary: Make delimiter sizing work. This involved - Adding the symbols for the remaining delimiters (like `\lfloor` and `\{`) - Adding metrics for the size1, size2, size3, and size4 fonts - Parsing delimiter sizing functions - Using the big fonts when possible, otherwise building large copies of the delimiters from scratch Test Plan: - See that `\bigl\uparrow\Bigl\downarrow\biggl\updownarrow\Biggl\Uparrow \Biggr\Downarrow\biggr\Updownarrow\bigm/\Bigm\backslash\biggm| \Biggm|\big\lceil\Big\rceil\bigg\langle\Bigg\rangle\bigl(\Bigl) \biggl[\Biggl]\Biggr\{\biggr\}\Bigr\lfloor\bigr\rfloor` parses correctly (this contains all of the delimiters, and all of the sizing modes) - See that the huxley tests didn't change, and the new one looks good - See the normal tests work Reviewers: alpert Reviewed By: alpert Differential Revision: http://phabricator.khanacademy.org/D7844
This commit is contained in:
parent
07e8d468de
commit
100798847b
60
Parser.js
60
Parser.js
|
@ -259,6 +259,30 @@ Parser.prototype.parseTextGroup = function(pos, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var delimiters = [
|
||||||
|
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
|
||||||
|
"\\{", "\\lbrace", "\\}", "\\rbrace",
|
||||||
|
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
|
||||||
|
"<", ">", "\\langle", "\\rangle",
|
||||||
|
"/", "\\backslash",
|
||||||
|
"|", "\\vert", "\\|", "\\Vert",
|
||||||
|
"\\uparrow", "\\Uparrow",
|
||||||
|
"\\downarrow", "\\Downarrow",
|
||||||
|
"\\updownarrow", "\\Updownarrow"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Parse a single delimiter
|
||||||
|
Parser.prototype.parseDelimiter = function(pos, mode) {
|
||||||
|
var delim = this.lexer.lex(pos, mode);
|
||||||
|
if (utils.contains(delimiters, delim.text)) {
|
||||||
|
return new ParseResult(
|
||||||
|
new ParseNode("delimiter", delim.text),
|
||||||
|
delim.position);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// A list of 1-argument color functions
|
// A list of 1-argument color functions
|
||||||
var colorFuncs = [
|
var colorFuncs = [
|
||||||
"\\blue", "\\orange", "\\pink", "\\red", "\\green", "\\gray", "\\purple"
|
"\\blue", "\\orange", "\\pink", "\\red", "\\green", "\\gray", "\\purple"
|
||||||
|
@ -278,6 +302,25 @@ var namedFns = [
|
||||||
"\\tan","\\tanh"
|
"\\tan","\\tanh"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
var delimiterSizes = {
|
||||||
|
"\\bigl" : {type: "open", size: 1},
|
||||||
|
"\\Bigl" : {type: "open", size: 2},
|
||||||
|
"\\biggl": {type: "open", size: 3},
|
||||||
|
"\\Biggl": {type: "open", size: 4},
|
||||||
|
"\\bigr" : {type: "close", size: 1},
|
||||||
|
"\\Bigr" : {type: "close", size: 2},
|
||||||
|
"\\biggr": {type: "close", size: 3},
|
||||||
|
"\\Biggr": {type: "close", size: 4},
|
||||||
|
"\\bigm" : {type: "rel", size: 1},
|
||||||
|
"\\Bigm" : {type: "rel", size: 2},
|
||||||
|
"\\biggm": {type: "rel", size: 3},
|
||||||
|
"\\Biggm": {type: "rel", size: 4},
|
||||||
|
"\\big" : {type: "textord", size: 1},
|
||||||
|
"\\Big" : {type: "textord", size: 2},
|
||||||
|
"\\bigg" : {type: "textord", size: 3},
|
||||||
|
"\\Bigg" : {type: "textord", size: 4}
|
||||||
|
};
|
||||||
|
|
||||||
// Parses a "nucleus", which is either a single token from the tokenizer or a
|
// Parses a "nucleus", which is either a single token from the tokenizer or a
|
||||||
// function and its arguments
|
// function and its arguments
|
||||||
Parser.prototype.parseNucleus = function(pos, mode) {
|
Parser.prototype.parseNucleus = function(pos, mode) {
|
||||||
|
@ -348,6 +391,23 @@ Parser.prototype.parseNucleus = function(pos, mode) {
|
||||||
return new ParseResult(
|
return new ParseResult(
|
||||||
new ParseNode("namedfn", nucleus.text, mode),
|
new ParseNode("namedfn", nucleus.text, mode),
|
||||||
nucleus.position);
|
nucleus.position);
|
||||||
|
} else if (mode === "math" && delimiterSizes[nucleus.type]) {
|
||||||
|
// If this is a delimiter size function, we parse a single delimiter
|
||||||
|
var delim = this.parseDelimiter(nucleus.position, mode);
|
||||||
|
if (delim) {
|
||||||
|
var type = delimiterSizes[nucleus.type].type;
|
||||||
|
|
||||||
|
return new ParseResult(
|
||||||
|
new ParseNode("delimsizing", {
|
||||||
|
size: delimiterSizes[nucleus.type].size,
|
||||||
|
type: delimiterSizes[nucleus.type].type,
|
||||||
|
value: delim.result.value
|
||||||
|
}, mode),
|
||||||
|
delim.position);
|
||||||
|
} else {
|
||||||
|
throw new ParseError(
|
||||||
|
"Expected delimiter after '" + nucleus.text + "'");
|
||||||
|
}
|
||||||
} else if (nucleus.type === "\\llap" || nucleus.type === "\\rlap") {
|
} else if (nucleus.type === "\\llap" || nucleus.type === "\\rlap") {
|
||||||
// If this is an llap or rlap, parse its argument and return
|
// If this is an llap or rlap, parse its argument and return
|
||||||
var group = this.parseGroup(nucleus.position, mode);
|
var group = this.parseGroup(nucleus.position, mode);
|
||||||
|
|
171
buildTree.js
171
buildTree.js
|
@ -70,6 +70,8 @@ var getTypeOfGroup = function(group) {
|
||||||
return getTypeOfGroup(group.value.value);
|
return getTypeOfGroup(group.value.value);
|
||||||
} else if (group.type === "sizing") {
|
} else if (group.type === "sizing") {
|
||||||
return getTypeOfGroup(group.value.value);
|
return getTypeOfGroup(group.value.value);
|
||||||
|
} else if (group.type === "delimsizing") {
|
||||||
|
return group.value.type;
|
||||||
} else {
|
} else {
|
||||||
return groupToType[group.type];
|
return groupToType[group.type];
|
||||||
}
|
}
|
||||||
|
@ -180,7 +182,7 @@ var groupTypes = {
|
||||||
}
|
}
|
||||||
|
|
||||||
var supsub;
|
var supsub;
|
||||||
var fixIE = makeSpan(["fix-ie"], []);
|
var fixIE = makeSpan(["fix-ie"], [new domTree.textNode("\u00a0")]);
|
||||||
|
|
||||||
if (!group.value.sup) {
|
if (!group.value.sup) {
|
||||||
v = Math.max(v, fontMetrics.metrics.sub1,
|
v = Math.max(v, fontMetrics.metrics.sub1,
|
||||||
|
@ -303,7 +305,7 @@ var groupTypes = {
|
||||||
denomrow.height = 0;
|
denomrow.height = 0;
|
||||||
denomrow.depth = denomrow.depth + v;
|
denomrow.depth = denomrow.depth + v;
|
||||||
|
|
||||||
var fixIE = makeSpan(["fix-ie"], []);
|
var fixIE = makeSpan(["fix-ie"], [new domTree.textNode("\u00a0")]);
|
||||||
|
|
||||||
var frac = makeSpan([], [numerrow, mid, denomrow, fixIE]);
|
var frac = makeSpan([], [numerrow, mid, denomrow, fixIE]);
|
||||||
|
|
||||||
|
@ -425,6 +427,165 @@ var groupTypes = {
|
||||||
["sizing", "reset-" + options.size, group.value.size,
|
["sizing", "reset-" + options.size, group.value.size,
|
||||||
getTypeOfGroup(group.value.value)],
|
getTypeOfGroup(group.value.value)],
|
||||||
[inner]);
|
[inner]);
|
||||||
|
},
|
||||||
|
|
||||||
|
delimsizing: function(group, options, prev) {
|
||||||
|
var normalDelimiters = [
|
||||||
|
"(", ")", "[", "\\lbrack", "]", "\\rbrack",
|
||||||
|
"\\{", "\\lbrace", "\\}", "\\rbrace",
|
||||||
|
"\\lfloor", "\\rfloor", "\\lceil", "\\rceil",
|
||||||
|
"<", ">", "\\langle", "\\rangle", "/", "\\backslash"
|
||||||
|
];
|
||||||
|
|
||||||
|
var stackDelimiters = [
|
||||||
|
"\\uparrow", "\\downarrow", "\\updownarrow",
|
||||||
|
"\\Uparrow", "\\Downarrow", "\\Updownarrow",
|
||||||
|
"|", "\\|", "\\vert", "\\Vert"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Metrics of the different sizes. Found by looking at TeX's output of
|
||||||
|
// $\bigl| \Bigl| \biggl| \Biggl| \showlists$
|
||||||
|
var sizeToMetrics = {
|
||||||
|
1: {height: .85, depth: .35},
|
||||||
|
2: {height: 1.15, depth: .65},
|
||||||
|
3: {height: 1.45, depth: .95},
|
||||||
|
4: {height: 1.75, depth: 1.25}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make an inner span with the given offset and in the given font
|
||||||
|
var makeInner = function(symbol, offset, font) {
|
||||||
|
var sizeClass;
|
||||||
|
if (font === "size1-regular") {
|
||||||
|
sizeClass = "size1";
|
||||||
|
}
|
||||||
|
|
||||||
|
var inner = makeSpan(
|
||||||
|
["delimsizinginner", sizeClass],
|
||||||
|
[makeSpan([], [makeText(symbol, font, group.mode)])]);
|
||||||
|
|
||||||
|
inner.style.top = offset + "em";
|
||||||
|
inner.height -= offset;
|
||||||
|
inner.depth += offset;
|
||||||
|
|
||||||
|
return inner;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get the metrics for a given symbol and font, after transformation
|
||||||
|
var getMetrics = function(symbol, font) {
|
||||||
|
if (symbols["math"][symbol] && symbols["math"][symbol].replace) {
|
||||||
|
return fontMetrics.getCharacterMetrics(
|
||||||
|
symbols["math"][symbol].replace, font);
|
||||||
|
} else {
|
||||||
|
return fontMetrics.getCharacterMetrics(
|
||||||
|
symbol, font);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var original = group.value.value;
|
||||||
|
|
||||||
|
if (utils.contains(normalDelimiters, original)) {
|
||||||
|
// These delimiters can be created by simply using the size1-size4
|
||||||
|
// fonts, so they don't require special treatment
|
||||||
|
if (original === "<") {
|
||||||
|
original = "\\langle";
|
||||||
|
} else if (original === ">") {
|
||||||
|
original = "\\rangle";
|
||||||
|
}
|
||||||
|
|
||||||
|
var size = "size" + group.value.size;
|
||||||
|
var inner = mathrmSize(
|
||||||
|
original, group.value.size, group.mode);
|
||||||
|
|
||||||
|
return makeSpan(
|
||||||
|
["delimsizing", size, groupToType[group.value.type]],
|
||||||
|
[inner], options.getColor());
|
||||||
|
} else if (utils.contains(stackDelimiters, original)) {
|
||||||
|
// These delimiters can be created by stacking other delimiters on
|
||||||
|
// top of each other to create the correct size
|
||||||
|
|
||||||
|
// There are three parts, the top, a repeated middle, and a bottom.
|
||||||
|
var top = middle = bottom = original;
|
||||||
|
var font = "size1-regular";
|
||||||
|
var overlap = false;
|
||||||
|
|
||||||
|
// We set the parts and font based on the symbol. Note that we use
|
||||||
|
// '\u23d0' instead of '|' and '\u2016' instead of '\\|' for the
|
||||||
|
// middles of the arrows
|
||||||
|
if (original === "\\uparrow") {
|
||||||
|
middle = bottom = "\u23d0";
|
||||||
|
} else if (original === "\\Uparrow") {
|
||||||
|
middle = bottom = "\u2016";
|
||||||
|
} else if (original === "\\downarrow") {
|
||||||
|
top = middle = "\u23d0";
|
||||||
|
} else if (original === "\\Downarrow") {
|
||||||
|
top = middle = "\u2016";
|
||||||
|
} else if (original === "\\updownarrow") {
|
||||||
|
top = "\\uparrow";
|
||||||
|
middle = "\u23d0";
|
||||||
|
bottom = "\\downarrow";
|
||||||
|
} else if (original === "\\Updownarrow") {
|
||||||
|
top = "\\Uparrow";
|
||||||
|
middle = "\u2016";
|
||||||
|
bottom = "\\Downarrow";
|
||||||
|
} else if (original === "|" || original === "\\vert") {
|
||||||
|
overlap = true;
|
||||||
|
} else if (original === "\\|" || original === "\\Vert") {
|
||||||
|
overlap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the metrics of the final symbol
|
||||||
|
var metrics = sizeToMetrics[group.value.size];
|
||||||
|
var heightTotal = metrics.height + metrics.depth;
|
||||||
|
|
||||||
|
// Get the metrics of the three sections
|
||||||
|
var topMetrics = getMetrics(top, font);
|
||||||
|
var topHeightTotal = topMetrics.height + topMetrics.depth;
|
||||||
|
var middleMetrics = getMetrics(middle, font);
|
||||||
|
var middleHeightTotal = middleMetrics.height + middleMetrics.depth;
|
||||||
|
var bottomMetrics = getMetrics(bottom, font);
|
||||||
|
var bottomHeightTotal = bottomMetrics.height + bottomMetrics.depth;
|
||||||
|
|
||||||
|
var middleHeight = heightTotal - topHeightTotal - bottomHeightTotal;
|
||||||
|
var symbolCount = Math.ceil(middleHeight / middleHeightTotal);
|
||||||
|
|
||||||
|
if (overlap) {
|
||||||
|
// 2 * overlapAmount + middleHeight =
|
||||||
|
// (symbolCount - 1) * (middleHeightTotal - overlapAmount) +
|
||||||
|
// middleHeightTotal
|
||||||
|
var overlapAmount = (symbolCount * middleHeightTotal -
|
||||||
|
middleHeight) / (symbolCount + 1);
|
||||||
|
} else {
|
||||||
|
var overlapAmount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep a list of the inner spans
|
||||||
|
var inners = [];
|
||||||
|
|
||||||
|
// Add the top symbol
|
||||||
|
inners.push(
|
||||||
|
makeInner(top, topMetrics.height - metrics.height, font));
|
||||||
|
|
||||||
|
// Add middle symbols until there's only space for the bottom symbol
|
||||||
|
var curr_height = metrics.height - topHeightTotal + overlapAmount;
|
||||||
|
for (var i = 0; i < symbolCount; i++) {
|
||||||
|
inners.push(
|
||||||
|
makeInner(middle, middleMetrics.height - curr_height, font));
|
||||||
|
curr_height -= middleHeightTotal - overlapAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the bottom symbol
|
||||||
|
inners.push(
|
||||||
|
makeInner(bottom, metrics.depth - bottomMetrics.depth, font));
|
||||||
|
|
||||||
|
var fixIE = makeSpan(["fix-ie"], [new domTree.textNode("\u00a0")]);
|
||||||
|
inners.push(fixIE);
|
||||||
|
|
||||||
|
return makeSpan(
|
||||||
|
["delimsizing", "mult", groupToType[group.value.type]],
|
||||||
|
inners, options.getColor());
|
||||||
|
} else {
|
||||||
|
throw new ParseError("Illegal delimiter: '" + original + "'");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -478,7 +639,7 @@ var buildGroup = function(group, options, prev) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var makeText = function(value, style, mode) {
|
var makeText = function(value, style, mode) {
|
||||||
if (symbols[mode][value].replace) {
|
if (symbols[mode][value] && symbols[mode][value].replace) {
|
||||||
value = symbols[mode][value].replace;
|
value = symbols[mode][value].replace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,6 +675,10 @@ var mathrm = function(value, mode) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var mathrmSize = function(value, size, mode) {
|
||||||
|
return makeText(value, "size" + size + "-regular", mode);
|
||||||
|
}
|
||||||
|
|
||||||
var buildTree = function(tree) {
|
var buildTree = function(tree) {
|
||||||
// Setup the default options
|
// Setup the default options
|
||||||
var options = new Options(Style.TEXT, "size5", "");
|
var options = new Options(Style.TEXT, "size5", "");
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -39,7 +39,8 @@ end
|
||||||
font_dir = File.join(File.dirname(__FILE__), 'static/fonts/')
|
font_dir = File.join(File.dirname(__FILE__), 'static/fonts/')
|
||||||
metrics = {}
|
metrics = {}
|
||||||
|
|
||||||
%w[main-regular math-italic ams-regular].each do |face|
|
%w[main-regular math-italic ams-regular
|
||||||
|
size1-regular size2-regular size3-regular size4-regular].each do |face|
|
||||||
metrics[face] = metrics_for_file(File.join(font_dir, 'katex_%s.ttf' % face))
|
metrics[face] = metrics_for_file(File.join(font_dir, 'katex_%s.ttf' % face))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,8 @@ big parens
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sizing { display: inline-block; }
|
.sizing {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
@size-1: 0.5;
|
@size-1: 0.5;
|
||||||
@size-2: 0.7;
|
@size-2: 0.7;
|
||||||
|
@ -322,7 +323,7 @@ big parens
|
||||||
@size-10: 2.49;
|
@size-10: 2.49;
|
||||||
|
|
||||||
.generate-size-change(@from, @to) {
|
.generate-size-change(@from, @to) {
|
||||||
.reset-size@{from}.size@{to} {
|
&.reset-size@{from}.size@{to} {
|
||||||
@sizeFromVariable: ~"size-@{from}";
|
@sizeFromVariable: ~"size-@{from}";
|
||||||
@sizeToVariable: ~"size-@{to}";
|
@sizeToVariable: ~"size-@{to}";
|
||||||
font-size: (@@sizeToVariable / @@sizeFromVariable) * 1em;
|
font-size: (@@sizeToVariable / @@sizeFromVariable) * 1em;
|
||||||
|
@ -342,4 +343,28 @@ big parens
|
||||||
}
|
}
|
||||||
|
|
||||||
.generate-from-size-change(1);
|
.generate-from-size-change(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.delimsizing {
|
||||||
|
&.size1 { font-family: katex_size1; }
|
||||||
|
&.size2 { font-family: katex_size2; }
|
||||||
|
&.size3 { font-family: katex_size3; }
|
||||||
|
&.size4 { font-family: katex_size4; }
|
||||||
|
|
||||||
|
&.mult {
|
||||||
|
.baseline-align-hack-outer;
|
||||||
|
|
||||||
|
> .fix-ie,
|
||||||
|
> .delimsizinginner {
|
||||||
|
.baseline-align-hack-middle;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.size1 {
|
||||||
|
> span {
|
||||||
|
font-family: katex_size1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
111
symbols.js
111
symbols.js
|
@ -314,7 +314,7 @@ var symbols = {
|
||||||
"\\lvert": {
|
"\\lvert": {
|
||||||
font: "main",
|
font: "main",
|
||||||
group: "open",
|
group: "open",
|
||||||
replace: "|"
|
replace: "\u2223"
|
||||||
},
|
},
|
||||||
")": {
|
")": {
|
||||||
font: "main",
|
font: "main",
|
||||||
|
@ -340,7 +340,7 @@ var symbols = {
|
||||||
"\\rvert": {
|
"\\rvert": {
|
||||||
font: "main",
|
font: "main",
|
||||||
group: "close",
|
group: "close",
|
||||||
replace: "|"
|
replace: "\u2223"
|
||||||
},
|
},
|
||||||
"=": {
|
"=": {
|
||||||
font: "main",
|
font: "main",
|
||||||
|
@ -563,6 +563,111 @@ var symbols = {
|
||||||
font: "main",
|
font: "main",
|
||||||
group: "textord",
|
group: "textord",
|
||||||
replace: "\u25b9"
|
replace: "\u25b9"
|
||||||
|
},
|
||||||
|
"\\{": {
|
||||||
|
font: "main",
|
||||||
|
group: "open",
|
||||||
|
replace: "{"
|
||||||
|
},
|
||||||
|
"\\}": {
|
||||||
|
font: "main",
|
||||||
|
group: "close",
|
||||||
|
replace: "}"
|
||||||
|
},
|
||||||
|
"\\lbrace": {
|
||||||
|
font: "main",
|
||||||
|
group: "open",
|
||||||
|
replace: "{"
|
||||||
|
},
|
||||||
|
"\\rbrace": {
|
||||||
|
font: "main",
|
||||||
|
group: "close",
|
||||||
|
replace: "}"
|
||||||
|
},
|
||||||
|
"\\lbrack": {
|
||||||
|
font: "main",
|
||||||
|
group: "open",
|
||||||
|
replace: "["
|
||||||
|
},
|
||||||
|
"\\rbrack": {
|
||||||
|
font: "main",
|
||||||
|
group: "close",
|
||||||
|
replace: "]"
|
||||||
|
},
|
||||||
|
"\\lfloor": {
|
||||||
|
font: "main",
|
||||||
|
group: "open",
|
||||||
|
replace: "\u230a"
|
||||||
|
},
|
||||||
|
"\\rfloor": {
|
||||||
|
font: "main",
|
||||||
|
group: "close",
|
||||||
|
replace: "\u230b"
|
||||||
|
},
|
||||||
|
"\\lceil": {
|
||||||
|
font: "main",
|
||||||
|
group: "open",
|
||||||
|
replace: "\u2308"
|
||||||
|
},
|
||||||
|
"\\rceil": {
|
||||||
|
font: "main",
|
||||||
|
group: "close",
|
||||||
|
replace: "\u2309"
|
||||||
|
},
|
||||||
|
"\\backslash": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\\"
|
||||||
|
},
|
||||||
|
"|": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2223"
|
||||||
|
},
|
||||||
|
"\\vert": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2223"
|
||||||
|
},
|
||||||
|
"\\|": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2225"
|
||||||
|
},
|
||||||
|
"\\Vert": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2225"
|
||||||
|
},
|
||||||
|
"\\uparrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2191"
|
||||||
|
},
|
||||||
|
"\\Uparrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u21d1"
|
||||||
|
},
|
||||||
|
"\\downarrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2193"
|
||||||
|
},
|
||||||
|
"\\Downarrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u21d3"
|
||||||
|
},
|
||||||
|
"\\updownarrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u2195"
|
||||||
|
},
|
||||||
|
"\\Updownarrow": {
|
||||||
|
font: "main",
|
||||||
|
group: "textord",
|
||||||
|
replace: "\u21d5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"text": {
|
"text": {
|
||||||
|
@ -584,7 +689,7 @@ var symbols = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var mathTextSymbols = "0123456789/|@.\"";
|
var mathTextSymbols = "0123456789/@.\"";
|
||||||
for (var i = 0; i < mathTextSymbols.length; i++) {
|
for (var i = 0; i < mathTextSymbols.length; i++) {
|
||||||
var ch = mathTextSymbols.charAt(i);
|
var ch = mathTextSymbols.charAt(i);
|
||||||
symbols["math"][ch] = {
|
symbols["math"][ch] = {
|
||||||
|
|
BIN
test/huxley/DelimiterSizing.hux/firefox-1.png
Normal file
BIN
test/huxley/DelimiterSizing.hux/firefox-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
5
test/huxley/DelimiterSizing.hux/record.json
Normal file
5
test/huxley/DelimiterSizing.hux/record.json
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"action": "screenshot"
|
||||||
|
}
|
||||||
|
]
|
|
@ -93,5 +93,11 @@
|
||||||
"name": "Lap",
|
"name": "Lap",
|
||||||
"screenSize": [1024, 768],
|
"screenSize": [1024, 768],
|
||||||
"url": "http://localhost:7936/test/huxley/test.html?m=ab\\llap{f}cd\\rlap{g}h"
|
"url": "http://localhost:7936/test/huxley/test.html?m=ab\\llap{f}cd\\rlap{g}h"
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "DelimiterSizing",
|
||||||
|
"screenSize": [1024, 768],
|
||||||
|
"url": "http://localhost:7936/test/huxley/test.html?m=\\bigl\\uparrow\\Bigl\\downarrow\\biggl\\updownarrow\\Biggl\\Uparrow\\Biggr\\Downarrow\\biggr\\langle\\Bigr\\}\\bigr\\rfloor"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -626,3 +626,44 @@ describe("A tie parser", function() {
|
||||||
expect(parse[2].type).toMatch("spacing");
|
expect(parse[2].type).toMatch("spacing");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("A delimiter sizing parser", function() {
|
||||||
|
var normalDelim = "\\bigl |";
|
||||||
|
var notDelim = "\\bigl x";
|
||||||
|
var bigDelim = "\\Biggr \\langle";
|
||||||
|
|
||||||
|
it("should parse normal delimiters", function() {
|
||||||
|
expect(function() {
|
||||||
|
parseTree(normalDelim);
|
||||||
|
parseTree(bigDelim);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should not parse not-delimiters", function() {
|
||||||
|
expect(function() {
|
||||||
|
parseTree(notDelim);
|
||||||
|
}).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should produce a delimsizing", function() {
|
||||||
|
var parse = parseTree(normalDelim)[0];
|
||||||
|
|
||||||
|
expect(parse.type).toMatch("delimsizing");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should produce the correct direction delimiter", function() {
|
||||||
|
var leftParse = parseTree(normalDelim)[0];
|
||||||
|
var rightParse = parseTree(bigDelim)[0];
|
||||||
|
|
||||||
|
expect(leftParse.value.type).toMatch("open");
|
||||||
|
expect(rightParse.value.type).toMatch("close");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should parse the correct size delimiter", function() {
|
||||||
|
var smallParse = parseTree(normalDelim)[0];
|
||||||
|
var bigParse = parseTree(bigDelim)[0];
|
||||||
|
|
||||||
|
expect(smallParse.value.size).toEqual(1);
|
||||||
|
expect(bigParse.value.size).toEqual(4);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user