let # convert rrggbb hex to rgba(r, g, b, a) rgba = lib: color: opacity: let r = toString (hexToDec lib (builtins.substring 0 2 color)); g = toString (hexToDec lib (builtins.substring 2 2 color)); b = toString (hexToDec lib (builtins.substring 4 2 color)); in "rgba(${r}, ${g}, ${b}, ${opacity})"; hexToDec = lib: v: let # Map of hex characters to their decimal values hexToInt = { "0" = 0; "1" = 1; "2" = 2; "3" = 3; "4" = 4; "5" = 5; "6" = 6; "7" = 7; "8" = 8; "9" = 9; "a" = 10; "b" = 11; "c" = 12; "d" = 13; "e" = 14; "f" = 15; "A" = 10; "B" = 11; "C" = 12; "D" = 13; "E" = 14; "F" = 15; }; # Remove any leading `#` from the input cleanHex = if lib.strings.substring 0 1 v == "#" then lib.strings.substring 1 (builtins.stringLength v - 1) v else v; # Convert the cleaned string into characters chars = lib.strings.stringToCharacters cleanHex; in # Fold over the characters to calculate the decimal value builtins.foldl' (acc: char: acc * 16 + hexToInt."${char}") 0 chars; blurImage = pkgs: path: pkgs.runCommand "${builtins.baseNameOf path}-blurred" { buildInputs = [pkgs.imagemagick]; } '' magick ${path} -gaussian-blur 0x12 "$out" ''; generateGtkColors = lib: palette: (lib.concatLines (lib.mapAttrsToList (name: color: "@define-color ${name} ${color};") palette)); in { inherit blurImage generateGtkColors rgba; }