| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- package markdown
- import (
- "fmt"
- "io"
- "github.com/diamondburned/ningen/v3/discordmd"
- "github.com/yuin/goldmark/ast"
- gmr "github.com/yuin/goldmark/renderer"
- )
- var (
- DefaultRenderer = newRenderer()
- )
- type renderer struct {
- config *gmr.Config
- }
- func newRenderer() *renderer {
- config := gmr.NewConfig()
- return &renderer{config}
- }
- // AddOptions implements renderer.Renderer.
- func (r *renderer) AddOptions(opts ...gmr.Option) {
- for _, opt := range opts {
- opt.SetConfig(r.config)
- }
- }
- func (r *renderer) Render(w io.Writer, source []byte, n ast.Node) error {
- return ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
- switch n := n.(type) {
- case *ast.Document:
- // noop
- case *ast.Heading:
- io.WriteString(w, "\n")
- case *ast.FencedCodeBlock:
- io.WriteString(w, "\n")
- if entering {
- // body
- for i := 0; i < n.Lines().Len(); i++ {
- line := n.Lines().At(i)
- io.WriteString(w, "| ")
- w.Write(line.Value(source))
- }
- }
- case *ast.AutoLink:
- if entering {
- linkColor := r.config.Options["linkColor"].(string)
- io.WriteString(w, "["+linkColor+"]")
- w.Write(n.URL(source))
- } else {
- io.WriteString(w, "[-::]")
- }
- case *ast.Link:
- if entering {
- linkColor := r.config.Options["linkColor"].(string)
- io.WriteString(w, fmt.Sprintf("[%s:::%s]", linkColor, n.Destination))
- } else {
- io.WriteString(w, "[-:::-]")
- }
- case *ast.Text:
- if entering {
- w.Write(n.Segment.Value(source))
- switch {
- case n.HardLineBreak():
- io.WriteString(w, "\n\n")
- case n.SoftLineBreak():
- io.WriteString(w, "\n")
- }
- }
- case *discordmd.Inline:
- if entering {
- switch n.Attr {
- case discordmd.AttrBold:
- io.WriteString(w, "[::b]")
- case discordmd.AttrItalics:
- io.WriteString(w, "[::i]")
- case discordmd.AttrUnderline:
- io.WriteString(w, "[::u]")
- case discordmd.AttrStrikethrough:
- io.WriteString(w, "[::s]")
- case discordmd.AttrMonospace:
- io.WriteString(w, "[::r]")
- }
- } else {
- io.WriteString(w, "[::-]")
- }
- case *discordmd.Mention:
- if entering {
- io.WriteString(w, "[::b]")
- switch {
- case n.Channel != nil:
- io.WriteString(w, "#"+n.Channel.Name)
- case n.GuildUser != nil:
- io.WriteString(w, "@"+n.GuildUser.Username)
- case n.GuildRole != nil:
- io.WriteString(w, "@"+n.GuildRole.Name)
- }
- } else {
- io.WriteString(w, "[::-]")
- }
- case *discordmd.Emoji:
- if entering {
- emojiColor := r.config.Options["emojiColor"].(string)
- io.WriteString(w, "["+emojiColor+"]")
- io.WriteString(w, ":"+n.Name+":")
- } else {
- io.WriteString(w, "[-]")
- }
- }
- return ast.WalkContinue, nil
- })
- }
|