function diff(str1, str2) { const dmp = new DiffMatchPatch(); const diff = dmp.diff_main(str1, str2); dmp.diff_cleanupSemantic(diff); return diff.reduce((res, [ flag, part ]) => { const text = flag === 0 ? part : part.replace('\n', 'ΒΆ\n'); return res + COLOR[flag](text); }, ''); }
function html_diff (a, b) { var diff = dmp.diff_main(b, a); dmp.diff_cleanupSemantic(diff); var ret = '', tag; diff.forEach(function(chunk){ switch (chunk[0]) { case 0: tag = 'span'; break; case 1: tag = 'ins'; break; case -1: tag = 'del'; break; } ret += '<'+tag+'>' + chunk[1] + '</'+tag+'>'; }); return ret; }
function check_win(data) { var player = data.player; var text = data.text; if (text === null) return false; var diffs = dmp.diff_main(text, target); console.log("Player " + player); console.log(diffs); // win condition if (diffs.length === 1 && diffs[0][0] === 0 && won === false) { return player; } }
exports.from_diff = function(old_value, new_value, mode, global_order) { // Do a diff, which results in an array of operations of the form // (op_type, op_data) // where // op_type == 0 => text same on both sides // op_type == -1 => text deleted (op_data is deleted text) // op_type == +1 => text inserted (op_data is inserted text) // If mode is undefined or 'chars', the diff is performed over // characters. Mode can also be 'words' or 'lines'. var diff_match_patch = require('googlediff'); var base = require(__dirname + "/base.js"); var dmp = new diff_match_patch(); ///////////////////////////////////////////////////////////// // adapted from diff_match_patch.prototype.diff_linesToChars_ function diff_tokensToChars_(text1, text2, split_regex) { var lineArray = []; var lineHash = {}; lineArray[0] = ''; function munge(text) { var chars = ''; var lineStart = 0; var lineEnd = -1; var lineArrayLength = lineArray.length; while (lineEnd < text.length - 1) { split_regex.lastIndex = lineStart; var m = split_regex.exec(text); if (m) lineEnd = m.index; else lineEnd = text.length - 1; var line = text.substring(lineStart, lineEnd + 1); lineStart = lineEnd + 1; if (lineHash.hasOwnProperty ? lineHash.hasOwnProperty(line) : (lineHash[line] !== undefined)) { chars += String.fromCharCode(lineHash[line]); } else { chars += String.fromCharCode(lineArrayLength); lineHash[line] = lineArrayLength; lineArray[lineArrayLength++] = line; } } return chars; } var chars1 = munge(text1); var chars2 = munge(text2); return {chars1: chars1, chars2: chars2, lineArray: lineArray}; } ///////////////////////////////////////////////////////////// // handle words or lines mode var token_state = null; if (mode == "words") token_state = diff_tokensToChars_(old_value, new_value, /[\W]/g); if (mode == "lines") token_state = diff_tokensToChars_(old_value, new_value, /\n/g); var t1 = old_value; var t2 = new_value; if (token_state) { t1 = token_state.chars1; t2 = token_state.chars2; } // perform the diff var d = dmp.diff_main(t1, t2); // handle words or lines mode if (token_state) dmp.diff_charsToLines_(d, token_state.lineArray); dmp.diff_cleanupSemantic(d); // turn the output into an array of DEL and INS operations var ret = []; var pos = 0; for (var i = 0; i < d.length; i++) { if (d[i][0] == 0) { pos += d[i][1].length; } else if (d[i][0] == -1) { ret.push(exports.DEL(pos, d[i][1], global_order)); // don't increment pos because next operation sees the string with this part deleted } else if (d[i][0] == 1) { ret.push(exports.INS(pos, d[i][1], global_order)); pos += d[i][1].length; } } return base.normalize_array(ret); }
/** * Generates diff data for the given strings. The diff data is cleaned up so as * to be suitable for display to a human. * * @param {string} left * @param {string} right * @return {Array.<[number, string]>} */ function diff(left, right) { var differ = new Diff(); var diffs = differ.diff_main(left, right); differ.diff_cleanupSemantic(diffs); return colorizeDiffs(diffs); }