diff --git a/texteditor/highlighting/highlighter.go b/texteditor/highlighting/highlighter.go index a02fc5a799..4e2862f21d 100644 --- a/texteditor/highlighting/highlighter.go +++ b/texteditor/highlighting/highlighter.go @@ -222,15 +222,16 @@ func ChromaTagsLine(clex chroma.Lexer, txt string) (lexer.Line, error) { // maxLineLen prevents overflow in allocating line length const ( - maxLineLen = 64 * 1024 * 1024 - maxNumTags = 1024 + maxLineLen = 64 * 1024 * 1024 + maxNumTags = 1024 + EscapeHTML = true + NoEscapeHTML = false ) // MarkupLine returns the line with html class tags added for each tag // takes both the hi tags and extra tags. Only fully nested tags are supported, -// with any dangling ends truncated. only operates on given inputs, does not -// require any locking in terms of internal state. -func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { +// with any dangling ends truncated. +func MarkupLine(txt []rune, hitags, tags lexer.Line, escapeHtml bool) []byte { if len(txt) > maxLineLen { // avoid overflow return nil } @@ -238,10 +239,19 @@ func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { if sz == 0 { return nil } + var escf func([]rune) []byte + if escapeHtml { + escf = HtmlEscapeRunes + } else { + escf = func(r []rune) []byte { + return []byte(string(r)) + } + } + ttags := lexer.MergeLines(hitags, tags) // ensures that inner-tags are *after* outer tags nt := len(ttags) if nt == 0 || nt > maxNumTags { - return HtmlEscapeRunes(txt) + return escf(txt) } sps := []byte(``) @@ -262,7 +272,7 @@ func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { if ts.Ed <= tr.St { ep := min(sz, ts.Ed) if cp < ep { - mu = append(mu, HtmlEscapeRunes(txt[cp:ep])...) + mu = append(mu, escf(txt[cp:ep])...) cp = ep } mu = append(mu, spe...) @@ -273,7 +283,7 @@ func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { break } if tr.St > cp { - mu = append(mu, HtmlEscapeRunes(txt[cp:tr.St])...) + mu = append(mu, escf(txt[cp:tr.St])...) } mu = append(mu, sps...) clsnm := tr.Token.Token.StyleName() @@ -302,7 +312,7 @@ func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { } ep = min(len(txt), ep) if tr.St < ep { - mu = append(mu, HtmlEscapeRunes(txt[tr.St:ep])...) + mu = append(mu, escf(txt[tr.St:ep])...) } if addEnd { mu = append(mu, spe...) @@ -310,7 +320,7 @@ func MarkupLine(txt []rune, hitags, tags lexer.Line) []byte { cp = ep } if sz > cp { - mu = append(mu, HtmlEscapeRunes(txt[cp:sz])...) + mu = append(mu, escf(txt[cp:sz])...) } // pop any left on stack.. for si := len(tstack) - 1; si >= 0; si-- { diff --git a/texteditor/layout.go b/texteditor/layout.go index 2322fa3063..16e269ae7f 100644 --- a/texteditor/layout.go +++ b/texteditor/layout.go @@ -109,12 +109,13 @@ func (ed *Editor) layoutAllLines() { mxwd := sz.X // always start with our render size ed.hasLinks = false + cssAgg := ed.textStyleProperties() for ln := 0; ln < nln; ln++ { if ln >= len(ed.renders) || ln >= len(buf.Markup) { break } rn := &ed.renders[ln] - rn.SetHTMLPre(buf.Markup[ln], fst, &sty.Text, &sty.UnitContext, ed.textStyleProperties()) + rn.SetHTMLPre(buf.Markup[ln], fst, &sty.Text, &sty.UnitContext, cssAgg) rn.Layout(&sty.Text, sty.FontRender(), &sty.UnitContext, sz) if !ed.hasLinks && len(rn.Links) > 0 { ed.hasLinks = true diff --git a/texteditor/render.go b/texteditor/render.go index 920331a984..54626b30d5 100644 --- a/texteditor/render.go +++ b/texteditor/render.go @@ -64,7 +64,7 @@ func (ed *Editor) RenderWidget() { // textStyleProperties returns the styling properties for text based on HiStyle Markup func (ed *Editor) textStyleProperties() map[string]any { - if ed.Buffer == nil || !ed.Buffer.Highlighter.Has { + if ed.Buffer == nil { return nil } return ed.Buffer.Highlighter.CSSProperties diff --git a/texteditor/textbuf/lines.go b/texteditor/textbuf/lines.go index a764030075..14ce4197e3 100644 --- a/texteditor/textbuf/lines.go +++ b/texteditor/textbuf/lines.go @@ -1356,6 +1356,7 @@ func (ls *Lines) markupApplyEdits(tags []lexer.Line) []lexer.Line { } else { stln := tbe.Reg.Start.Ln + 1 nlns := (tbe.Reg.End.Ln - tbe.Reg.Start.Ln) + stln = min(stln, len(tags)) tags = slices.Insert(tags, stln, make([]lexer.Line, nlns)...) } } @@ -1371,7 +1372,7 @@ func (ls *Lines) markupApplyTags(tags []lexer.Line) { for ln := range maxln { ls.hiTags[ln] = tags[ln] ls.tags[ln] = ls.adjustedTags(ln) - ls.Markup[ln] = highlighting.MarkupLine(ls.lines[ln], tags[ln], ls.tags[ln]) + ls.Markup[ln] = highlighting.MarkupLine(ls.lines[ln], tags[ln], ls.tags[ln], highlighting.EscapeHTML) } if ls.MarkupDoneFunc != nil { ls.MarkupDoneFunc() @@ -1396,7 +1397,7 @@ func (ls *Lines) markupLines(st, ed int) bool { mt, err := ls.Highlighter.MarkupTagsLine(ln, ltxt) if err == nil { ls.hiTags[ln] = mt - ls.Markup[ln] = highlighting.MarkupLine(ltxt, mt, ls.adjustedTags(ln)) + ls.Markup[ln] = highlighting.MarkupLine(ltxt, mt, ls.adjustedTags(ln), highlighting.EscapeHTML) } else { ls.Markup[ln] = highlighting.HtmlEscapeRunes(ltxt) allgood = false