renderer.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package notifications
  2. import (
  3. "io"
  4. "github.com/diamondburned/ningen/v3/discordmd"
  5. "github.com/yuin/goldmark/ast"
  6. gmr "github.com/yuin/goldmark/renderer"
  7. )
  8. // Using a modified version of the discordmd BasicRenderer
  9. var PlainTextRenderer = newRenderer()
  10. type renderer struct {
  11. config *gmr.Config
  12. }
  13. func newRenderer() *renderer {
  14. config := gmr.NewConfig()
  15. return &renderer{config}
  16. }
  17. func (r *renderer) AddOptions(opts ...gmr.Option) {
  18. for _, opt := range opts {
  19. opt.SetConfig(r.config)
  20. }
  21. }
  22. func (r *renderer) Render(w io.Writer, source []byte, n ast.Node) error {
  23. return ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) {
  24. switch n := n.(type) {
  25. case *ast.Document:
  26. // noop
  27. case *ast.Blockquote:
  28. io.WriteString(w, "\"")
  29. case *ast.Heading:
  30. io.WriteString(w, "\n")
  31. case *ast.FencedCodeBlock:
  32. io.WriteString(w, "\n")
  33. if entering {
  34. for i := range n.Lines().Len() {
  35. line := n.Lines().At(i)
  36. io.WriteString(w, "| ")
  37. w.Write(line.Value(source))
  38. }
  39. }
  40. case *ast.AutoLink:
  41. if entering {
  42. w.Write(n.URL(source))
  43. }
  44. case *ast.Link:
  45. if !entering {
  46. io.WriteString(w, " ("+string(n.Destination)+")")
  47. }
  48. case *discordmd.Inline:
  49. if n.Attr&discordmd.AttrSpoiler != 0 {
  50. if entering {
  51. io.WriteString(w, "*spoiler*")
  52. }
  53. return ast.WalkSkipChildren, nil
  54. }
  55. case *ast.Text:
  56. if entering {
  57. w.Write(n.Segment.Value(source))
  58. switch {
  59. case n.HardLineBreak():
  60. io.WriteString(w, "\n\n")
  61. case n.SoftLineBreak():
  62. io.WriteString(w, "\n")
  63. }
  64. }
  65. case *discordmd.Mention:
  66. if entering {
  67. switch {
  68. case n.Channel != nil:
  69. io.WriteString(w, "#"+n.Channel.Name)
  70. case n.GuildUser != nil:
  71. io.WriteString(w, "@"+n.GuildUser.Username)
  72. case n.GuildRole != nil:
  73. io.WriteString(w, "@"+n.GuildRole.Name)
  74. }
  75. }
  76. case *discordmd.Emoji:
  77. if entering {
  78. io.WriteString(w, ":"+string(n.Name)+":")
  79. }
  80. }
  81. return ast.WalkContinue, nil
  82. })
  83. }