markdown.go

  1package styles
  2
  3import (
  4	"fmt"
  5	"image/color"
  6
  7	"github.com/charmbracelet/glamour/v2"
  8	"github.com/charmbracelet/glamour/v2/ansi"
  9)
 10
 11// lipglossColorToHex converts a color.Color to hex string
 12func lipglossColorToHex(c color.Color) string {
 13	r, g, b, _ := c.RGBA()
 14	return fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
 15}
 16
 17// Helper functions for style pointers
 18func boolPtr(b bool) *bool       { return &b }
 19func stringPtr(s string) *string { return &s }
 20func uintPtr(u uint) *uint       { return &u }
 21
 22// returns a glamour TermRenderer configured with the current theme
 23func GetMarkdownRenderer(width int) *glamour.TermRenderer {
 24	t := CurrentTheme()
 25	r, _ := glamour.NewTermRenderer(
 26		glamour.WithStyles(t.S().Markdown),
 27		glamour.WithWordWrap(width),
 28	)
 29	return r
 30}
 31
 32// returns a glamour TermRenderer with no colors (plain text with structure)
 33func GetPlainMarkdownRenderer(width int) *glamour.TermRenderer {
 34	r, _ := glamour.NewTermRenderer(
 35		glamour.WithStyles(PlainMarkdownStyle()),
 36		glamour.WithWordWrap(width),
 37	)
 38	return r
 39}
 40
 41// PlainMarkdownStyle returns a glamour style config with no colors
 42func PlainMarkdownStyle() ansi.StyleConfig {
 43	t := CurrentTheme()
 44	bgColor := stringPtr(lipglossColorToHex(t.BgBaseLighter))
 45	fgColor := stringPtr(lipglossColorToHex(t.FgMuted))
 46	return ansi.StyleConfig{
 47		Document: ansi.StyleBlock{
 48			StylePrimitive: ansi.StylePrimitive{
 49				Color:           fgColor,
 50				BackgroundColor: bgColor,
 51			},
 52		},
 53		BlockQuote: ansi.StyleBlock{
 54			StylePrimitive: ansi.StylePrimitive{
 55				Color:           fgColor,
 56				BackgroundColor: bgColor,
 57			},
 58			Indent:      uintPtr(1),
 59			IndentToken: stringPtr("│ "),
 60		},
 61		List: ansi.StyleList{
 62			LevelIndent: defaultListIndent,
 63		},
 64		Heading: ansi.StyleBlock{
 65			StylePrimitive: ansi.StylePrimitive{
 66				BlockSuffix:     "\n",
 67				Bold:            boolPtr(true),
 68				Color:           fgColor,
 69				BackgroundColor: bgColor,
 70			},
 71		},
 72		H1: ansi.StyleBlock{
 73			StylePrimitive: ansi.StylePrimitive{
 74				Prefix:          " ",
 75				Suffix:          " ",
 76				Bold:            boolPtr(true),
 77				Color:           fgColor,
 78				BackgroundColor: bgColor,
 79			},
 80		},
 81		H2: ansi.StyleBlock{
 82			StylePrimitive: ansi.StylePrimitive{
 83				Prefix:          "## ",
 84				Color:           fgColor,
 85				BackgroundColor: bgColor,
 86			},
 87		},
 88		H3: ansi.StyleBlock{
 89			StylePrimitive: ansi.StylePrimitive{
 90				Prefix:          "### ",
 91				Color:           fgColor,
 92				BackgroundColor: bgColor,
 93			},
 94		},
 95		H4: ansi.StyleBlock{
 96			StylePrimitive: ansi.StylePrimitive{
 97				Prefix:          "#### ",
 98				Color:           fgColor,
 99				BackgroundColor: bgColor,
100			},
101		},
102		H5: ansi.StyleBlock{
103			StylePrimitive: ansi.StylePrimitive{
104				Prefix:          "##### ",
105				Color:           fgColor,
106				BackgroundColor: bgColor,
107			},
108		},
109		H6: ansi.StyleBlock{
110			StylePrimitive: ansi.StylePrimitive{
111				Prefix:          "###### ",
112				Color:           fgColor,
113				BackgroundColor: bgColor,
114			},
115		},
116		Strikethrough: ansi.StylePrimitive{
117			CrossedOut:      boolPtr(true),
118			Color:           fgColor,
119			BackgroundColor: bgColor,
120		},
121		Emph: ansi.StylePrimitive{
122			Italic:          boolPtr(true),
123			Color:           fgColor,
124			BackgroundColor: bgColor,
125		},
126		Strong: ansi.StylePrimitive{
127			Bold:            boolPtr(true),
128			Color:           fgColor,
129			BackgroundColor: bgColor,
130		},
131		HorizontalRule: ansi.StylePrimitive{
132			Format:          "\n--------\n",
133			Color:           fgColor,
134			BackgroundColor: bgColor,
135		},
136		Item: ansi.StylePrimitive{
137			BlockPrefix:     "• ",
138			Color:           fgColor,
139			BackgroundColor: bgColor,
140		},
141		Enumeration: ansi.StylePrimitive{
142			BlockPrefix:     ". ",
143			Color:           fgColor,
144			BackgroundColor: bgColor,
145		},
146		Task: ansi.StyleTask{
147			StylePrimitive: ansi.StylePrimitive{
148				Color:           fgColor,
149				BackgroundColor: bgColor,
150			},
151			Ticked:   "[✓] ",
152			Unticked: "[ ] ",
153		},
154		Link: ansi.StylePrimitive{
155			Underline:       boolPtr(true),
156			Color:           fgColor,
157			BackgroundColor: bgColor,
158		},
159		LinkText: ansi.StylePrimitive{
160			Bold:            boolPtr(true),
161			Color:           fgColor,
162			BackgroundColor: bgColor,
163		},
164		Image: ansi.StylePrimitive{
165			Underline:       boolPtr(true),
166			Color:           fgColor,
167			BackgroundColor: bgColor,
168		},
169		ImageText: ansi.StylePrimitive{
170			Format:          "Image: {{.text}} →",
171			Color:           fgColor,
172			BackgroundColor: bgColor,
173		},
174		Code: ansi.StyleBlock{
175			StylePrimitive: ansi.StylePrimitive{
176				Prefix:          " ",
177				Suffix:          " ",
178				Color:           fgColor,
179				BackgroundColor: bgColor,
180			},
181		},
182		CodeBlock: ansi.StyleCodeBlock{
183			StyleBlock: ansi.StyleBlock{
184				StylePrimitive: ansi.StylePrimitive{
185					Color:           fgColor,
186					BackgroundColor: bgColor,
187				},
188				Margin: uintPtr(defaultMargin),
189			},
190		},
191		Table: ansi.StyleTable{
192			StyleBlock: ansi.StyleBlock{
193				StylePrimitive: ansi.StylePrimitive{
194					Color:           fgColor,
195					BackgroundColor: bgColor,
196				},
197			},
198		},
199		DefinitionDescription: ansi.StylePrimitive{
200			BlockPrefix:     "\n ",
201			Color:           fgColor,
202			BackgroundColor: bgColor,
203		},
204	}
205}