Refactor palette around color objects

This commit is contained in:
Andrew Kvalheim 2024-04-25 21:04:34 -07:00
parent a881ba4f77
commit ce62da6130
2 changed files with 34 additions and 18 deletions

View file

@ -60,11 +60,15 @@ rec {
(color "${pad "" ""}")
]);
# Adapted from https://bottosson.github.io/posts/colorwrong/#what-can-we-do%3F
linearRgbToRgb = rgb:
mapAttrs (_: u: if u > 0.0031308 then 1.055 * (pow124 u) - 0.055 else 12.92 * u) rgb;
oklchToCss = { l, c, h }: "oklch(${toString l} ${toString c} ${toString h})";
oklchToRgb = target:
oklchToLinearRgb = target:
let
toLinearRgb = { l, c, h }:
convert = { l, c, h }:
let
# Adapted from https://drafts.csswg.org/css-color-4/#color-conversion-code
a = c * cos (h * pi / 180);
@ -82,22 +86,20 @@ rec {
in
if all (u: 0 <= u && u <= 1) (attrValues rgb) then rgb else null;
# Adapted from https://bottosson.github.io/posts/colorwrong/#what-can-we-do%3F
oetf = u: if u > 0.0031308 then 1.055 * (pow124 u) - 0.055 else 12.92 * u;
inGamut = c: toLinearRgb (target // { inherit c; }) != null;
result = convert target;
inGamut = c: convert (target // { inherit c; }) != null;
clamped = target // { c = findHighest inGamut 0.0000005 0 0.37; };
linearRgb = toLinearRgb target;
in
throwIf (linearRgb == null)
throwIf (result == null)
"Not representable in sRGB\n Target: ${oklchToCss target}\n Clamped: ${oklchToCss clamped}"
(mapAttrs (_: oetf) linearRgb);
result;
printableLength = text: fold add 0 (map (v: if isList v then 0 else stringLength v) (split "\\[[^m]*m" text));
printablePad = width: placeholder: text: text + replicate (width - printableLength text) placeholder;
rgbToAnsi = rgb: with mapAttrs (_: v: toString (round (v * 255))) rgb; "38;2;${r};${g};${b}";
rgbToHex = { r, g, b }:
let f = x: fixedWidthNumber 2 (toHexString (round (x * 255)));
in "#${f r}${f g}${f b}";

View file

@ -3,7 +3,7 @@
let
inherit (builtins) listToAttrs mapAttrs;
inherit (lib) concatLines imap0 mapAttrsRecursive mapAttrsToList nameValuePair;
inherit (import ./lib.nix { inherit lib; }) oklchToRgb rgbToHex round;
inherit (import ./lib.nix { inherit lib; }) linearRgbToRgb oklchToCss oklchToLinearRgb rgbToAnsi rgbToHex;
dark = c: c // { l = 0.35; c = if c.c == 0 then 0 else 0.060; };
dim = c: c // { l = 0.50; c = if c.c == 0 then 0 else 0.150; };
@ -11,7 +11,7 @@ let
ansiNames = [ "black" "red" "green" "yellow" "blue" "magenta" "cyan" "white" ];
oklch = rec {
spec = rec {
# Base Monokai
black = { l = 0.22; c = 0.000; h = 0; };
blue = { l = 0.83; c = 0.108; h = 212; };
@ -46,6 +46,18 @@ let
vermilion-dark-contrast-minimum = contrast-minimum vermilion-dark;
white-dark = dark white;
};
mkColor = oklch: rec {
inherit oklch;
ansi = rgbToAnsi rgb;
css = oklchToCss oklch;
hex = rgbToHex rgb;
linearRgb = oklchToLinearRgb oklch;
rgb = linearRgbToRgb linearRgb;
};
colors = mapAttrs (_: mkColor) spec;
in
rec {
ansi =
@ -53,15 +65,17 @@ rec {
base = listToAttrs (imap0 (i: n: nameValuePair n (toString (30 + i))) ansiNames);
effect = p: mapAttrs (_: a: "${p};${a}") base;
in
base
// { bold = effect "1"; dim = effect "2" // { italic = effect "2;3"; }; italic = effect "3"; }
// { true = mapAttrs (_: c: with mapAttrs (_: v: toString (round (v * 255))) c; "38;2;${r};${g};${b}") rgb; };
base // { bold = effect "1"; dim = effect "2" // { italic = effect "2;3"; }; italic = effect "3"; };
ansiFormat = mapAttrsRecursive (_: a: t: "[${a}m${t}") ansi;
hex = mapAttrs (_: rgbToHex) rgb;
hex = mapAttrs (_: c: c.hex) colors;
report = concatLines (mapAttrsToList (n: f: f " ${n}") ansiFormat.true);
report = concatLines (mapAttrsToList
(name: { ansi, css, hex, rgb, ... }:
"[${ansi}m ${name} ${ansiFormat.black "${css} ${hex}"}")
colors
);
rgb = mapAttrs (_: oklchToRgb) oklch;
rgb = mapAttrs (_: c: c.rgb) colors;
}