From ce62da613094b75397e9baa07be6e2c66994d730 Mon Sep 17 00:00:00 2001 From: Andrew Kvalheim Date: Thu, 25 Apr 2024 21:04:34 -0700 Subject: [PATCH] Refactor palette around color objects --- common/resources/lib.nix | 22 ++++++++++++---------- common/resources/palette.nix | 30 ++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/common/resources/lib.nix b/common/resources/lib.nix index b898b6f..068d95c 100644 --- a/common/resources/lib.nix +++ b/common/resources/lib.nix @@ -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}"; diff --git a/common/resources/palette.nix b/common/resources/palette.nix index af118b7..6d3e278 100644 --- a/common/resources/palette.nix +++ b/common/resources/palette.nix @@ -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; }