aboutsummaryrefslogtreecommitdiffstats
path: root/services/gitdiff/gitdiff.go
diff options
context:
space:
mode:
Diffstat (limited to 'services/gitdiff/gitdiff.go')
-rw-r--r--services/gitdiff/gitdiff.go47
1 files changed, 27 insertions, 20 deletions
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 85354784d4..fca210bb10 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -16,6 +16,7 @@ import (
"net/url"
"os"
"os/exec"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -180,55 +181,61 @@ var (
removedCodePrefix = []byte(`<span class="removed-code">`)
codeTagSuffix = []byte(`</span>`)
)
+var addSpanRegex = regexp.MustCompile(`<span class="[a-z]*$`)
func diffToHTML(fileName string, diffs []diffmatchpatch.Diff, lineType DiffLineType) template.HTML {
buf := bytes.NewBuffer(nil)
- var addSpan bool
+ var addSpan string
for i := range diffs {
switch {
case diffs[i].Type == diffmatchpatch.DiffEqual:
// Looking for the case where our 3rd party diff library previously detected a string difference
// in the middle of a span class because we highlight them first. This happens when added/deleted code
- // also changes the chroma class name. If found, just move the openining span code forward into the next section
- if addSpan {
- diffs[i].Text = "<span class=\"" + diffs[i].Text
+ // also changes the chroma class name, either partially or fully. If found, just move the openining span code forward into the next section
+ // see TestDiffToHTML for examples
+ if len(addSpan) > 0 {
+ diffs[i].Text = addSpan + diffs[i].Text
+ addSpan = ""
}
- if strings.HasSuffix(diffs[i].Text, "<span class=\"") {
- addSpan = true
- buf.WriteString(strings.TrimSuffix(diffs[i].Text, "<span class=\""))
+ m := addSpanRegex.FindStringSubmatchIndex(diffs[i].Text)
+ if m != nil {
+ addSpan = diffs[i].Text[m[0]:m[1]]
+ buf.WriteString(strings.TrimSuffix(diffs[i].Text, addSpan))
} else {
- addSpan = false
+ addSpan = ""
buf.WriteString(getLineContent(diffs[i].Text))
}
case diffs[i].Type == diffmatchpatch.DiffInsert && lineType == DiffLineAdd:
- if addSpan {
- addSpan = false
- diffs[i].Text = "<span class=\"" + diffs[i].Text
+ if len(addSpan) > 0 {
+ diffs[i].Text = addSpan + diffs[i].Text
+ addSpan = ""
}
// Print existing closing span first before opening added-code span so it doesn't unintentionally close it
if strings.HasPrefix(diffs[i].Text, "</span>") {
buf.WriteString("</span>")
diffs[i].Text = strings.TrimPrefix(diffs[i].Text, "</span>")
}
- if strings.HasSuffix(diffs[i].Text, "<span class=\"") {
- addSpan = true
- diffs[i].Text = strings.TrimSuffix(diffs[i].Text, "<span class=\"")
+ m := addSpanRegex.FindStringSubmatchIndex(diffs[i].Text)
+ if m != nil {
+ addSpan = diffs[i].Text[m[0]:m[1]]
+ diffs[i].Text = strings.TrimSuffix(diffs[i].Text, addSpan)
}
buf.Write(addedCodePrefix)
buf.WriteString(getLineContent(diffs[i].Text))
buf.Write(codeTagSuffix)
case diffs[i].Type == diffmatchpatch.DiffDelete && lineType == DiffLineDel:
- if addSpan {
- addSpan = false
- diffs[i].Text = "<span class=\"" + diffs[i].Text
+ if len(addSpan) > 0 {
+ diffs[i].Text = addSpan + diffs[i].Text
+ addSpan = ""
}
if strings.HasPrefix(diffs[i].Text, "</span>") {
buf.WriteString("</span>")
diffs[i].Text = strings.TrimPrefix(diffs[i].Text, "</span>")
}
- if strings.HasSuffix(diffs[i].Text, "<span class=\"") {
- addSpan = true
- diffs[i].Text = strings.TrimSuffix(diffs[i].Text, "<span class=\"")
+ m := addSpanRegex.FindStringSubmatchIndex(diffs[i].Text)
+ if m != nil {
+ addSpan = diffs[i].Text[m[0]:m[1]]
+ diffs[i].Text = strings.TrimSuffix(diffs[i].Text, addSpan)
}
buf.Write(removedCodePrefix)
buf.WriteString(getLineContent(diffs[i].Text))