|
| 1 | +MathJax.Hub.Config({ |
| 2 | + showProcessingMessages: false, |
| 3 | + tex2jax: { |
| 4 | + inlineMath: [['$','$']], |
| 5 | + displayMath: [['$$', '$$']], |
| 6 | + ignoreClass: ".*", |
| 7 | + processClass: "mathjax" |
| 8 | + }, |
| 9 | + TeX: { |
| 10 | + equationNumbers: { |
| 11 | + autoNumber: "AMS" |
| 12 | + } |
| 13 | + } |
| 14 | +}); |
| 15 | + |
| 16 | +marked.setOptions({ |
| 17 | + renderer: new marked.Renderer(), |
| 18 | + gfm: true, |
| 19 | + tables: true, |
| 20 | + breaks: false, |
| 21 | + pedantic: false, |
| 22 | + sanitize: false, |
| 23 | + smartLists: true, |
| 24 | + smartypants: false, |
| 25 | + highlight: function (code) { |
| 26 | + return hljs.highlightAuto(code).value; |
| 27 | + } |
| 28 | +}); |
| 29 | + |
| 30 | +var Preview = { |
| 31 | + delay: 50, |
| 32 | + |
| 33 | + input: null, |
| 34 | + preview: null, |
| 35 | + buffer: null, |
| 36 | + |
| 37 | + timeout: [], |
| 38 | + isRunning: [], |
| 39 | + oldText: [], |
| 40 | + |
| 41 | + numberOfElements: null, |
| 42 | + |
| 43 | + markdownEnabled: true, |
| 44 | + mathjaxEnabled: true, |
| 45 | + forceUpdate: false, |
| 46 | + |
| 47 | + Init: function () { |
| 48 | + this.input = document.getElementsByClassName("markjax-input"); |
| 49 | + this.preview = document.getElementsByClassName("markjax-preview"); |
| 50 | + this.buffer = document.getElementsByClassName("markjax-preview-buffer"); |
| 51 | + |
| 52 | + this.numberOfElements = this.preview.length; |
| 53 | + for (var i = 0; i < this.numberOfElements; i++) { |
| 54 | + this.input[i].setAttribute("markjax-index", i); |
| 55 | + this.preview[i].setAttribute("markjax-index", i); |
| 56 | + this.buffer[i].setAttribute("markjax-index", i); |
| 57 | + } |
| 58 | + }, |
| 59 | + |
| 60 | + Update: function (index) { |
| 61 | + if (this.timeout[index]) { |
| 62 | + clearTimeout(this.timeout[index]); |
| 63 | + } |
| 64 | + |
| 65 | + this.timeout[index] = setTimeout( |
| 66 | + MathJax.Callback(["CreatePreview", Preview, index]), this.delay |
| 67 | + ); |
| 68 | + }, |
| 69 | + |
| 70 | + UpdateAll: function () { |
| 71 | + for (var i = 0; i < this.numberOfElements; i++) { |
| 72 | + this.Update(i); |
| 73 | + } |
| 74 | + }, |
| 75 | + |
| 76 | + CreatePreview: function (index) { |
| 77 | + this.timeout[index] = null; |
| 78 | + if (this.isRunning[index]) { |
| 79 | + return; |
| 80 | + } |
| 81 | + |
| 82 | + var text; |
| 83 | + if (this.input[index].classList.contains("markjax-editor")) { |
| 84 | + text = this.input[index].value; |
| 85 | + } else { |
| 86 | + text = this.input[index].innerHTML.replace(/</mg, '<').replace(/>/mg, '>'); |
| 87 | + } |
| 88 | + |
| 89 | + if (!this.forceUpdate && text === this.oldText[index]) { |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + this.oldText[index] = text; |
| 94 | + this.isRunning[index] = true; |
| 95 | + |
| 96 | + if (this.markdownEnabled === true) { |
| 97 | + this.buffer[index].innerHTML = this.ReEscapeTex(marked(this.EscapeTex(text))); |
| 98 | + var code = $(this.buffer[index]).find("code"); |
| 99 | + for (var i = 0; i < code.length; i++) { |
| 100 | + code[i].innerHTML = code[i].innerHTML.replace(/\\\$/g, '$'); |
| 101 | + } |
| 102 | + $(this.buffer[index]).find("*").not("code").addClass("mathjax"); |
| 103 | + } else { |
| 104 | + this.buffer[index].innerHTML = text; |
| 105 | + } |
| 106 | + |
| 107 | + if (this.mathjaxEnabled === true) { |
| 108 | + MathJax.Hub.Queue( |
| 109 | + ["Typeset", MathJax.Hub, this.buffer[index]], |
| 110 | + ["PreviewDone", this, index], |
| 111 | + ["resetEquationNumbers", MathJax.InputJax.TeX] |
| 112 | + ); |
| 113 | + } else { |
| 114 | + this.PreviewDone(index); |
| 115 | + } |
| 116 | + }, |
| 117 | + |
| 118 | + PreviewDone: function (index) { |
| 119 | + this.isRunning[index] = false; |
| 120 | + Preview.forceUpdate = false; |
| 121 | + this.preview[index].innerHTML = this.buffer[index].innerHTML; |
| 122 | + }, |
| 123 | + |
| 124 | + EscapeTex: function(text) { |
| 125 | + var re = /(`+)(\s*)([\s\S]*?[^`])(\s*)(\1)(?!`)/g; |
| 126 | + var out = text.replace(re, function(m, p1, p2, p3, p4, p5, offset, string) { |
| 127 | + return p1 + p2 + p3.replace(/\$/g, '\\$') + p4 + p5; |
| 128 | + }); |
| 129 | + |
| 130 | + re = /^( {4}[^\n]+\n*)+/g; |
| 131 | + out = out.replace(re, function(m, p1, offset, string) { |
| 132 | + return p1.replace(/\$/g, '\\$'); |
| 133 | + }); |
| 134 | + |
| 135 | + re = /([^\\\$]|^)(\${1,2})(?!\$)(\s*)([\s\S]*?[^$])(\s*)(\2)(?!\2)/g; |
| 136 | + out = out.replace(re, function(m, p1, p2, p3, p4, p5, p6, offset, string) { |
| 137 | + return p1 + p2 + p3 + p4.replace(/(.)/g, '\\$1') + p5 + p6; |
| 138 | + }); |
| 139 | + |
| 140 | + return out; |
| 141 | + }, |
| 142 | + |
| 143 | + ReEscapeTex: function(text) { |
| 144 | + var re = /([^\\\$]|^)(\${1,2})(?!\$)(\s*)([\s\S]*?[^$])(\s*)(\2)(?!\2)/g; |
| 145 | + var out = text.replace(re, function(m, p1, p2, p3, p4, p5, p6, offset, string) { |
| 146 | + return p1 + p2 + p3 + p4.replace(/\\(.)/g, '$1') + p5 + p6; |
| 147 | + }); |
| 148 | + |
| 149 | + return out; |
| 150 | + } |
| 151 | +}; |
| 152 | + |
| 153 | +$(document).ready(function() { |
| 154 | + Preview.Init(); |
| 155 | + Preview.UpdateAll(); |
| 156 | + |
| 157 | + autosize($("textarea.markjax-editor.markjax-input")); |
| 158 | + $('.modal-trigger').leanModal(); |
| 159 | + |
| 160 | + $(".btn.modal-trigger").on("click", function() { |
| 161 | + $("#fullscreen-preview .modal-content").html($(".markjax-editor.markjax-preview").html()); |
| 162 | + }); |
| 163 | + |
| 164 | + $("#column_view").on("change", function() { |
| 165 | + $(".input-column").removeClass("s12 m12 l12"); |
| 166 | + $(".preview-column").removeClass("s12 m12 l12"); |
| 167 | + $(".input-column").addClass("s6 m6 l6"); |
| 168 | + $(".preview-column").addClass("s6 m6 l6"); |
| 169 | + }); |
| 170 | + $("#stream_view").on("change", function() { |
| 171 | + $(".input-column").removeClass("s6 m6 l6"); |
| 172 | + $(".preview-column").removeClass("s6 m6 l6"); |
| 173 | + $(".input-column").addClass("s12 m12 l12"); |
| 174 | + $(".preview-column").addClass("s12 m12 l12"); |
| 175 | + }); |
| 176 | + |
| 177 | + $(".markjax-editor.markjax-input").on("keyup", function(){ |
| 178 | + Preview.Update(parseInt(this.getAttribute("markjax-index"))); |
| 179 | + }); |
| 180 | + |
| 181 | + $("#select-markdown").on("change", function() { |
| 182 | + Preview.markdownEnabled = this.checked; |
| 183 | + Preview.forceUpdate = true; |
| 184 | + Preview.UpdateAll(); |
| 185 | + }); |
| 186 | + $("#select-mathjax").on("change", function() { |
| 187 | + Preview.mathjaxEnabled = this.checked; |
| 188 | + Preview.forceUpdate = true; |
| 189 | + Preview.UpdateAll(); |
| 190 | + }); |
| 191 | + |
| 192 | + $("textarea.markjax-editor.markjax-input").keydown(function(e) { |
| 193 | + if(e.keyCode === 9) { // tab was pressed |
| 194 | + // get caret position/selection |
| 195 | + var start = this.selectionStart; |
| 196 | + var end = this.selectionEnd; |
| 197 | + |
| 198 | + var $this = $(this); |
| 199 | + var value = $this.val(); |
| 200 | + |
| 201 | + // set textarea value to: text before caret + tab + text after caret |
| 202 | + $this.val(value.substring(0, start) + " " + value.substring(end)); |
| 203 | + |
| 204 | + // put caret at right position again (add one for the tab) |
| 205 | + this.selectionStart = this.selectionEnd = start + 2; |
| 206 | + |
| 207 | + // prevent the focus lose |
| 208 | + e.preventDefault(); |
| 209 | + } |
| 210 | + }); |
| 211 | +}); |
0 commit comments