mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-05 19:28:39 +00:00
feat: Support \Braket, \set, and \Set (#3214)
* feat: Support \Braket, \set, and \Set * Update screenshots. * Rewrite to redefine | via macros * Update screenshot after merge * Rename \bra@ket@one -> \bra@set * Fix spacing in \set and \Set to match braket.sty * Add || and \| support * Update tests * Update screenshots Co-authored-by: Ron Kok <ronkok@comcast.net>
This commit is contained in:
@@ -193,6 +193,7 @@ table td {
|
||||
|\Bra|$\Bra{\psi}$|`\Bra{\psi}`|
|
||||
|\bra|$\bra{\psi}$|`\bra{\psi}`|
|
||||
|\braket|$\braket{\phi\vert\psi}$|`\braket{\phi\vert\psi}`|
|
||||
|\Braket|$\Braket{ ϕ \| \frac{∂^2}{∂ t^2} \| ψ }$| `\Braket{ ϕ \| \frac{∂^2}{∂ t^2} \| ψ }`|
|
||||
|\brace|${n\brace k}$|`{n\brace k}`|
|
||||
|\bracevert|<span style="color:firebrick;">Not supported</span>||
|
||||
|\brack|${n\brack k}$|`{n\brack k}`|
|
||||
@@ -953,6 +954,8 @@ use `\ce` instead|
|
||||
|\searrow|$\searrow$||
|
||||
|\sec|$\sec$||
|
||||
|\sect|$\text{\sect}$|`\text{\sect}`|
|
||||
|\set|$\set{x\|x<5}$|`\set{x\|x<5}` |
|
||||
|\Set|$\Set{ x \| x<\frac 1 2 }$ | `\Set{ x \| x<\frac 1 2 }` |
|
||||
|\setlength|<span style="color:firebrick;">Not supported</span>|[Issue #687](https://github.com/KaTeX/KaTeX/issues/687)|
|
||||
|\setminus|$\setminus$||
|
||||
|\sf|$\sf AaBb123$|`\sf AaBb123`|
|
||||
|
@@ -321,6 +321,7 @@ KaTeX also supports `\llap`, `\rlap`, and `\clap`, but they will take only text,
|
||||
|$\in$ `\in` |$\land$ `\land` |$\gets$ `\gets` |$\impliedby$ `\impliedby`
|
||||
|$\isin$ `\isin` |$\lor$ `\lor` |$\leftrightarrow$ `\leftrightarrow`|$\iff$ `\iff`
|
||||
|$\notin$ `\notin` |$\ni$ `\ni` |$\notni$ `\notni` |$\neg$ `\neg` or `\lnot`
|
||||
| | $\Set{ x \| x<\frac 1 2 }$<br>`\Set{ x \| x<\frac 1 2 }` | $\set{x\|x<5}$<br>`\set{x\|x<5}`
|
||||
|
||||
Direct Input: $∀ ∴ ∁ ∵ ∃ ∣ ∈ ∉ ∋ ⊂ ⊃ ∧ ∨ ↦ → ← ↔ ¬$ ℂ ℍ ℕ ℙ ℚ ℝ
|
||||
|
||||
@@ -563,7 +564,7 @@ Extensible arrows all can take an optional argument in the same manner<br>as `\x
|
||||
||||
|
||||
|:----------|:----------|:----------|
|
||||
|$\bra{\phi}$ `\bra{\phi}` |$\ket{\psi}$ `\ket{\psi}` |$\braket{\phi\vert\psi}$ `\braket{\phi\vert\psi}` |
|
||||
|$\Bra{\phi}$ `\Bra{\phi}` |$\Ket{\psi}$ `\Ket{\psi}` ||
|
||||
|$\Bra{\phi}$ `\Bra{\phi}` |$\Ket{\psi}$ `\Ket{\psi}` |$\Braket{ ϕ \| \frac{∂^2}{∂ t^2} \| ψ }$ `\Braket{ ϕ \| \frac{∂^2}{∂ t^2} \| ψ }`|
|
||||
|
||||
## Style, Color, Size, and Font
|
||||
|
||||
|
@@ -356,7 +356,9 @@ export default class MacroExpander implements MacroContextInterface {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fully expand the given token stream and return the resulting list of tokens
|
||||
* Fully expand the given token stream and return the resulting list of
|
||||
* tokens. Note that the input tokens are in reverse order, but the
|
||||
* output tokens are in forward order.
|
||||
*/
|
||||
expandTokens(tokens: Token[]): Token[] {
|
||||
const output = [];
|
||||
|
@@ -61,6 +61,13 @@ export interface MacroContextInterface {
|
||||
*/
|
||||
expandMacroAsText(name: string): string | void;
|
||||
|
||||
/**
|
||||
* Fully expand the given token stream and return the resulting list of
|
||||
* tokens. Note that the input tokens are in reverse order, but the
|
||||
* output tokens are in forward order.
|
||||
*/
|
||||
expandTokens(tokens: Token[]): Token[];
|
||||
|
||||
/**
|
||||
* Consume an argument from the token stream, and return the resulting array
|
||||
* of tokens and start/end token.
|
||||
|
@@ -912,6 +912,58 @@ defineMacro("\\ket", "\\mathinner{|{#1}\\rangle}");
|
||||
defineMacro("\\braket", "\\mathinner{\\langle{#1}\\rangle}");
|
||||
defineMacro("\\Bra", "\\left\\langle#1\\right|");
|
||||
defineMacro("\\Ket", "\\left|#1\\right\\rangle");
|
||||
const braketHelper = (one) => (context) => {
|
||||
const left = context.consumeArg().tokens;
|
||||
const middle = context.consumeArg().tokens;
|
||||
const middleDouble = context.consumeArg().tokens;
|
||||
const right = context.consumeArg().tokens;
|
||||
const oldMiddle = context.macros.get("|");
|
||||
const oldMiddleDouble = context.macros.get("\\|");
|
||||
context.macros.beginGroup();
|
||||
const midMacro = (double) => (context) => {
|
||||
if (one) {
|
||||
// Only modify the first instance of | or \|
|
||||
context.macros.set("|", oldMiddle);
|
||||
if (middleDouble.length) {
|
||||
context.macros.set("\\|", oldMiddleDouble);
|
||||
}
|
||||
}
|
||||
let doubled = double;
|
||||
if (!double && middleDouble.length) {
|
||||
// Mimic \@ifnextchar
|
||||
const nextToken = context.future();
|
||||
if (nextToken.text === "|") {
|
||||
context.popToken();
|
||||
doubled = true;
|
||||
}
|
||||
}
|
||||
return {
|
||||
tokens: doubled ? middleDouble : middle,
|
||||
numArgs: 0,
|
||||
};
|
||||
};
|
||||
context.macros.set("|", midMacro(false));
|
||||
if (middleDouble.length) {
|
||||
context.macros.set("\\|", midMacro(true));
|
||||
}
|
||||
const arg = context.consumeArg().tokens;
|
||||
const expanded = context.expandTokens([
|
||||
...right, ...arg, ...left, // reversed
|
||||
]);
|
||||
context.macros.endGroup();
|
||||
return {
|
||||
tokens: expanded.reverse(),
|
||||
numArgs: 0,
|
||||
};
|
||||
};
|
||||
defineMacro("\\bra@ket", braketHelper(false));
|
||||
defineMacro("\\bra@set", braketHelper(true));
|
||||
defineMacro("\\Braket", "\\bra@ket{\\left\\langle}" +
|
||||
"{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}");
|
||||
defineMacro("\\Set", "\\bra@set{\\left\\{\\:}" +
|
||||
"{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}");
|
||||
defineMacro("\\set", "\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}");
|
||||
// has no support for special || or \|
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// actuarialangle.dtx
|
||||
|
@@ -3610,6 +3610,26 @@ describe("A macro expander", function() {
|
||||
it("should expand \\Ket as expected", () => {
|
||||
expect`\Ket{\psi}`.toParseLike`\left|\psi\right\rangle`;
|
||||
});
|
||||
|
||||
it("should expand \\Braket as expected", () => {
|
||||
expect`\Braket{ ϕ | \frac{∂^2}{∂ t^2} | ψ }`.toParseLike`\left\langle ϕ\,\middle\vert\,\frac{∂^2}{∂ t^2}\,\middle\vert\, ψ\right\rangle`;
|
||||
});
|
||||
|
||||
it("should expand \\set as expected", () => {
|
||||
expect`\set{x|x<5|S|}`.toParseLike`\{\,x\mid x<5|S|\,\}`;
|
||||
// \set doesn't support special || or \| handling
|
||||
expect`\set{x||x<5|S|}`.toParseLike`\{\,x\mid |x<5|S|\,\}`;
|
||||
expect`\set{x\|x<5|S|}`.toParseLike`\{\,x\|x<5\mid S|\,\}`;
|
||||
});
|
||||
|
||||
it("should expand \\Set as expected", () => {
|
||||
expect`\Set{ x | x<\frac 1 2 |S| }`
|
||||
.toParseLike`\left\{\: x\;\middle\vert\; x<\frac 1 2 |S| \:\right\}`;
|
||||
expect`\Set{ x || x<\frac 1 2 |S| }`
|
||||
.toParseLike`\left\{\: x\;\middle\Vert\; x<\frac 1 2 |S| \:\right\}`;
|
||||
expect`\Set{ x \| x<\frac 1 2 |S| }`
|
||||
.toParseLike`\left\{\: x\;\middle\Vert\; x<\frac 1 2 |S| \:\right\}`;
|
||||
});
|
||||
});
|
||||
|
||||
describe("\\tag support", function() {
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 27 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 28 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 27 KiB |
@@ -119,12 +119,12 @@ DeepFontSizing:
|
||||
nolatex: \Huge inside \dfrac doesn't work, needs an extra {…}
|
||||
DelimiterSizing: |
|
||||
\bigl\uparrow\Bigl\downarrow\biggl\updownarrow
|
||||
\Biggl\Uparrow\Biggr\Downarrow\biggr\langle\Bigr\}\bigr\rfloor \\
|
||||
\Biggl\Uparrow\Biggr\Downarrow\biggr\langle\Bigr\}\bigr\rfloor\; \Set{ x | x<\frac 1 2 } \\
|
||||
\begin{pmatrix}
|
||||
a & b & c\\
|
||||
a & b & c\\
|
||||
a & b & c\\
|
||||
\end{pmatrix}
|
||||
\end{pmatrix}\; \Braket{ ϕ | \frac{∂^2}{∂ t^2} | ψ } \\
|
||||
DisplayMode:
|
||||
tex: \sum_{i=0}^\infty \frac{1}{i}
|
||||
pre: pre
|
||||
|
Reference in New Issue
Block a user