mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-06 11:48:41 +00:00
feat: implement \relax as no-op function (#3384)
* feat: implement \relax as no-op function BREAKING CHANGE: `\relax` is now implemented as a function. It'll stop expansions and parsing, so the behavior around `\relax` may change. For example, `\kern2\relax em` will no longer work.
This commit is contained in:
@@ -3,6 +3,12 @@ id: migration
|
||||
title: Migration Guide
|
||||
---
|
||||
|
||||
## v0.15.0
|
||||
|
||||
`\relax` is now implemented as a function. It'll stop expansions and parsing,
|
||||
so the behavior around `\relax` may change. For example, `\kern2\relax em` will
|
||||
no longer work.
|
||||
|
||||
## v0.14.0
|
||||
|
||||
With module loaders that support conditional exports and ECMAScript modules,
|
||||
|
@@ -20,7 +20,6 @@ import type Settings from "./Settings";
|
||||
// List of commands that act like macros but aren't defined as a macro,
|
||||
// function, or symbol. Used in `isDefined`.
|
||||
export const implicitCommands = {
|
||||
"\\relax": true, // MacroExpander.js
|
||||
"^": true, // Parser.js
|
||||
"_": true, // Parser.js
|
||||
"\\limits": true, // Parser.js
|
||||
@@ -333,15 +332,12 @@ export default class MacroExpander implements MacroContextInterface {
|
||||
const expanded = this.expandOnce();
|
||||
// expandOnce returns Token if and only if it's fully expanded.
|
||||
if (expanded instanceof Token) {
|
||||
// \relax stops the expansion, but shouldn't get returned (a
|
||||
// null return value couldn't get implemented as a function).
|
||||
// the token after \noexpand is interpreted as if its meaning
|
||||
// were ‘\relax’
|
||||
if (expanded.text === "\\relax" || expanded.treatAsRelax) {
|
||||
this.stack.pop();
|
||||
} else {
|
||||
return this.stack.pop(); // === expanded
|
||||
if (expanded.treatAsRelax) {
|
||||
expanded.text = "\\relax";
|
||||
}
|
||||
return this.stack.pop(); // === expanded
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@ import "./functions/ordgroup";
|
||||
import "./functions/overline";
|
||||
import "./functions/phantom";
|
||||
import "./functions/raisebox";
|
||||
import "./functions/relax";
|
||||
import "./functions/rule";
|
||||
import "./functions/sizing";
|
||||
import "./functions/smash";
|
||||
|
17
src/functions/relax.js
Normal file
17
src/functions/relax.js
Normal file
@@ -0,0 +1,17 @@
|
||||
//@flow
|
||||
import defineFunction from "../defineFunction";
|
||||
|
||||
defineFunction({
|
||||
type: "internal",
|
||||
names: ["\\relax"],
|
||||
props: {
|
||||
numArgs: 0,
|
||||
allowedInText: true,
|
||||
},
|
||||
handler({parser}) {
|
||||
return {
|
||||
type: "internal",
|
||||
mode: parser.mode,
|
||||
};
|
||||
},
|
||||
});
|
@@ -368,7 +368,7 @@ defineMacro("\\substack", "\\begin{subarray}{c}#1\\end{subarray}");
|
||||
// \renewcommand{\colon}{\nobreak\mskip2mu\mathpunct{}\nonscript
|
||||
// \mkern-\thinmuskip{:}\mskip6muplus1mu\relax}
|
||||
defineMacro("\\colon", "\\nobreak\\mskip2mu\\mathpunct{}" +
|
||||
"\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu");
|
||||
"\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax");
|
||||
|
||||
// \newcommand{\boxed}[1]{\fbox{\m@th$\displaystyle#1$}}
|
||||
defineMacro("\\boxed", "\\fbox{$\\displaystyle{#1}$}");
|
||||
|
@@ -4046,3 +4046,9 @@ describe("debugging macros", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("\\relax", () => {
|
||||
it("should stop the expansion", () => {
|
||||
expect`\kern2\relax em`.not.toParse();
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user