Skip to content

Commit

Permalink
add @burgerga's math plugin with MathJax2, MathJax3 and KaTeX support h…
Browse files Browse the repository at this point in the history
  • Loading branch information
hakimel committed Oct 28, 2021
1 parent 810d80b commit 0ea4193
Show file tree
Hide file tree
Showing 8 changed files with 282 additions and 100 deletions.
11 changes: 8 additions & 3 deletions examples/math.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,7 @@ <h3>TeX Macros</h3>
history: true,
transition: 'linear',

math: {
// mathjax: 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js',
mathjax2: {
config: 'TeX-AMS_HTML-full',
TeX: {
Macros: {
Expand All @@ -193,7 +192,13 @@ <h3>TeX Macros</h3>
}
},

plugins: [ RevealMath ]
// There are three typesetters available
// RevealMath.MathJax2 (default)
// RevealMath.MathJax3
// RevealMath.KaTeX
//
// More info at https://revealjs.com/math/
plugins: [ RevealMath.MathJax2 ]
});
</script>

Expand Down
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

87 changes: 87 additions & 0 deletions plugin/math/katex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* 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: false},
{left: '$$', right: '$$', display: true},
{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);

loadCss(cssUrl);

// For some reason dynamically loading with defer attribute doesn't result in the expected behavior, the below code does
loadScripts(katexScripts).then(() => {
renderMathInElement(document.body, katexOptions);
deck.layout();
});

}
}

};
2 changes: 1 addition & 1 deletion plugin/math/math.esm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion plugin/math/math.js

Large diffs are not rendered by default.

89 changes: 89 additions & 0 deletions plugin/math/mathjax2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for MathJax.
*
* @author Hakim El Hattab
*/
export const MathJax2 = () => {

// The reveal.js instance this plugin is attached to
let deck;

let defaultOptions = {
messageStyle: 'none',
tex2jax: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
skipStartupTypeset: true
};

function loadScript( url, callback ) {

let head = document.querySelector( 'head' );
let script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;

// Wrapper for callback to make sure it only fires once
let finish = () => {
if( typeof callback === 'function' ) {
callback.call();
callback = null;
}
}

script.onload = finish;

// IE
script.onreadystatechange = () => {
if ( this.readyState === 'loaded' ) {
finish();
}
}

// Normal browsers
head.appendChild( script );

}

return {
id: 'mathjax2',

init: function( reveal ) {

deck = reveal;

let revealOptions = deck.getConfig().mathjax2 || deck.getConfig().math || {};

let options = { ...defaultOptions, ...revealOptions };
let mathjax = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js';
let config = options.config || 'TeX-AMS_HTML-full';
let url = mathjax + '?config=' + config;

options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };

options.mathjax = options.config = null;

loadScript( url, function() {

MathJax.Hub.Config( options );

// Typeset followed by an immediate reveal.js layout since
// the typesetting process could affect slide height
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
MathJax.Hub.Queue( deck.layout );

// Reprocess equations in slides when they turn visible
deck.on( 'slidechanged', function( event ) {

MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );

} );

} );

}
}

};
77 changes: 77 additions & 0 deletions plugin/math/mathjax3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* A plugin which enables rendering of math equations inside
* of reveal.js slides. Essentially a thin wrapper for MathJax 3
*
* @author Hakim El Hattab
* @author Gerhard Burger
*/
export const MathJax3 = () => {

// The reveal.js instance this plugin is attached to
let deck;

let defaultOptions = {
tex: {
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ]
},
options: {
skipHtmlTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
},
startup: {
ready: () => {
MathJax.startup.defaultReady();
MathJax.startup.promise.then(() => {
Reveal.layout();
});
}
}
};

function loadScript( url, callback ) {

let script = document.createElement( 'script' );
script.type = "text/javascript"
script.id = "MathJax-script"
script.src = url;
script.async = true

// Wrapper for callback to make sure it only fires once
script.onload = () => {
if (typeof callback === 'function') {
callback.call();
callback = null;
}
};

document.head.appendChild( script );

}

return {
id: 'mathjax3',
init: function(reveal) {

deck = reveal;

let revealOptions = deck.getConfig().mathjax3 || {};
let options = {...defaultOptions, ...revealOptions};
options.tex = {...defaultOptions.tex, ...revealOptions.tex}
options.options = {...options.options, ...defaultOptions.options}
options.startup = {...defaultOptions.startup, ...revealOptions.startup}

let url = options.mathjax || 'https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js';
options.mathjax = null;

window.MathJax = options;

loadScript( url, function() {
// Reprocess equations in slides when they turn visible
Reveal.addEventListener( 'slidechanged', function( event ) {
MathJax.typeset();
} );
} );

}
}

};
Loading

0 comments on commit 0ea4193

Please sign in to comment.