1
0
Fork 0
why-cant-we-deploy-today/plugin/math/katex.js

93 lines
2.7 KiB
JavaScript
Executable File

/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for KaTeX.
*
* @author Hakim El Hattab
* @author Gerhard Burger
*/
export const KaTeX = () => {
let deck;
let defaultOptions = {
version: "latest",
delimiters: [
{ left: "$$", right: "$$", display: true }, // Note: $$ has to come before $
{ left: "$", right: "$", display: false },
{ left: "\\(", right: "\\)", display: false },
{ left: "\\[", right: "\\]", display: true },
],
ignoredTags: ["script", "noscript", "style", "textarea", "pre"],
};
const loadCss = (src) => {
let link = document.createElement("link");
link.rel = "stylesheet";
link.href = src;
document.head.appendChild(link);
};
/**
* Loads a JavaScript file and returns a Promise for when it is loaded
* Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/
*/
const loadScript = (src) => {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.type = "text/javascript";
script.onload = resolve;
script.onerror = reject;
script.src = src;
document.head.append(script);
});
};
async function loadScripts(urls) {
for (const url of urls) {
await loadScript(url);
}
}
return {
id: "katex",
init: function (reveal) {
deck = reveal;
let revealOptions = deck.getConfig().katex || {};
let options = { ...defaultOptions, ...revealOptions };
const { local, version, extensions, ...katexOptions } = options;
let baseUrl = options.local || "https://cdn.jsdelivr.net/npm/katex";
let versionString = options.local ? "" : "@" + options.version;
let cssUrl = baseUrl + versionString + "/dist/katex.min.css";
let katexUrl = baseUrl + versionString + "/dist/katex.min.js";
let mhchemUrl = baseUrl + versionString + "/dist/contrib/mhchem.min.js";
let karUrl = baseUrl + versionString + "/dist/contrib/auto-render.min.js";
let katexScripts = [katexUrl];
if (options.extensions && options.extensions.includes("mhchem")) {
katexScripts.push(mhchemUrl);
}
katexScripts.push(karUrl);
const renderMath = () => {
renderMathInElement(reveal.getSlidesElement(), katexOptions);
deck.layout();
};
loadCss(cssUrl);
// For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does
loadScripts(katexScripts).then(() => {
if (deck.isReady()) {
renderMath();
} else {
deck.on("ready", renderMath.bind(this));
}
});
},
};
};