From f4e3be9847a45e2e8743fa1797ca341badac481a Mon Sep 17 00:00:00 2001 From: danpros Date: Thu, 4 Mar 2021 12:48:14 +0700 Subject: [PATCH] Add striketrough and table --- system/admin/editor/js/Markdown.Editor.js | 245 ++++++++++++++++++++++++++++-- 1 file changed, 233 insertions(+), 12 deletions(-) diff --git a/system/admin/editor/js/Markdown.Editor.js b/system/admin/editor/js/Markdown.Editor.js index 56bc641..38d6037 100644 --- a/system/admin/editor/js/Markdown.Editor.js +++ b/system/admin/editor/js/Markdown.Editor.js @@ -23,6 +23,9 @@ italic: "Emphasis Ctrl+I", italicexample: "emphasized text", + + strikethrough: "Strikethrough Ctrl+X", + strikethroughexample: "strikethrough text", link: "Hyperlink Ctrl+L", linkdescription: "enter link description here", @@ -48,6 +51,8 @@ hr: "Horizontal Rule
Ctrl+R", readmore: "Read More Ctrl+M", + + table: "Table - Ctrl+T", undo: "Undo - Ctrl+Z", redo: "Redo - Ctrl+Y", @@ -1287,6 +1292,12 @@ case "m": doClick(buttons.readmore); break; + case "x": + doClick(buttons.strikethrough); + break; + case "j": + doClick(buttons.table); + break; case "y": doClick(buttons.redo); break; @@ -1471,26 +1482,28 @@ buttons.bold = makeButton("wmd-bold-button", getString("bold"), "fa fa-bold", bindCommand("doBold")); buttons.italic = makeButton("wmd-italic-button", getString("italic"), "fa fa-italic", bindCommand("doItalic")); - makeSpacer(1); - buttons.link = makeButton("wmd-link-button", getString("link"), "fa fa-link", bindCommand(function (chunk, postProcessing) { - return this.doLinkOrImage(chunk, postProcessing, false); - })); - buttons.quote = makeButton("wmd-quote-button", getString("quote"), "fa fa-quote-right", bindCommand("doBlockquote")); - buttons.code = makeButton("wmd-code-button", getString("code"), "fa fa-code", bindCommand("doCode")); - buttons.image = makeButton("wmd-image-button", getString("image"), "fa fa-image", bindCommand(function (chunk, postProcessing) { - return this.doLinkOrImage(chunk, postProcessing, true); - })); - makeSpacer(2); + buttons.heading = makeButton("wmd-heading-button", getString("heading"), "fa fa-header", bindCommand("doHeading")); + buttons.strikethrough = makeButton("wmd-strikethrough-button", getString("strikethrough"), "fa fa-strikethrough", bindCommand("doStrikethrough")); + //makeSpacer(1); buttons.olist = makeButton("wmd-olist-button", getString("olist"), "fa fa-list-ol", bindCommand(function (chunk, postProcessing) { this.doList(chunk, postProcessing, true); })); buttons.ulist = makeButton("wmd-ulist-button", getString("ulist"), "fa fa-list-ul", bindCommand(function (chunk, postProcessing) { this.doList(chunk, postProcessing, false); })); - buttons.heading = makeButton("wmd-heading-button", getString("heading"), "fa fa-header", bindCommand("doHeading")); + buttons.quote = makeButton("wmd-quote-button", getString("quote"), "fa fa-quote-right", bindCommand("doBlockquote")); + buttons.code = makeButton("wmd-code-button", getString("code"), "fa fa-code", bindCommand("doCode")); + buttons.table = makeButton("wmd-table-button", getString("table"), "fa fa-table", bindCommand("doTable")); + //makeSpacer(2); + buttons.link = makeButton("wmd-link-button", getString("link"), "fa fa-link", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, false); + })); + buttons.image = makeButton("wmd-image-button", getString("image"), "fa fa-image", bindCommand(function (chunk, postProcessing) { + return this.doLinkOrImage(chunk, postProcessing, true); + })); buttons.hr = makeButton("wmd-hr-button", getString("hr"), "fa fa-ellipsis-h", bindCommand("doHorizontalRule")); buttons.readmore = makeButton("wmd-readmore-button", getString("readmore"), "fa fa-arrow-right", bindCommand("doReadMore")); - makeSpacer(3); + //makeSpacer(3); buttons.undo = makeButton("wmd-undo-button", getString("undo"), "fa fa-undo", null); buttons.undo.execute = function (manager) { if (manager) manager.undo(); @@ -2225,6 +2238,214 @@ chunk.selection = ""; chunk.skipLines(0, 1, true); } + + commandProto.doStrikethrough = function (chunk, postProcessing) { + + // Get rid of whitespace and fixup newlines. + chunk.trimWhitespace(); + chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n"); + + // Look for stars before and after. Is the chunk already marked up? + // note that these regex matches cannot fail + var starsBefore = /(~*$)/.exec(chunk.before)[0]; + var starsAfter = /(^~*)/.exec(chunk.after)[0]; + + var prevStars = Math.min(starsBefore.length, starsAfter.length); + + var nStars = 2; + + // Remove stars if we have to since the button acts as a toggle. + if ((prevStars >= nStars) && (prevStars != 2 || nStars != 1)) { + chunk.before = chunk.before.replace(re("[~]{" + nStars + "}$", ""), ""); + chunk.after = chunk.after.replace(re("^[~]{" + nStars + "}", ""), ""); + } else if (!chunk.selection && starsAfter) { + // It's not really clear why this code is necessary. It just moves + // some arbitrary stuff around. + chunk.after = chunk.after.replace(/^(~*)/, ""); + chunk.before = chunk.before.replace(/(\s?)$/, ""); + var whitespace = re.$1; + chunk.before = chunk.before + starsAfter + whitespace; + } else { + + // In most cases, if you don't have any selected text and click the button + // you'll get a selected, marked up region with the default text inserted. + if (!chunk.selection && !starsAfter) { + chunk.selection = this.getString("strikethroughexample"); + } + + // Add the true markup. + var markup = "~~"; // shouldn't the test be = ? + chunk.before = chunk.before + markup; + chunk.after = markup + chunk.after; + } + + return; + }; + + commandProto.doTable = function (chunk) { + // Credit: https://github.com/fcrespo82/atom-markdown-table-formatter + + var keepFirstAndLastPipes = true, + /* + ( # header capture + (?: + (?:[^\n]*?\|[^\n]*) # line w/ at least one pipe + \ * # maybe trailing whitespace + )? # maybe header + (?:\n|^) # newline + ) + ( # format capture + (?: + \|\ *:?-+:?\ * # format starting w/pipe + |\|?(?:\ *:?-+:?\ *\|)+ # or separated by pipe + ) + (?:\ *:?-+:?\ *)? # maybe w/o trailing pipe + \ * # maybe trailing whitespace + \n # newline + ) + ( # body capture + (?: + (?:[^\n]*?\|[^\n]*) # line w/ at least one pipe + \ * # maybe trailing whitespace + (?:\n|$) # newline + )+ # at least one + ) + */ + regex = /((?:(?:[^\n]*?\|[^\n]*) *)?(?:\r?\n|^))((?:\| *:?-+:? *|\|?(?: *:?-+:? *\|)+)(?: *:?-+:? *)? *\r?\n)((?:(?:[^\n]*?\|[^\n]*) *(?:\r?\n|$))+)/; + + + function padding(len, str) { + var result = ''; + str = str || ' '; + len = Math.floor(len); + for (var i = 0; i < len; i++) { + result += str; + } + return result; + } + + function stripTailPipes(str) { + return str.trim().replace(/(^\||\|$)/g, ""); + } + + function splitCells(str) { + return str.split('|'); + } + + function addTailPipes(str) { + if (keepFirstAndLastPipes) { + return "|" + str + "|"; + } else { + return str; + } + } + + function joinCells(arr) { + return arr.join('|'); + } + + function formatTable(text, appendNewline) { + var i, j, len1, ref1, ref2, ref3, k, len2, results, formatline, headerline, just, formatrow, data, line, lines, justify, cell, cells, first, last, ends, columns, content, widths, formatted, front, back; + formatline = text[2].trim(); + headerline = text[1].trim(); + ref1 = headerline.length === 0 ? [0, text[3]] : [1, text[1] + text[3]], formatrow = ref1[0], data = ref1[1]; + lines = data.trim().split('\n'); + justify = []; + ref2 = splitCells(stripTailPipes(formatline)); + for (j = 0, len1 = ref2.length; j < len1; j++) { + cell = ref2[j]; + ref3 = cell.trim(), first = ref3[0], last = ref3[ref3.length - 1]; + switch ((ends = (first ? first : ':') + (last ? last : ''))) { + case '::': + case '-:': + case ':-': + justify.push(ends); + break; + default: + justify.push('--'); + } + } + columns = justify.length; + content = []; + for (j = 0, len1 = lines.length; j < len1; j++) { + line = lines[j]; + cells = splitCells(stripTailPipes(line)); + cells[columns - 1] = joinCells(cells.slice(columns - 1)); + results = []; + for (k = 0, len2 = cells.length; k < len2; k++) { + cell = cells[k]; + results.push(padding(' ') + ((ref2 = cell ? typeof cell.trim === "function" ? cell.trim() : void 0 : void 0) ? ref2 : '') + padding(' ')); + } + content.push(results); + } + widths = []; + for (i = j = 0, ref2 = columns - 1; 0 <= ref2 ? j <= ref2 : j >= ref2; i = 0 <= ref2 ? ++j : --j) { + results = []; + for (k = 0, len1 = content.length; k < len1; k++) { + cells = content[k]; + results.push(cells[i].length); + } + widths.push(Math.max.apply(Math, [2].concat(results))); + } + just = function (string, col) { + var back, front, length; + length = widths[col] - string.length; + switch (justify[col]) { + case '::': + front = padding[0], back = padding[1]; + return padding(length / 2) + string + padding((length + 1) / 2); + case '-:': + return padding(length) + string; + default: + return string + padding(length); + } + }; + formatted = []; + for (j = 0, len1 = content.length; j < len1; j++) { + cells = content[j]; + results = []; + for (i = k = 0, ref2 = columns - 1; 0 <= ref2 ? k <= ref2 : k >= ref2; i = 0 <= ref2 ? ++k : --k) { + results.push(just(cells[i], i)); + } + formatted.push(addTailPipes(joinCells(results))); + } + formatline = addTailPipes(joinCells((function () { + var j, ref2, ref3, results; + results = []; + for (i = j = 0, ref2 = columns - 1; 0 <= ref2 ? j <= ref2 : j >= ref2; i = 0 <= ref2 ? ++j : --j) { + ref3 = justify[i], front = ref3[0], back = ref3[1]; + results.push(front + padding(widths[i] - 2, '-') + back); + } + return results; + })())); + formatted.splice(formatrow, 0, formatline); + var result = (headerline.length === 0 && text[1] !== '' ? '\n' : '') + formatted.join('\n'); + if (appendNewline !== false) { + result += '\n' + } + return result; + } + + if (chunk.before.slice(-1) !== '\n') { + chunk.before += '\n'; + } + var match = chunk.selection.match(regex); + if (match) { + chunk.selection = formatTable(match, chunk.selection.slice(-1) === '\n'); + } else { + var table = chunk.selection + '|\n-|-\n|'; + match = table.match(regex); + if (!match || match[0].slice(0, table.length) !== table) { + return; + } + table = formatTable(match); + var selectionOffset = keepFirstAndLastPipes ? 1 : 0; + var pipePos = table.indexOf('|', selectionOffset); + chunk.before += table.slice(0, selectionOffset); + chunk.selection = table.slice(selectionOffset, pipePos); + chunk.after = table.slice(pipePos) + chunk.after; + } + }; })(); \ No newline at end of file