mirror of
https://github.com/httpjamesm/AnonymousOverflow.git
synced 2025-05-14 05:52:54 +00:00
feat: highlight code blocks within answers
This commit is contained in:
parent
da57f98fec
commit
631a700c9f
6 changed files with 161 additions and 1 deletions
78
src/utils/syntax.go
Normal file
78
src/utils/syntax.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"html"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma/formatters"
|
||||
"github.com/alecthomas/chroma/lexers"
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
)
|
||||
|
||||
var plainFormattedCodeRegex = regexp.MustCompile(`(?s)<pre tabindex="0" class="chroma"><code>(.+?)</code></pre>`)
|
||||
|
||||
func HighlightSyntaxViaContent(content string) (htmlOut string) {
|
||||
content = html.UnescapeString(content)
|
||||
|
||||
fallbackOut := content
|
||||
|
||||
// identify the language
|
||||
lexer := lexers.Analyse(content)
|
||||
if lexer == nil {
|
||||
// unable to identify, so just return the wrapped content
|
||||
htmlOut = fallbackOut
|
||||
return
|
||||
}
|
||||
|
||||
style := styles.Get("xcode")
|
||||
if style == nil {
|
||||
style = styles.Fallback
|
||||
}
|
||||
|
||||
formatter := formatters.Get("html")
|
||||
if formatter == nil {
|
||||
formatter = formatters.Fallback
|
||||
}
|
||||
|
||||
iterator, err := lexer.Tokenise(nil, content)
|
||||
if err != nil {
|
||||
htmlOut = fallbackOut
|
||||
return
|
||||
}
|
||||
|
||||
b := bytes.NewBufferString("")
|
||||
w := io.Writer(b)
|
||||
|
||||
err = formatter.Format(w, style, iterator)
|
||||
if err != nil {
|
||||
htmlOut = fallbackOut
|
||||
return
|
||||
}
|
||||
|
||||
// parse only the <pre><code>...</code></pre> part
|
||||
htmlOut = b.String()
|
||||
htmlOut = plainFormattedCodeRegex.FindString(htmlOut)
|
||||
|
||||
htmlOut = StripBlockTags(htmlOut)
|
||||
|
||||
// remove <pre tabindex="0" class="chroma">
|
||||
htmlOut = strings.Replace(htmlOut, "<pre tabindex=\"0\" class=\"chroma\">", "", -1)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func StripBlockTags(content string) (result string) {
|
||||
// strip all "<code>" tags
|
||||
content = strings.Replace(content, "<code>", "", -1)
|
||||
content = strings.Replace(content, "</code>", "", -1)
|
||||
// and the <pre>
|
||||
content = strings.Replace(content, "<pre>", "", -1)
|
||||
content = strings.Replace(content, "</pre>", "", -1)
|
||||
|
||||
result = content
|
||||
|
||||
return
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue