in[i+1].Text+in[i+2].Text == in[i+2].Text+in[i+1].Text {
in[i+2], in[i+1] = in[i+1], in[i+2]
}
+ // Likewise, diffmatchpatch solves
+ // diff("XXXA","XXAA") with [delX,=XXA,insA], we
+ // prefer [=XX,delX,insA,=A]
+ if i < len(in)-2 &&
+ d.Type == diffmatchpatch.DiffDelete &&
+ in[i+1].Type == diffmatchpatch.DiffEqual &&
+ in[i+2].Type == diffmatchpatch.DiffInsert {
+ redo := false
+ for x := len(d.Text); x <= len(in[i+1].Text)-len(in[i+2].Text); x++ {
+ // d in[i+1] in[i+2]
+ // x xxx aaa a
+ // ^
+ // x xx
+ // xxx
+ // aaa
+ // aa a
+ if d.Text+in[i+1].Text[:x-len(d.Text)] == in[i+1].Text[:x] &&
+ in[i+1].Text[x:] == in[i+1].Text[x+len(in[i+2].Text):]+in[i+2].Text {
+ out = append(out, diffmatchpatch.Diff{diffmatchpatch.DiffEqual, d.Text + in[i+1].Text[:x-len(d.Text)]})
+ in[i], in[i+1], in[i+2] = diffmatchpatch.Diff{diffmatchpatch.DiffDelete, in[i+1].Text[x-len(d.Text) : x]},
+ diffmatchpatch.Diff{diffmatchpatch.DiffInsert, in[i+1].Text[x : x+len(in[i+2].Text)]},
+ diffmatchpatch.Diff{diffmatchpatch.DiffEqual, in[i+1].Text[x+len(in[i+2].Text):] + in[i+2].Text}
+ redo = true
+ break
+ }
+ }
+ if redo {
+ i--
+ continue
+ }
+ }
// when diffmatchpatch says [delAAA, insXAY] and
// len(X)==1, we prefer to treat the A>X as a snp.
if i < len(in)-1 &&
i++
continue
}
+ // [=AB,insCB,=D] => [=A,insBC,=BD]
+ // and
+ // [=AB,delCB,=D] => [=A,delBC,=BD]
+ if i < len(in)-2 &&
+ d.Type == diffmatchpatch.DiffEqual &&
+ in[i+1].Type != diffmatchpatch.DiffEqual &&
+ in[i+2].Type == diffmatchpatch.DiffEqual &&
+ len(d.Text) > 0 && len(in[i+1].Text) > 0 &&
+ !(i+3 < len(in) &&
+ // Except: leave deletion alone if an
+ // upcoming insertion will be moved up
+ // against it: e.g., for
+ // [=AB,delCB,=D,insED] we want
+ // [=AB,delCB,=D,insED] for now, so it
+ // can become [=AB,delCB,insDE,=D] on
+ // the next iteration.
+ in[i+1].Type == diffmatchpatch.DiffDelete &&
+ in[i+3].Type == diffmatchpatch.DiffInsert &&
+ strings.HasSuffix(in[i+3].Text, in[i+2].Text)) {
+ if i+3 < len(in) && in[i+1].Type == in[i+3].Type && strings.HasSuffix(in[i+3].Text, in[i+2].Text) {
+ // [=AB,delC,=E,delDBE] => [=AB,delCEDB,=E,=]
+ in[i+1], in[i+2], in[i+3] = diffmatchpatch.Diff{in[i+1].Type, in[i+1].Text + in[i+2].Text + in[i+3].Text[:len(in[i+3].Text)-len(in[i+2].Text)]},
+ diffmatchpatch.Diff{diffmatchpatch.DiffEqual, in[i+2].Text},
+ diffmatchpatch.Diff{diffmatchpatch.DiffEqual, ""}
+ }
+ // Find x, length of common suffix B
+ x := 1
+ for ; x <= len(d.Text) && x <= len(in[i+1].Text); x++ {
+ if d.Text[len(d.Text)-x] != in[i+1].Text[len(in[i+1].Text)-x] {
+ break
+ }
+ }
+ x--
+ d.Text, in[i+1].Text, in[i+2].Text =
+ d.Text[:len(d.Text)-x],
+ d.Text[len(d.Text)-x:]+
+ in[i+1].Text[:len(in[i+1].Text)-x],
+ in[i+1].Text[len(in[i+1].Text)-x:]+in[i+2].Text
+ }
+ // [=X,delAX] => [delXA,=X]
+ if i < len(in)-1 &&
+ d.Type == diffmatchpatch.DiffEqual &&
+ in[i+1].Type == diffmatchpatch.DiffDelete && false {
+ }
out = append(out, d)
}
in, out = out, make([]diffmatchpatch.Diff, 0, len(in))