This commit is contained in:
benweet 2014-04-29 21:23:22 +01:00
parent 3c384739ee
commit a7877483b0
4 changed files with 270 additions and 162 deletions

1
.gitignore vendored
View File

@ -4,4 +4,5 @@
node_modules node_modules
Thumbs.db Thumbs.db
.DS_Store .DS_Store
stackedit.iml
public/res/bower-libs public/res/bower-libs

View File

@ -534,8 +534,7 @@ define([
if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) == '\n') { if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) == '\n') {
newTextContent = newTextContent.slice(0, -1); newTextContent = newTextContent.slice(0, -1);
} }
newTextContent = newTextContent.replace(/\r\n/g, '\n'); // DOS to Unix newTextContent = newTextContent.replace(/\r\n?/g, '\n'); // Mac/DOS to Unix
newTextContent = newTextContent.replace(/\r/g, '\n'); // Mac to Unix
if(fileChanged === false) { if(fileChanged === false) {
if(newTextContent == textContent) { if(newTextContent == textContent) {

View File

@ -9,7 +9,7 @@ define([
var mathJax = new Extension("mathJax", "MathJax", true); var mathJax = new Extension("mathJax", "MathJax", true);
mathJax.settingsBlock = mathJaxSettingsBlockHTML; mathJax.settingsBlock = mathJaxSettingsBlockHTML;
mathJax.defaultConfig = { mathJax.defaultConfig = {
tex: "{}", tex : "{}",
tex2jax: '{ inlineMath: [["$","$"],["\\\\\\\\(","\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true }' tex2jax: '{ inlineMath: [["$","$"],["\\\\\\\\(","\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true }'
}; };
@ -25,141 +25,249 @@ define([
/*jshint ignore:start */ /*jshint ignore:start */
mathJax.onPagedownConfigure = function(editorObject) { mathJax.onPagedownConfigure = function(editorObject) {
t = document.getElementById("preview-contents"); preview = document.getElementById("preview-contents");
var converter = editorObject.getConverter(); var converter = editorObject.getConverter();
converter.hooks.chain("preConversion", p); converter.hooks.chain("preConversion", removeMath);
converter.hooks.chain("postConversion", d); converter.hooks.chain("postConversion", replaceMath);
}; };
var afterRefreshCallback; var afterRefreshCallback;
mathJax.onAsyncPreview = function(callback) { mathJax.onAsyncPreview = function(callback) {
afterRefreshCallback = callback; afterRefreshCallback = callback;
j(); UpdateMJ();
}; };
// From math.stackexchange.com... // From math.stackexchange.com...
function b(a, f, b) { //
var c = k.slice(a, f + 1).join("").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"); // The math is in blocks i through j, so
for (h.Browser.isMSIE && (c = c.replace(/(%[^\n]*)\n/g, "$1<br/>\n")); f > a; ) // collect it into one block and clear the others.
k[f] = "", f--; // Replace &, <, and > by named entities.
k[a] = "@@" + m.length + "@@"; // For IE, put <br> at the ends of comments since IE removes \n.
b && (c = b(c)); // Clear the current math positions and store the index of the
m.push(c); // math, then push the math string onto the storage array.
i = o = l = null //
function processMath(i, j, unescape) {
var block = blocks.slice(i, j + 1).join("")
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
for(HUB.Browser.isMSIE && (block = block.replace(/(%[^\n]*)\n/g, "$1<br/>\n")); j > i;)
blocks[j] = "", j--;
blocks[i] = "@@" + math.length + "@@";
unescape && (block = unescape(block));
math.push(block);
start = end = last = null;
} }
function p(a) {
i = o = l = null; function removeMath(text) {
m = []; start = end = last = null;
var f; math = [];
/`/.test(a) ? (a = a.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function(a) { var unescape;
return a.replace(/\$/g, "~D") if(/`/.test(text)) {
}), f = function(a) { text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function(text) {
return a.replace(/~([TD])/g, return text.replace(/\$/g, "~D")
function(a, c) { });
return {T: "~",D: "$"}[c] unescape = function(text) {
return text.replace(/~([TD])/g,
function(match, n) {
return {T: "~", D: "$"}[n]
}) })
}) : f = function(a) {
return a
}; };
k = r(a.replace(/\r\n?/g, "\n"), u); } else {
for (var a = 1, d = k.length; a < d; a += 2) { unescape = function(text) {
var c = k[a]; return text
"@" === c.charAt(0) ? (k[a] = "@@" + m.length + "@@", m.push(c)) : i ? c === o ? n ? l = a : b(i, a, f) : c.match(/\n.*\n/) ? (l && (a = l, b(i, a, f)), i = o = l = null, n = 0) : "{" === c ? n++ : "}" === c && n && n-- : c === s || "$$" === c ? (i = a, o = c, n = 0) : "begin" === c.substr(1, 5) && (i = a, o = "\\end" + c.substr(6), n = 0) };
} }
l && b(i, l, f); blocks = split(text.replace(/\r\n?/g, "\n"), splitDelimiter);
return f(k.join("")) for(var i = 1, m = blocks.length; i < m; i += 2) {
var block = blocks[i];
if("@" === block.charAt(0)) {
//
// Things that look like our math markers will get
// stored and then retrieved along with the math.
//
blocks[i] = "@@" + math.length + "@@";
math.push(block)
} else if(start) {
//
// If we are in math, look for the end delimiter,
// but don't go past double line breaks, and
// and balance braces within the math.
//
if(end == inline && block.charAt(0) == '\n') {
// This should fix #136 by ignoring inline maths that are actually multiline
start = end = last = null;
} else if(block === end) {
if(braces) {
last = i
} else {
processMath(start, i, unescape)
} }
function d(a) { } else {
a = a.replace(/@@(\d+)@@/g, function(a, b) { if(block.match(/\n.*\n/)) {
return m[b] last && (i = last, processMath(start, i, unescape)), start = end = last = null, braces = 0
} else {
if("{" === block) {
braces++
} else {
"}" === block && braces && braces--
}
}
}
} else {
if(block === inline || "$$" === block) {
start = i;
end = block;
braces = 0;
} else {
if("begin" === block.substr(1, 5)) {
start = i;
end = "\\end" + block.substr(6);
braces = 0;
}
}
}
}
last && processMath(start, last, unescape);
return unescape(blocks.join(""))
}
//
// Put back the math strings that were saved,
// and clear the math array (no need to keep it around).
//
function replaceMath(text) {
text = text.replace(/@@(\d+)@@/g, function(match, n) {
return math[n]
}); });
m = null; math = null;
return a return text
} }
function e() {
q = !1; //
h.cancelTypeset = !1; // This is run to restart MathJax after it has finished
h.Queue(["Typeset", h, t]) // the previous run (that may have been canceled)
h.Queue(afterRefreshCallback); //benweet //
function RestartMJ() {
pending = false;
HUB.cancelTypeset = false;
HUB.Queue([
"Typeset",
HUB,
preview
]);
HUB.Queue(afterRefreshCallback); //benweet
} }
function j() {
!q && /*benweet (we need to call our afterRefreshCallback) g &&*/ (q = !0, h.Cancel(), h.Queue(e)) //
// When the preview changes, cancel MathJax and restart,
// if we haven't done that already.
//
function UpdateMJ() {
if(!pending /*benweet (we need to call our afterRefreshCallback) && ready */) {
pending = true;
HUB.Cancel();
HUB.Queue(RestartMJ);
} }
var g = !1, q = !1, t = null, s = "$", k, i, o, l, n, m, h = MathJax.Hub; }
h.Queue(function() {
g = !0; var ready = false, pending = false, preview = null, inline = "$", blocks, start, end, last, braces, math, HUB = MathJax.Hub;
h.processUpdateTime = 50;
h.Config({"HTML-CSS": {EqnChunk: 10,EqnChunkFactor: 1},SVG: {EqnChunk: 10,EqnChunkFactor: 1}}) //
// Runs after initial typeset
//
HUB.Queue(function() {
ready = true;
HUB.processUpdateTime = 50;
HUB.Config({"HTML-CSS": {EqnChunk: 10, EqnChunkFactor: 1}, SVG: {EqnChunk: 10, EqnChunkFactor: 1}})
}); });
/*benweet /*benweet
Don't hash inline math $...$ (see https://github.com/benweet/stackedit/issues/136) Don't hash inline math $...$ (see https://github.com/benweet/stackedit/issues/136)
var u = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i, r; var u = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i, r;
*/ */
var u = /(\$\$|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i, r;
r = 3 === "aba".split(/(b)/).length ? function(a, f) {
return a.split(f) //
} : function(a, f) { // The pattern for math delimiters and special symbols
// needed for searching for math in the page.
//
var splitDelimiter = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i;
var split;
if(3 === "aba".split(/(b)/).length) {
split = function(text, delimiter) {
return text.split(delimiter)
};
} else {
split = function(text, delimiter) {
var b = [], c; var b = [], c;
if (!f.global) { if(!delimiter.global) {
c = f.toString(); c = delimiter.toString();
var d = ""; var d = "";
c = c.replace(/^\/(.*)\/([im]*)$/, function(a, c, b) { c = c.replace(/^\/(.*)\/([im]*)$/, function(a, c, b) {
d = b; d = b;
return c return c
}); });
f = RegExp(c, d + "g") delimiter = RegExp(c, d + "g")
} }
for (var e = f.lastIndex = 0; c = f.exec(a); ) for(var e = delimiter.lastIndex = 0; c = delimiter.exec(text);) {
b.push(a.substring(e, c.index)), b.push.apply(b, c.slice(1)), e = c.index + c[0].length; b.push(text.substring(e, c.index));
b.push(a.substring(e)); b.push.apply(b, c.slice(1));
e = c.index + c[0].length;
}
b.push(text.substring(e));
return b return b
}; };
}
(function() { (function() {
var b = MathJax.Hub; var HUB = MathJax.Hub;
if (!b.Cancel) { if(!HUB.Cancel) {
b.cancelTypeset = !1; HUB.cancelTypeset = !1;
b.Register.StartupHook("HTML-CSS Jax Config", function() { HUB.Register.StartupHook("HTML-CSS Jax Config", function() {
var d = MathJax.OutputJax["HTML-CSS"], e = d.Translate; var HTMLCSS = MathJax.OutputJax["HTML-CSS"], TRANSLATE = HTMLCSS.Translate;
d.Augment({Translate: function(j, g) { HTMLCSS.Augment({Translate: function(script, state) {
if (b.cancelTypeset || g.cancelled) if(HUB.cancelTypeset || state.cancelled)
throw Error("MathJax Canceled"); throw Error("MathJax Canceled");
return e.call(d, j, g) return TRANSLATE.call(HTMLCSS, script, state)
}}) }})
}); });
b.Register.StartupHook("SVG Jax Config", function() { HUB.Register.StartupHook("SVG Jax Config", function() {
var d = MathJax.OutputJax.SVG, e = d.Translate; var SVG = MathJax.OutputJax.SVG, TRANSLATE = SVG.Translate;
d.Augment({Translate: function(j, g) { SVG.Augment({Translate: function(script, state) {
if (b.cancelTypeset || g.cancelled) if(HUB.cancelTypeset || state.cancelled)
throw Error("MathJax Canceled"); throw Error("MathJax Canceled");
return e.call(d, return TRANSLATE.call(SVG,
j, g) script, state)
}}) }})
}); });
b.Register.StartupHook("TeX Jax Config", function() { HUB.Register.StartupHook("TeX Jax Config", function() {
var d = MathJax.InputJax.TeX, e = d.Translate; var TEX = MathJax.InputJax.TeX, TRANSLATE = TEX.Translate;
d.Augment({Translate: function(j, g) { TEX.Augment({Translate: function(script, state) {
if (b.cancelTypeset || g.cancelled) if(HUB.cancelTypeset || state.cancelled)
throw Error("MathJax Canceled"); throw Error("MathJax Canceled");
return e.call(d, j, g) return TRANSLATE.call(TEX, script, state)
}}) }})
}); });
var p = b.processError; var PROCESSERROR = HUB.processError;
b.processError = function(d, e, j) { HUB.processError = function(error, state, type) {
if ("MathJax Canceled" !== d.message) if("MathJax Canceled" !== error.message)
return p.call(b, d, e, j); return PROCESSERROR.call(HUB, error, state, type);
MathJax.Message.Clear(0, 0); MathJax.Message.Clear(0, 0);
e.jaxIDs = []; state.jaxIDs = [];
e.jax = {}; state.jax = {};
e.scripts = []; state.scripts = [];
e.i = e.j = 0; state.i = state.j = 0;
e.cancelled = !0; state.cancelled = true;
return null return null
}; };
b.Cancel = function() { HUB.Cancel = function() {
this.cancelTypeset = !0 this.cancelTypeset = true
} }
} }
})(); })();

View File

@ -36,7 +36,7 @@
<a target="_blank" href="https://twitter.com/benweet">Benoit Schweblin</a><br /> <a target="_blank" href="https://twitter.com/benweet">Benoit Schweblin</a><br />
Pete Eigel (contributor)<br /> Pete Eigel (contributor)<br />
wiibaa (contributor)<br /> wiibaa (contributor)<br />
<a target="_blank" href="http://www.hugwebdesign.com/">Daniel Hug (contributor)</a><br /> <a target="_blank" href="http://www.hugwebdesign.com/">Daniel Hug</a> (contributor)<br />
</dd> </dd>
</dl> </dl>
<dl> <dl>
@ -60,8 +60,8 @@
</dd> </dd>
</dl> </dl>
<p> <p>
StackEdit <%= version %> &ndash; <a target="_blank" href="privacy_policy.html">Privacy Policy</a><br /> Copyright 2013 <a StackEdit <%= version %> &ndash; <a target="_blank" href="privacy_policy.html">Privacy Policy</a><br /> Copyright 2013-2014 <a
target="_blank" href="http://www.benoitschweblin.com">Benoit target="_blank" href="https://twitter.com/benweet">Benoit
Schweblin</a><br /> Licensed under an <a target="_blank" Schweblin</a><br /> Licensed under an <a target="_blank"
href="http://www.apache.org/licenses/LICENSE-2.0">Apache href="http://www.apache.org/licenses/LICENSE-2.0">Apache
License</a> License</a>