katex.js (2574B)
1 /** 2 * A plugin which enables rendering of math equations inside 3 * of reveal.js slides. Essentially a thin wrapper for KaTeX. 4 * 5 * @author Hakim El Hattab 6 * @author Gerhard Burger 7 */ 8 export const KaTeX = () => { 9 let deck; 10 11 let defaultOptions = { 12 version: 'latest', 13 delimiters: [ 14 {left: '$$', right: '$$', display: true}, // Note: $$ has to come before $ 15 {left: '$', right: '$', display: false}, 16 {left: '\\(', right: '\\)', display: false}, 17 {left: '\\[', right: '\\]', display: true} 18 ], 19 ignoredTags: ['script', 'noscript', 'style', 'textarea', 'pre'] 20 } 21 22 const loadCss = src => { 23 let link = document.createElement('link'); 24 link.rel = 'stylesheet'; 25 link.href = src; 26 document.head.appendChild(link); 27 }; 28 29 /** 30 * Loads a JavaScript file and returns a Promise for when it is loaded 31 * Credits: https://aaronsmith.online/easily-load-an-external-script-using-javascript/ 32 */ 33 const loadScript = src => { 34 return new Promise((resolve, reject) => { 35 const script = document.createElement('script') 36 script.type = 'text/javascript' 37 script.onload = resolve 38 script.onerror = reject 39 script.src = src 40 document.head.append(script) 41 }) 42 }; 43 44 async function loadScripts(urls) { 45 for(const url of urls) { 46 await loadScript(url); 47 } 48 } 49 50 return { 51 id: 'katex', 52 53 init: function (reveal) { 54 55 deck = reveal; 56 57 let revealOptions = deck.getConfig().katex || {}; 58 59 let options = {...defaultOptions, ...revealOptions}; 60 const {local, version, extensions, ...katexOptions} = options; 61 62 let baseUrl = options.local || 'https://cdn.jsdelivr.net/npm/katex'; 63 let versionString = options.local ? '' : '@' + options.version; 64 65 let cssUrl = baseUrl + versionString + '/dist/katex.min.css'; 66 let katexUrl = baseUrl + versionString + '/dist/katex.min.js'; 67 let mhchemUrl = baseUrl + versionString + '/dist/contrib/mhchem.min.js' 68 let karUrl = baseUrl + versionString + '/dist/contrib/auto-render.min.js'; 69 70 let katexScripts = [katexUrl]; 71 if(options.extensions && options.extensions.includes("mhchem")) { 72 katexScripts.push(mhchemUrl); 73 } 74 katexScripts.push(karUrl); 75 76 const renderMath = () => { 77 renderMathInElement(reveal.getSlidesElement(), katexOptions); 78 deck.layout(); 79 } 80 81 loadCss(cssUrl); 82 83 // For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does 84 loadScripts(katexScripts).then(() => { 85 if( deck.isReady() ) { 86 renderMath(); 87 } 88 else { 89 deck.on( 'ready', renderMath.bind( this ) ); 90 } 91 }); 92 93 } 94 } 95 96 };