lipstick
Safe HaskellNone
LanguageGHC2024

Lipstick.Color

Description

Colours, colour profiles and downsampling.

A Color is what you write in a style. It may be adaptive (lightDark, complete), so it is only turned into a concrete TermColor when the block is serialised and the terminal's ColorProfile is known.

Examples

Colours are written as strings (hex or a palette index), or with the functions and names below:

>>> ["#7D56F4", "#fa0", "201", "5"] :: [Color]
[rgb 125 86 244,rgb 255 170 0,ansi256 201,ansi 5]
>>> (rgb 125 86 244, ansi256 201, brightBlue)
(rgb 125 86 244,ansi256 201,ansi 12)
>>> hex "7D56F4"
Just (rgb 125 86 244)
>>> hex "nope"
Nothing

An adaptive colour is resolved for a profile and background (dark or not) when it is printed:

>>> let accent = lightDark "#5A3FC0" "#B39DFF"
>>> resolveColor TrueColor True accent
Just (TCRGB 179 157 255)
>>> resolveColor TrueColor False accent
Just (TCRGB 90 63 192)
>>> resolveColor ANSI256 True "#7D56F4"
Just (TC256 99)
>>> resolveColor ANSI16 True "#7D56F4"
Just (TC16 12)
>>> resolveColor Ascii True "#7D56F4"
Nothing
>>> resolveColor ANSI16 True (complete "#7D56F4" "99" magenta)
Just (TC16 5)

Gradients and adjustments:

>>> blend 3 ["#ff0000", "#0000ff"]
[rgb 255 0 0,rgb 140 83 162,rgb 0 0 255]
>>> mix 0.25 black white
rgb 29 29 29
>>> darken 0.5 "#7D56F4"
rgb 44 28 94
>>> lighten 0.5 "#7D56F4"
rgb 184 175 255
>>> complementary "#7D56F4"
rgb 138 128 0
Synopsis

Colours

data Color Source #

A colour as written in a style.

Instances

Instances details
Eq Color Source # 
Instance details

Defined in Lipstick.Internal.Color

Methods

(==) :: Color -> Color -> Bool #

(/=) :: Color -> Color -> Bool #

Ord Color Source # 
Instance details

Defined in Lipstick.Internal.Color

Methods

compare :: Color -> Color -> Ordering #

(<) :: Color -> Color -> Bool #

(<=) :: Color -> Color -> Bool #

(>) :: Color -> Color -> Bool #

(>=) :: Color -> Color -> Bool #

max :: Color -> Color -> Color #

min :: Color -> Color -> Color #

IsString Color Source #

Parses "#rgb", "#rrggbb" or a palette index "0"–"255". Calls error on anything else; use hex for a total parser of hex colours.

Instance details

Defined in Lipstick.Internal.Color

Methods

fromString :: String -> Color #

Show Color Source #

Shown as the functions that make it, since the constructors are not exported: rgb 125 86 244, ansi256 201, ansi 5, lightDark …, complete ….

Instance details

Defined in Lipstick.Internal.Color

Methods

showsPrec :: Int -> Color -> ShowS #

show :: Color -> String #

showList :: [Color] -> ShowS #

rgb :: Word8 -> Word8 -> Word8 -> Color Source #

A 24-bit colour from its red, green and blue components. On a terminal with fewer colours, the nearest one it has is used.

ansi :: Int -> Color Source #

One of the 16 basic colours; the index is taken modulo 16.

ansi256 :: Int -> Color Source #

A colour from the 256-colour palette; the index is taken modulo 256.

hex :: Text -> Maybe Color Source #

Parses "#rgb" or "#rrggbb" (the # is optional).

lightDark :: Color -> Color -> Color Source #

lightDark light dark is light on a light background and dark on a dark one. The choice is made when the block is printed, from envDarkBackground.

complete :: Color -> Color -> Color -> Color Source #

complete trueColor color256 color16

The 16 basic colours

What they look like is up to the terminal's palette. Where they are turned into RGB, xterm's palette is used.

black :: Color Source #

Basic colour 0: ansi 0.

red :: Color Source #

Basic colour 1: ansi 1.

green :: Color Source #

Basic colour 2: ansi 2.

yellow :: Color Source #

Basic colour 3: ansi 3.

blue :: Color Source #

Basic colour 4: ansi 4.

magenta :: Color Source #

Basic colour 5: ansi 5.

cyan :: Color Source #

Basic colour 6: ansi 6.

white :: Color Source #

Basic colour 7: ansi 7.

brightBlack :: Color Source #

Basic colour 8: ansi 8.

brightRed :: Color Source #

Basic colour 9: ansi 9.

brightGreen :: Color Source #

Basic colour 10: ansi 10.

brightYellow :: Color Source #

Basic colour 11: ansi 11.

brightBlue :: Color Source #

Basic colour 12: ansi 12.

brightMagenta :: Color Source #

Basic colour 13: ansi 13.

brightCyan :: Color Source #

Basic colour 14: ansi 14.

brightWhite :: Color Source #

Basic colour 15: ansi 15.

Manipulating colours

These work in the OkLab colour space, so steps look even. Palette colours are converted to RGB using xterm's palette, and adaptive colours are transformed in every variant.

mix :: Double -> Color -> Color -> Color Source #

mix t c1 c2 is c1 at 0, c2 at 1, and in between otherwise; t is clamped to [0, 1]. Adaptive colours are mixed variant by variant: for each background and each profile, with the matching variant of the other colour.

blend :: Int -> [Color] -> [Color] Source #

blend n stops is a gradient of n colours going evenly through the stops, starting at the first and ending at the last.

blend2D :: Int -> Int -> Double -> [Color] -> [[Color]] Source #

blend2D width height angle stops is a two-dimensional gradient, as height rows of width colours, at least one each way (no rows without stops). The gradient runs through the stops along the direction given by the angle in degrees, anticlockwise as in lipgloss (0 is left to right, 90 bottom to top).

darken :: Double -> Color -> Color Source #

Move a colour a fraction (0–1) of the way to black.

lighten :: Double -> Color -> Color Source #

Move a colour a fraction (0–1) of the way to white.

complementary :: Color -> Color Source #

The colour on the opposite side of the colour wheel, with the same lightness.

Terminal colours

data TermColor Source #

A concrete colour a terminal understands.

Constructors

TC16 !Word8 
TC256 !Word8 
TCRGB !Word8 !Word8 !Word8 

data ColorProfile Source #

What the output can display, from least to most capable.

Constructors

NoTTY

Not a terminal: no escape sequences at all.

Ascii

Text attributes (bold, underline, …) but no colours.

ANSI16 
ANSI256 
TrueColor 

resolveColor :: ColorProfile -> Bool -> Color -> Maybe TermColor Source #

Resolve an adaptive colour for a profile and for whether the background is dark, then downsample. Nothing means the profile cannot show colours.

downsample :: ColorProfile -> TermColor -> Maybe TermColor Source #

Convert a colour to the closest one the profile supports.

termColorRGB :: TermColor -> (Word8, Word8, Word8) Source #

The RGB value of a terminal colour, using xterm's default palette for the 16 basic colours.