Action
Diff2
Posted by @galtenberg,
Last update
over 1 year ago
Compare 2 versions of current draft.
Shows time stamp and size of all versions.
Based on Diff action: https://directory.getdrafts.com/a/2J7
h/t: jsamlarose
Diff js via: http://ejohn.org/projects/javascript-diff-algorithm/
Steps
-
script
// Based on Diff action: https://directory.getdrafts.com/a/2J7 // h/t: jsamlarose //////////////////////////////////////////////////////////////////// // Diff js via: http://ejohn.org/projects/javascript-diff-algorithm/ function escape(s) { let n = s n = n.replace(/&/g, "&") n = n.replace(/</g, "<") n = n.replace(/>/g, ">") n = n.replace(/"/g, """) return n } function diffString(o, n) { o = o.replace(/\s+$/, '') n = n.replace(/\s+$/, '') let out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)) let str = "" let oSpace = o.match(/\s+/g) if (oSpace == null) oSpace = ["\n"] else oSpace.push("\n") let nSpace = n.match(/\s+/g) if (nSpace == null) nSpace = ["\n"] else nSpace.push("\n") if (out.n.length == 0) { for (var i = 0; i < out.o.length; i++) str += '<del>' + escape(out.o[i]) + oSpace[i] + "</del>" } else { if (out.n[0].text == null) { for (n = 0; n < out.o.length && out.o[n].text == null; n++) str += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>" } for (let i = 0; i < out.n.length; i++ ) { if (out.n[i].text == null) str += '<ins>' + escape(out.n[i]) + nSpace[i] + "</ins>" else { let pre = "" for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++ ) { pre += '<del>' + escape(out.o[n]) + oSpace[n] + "</del>" } str += " " + out.n[i].text + nSpace[i] + pre } } } return str } function randomColor() { return "rgb(" + (Math.random() * 100) + "%, " + (Math.random() * 100) + "%, " + (Math.random() * 100) + "%)" } function diffString2(o, n) { o = o.replace(/\s+$/, '') n = n.replace(/\s+$/, '') let out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/)) let oSpace = o.match(/\s+/g) if (oSpace == null) oSpace = ["\n"] else oSpace.push("\n") let nSpace = n.match(/\s+/g) if (nSpace == null) nSpace = ["\n"] else nSpace.push("\n") let os = "" let colors = new Array() for (let i = 0; i < out.o.length; i++) { colors[i] = randomColor() if (out.o[i].text != null) os += '<span style="background-color: ' +colors[i]+ '">' + escape(out.o[i].text) + oSpace[i] + "</span>" else os += "<del>" + escape(out.o[i]) + oSpace[i] + "</del>" } let ns = "" for (let i = 0; i < out.n.length; i++) { if (out.n[i].text != null) ns += '<span style="background-color: ' +colors[out.n[i].row]+ '">' + escape(out.n[i].text) + nSpace[i] + "</span>" else ns += "<ins>" + escape(out.n[i]) + nSpace[i] + "</ins>" } return { o: os, n: ns } } function diff(o, n) { let ns = new Object() let os = new Object() for (let i = 0; i < n.length; i++) { if (ns[n[i]] == null) ns[n[i]] = { rows: new Array(), o: null } ns[n[i]].rows.push(i) } for (let i = 0; i < o.length; i++) { if (os[o[i]] == null) os[o[i]] = { rows: new Array(), n: null } os[o[i]].rows.push(i) } for (let i in ns) { if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) { n[ns[i].rows[0]] = { text: n[ns[i].rows[0]], row: os[i].rows[0] } o[os[i].rows[0]] = { text: o[os[i].rows[0]], row: ns[i].rows[0] } } } for (let i = 0; i < n.length - 1; i++) { if (n[i].text != null && n[i+1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null && n[i+1] == o[n[i].row + 1] ) { n[i+1] = { text: n[i+1], row: n[i].row + 1 } o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 } } } for (let i = n.length - 1; i > 0; i--) { if (n[i].text != null && n[i-1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null && n[i-1] == o[n[i].row - 1]) { n[i-1] = { text: n[i-1], row: n[i].row - 1 } o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 } } } return { o, n } } //////////////////////////////////////////////////////////////////// const p = Prompt.create() p.title = "Diff2" p.addSelect( 'select', 'Select 2 versions to compare', draft.versions.map(v => `${v.createdAt.toISOString().split('.')[0]} (${v.content.length}c)`), [], true ) p.addButton('Diff') if (p.show()) { if (p.buttonPressed) { const versions = p.fieldValues['select'] if (versions.length === 2) { const mmd = GitHubMarkdown.create() mmd.safe = false mmd.unsafe = true const dates = [versions[0].split(" ")[0], versions[1].split(" ")[0]].sort() const v1 = draft.versions.find(v => v.createdAt.toISOString().split('.')[0] === dates[0]).content const v2 = draft.versions.find(v => v.createdAt.toISOString().split('.')[0] === dates[1]).content myDiff = diffString(v1, v2) myDiff = mmd.render(myDiff.replace(/\t/g, ' ')) draft.setTemplateTag("myDiff", myDiff) } // if (versions.length === 2) else context.cancel() } // if (p.buttonPressed) else context.cancel() } // if (p.show()) else context.cancel() if (device.model === "iPhone") app.hideActionList()
-
htmlpreview
<!DOCTYPE html> <html dir="auto"> <head> <title>Diff</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> @charset "utf-8"; :root { --del-color: #ff92bf; --ins-color: #b1f315; --main-bg-color: white; --main-color: black; --alternate-bg-color: #efefef; --alternate-color: #222222; --main-border-color: #BBBBBB; --link-color: #627EC9; } @media (prefers-color-scheme: dark) { :root { --main-bg-color: #222222; --main-color: #eeeeee; --alternate-bg-color: #444444; --alternate-color: #cccccc; --main-border-color: #AAAAAA; --link-color: #627EC9; } } html { font-size: 17px; font-family: Kohinoor Bangla, -apple-system, BlinkMacSystemFont, "helvetica neue", helvetica, roboto, noto, "segoe ui", arial, sans-serif; line-height: 1.6; -webkit-text-size-adjust: auto; background-color: var(--main-bg-color); overflow-x: hidden; } body { margin: 0 2vw; padding: 1em; background-color: var(--main-bg-color); color: var(--main-color); white-space: pre-wrap; overflow-x: hidden; } @media (max-device-width: 480px) { } @media (min-device-width: 481px) { body { margin:auto; max-width:700px; } } p { padding-top: 0; padding-bottom: 0; margin-top: 0; margin-bottom: 0; } ul, li { margin: 0; list-style: none; padding: 0; } ul { margin-top: -52px; margin-bottom: -1vmax; } li:before { content: "-"; margin-left: 0px; margin-right: 5px; } /* basic styles */ blockquote { font-style: italic; } a { color: var(--link-color); } pre { white-space: pre-wrap; display: block; overflow: scroll; width: 100%; background-color: var(--main-bg-color); padding: 0; margin: 0; font-family: Kohinoor Bangla; } code { background-color: var(--alternate-bg-color); color: var(--alternate-color); font-family: Menlo, Courier, sans-serif; padding: 0; } table { margin: 1.5em 0; border: 1px solid var(--main-border-color); border-collapse: collapse; } th { padding: .25em .5em; background: var(--alternate-bg-color); border: 1px solid var(--main-border-color); } td { padding: .25em .5em; border: 1px solid var(--main-border-color); } img { max-width: 90%; } /* end basic */ del { text-decoration: line-through; color: #ff92bf; } ins { background: #37b042; text-decoration: none; } </style> </head> <body> <div class="container"> [[myDiff]] </div> </body> </html>
Options
-
After Success Default Notification Error Log Level Error
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.