forked from forgejo/forgejo
Improved diff syntax highlighting fix (#12455)
Make previous fix from #12238 more robust since I saw a case where a diff changes only a single character in a chroma class instead of the entire thing. Add another more complicated test to match. Co-authored-by: Lauris BH <lauris@nix.lv>
This commit is contained in:
parent
96add8c319
commit
0171dda728
2 changed files with 37 additions and 20 deletions
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue