return d;
}
+ // First, note that deletion is just substition with nothing, so
+ // any DEL operation can be replaced by a SUB. Second, the
+ // operation code *is* the necessary slice offset for applying the
+ // diff.
+ var INS = 0, SUB = 1;
+
function editPath(costs, target) {
/** Given a cost matrix and a target, create an edit list */
var path = [];
var ins = j ? costs[n * i + j - 1] : Infinity;
if (sub <= ins && sub <= del) {
if (costs[n * i + j] !== costs[n * (i - 1) + j - 1])
- path.push(["sub", i - 1, target[j - 1]]);
+ path.push([SUB, i - 1, target[j - 1]]);
--i; --j;
} else if (ins <= del) {
- path.push(["ins", i, target[j - 1]]);
+ path.push([INS, i, target[j - 1]]);
--j;
} else {
- path.push(["del", i - 1]);
+ path.push([SUB, i - 1, ""]);
--i;
}
}
return editPath(costMatrix(source, target, ins, del, sub), target);
}
- function patch(edits, s) {
+ function patch(diff, source) {
/** Apply the list of edits to s */
var edit;
var i;
- if (Array.isArray(s)) {
- for (i = 0; i < edits.length; ++i) {
- edit = edits[i];
- switch (edit[0]) {
- case "sub":
- s[edit[1]] = edit[2];
- break;
- case "ins":
- s.splice(edit[1], 0, edit[2]);
- break;
- case "del":
- s.splice(edit[1], 1);
- break;
- }
+ if (Array.isArray(source)) {
+ for (i = 0; i < diff.length; ++i) {
+ edit = diff[i];
+ source.splice(edit[1], edit[0], edit[2]);
}
} else {
- for (i = 0; i < edits.length; ++i) {
- edit = edits[i];
- switch (edit[0]) {
- case "sub":
- s = s.slice(0, edit[1]) + edit[2] + s.slice(edit[1] + 1);
- break;
- case "ins":
- s = s.slice(0, edit[1]) + edit[2] + s.slice(edit[1]);
- break;
- case "del":
- s = s.slice(0, edit[1]) + s.slice(edit[1] + 1);
- break;
- }
+ for (i = 0; i < diff.length; ++i) {
+ edit = diff[i];
+ var head = source.slice(0, edit[1]);
+ var tail = source.slice(edit[1] + edit[0]);
+ source = head + edit[2] + tail;
}
}
- return s;
+ return source;
}
var MULTI = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\u0300-\u036F\u1DC0-\u1DFF\u20D0-\u20FF\uFE20-\uFE2F]/;