mirror of
https://github.com/Smaug123/KaTeX
synced 2025-10-04 18:58:39 +00:00
Re includegraphics (#2053)
* Re-enable \includegraphics now that we have trust setting
This reverts commit 5806b240b3
.
* Include Khan Academy test logo in repo and use in test (fix #1892)
* Update screenshots
* Update documentation
* Add tests, cleanup existing tests
* Update snapshots
* Enable trust testing (trust=true by default)
This commit is contained in:
@@ -480,6 +480,7 @@ use `\ce` instead|
|
||||
|\impliedby|$P\impliedby Q$|`P\impliedby Q`|
|
||||
|\implies|$P\implies Q$|`P\implies Q`|
|
||||
|\in|$\in$||
|
||||
|\includegraphics|$\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}$|`\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}` Requires `trust` [option](options.md)
|
||||
|\inf|$\inf$||
|
||||
|\infin|$\infin$||
|
||||
|\infty|$\infty$||
|
||||
|
@@ -112,6 +112,10 @@ or for just some URLs via the `trust` [option](options.md).
|
||||
|:----------------|:-------------------|
|
||||
| $\href{https://katex.org/}{\KaTeX}$ | `\href{https://katex.org/}{\KaTeX}` |
|
||||
| $\url{https://katex.org/}$ | `\url{https://katex.org/}` |
|
||||
| $\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://katex.org/img/khan-academy.png}$ | `\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://katex.org/img/khan-academy.png}` |
|
||||
|
||||
`\includegraphics` supports `height`, `width`, `totalheight`, and `alt` in its first argument. `height` is required.
|
||||
|
||||
|
||||
## Letters and Unicode
|
||||
|
||||
|
@@ -21,8 +21,7 @@ import "./functions/genfrac";
|
||||
import "./functions/horizBrace";
|
||||
import "./functions/href";
|
||||
import "./functions/htmlmathml";
|
||||
// Disabled until https://github.com/KaTeX/KaTeX/pull/1794 is merged.
|
||||
// import "./functions/includegraphics";
|
||||
import "./functions/includegraphics";
|
||||
import "./functions/kern";
|
||||
import "./functions/lap";
|
||||
import "./functions/math";
|
||||
|
@@ -14,7 +14,7 @@ function init() {
|
||||
input.addEventListener("input", reprocess, false);
|
||||
permalink.addEventListener("click", setSearch);
|
||||
|
||||
const options = {displayMode: true, throwOnError: true};
|
||||
const options = {displayMode: true, throwOnError: true, trust: true};
|
||||
const macros = {};
|
||||
const query = queryString.parse(window.location.search);
|
||||
|
||||
@@ -50,6 +50,11 @@ function init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Use `trust=0` (or `=f`/`=false`/`=n`/`=no`) to not trust input.
|
||||
if (query.trust && query.trust.match(/^(0|f|n)/)) {
|
||||
options.trust = false;
|
||||
}
|
||||
|
||||
// The `before` or `pre` search parameter puts normal text before the math.
|
||||
// The `after` or `post` search parameter puts normal text after the math.
|
||||
// Example use: testing baseline alignment.
|
||||
|
@@ -780,6 +780,62 @@ exports[`An implicit group parser within optional groups should work with sizing
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`An includegraphics builder should not render without trust setting 1`] = `
|
||||
[
|
||||
{
|
||||
"attributes": {
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"classes": [
|
||||
"mord",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"depth": 0.25,
|
||||
"height": 0.75,
|
||||
"italic": 0,
|
||||
"maxFontSize": 1,
|
||||
"skew": 0,
|
||||
"style": {
|
||||
"color": "#cc0000"
|
||||
},
|
||||
"text": "\\\\includegraphics",
|
||||
"width": 0.5
|
||||
}
|
||||
],
|
||||
"classes": [
|
||||
"mord",
|
||||
"text"
|
||||
],
|
||||
"depth": 0.25,
|
||||
"height": 0.75,
|
||||
"maxFontSize": 1,
|
||||
"style": {
|
||||
"color": "#cc0000"
|
||||
}
|
||||
}
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`An includegraphics builder should render with trust setting 1`] = `
|
||||
[
|
||||
{
|
||||
"alt": "KA logo",
|
||||
"classes": [
|
||||
"mord"
|
||||
],
|
||||
"depth": 0,
|
||||
"height": 0.9,
|
||||
"src": "https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png",
|
||||
"style": {
|
||||
"height": "0.9em",
|
||||
"width": "0.9em"
|
||||
}
|
||||
}
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Extending katex by new fonts and symbols Add new font class to new extended symbols 1`] = `
|
||||
|
||||
<span class="katex">
|
||||
|
@@ -60,6 +60,7 @@ const printExpectedResult = (mode, isNot, expectedError) => expectedError == nul
|
||||
|
||||
export const nonstrictSettings = new Settings({strict: false});
|
||||
export const strictSettings = new Settings({strict: true});
|
||||
export const trustSettings = new Settings({trust: true});
|
||||
|
||||
/**
|
||||
* Return the root node of the rendered HTML.
|
||||
|
@@ -12,7 +12,7 @@ import Options from "../src/Options";
|
||||
import Settings from "../src/Settings";
|
||||
import Style from "../src/Style";
|
||||
import {
|
||||
strictSettings, nonstrictSettings, r,
|
||||
strictSettings, nonstrictSettings, trustSettings, r,
|
||||
getBuilt, getParsed, stripPositions,
|
||||
} from "./helpers";
|
||||
|
||||
@@ -1981,15 +1981,24 @@ describe("A MathML font tree-builder", function() {
|
||||
});
|
||||
});
|
||||
|
||||
// Disabled until https://github.com/KaTeX/KaTeX/pull/1794 is merged.
|
||||
describe.skip("An includegraphics builder", function() {
|
||||
describe("An includegraphics builder", function() {
|
||||
const img = "\\includegraphics[height=0.9em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}";
|
||||
it("should not fail", function() {
|
||||
expect(img).toBuild();
|
||||
expect(img).toBuild(trustSettings);
|
||||
});
|
||||
|
||||
it("should produce mords", function() {
|
||||
expect(getBuilt(img)[0].classes).toContain("mord");
|
||||
expect(getBuilt(img, trustSettings)[0].classes).toContain("mord");
|
||||
});
|
||||
|
||||
it("should not render without trust setting", function() {
|
||||
const built = getBuilt(img);
|
||||
expect(built).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should render with trust setting", function() {
|
||||
const built = getBuilt(img, trustSettings);
|
||||
expect(built).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2661,41 +2670,41 @@ describe("href and url commands", function() {
|
||||
// We can't use raw strings for \url because \u is for Unicode escapes.
|
||||
|
||||
it("should parse its input", function() {
|
||||
expect`\href{http://example.com/}{\sin}`.toBuild();
|
||||
expect("\\url{http://example.com/}").toBuild();
|
||||
expect`\href{http://example.com/}{\sin}`.toBuild(trustSettings);
|
||||
expect("\\url{http://example.com/}").toBuild(trustSettings);
|
||||
});
|
||||
|
||||
it("should allow empty URLs", function() {
|
||||
expect`\href{}{example here}`.toBuild();
|
||||
expect("\\url{}").toBuild();
|
||||
expect`\href{}{example here}`.toBuild(trustSettings);
|
||||
expect("\\url{}").toBuild(trustSettings);
|
||||
});
|
||||
|
||||
it("should allow single-character URLs", () => {
|
||||
expect`\href%end`.toParseLike("\\href{%}end");
|
||||
expect("\\url%end").toParseLike("\\url{%}end");
|
||||
expect("\\url%%end\n").toParseLike("\\url{%}");
|
||||
expect("\\url end").toParseLike("\\url{e}nd");
|
||||
expect("\\url%end").toParseLike("\\url {%}end");
|
||||
expect`\href%end`.toParseLike("\\href{%}end", trustSettings);
|
||||
expect("\\url%end").toParseLike("\\url{%}end", trustSettings);
|
||||
expect("\\url%%end\n").toParseLike("\\url{%}", trustSettings);
|
||||
expect("\\url end").toParseLike("\\url{e}nd", trustSettings);
|
||||
expect("\\url%end").toParseLike("\\url {%}end", trustSettings);
|
||||
});
|
||||
|
||||
it("should allow spaces single-character URLs", () => {
|
||||
expect`\href %end`.toParseLike("\\href{%}end");
|
||||
expect("\\url %end").toParseLike("\\url{%}end");
|
||||
expect`\href %end`.toParseLike("\\href{%}end", trustSettings);
|
||||
expect("\\url %end").toParseLike("\\url{%}end", trustSettings);
|
||||
});
|
||||
|
||||
it("should allow letters [#$%&~_^] without escaping", function() {
|
||||
const url = "http://example.org/~bar/#top?foo=$foo&bar=ba^r_boo%20baz";
|
||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`, new Settings({trust: true}))[0];
|
||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`, trustSettings)[0];
|
||||
expect(parsed1.href).toBe(url);
|
||||
const parsed2 = getParsed(`\\url{${url}}`, new Settings({trust: true}))[0];
|
||||
const parsed2 = getParsed(`\\url{${url}}`, trustSettings)[0];
|
||||
expect(parsed2.href).toBe(url);
|
||||
});
|
||||
|
||||
it("should allow balanced braces in url", function() {
|
||||
const url = "http://example.org/{{}t{oo}}";
|
||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`, new Settings({trust: true}))[0];
|
||||
const parsed1 = getParsed(`\\href{${url}}{\\alpha}`, trustSettings)[0];
|
||||
expect(parsed1.href).toBe(url);
|
||||
const parsed2 = getParsed(`\\url{${url}}`, new Settings({trust: true}))[0];
|
||||
const parsed2 = getParsed(`\\url{${url}}`, trustSettings)[0];
|
||||
expect(parsed2.href).toBe(url);
|
||||
});
|
||||
|
||||
@@ -2709,9 +2718,9 @@ describe("href and url commands", function() {
|
||||
it("should allow escape for letters [#$%&~_^{}]", function() {
|
||||
const url = "http://example.org/~bar/#top?foo=$}foo{&bar=bar^r_boo%20baz";
|
||||
const input = url.replace(/([#$%&~_^{}])/g, '\\$1');
|
||||
const parsed1 = getParsed(`\\href{${input}}{\\alpha}`, new Settings({trust: true}))[0];
|
||||
const parsed1 = getParsed(`\\href{${input}}{\\alpha}`, trustSettings)[0];
|
||||
expect(parsed1.href).toBe(url);
|
||||
const parsed2 = getParsed(`\\url{${input}}`, new Settings({trust: true}))[0];
|
||||
const parsed2 = getParsed(`\\url{${input}}`, trustSettings)[0];
|
||||
expect(parsed2.href).toBe(url);
|
||||
});
|
||||
|
||||
@@ -2725,7 +2734,7 @@ describe("href and url commands", function() {
|
||||
});
|
||||
|
||||
it("should not affect spacing around", function() {
|
||||
const built = getBuilt("a\\href{http://example.com/}{+b}", new Settings({trust: true}));
|
||||
const built = getBuilt("a\\href{http://example.com/}{+b}", trustSettings);
|
||||
expect(built).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -2743,10 +2752,7 @@ describe("href and url commands", function() {
|
||||
});
|
||||
|
||||
it("should allow all protocols when trust option is true", () => {
|
||||
const parsed = getParsed(
|
||||
"\\href{ftp://x}{foo}",
|
||||
new Settings({trust: true}),
|
||||
);
|
||||
const parsed = getParsed("\\href{ftp://x}{foo}", trustSettings);
|
||||
expect(parsed).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -2765,8 +2771,7 @@ describe("A raw text parser", function() {
|
||||
// Unicode combining character. So this is a test that the parser will catch a bad string.
|
||||
expect("\\includegraphics[\u030aheight=0.8em, totalheight=0.9em, width=0.9em]{" + "https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}").not.toParse();
|
||||
});
|
||||
// Disabled until https://github.com/KaTeX/KaTeX/pull/1794 is merged.
|
||||
it.skip("should return null for a omitted optional string", function() {
|
||||
it("should return null for a omitted optional string", function() {
|
||||
expect("\\includegraphics{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}").toParse();
|
||||
});
|
||||
});
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 36 KiB |
Binary file not shown.
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 22 KiB |
@@ -145,14 +145,13 @@ GroupMacros:
|
||||
\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}}
|
||||
# Disabled until https://github.com/KaTeX/KaTeX/pull/1794 is merged.
|
||||
# Includegraphics: |
|
||||
# \def\logo{\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}}
|
||||
# \def\logoB{\includegraphics[height=0.4em, totalheight=0.9em, width=0.9em, alt=KA logo]{https://cdn.kastatic.org/images/apple-touch-icon-57x57-precomposed.new.png}}
|
||||
# \begin{array}{l}
|
||||
# \underline{A\logo} + \sqrt{\logo} + \tfrac{A\logo}{\logo}\\[1em]
|
||||
# \underline{A\logoB} + \sqrt{x\logoB} + \tfrac{A\logoB}{\logoB}
|
||||
# \end{array}
|
||||
Includegraphics: |
|
||||
\def\logo{\includegraphics[height=0.8em, totalheight=0.9em, width=0.9em, alt=KA logo]{../../website/static/img/khan-academy.png}}
|
||||
\def\logoB{\includegraphics[height=0.4em, totalheight=0.9em, width=0.9em, alt=KA logo]{../../website/static/img/khan-academy.png}}
|
||||
\begin{array}{l}
|
||||
\underline{A\logo} + \sqrt{\logo} + \tfrac{A\logo}{\logo}\\[1em]
|
||||
\underline{A\logoB} + \sqrt{x\logoB} + \tfrac{A\logoB}{\logoB}
|
||||
\end{array}
|
||||
Integrands: |
|
||||
\begin{array}{l}
|
||||
\displaystyle \int + \oint + \iint + \oiint_i^n \\[0.6em]
|
||||
|
@@ -12,7 +12,7 @@
|
||||
const users = [
|
||||
{
|
||||
caption: 'Khan Academy',
|
||||
image: 'https://avatars0.githubusercontent.com/u/15455',
|
||||
image: '/img/khan-academy.png',
|
||||
infoLink: 'https://www.khanacademy.org/',
|
||||
},
|
||||
{
|
||||
|
BIN
website/static/img/khan-academy.png
Normal file
BIN
website/static/img/khan-academy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
Reference in New Issue
Block a user