package style import ( "fmt" "os" "strings" ) var noColor = os.Getenv("NO_COLOR") != "" || os.Getenv("TERM") == "dumb" type Style struct { codes []string } func New() *Style { return &Style{} } func (s *Style) clone() *Style { c := &Style{codes: make([]string, len(s.codes))} copy(c.codes, s.codes) return c } func (s *Style) Bold() *Style { c := s.clone() c.codes = append(c.codes, "1") return c } func (s *Style) Dim() *Style { c := s.clone() c.codes = append(c.codes, "2") return c } func (s *Style) Italic() *Style { c := s.clone() c.codes = append(c.codes, "3") return c } func (s *Style) Underline() *Style { c := s.clone() c.codes = append(c.codes, "4") return c } func (s *Style) Fg(c Color) *Style { n := s.clone() n.codes = append(n.codes, fmt.Sprintf("%d", c)) return n } func (s *Style) Bg(c Color) *Style { n := s.clone() n.codes = append(n.codes, fmt.Sprintf("%d", c+10)) return n } func (s *Style) FgHex(hex string) *Style { n := s.clone() r, g, b := hexToRGB(hex) n.codes = append(n.codes, fmt.Sprintf("38;2;%d;%d;%d", r, g, b)) return n } func (s *Style) BgHex(hex string) *Style { n := s.clone() r, g, b := hexToRGB(hex) n.codes = append(n.codes, fmt.Sprintf("48;2;%d;%d;%d", r, g, b)) return n } func hexToRGB(hex string) (r, g, b int) { hex = strings.TrimPrefix(hex, "#") if len(hex) != 6 { return 255, 255, 255 } r = parseHex(hex[0:2]) g = parseHex(hex[2:4]) b = parseHex(hex[4:6]) return } func parseHex(s string) int { v := 0 for _, c := range s { v *= 16 switch { case c >= '0' && c <= '9': v += int(c - '0') case c >= 'a' && c <= 'f': v += int(c - 'a' + 10) case c >= 'A' && c <= 'F': v += int(c - 'A' + 10) } } return v } func (s *Style) Render(text string) string { if noColor || len(s.codes) == 0 { return text } return "\033[" + strings.Join(s.codes, ";") + "m" + text + "\033[0m" } type Color int const ( ColorBlack Color = 30 ColorRed Color = 31 ColorGreen Color = 32 ColorYellow Color = 33 ColorBlue Color = 34 ColorMagenta Color = 35 ColorCyan Color = 36 ColorWhite Color = 37 ) var ( Red = New().Fg(ColorRed) Green = New().Fg(ColorGreen) Yellow = New().Fg(ColorYellow) Cyan = New().Fg(ColorCyan) Blue = New().Fg(ColorBlue) Magenta = New().Fg(ColorMagenta) White = New().Fg(ColorWhite) Bold = New().Bold() Dim = New().Dim() )