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:
Erik Demaine
2019-07-21 11:15:29 -04:00
committed by ylemkimon
parent 223b9c3f24
commit 285c9fe0b6
12 changed files with 111 additions and 41 deletions

View File

@@ -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$||

View File

@@ -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

View File

@@ -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";

View File

@@ -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.

View File

@@ -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">

View File

@@ -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.

View File

@@ -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

View File

@@ -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]

View File

@@ -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/',
},
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB