diff --git a/cmd/messages_list.go b/cmd/messages_list.go index e044023..0b45a85 100644 --- a/cmd/messages_list.go +++ b/cmd/messages_list.go @@ -29,7 +29,6 @@ import ( "github.com/skratchdot/open-golang/open" "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/parser" - "github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/text" "golang.design/x/clipboard" ) @@ -39,6 +38,8 @@ type messagesList struct { cfg *config.Config selectedMessageID discord.MessageID + renderer *markdown.Renderer + fetchingMembers struct { mu sync.Mutex value bool @@ -51,6 +52,7 @@ func newMessagesList(cfg *config.Config) *messagesList { ml := &messagesList{ TextView: tview.NewTextView(), cfg: cfg, + renderer: markdown.NewRenderer(cfg.Theme.MessagesList), } ml.Box = ui.ConfigureBox(ml.Box, &cfg.Theme) @@ -62,8 +64,6 @@ func newMessagesList(cfg *config.Config) *messagesList { SetHighlightedFunc(ml.onHighlighted). SetTitle("Messages"). SetInputCapture(ml.onInputCapture) - - markdown.DefaultRenderer.AddOptions(renderer.WithOption("theme", cfg.Theme)) return ml } @@ -168,7 +168,7 @@ func (ml *messagesList) drawContent(message discord.Message) { c := []byte(tview.Escape(message.Content)) if app.cfg.Markdown { ast := discordmd.ParseWithMessage(c, *discordState.Cabinet, &message, false) - markdown.DefaultRenderer.Render(ml, c, ast) + ml.renderer.Render(ml, c, ast) } else { ml.Write(c) // write the content as is } diff --git a/internal/markdown/renderer.go b/internal/markdown/renderer.go index 637c511..1310d3e 100644 --- a/internal/markdown/renderer.go +++ b/internal/markdown/renderer.go @@ -10,34 +10,24 @@ import ( "github.com/ayn2op/discordo/internal/config" "github.com/ayn2op/tview" "github.com/diamondburned/ningen/v3/discordmd" - "github.com/gdamore/tcell/v2" "github.com/yuin/goldmark/ast" gmr "github.com/yuin/goldmark/renderer" ) -var DefaultRenderer = newRenderer() - -type renderer struct { - config *gmr.Config +type Renderer struct { + theme config.MessagesListTheme listIx *int listNested int } -func newRenderer() *renderer { - config := gmr.NewConfig() - return &renderer{config: config} +func NewRenderer(theme config.MessagesListTheme) *Renderer { + return &Renderer{theme: theme} } -// AddOptions implements renderer.Renderer. -func (r *renderer) AddOptions(opts ...gmr.Option) { - for _, opt := range opts { - opt.SetConfig(r.config) - } -} +func (r *Renderer) AddOptions(opts ...gmr.Option) {} -func (r *renderer) Render(w io.Writer, source []byte, node ast.Node) error { - theme := r.config.Options["theme"].(config.Theme) +func (r *Renderer) Render(w io.Writer, source []byte, node ast.Node) error { return ast.Walk(node, func(node ast.Node, entering bool) (ast.WalkStatus, error) { switch node := node.(type) { case *ast.Document: @@ -49,9 +39,9 @@ func (r *renderer) Render(w io.Writer, source []byte, node ast.Node) error { case *ast.FencedCodeBlock: r.renderFencedCodeBlock(w, node, entering, source) case *ast.AutoLink: - r.renderAutoLink(w, node, entering, source, theme.MessagesList.URLStyle.Style) + r.renderAutoLink(w, node, entering, source) case *ast.Link: - r.renderLink(w, node, entering, theme.MessagesList.URLStyle.Style) + r.renderLink(w, node, entering) case *ast.List: r.renderList(w, node, entering) case *ast.ListItem: @@ -60,16 +50,16 @@ func (r *renderer) Render(w io.Writer, source []byte, node ast.Node) error { case *discordmd.Inline: r.renderInline(w, node, entering) case *discordmd.Mention: - r.renderMention(w, node, entering, theme.MessagesList.MentionStyle.Style) + r.renderMention(w, node, entering) case *discordmd.Emoji: - r.renderEmoji(w, node, entering, theme.MessagesList.EmojiStyle.Style) + r.renderEmoji(w, node, entering) } return ast.WalkContinue, nil }) } -func (r *renderer) renderHeading(w io.Writer, node *ast.Heading, entering bool) { +func (r *Renderer) renderHeading(w io.Writer, node *ast.Heading, entering bool) { if entering { io.WriteString(w, strings.Repeat("#", node.Level)) io.WriteString(w, " ") @@ -78,7 +68,7 @@ func (r *renderer) renderHeading(w io.Writer, node *ast.Heading, entering bool) } } -func (r *renderer) renderFencedCodeBlock(w io.Writer, node *ast.FencedCodeBlock, entering bool, source []byte) { +func (r *Renderer) renderFencedCodeBlock(w io.Writer, node *ast.FencedCodeBlock, entering bool, source []byte) { io.WriteString(w, tview.NewLine) if entering { @@ -99,7 +89,9 @@ func (r *renderer) renderFencedCodeBlock(w io.Writer, node *ast.FencedCodeBlock, } } -func (r *renderer) renderAutoLink(w io.Writer, node *ast.AutoLink, entering bool, source []byte, urlStyle tcell.Style) { +func (r *Renderer) renderAutoLink(w io.Writer, node *ast.AutoLink, entering bool, source []byte) { + urlStyle := r.theme.URLStyle + if entering { fg, bg, _ := urlStyle.Decompose() fmt.Fprintf(w, "[%s:%s]", fg, bg) @@ -109,7 +101,8 @@ func (r *renderer) renderAutoLink(w io.Writer, node *ast.AutoLink, entering bool } } -func (r *renderer) renderLink(w io.Writer, node *ast.Link, entering bool, urlStyle tcell.Style) { +func (r *Renderer) renderLink(w io.Writer, node *ast.Link, entering bool) { + urlStyle := r.theme.URLStyle if entering { fg, bg, _ := urlStyle.Decompose() fmt.Fprintf(w, "[%s:%s::%s]", fg, bg, node.Destination) @@ -118,7 +111,7 @@ func (r *renderer) renderLink(w io.Writer, node *ast.Link, entering bool, urlSty } } -func (r *renderer) renderList(w io.Writer, node *ast.List, entering bool) { +func (r *Renderer) renderList(w io.Writer, node *ast.List, entering bool) { if node.IsOrdered() { r.listIx = &node.Start } else { @@ -133,7 +126,7 @@ func (r *renderer) renderList(w io.Writer, node *ast.List, entering bool) { } } -func (r *renderer) renderListItem(w io.Writer, entering bool) { +func (r *Renderer) renderListItem(w io.Writer, entering bool) { if entering { io.WriteString(w, strings.Repeat(" ", r.listNested-1)) @@ -149,7 +142,7 @@ func (r *renderer) renderListItem(w io.Writer, entering bool) { } } -func (r *renderer) renderText(w io.Writer, node *ast.Text, entering bool, source []byte) { +func (r *Renderer) renderText(w io.Writer, node *ast.Text, entering bool, source []byte) { if entering { w.Write(node.Segment.Value(source)) switch { @@ -160,7 +153,7 @@ func (r *renderer) renderText(w io.Writer, node *ast.Text, entering bool, source } } } -func (r *renderer) renderInline(w io.Writer, node *discordmd.Inline, entering bool) { +func (r *Renderer) renderInline(w io.Writer, node *discordmd.Inline, entering bool) { if start, end := attrToTag(node.Attr); entering && start != "" { io.WriteString(w, start) } else { @@ -168,9 +161,10 @@ func (r *renderer) renderInline(w io.Writer, node *discordmd.Inline, entering bo } } -func (r *renderer) renderMention(w io.Writer, node *discordmd.Mention, entering bool, style tcell.Style) { +func (r *Renderer) renderMention(w io.Writer, node *discordmd.Mention, entering bool) { + mentionStyle := r.theme.MentionStyle if entering { - fg, bg, _ := style.Decompose() + fg, bg, _ := mentionStyle.Decompose() fmt.Fprintf(w, "[%s:%s:b]", fg, bg) switch { @@ -191,7 +185,8 @@ func (r *renderer) renderMention(w io.Writer, node *discordmd.Mention, entering } } -func (r *renderer) renderEmoji(w io.Writer, node *discordmd.Emoji, entering bool, emojiStyle tcell.Style) { +func (r *Renderer) renderEmoji(w io.Writer, node *discordmd.Emoji, entering bool) { + emojiStyle := r.theme.EmojiStyle if entering { fg, bg, _ := emojiStyle.Decompose() fmt.Fprintf(w, "[%s:%s]", fg, bg)