Support stretchy wide elements. (#670)
@@ -1797,8 +1797,12 @@ describe("An accent parser", function() {
|
||||
expect(parse.type).toEqual("supsub");
|
||||
});
|
||||
|
||||
it("should not parse expanding accents", function() {
|
||||
expect("\\widehat{x}").toNotParse();
|
||||
it("should parse stretchy, shifty accents", function() {
|
||||
expect("\\widehat{x}").toParse();
|
||||
});
|
||||
|
||||
it("should parse stretchy, non-shifty accents", function() {
|
||||
expect("\\overrightarrow{x}").toParse();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1819,6 +1823,234 @@ describe("An accent builder", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("A stretchy and shifty accent builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\widehat{AB}").toBuild();
|
||||
expect("\\widehat{AB}^2").toBuild();
|
||||
expect("\\widehat{AB}_2").toBuild();
|
||||
expect("\\widehat{AB}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\widehat{AB}")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\widehat +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\widehat +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\widehat )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\widehat )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A stretchy and non-shifty accent builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\overrightarrow{AB}").toBuild();
|
||||
expect("\\overrightarrow{AB}^2").toBuild();
|
||||
expect("\\overrightarrow{AB}_2").toBuild();
|
||||
expect("\\overrightarrow{AB}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\overrightarrow{AB}")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overrightarrow +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overrightarrow +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\overrightarrow )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overrightarrow )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("An under-accent parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\underrightarrow{x}").toParse();
|
||||
expect("\\underrightarrow{x^2}").toParse();
|
||||
expect("\\underrightarrow{x}^2").toParse();
|
||||
expect("\\underrightarrow x").toParse();
|
||||
});
|
||||
|
||||
it("should produce accentUnder", function() {
|
||||
const parse = getParsed("\\underrightarrow x")[0];
|
||||
|
||||
expect(parse.type).toEqual("accentUnder");
|
||||
});
|
||||
|
||||
it("should be grouped more tightly than supsubs", function() {
|
||||
const parse = getParsed("\\underrightarrow x^2")[0];
|
||||
|
||||
expect(parse.type).toEqual("supsub");
|
||||
});
|
||||
});
|
||||
|
||||
describe("An under-accent builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\underrightarrow{x}").toBuild();
|
||||
expect("\\underrightarrow{x}^2").toBuild();
|
||||
expect("\\underrightarrow{x}_2").toBuild();
|
||||
expect("\\underrightarrow{x}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\underrightarrow x")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\underrightarrow +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\underrightarrow +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\underrightarrow )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\underrightarrow )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("An extensible arrow parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\xrightarrow{x}").toParse();
|
||||
expect("\\xrightarrow{x^2}").toParse();
|
||||
expect("\\xrightarrow{x}^2").toParse();
|
||||
expect("\\xrightarrow x").toParse();
|
||||
expect("\\xrightarrow[under]{over}").toParse();
|
||||
});
|
||||
|
||||
it("should produce xArrow", function() {
|
||||
const parse = getParsed("\\xrightarrow x")[0];
|
||||
|
||||
expect(parse.type).toEqual("xArrow");
|
||||
});
|
||||
|
||||
it("should be grouped more tightly than supsubs", function() {
|
||||
const parse = getParsed("\\xrightarrow x^2")[0];
|
||||
|
||||
expect(parse.type).toEqual("supsub");
|
||||
});
|
||||
});
|
||||
|
||||
describe("An extensible arrow builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\xrightarrow{x}").toBuild();
|
||||
expect("\\xrightarrow{x}^2").toBuild();
|
||||
expect("\\xrightarrow{x}_2").toBuild();
|
||||
expect("\\xrightarrow{x}_2^2").toBuild();
|
||||
expect("\\xrightarrow[under]{over}").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mrell", function() {
|
||||
expect(getBuilt("\\xrightarrow x")[0].classes).toContain("mrel");
|
||||
expect(getBuilt("\\xrightarrow [under]{over}")[0].classes).toContain("mrel");
|
||||
expect(getBuilt("\\xrightarrow +")[0].classes).toContain("mrel");
|
||||
expect(getBuilt("\\xrightarrow +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\xrightarrow )^2")[0].classes).toContain("mrel");
|
||||
expect(getBuilt("\\xrightarrow )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A horizontal brace parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\overbrace{x}").toParse();
|
||||
expect("\\overbrace{x^2}").toParse();
|
||||
expect("\\overbrace{x}^2").toParse();
|
||||
expect("\\overbrace x").toParse();
|
||||
expect("\\underbrace{x}_2").toParse();
|
||||
expect("\\underbrace{x}_2^2").toParse();
|
||||
});
|
||||
|
||||
it("should produce horizBrace", function() {
|
||||
const parse = getParsed("\\overbrace x")[0];
|
||||
|
||||
expect(parse.type).toEqual("horizBrace");
|
||||
});
|
||||
|
||||
it("should be grouped more tightly than supsubs", function() {
|
||||
const parse = getParsed("\\overbrace x^2")[0];
|
||||
|
||||
expect(parse.type).toEqual("supsub");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A horizontal brace builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\overbrace{x}").toBuild();
|
||||
expect("\\overbrace{x}^2").toBuild();
|
||||
expect("\\underbrace{x}_2").toBuild();
|
||||
expect("\\underbrace{x}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\overbrace x")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overbrace{x}^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overbrace +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overbrace +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\overbrace )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\overbrace )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A boxed parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\boxed{x}").toParse();
|
||||
expect("\\boxed{x^2}").toParse();
|
||||
expect("\\boxed{x}^2").toParse();
|
||||
expect("\\boxed x").toParse();
|
||||
});
|
||||
|
||||
it("should produce enclose", function() {
|
||||
const parse = getParsed("\\boxed x")[0];
|
||||
|
||||
expect(parse.type).toEqual("enclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A boxed builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\boxed{x}").toBuild();
|
||||
expect("\\boxed{x}^2").toBuild();
|
||||
expect("\\boxed{x}_2").toBuild();
|
||||
expect("\\boxed{x}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\boxed x")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\boxed +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\boxed +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\boxed )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\boxed )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A strike-through parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\cancel{x}").toParse();
|
||||
expect("\\cancel{x^2}").toParse();
|
||||
expect("\\cancel{x}^2").toParse();
|
||||
expect("\\cancel x").toParse();
|
||||
});
|
||||
|
||||
it("should produce enclose", function() {
|
||||
const parse = getParsed("\\cancel x")[0];
|
||||
|
||||
expect(parse.type).toEqual("enclose");
|
||||
});
|
||||
|
||||
it("should be grouped more tightly than supsubs", function() {
|
||||
const parse = getParsed("\\cancel x^2")[0];
|
||||
|
||||
expect(parse.type).toEqual("supsub");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A strike-through builder", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\cancel{x}").toBuild();
|
||||
expect("\\cancel{x}^2").toBuild();
|
||||
expect("\\cancel{x}_2").toBuild();
|
||||
expect("\\cancel{x}_2^2").toBuild();
|
||||
expect("\\sout{x}").toBuild();
|
||||
expect("\\sout{x}^2").toBuild();
|
||||
expect("\\sout{x}_2").toBuild();
|
||||
expect("\\sout{x}_2^2").toBuild();
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt("\\cancel x")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\cancel +")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\cancel +")[0].classes).not.toContain("mbin");
|
||||
expect(getBuilt("\\cancel )^2")[0].classes).toContain("mord");
|
||||
expect(getBuilt("\\cancel )^2")[0].classes).not.toContain("mclose");
|
||||
});
|
||||
});
|
||||
|
||||
describe("A phantom parser", function() {
|
||||
it("should not fail", function() {
|
||||
expect("\\phantom{x}").toParse();
|
||||
|
BIN
test/screenshotter/images/Boxed-chrome.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
test/screenshotter/images/Boxed-firefox.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
test/screenshotter/images/ExtensibleArrows-chrome.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
test/screenshotter/images/ExtensibleArrows-firefox.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
test/screenshotter/images/HorizontalBraces-chrome.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
test/screenshotter/images/HorizontalBraces-firefox.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
test/screenshotter/images/LowerAccent-chrome.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
test/screenshotter/images/LowerAccent-firefox.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
test/screenshotter/images/StretchyAccent-chrome.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
test/screenshotter/images/StretchyAccent-firefox.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
test/screenshotter/images/StrikeThrough-chrome.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
test/screenshotter/images/StrikeThrough-firefox.png
Normal file
After Width: | Height: | Size: 22 KiB |
@@ -42,6 +42,7 @@ BinCancellation: |
|
||||
\end{array}
|
||||
BinomTest: \dbinom{a}{b}\tbinom{a}{b}^{\binom{a}{b}+17}
|
||||
BoldSpacing: \mathbf{A}^2+\mathbf{B}_3*\mathscr{C}'
|
||||
Boxed: \boxed{F=ma} \quad \boxed{ac}\color{magenta}{\boxed{F}}\boxed{F=mg}
|
||||
Cases: |
|
||||
f(a,b)=\begin{cases}
|
||||
a+1&\text{if }b\text{ is odd} \\
|
||||
@@ -72,6 +73,12 @@ DisplayStyle: |
|
||||
{\displaystyle\sqrt{x}}{\sqrt{x}}
|
||||
{\displaystyle \frac12}{\frac12}{\displaystyle x^1_2}{x^1_2}
|
||||
Exponents: a^{a^a_a}_{a^a_a}
|
||||
ExtensibleArrows: |
|
||||
\begin{array}{l}
|
||||
\xrightarrow[ab]{ABC} + \xRightarrow{ABC} \\
|
||||
\xrightleftharpoons[ab]{ABC} + \xhookrightarrow[ab]{ABC} \\
|
||||
\xtwoheadrightarrow{ABC} + \frac{\xrightarrow[ab]{ABC}}{\xrightarrow[ab]{ABC}} + \left\lvert\xrightarrow[ab]{ABC}\right\rvert
|
||||
\end{array}
|
||||
FractionTest: \dfrac{a}{b}\frac{a}{b}\tfrac{a}{b}\;-\dfrac12\;1\tfrac12\;{1 \atop 2}
|
||||
Functions: \sin\cos\tan\ln\log
|
||||
Gathered: |
|
||||
@@ -89,6 +96,7 @@ GroupMacros:
|
||||
\startExp: e^\bgroup
|
||||
\endExp: \egroup
|
||||
tex: \startExp a+b\endExp
|
||||
HorizontalBraces: \overbrace{\displaystyle{\oint_S{\vec E\cdot\hat n\,\mathrm d a}}}^\text{emf} = \underbrace{\frac{q_{\text{enc}}}{\varepsilon_0}}_{\text{charge}}
|
||||
KaTeX: \KaTeX
|
||||
Kern:
|
||||
tex: \frac{a\kern{1em}b}{c}a\kern{1em}b\kern{1ex}c\kern{-0.25em}d
|
||||
@@ -104,6 +112,13 @@ LeftRightStyleSizing: |
|
||||
LimitControls: |
|
||||
\displaystyle\int\limits_2^3 3x^2\,dx + \sum\nolimits^n_{i=1}i +
|
||||
\textstyle\int\limits_x^y z
|
||||
LowerAccent: |
|
||||
\begin{matrix}
|
||||
\underleftarrow{AB} \quad \underrightarrow{AB} \quad \underleftrightarrow{AB} \quad \undergroup{AB} \\
|
||||
\underlinesegment{AB} \quad \undertilde{AB} \quad \color{green}{\underrightarrow{AB}} \\
|
||||
\underrightarrow{F} + \underrightarrow{AB} + \underrightarrow{AB}^2 + \underrightarrow{AB}_2 \\
|
||||
\frac{\underrightarrow{AB}}{\underrightarrow{AB}} + \sqrt{\underrightarrow{AB}} + \left\lvert\underrightarrow{AB}\right\rvert
|
||||
\end{matrix}
|
||||
MathAtom: a\mathrel{\mathop{=}\limits^{\blue ?}}b
|
||||
MathAtom2: \mathop{\overline{\mathrm{lim}}}\limits_{x\to\infty}f(x)
|
||||
MathDefaultFonts: Ax2k\breve{a}\omega\Omega\imath+\KaTeX
|
||||
@@ -168,6 +183,21 @@ Sqrt: |
|
||||
SqrtRoot: |
|
||||
1+\sqrt[3]{2}+\sqrt[1923^234]{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^{2^2}}}}}}}}}}}
|
||||
StackRel: a \stackrel{?}{=} b \stackrel{\text{def}}{=} c
|
||||
StretchyAccent: |
|
||||
\begin{array}{l}
|
||||
\overrightarrow{AB} \quad \overleftarrow{AB} \quad \Overrightarrow{AB} \quad \overleftrightarrow{AB} \quad \overgroup{AB} \\
|
||||
\overlinesegment{AB} \quad \overleftharpoon{AB} \quad \overrightharpoon{AB} \quad \color{red}{\overrightarrow{AB}} \quad \widehat{\theta} \widetilde{A} \\
|
||||
\widehat{AB} \quad \widehat{ABC} \quad \widetilde{AB} \quad \widetilde{ABC} \\
|
||||
\overrightarrow{F} + \overrightarrow{AB} + \overrightarrow{F}^2 + \overrightarrow{F}_2 + \overrightarrow{F}_1^2 \\
|
||||
\overrightarrow{AB}^2+\frac{\overrightarrow{AB}}{\overrightarrow{AB}} + \sqrt{\overrightarrow{AB}} + \left\lvert\overrightarrow{AB}\right\rvert
|
||||
\end{array}
|
||||
StrikeThrough: |
|
||||
\begin{array}{l}
|
||||
\cancel x \quad \cancel{2B} + \bcancel 5 +\bcancel{5ay} \\
|
||||
\sout{5ab} + \sout{5ABC} + \xcancel{\oint_S{\vec E\cdot\hat n\,\mathrm d a}} \\
|
||||
\frac{x+\cancel B}{x+\cancel x} + \frac{x+\cancel y}{x} + \cancel{B}_1^2 + \cancel{B^2} \\
|
||||
\left\lvert\cancel{ac}\right\rvert
|
||||
\end{array}
|
||||
StyleSpacing: \scriptstyle ab\;cd
|
||||
StyleSwitching: a\cdot b\scriptstyle a\cdot ba\textstyle\cdot ba\scriptstyle\cdot b
|
||||
SupSubCharacterBox: a_2f_2{f}_2{aa}_2{af}_2\mathbf{y}_Ay_A
|
||||
|