Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at 10ee2ad8ad2d289fc0d61c8ef318ee7877ec8fe1 77 lines 1.6 kB view raw
1package version 2 3import ( 4 "strings" 5 6 difflib "github.com/sergi/go-diff/diffmatchpatch" 7) 8 9type DiffLine struct { 10 Type string `json:"type"` // equal, insert, delete 11 Content string `json:"content"` 12 OldNum int `json:"old_num,omitempty"` 13 NewNum int `json:"new_num,omitempty"` 14} 15 16func Diff(oldText, newText string) []DiffLine { 17 dmp := difflib.New() 18 diffs := dmp.DiffMain(oldText, newText, true) 19 diffs = dmp.DiffCleanupSemantic(diffs) 20 21 var lines []DiffLine 22 oldNum := 1 23 newNum := 1 24 25 for _, d := range diffs { 26 parts := strings.Split(d.Text, "\n") 27 for i, part := range parts { 28 if i == len(parts)-1 && part == "" { 29 continue 30 } 31 switch d.Type { 32 case difflib.DiffEqual: 33 lines = append(lines, DiffLine{ 34 Type: "equal", 35 Content: part, 36 OldNum: oldNum, 37 NewNum: newNum, 38 }) 39 oldNum++ 40 newNum++ 41 case difflib.DiffInsert: 42 lines = append(lines, DiffLine{ 43 Type: "insert", 44 Content: part, 45 NewNum: newNum, 46 }) 47 newNum++ 48 case difflib.DiffDelete: 49 lines = append(lines, DiffLine{ 50 Type: "delete", 51 Content: part, 52 OldNum: oldNum, 53 }) 54 oldNum++ 55 } 56 } 57 } 58 return lines 59} 60 61func Stats(oldText, newText string) (added, removed int) { 62 dmp := difflib.New() 63 diffs := dmp.DiffMain(oldText, newText, true) 64 for _, d := range diffs { 65 lineCount := strings.Count(d.Text, "\n") 66 if d.Text != "" && !strings.HasSuffix(d.Text, "\n") { 67 lineCount++ 68 } 69 switch d.Type { 70 case difflib.DiffInsert: 71 added += lineCount 72 case difflib.DiffDelete: 73 removed += lineCount 74 } 75 } 76 return 77}