diff --git a/.gitignore b/.gitignore
index af94e349..1c02ab40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@
node_modules
Thumbs.db
.DS_Store
+stackedit.iml
public/res/bower-libs
diff --git a/public/res/editor.js b/public/res/editor.js
index 838387fc..64947526 100644
--- a/public/res/editor.js
+++ b/public/res/editor.js
@@ -534,8 +534,7 @@ define([
if(contentElt.lastChild === trailingLfNode && trailingLfNode.textContent.slice(-1) == '\n') {
newTextContent = newTextContent.slice(0, -1);
}
- newTextContent = newTextContent.replace(/\r\n/g, '\n'); // DOS to Unix
- newTextContent = newTextContent.replace(/\r/g, '\n'); // Mac to Unix
+ newTextContent = newTextContent.replace(/\r\n?/g, '\n'); // Mac/DOS to Unix
if(fileChanged === false) {
if(newTextContent == textContent) {
diff --git a/public/res/extensions/mathJax.js b/public/res/extensions/mathJax.js
index 9597f6a7..46e45587 100644
--- a/public/res/extensions/mathJax.js
+++ b/public/res/extensions/mathJax.js
@@ -1,169 +1,277 @@
/*defines MathJax */
define([
- "utils",
- "classes/Extension",
- "text!html/mathJaxSettingsBlock.html",
- "mathjax"
+ "utils",
+ "classes/Extension",
+ "text!html/mathJaxSettingsBlock.html",
+ "mathjax"
], function(utils, Extension, mathJaxSettingsBlockHTML) {
-
+
var mathJax = new Extension("mathJax", "MathJax", true);
mathJax.settingsBlock = mathJaxSettingsBlockHTML;
- mathJax.defaultConfig = {
- tex: "{}",
- tex2jax: '{ inlineMath: [["$","$"],["\\\\\\\\(","\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true }'
- };
+ mathJax.defaultConfig = {
+ tex : "{}",
+ tex2jax: '{ inlineMath: [["$","$"],["\\\\\\\\(","\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true }'
+ };
- mathJax.onLoadSettings = function() {
- utils.setInputValue("#input-mathjax-config-tex", mathJax.config.tex);
- utils.setInputValue("#input-mathjax-config-tex2jax", mathJax.config.tex2jax);
- };
+ mathJax.onLoadSettings = function() {
+ utils.setInputValue("#input-mathjax-config-tex", mathJax.config.tex);
+ utils.setInputValue("#input-mathjax-config-tex2jax", mathJax.config.tex2jax);
+ };
- mathJax.onSaveSettings = function(newConfig, event) {
- newConfig.tex = utils.getInputJsValue("#input-mathjax-config-tex", event);
- newConfig.tex2jax = utils.getInputJsValue("#input-mathjax-config-tex2jax", event);
- };
-
- /*jshint ignore:start */
- mathJax.onPagedownConfigure = function(editorObject) {
- t = document.getElementById("preview-contents");
+ mathJax.onSaveSettings = function(newConfig, event) {
+ newConfig.tex = utils.getInputJsValue("#input-mathjax-config-tex", event);
+ newConfig.tex2jax = utils.getInputJsValue("#input-mathjax-config-tex2jax", event);
+ };
- var converter = editorObject.getConverter();
- converter.hooks.chain("preConversion", p);
- converter.hooks.chain("postConversion", d);
- };
-
- var afterRefreshCallback;
- mathJax.onAsyncPreview = function(callback) {
- afterRefreshCallback = callback;
- j();
- };
-
- // From math.stackexchange.com...
+ /*jshint ignore:start */
+ mathJax.onPagedownConfigure = function(editorObject) {
+ preview = document.getElementById("preview-contents");
- function b(a, f, b) {
- var c = k.slice(a, f + 1).join("").replace(/&/g, "&").replace(//g, ">");
- for (h.Browser.isMSIE && (c = c.replace(/(%[^\n]*)\n/g, "$1
\n")); f > a; )
- k[f] = "", f--;
- k[a] = "@@" + m.length + "@@";
- b && (c = b(c));
- m.push(c);
- i = o = l = null
- }
- function p(a) {
- i = o = l = null;
- m = [];
- var f;
- /`/.test(a) ? (a = a.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function(a) {
- return a.replace(/\$/g, "~D")
- }), f = function(a) {
- return a.replace(/~([TD])/g,
- function(a, c) {
- return {T: "~",D: "$"}[c]
- })
- }) : f = function(a) {
- return a
- };
- k = r(a.replace(/\r\n?/g, "\n"), u);
- for (var a = 1, d = k.length; a < d; a += 2) {
- var c = k[a];
- "@" === 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);
- return f(k.join(""))
- }
- function d(a) {
- a = a.replace(/@@(\d+)@@/g, function(a, b) {
- return m[b]
- });
- m = null;
- return a
- }
- function e() {
- q = !1;
- h.cancelTypeset = !1;
- h.Queue(["Typeset", h, t])
- h.Queue(afterRefreshCallback); //benweet
- }
- function j() {
- !q && /*benweet (we need to call our afterRefreshCallback) g &&*/ (q = !0, h.Cancel(), h.Queue(e))
- }
- var g = !1, q = !1, t = null, s = "$", k, i, o, l, n, m, h = MathJax.Hub;
- h.Queue(function() {
- g = !0;
- h.processUpdateTime = 50;
- h.Config({"HTML-CSS": {EqnChunk: 10,EqnChunkFactor: 1},SVG: {EqnChunk: 10,EqnChunkFactor: 1}})
- });
- /*benweet
- 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;
- r = 3 === "aba".split(/(b)/).length ? function(a, f) {
- return a.split(f)
- } : function(a, f) {
- var b = [], c;
- if (!f.global) {
- c = f.toString();
- var d = "";
- c = c.replace(/^\/(.*)\/([im]*)$/, function(a, c, b) {
- d = b;
- return c
- });
- f = RegExp(c, d + "g")
- }
- for (var e = f.lastIndex = 0; c = f.exec(a); )
- b.push(a.substring(e, c.index)), b.push.apply(b, c.slice(1)), e = c.index + c[0].length;
- b.push(a.substring(e));
- return b
- };
-
- (function() {
- var b = MathJax.Hub;
- if (!b.Cancel) {
- b.cancelTypeset = !1;
- b.Register.StartupHook("HTML-CSS Jax Config", function() {
- var d = MathJax.OutputJax["HTML-CSS"], e = d.Translate;
- d.Augment({Translate: function(j, g) {
- if (b.cancelTypeset || g.cancelled)
- throw Error("MathJax Canceled");
- return e.call(d, j, g)
- }})
- });
- b.Register.StartupHook("SVG Jax Config", function() {
- var d = MathJax.OutputJax.SVG, e = d.Translate;
- d.Augment({Translate: function(j, g) {
- if (b.cancelTypeset || g.cancelled)
- throw Error("MathJax Canceled");
- return e.call(d,
- j, g)
- }})
- });
- b.Register.StartupHook("TeX Jax Config", function() {
- var d = MathJax.InputJax.TeX, e = d.Translate;
- d.Augment({Translate: function(j, g) {
- if (b.cancelTypeset || g.cancelled)
- throw Error("MathJax Canceled");
- return e.call(d, j, g)
- }})
- });
- var p = b.processError;
- b.processError = function(d, e, j) {
- if ("MathJax Canceled" !== d.message)
- return p.call(b, d, e, j);
- MathJax.Message.Clear(0, 0);
- e.jaxIDs = [];
- e.jax = {};
- e.scripts = [];
- e.i = e.j = 0;
- e.cancelled = !0;
- return null
- };
- b.Cancel = function() {
- this.cancelTypeset = !0
- }
- }
- })();
- /*jshint ignore:end */
+ var converter = editorObject.getConverter();
+ converter.hooks.chain("preConversion", removeMath);
+ converter.hooks.chain("postConversion", replaceMath);
+ };
+
+ var afterRefreshCallback;
+ mathJax.onAsyncPreview = function(callback) {
+ afterRefreshCallback = callback;
+ UpdateMJ();
+ };
+
+ // From math.stackexchange.com...
+
+ //
+ // The math is in blocks i through j, so
+ // collect it into one block and clear the others.
+ // Replace &, <, and > by named entities.
+ // For IE, put
at the ends of comments since IE removes \n.
+ // Clear the current math positions and store the index of the
+ // math, then push the math string onto the storage array.
+ //
+ function processMath(i, j, unescape) {
+ var block = blocks.slice(i, j + 1).join("")
+ .replace(/&/g, "&")
+ .replace(//g, ">");
+ for(HUB.Browser.isMSIE && (block = block.replace(/(%[^\n]*)\n/g, "$1
\n")); j > i;)
+ blocks[j] = "", j--;
+ blocks[i] = "@@" + math.length + "@@";
+ unescape && (block = unescape(block));
+ math.push(block);
+ start = end = last = null;
+ }
+
+ function removeMath(text) {
+ start = end = last = null;
+ math = [];
+ var unescape;
+ if(/`/.test(text)) {
+ text = text.replace(/~/g, "~T").replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm, function(text) {
+ return text.replace(/\$/g, "~D")
+ });
+ unescape = function(text) {
+ return text.replace(/~([TD])/g,
+ function(match, n) {
+ return {T: "~", D: "$"}[n]
+ })
+ };
+ } else {
+ unescape = function(text) {
+ return text
+ };
+ }
+ blocks = split(text.replace(/\r\n?/g, "\n"), splitDelimiter);
+ 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)
+ }
+ } else {
+ if(block.match(/\n.*\n/)) {
+ 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]
+ });
+ math = null;
+ return text
+ }
+
+ //
+ // This is run to restart MathJax after it has finished
+ // the previous run (that may have been canceled)
+ //
+ function RestartMJ() {
+ pending = false;
+ HUB.cancelTypeset = false;
+ HUB.Queue([
+ "Typeset",
+ HUB,
+ preview
+ ]);
+ HUB.Queue(afterRefreshCallback); //benweet
+ }
+
+ //
+ // 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 ready = false, pending = false, preview = null, inline = "$", blocks, start, end, last, braces, math, HUB = MathJax.Hub;
+
+ //
+ // 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
+ Don't hash inline math $...$ (see https://github.com/benweet/stackedit/issues/136)
+ var u = /(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[\\{}$]|[{}]|(?:\n\s*)+|@@\d+@@)/i, r;
+ */
+
+
+ //
+ // 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;
+ if(!delimiter.global) {
+ c = delimiter.toString();
+ var d = "";
+ c = c.replace(/^\/(.*)\/([im]*)$/, function(a, c, b) {
+ d = b;
+ return c
+ });
+ delimiter = RegExp(c, d + "g")
+ }
+ for(var e = delimiter.lastIndex = 0; c = delimiter.exec(text);) {
+ b.push(text.substring(e, c.index));
+ b.push.apply(b, c.slice(1));
+ e = c.index + c[0].length;
+ }
+ b.push(text.substring(e));
+ return b
+ };
+ }
+
+ (function() {
+ var HUB = MathJax.Hub;
+ if(!HUB.Cancel) {
+ HUB.cancelTypeset = !1;
+ HUB.Register.StartupHook("HTML-CSS Jax Config", function() {
+ var HTMLCSS = MathJax.OutputJax["HTML-CSS"], TRANSLATE = HTMLCSS.Translate;
+ HTMLCSS.Augment({Translate: function(script, state) {
+ if(HUB.cancelTypeset || state.cancelled)
+ throw Error("MathJax Canceled");
+ return TRANSLATE.call(HTMLCSS, script, state)
+ }})
+ });
+ HUB.Register.StartupHook("SVG Jax Config", function() {
+ var SVG = MathJax.OutputJax.SVG, TRANSLATE = SVG.Translate;
+ SVG.Augment({Translate: function(script, state) {
+ if(HUB.cancelTypeset || state.cancelled)
+ throw Error("MathJax Canceled");
+ return TRANSLATE.call(SVG,
+ script, state)
+ }})
+ });
+ HUB.Register.StartupHook("TeX Jax Config", function() {
+ var TEX = MathJax.InputJax.TeX, TRANSLATE = TEX.Translate;
+ TEX.Augment({Translate: function(script, state) {
+ if(HUB.cancelTypeset || state.cancelled)
+ throw Error("MathJax Canceled");
+ return TRANSLATE.call(TEX, script, state)
+ }})
+ });
+ var PROCESSERROR = HUB.processError;
+ HUB.processError = function(error, state, type) {
+ if("MathJax Canceled" !== error.message)
+ return PROCESSERROR.call(HUB, error, state, type);
+ MathJax.Message.Clear(0, 0);
+ state.jaxIDs = [];
+ state.jax = {};
+ state.scripts = [];
+ state.i = state.j = 0;
+ state.cancelled = true;
+ return null
+ };
+ HUB.Cancel = function() {
+ this.cancelTypeset = true
+ }
+ }
+ })();
+ /*jshint ignore:end */
return mathJax;
});
\ No newline at end of file
diff --git a/public/res/html/dialogAbout.html b/public/res/html/dialogAbout.html
index 65c9acb1..87b475d5 100644
--- a/public/res/html/dialogAbout.html
+++ b/public/res/html/dialogAbout.html
@@ -36,7 +36,7 @@
Benoit Schweblin
Pete Eigel (contributor)
wiibaa (contributor)
- Daniel Hug (contributor)
+ Daniel Hug (contributor)
- StackEdit <%= version %> – Privacy Policy
Copyright 2013 Benoit
+ StackEdit <%= version %> – Privacy Policy
Copyright 2013-2014 Benoit
Schweblin
Licensed under an Apache
License