/** * 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 ) ); } }); } } };