mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-08 12:38:39 +00:00
Flatten "styling", "text", and "array" ParseNodes. (#1559)
* Flatten "styling" ParseNode. * Flatten "text" ParseNode. * Flatten "array" ParseNode.
This commit is contained in:
@@ -319,10 +319,7 @@ export default class Parser {
|
||||
const textNode = {
|
||||
type: "text",
|
||||
mode: this.mode,
|
||||
value: {
|
||||
type: "text",
|
||||
body: textordArray,
|
||||
},
|
||||
};
|
||||
|
||||
const colorNode = {
|
||||
|
@@ -171,8 +171,7 @@ export const buildExpression = function(
|
||||
} else if (node.type === "sizing") {
|
||||
glueOptions = options.havingSize(node.size);
|
||||
} else if (node.type === "styling") {
|
||||
glueOptions = options.havingStyle(
|
||||
styleMap[node.value.style]);
|
||||
glueOptions = options.havingStyle(styleMap[node.style]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,39 +16,15 @@ import type Parser from "../Parser";
|
||||
import type {ParseNode, AnyParseNode} from "../parseNode";
|
||||
import type {StyleStr} from "../types";
|
||||
import type {HtmlBuilder, MathMLBuilder} from "../defineFunction";
|
||||
import type {Measurement} from "../units";
|
||||
|
||||
// Data stored in the ParseNode associated with the environment.
|
||||
type AlignSpec = { type: "separator", separator: string } | {
|
||||
export type AlignSpec = { type: "separator", separator: string } | {
|
||||
type: "align",
|
||||
align: string,
|
||||
pregap?: number,
|
||||
postgap?: number,
|
||||
};
|
||||
|
||||
export type ArrayEnvNodeData = {|
|
||||
type: "array",
|
||||
hskipBeforeAndAfter?: boolean,
|
||||
addJot?: boolean,
|
||||
cols?: AlignSpec[],
|
||||
arraystretch: number,
|
||||
body: AnyParseNode[][], // List of rows in the (2D) array.
|
||||
rowGaps: (?Measurement)[],
|
||||
hLinesBeforeRow: Array<boolean[]>,
|
||||
|};
|
||||
// Same as above but with some fields not yet filled.
|
||||
type ArrayEnvNodeDataIncomplete = {|
|
||||
type: "array",
|
||||
hskipBeforeAndAfter?: boolean,
|
||||
addJot?: boolean,
|
||||
cols?: AlignSpec[],
|
||||
// Before these fields are filled.
|
||||
arraystretch?: number,
|
||||
body?: AnyParseNode[][],
|
||||
rowGaps?: (?Measurement)[],
|
||||
hLinesBeforeRow?: Array<boolean[]>,
|
||||
|};
|
||||
|
||||
function getHLines(parser: Parser): boolean[] {
|
||||
// Return an array. The array length = number of hlines.
|
||||
// Each element in the array tells if the line is dashed.
|
||||
@@ -72,7 +48,12 @@ function getHLines(parser: Parser): boolean[] {
|
||||
*/
|
||||
function parseArray(
|
||||
parser: Parser,
|
||||
result: ArrayEnvNodeDataIncomplete,
|
||||
{hskipBeforeAndAfter, addJot, cols, arraystretch}: {|
|
||||
hskipBeforeAndAfter?: boolean,
|
||||
addJot?: boolean,
|
||||
cols?: AlignSpec[],
|
||||
arraystretch?: number,
|
||||
|},
|
||||
style: StyleStr,
|
||||
): ParseNode<"array"> {
|
||||
// Parse body of array with \\ temporarily mapped to \cr
|
||||
@@ -80,15 +61,15 @@ function parseArray(
|
||||
parser.gullet.macros.set("\\\\", "\\cr");
|
||||
|
||||
// Get current arraystretch if it's not set by the environment
|
||||
if (!result.arraystretch) {
|
||||
const arraystretch = parser.gullet.expandMacroAsText("\\arraystretch");
|
||||
if (arraystretch == null) {
|
||||
if (!arraystretch) {
|
||||
const stretch = parser.gullet.expandMacroAsText("\\arraystretch");
|
||||
if (stretch == null) {
|
||||
// Default \arraystretch from lttab.dtx
|
||||
result.arraystretch = 1;
|
||||
arraystretch = 1;
|
||||
} else {
|
||||
result.arraystretch = parseFloat(arraystretch);
|
||||
if (!result.arraystretch || result.arraystretch < 0) {
|
||||
throw new ParseError(`Invalid \\arraystretch: ${arraystretch}`);
|
||||
arraystretch = parseFloat(stretch);
|
||||
if (!arraystretch || arraystretch < 0) {
|
||||
throw new ParseError(`Invalid \\arraystretch: ${stretch}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,11 +93,8 @@ function parseArray(
|
||||
cell = {
|
||||
type: "styling",
|
||||
mode: parser.mode,
|
||||
value: {
|
||||
type: "styling",
|
||||
style: style,
|
||||
value: [cell],
|
||||
},
|
||||
style,
|
||||
body: [cell],
|
||||
};
|
||||
}
|
||||
row.push(cell);
|
||||
@@ -128,7 +106,7 @@ function parseArray(
|
||||
// the last line is empty.
|
||||
// NOTE: Currently, `cell` is the last item added into `row`.
|
||||
if (row.length === 1 && cell.type === "styling" &&
|
||||
cell.value.value[0].value.length === 0) {
|
||||
cell.body[0].value.length === 0) {
|
||||
body.pop();
|
||||
}
|
||||
if (hLinesBeforeRow.length < body.length + 1) {
|
||||
@@ -152,16 +130,17 @@ function parseArray(
|
||||
parser.nextToken);
|
||||
}
|
||||
}
|
||||
result.body = body;
|
||||
result.rowGaps = rowGaps;
|
||||
result.hLinesBeforeRow = hLinesBeforeRow;
|
||||
// $FlowFixMe: The required fields were added immediately above.
|
||||
const res: ArrayEnvNodeData = result;
|
||||
parser.gullet.endGroup();
|
||||
return {
|
||||
type: "array",
|
||||
mode: parser.mode,
|
||||
value: res,
|
||||
addJot,
|
||||
arraystretch,
|
||||
body,
|
||||
cols,
|
||||
rowGaps,
|
||||
hskipBeforeAndAfter,
|
||||
hLinesBeforeRow,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -186,8 +165,8 @@ type Outrow = {
|
||||
const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
let r;
|
||||
let c;
|
||||
const nr = group.value.body.length;
|
||||
const hLinesBeforeRow = group.value.hLinesBeforeRow;
|
||||
const nr = group.body.length;
|
||||
const hLinesBeforeRow = group.hLinesBeforeRow;
|
||||
let nc = 0;
|
||||
let body = new Array(nr);
|
||||
const hlines = [];
|
||||
@@ -201,7 +180,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
// Default \jot from ltmath.dtx
|
||||
// TODO(edemaine): allow overriding \jot via \setlength (#687)
|
||||
const jot = 3 * pt;
|
||||
const arrayskip = group.value.arraystretch * baselineskip;
|
||||
const arrayskip = group.arraystretch * baselineskip;
|
||||
const arstrutHeight = 0.7 * arrayskip; // \strutbox in ltfsstrc.dtx and
|
||||
const arstrutDepth = 0.3 * arrayskip; // \@arstrutbox in lttab.dtx
|
||||
|
||||
@@ -218,8 +197,8 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
}
|
||||
setHLinePos(hLinesBeforeRow[0]);
|
||||
|
||||
for (r = 0; r < group.value.body.length; ++r) {
|
||||
const inrow = group.value.body[r];
|
||||
for (r = 0; r < group.body.length; ++r) {
|
||||
const inrow = group.body[r];
|
||||
let height = arstrutHeight; // \@array adds an \@arstrut
|
||||
let depth = arstrutDepth; // to each tow (via the template)
|
||||
|
||||
@@ -239,7 +218,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
outrow[c] = elt;
|
||||
}
|
||||
|
||||
const rowGap = group.value.rowGaps[r];
|
||||
const rowGap = group.rowGaps[r];
|
||||
let gap = 0;
|
||||
if (rowGap) {
|
||||
gap = calculateSize(rowGap, options);
|
||||
@@ -254,7 +233,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
// In AMS multiline environments such as aligned and gathered, rows
|
||||
// correspond to lines that have additional \jot added to the
|
||||
// \baselineskip via \openup.
|
||||
if (group.value.addJot) {
|
||||
if (group.addJot) {
|
||||
depth += jot;
|
||||
}
|
||||
|
||||
@@ -270,7 +249,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
}
|
||||
|
||||
const offset = totalHeight / 2 + options.fontMetrics().axisHeight;
|
||||
const colDescriptions = group.value.cols || [];
|
||||
const colDescriptions = group.cols || [];
|
||||
const cols = [];
|
||||
let colSep;
|
||||
let colDescrNum;
|
||||
@@ -326,7 +305,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
}
|
||||
|
||||
let sepwidth;
|
||||
if (c > 0 || group.value.hskipBeforeAndAfter) {
|
||||
if (c > 0 || group.hskipBeforeAndAfter) {
|
||||
sepwidth = utils.deflt(colDescr.pregap, arraycolsep);
|
||||
if (sepwidth !== 0) {
|
||||
colSep = buildCommon.makeSpan(["arraycolsep"], []);
|
||||
@@ -357,7 +336,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
[col]);
|
||||
cols.push(col);
|
||||
|
||||
if (c < nc - 1 || group.value.hskipBeforeAndAfter) {
|
||||
if (c < nc - 1 || group.hskipBeforeAndAfter) {
|
||||
sepwidth = utils.deflt(colDescr.postgap, arraycolsep);
|
||||
if (sepwidth !== 0) {
|
||||
colSep = buildCommon.makeSpan(["arraycolsep"], []);
|
||||
@@ -393,7 +372,7 @@ const htmlBuilder: HtmlBuilder<"array"> = function(group, options) {
|
||||
|
||||
const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
||||
return new mathMLTree.MathNode(
|
||||
"mtable", group.value.body.map(function(row) {
|
||||
"mtable", group.body.map(function(row) {
|
||||
return new mathMLTree.MathNode(
|
||||
"mtr", row.map(function(cell) {
|
||||
return new mathMLTree.MathNode(
|
||||
@@ -405,12 +384,7 @@ const mathmlBuilder: MathMLBuilder<"array"> = function(group, options) {
|
||||
// Convenience function for aligned and alignedat environments.
|
||||
const alignedHandler = function(context, args) {
|
||||
const cols = [];
|
||||
let res = {
|
||||
type: "array",
|
||||
cols,
|
||||
addJot: true,
|
||||
};
|
||||
res = parseArray(context.parser, res, "display");
|
||||
const res = parseArray(context.parser, {cols, addJot: true}, "display");
|
||||
|
||||
// Determining number of columns.
|
||||
// 1. If the first argument is given, we use it as a number of columns,
|
||||
@@ -439,11 +413,11 @@ const alignedHandler = function(context, args) {
|
||||
numCols = numMaths * 2;
|
||||
}
|
||||
const isAligned = !numCols;
|
||||
res.value.body.forEach(function(row) {
|
||||
res.body.forEach(function(row) {
|
||||
for (let i = 1; i < row.length; i += 2) {
|
||||
// Modify ordgroup node within styling node
|
||||
const styling = assertNodeType(row[i], "styling");
|
||||
const ordgroup = assertNodeType(styling.value.value[0], "ordgroup");
|
||||
const ordgroup = assertNodeType(styling.body[0], "ordgroup");
|
||||
ordgroup.value.unshift(emptyGroup);
|
||||
}
|
||||
if (!isAligned) { // Case 1
|
||||
@@ -519,13 +493,11 @@ defineEnvironment({
|
||||
}
|
||||
throw new ParseError("Unknown column alignment: " + ca, nde);
|
||||
});
|
||||
let res = {
|
||||
type: "array",
|
||||
cols: cols,
|
||||
const res = {
|
||||
cols,
|
||||
hskipBeforeAndAfter: true, // \@preamble in lttab.dtx
|
||||
};
|
||||
res = parseArray(context.parser, res, dCellStyle(context.envName));
|
||||
return res;
|
||||
return parseArray(context.parser, res, dCellStyle(context.envName));
|
||||
},
|
||||
htmlBuilder,
|
||||
mathmlBuilder,
|
||||
@@ -555,10 +527,8 @@ defineEnvironment({
|
||||
"vmatrix": ["|", "|"],
|
||||
"Vmatrix": ["\\Vert", "\\Vert"],
|
||||
}[context.envName];
|
||||
const payload = {
|
||||
type: "array",
|
||||
hskipBeforeAndAfter: false, // \hskip -\arraycolsep in amsmath
|
||||
};
|
||||
// \hskip -\arraycolsep in amsmath
|
||||
const payload = {hskipBeforeAndAfter: false};
|
||||
const res: ParseNode<"array"> =
|
||||
parseArray(context.parser, payload, dCellStyle(context.envName));
|
||||
return delimiters ? {
|
||||
@@ -589,7 +559,6 @@ defineEnvironment({
|
||||
},
|
||||
handler(context) {
|
||||
const payload = {
|
||||
type: "array",
|
||||
arraystretch: 1.2,
|
||||
cols: [{
|
||||
type: "align",
|
||||
@@ -645,17 +614,15 @@ defineEnvironment({
|
||||
props: {
|
||||
numArgs: 0,
|
||||
},
|
||||
handler: function(context) {
|
||||
let res = {
|
||||
type: "array",
|
||||
handler(context) {
|
||||
const res = {
|
||||
cols: [{
|
||||
type: "align",
|
||||
align: "c",
|
||||
}],
|
||||
addJot: true,
|
||||
};
|
||||
res = parseArray(context.parser, res, "display");
|
||||
return res;
|
||||
return parseArray(context.parser, res, "display");
|
||||
},
|
||||
htmlBuilder,
|
||||
mathmlBuilder,
|
||||
|
@@ -62,11 +62,8 @@ defineFunction({
|
||||
const body = {
|
||||
type: "text",
|
||||
mode: parser.mode,
|
||||
value: {
|
||||
type: "text",
|
||||
font: "\\texttt",
|
||||
body: chars,
|
||||
},
|
||||
};
|
||||
return {
|
||||
type: "href",
|
||||
|
@@ -25,11 +25,8 @@ defineFunction({
|
||||
return {
|
||||
type: "styling",
|
||||
mode: parser.mode,
|
||||
value: {
|
||||
type: "styling",
|
||||
style: "text",
|
||||
value: body,
|
||||
},
|
||||
body,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -31,11 +31,8 @@ defineFunction({
|
||||
const text = {
|
||||
type: "text",
|
||||
mode: group.mode,
|
||||
value: {
|
||||
type: "text",
|
||||
body: ordargument(group.body),
|
||||
font: "mathrm", // simulate \textrm
|
||||
},
|
||||
};
|
||||
const sizedText = {
|
||||
type: "sizing",
|
||||
|
@@ -23,7 +23,7 @@ defineFunction({
|
||||
numArgs: 0,
|
||||
allowedInText: true,
|
||||
},
|
||||
handler: ({breakOnTokenText, funcName, parser}, args) => {
|
||||
handler({breakOnTokenText, funcName, parser}, args) {
|
||||
// parse out the implicit body
|
||||
parser.consumeSpaces();
|
||||
const body = parser.parseExpression(true, breakOnTokenText);
|
||||
@@ -35,22 +35,19 @@ defineFunction({
|
||||
return {
|
||||
type: "styling",
|
||||
mode: parser.mode,
|
||||
value: {
|
||||
type: "styling",
|
||||
// Figure out what style to use by pulling out the style from
|
||||
// the function name
|
||||
style,
|
||||
value: body,
|
||||
},
|
||||
body,
|
||||
};
|
||||
},
|
||||
htmlBuilder: (group, options) => {
|
||||
htmlBuilder(group, options) {
|
||||
// Style changes are handled in the TeXbook on pg. 442, Rule 3.
|
||||
const newStyle = styleMap[group.value.style];
|
||||
const newStyle = styleMap[group.style];
|
||||
const newOptions = options.havingStyle(newStyle).withFont('');
|
||||
return sizingGroup(group.value.value, newOptions, options);
|
||||
return sizingGroup(group.body, newOptions, options);
|
||||
},
|
||||
mathmlBuilder: (group, options) => {
|
||||
mathmlBuilder(group, options) {
|
||||
// Figure out what style we're changing to.
|
||||
// TODO(kevinb): dedupe this with buildHTML.js
|
||||
// This will be easier of handling of styling nodes is in the same file.
|
||||
@@ -61,10 +58,10 @@ defineFunction({
|
||||
"scriptscript": Style.SCRIPTSCRIPT,
|
||||
};
|
||||
|
||||
const newStyle = styleMap[group.value.style];
|
||||
const newStyle = styleMap[group.style];
|
||||
const newOptions = options.havingStyle(newStyle);
|
||||
|
||||
const inner = mml.buildExpression(group.value.value, newOptions);
|
||||
const inner = mml.buildExpression(group.body, newOptions);
|
||||
|
||||
const node = new mathMLTree.MathNode("mstyle", inner);
|
||||
|
||||
@@ -75,7 +72,7 @@ defineFunction({
|
||||
"scriptscript": ["2", "false"],
|
||||
};
|
||||
|
||||
const attr = styleAttributes[group.value.style];
|
||||
const attr = styleAttributes[group.style];
|
||||
|
||||
node.setAttribute("scriptlevel", attr[0]);
|
||||
node.setAttribute("displaystyle", attr[1]);
|
||||
|
@@ -20,7 +20,7 @@ const textFontShapes = {
|
||||
};
|
||||
|
||||
const optionsWithFont = (group, options) => {
|
||||
const font = group.value.font;
|
||||
const font = group.font;
|
||||
// Checks if the argument is a font family or a font style.
|
||||
if (!font) {
|
||||
return options;
|
||||
@@ -55,21 +55,18 @@ defineFunction({
|
||||
return {
|
||||
type: "text",
|
||||
mode: parser.mode,
|
||||
value: {
|
||||
type: "text",
|
||||
body: ordargument(body),
|
||||
font: funcName,
|
||||
},
|
||||
};
|
||||
},
|
||||
htmlBuilder(group, options) {
|
||||
const newOptions = optionsWithFont(group, options);
|
||||
const inner = html.buildExpression(group.value.body, newOptions, true);
|
||||
const inner = html.buildExpression(group.body, newOptions, true);
|
||||
buildCommon.tryCombineChars(inner);
|
||||
return buildCommon.makeSpan(["mord", "text"], inner, newOptions);
|
||||
},
|
||||
mathmlBuilder(group, options) {
|
||||
const newOptions = optionsWithFont(group, options);
|
||||
return mml.buildExpressionRow(group.value.body, newOptions);
|
||||
return mml.buildExpressionRow(group.body, newOptions);
|
||||
},
|
||||
});
|
||||
|
@@ -1,7 +1,7 @@
|
||||
// @flow
|
||||
import {NON_ATOMS} from "./symbols";
|
||||
import type SourceLocation from "./SourceLocation";
|
||||
import type {ArrayEnvNodeData} from "./environments/array";
|
||||
import type {AlignSpec} from "./environments/array";
|
||||
import type {Atom} from "./symbols";
|
||||
import type {Mode, StyleStr} from "./types";
|
||||
import type {Token} from "./Token";
|
||||
@@ -28,7 +28,13 @@ type ParseNodeTypes = {
|
||||
type: "array",
|
||||
mode: Mode,
|
||||
loc?: ?SourceLocation,
|
||||
value: ArrayEnvNodeData,
|
||||
hskipBeforeAndAfter?: boolean,
|
||||
addJot?: boolean,
|
||||
cols?: AlignSpec[],
|
||||
arraystretch: number,
|
||||
body: AnyParseNode[][], // List of rows in the (2D) array.
|
||||
rowGaps: (?Measurement)[],
|
||||
hLinesBeforeRow: Array<boolean[]>,
|
||||
|},
|
||||
"color": {|
|
||||
type: "color",
|
||||
@@ -85,11 +91,8 @@ type ParseNodeTypes = {
|
||||
type: "styling",
|
||||
mode: Mode,
|
||||
loc?: ?SourceLocation,
|
||||
value: {|
|
||||
type: "styling",
|
||||
style: StyleStr,
|
||||
value: AnyParseNode[],
|
||||
|},
|
||||
body: AnyParseNode[],
|
||||
|},
|
||||
"supsub": {|
|
||||
type: "supsub",
|
||||
@@ -110,12 +113,9 @@ type ParseNodeTypes = {
|
||||
type: "text",
|
||||
mode: Mode,
|
||||
loc?: ?SourceLocation,
|
||||
value: {|
|
||||
type: "text",
|
||||
body: AnyParseNode[],
|
||||
font?: string,
|
||||
|},
|
||||
|},
|
||||
"url": {|
|
||||
type: "url",
|
||||
mode: Mode,
|
||||
|
@@ -3,20 +3,13 @@
|
||||
exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
[
|
||||
{
|
||||
"type": "array",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "array",
|
||||
"arraystretch": 1.5,
|
||||
"body": [
|
||||
[
|
||||
{
|
||||
"type": "styling",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "styling",
|
||||
"style": "text",
|
||||
"value": [
|
||||
"body": [
|
||||
{
|
||||
"type": "ordgroup",
|
||||
"mode": "math",
|
||||
@@ -36,16 +29,13 @@ exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "math",
|
||||
"style": "text"
|
||||
},
|
||||
{
|
||||
"type": "styling",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "styling",
|
||||
"style": "text",
|
||||
"value": [
|
||||
"body": [
|
||||
{
|
||||
"type": "ordgroup",
|
||||
"mode": "math",
|
||||
@@ -65,18 +55,15 @@ exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "math",
|
||||
"style": "text"
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"type": "styling",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "styling",
|
||||
"style": "text",
|
||||
"value": [
|
||||
"body": [
|
||||
{
|
||||
"type": "ordgroup",
|
||||
"mode": "math",
|
||||
@@ -96,16 +83,13 @@ exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "math",
|
||||
"style": "text"
|
||||
},
|
||||
{
|
||||
"type": "styling",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "styling",
|
||||
"style": "text",
|
||||
"value": [
|
||||
"body": [
|
||||
{
|
||||
"type": "ordgroup",
|
||||
"mode": "math",
|
||||
@@ -125,8 +109,9 @@ exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "math",
|
||||
"style": "text"
|
||||
}
|
||||
]
|
||||
],
|
||||
@@ -139,11 +124,11 @@ exports[`A begin/end parser should grab \\arraystretch 1`] = `
|
||||
]
|
||||
],
|
||||
"hskipBeforeAndAfter": false,
|
||||
"mode": "math",
|
||||
"rowGaps": [
|
||||
null
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
`;
|
||||
|
||||
@@ -660,18 +645,15 @@ exports[`An implicit group parser within optional groups should work style comma
|
||||
"value": [
|
||||
{
|
||||
"type": "styling",
|
||||
"mode": "math",
|
||||
"value": {
|
||||
"type": "styling",
|
||||
"style": "text",
|
||||
"value": [
|
||||
"body": [
|
||||
{
|
||||
"type": "textord",
|
||||
"mode": "math",
|
||||
"value": "3"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"mode": "math",
|
||||
"style": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@@ -666,12 +666,12 @@ describe("A text parser", function() {
|
||||
const parse = getParsed(textExpression)[0];
|
||||
|
||||
expect(parse.type).toEqual("text");
|
||||
expect(parse.value).toBeDefined();
|
||||
expect(parse.body).toBeDefined();
|
||||
});
|
||||
|
||||
it("should produce textords instead of mathords", function() {
|
||||
const parse = getParsed(textExpression)[0];
|
||||
const group = parse.value.body;
|
||||
const group = parse.body;
|
||||
|
||||
expect(group[0].type).toEqual("textord");
|
||||
});
|
||||
@@ -694,7 +694,7 @@ describe("A text parser", function() {
|
||||
|
||||
it("should contract spaces", function() {
|
||||
const parse = getParsed(spaceTextExpression)[0];
|
||||
const group = parse.value.body;
|
||||
const group = parse.body;
|
||||
|
||||
expect(group[0].type).toEqual("spacing");
|
||||
expect(group[1].type).toEqual("textord");
|
||||
@@ -709,10 +709,8 @@ describe("A text parser", function() {
|
||||
it("should ignore a space before the text group", function() {
|
||||
const parse = getParsed(leadingSpaceTextExpression)[0];
|
||||
// [m, o, o]
|
||||
expect(parse.value.body).toHaveLength(3);
|
||||
expect(
|
||||
parse.value.body.map(function(n) { return n.value; }).join("")
|
||||
).toBe("moo");
|
||||
expect(parse.body).toHaveLength(3);
|
||||
expect(parse.body.map(n => n.value).join("")).toBe("moo");
|
||||
});
|
||||
|
||||
it("should parse math within text group", function() {
|
||||
@@ -860,14 +858,14 @@ describe("A tie parser", function() {
|
||||
|
||||
it("should produce spacing in text mode", function() {
|
||||
const text = getParsed(textTie)[0];
|
||||
const parse = text.value.body;
|
||||
const parse = text.body;
|
||||
|
||||
expect(parse[1].type).toEqual("spacing");
|
||||
});
|
||||
|
||||
it("should not contract with spaces in text mode", function() {
|
||||
const text = getParsed(textTie)[0];
|
||||
const parse = text.value.body;
|
||||
const parse = text.body;
|
||||
|
||||
expect(parse[2].type).toEqual("spacing");
|
||||
});
|
||||
@@ -1241,7 +1239,7 @@ describe("A begin/end parser", function() {
|
||||
|
||||
it("should eat a final newline", function() {
|
||||
const m3 = getParsed`\begin{matrix}a&b\\ c&d \\ \end{matrix}`[0];
|
||||
expect(m3.value.body).toHaveLength(2);
|
||||
expect(m3.body).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("should grab \\arraystretch", function() {
|
||||
@@ -1440,10 +1438,10 @@ describe("A style change parser", function() {
|
||||
|
||||
it("should produce the correct style", function() {
|
||||
const displayParse = getParsed`\displaystyle x`[0];
|
||||
expect(displayParse.value.style).toEqual("display");
|
||||
expect(displayParse.style).toEqual("display");
|
||||
|
||||
const scriptscriptParse = getParsed`\scriptscriptstyle x`[0];
|
||||
expect(scriptscriptParse.value.style).toEqual("scriptscript");
|
||||
expect(scriptscriptParse.style).toEqual("scriptscript");
|
||||
});
|
||||
|
||||
it("should only change the style within its group", function() {
|
||||
@@ -1454,7 +1452,7 @@ describe("A style change parser", function() {
|
||||
|
||||
expect(displayNode.type).toEqual("styling");
|
||||
|
||||
const displayBody = displayNode.value.value;
|
||||
const displayBody = displayNode.body;
|
||||
|
||||
expect(displayBody).toHaveLength(2);
|
||||
expect(displayBody[0].value).toEqual("e");
|
||||
@@ -2407,7 +2405,7 @@ describe("An array environment", function() {
|
||||
it("should accept a single alignment character", function() {
|
||||
const parse = getParsed`\begin{array}r1\\20\end{array}`;
|
||||
expect(parse[0].type).toBe("array");
|
||||
expect(parse[0].value.cols).toEqual([
|
||||
expect(parse[0].cols).toEqual([
|
||||
{type: "align", align: "r"},
|
||||
]);
|
||||
});
|
||||
@@ -2415,7 +2413,7 @@ describe("An array environment", function() {
|
||||
it("should accept vertical separators", function() {
|
||||
const parse = getParsed`\begin{array}{|l||c:r::}\end{array}`;
|
||||
expect(parse[0].type).toBe("array");
|
||||
expect(parse[0].value.cols).toEqual([
|
||||
expect(parse[0].cols).toEqual([
|
||||
{type: "separator", separator: "|"},
|
||||
{type: "align", align: "l"},
|
||||
{type: "separator", separator: "|"},
|
||||
@@ -2455,7 +2453,7 @@ describe("An aligned environment", function() {
|
||||
|
||||
it("should not eat the last row when its first cell is empty", function() {
|
||||
const ae = getParsed`\begin{aligned}&E_1 & (1)\\&E_2 & (2)\\&E_3 & (3)\end{aligned}`[0];
|
||||
expect(ae.value.body).toHaveLength(3);
|
||||
expect(ae.body).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user