package sneklog import ( "fmt" "strings" ) // FgColor is a basic ANSI foreground color code. type FgColor uint8 // BgColor is a basic ANSI background color code. type BgColor uint8 // FgColor256 is an ANSI 256-color foreground value. type FgColor256 uint8 // BgColor256 is an ANSI 256-color background value. type BgColor256 uint8 // BgColorRGB is an ANSI truecolor background value encoded as RGB bytes. type BgColorRGB []uint8 // FgColorRGB is an ANSI truecolor foreground value encoded as RGB bytes. type FgColorRGB []uint8 // Attribute is an ANSI text attribute code. type Attribute uint8 // NewBgColorRGB builds an RGB background color value. func NewBgColorRGB(r, g, b uint8) BgColorRGB { return BgColorRGB{r, g, b} } // NewFgColorRGB builds an RGB foreground color value. func NewFgColorRGB(r, g, b uint8) FgColorRGB { return FgColorRGB{r, g, b} } // Text attribute codes. const ( Reset Attribute = iota Bold Faint Italic Underline BlinkSlow BlinkRapid Invert Conceal CrossedOut ) // Additional text attribute codes. const ( DoubleUnderline Attribute = iota + 21 // Can be disable bold on some terminals DisableBold DisableItalic DisableUnderline DisableBlink DisableInvert DisableConceal DisableCrossedOut ) // Basic foreground color codes. const ( FgNone = 0 FgBlack FgColor = iota + 30 FgRed FgGreen FgYellow FgBlue FgMagenta FgCyan FgWhite FgDefault FgColor = 39 ) // Basic background color codes. const ( BgNone = 0 BgBlack BgColor = iota + 40 BgRed BgGreen BgYellow BgBlue BgMagenta BgCyan BgWhite BgDefault BgColor = 49 ) // High-intensity foreground color codes. const ( FgHiBlack FgColor = iota + 90 FgHiRed FgHiGreen FgHiYellow FgHiBlue FgHiMagenta FgHiCyan FgHiWhite ) // High-intensity background color codes. const ( BgHiBlack BgColor = iota + 100 BgHiRed BgHiGreen BgHiYellow BgHiBlue BgHiMagenta BgHiCyan BgHiWhite ) // Rarely used text attribute codes that are not supported by all terminals. const ( Border Attribute = iota + 51 Outline Upperline DisableBorderOutline DisableUpperline ) // ColorStringBuilder incrementally builds ANSI-colored strings. type ColorStringBuilder struct { str string } // NewColorStringBuilder creates a builder for composing ANSI-colored strings. func NewColorStringBuilder() *ColorStringBuilder { return &ColorStringBuilder{str: ""} } // AddAttribute appends an ANSI text attribute sequence. func (builder *ColorStringBuilder) AddAttribute(attr Attribute) *ColorStringBuilder { builder.str += attr.String() return builder } // AddFgColor appends a basic ANSI foreground color sequence. func (builder *ColorStringBuilder) AddFgColor(color FgColor) *ColorStringBuilder { if color <= 0 { return builder } builder.str += color.String() return builder } // AddBgColor appends a basic ANSI background color sequence. func (builder *ColorStringBuilder) AddBgColor(color BgColor) *ColorStringBuilder { if color <= 0 { return builder } builder.str += color.String() return builder } // AddForeground256Color appends a 256-color foreground sequence. func (builder *ColorStringBuilder) AddForeground256Color(color FgColor256) *ColorStringBuilder { builder.str += color.String() return builder } // AddColor256Fg appends a 256-color foreground sequence. // Deprecated: use AddForeground256Color. This method will be removed in v3. func (builder *ColorStringBuilder) AddColor256Fg(color uint8) *ColorStringBuilder { return builder.AddForeground256Color(FgColor256(color)) } // AddBackground256Color appends a 256-color background sequence. func (builder *ColorStringBuilder) AddBackground256Color(color BgColor256) *ColorStringBuilder { builder.str += color.String() return builder } // AddColor256Bg appends a 256-color background sequence. // Deprecated: use AddBackground256Color. This method will be removed in v3. func (builder *ColorStringBuilder) AddColor256Bg(color uint8) *ColorStringBuilder { return builder.AddBackground256Color(BgColor256(color)) } // AddForegroundRGB appends an RGB foreground sequence. func (builder *ColorStringBuilder) AddForegroundRGB(color FgColorRGB) *ColorStringBuilder { builder.str += color.String() return builder } // AddColorRgbFg appends an RGB foreground sequence. // Deprecated: use AddForegroundRGB. This method will be removed in v3. func (builder *ColorStringBuilder) AddColorRgbFg(r, g, b uint8) *ColorStringBuilder { return builder.AddForegroundRGB(FgColorRGB{r, g, b}) } // AddBackgroundRGB appends an RGB background sequence. func (builder *ColorStringBuilder) AddBackgroundRGB(color BgColorRGB) *ColorStringBuilder { builder.str += color.String() return builder } // AddColorRgbBg appends an RGB background sequence. // Deprecated: use AddBackgroundRGB. This method will be removed in v3. func (builder *ColorStringBuilder) AddColorRgbBg(r, g, b uint8) *ColorStringBuilder { return builder.AddBackgroundRGB(BgColorRGB{r, g, b}) } // AddReset appends the ANSI reset sequence. func (builder *ColorStringBuilder) AddReset() *ColorStringBuilder { builder.str += "\x1b[0m" return builder } // AddText appends plain text to the builder. func (builder *ColorStringBuilder) AddText(text string) *ColorStringBuilder { builder.str += text return builder } // String returns the built string and appends a reset sequence when needed. func (builder *ColorStringBuilder) String() string { if strings.Contains(builder.str, "\x1b[") && !strings.HasSuffix(builder.str, "\x1b[0m") { builder.AddReset() } return builder.str } // String returns the ANSI escape sequence for the attribute. func (a Attribute) String() string { return fmt.Sprintf("\x1b[%dm", a) } // Uint8 returns the raw attribute value. func (a Attribute) Uint8() uint8 { return uint8(a) } // Int returns the raw attribute value as int. func (a Attribute) Int() int { return int(a) } // String returns the ANSI escape sequence for the foreground color. func (c FgColor) String() string { return fmt.Sprintf("\x1b[%dm", c) } // Uint8 returns the raw foreground color value. func (c FgColor) Uint8() uint8 { return uint8(c) } // Int returns the raw foreground color value as int. func (c FgColor) Int() int { return int(c) } // String returns the ANSI escape sequence for the background color. func (c BgColor) String() string { return fmt.Sprintf("\x1b[%dm", c) } // Uint8 returns the raw background color value. func (c BgColor) Uint8() uint8 { return uint8(c) } // Int returns the raw background color value as int. func (c BgColor) Int() int { return int(c) } // String returns the ANSI escape sequence for the 256-color foreground value. func (c FgColor256) String() string { return fmt.Sprintf("\u001B[38;5;%dm", c) } // Uint8 returns the raw 256-color foreground value. func (c FgColor256) Uint8() uint8 { return uint8(c) } // Int returns the raw 256-color foreground value as int. func (c FgColor256) Int() int { return int(c) } // String returns the ANSI escape sequence for the 256-color background value. func (c BgColor256) String() string { return fmt.Sprintf("\u001B[48;5;%dm", c) } // Uint8 returns the raw 256-color background value. func (c BgColor256) Uint8() uint8 { return uint8(c) } // Int returns the raw 256-color background value as int. func (c BgColor256) Int() int { return int(c) } // String returns the ANSI escape sequence for the RGB foreground value. func (c FgColorRGB) String() string { return fmt.Sprintf("\x1b[38;2;%d;%d;%dm", c[0], c[1], c[2]) } // Uint8 returns the raw RGB foreground components. func (c FgColorRGB) Uint8() []uint8 { return c } // String returns the ANSI escape sequence for the RGB background value. func (c BgColorRGB) String() string { return fmt.Sprintf("\x1b[48;2;%d;%d;%dm", c[0], c[1], c[2]) } // Uint8 returns the raw RGB background components. func (c BgColorRGB) Uint8() []uint8 { return c }