diff --git a/diffmatchpatch/diff.go b/diffmatchpatch/diff.go
index 2a9f2dc..06b7ba6 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..a31e1a9 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: "a¶
<B>b</B>",
+ ExpectedNew: "a¶
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