e60c792 Aug 31, 2016
Davide P. Cervone Update versions and copyrights
@pkra @jaredwindover @Grahack
132 lines (114 sloc) 4.1 KB
<!DOCTYPE html>
<title>Dynamic Preview of Textarea with MathJax Content</title>
<!-- Copyright (c) 2012-2016 The MathJax Consortium -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/x-mathjax-config">
showProcessingMessages: false,
tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }
<script type="text/javascript" src="../MathJax.js?config=TeX-MML-AM_HTMLorMML"></script>
var Preview = {
delay: 150, // delay after keystroke before updating
preview: null, // filled in by Init below
buffer: null, // filled in by Init below
timeout: null, // store setTimout id
mjRunning: false, // true when MathJax is processing
mjPending: false, // true when a typeset has been queued
oldText: null, // used to check if an update is needed
// Get the preview and buffer DIV's
Init: function () {
this.preview = document.getElementById("MathPreview");
this.buffer = document.getElementById("MathBuffer");
// Switch the buffer and preview, and display the right one.
// (We use visibility:hidden rather than display:none since
// the results of running MathJax are more accurate that way.)
SwapBuffers: function () {
var buffer = this.preview, preview = this.buffer;
this.buffer = buffer; this.preview = preview; = "hidden"; = "absolute"; = ""; = "";
// This gets called when a key is pressed in the textarea.
// We check if there is already a pending update and clear it if so.
// Then set up an update to occur after a small delay (so if more keys
// are pressed, the update won't occur until after there has been
// a pause in the typing).
// The callback function is set up below, after the Preview object is set up.
Update: function () {
if (this.timeout) {clearTimeout(this.timeout)}
this.timeout = setTimeout(this.callback,this.delay);
// Creates the preview and runs MathJax on it.
// If MathJax is already trying to render the code, return
// If the text hasn't changed, return
// Otherwise, indicate that MathJax is running, and start the
// typesetting. After it is done, call PreviewDone.
CreatePreview: function () {
Preview.timeout = null;
if (this.mjPending) return;
var text = document.getElementById("MathInput").value;
if (text === this.oldtext) return;
if (this.mjRunning) {
this.mjPending = true;
} else {
this.buffer.innerHTML = this.oldtext = text;
this.mjRunning = true;
// Indicate that MathJax is no longer running,
// and swap the buffers to show the results.
PreviewDone: function () {
this.mjRunning = this.mjPending = false;
// Cache a callback to the CreatePreview action
Preview.callback = MathJax.Callback(["CreatePreview",Preview]);
Preview.callback.autoReset = true; // make sure it can run more than once
<p> Type text (mixed with MathML, TeX or asciimath) in the box below for a live preview.</p>
<textarea id="MathInput" cols="60" rows="10" onkeyup="Preview.Update()" style="margin-top:5px">
<p>Configured delimiters:
<li>TeX, inline mode: <code>\(...\)</code> or <code>$...$</code></li>
<li>TeX, display mode: <code>\[...\]</code> or <code> $$...$$</code></li>
<li>Asciimath: <code>`...`</code>.</li>
<p>Preview is shown here:</p>
<div id="MathPreview" style="border:1px solid; padding: 3px; width:50%; margin-top:5px"></div>
<div id="MathBuffer" style="border:1px solid; padding: 3px; width:50%; margin-top:5px;
visibility:hidden; position:absolute; top:0; left: 0"></div>