You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
97 lines
2.5 KiB
97 lines
2.5 KiB
2 weeks ago
|
/**
|
||
|
* 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 ) );
|
||
|
}
|
||
|
});
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|