From 491e62bcb2083817451a15ea15fc52be3d4dcb9a Mon Sep 17 00:00:00 2001 From: mortywang Date: Wed, 20 Jul 2022 03:43:54 +0800 Subject: [PATCH 1/2] Restructure the pretty functions. Add markdown pretty function. Diff result with old and new pretty color function --- diffmatchpatch/diff.go | 138 ++++++++++++++++++++++++++++++++---- diffmatchpatch/diff_test.go | 106 +++++++++++++++++++++++++++ 2 files changed, 229 insertions(+), 15 deletions(-) diff --git a/diffmatchpatch/diff.go b/diffmatchpatch/diff.go index 2a9f2dc..495063a 100644 --- a/diffmatchpatch/diff.go +++ b/diffmatchpatch/diff.go @@ -44,6 +44,16 @@ type Diff struct { Text string } +type PrettyInfo struct { + PrefixInsert string + SuffixInsert string + PrefixDelete string + SuffixDelete string + PrefixEqual string + SuffixEqual string + Escape bool +} + // splice removes amount elements from slice at index index, replacing them with elements. func splice(slice []Diff, index int, amount int, elements ...Diff) []Diff { if len(elements) == amount { @@ -1122,44 +1132,142 @@ func (dmp *DiffMatchPatch) DiffXIndex(diffs []Diff, loc int) int { // DiffPrettyHtml converts a []Diff into a pretty HTML report. // It is intended as an example from which to write one's own display functions. func (dmp *DiffMatchPatch) DiffPrettyHtml(diffs []Diff) string { + return dmp.DiffPretty(diffs, PrettyInfo{ + PrefixInsert: "", + SuffixInsert: "", + PrefixDelete: "", + SuffixDelete: "", + PrefixEqual: "", + SuffixEqual: "", + Escape: true, + }) +} + +// DiffPrettyText converts a []Diff into a colored text report. +func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string { + return dmp.DiffPretty(diffs, PrettyInfo{ + PrefixInsert: "\x1b[32m", + SuffixInsert: "\x1b[0m", + PrefixDelete: "\x1b[31m", + SuffixDelete: "\x1b[0m", + PrefixEqual: "", + SuffixEqual: "", + }) +} + +// DiffPrettyMarkdown converts a []Diff into a colored makdown report. +func (dmp *DiffMatchPatch) DiffPrettyMarkdown(diffs []Diff) string { + return dmp.DiffPretty(diffs, PrettyInfo{ + PrefixInsert: "", + SuffixInsert: "", + PrefixDelete: "", + SuffixDelete: "", + PrefixEqual: "", + SuffixEqual: "", + }) +} + +func (dmp *DiffMatchPatch) DiffPrettyHtmlAll(diffs []Diff) (old, new string) { + prettyInfo := PrettyInfo{ + PrefixInsert: "", + SuffixInsert: "", + PrefixDelete: "", + SuffixDelete: "", + PrefixEqual: "", + SuffixEqual: "", + Escape: true, + } + return dmp.DiffPrettyOld(diffs, prettyInfo), dmp.DiffPrettyNew(diffs, prettyInfo) +} + +func (dmp *DiffMatchPatch) DiffPrettyTextAll(diffs []Diff) (old, new string) { + prettyInfo := PrettyInfo{ + PrefixInsert: "\x1b[32m", + SuffixInsert: "\x1b[0m", + PrefixDelete: "\x1b[31m", + SuffixDelete: "\x1b[0m", + PrefixEqual: "", + SuffixEqual: "", + } + return dmp.DiffPrettyOld(diffs, prettyInfo), dmp.DiffPrettyNew(diffs, prettyInfo) +} + +func (dmp *DiffMatchPatch) DiffPrettyMarkdownAll(diffs []Diff) (old, new string) { + prettyInfo := PrettyInfo{ + PrefixInsert: "", + SuffixInsert: "", + PrefixDelete: "", + SuffixDelete: "", + PrefixEqual: "", + SuffixEqual: "", + } + return dmp.DiffPrettyOld(diffs, prettyInfo), dmp.DiffPrettyNew(diffs, prettyInfo) +} + +func (dmp *DiffMatchPatch) DiffPretty(diffs []Diff, PrettyInfo PrettyInfo) string { var buff bytes.Buffer for _, diff := range diffs { - text := strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1) + text := diff.Text + if PrettyInfo.Escape { + text = strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1) + } switch diff.Type { case DiffInsert: - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.PrefixInsert) _, _ = buff.WriteString(text) - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.SuffixInsert) case DiffDelete: - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.PrefixDelete) _, _ = buff.WriteString(text) - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.SuffixDelete) case DiffEqual: - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.PrefixEqual) _, _ = buff.WriteString(text) - _, _ = buff.WriteString("") + _, _ = buff.WriteString(PrettyInfo.SuffixEqual) } } + return buff.String() } -// DiffPrettyText converts a []Diff into a colored text report. -func (dmp *DiffMatchPatch) DiffPrettyText(diffs []Diff) string { +func (dmp *DiffMatchPatch) DiffPrettyOld(diffs []Diff, PrettyInfo PrettyInfo) string { var buff bytes.Buffer for _, diff := range diffs { text := diff.Text + if PrettyInfo.Escape { + text = strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1) + } + switch diff.Type { + case DiffDelete: + _, _ = buff.WriteString(PrettyInfo.PrefixDelete) + _, _ = buff.WriteString(text) + _, _ = buff.WriteString(PrettyInfo.SuffixDelete) + case DiffEqual: + _, _ = buff.WriteString(PrettyInfo.PrefixEqual) + _, _ = buff.WriteString(text) + _, _ = buff.WriteString(PrettyInfo.SuffixEqual) + } + } + return buff.String() +} + +func (dmp *DiffMatchPatch) DiffPrettyNew(diffs []Diff, PrettyInfo PrettyInfo) string { + var buff bytes.Buffer + for _, diff := range diffs { + text := diff.Text + if PrettyInfo.Escape { + text = strings.Replace(html.EscapeString(diff.Text), "\n", "¶
", -1) + } switch diff.Type { case DiffInsert: - _, _ = buff.WriteString("\x1b[32m") - _, _ = buff.WriteString(text) - _, _ = buff.WriteString("\x1b[0m") - case DiffDelete: - _, _ = buff.WriteString("\x1b[31m") + _, _ = buff.WriteString(PrettyInfo.PrefixInsert) _, _ = buff.WriteString(text) - _, _ = buff.WriteString("\x1b[0m") + _, _ = buff.WriteString(PrettyInfo.SuffixInsert) case DiffEqual: + _, _ = buff.WriteString(PrettyInfo.PrefixEqual) _, _ = buff.WriteString(text) + _, _ = buff.WriteString(PrettyInfo.SuffixEqual) } } diff --git a/diffmatchpatch/diff_test.go b/diffmatchpatch/diff_test.go index acb97e3..a1645b5 100644 --- a/diffmatchpatch/diff_test.go +++ b/diffmatchpatch/diff_test.go @@ -1037,6 +1037,112 @@ func TestDiffPrettyText(t *testing.T) { } } +func TestDiffPrettyMarkdown(t *testing.T) { + type TestCase struct { + Diffs []Diff + + Expected string + } + + dmp := New() + + for i, tc := range []TestCase{ + { + Diffs: []Diff{ + {DiffEqual, "a\n"}, + {DiffDelete, "b"}, + {DiffInsert, "c&d"}, + }, + + Expected: "a\nbc&d", + }, + } { + actual := dmp.DiffPrettyMarkdown(tc.Diffs) + assert.Equal(t, tc.Expected, actual, fmt.Sprintf("Test case #%d, %#v", i, tc)) + } +} + +func TestDiffPrettyHtmlAll(t *testing.T) { + type TestCase struct { + Diffs []Diff + + ExpectedOld string + ExpectedNew string + } + + dmp := New() + + for i, tc := range []TestCase{ + { + Diffs: []Diff{ + {DiffEqual, "a\n"}, + {DiffDelete, "b"}, + {DiffInsert, "c&d"}, + }, + ExpectedOld: "
<B>b</B>", + ExpectedNew: "
c&d", + }, + } { + actualOld, actualNew := dmp.DiffPrettyHtmlAll(tc.Diffs) + assert.Equal(t, tc.ExpectedOld, actualOld, fmt.Sprintf("Test case #%d, %#v", i, tc)) + assert.Equal(t, tc.ExpectedNew, actualNew, fmt.Sprintf("Test case #%d, %#v", i, tc)) + } +} + +func TestDiffPrettyTextAll(t *testing.T) { + type TestCase struct { + Diffs []Diff + + ExpectedOld string + ExpectedNew string + } + + dmp := New() + + for i, tc := range []TestCase{ + { + Diffs: []Diff{ + {DiffEqual, "a\n"}, + {DiffDelete, "b"}, + {DiffInsert, "c&d"}, + }, + ExpectedOld: "a\n\x1b[31mb\x1b[0m", + ExpectedNew: "a\n\x1b[32mc&d\x1b[0m", + }, + } { + actualOld, actualNew := dmp.DiffPrettyTextAll(tc.Diffs) + assert.Equal(t, tc.ExpectedOld, actualOld, fmt.Sprintf("Test case #%d, %#v", i, tc)) + assert.Equal(t, tc.ExpectedNew, actualNew, fmt.Sprintf("Test case #%d, %#v", i, tc)) + } +} + +func TestDiffPrettyMarkdownAll(t *testing.T) { + type TestCase struct { + Diffs []Diff + + ExpectedOld string + ExpectedNew string + } + + dmp := New() + + for i, tc := range []TestCase{ + { + Diffs: []Diff{ + {DiffEqual, "a\n"}, + {DiffDelete, "b"}, + {DiffInsert, "c&d"}, + }, + ExpectedOld: "a\nb", + ExpectedNew: "a\nc&d", + }, + } { + actualOld, actualNew := dmp.DiffPrettyMarkdownAll(tc.Diffs) + assert.Equal(t, tc.ExpectedOld, actualOld, fmt.Sprintf("Test case #%d, %#v", i, tc)) + assert.Equal(t, tc.ExpectedNew, actualNew, fmt.Sprintf("Test case #%d, %#v", i, tc)) + } +} + func TestDiffText(t *testing.T) { type TestCase struct { Diffs []Diff From 5b2bf63e90a14dd46b7291107012d4aefc8e28f0 Mon Sep 17 00:00:00 2001 From: mortywang Date: Wed, 20 Jul 2022 03:47:22 +0800 Subject: [PATCH 2/2] Restructure the pretty functions. Add markdown pretty function. Diff result with old and new pretty color function --- diffmatchpatch/diff.go | 2 +- diffmatchpatch/diff_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/diffmatchpatch/diff.go b/diffmatchpatch/diff.go index 495063a..06b7ba6 100644 --- a/diffmatchpatch/diff.go +++ b/diffmatchpatch/diff.go @@ -1196,7 +1196,7 @@ func (dmp *DiffMatchPatch) DiffPrettyMarkdownAll(diffs []Diff) (old, new string) prettyInfo := PrettyInfo{ PrefixInsert: "", SuffixInsert: "", - PrefixDelete: "", + PrefixDelete: "", SuffixDelete: "", PrefixEqual: "", SuffixEqual: "", diff --git a/diffmatchpatch/diff_test.go b/diffmatchpatch/diff_test.go index a1645b5..a31e1a9 100644 --- a/diffmatchpatch/diff_test.go +++ b/diffmatchpatch/diff_test.go @@ -1133,7 +1133,7 @@ func TestDiffPrettyMarkdownAll(t *testing.T) { {DiffDelete, "b"}, {DiffInsert, "c&d"}, }, - ExpectedOld: "a\nb", + ExpectedOld: "a\nb", ExpectedNew: "a\nc&d", }, } {