Implement cases environment
See issue #278. Although the official definition makes use of @{…} notation, we use custom spacing instead, since that seems easier for now.
This commit is contained in:
parent
7f1b53cbfd
commit
758bdba31e
|
@ -511,7 +511,9 @@ var groupTypes = {
|
|||
|
||||
// Vertical spacing
|
||||
var baselineskip = 12 * pt; // see size10.clo
|
||||
var arraystretch = 1; // factor, see lttab.dtx
|
||||
// Default \arraystretch from lttab.dtx
|
||||
// TODO(gagern): may get redefined once we have user-defined macros
|
||||
var arraystretch = utils.deflt(group.value.arraystretch, 1);
|
||||
var arrayskip = arraystretch * baselineskip;
|
||||
var arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and
|
||||
var arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx
|
||||
|
@ -565,14 +567,19 @@ var groupTypes = {
|
|||
body[r] = outrow;
|
||||
}
|
||||
var offset = totalHeight / 2 + fontMetrics.metrics.axisHeight;
|
||||
var colalign = group.value.colalign || [];
|
||||
var coldescriptions = group.value.cols || [];
|
||||
var cols = [];
|
||||
var colsep;
|
||||
for (c = 0; c < nc; ++c) {
|
||||
var coldescr = coldescriptions[c] || {};
|
||||
var sepwidth;
|
||||
if (c > 0 || group.value.hskipBeforeAndAfter) {
|
||||
colsep = makeSpan(["arraycolsep"], []);
|
||||
colsep.style.width = arraycolsep + "em";
|
||||
cols.push(colsep);
|
||||
sepwidth = utils.deflt(coldescr.pregap, arraycolsep);
|
||||
if (sepwidth !== 0) {
|
||||
colsep = makeSpan(["arraycolsep"], []);
|
||||
colsep.style.width = sepwidth + "em";
|
||||
cols.push(colsep);
|
||||
}
|
||||
}
|
||||
var col = [];
|
||||
for (r = 0; r < nr; ++r) {
|
||||
|
@ -588,13 +595,16 @@ var groupTypes = {
|
|||
}
|
||||
col = buildCommon.makeVList(col, "individualShift", null, options);
|
||||
col = makeSpan(
|
||||
["col-align-" + (colalign[c] || "c")],
|
||||
["col-align-" + (coldescr.align || "c")],
|
||||
[col]);
|
||||
cols.push(col);
|
||||
if (c < nc - 1 || group.value.hskipBeforeAndAfter) {
|
||||
colsep = makeSpan(["arraycolsep"], []);
|
||||
colsep.style.width = arraycolsep + "em";
|
||||
cols.push(colsep);
|
||||
sepwidth = utils.deflt(coldescr.postgap, arraycolsep);
|
||||
if (sepwidth !== 0) {
|
||||
colsep = makeSpan(["arraycolsep"], []);
|
||||
colsep.style.width = sepwidth + "em";
|
||||
cols.push(colsep);
|
||||
}
|
||||
}
|
||||
}
|
||||
body = makeSpan(["mtable"], cols);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var fontMetrics = require("./fontMetrics");
|
||||
var parseData = require("./parseData");
|
||||
var ParseError = require("./ParseError");
|
||||
|
||||
|
@ -66,10 +67,12 @@ var environmentDefinitions = [
|
|||
var parser = this;
|
||||
// Currently only supports alignment, no separators like | yet.
|
||||
colalign = colalign.value.map ? colalign.value : [colalign];
|
||||
colalign = colalign.map(function(node) {
|
||||
var cols = colalign.map(function(node) {
|
||||
var ca = node.value;
|
||||
if ("lcr".indexOf(ca) !== -1) {
|
||||
return ca;
|
||||
return {
|
||||
align: ca
|
||||
};
|
||||
}
|
||||
throw new ParseError(
|
||||
"Unknown column alignment: " + node.value,
|
||||
|
@ -77,7 +80,7 @@ var environmentDefinitions = [
|
|||
});
|
||||
var res = {
|
||||
type: "array",
|
||||
colalign: colalign,
|
||||
cols: cols,
|
||||
hskipBeforeAndAfter: true // \@preamble in lttab.dtx
|
||||
};
|
||||
res = parseArray(parser, pos, mode, res);
|
||||
|
@ -111,8 +114,36 @@ var environmentDefinitions = [
|
|||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// A cases environment (in amsmath.sty) is almost equivalent to
|
||||
// \def\arraystretch{1.2}%
|
||||
// \left\{\begin{array}{@{}l@{\quad}l@{}} … \end{array}\right.
|
||||
{
|
||||
names: ["cases"],
|
||||
handler: function(pos, mode, envName) {
|
||||
var res = {
|
||||
type: "array",
|
||||
arraystretch: 1.2,
|
||||
cols: [{
|
||||
align: "l",
|
||||
pregap: 0,
|
||||
postgap: fontMetrics.metrics.quad
|
||||
}, {
|
||||
align: "l",
|
||||
pregap: 0,
|
||||
postgap: 0
|
||||
}]
|
||||
};
|
||||
res = parseArray(this, pos, mode, res);
|
||||
res.result = new ParseNode("leftright", {
|
||||
body: [res.result],
|
||||
left: "\\{",
|
||||
right: "."
|
||||
}, mode);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = (function() {
|
||||
|
|
|
@ -31,6 +31,13 @@ var contains = function(list, elem) {
|
|||
return indexOf(list, elem) !== -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provide a default value if a setting is undefined
|
||||
*/
|
||||
var deflt = function(setting, defaultIfUndefined) {
|
||||
return setting === undefined ? defaultIfUndefined : setting;
|
||||
};
|
||||
|
||||
// hyphenate and escape adapted from Facebook's React under Apache 2 license
|
||||
|
||||
var uppercase = /([A-Z])/g;
|
||||
|
@ -89,6 +96,7 @@ function clearNode(node) {
|
|||
|
||||
module.exports = {
|
||||
contains: contains,
|
||||
deflt: deflt,
|
||||
escape: escape,
|
||||
hyphenate: hyphenate,
|
||||
indexOf: indexOf,
|
||||
|
|
|
@ -1310,7 +1310,17 @@ describe("An array environment", function() {
|
|||
it("should accept a single alignment character", function() {
|
||||
var parse = getParsed("\\begin{array}r1\\\\20\\end{array}");
|
||||
expect(parse[0].type).toBe("array");
|
||||
expect(parse[0].value.colalign).toEqual(["r"]);
|
||||
expect(parse[0].value.cols).toEqual([{align:"r"}]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("A cases environment", function() {
|
||||
|
||||
it("should parse its input", function() {
|
||||
expect("f(a,b)=\\begin{cases}a+1&\\text{if }b\\text{ is odd}\\\\" +
|
||||
"a&\\text{if }b=0\\\\a-1&\\text{otherwise}\\end{cases}")
|
||||
.toParse();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
BIN
test/screenshotter/images/Cases-firefox.png
Normal file
BIN
test/screenshotter/images/Cases-firefox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -4,6 +4,7 @@
|
|||
"Baseline": "http://localhost:7936/test/screenshotter/test.html?m=a+b-c\\cdot d/e",
|
||||
"BasicTest": "http://localhost:7936/test/screenshotter/test.html?m=a",
|
||||
"BinomTest": "http://localhost:7936/test/screenshotter/test.html?m=\\dbinom{a}{b}\\tbinom{a}{b}^{\\binom{a}{b}+17}",
|
||||
"Cases": "http://localhost:7936/test/screenshotter/test.html?m=f(a,b)=\\begin{cases}a+1%26\\text{if }b\\text{ is odd}\\\\a%26\\text{if }b=0\\\\a-1%26\\text{otherwise}\\end{cases}",
|
||||
"Colors": "http://localhost:7936/test/screenshotter/test.html?m=\\blue{a}\\color{%230f0}{b}\\color{red}{c}",
|
||||
"DeepFontSizing": "http://localhost:7936/test/screenshotter/test.html?m=a^{\\big| x^{\\big(}}_{\\Big\\uparrow} + i^{i^{\\Huge x}_y}_{\\Huge z} + \\dfrac{\\Huge x}{y}",
|
||||
"DelimiterSizing": "http://localhost:7936/test/screenshotter/test.html?m=\\bigl\\uparrow\\Bigl\\downarrow\\biggl\\updownarrow\\Biggl\\Uparrow\\Biggr\\Downarrow\\biggr\\langle\\Bigr\\}\\bigr\\rfloor",
|
||||
|
|
Loading…
Reference in New Issue
Block a user