Terminal color profile detection + ANSI conversion
Detect the terminal's colour capability (NoTTY / Ascii / ANSI / ANSI256 / TrueColor) and degrade colours, strings and whole output streams to match it.
composer require sugarcraft/candy-palette
use SugarCraft\Palette\{Color, Palette, Profile, ProfileWriter};
$profile = Palette::detect(STDOUT); // Profile::TrueColor | ANSI256 | ANSI | Ascii | NoTTY
echo $profile->label(); // e.g. "No TTY" when piped
// Downsample one colour to an explicit profile
$coral = Color::parse('#ff6b6b'); // r 255, g 107, b 107
$c256 = Palette::toProfile($coral, Profile::ANSI256);
echo $c256->toAnsi256Index(); // 203
echo $c256->toAnsi256Foreground(); // "\x1b[38;5;203m"
// Rewrite every colour in a string for a given profile
$ansi = (new Palette())->withProfile(Profile::ANSI256)
->degrade("\x1b[38;2;255;107;107mhi\x1b[0m"); // "\x1b[38;5;203mhi\x1b[0m"
// Or wrap a stream and let it degrade (or strip, under NoTTY) on write
ProfileWriter::wrap(STDOUT)->write("\x1b[38;2;107;80;255mFancy\x1b[0m\n");
NO_COLOR, FORCE_COLOR, COLORTERM, TERM, TERM_PROGRAM, tmux/screen and whether the stream is a TTY, in upstream's precedence order. The result is a Profile: TrueColor, ANSI256, ANSI, Ascii or NoTTY.Palette::toProfile() / Color::convert() downsample a colour to the 256-colour cube and grey ramp or to the 16 ANSI slots.degrade() rewrites the SGR colours in a string for the current profile and strips every escape under NoTTY. ProfileWriter does the same to everything written to a stream.Color values (StandardColors::$red, $brightBlack, …).DeltaE) and an opt-in nearest-palette matcher (NearestColor).| Class | Method | Description |
|---|---|---|
| Palette | static detect($stream = null, array $env = []): Profile | Detect the colour profile for a stream |
| Palette | __construct($stream = null, array $env = []) / profile() / withProfile(Profile) | Detected profile, or an explicit one |
| Palette | convert(Color) / static toProfile(Color, Profile) | Downsample a colour |
| Palette | degrade(string) / static stripAnsi(string) | Rewrite or strip the escapes in a string |
| Color | static parse('#rrggbb') / static fromHex(0xrrggbb) / new Color(r, g, b, a) | Construct a colour |
| Color | toHex() / toAnsi256Index() / toAnsi16Index() / toAnsiForeground() / toAnsi256Foreground() / toAnsi16Foreground() | Encode a colour |
| Profile | TrueColor, ANSI256, ANSI, Ascii, NoTTY / label() / maxColors() / degradedTo() | Enum of colour profiles |
| ProfileWriter | static wrap($stream, array $env = []) / write(string) / printf(format, ...) | Stream that degrades colour on write |
| StandardColors | static $black, $red, … $brightWhite | The 16 ANSI colours |
VHS-recorded GIFs of every example shipped with the library. Regenerated automatically on every push that touches the source.