From 9a98e13af98db2801430c5c4062a822b66ad74a2 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Tue, 7 Nov 2017 23:36:30 -0500 Subject: render cleanup, move examples to data --- htdocs/js/data.js | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++ htdocs/js/mathy.js | 221 ++++++++++++++++++++++--------------------- 2 files changed, 384 insertions(+), 105 deletions(-) create mode 100644 htdocs/js/data.js (limited to 'htdocs/js') 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($) { "", "", ], - }); - var Preview = window.Preview = { - delay: 150, // delay after keystroke before updating + help: [ + "", - 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 + "
  • ", + "
  • ", + ], - // - // Get the preview and buffer DIV's - // - Init: function () { - this.preview = document.getElementById("MathPreview"); - this.buffer = document.getElementById("MathBuffer"); - }, + help_row: [ + "
  • ", + "", + "%{num|h}. %{name|h}", + "", + "
  • ", + ], + }); + // 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(); }); -- cgit v1.2.3