func Edit(db *gorp.DbMap, w WikiPage) (WikiPage, bool) { if w.Id == 0 { db.Insert(&w) } else { wOld, ok := GetBySlug(db, w.Title) if !ok { return WikiPage{}, false } textOld := string(wOld.Body) textNew := string(w.Body) d := diffmatchpatch.New() b := d.DiffMain(textNew, textOld, false) dl := d.DiffToDelta(b) delta := WikiDelta{ ItemId: w.Id, PrevDelta: w.PrevDelta, Delta: []byte(dl), } db.Insert(&delta) w.PrevDelta = delta.Id db.Update(&w) } return w, true }
func writeDiffHTML(out *bytes.Buffer, from, to, header string) { dmp := diffmatchpatch.New() diff := dmp.DiffMain(from, to, true) diff = dmp.DiffCleanupSemantic(diff) out.WriteString("<h1>" + html.EscapeString(header) + "</h1>\n<pre>") // write the diff for _, chunk := range diff { txt := html.EscapeString(chunk.Text) txt = strings.Replace(txt, "\n", "↩\n", -1) switch chunk.Type { case diffmatchpatch.DiffInsert: out.WriteString(`<ins style="background:#e6ffe6;">`) out.WriteString(txt) out.WriteString(`</ins>`) case diffmatchpatch.DiffDelete: out.WriteString(`<del style="background:#ffe6e6;">`) out.WriteString(txt) out.WriteString(`</del>`) case diffmatchpatch.DiffEqual: out.WriteString(`<span>`) out.WriteString(txt) out.WriteString(`</span>`) } } if out.Len() > MaxDetailsLen { out.Truncate(MaxDetailsLen) out.WriteString("\n\n[TRUNCATED]") } out.WriteString("</pre>") }
func CompareGotExpected(t *testing.T, err error, got, expected interface{}) { if reflect.DeepEqual(got, expected) { return } t.Logf("got:\n%v", got) t.Logf("expected:\n%v", expected) differ := diffmatchpatch.New() diff := differ.DiffMain(fmt.Sprintf("%+v", expected), fmt.Sprintf("%+v", got), true) var diffout string for _, line := range diff { switch line.Type { case diffmatchpatch.DiffDelete: diffout += fmt.Sprintf("\033[32m%v\033[0m", line.Text) case diffmatchpatch.DiffInsert: diffout += fmt.Sprintf("\033[31m%v\033[0m", line.Text) default: diffout += line.Text } } t.Logf("diff:\n%v", diffout) t.Fatal("got is not like expected") }
// Do computes the (line oriented) modifications needed to turn the src // string into the dst string. func Do(src, dst string) (diffs []diffmatchpatch.Diff) { dmp := diffmatchpatch.New() wSrc, wDst, warray := dmp.DiffLinesToChars(src, dst) diffs = dmp.DiffMain(wSrc, wDst, false) diffs = dmp.DiffCharsToLines(diffs, warray) return diffs }
func lineDiff(src1, src2 *string) []diffmatchpatch.Diff { dmp := diffmatchpatch.New() a, b, c := dmp.DiffLinesToChars(*src1, *src2) diffs := dmp.DiffMain(a, b, false) result := dmp.DiffCharsToLines(diffs, c) return result }
func (this *highlightedDiff) Update() { left := this.GetSources()[0].(caret.MultilineContentI) right := this.GetSources()[1].(caret.MultilineContentI) dmp := diffmatchpatch.New() diffs := dmp.DiffMain(left.Content(), right.Content(), true) for side := range this.segments { this.segments[side] = nil offset := uint32(0) for _, diff := range diffs { if side == 0 && diff.Type == -1 { this.segments[side] = append(this.segments[side], highlightSegment{offset: offset, color: mediumRedColor}) offset += uint32(len(diff.Text)) } if side == 1 && diff.Type == +1 { this.segments[side] = append(this.segments[side], highlightSegment{offset: offset, color: mediumGreenColor}) offset += uint32(len(diff.Text)) } if diff.Type == 0 { this.segments[side] = append(this.segments[side], highlightSegment{offset: offset}) offset += uint32(len(diff.Text)) } } // HACK: Fake last element. if side == 0 { this.segments[side] = append(this.segments[side], highlightSegment{offset: uint32(left.LenContent())}) } else { this.segments[side] = append(this.segments[side], highlightSegment{offset: uint32(right.LenContent())}) } } }
func (p *CowyoData) save(newText string) error { if !open { return fmt.Errorf("db must be opened before saving") } err := db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte("datas")) if err != nil { return fmt.Errorf("create bucket: %s", err) } // find diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(p.CurrentText, newText, true) delta := dmp.DiffToDelta(diffs) p.CurrentText = newText p.Timestamps = append(p.Timestamps, time.Now().Format(time.ANSIC)) p.Diffs = append(p.Diffs, delta) enc, err := p.encode() if err != nil { return fmt.Errorf("could not encode CowyoData: %s", err) } err = bucket.Put([]byte(p.Title), enc) return err }) return err }
func main() { // Read whole file as string inbyte, err := ioutil.ReadFile("text1.txt") if err != nil { panic(err) } text1 := string(inbyte[:]) inbyte, err = ioutil.ReadFile("text2.txt") if err != nil { panic(err) } text2 := string(inbyte[:]) // Check diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(text1, text2, false) // Make patch patch := dmp.PatchMake(text1, diffs) // Print patch to see the results before they're applied fmt.Println(dmp.PatchToText(patch)) // Apply patch text3, _ := dmp.PatchApply(patch, text1) // Write the patched text to a new file err = ioutil.WriteFile("text3.txt", []byte(text3), 0644) if err != nil { panic(err) } }
func diffBackup(store configstore.Store, w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) t1, err := time.Parse(file.DefaultDateFormat, vars["date1"]) if err != nil { log.Printf("Error: %s", err) http.Error(w, "error :(", 500) return } t2, err := time.Parse(file.DefaultDateFormat, vars["date2"]) if err != nil { log.Printf("Error: %s", err) http.Error(w, "error :(", 500) return } e1 := configstore.Entry{ Name: vars["hostname"], Date: t1, } e2 := configstore.Entry{ Name: vars["hostname"], Date: t2, } err = store.Get(&e1) if err != nil { log.Printf("Error: %s", err) http.Error(w, "error :(", 500) return } err = store.Get(&e2) if err != nil { log.Printf("Error: %s", err) http.Error(w, "error :(", 500) return } dmp := diffmatchpatch.New() diffs := dmp.DiffMain(e1.Content.String(), e2.Content.String(), true) em := struct { Hostname string Date1 time.Time Date2 time.Time Diff string }{ vars["hostname"], t1, t2, dmp.DiffPrettyHtml(diffs), } io.WriteString(w, mustache.RenderFileInLayout("templates/diff.html.mustache", "templates/layout.html.mustache", em)) }
func diff(a, b string) []diffmatchpatch.Diff { dmp := diffmatchpatch.New() diffs := dmp.DiffMain(a, b, true) if len(diffs) > 2 { diffs = dmp.DiffCleanupSemantic(diffs) diffs = dmp.DiffCleanupEfficiency(diffs) } return diffs }
func main() { var text1 string = "hej" var text2 string = "hejj" var dmp = diffmatchpatch.New() var diffs = dmp.DiffMain(text1, text2, false) fmt.Println("%s", diffs) }
func (self *SanityTest) TestDiffShow(c *Case) { state := dmp.New() diffs := state.DiffMain("aaabdef", "aaacdef1", false) c.AssertEquals(dmp.Diff{dmp.DiffEqual, "aaa"}, diffs[0]) c.AssertEquals(dmp.Diff{dmp.DiffDelete, "b"}, diffs[1]) c.AssertEquals(dmp.Diff{dmp.DiffInsert, "c"}, diffs[2]) c.AssertEquals(dmp.Diff{dmp.DiffEqual, "def"}, diffs[3]) c.AssertEquals(dmp.Diff{dmp.DiffInsert, "1"}, diffs[4]) }
func getImportantVersions(p CowyoData) []versionsInfo { m := map[int]int{} dmp := diffmatchpatch.New() lastText := "" lastTime := time.Now().AddDate(0, -1, 0) for i, diff := range p.Diffs { seq1, _ := dmp.DiffFromDelta(lastText, diff) texts_linemode := diffRebuildtexts(seq1) rebuilt := texts_linemode[len(texts_linemode)-1] parsedTime, _ := time.Parse(time.ANSIC, p.Timestamps[i]) duration := parsedTime.Sub(lastTime) m[i] = int(duration.Seconds()) if i > 0 { m[i-1] = m[i] } // On to the next one lastText = rebuilt lastTime = parsedTime } // Sort in order of decreasing diff times n := map[int][]int{} var a []int for k, v := range m { n[v] = append(n[v], k) } for k := range n { a = append(a, k) } sort.Sort(sort.Reverse(sort.IntSlice(a))) // Get the top 4 biggest diff times var importantVersions []int var r []versionsInfo for _, k := range a { for _, s := range n[k] { if s != 0 && s != len(n) { fmt.Printf("%d, %d\n", s, k) importantVersions = append(importantVersions, s) if len(importantVersions) > 10 { sort.Ints(importantVersions) for _, nn := range importantVersions { r = append(r, versionsInfo{p.Timestamps[nn], nn}) } return r } } } } sort.Ints(importantVersions) for _, nn := range importantVersions { r = append(r, versionsInfo{p.Timestamps[nn], nn}) } return r }
func reportOnFileWatch(fw *FileWatch) { file, err := os.Open(fw.Source) if err != nil { //TODO report that the file is not there } else { changes := []Change{} fileInfo, _ := file.Stat() // If the cached size is greater than the live size // it means the file has lost content. This is not common behavior // for a log file, and that iss what we are concerned about. So... (for now at least) // we are going to reset the cached content. Meaning that the diff will include all that // is in the file. if fw.Size() > fileInfo.Size() { fw.SetContent([]byte{}) } if fw.Size() != fileInfo.Size() { fileBytes := GatherBytes(fw.Source) dmp := diffmatchpatch.New() diffs := dmp.DiffMain(string(fw.Content()), string(fileBytes), true) for _, x := range diffs { if x.Type == 1 { if fw.Lines { for _, i := range SplitByLine(x.Text) { changes = append(changes, NewChange(fw, i)) } } else { changes = append(changes, NewChange(fw, x.Text)) } } } fw.SetContent(fileBytes) } fw.SetSize(fileInfo.Size()) for _, i := range changes { if strings.Trim(i.Content, trimset) != "" { jsondChange, err := json.Marshal(i) if err != nil { fmt.Println(err) } else { fmt.Println(string(jsondChange)) } } } } }
func rebuildTextsToDiffN(p WikiData, n int) string { dmp := diffmatchpatch.New() lastText := "" for i, diff := range p.Diffs { seq1, _ := dmp.DiffFromDelta(lastText, diff) textsLinemode := diffRebuildtexts(seq1) rebuilt := textsLinemode[len(textsLinemode)-1] if i == n { return rebuilt } lastText = rebuilt } return "ERROR" }
// ErrorWithDiff is like test.Error with a textual diff between the 2 results func ErrorWithDiff(t Tester, got, want interface{}, comments ...string) { var comment string if want != got { if len(comments) > 0 { comment = comments[0] } else { comment = "Expect" } _, file, line, _ := runtime.Caller(1) diff := diffmatchpatch.New() gotDiffed := diff.DiffPrettyText(diff.DiffMain(fmt.Sprintf("%+v", want), fmt.Sprintf("%+v", got), false)) t.Errorf(template, comment, file, line, want, gotDiffed) } }
// DiffVersions compares to structs and returns the result as html. // The html can be displayed with utils.OpenInBrowser() func DiffVersions(versionA interface{}, versionB interface{}) (string, error) { jsonA, err := json.MarshalIndent(versionA, "", " ") if err != nil { return "", err } jsonB, err := json.MarshalIndent(versionB, "", " ") if err != nil { return "", err } d := diffmatchpatch.New() diffs := d.DiffMain(string(jsonA), string(jsonB), false) html := d.DiffPrettyHtml(diffs) return html, nil }
func showDiff(oldText, newText string) { dmp := diffmatchpatch.New() diffs := dmp.DiffMain(oldText, newText, true) for _, diff := range diffs { switch diff.Type { case diffmatchpatch.DiffInsert: color := gocolorize.NewColor("green") printLinesWithPrefix(color.Paint("+"), diff.Text) case diffmatchpatch.DiffDelete: color := gocolorize.NewColor("red") printLinesWithPrefix(color.Paint("-"), diff.Text) } } }
func difference(slice1, slice2 []string) { var dmp = diffmatchpatch.New() str1 := string(slice2[:]) str2 := string(slice1[:]) var diff = dmp.DiffMain(str1, str2, false) // if there is some changes made return them. If not return stored document. if diff != 1 { return diff } return slice1 }
// Diff returns a diff string indiciating edits with ANSI color encodings // (red for deletions, green for additions). func Diff(a, b interface{}) string { d := dmp.New() diffs := d.DiffMain(fmt.Sprintf("%+v", a), fmt.Sprintf("%+v", b), true) var buff bytes.Buffer for _, d := range diffs { switch d.Type { case dmp.DiffDelete: buff.WriteString(ansi.Color(d.Text, "red")) case dmp.DiffInsert: buff.WriteString(ansi.Color(d.Text, "green")) case dmp.DiffEqual: buff.WriteString(d.Text) } } return buff.String() }
func (differ *Differ) compareValues( position Position, left interface{}, right interface{}, ) (same bool, delta Delta) { if reflect.TypeOf(left) != reflect.TypeOf(right) { return false, NewModified(position, left, right) } switch left.(type) { case map[string]interface{}: l := left.(map[string]interface{}) childDeltas := differ.compareMaps(l, right.(map[string]interface{})) if len(childDeltas) > 0 { return false, NewObject(position, childDeltas) } case []interface{}: l := left.([]interface{}) childDeltas := differ.compareArrays(l, right.([]interface{})) if len(childDeltas) > 0 { return false, NewArray(position, childDeltas) } default: if !reflect.DeepEqual(left, right) { if reflect.ValueOf(left).Kind() == reflect.String && reflect.ValueOf(right).Kind() == reflect.String && differ.textDiffMinimumLength <= len(left.(string)) { textDiff := dmp.New() patchs := textDiff.PatchMake(left.(string), right.(string)) return false, NewTextDiff(position, patchs, left, right) } else { return false, NewModified(position, left, right) } } } return true, nil }
func Diff(src1, src2 string) (s string) { dmp := diffmatchpatch.New() a, b, c := dmp.DiffLinesToChars(src1, src2) diffs := dmp.DiffMain(a, b, false) lines := dmp.DiffCharsToLines(diffs, c) var ls []string for _, line := range lines { switch line.Type { case diffmatchpatch.DiffDelete: ls = append(ls, prefix("- ", line.Text)) case diffmatchpatch.DiffInsert: ls = append(ls, prefix("+ ", line.Text)) } } s = strings.Join(ls, "\n") return }
func (p *WikiData) save(newText string) error { if !open { Open(RuntimeArgs.DatabaseLocation) defer Close() } err := db.Update(func(tx *bolt.Tx) error { bucket, err := tx.CreateBucketIfNotExists([]byte("datas")) if err != nil { return fmt.Errorf("create bucket: %s", err) } // find diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(p.CurrentText, newText, true) delta := dmp.DiffToDelta(diffs) p.CurrentText = newText p.Timestamps = append(p.Timestamps, time.Now().Format(time.ANSIC)) p.Diffs = append(p.Diffs, delta) enc, err := p.encode() if err != nil { return fmt.Errorf("could not encode WikiData: %s", err) } p.Title = strings.ToLower(p.Title) err = bucket.Put([]byte(p.Title), enc) if err != nil { return fmt.Errorf("could add to bucket: %s", err) } return err }) // // Add the new name to the programdata so its not randomly generated // if err == nil && len(p.Timestamps) > 0 && len(p.CurrentText) > 0 { // err2 := db.Update(func(tx *bolt.Tx) error { // b := tx.Bucket([]byte("programdata")) // id, _ := b.NextSequence() // idInt := int(id) // return b.Put(itob(idInt), []byte(p.Title)) // }) // if err2 != nil { // return fmt.Errorf("could not add to programdata: %s", err) // } // } return err }
func differances(text string, clientBackup *backup, clientShadow *shadow) { clientShadowLocalVersion := shadow{shadowLocalVersion: 0} //Check diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(clientShadow.shadowstring, text, false) if len(diffs) == 1 { // no diffs return } dmp.DiffCleanupEfficiency(diffs) // Make patch patch := dmp.PatchMake(clientShadow.shadowstring, diffs) fmt.Println(dmp.PatchToText(patch)) result := dmp.PatchToText(patch) clientShadow.shadowstring = text clientShadowLocalVersion.shadowLocalVersion++ /*// Check diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(text1, text2, false) // Make patch patch := dmp.PatchMake(text1, diffs) // Print patch to see the results before they're applied fmt.Println(dmp.PatchToText(patch)) result := dmp.PatchToText(patch) // detta sker efter att vi har mottagit från klienten! // Apply patch //text3, _ := dmp.PatchApply(patch, text1) // Write the patched text to a new file err := ioutil.WriteFile("resultClient.txt", []byte(result), 0644) if err != nil { panic(err) } */ }
func (self *Case) printDiff(s1, s2 string) { s1, s2 = formatize(" ", s1), formatize(" ", s2) color.Printf("@r...@| expected @gstring =@|\n%v\n", s1) color.Printf("@r...@| actual @rstring =@|\n%v\n", s2) color.Printf("@r...@| diff is\n") state := dmp.New() diffs := state.DiffMain(s1, s2, false) for _, diff := range diffs { switch diff.Type { case dmp.DiffEqual: fmt.Print(diff.Text) case dmp.DiffDelete: color.Printf("@r[-%s]@|", diff.Text) case dmp.DiffInsert: color.Printf("@g[+%s]@|", diff.Text) } } fmt.Println() }
func HighlightedDiffFunc(leftContent, rightContent string, segments *[2][]*annotate.Annotation, offsets [2]int) { dmp := diffmatchpatch.New() diffs := dmp.DiffMain(leftContent, rightContent, true) for side := range *segments { offset := offsets[side] for _, diff := range diffs { if side == 0 && diff.Type == -1 { (*segments)[side] = append((*segments)[side], &annotate.Annotation{Start: offset, End: offset + len(diff.Text), Left: []byte(`<span class="x">`), Right: []byte(`</span>`), WantInner: 1}) offset += len(diff.Text) } if side == 1 && diff.Type == +1 { (*segments)[side] = append((*segments)[side], &annotate.Annotation{Start: offset, End: offset + len(diff.Text), Left: []byte(`<span class="x">`), Right: []byte(`</span>`), WantInner: 1}) offset += len(diff.Text) } if diff.Type == 0 { offset += len(diff.Text) } } } }
func DiffValues(a, b interface{}) string { printer := colour.String() diff := diffmatchpatch.New() at := repr.String(a, repr.OmitEmpty()) bt := repr.String(b, repr.OmitEmpty()) diffs := diff.DiffMain(at, bt, true) for _, d := range diffs { switch d.Type { case diffmatchpatch.DiffEqual: if len(d.Text) <= 40 { printer.Print(d.Text) } else { printer.Printf("%s^B...^R%s", d.Text[:15], d.Text[len(d.Text)-15:]) } case diffmatchpatch.DiffDelete: printer.Printf("^9%s^R", d.Text) case diffmatchpatch.DiffInsert: printer.Printf("^a%s^R", d.Text) } } return printer.String() }
func DiffValuesDefault(a, b interface{}) string { diff := diffmatchpatch.New() at := repr.String(a) bt := repr.String(b) diffs := diff.DiffMain(at, bt, true) w := bytes.NewBuffer(nil) for _, d := range diffs { switch d.Type { case diffmatchpatch.DiffEqual: if len(d.Text) <= 40 { w.WriteString(d.Text) } else { fmt.Fprintf(w, "%s...%s", d.Text[:15], d.Text[len(d.Text)-15:]) } case diffmatchpatch.DiffDelete: fmt.Fprintf(w, "-{{%s}}", d.Text) case diffmatchpatch.DiffInsert: fmt.Fprintf(w, "+{{%s}}", d.Text) } } return w.String() }
func highlightedDiffFunc(leftContent, rightContent string, segments *[2][]highlightSegment, offsets [2]uint32) { dmp := diffmatchpatch.New() diffs := dmp.DiffMain(leftContent, rightContent, true) for side := range *segments { offset := offsets[side] for _, diff := range diffs { if side == 0 && diff.Type == -1 { (*segments)[side] = append((*segments)[side], highlightSegment{offset: offset, color: darkRedColor}) offset += uint32(len(diff.Text)) } if side == 1 && diff.Type == +1 { (*segments)[side] = append((*segments)[side], highlightSegment{offset: offset, color: darkGreenColor}) offset += uint32(len(diff.Text)) } if diff.Type == 0 { (*segments)[side] = append((*segments)[side], highlightSegment{offset: offset}) offset += uint32(len(diff.Text)) } } } }
func differances(text1, text2 string) { // Check diffs dmp := diffmatchpatch.New() diffs := dmp.DiffMain(text1, text2, false) // Make patch patch := dmp.PatchMake(text1, diffs) // Print patch to see the results before they're applied fmt.Println(dmp.PatchToText(patch)) result := dmp.PatchToText(patch) // detta sker efter att vi har mottagit från klienten! // Apply patch //text3, _ := dmp.PatchApply(patch, text1) // Write the patched text to a new file err := ioutil.WriteFile("resultClient.txt", []byte(result), 0644) if err != nil { panic(err) } }