mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-10 13:38:39 +00:00
\color affects following \right, put array cells in their own groups (#1845)
* \color affects following \right Fix #1844 by giving `leftright` nodes a `rightColor` attribute for how to color the right bracket. Now `\color` sets the macro `\current@color` in the current environment (in particular, resetting after `\right`), just like `color.sty` does in LaTeX. This is used to specially pass the current color into any following `\right` and then into the `leftright` parse node. * Add test * Put each array cell in its own group/namespace * Improve cell group isolation, add test and TODO * Improve comments
This commit is contained in:
committed by
Kevin Barabash
parent
39da3f5119
commit
19d9d83ad3
@@ -79,6 +79,9 @@ function parseArray(
|
||||
}
|
||||
}
|
||||
|
||||
// Start group for first cell
|
||||
parser.gullet.beginGroup();
|
||||
|
||||
let row = [];
|
||||
const body = [row];
|
||||
const rowGaps = [];
|
||||
@@ -88,7 +91,11 @@ function parseArray(
|
||||
hLinesBeforeRow.push(getHLines(parser));
|
||||
|
||||
while (true) { // eslint-disable-line no-constant-condition
|
||||
// Parse each cell in its own group (namespace)
|
||||
let cell = parser.parseExpression(false, "\\cr");
|
||||
parser.gullet.endGroup();
|
||||
parser.gullet.beginGroup();
|
||||
|
||||
cell = {
|
||||
type: "ordgroup",
|
||||
mode: parser.mode,
|
||||
@@ -132,7 +139,12 @@ function parseArray(
|
||||
parser.nextToken);
|
||||
}
|
||||
}
|
||||
|
||||
// End cell group
|
||||
parser.gullet.endGroup();
|
||||
// End array group defining \\
|
||||
parser.gullet.endGroup();
|
||||
|
||||
return {
|
||||
type: "array",
|
||||
mode: parser.mode,
|
||||
@@ -671,6 +683,7 @@ defineEnvironment({
|
||||
body: [res],
|
||||
left: delimiters[0],
|
||||
right: delimiters[1],
|
||||
rightColor: undefined, // \right uninfluenced by \color in array
|
||||
} : res;
|
||||
},
|
||||
htmlBuilder,
|
||||
@@ -775,6 +788,7 @@ defineEnvironment({
|
||||
body: [res],
|
||||
left: "\\{",
|
||||
right: ".",
|
||||
rightColor: undefined,
|
||||
};
|
||||
},
|
||||
htmlBuilder,
|
||||
|
@@ -67,7 +67,13 @@ defineFunction({
|
||||
handler({parser, breakOnTokenText}, args) {
|
||||
const color = assertNodeType(args[0], "color-token").color;
|
||||
|
||||
// If we see a styling function, parse out the implicit body
|
||||
// Set macro \current@color in current namespace to store the current
|
||||
// color, mimicking the behavior of color.sty.
|
||||
// This is currently used just to correctly color a \right
|
||||
// that follows a \color command.
|
||||
parser.gullet.macros.set("\\current@color", color);
|
||||
|
||||
// Parse out the implicit body that should be colored.
|
||||
const body = parser.parseExpression(true, breakOnTokenText);
|
||||
|
||||
return {
|
||||
|
@@ -145,10 +145,16 @@ defineFunction({
|
||||
// \left case below triggers parsing of \right in
|
||||
// `const right = parser.parseFunction();`
|
||||
// uses this return value.
|
||||
const color = context.parser.gullet.macros.get("\\current@color");
|
||||
if (color && typeof color !== "string") {
|
||||
throw new ParseError(
|
||||
"\\current@color set to non-string in \\right");
|
||||
}
|
||||
return {
|
||||
type: "leftright-right",
|
||||
mode: context.parser.mode,
|
||||
delim: checkDelimiter(args[0], context).text,
|
||||
color, // undefined if not set via \color
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -178,6 +184,7 @@ defineFunction({
|
||||
body,
|
||||
left: delim.text,
|
||||
right: right.delim,
|
||||
rightColor: right.color,
|
||||
};
|
||||
},
|
||||
htmlBuilder: (group, options) => {
|
||||
@@ -241,12 +248,14 @@ defineFunction({
|
||||
}
|
||||
|
||||
let rightDelim;
|
||||
// Same for the right delimiter
|
||||
// Same for the right delimiter, but using color specified by \color
|
||||
if (group.right === ".") {
|
||||
rightDelim = html.makeNullDelimiter(options, ["mclose"]);
|
||||
} else {
|
||||
const colorOptions = group.rightColor ?
|
||||
options.withColor(group.rightColor) : options;
|
||||
rightDelim = delimiter.leftRightDelim(
|
||||
group.right, innerHeight, innerDepth, options,
|
||||
group.right, innerHeight, innerDepth, colorOptions,
|
||||
group.mode, ["mclose"]);
|
||||
}
|
||||
// Add it to the end of the expression.
|
||||
@@ -273,6 +282,10 @@ defineFunction({
|
||||
|
||||
rightNode.setAttribute("fence", "true");
|
||||
|
||||
if (group.rightColor) {
|
||||
rightNode.setAttribute("mathcolor", group.rightColor);
|
||||
}
|
||||
|
||||
inner.push(rightNode);
|
||||
}
|
||||
|
||||
|
@@ -318,12 +318,14 @@ type ParseNodeTypes = {
|
||||
body: AnyParseNode[],
|
||||
left: string,
|
||||
right: string,
|
||||
rightColor: ?string, // undefined means "inherit"
|
||||
|},
|
||||
"leftright-right": {|
|
||||
type: "leftright-right",
|
||||
mode: Mode,
|
||||
loc?: ?SourceLocation,
|
||||
delim: string,
|
||||
color: ?string, // undefined means "inherit"
|
||||
|},
|
||||
"mathchoice": {|
|
||||
type: "mathchoice",
|
||||
|
@@ -3123,6 +3123,21 @@ describe("A macro expander", function() {
|
||||
.toParseLike`11\sqrt[2]{2}11`;
|
||||
});
|
||||
|
||||
it("array cells generate groups", () => {
|
||||
expect`\def\x{1}\begin{matrix}\x&\def\x{2}\x&\x\end{matrix}`
|
||||
.toParseLike`\begin{matrix}1&2&1\end{matrix}`;
|
||||
});
|
||||
|
||||
// TODO: This doesn't yet work; before the environment gets called,
|
||||
// {matrix} gets consumed which means that the \def gets executed, before
|
||||
// we can create a group. :-( Issue #1989
|
||||
/*
|
||||
it("array cells generate groups", () => {
|
||||
expect`\def\x{1}\begin{matrix}\def\x{2}&\x\end{matrix}`
|
||||
.toParseLike`\begin{matrix}&1\end{matrix}`;
|
||||
});
|
||||
*/
|
||||
|
||||
it("\\gdef changes settings.macros", () => {
|
||||
const macros = {};
|
||||
expect`\gdef\foo{1}`.toParse(new Settings({macros}));
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 39 KiB |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 28 KiB |
@@ -77,7 +77,11 @@ Cases: |
|
||||
Colors:
|
||||
tex: \blue{a}\textcolor{#0f0}{b}\textcolor{red}{c}
|
||||
nolatex: different syntax and different scope
|
||||
ColorImplicit: bl{ack\color{red}red\textcolor{green}{green}red\color{blue}blue}black
|
||||
ColorImplicit:
|
||||
\begin{array}{l}
|
||||
bl{ack\color{red}red\textcolor{green}{green}red\color{blue}blue}black \\
|
||||
black\left(black\color{red}red\right)black
|
||||
\end{array}
|
||||
ColorSpacing: \textcolor{red}{\displaystyle \int x} + 1
|
||||
Colorbox: a \colorbox{teal} B \fcolorbox{blue}{red}{C} e+\colorbox{teal}x
|
||||
DashesAndQuotes: |
|
||||
|
Reference in New Issue
Block a user