diff --git a/README.md b/README.md index be82827..a5748f9 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ suits you. ## Install -```bash +``` go get github.com/fatih/color ``` @@ -30,6 +30,18 @@ color.Magenta("And many others ..") ``` +### RGB colors + +If your terminal supports 24-bit colors, you can use RGB color codes. + +```go +color.RGB(255, 128, 0).Println("foreground orange") +color.RGB(230, 42, 42).Println("foreground red") + +color.BgRGB(255, 128, 0).Println("background orange") +color.BgRGB(230, 42, 42).Println("background red") +``` + ### Mix and reuse colors ```go @@ -49,6 +61,11 @@ boldRed.Println("This will print text in bold red.") whiteBackground := red.Add(color.BgWhite) whiteBackground.Println("Red text with white background.") + +// Mix with RGB color codes +color.RGB(255, 128, 0).AddBgRGB(0, 0, 0).Println("orange with black background") + +color.BgRGB(255, 128, 0).AddRGB(255, 255, 255).Println("orange background with white foreground") ``` ### Use your own output (io.Writer) diff --git a/color.go b/color.go index c423428..288db16 100644 --- a/color.go +++ b/color.go @@ -98,6 +98,9 @@ const ( FgMagenta FgCyan FgWhite + + // used internally for 256 and 24-bit coloring + foreground ) // Foreground Hi-Intensity text colors @@ -122,6 +125,9 @@ const ( BgMagenta BgCyan BgWhite + + // used internally for 256 and 24-bit coloring + background ) // Background Hi-Intensity text colors @@ -150,6 +156,30 @@ func New(value ...Attribute) *Color { return c } +// RGB returns a new foreground color in 24-bit RGB. +func RGB(r, g, b int) *Color { + return New(foreground, 2, Attribute(r), Attribute(g), Attribute(b)) +} + +// BgRGB returns a new background color in 24-bit RGB. +func BgRGB(r, g, b int) *Color { + return New(background, 2, Attribute(r), Attribute(g), Attribute(b)) +} + +// AddRGB is used to chain foreground RGB SGR parameters. Use as many as parameters to combine +// and create custom color objects. Example: .Add(34, 0, 12).Add(255, 128, 0). +func (c *Color) AddRGB(r, g, b int) *Color { + c.params = append(c.params, foreground, 2, Attribute(r), Attribute(g), Attribute(b)) + return c +} + +// AddRGB is used to chain background RGB SGR parameters. Use as many as parameters to combine +// and create custom color objects. Example: .Add(34, 0, 12).Add(255, 128, 0). +func (c *Color) AddBgRGB(r, g, b int) *Color { + c.params = append(c.params, background, 2, Attribute(r), Attribute(g), Attribute(b)) + return c +} + // Set sets the given parameters immediately. It will change the color of // output with the given SGR parameters until color.Unset() is called. func Set(p ...Attribute) *Color { diff --git a/color_test.go b/color_test.go index a8cc887..b220a1f 100644 --- a/color_test.go +++ b/color_test.go @@ -471,17 +471,17 @@ func readRaw(t *testing.T, r io.Reader) string { } func TestIssue206_1(t *testing.T) { - //visual test, go test -v . - //to see the string with escape codes, use go test -v . > c:\temp\test.txt - var underline = New(Underline).Sprint + // visual test, go test -v . + // to see the string with escape codes, use go test -v . > c:\temp\test.txt + underline := New(Underline).Sprint - var line = fmt.Sprintf("%s %s %s %s", "word1", underline("word2"), "word3", underline("word4")) + line := fmt.Sprintf("%s %s %s %s", "word1", underline("word2"), "word3", underline("word4")) line = CyanString(line) fmt.Println(line) - var result = fmt.Sprintf("%v", line) + result := fmt.Sprintf("%v", line) const expectedResult = "\x1b[36mword1 \x1b[4mword2\x1b[24m word3 \x1b[4mword4\x1b[24m\x1b[0m" if !bytes.Equal([]byte(result), []byte(expectedResult)) { @@ -490,17 +490,35 @@ func TestIssue206_1(t *testing.T) { } func TestIssue206_2(t *testing.T) { - var underline = New(Underline).Sprint - var bold = New(Bold).Sprint + underline := New(Underline).Sprint + bold := New(Bold).Sprint - var line = fmt.Sprintf("%s %s", GreenString(underline("underlined regular green")), RedString(bold("bold red"))) + line := fmt.Sprintf("%s %s", GreenString(underline("underlined regular green")), RedString(bold("bold red"))) fmt.Println(line) - var result = fmt.Sprintf("%v", line) + result := fmt.Sprintf("%v", line) const expectedResult = "\x1b[32m\x1b[4munderlined regular green\x1b[24m\x1b[0m \x1b[31m\x1b[1mbold red\x1b[22m\x1b[0m" if !bytes.Equal([]byte(result), []byte(expectedResult)) { t.Errorf("Expecting %v, got '%v'\n", expectedResult, result) } } + +func TestRGB(t *testing.T) { + tests := []struct { + r, g, b int + }{ + {255, 128, 0}, // orange + {230, 42, 42}, // red + } + + for i, tt := range tests { + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + RGB(tt.r, tt.g, tt.b).Println("foreground") + RGB(tt.r, tt.g, tt.b).AddBgRGB(0, 0, 0).Println("with background") + BgRGB(tt.r, tt.g, tt.b).Println("background") + BgRGB(tt.r, tt.g, tt.b).AddRGB(255, 255, 255).Println("with foreground") + }) + } +}