mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-09-17 19:13:56 +02:00
add nip23 markdown helper.
This commit is contained in:
64
nip23/markdown.go
Normal file
64
nip23/markdown.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package nip23
|
||||
|
||||
import (
|
||||
stdhtml "html"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/gomarkdown/markdown"
|
||||
"github.com/gomarkdown/markdown/ast"
|
||||
"github.com/gomarkdown/markdown/html"
|
||||
"github.com/gomarkdown/markdown/parser"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
)
|
||||
|
||||
var nostrEveryMatcher = regexp.MustCompile(`nostr:((npub|note|nevent|nprofile|naddr)1[a-z0-9]+)\b`)
|
||||
|
||||
var renderer = html.NewRenderer(html.RendererOptions{
|
||||
Flags: html.HrefTargetBlank | html.SkipHTML,
|
||||
RenderNodeHook: func(w io.Writer, node ast.Node, entering bool) (ast.WalkStatus, bool) {
|
||||
switch v := node.(type) {
|
||||
case *ast.HTMLSpan:
|
||||
w.Write([]byte(stdhtml.EscapeString(string(v.Literal))))
|
||||
return ast.GoToNext, true
|
||||
case *ast.HTMLBlock:
|
||||
w.Write([]byte(stdhtml.EscapeString(string(v.Literal))))
|
||||
return ast.GoToNext, true
|
||||
}
|
||||
|
||||
return ast.GoToNext, false
|
||||
},
|
||||
})
|
||||
|
||||
func MarkdownToHTML(md string) string {
|
||||
md = strings.ReplaceAll(md, "\u00A0", " ")
|
||||
|
||||
// create markdown parser with extensions
|
||||
// this parser is stateful so it must be reinitialized every time
|
||||
doc := parser.NewWithExtensions(
|
||||
parser.AutoHeadingIDs |
|
||||
parser.NoIntraEmphasis |
|
||||
parser.FencedCode |
|
||||
parser.Autolink |
|
||||
parser.Footnotes |
|
||||
parser.SpaceHeadings,
|
||||
).Parse([]byte(md))
|
||||
|
||||
// create HTML renderer with extensions
|
||||
output := string(markdown.Render(doc, renderer))
|
||||
|
||||
// sanitize content
|
||||
output = sanitizeXSS(output)
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
func sanitizeXSS(html string) string {
|
||||
p := bluemonday.UGCPolicy()
|
||||
p.RequireNoFollowOnLinks(false)
|
||||
p.AllowElements("video", "source")
|
||||
p.AllowAttrs("controls", "width").OnElements("video")
|
||||
p.AllowAttrs("src", "width").OnElements("source")
|
||||
return p.Sanitize(html)
|
||||
}
|
Reference in New Issue
Block a user