Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: adjust readme and add example #2

Merged
merged 9 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 65 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,81 @@
# Color Profile
# Colorprofile

<p>
<a href="https://github.com/charmbracelet/colorprofile/releases"><img src="https://img.shields.io/github/release/charmbracelet/colorprofile.svg" alt="Latest Release"></a>
<a href="https://pkg.go.dev/github.com/charmbracelet/colorprofile?tab=doc"><img src="https://godoc.org/github.com/charmbracelet/colorprofile?status.svg" alt="GoDoc"></a>
<a href="https://github.com/charmbracelet/colorprofile/actions"><img src="https://github.com/charmbracelet/colorprofile/actions/workflows/build.yml/badge.svg" alt="Build Status"></a>
</p>

Color Profile is a Go package for working with terminal color profiles and
color degradation.
A simple, powerful—and at times magical—package for detecting terminal color
profiles and performing color (and CSI) degradation.

## Installation
## Detecting the terminal’s color profile

```sh
go get github.com/charmbracelet/colorprofile@latest
Detecting the terminal’s color profile is easy.

```go
import "github.com/charmbracelet/colorprofile"

// Detect the color profile. If you’re planning on writing to stderr you'd want
// to use os.Stderr instead.
p := colorprofile.Detect(os.Stdout, os.Environ())

// Comment on the profile.
fmt.Printf("You know, your colors are quite %s.", func() string {
switch p {
case colorprofile.TrueColor:
return "fancy"
case colorprofile.ANSI256:
return "1990s fancy"
case colorprofile.ANSI:
return "normcore"
case colorprofile.Ascii:
return "ancient"
case colorprofile.NoTTY:
return "naughty!"
}
return "...IDK" // this should never happen
}())
```

## Downsampling colors

When necessary, colors can be downsampled to a given profile, or manually
downsampled to a specific profile.

```go
p := colorprofile.Detect(os.Stdout, os.Environ())
c := color.RGBA{0x6b, 0x50, 0xff, 0xff} // #6b50ff

// Downsample to the detected profile, when necessary.
convertedColor := p.Convert(c)

// Or manually convert to a given profile.
ansi256Color := colorprofile.ANSI256.Convert(c)
ansiColor := colorprofile.ANSI.Convert(c)
noColor := colorprofile.Ascii.Convert(c)
noANSI := colorprofile.NoTTY.Convert(c)
```

## Usage
## Automatic downsampling with a Writer

You can also magically downsample colors in ANSI output, when necessary. If
output is not a TTY ANSI will be dropped entirely.

```go
package main

import (
"fmt"
"image/color"
"os"

"github.com/charmbracelet/colorprofile"
"github.com/lucasb-eyer/go-colorful"
)

func printColor(profile colorprofile.Profile, c color.Color) {
// Print the converted color in the terminal
c = profile.Convert(c)
info := fmt.Sprintf("%T(%v)", c, c)
col, _ := colorful.MakeColor(c)
fmt.Println("This is a nice color:", col.Hex(), info)
}

func main() {
// Get the terminal's color profile
profile := colorprofile.Detect(os.Stdout, os.Environ())

// Convert 24-bit RGB color to the terminal's color profile.
// This will return the closest color in the profile's palette
// if the terminal doesn't support 24-bit color.
mycolor := color.RGBA{0xff, 0x7b, 0xf5, 0xff} // #ff7bf5
printColor(profile, mycolor)

// Use ANSI256 color profile
printColor(colorprofile.ANSI256, mycolor)
}
fancyANSI := "\x1b[38;2;107;80;255mCute puppy!!\x1b[m"

// Automatically downsample for the terminal at stdout.
w := colorprofile.NewWriter(os.Stdout, os.Environ())
fmt.Fprintf(w, fancyANSI)

// Downsample to 4-bit ANSI.
w.Profile = colorprofile.ANSI
fmt.Fprintf(w, myFancyANSI)

// Strip ANSI altogether.
w.Profile = colorprofile.NoTTY
fmt.Fprintf(w, myFancyANSI) // not as fancy
```

## Feedback
Expand All @@ -67,4 +93,3 @@ Part of [Charm](https://charm.sh).
<a href="https://charm.sh/"><img alt="The Charm logo" src="https://stuff.charm.sh/charm-badge.jpg" width="400"></a>

Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة

3 changes: 2 additions & 1 deletion examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ go 1.23.1

replace github.com/charmbracelet/colorprofile => ../

require github.com/charmbracelet/colorprofile v0.0.0-20240913192632-4a4ff4a5f48a

require (
github.com/charmbracelet/colorprofile v0.0.0-20240913192632-4a4ff4a5f48a // indirect
github.com/charmbracelet/x/ansi v0.3.1 // indirect
github.com/charmbracelet/x/term v0.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
71 changes: 71 additions & 0 deletions examples/profile/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package main

import (
"fmt"
"image/color"
"os"

"github.com/charmbracelet/colorprofile"
)

func main() {
// Detect the color profile for stdout.
p := colorprofile.Detect(os.Stdout, os.Environ())
fmt.Printf("Your color profile is what we call '%s'.\n\n", p)

// Let's talk about the profile.
fmt.Printf("You know, your colors are quite %s.\n\n", func() string {
switch p {
case colorprofile.TrueColor:
return "fancy"
case colorprofile.ANSI256:
return "1990s fancy"
case colorprofile.ANSI:
return "normcore"
case colorprofile.Ascii:
return "ancient"
case colorprofile.NoTTY:
return "naughty!"
}
// This should never happen.
return "...IDK"
}())

// Here's a nice color.
myCuteColor := color.RGBA{0x6b, 0x50, 0xff, 0xff} // #6b50ff
fmt.Printf("A cute color we like is: %s.\n\n", colorToHex(myCuteColor))

// Let's convert it to the detected color profile.
theColorWeNeed := p.Convert(myCuteColor)
fmt.Printf("This terminal needs that color to be a %T, at best.\n", theColorWeNeed)
fmt.Printf("In this case that color is %s.\n\n", colorToHex(theColorWeNeed))

// Now let's convert it to a color profile that only supports up to 256
// colors.
ansi256Color := colorprofile.ANSI256.Convert(myCuteColor)
fmt.Printf("Apple Terminal would want this color to be: %d (an %T).\n\n", ansi256Color, ansi256Color)

// But really, who has time to convert? Not you? Well, kiddo, here's
// a magical writer that will just auto-convert whatever ANSI you throw at
// it to the appropriate color profile.
myFancyANSI := "\x1b[38;2;107;80;255mCute \x1b[1;3mpuppy!!\x1b[m"
w := colorprofile.NewWriter(os.Stdout, os.Environ())
fmt.Fprintln(w, "This terminal:", myFancyANSI)

// But we're old school. Make the writer only use 4-bit ANSI, 1980s style.
w.Profile = colorprofile.ANSI
fmt.Fprintln(w, "4-bit ANSI:", myFancyANSI)

// Too colorful. Use black and white only.
w.Profile = colorprofile.Ascii
fmt.Fprintln(w, "Old school cool:", myFancyANSI) // no colors

// That's way too modern. Let's go back to MIT in the 1970s.
w.Profile = colorprofile.NoTTY
fmt.Fprintln(w, "No TTY :(", myFancyANSI) // less fancy
}

func colorToHex(c color.Color) string {
r, g, b, _ := c.RGBA()
return fmt.Sprintf("#%02x%02x%02x", r>>8, g>>8, b>>8)
}
Loading