bookclub-advr

DSLC Advanced R Book Club
git clone https://git.eamoncaddigan.net/bookclub-advr.git
Log | Files | Refs | README | LICENSE

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 };