aboutsummaryrefslogtreecommitdiff
path: root/htdocs/js
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2017-11-07 23:36:30 -0500
committerPaul Duncan <pabs@pablotron.org>2017-11-07 23:36:30 -0500
commit9a98e13af98db2801430c5c4062a822b66ad74a2 (patch)
tree35384dcf2a8e82852a5e6b0ce937feffaee10b21 /htdocs/js
parent4a6ad960f36051d88cf7a9f7425eac8a7a85b39d (diff)
downloadmathy-9a98e13af98db2801430c5c4062a822b66ad74a2.tar.bz2
mathy-9a98e13af98db2801430c5c4062a822b66ad74a2.zip
render cleanup, move examples to data
Diffstat (limited to 'htdocs/js')
-rw-r--r--htdocs/js/data.js268
-rw-r--r--htdocs/js/mathy.js221
2 files changed, 384 insertions, 105 deletions
diff --git a/htdocs/js/data.js b/htdocs/js/data.js
new file mode 100644
index 0000000..f17f364
--- /dev/null
+++ b/htdocs/js/data.js
@@ -0,0 +1,268 @@
+var DATA = {
+ examples: [{
+ name: "Some Limit",
+ text: [
+ "\\lim_{x \\to \\infty}{\\frac{1}{x^2}}",
+ ],
+ }, {
+ name: "Quadratic Formula",
+ text: [
+ "\\text{Quadratic Formula} \\\\",
+ "x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}",
+ ],
+ }, {
+ name: "Cross Product",
+ text: [
+ "\\text{Cross Product via Matrix Determinant} \\\\",
+ "",
+ "\\begin{align*}",
+ " \\vec{a} \\times \\vec{b} & = \\begin{vmatrix}",
+ " \\hat{i} & \\hat{j} & \\hat{k} \\\\",
+ " \\vec{a}_x & \\vec{a}_y & \\vec{a}_z \\\\",
+ " \\vec{b}_x & \\vec{b}_y & \\vec{b}_z ",
+ " \\end{vmatrix} \\\\",
+ " ",
+ " & = ",
+ " \\begin{vmatrix}",
+ " \\vec{a}_y & \\vec{a}_z \\\\",
+ " \\vec{b}_y & \\vec{b}_z",
+ " \\end{vmatrix} \\hat{i} - ",
+ " ",
+ " \\begin{vmatrix}",
+ " \\vec{a}_x & \\vec{a}_z \\\\",
+ " \\vec{b}_x & \\vec{b}_z",
+ " \\end{vmatrix} \\hat{j} +",
+ " ",
+ " \\begin{vmatrix}",
+ " \\vec{a}_x & \\vec{a}_y \\\\",
+ " \\vec{b}_x & \\vec{b}_y",
+ " \\end{vmatrix} \\hat{k} \\\\",
+ " ",
+ " & = ",
+ " (\\vec{a}_y\\vec{b}_z - \\vec{a}_z\\vec{b}_y)\\hat{i} -",
+ " (\\vec{a}_x\\vec{b}_z - \\vec{a}_z\\vec{b}_x)\\hat{j} +",
+ " (\\vec{a}_x\\vec{b}_y - \\vec{a}_x\\vec{b}_y)\\hat{k} \\\\",
+ " ",
+ " & =",
+ " \\langle",
+ " \\vec{a}_y\\vec{b}_z - \\vec{a}_z\\vec{b}_y\\text{, } ",
+ " \\vec{a}_x\\vec{b}_z - \\vec{a}_z\\vec{b}_x\\text{, } ",
+ " \\vec{a}_x\\vec{b}_y - \\vec{a}_y\\vec{b}_z",
+ " \\rangle \\\\",
+ " ",
+ " \\vec{a} & = \\langle2, 1, -1\\rangle \\\\",
+ " \\vec{b} & = \\langle-3, 4, 1\\rangle \\\\",
+ " \\vec{a} \\times \\vec{b} & = \\langle",
+ " (1)(1) - (-1)(4),",
+ " (2)(1) - (-1)(-3),",
+ " (2)(4) - (1)(-3)",
+ " \\rangle \\\\",
+ " ",
+ " & = \\langle",
+ " 5, 5, 11",
+ " \\rangle \\\\",
+ " \\vec{b} \\times \\vec{a} & = \\langle",
+ " (4)(-1) - (1)(1),",
+ " (-3)(-1) - (1)(2),",
+ " (-3)(1) - (4)(2)",
+ " \\rangle \\\\",
+ " & = \\langle",
+ " -5, -5, -11",
+ " \\rangle",
+ "\\end{align*}",
+ ],
+ }, {
+ name: "Derivative Rules",
+ text: [
+ "\\text{Derivative Rules} \\\\",
+ "",
+ "\\begin{align*}",
+ "% sum/difference rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "f(x) \\pm g(x) &=",
+ "\\frac{\\text{d}}{\\text{d}x} \\, f(x) \\pm",
+ "\\frac{\\text{d}}{\\text{d}x} \\, g(x) &",
+ "\\text{Sum/Difference Rule} \\\\",
+ "",
+ "% constant factor rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "k f(x) &=",
+ "k \\frac{\\text{d}}{\\text{d}x} \\, f(x) &",
+ "\\text{Constant Factor Rule} \\\\",
+ "",
+ "% constant rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "k &=",
+ "0 &",
+ "\\text{Constant Rule} \\\\",
+ "",
+ "% power rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "x^n &=",
+ "nx^{n-1} &",
+ "\\text{Power Rule} \\\\",
+ "",
+ "% exponent rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "b^x &=",
+ "b^xln(b) &",
+ "\\text{Exponent Rule} \\\\",
+ "",
+ "% chain rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "f(g(x)) &=",
+ "% (f \\cdot g)(x) &=",
+ "f'(g(x))g'(x) &",
+ "\\text{Chain Rule} \\\\",
+ "",
+ "% product rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "f(x)g(x) &=",
+ "f'(x)g(x) + f(x)g'(x) &",
+ "\\text{Product Rule} \\\\",
+ "",
+ "% quotient rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "\\frac{f(x)}{g(x)} &=",
+ "\\frac{f'(x)g(x) - f(x)g'(x)}{g(x)^2} &",
+ "\\text{Quotient Rule} \\\\",
+ "",
+ "% logarithm rule",
+ "\\frac{\\text{d}}{\\text{d}x} \\,",
+ "log_b{x} &=",
+ "\\frac{1}{x ln(b)} &",
+ "\\text{Logarithm Rule} \\\\",
+ "",
+ "\\end{align*}",
+ ],
+ }, {
+ name: "Cubic Formula",
+ text: [
+ "% https://math.vanderbilt.edu/schectex/courses/cubic/",
+ "\\text{The Cubic Formula} \\\\",
+ "\\begin{align*}",
+ "% first term",
+ "x &= \\sqrt[3]{",
+ " % first term, first subterm",
+ " \\left (",
+ " \\frac{-b^3}{27a^3} +",
+ " \\frac{bc}{6a^2} -",
+ " \\frac{d}{2a}",
+ " \\right )",
+ "",
+ " +",
+ "",
+ " \\sqrt{",
+ " % first term, second subterm",
+ " \\left (",
+ " \\frac{-b^3}{27a^3} +",
+ " \\frac{bc}{6a^2} -",
+ " \\frac{d}{2a}",
+ " \\right )^2",
+ "",
+ " +",
+ "",
+ " % first term, third subterm",
+ " \\left (",
+ " \\frac{c}{3a} -",
+ " \\frac{b^2}{9a^2}",
+ " \\right )^3",
+ " }",
+ "} \\\\",
+ "",
+ "&+",
+ "",
+ "% second term",
+ "\\sqrt[3]{",
+ " % first term, second subterm",
+ " \\left (",
+ " \\frac{-b^3}{27a^3} +",
+ " \\frac{bc}{6a^2} -",
+ " \\frac{d}{2a}",
+ " \\right )",
+ "",
+ " -",
+ "",
+ " \\sqrt{",
+ " % second term, second subterm",
+ " \\left (",
+ " \\frac{-b^3}{27a^3} +",
+ " \\frac{bc}{6a^2} -",
+ " \\frac{d}{2a}",
+ " \\right )^2",
+ "",
+ " +",
+ "",
+ " % second term, third subterm",
+ " \\left (",
+ " \\frac{c}{3a} -",
+ " \\frac{b^2}{9a^2}",
+ " \\right )^3",
+ " }",
+ "} \\\\",
+ "",
+ "&-",
+ "",
+ "% third part",
+ "\\frac{b}{3a}",
+ "\\end{align*}",
+ ],
+ }, {
+ name: "Linear Regression",
+ text: [
+ "\\text{Linear Regression} \\\\",
+ "",
+ "\\begin{align*}",
+ " m &= \\frac{",
+ " \\sum(x_i - \\bar{x})(y_i - \\bar{y} )",
+ " }{",
+ " \\sum(x_i - \\bar{x})^2",
+ " } \\\\",
+ "",
+ " b &= \\bar{y} - m\\bar{x} \\\\",
+ "",
+ " y &= mx + b",
+ "\\end{align*}",
+ ],
+ }],
+
+ themes: [
+ "ambiance",
+ "chaos",
+ "chrome",
+ "clouds",
+ "clouds_midnight",
+ "cobalt",
+ "crimson_editor",
+ "dawn",
+ "dracula",
+ "dreamweaver",
+ "eclipse",
+ "github",
+ "gob",
+ "gruvbox",
+ "idle_fingers",
+ "iplastic",
+ "katzenmilch",
+ "kr_theme",
+ "kuroir",
+ "merbivore",
+ "merbivore_soft",
+ "mono_industrial",
+ "monokai",
+ "pastel_on_dark",
+ "solarized_dark",
+ "solarized_light",
+ "sqlserver",
+ "terminal",
+ "textmate",
+ "tomorrow",
+ "tomorrow_night_blue",
+ "tomorrow_night_bright",
+ "tomorrow_night_eighties",
+ "tomorrow_night",
+ "twilight",
+ "vibrant_ink",
+ "xcode",
+ ],
+};
diff --git a/htdocs/js/mathy.js b/htdocs/js/mathy.js
index 13794fc..500f677 100644
--- a/htdocs/js/mathy.js
+++ b/htdocs/js/mathy.js
@@ -25,161 +25,162 @@ jQuery(function($) {
"</a>",
"</li>",
],
- });
- var Preview = window.Preview = {
- delay: 150, // delay after keystroke before updating
+ help: [
+ "<li class='dropdown-header'>",
+ " Examples",
+ "</li>",
- preview: null, // filled in by Init below
- buffer: null, // filled in by Init below
+ "%{examples}",
- 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
+ "<li class='divider'>",
+ "</li>",
+ ],
- //
- // Get the preview and buffer DIV's
- //
- Init: function () {
- this.preview = document.getElementById("MathPreview");
- this.buffer = document.getElementById("MathBuffer");
- },
+ help_row: [
+ "<li>",
+ "<a ",
+ "href='#' ",
+ "class='example' ",
+ "data-text='%{text|h}' ",
+ ">",
+ "%{num|h}. %{name|h}",
+ "</a>",
+ "</li>",
+ ],
+ });
+ // init mathjax
+ var math = (function() {
+ var delay = 150, // delay after keystroke before updating
+ preview = document.getElementById("math-preview"),
+ buffer = document.getElementById("math-buffer"),
+ timeout = null, // timeout ID
+ is_running = false, // true when MathJax is processing
+ is_pending = false, // true when a typeset has been queued
+ old_text = null; // used to check if an update is needed
+
+ // Swap render buffers.
//
- // 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;
- buffer.style.visibility = "hidden"; buffer.style.position = "absolute";
- preview.style.position = ""; preview.style.visibility = "";
- },
+ // Note from MathJax example: We use visibility:hidden rather than
+ // display:none since the results of running MathJax are more
+ // accurate that way.
+ function swap_buffers() {
+ var tmp_buffer = preview,
+ tmp_preview = buffer;
+
+ // update buffer
+ buffer = tmp_buffer;
+ buffer.style.visibility = "hidden";
+ buffer.style.position = "absolute";
+
+ // update preview
+ preview = tmp_preview;
+ preview.style.position = "";
+ preview.style.visibility = "";
+ }
- //
- // 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 () {
- var syntax = $('#menu-syntax .active a').data();
+ function preview_done() {
+ is_running = is_pending = false;
+ swap_buffers();
+ }
+
+ function create_preview() {
+ // clear timeout value
+ timeout = null;
- Preview.timeout = null;
- if (this.mjPending) return;
+ if (is_pending)
+ return;
+
+ // get editor text
var text = "\\[" + editor.getValue() + "\\]";
- if (text === this.oldtext) return;
- if (this.mjRunning) {
- this.mjPending = true;
- MathJax.Hub.Queue(["CreatePreview",this]);
+
+ if (text === old_text)
+ return;
+
+ if (is_running) {
+ is_pending = true;
+ MathJax.Hub.Queue(create_preview);
} else {
- this.buffer.innerHTML = this.oldtext = text;
- this.mjRunning = true;
+ buffer.innerHTML = old_text = text;
+ is_running = true;
MathJax.Hub.Queue(
- ["Typeset",MathJax.Hub,this.buffer],
- ["PreviewDone",this]
+ ['Typeset', MathJax.Hub, buffer],
+ preview_done
);
}
- },
-
- //
- // Indicate that MathJax is no longer running,
- // and swap the buffers to show the results.
- //
- PreviewDone: function () {
- this.mjRunning = this.mjPending = false;
- this.SwapBuffers();
}
- };
- //
- // 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
-
- function add_text(el, text, pos) {
- var val = el.value,
- head = val.substring(0, el.selectionStart),
- tail = val.substring(el.selectionEnd, val.length);
-
- // update value
- el.value = head + text + tail;
-
- // get offset
- if (pos === undefined)
- pos = text.length;
-
- // update caret position
- el.selectionStart = el.selectionEnd = head.length + pos;
- }
-
- $('#input').keyup(function(ev) {
- window.Preview.Update();
- });
+ // init callback
+ var callback = MathJax.Callback(create_preview);
+ callback.autoReset = true;
+
+ return {
+ update: function() {
+ if (timeout) {
+ clearTimeout(timeout);
+ timeout = null;
+ }
+ timeout = setTimeout(callback, delay);
+ },
+ };
+ })();
+ // init editor
var autosave_timeout = null,
editor = ace.edit('editor');
editor.setShowPrintMargin(false);
editor.setTheme('ace/theme/monokai');
editor.getSession().setMode('ace/mode/latex');
editor.getSession().on('change', function(e) {
- window.Preview.Update();
+ // queue update
+ math.update();
+
if (autosave_timeout) {
+ // clear autosave timeout
clearTimeout(autosave_timeout);
autosave_timeout = null;
}
+
+ // set autosave timeout
autosave_timeout = setTimeout(function() {
+ // autosave text
localStorage.setItem('mathy_last', editor.getValue());
}, 1000);
});
(function() {
+ // load autosaved text
var last = localStorage.getItem('mathy_last');
if (!last)
return;
+
+ // set text
editor.setValue(last);
})();
- $('#add').click(function() {
- var el = $('#input')[0];
- add_shit(el, 'shit');
- try { el.focus(); } catch (e) {}
- return false;
- });
-
$('#saves').on('click', 'a', function() {
if ($(this).parent().hasClass('disabled'))
return false;
+ // get text, hide dropdown
var text = $(this).data('text');
$('body').trigger('click');
setTimeout(function() {
+ // set editor text
editor.setValue(text);
}, 10);
+ // stop event
return false;
}).parent().on('show.bs.dropdown', function() {
+ // load saves
var saves = localStorage.getItem('mathy_saves');
saves = saves ? JSON.parse(saves) : [];
+ // build html
var html = '';
if (saves.length > 0) {
html = $.map(saves, function(row) {
@@ -189,10 +190,11 @@ jQuery(function($) {
html = TEMPLATES.run('none');
}
+ // populate html
$('#saves').html(html);
});
- $('#btn-save').click(function() {
+ $('#save').click(function() {
// get name
var name = prompt('Enter name:', '');
if (!name)
@@ -230,16 +232,25 @@ jQuery(function($) {
return false;
});
- $('#help').on('click', 'a', function() {
- var text = $(this).data('text').replace(/^\s+|\s+$/g, '');
+ $('#help').html(TEMPLATES.run('help', {
+ examples: $.map(DATA.examples, function(row, i) {
+ return TEMPLATES.run('help_row', $.extend({}, row, {
+ num: i + 1,
+ text: row.text.join('\n'),
+ }));
+ }).join(''),
+ })).on('click', 'a', function() {
+ var text = $(this).data('text');
+
+ // hide dropdown
$('body').trigger('click');
setTimeout(function() {
+ // load text
editor.setValue(text);
}, 10);
+ // stop event
return false;
});
-
- Preview.Init();
});