package sneklog import ( "fmt" "strings" ) type FgColor uint8 type BgColor uint8 type Attribute uint8 const ( Reset Attribute = iota Bold Faint Italic Underline BlinkSlow BlinkRapid Invert Conceal CrossedOut ) const ( DoubleUnderline Attribute = iota + 21 // Can be disable bold on some terminals DisableBold DisableItalic DisableUnderline DisableBlink DisableInvert DisableConceal DisableCrossedOut ) const ( FgBlack FgColor = iota + 30 FgRed FgGreen FgYellow FgBlue FgMagenta FgCyan FgWhite FgDefault FgColor = 39 ) const ( BgBlack BgColor = iota + 40 BgRed BgGreen BgYellow BgBlue BgMagenta BgCyan BgWhite BgDefault BgColor = 49 ) const ( FgHiBlack FgColor = iota + 90 FgHiRed FgHiGreen FgHiYellow FgHiBlue FgHiMagenta FgHiCyan FgHiWhite ) const ( BgHiBlack BgColor = iota + 100 BgHiRed BgHiGreen BgHiYellow BgHiBlue BgHiMagenta BgHiCyan BgHiWhite ) // This attributes rarely used and not supported by all terminals. const ( Border Attribute = iota + 51 Outline Upperline DisableBorderOutline DisableUpperline ) type ColorStringBuilder struct { str string } func NewColorStringBuilder() *ColorStringBuilder { return &ColorStringBuilder{str: ""} } func (builder *ColorStringBuilder) AddAttribute(attr Attribute) *ColorStringBuilder { builder.str += attr.String() return builder } func (builder *ColorStringBuilder) AddFgColor(color FgColor) *ColorStringBuilder { if color == 0 { return builder } builder.str += color.String() return builder } func (builder *ColorStringBuilder) AddBgColor(color BgColor) *ColorStringBuilder { if color == 0 { return builder } builder.str += color.String() return builder } func (builder *ColorStringBuilder) AddColor256Fg(color uint8) *ColorStringBuilder { builder.str += color256Fg(color) return builder } func (builder *ColorStringBuilder) AddColor256Bg(color uint8) *ColorStringBuilder { builder.str += color256Bg(color) return builder } func (builder *ColorStringBuilder) AddColorRgbFg(r, g, b uint8) *ColorStringBuilder { builder.str += colorRgbFg(r, g, b) return builder } func (builder *ColorStringBuilder) AddColorRgbBg(r, g, b uint8) *ColorStringBuilder { builder.str += colorRgbBg(r, g, b) return builder } func (builder *ColorStringBuilder) AddReset() *ColorStringBuilder { builder.str += "\x1b[0m" return builder } func (builder *ColorStringBuilder) AddText(text string) *ColorStringBuilder { builder.str += text return builder } func (builder *ColorStringBuilder) String() string { if strings.Contains(builder.str, "\x1b[") && !strings.HasSuffix(builder.str, "\x1b[0m") { builder.AddReset() } return builder.str } func (a Attribute) String() string { return fmt.Sprintf("\x1b[%dm", a) } func (a Attribute) Uint8() uint8 { return uint8(a) } func (a Attribute) Int() int { return int(a) } func (c FgColor) String() string { return fmt.Sprintf("\x1b[%dm", c) } func (c FgColor) Uint8() uint8 { return uint8(c) } func (c FgColor) Int() int { return int(c) } func (c BgColor) String() string { return fmt.Sprintf("\x1b[%dm", c) } func (c BgColor) Uint8() uint8 { return uint8(c) } func (c BgColor) Int() int { return int(c) } func color256Fg(color uint8) string { return fmt.Sprintf("\x1b[38;5;%dm", color) } func color256Bg(color uint8) string { return fmt.Sprintf("\x1b[48;5;%dm", color) } func colorRgbFg(r, g, b uint8) string { return fmt.Sprintf("\x1b[38;2;%d;%d;%dm", r, g, b) } func colorRgbBg(r, g, b uint8) string { return fmt.Sprintf("\x1b[48;2;%d;%d;%dm", r, g, b) }