mirror of
https://github.com/abhinavxd/libredesk.git
synced 2026-09-10 14:15:42 +00:00
a3d29011b6
enmime's charset detection was overriding the declared UTF-8 charset on long mostly-ASCII bodies, storing accented text as mojibake (issue #512). Parse with detection disabled so the declared charset wins, bump enmime to v2, and swap the abandoned jaytaylor/html2text for its inbucket fork. Pin behavior with charset tests across locales, encodings, and malformed inputs.
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package stringutil
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/inbucket/html2text"
|
|
"golang.org/x/net/html"
|
|
)
|
|
|
|
// HTML2TextMarkdownLinks converts HTML to text keeping links as markdown "[text](url)", the form a
|
|
// model copies back into its reply and that Markdown2HTML turns into an anchor again.
|
|
func HTML2TextMarkdownLinks(htmlContent string) string {
|
|
if doc, err := html.Parse(strings.NewReader(htmlContent)); err == nil {
|
|
inlineAnchorMarkdown(doc)
|
|
var b strings.Builder
|
|
if err := html.Render(&b, doc); err == nil {
|
|
htmlContent = b.String()
|
|
}
|
|
}
|
|
return htmlToText(htmlContent, html2text.Options{})
|
|
}
|
|
|
|
func inlineAnchorMarkdown(n *html.Node) {
|
|
var next *html.Node
|
|
for child := n.FirstChild; child != nil; child = next {
|
|
next = child.NextSibling
|
|
if child.Type == html.ElementNode && child.Data == "a" {
|
|
link := markdownLink(nodeText(child), strings.TrimSpace(attrValue(child, "href")))
|
|
if link != "" {
|
|
n.InsertBefore(&html.Node{Type: html.TextNode, Data: link}, child)
|
|
n.RemoveChild(child)
|
|
continue
|
|
}
|
|
}
|
|
inlineAnchorMarkdown(child)
|
|
}
|
|
}
|
|
|
|
// markdownLink returns "" when the anchor is not worth rewriting, leaving it to the text conversion.
|
|
func markdownLink(text, href string) string {
|
|
if href == "" || strings.HasPrefix(href, "#") || strings.HasPrefix(href, "cid:") {
|
|
return ""
|
|
}
|
|
text = strings.Join(strings.Fields(text), " ")
|
|
if text == "" || text == href {
|
|
return href
|
|
}
|
|
if strings.ContainsAny(href, " ()") {
|
|
href = "<" + href + ">"
|
|
}
|
|
return "[" + strings.NewReplacer("[", `\[`, "]", `\]`).Replace(text) + "](" + href + ")"
|
|
}
|
|
|
|
func nodeText(n *html.Node) string {
|
|
var b strings.Builder
|
|
var walk func(*html.Node)
|
|
walk = func(node *html.Node) {
|
|
if node.Type == html.TextNode {
|
|
b.WriteString(node.Data)
|
|
}
|
|
for c := node.FirstChild; c != nil; c = c.NextSibling {
|
|
walk(c)
|
|
}
|
|
}
|
|
walk(n)
|
|
return b.String()
|
|
}
|