Skip to content

Commit

Permalink
feat: Support \Braket, \set, and \Set (#3214)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
edemaine and ronkok committed May 20, 2022
1 parent 8319467 commit 9e3ae4d
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 4 deletions.
3 changes: 3 additions & 0 deletions docs/support_table.md
Expand Up @@ -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}`|
Expand Down Expand Up @@ -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`|
Expand Down
3 changes: 2 additions & 1 deletion docs/supported.md
Expand Up @@ -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: $∀ ∴ ∁ ∵ ∃ ∣ ∈ ∉ ∋ ⊂ ⊃ ∧ ∨ ↦ → ← ↔ ¬$ ℂ ℍ ℕ ℙ ℚ ℝ

Expand Down Expand Up @@ -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

Expand Down
4 changes: 3 additions & 1 deletion src/MacroExpander.js
Expand Up @@ -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 = [];
Expand Down
7 changes: 7 additions & 0 deletions src/defineMacro.js
Expand Up @@ -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.
Expand Down
52 changes: 52 additions & 0 deletions src/macros.js
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions test/katex-spec.js
Expand Up @@ -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() {
Expand Down
Binary file modified test/screenshotter/images/DelimiterSizing-chrome.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/screenshotter/images/DelimiterSizing-firefox.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/screenshotter/images/DelimiterSizing-safari.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions test/screenshotter/ss_data.yaml
Expand Up @@ -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
Expand Down

0 comments on commit 9e3ae4d

Please sign in to comment.