Skip to content

Commit

Permalink
docs: adjust readme and add example (#2)
Browse files Browse the repository at this point in the history
* docs(readme): show off and brag more

* docs(readme): edit readme example

* docs(readme): further improve readme

* docs(example): minor example edits

* Update example/main.go

* Update example/main.go

* fix: move example to submodule

* docs: use fmt.Fprintf instead of w.Printf in README.md

* fix: update example to use fmt.Fprintln

---------

Co-authored-by: Ayman Bagabas <[email protected]>
  • Loading branch information
meowgorithm and aymanbagabas authored Sep 16, 2024
1 parent d551e7a commit 0bf1814
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 41 deletions.
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)
}

0 comments on commit 0bf1814

Please sign in to comment.