{
switch lang {
case "go":
return highlightGo(code), true
case "rtml":
return highlightRTML(code), true
default:
return "", false
}
}
{
esc := html.EscapeString(code)
esc = goCommentRe.ReplaceAllStringFunc(esc, func(m string) string {
return `<span class="hl-comment">` + m + `</span>`
})
esc = goStringRe.ReplaceAllStringFunc(esc, func(m string) string {
return `<span class="hl-string">` + m + `</span>`
})
esc = goKeywordRe.ReplaceAllString(esc, `<span class="hl-kw">$1</span>`)
return esc
}
{
esc := html.EscapeString(code)
esc = rtmlTagRe.ReplaceAllStringFunc(esc, func(m string) string {
s := rtmlAttrRe.ReplaceAllString(m, ` <span class="hl-attr">$1</span>=`)
s = rtmlCmdAttrRe.ReplaceAllString(s, ` <span class="hl-cmd">$1</span>`)
s = rtmlStringRe.ReplaceAllStringFunc(s, func(str string) string {
quote := """
inner := str[len(quote) : len(str)-len(quote)]
inner = rtmlCmdRe.ReplaceAllStringFunc(inner, func(cmd string) string {
return `<span class="hl-cmd">` + cmd + `</span>`
})
return `<span class="hl-string">` + quote + inner + quote + `</span>`
})
return `<span class="hl-tag">` + s + `</span>`
})
esc = rtmlStandaloneRe.ReplaceAllString(esc, `$1<span class="hl-cmd">$2</span>`)
esc = rtmlInterpRe.ReplaceAllStringFunc(esc, func(m string) string {
return `<span class="hl-var">` + m + `</span>`
})
return esc
}
{
code := "package main\n// comment\nvar s = \"hi\""
out, ok := Highlight(code, "go")
if !ok {
t.Fatalf("unexpected highlight failure: %s", out)
}
if !strings.Contains(out, `<span class="hl-kw">package</span>`) {
t.Fatalf("missing keyword highlighting: %s", out)
}
if !strings.Contains(out, `<span class="hl-comment">// comment</span>`) {
t.Fatalf("missing comment highlighting: %s", out)
}
if !strings.Contains(out, `<span class="hl-string">"hi"</span>`) {
t.Fatalf("missing string highlighting: %s", out)
}
}
{
code := "<div class=\"x\">{name}</div>\n<button @on:click:save>ok</button>\n@for:item in items"
out, ok := Highlight(code, "rtml")
if !ok {
t.Fatalf("unexpected highlight failure: %s", out)
}
tag := "<span class=\"hl-tag\"><div <span class=\"hl-attr\">class</span>=<span class=\"hl-string\">"x"</span>></span>"
if !strings.Contains(out, tag) {
t.Fatalf("missing tag highlighting: %s", out)
}
if !strings.Contains(out, `<span class="hl-var">{name}</span>`) {
t.Fatalf("missing variable highlighting: %s", out)
}
if !strings.Contains(out, `<span class="hl-cmd">@on:click:save</span>`) {
t.Fatalf("missing command attribute highlighting: %s", out)
}
if !strings.Contains(out, `<span class="hl-cmd">@for:item</span>`) {
t.Fatalf("missing standalone command highlighting: %s", out)
}
}
{
prev := Highlight
defer func() { Highlight = prev }()
Highlight = func(code, lang string) (string, bool) {
if code == "c" && lang == "l" {
return "ok", true
}
return "", false
}
if out, ok := Highlight("c", "l"); !ok || out != "ok" {
t.Fatalf("override failed: %v %v", out, ok)
}
}
{ return nil }
{
js.ExposeFunc("rfwHighlight", func(this js.Value, args []js.Value) any {
if len(args) < 2 {
return ""
}
code := args[0].String()
lang := args[1].String()
if res, ok := Highlight(code, lang); ok {
return res
}
return ""
})
js.ExposeFunc("rfwHighlightAll", func(this js.Value, args []js.Value) any {
HighlightAll()
return nil
})
doc := dom.Doc()
style := doc.CreateElement("style")
style.SetHTML(`.hl-kw{color:#ff7b72}.hl-tag{color:#7ee787}.hl-attr{color:#e3b341}.hl-string{color:#a5d6ff}.hl-comment{color:#8b949e;font-style:italic}.hl-var{color:#d2a8ff}.hl-cmd{color:#ffa657}`)
doc.Query("head").Call("appendChild", style.Value)
}
{ return &Plugin{} }
HighlightAll finds all
blocks in the document and replaces
their contents with highlighted HTML using the registered Highlight
function. The language is detected from `language-` classes or the
`data-lang` attribute.
Show/Hide Function
Body
{
doc := dom.Doc()
codes := doc.QueryAll("pre code")
length := codes.Length()
for i := 0; i < length; i++ {
el := codes.Index(i)
cls := el.Get("className").String()
lang := ""
for _, c := range strings.Split(cls, " ") {
lc := strings.ToLower(c)
if strings.HasPrefix(lc, "language-") {
lang = strings.TrimPrefix(lc, "language-")
break
}
}
if lang == "" {
lang = strings.ToLower(el.Get("dataset").Get("lang").String())
}
code := el.Get("textContent").String()
if res, ok := Highlight(code, lang); ok {
el.SetHTML(res)
}
}
}
import "html"
import "regexp"
import "strings"
import "strings"
import "testing"
import "encoding/json"
import "strings"
import "github.com/rfwlab/rfw/v1/core"
import "github.com/rfwlab/rfw/v1/dom"
dom
import "github.com/rfwlab/rfw/v1/js"
js