Skip to content

Commit

Permalink
Merge pull request #225 from fatih/add-rgb-api
Browse files Browse the repository at this point in the history
Add RGB API support
  • Loading branch information
fatih authored Oct 3, 2024
2 parents f203fbc + 1ff0f97 commit 546c2d0
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 11 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ suits you.

## Install

```bash
```
go get github.com/fatih/color
```

Expand All @@ -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
Expand All @@ -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)
Expand Down
30 changes: 30 additions & 0 deletions color.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ const (
FgMagenta
FgCyan
FgWhite

// used internally for 256 and 24-bit coloring
foreground
)

// Foreground Hi-Intensity text colors
Expand All @@ -122,6 +125,9 @@ const (
BgMagenta
BgCyan
BgWhite

// used internally for 256 and 24-bit coloring
background
)

// Background Hi-Intensity text colors
Expand Down Expand Up @@ -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 {
Expand Down
38 changes: 28 additions & 10 deletions color_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -490,14 +490,14 @@ 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)) {
Expand All @@ -512,7 +512,7 @@ func TestIssue218(t *testing.T) {
c := New(FgCyan)
c.Println(params...)

var result = c.Sprintln(params...)
result := c.Sprintln(params...)
fmt.Println(params...)
fmt.Print(result)

Expand All @@ -535,3 +535,21 @@ func TestIssue218(t *testing.T) {
t.Errorf("Fprintln: Expecting %v (%v), got '%v (%v)'\n", expectedResult, []byte(expectedResult), result, []byte(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")
})
}
}

0 comments on commit 546c2d0

Please sign in to comment.