From b25ed0989d44037372478751576599c63df41068 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Sat, 2 Mar 2024 17:56:28 +0800 Subject: [PATCH] bahaghari/lib: update Tinted Theming subset --- subprojects/bahaghari/lib/tinted-theming.nix | 124 ++++++++++++++++-- .../tests/lib/tinted-theming/default.nix | 111 +++++++++++++++- .../tinted-theming/sample-legacy-base16.yml | 19 +++ .../tinted-theming/sample-legacy-base24.yml | 27 ++++ 4 files changed, 267 insertions(+), 14 deletions(-) create mode 100644 subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base16.yml create mode 100644 subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base24.yml diff --git a/subprojects/bahaghari/lib/tinted-theming.nix b/subprojects/bahaghari/lib/tinted-theming.nix index 4db68597..e51f0ae0 100644 --- a/subprojects/bahaghari/lib/tinted-theming.nix +++ b/subprojects/bahaghari/lib/tinted-theming.nix @@ -1,5 +1,7 @@ { pkgs, lib }: +# TODO: Remove the legacy scheme support once it is entirely removed in Tinted +# Theming standard. let isBaseX = i: palette: let @@ -10,22 +12,23 @@ let in (pkgs.lib.count (name: pkgs.lib.elem name schemeNames) paletteNames) == i; in -{ +rec { # TODO: Return a Nix object to generate a Tinted Theming color scheme from an # image. generateScheme = image: { }; /* A very naive implementation of checking whether the given palette is a - valid Base16 palette. It simply checks if `base00` to `base0F` is present. + valid Base16 scheme. It simply checks if palette has `base00` to `base0F` + is present as well as other required keys. Type: isBase16 :: Attrs -> Bool Example: - isBase16 (bahaghariLib.importYAML ./base16.yml).palette - => true + isBase16 (bahaghariLib.tinted-theming.importScheme ./base16.yml) + => true - isBase16 (bahaghariLib.importYAML ./base16-scheme-with-missing-base0F.yml).palette - => false + isBase16 (bahaghariLib.tinted-theming.importScheme ./base16-scheme-with-missing-base0F.yml) + => false */ isBase16 = isBaseX 16; @@ -35,11 +38,112 @@ in Type: isBase24 :: Attrs -> Bool Example: - isBase24 (bahaghariLib.importYAML ./base24.yml).palette - => true + isBase24 (bahaghariLib.tinted-theming.importScheme ./base24.yml) + => true - isBase24 (bahaghariLib.importYAML ./base24-scheme-with-missing-base0F.yml).palette - => false + isBase24 (bahaghariLib.tinted-theming.importScheme ./base24-scheme-with-missing-base0F.yml) + => false */ isBase24 = isBaseX 24; + + /* Given a scheme, checks if it's a valid Tinted Theming scheme format (e.g., + Base16, Base24). Take note it doesn't accept deprecated scheme formats. + + Type: isValidScheme :: Attrs -> Bool + + Example: + isValidScheme (bahaghariLib.importYAML ./base24.yml).palette + => true + + isValidScheme (bahaghariLib.importYAML ./base16.yml).palette + => true + */ + isValidScheme = scheme: + scheme?palette && scheme?author && scheme?name; + + /* Checks if the given scheme is in the deprecated Base16 legacy schema. + + Type: isLegacyBase16 :: Attrs -> Bool + + Example: + isLegacyBase16 { + # Some old-ass scheme... + } + => true + + isLegacyBase16 { + # Some new-ass scheme such as from the updated schemes repo... + } + => false + */ + isLegacyScheme = scheme: + scheme?scheme && scheme?author; + + /* Given a legacy BaseX scheme, update the scheme into the current iteration + of the Tinted Theming scheme format. + + Type: modernizeLegacyBaseScheme :: Attrs -> Attrs + + Example: + modernizeLegacyScheme (importYAML ./legacy-base16-scheme.yml) + => { + system = "base16"; + name = "Yo mama"; + author = "You"; + palette = { + # All of the top-level keys except for author, description, and scheme. + }; + } + */ + modernizeLegacyScheme = scheme: + let + system = + if isBase24 scheme + then "base24" + else if isBase16 scheme + then "base16" + else null; + + palette = + pkgs.lib.attrsets.removeAttrs scheme [ "author" "description" "scheme" ]; + in + { + inherit (scheme) author; + inherit palette; + + name = scheme.scheme; + } + // pkgs.lib.optionalAttrs (scheme?description) { inherit (scheme) description; } + // pkgs.lib.optionalAttrs (system != null) { inherit system; }; + + /* Imports a Base16 scheme. This also handles converting the legacy Base16 + schema into the new one if it's detected. Take note, every single token + that is not part of the legacy proper is assumed to be part of the + `palette` of the new schema. + + Type: importBase16Scheme :: Path -> Attrs + + Example: + importScheme ./legacy-base16-scheme.yml + => { + system = "base16"; + name = "Scheme name"; + author = "Scheme author"; + palette = { + # All legacy token that are not included in the old standard proper + # are placed here. This is typically something like `background`, + # `foreground`, and whatnot that are added for enriching the palette + # or just for semantics for the theme designers. + }; + } + */ + importScheme = yamlpath: + let + scheme = lib.importYAML yamlpath; + in + assert pkgs.lib.assertMsg (isValidScheme scheme || isLegacyScheme scheme) + "bahaghariLib.tinted-theming.importScheme: given data is not a valid Tinted Theming scheme"; + if isLegacyScheme scheme + then modernizeLegacyScheme scheme + else scheme; } diff --git a/subprojects/bahaghari/tests/lib/tinted-theming/default.nix b/subprojects/bahaghari/tests/lib/tinted-theming/default.nix index 55bcb08b..24a4a2ea 100644 --- a/subprojects/bahaghari/tests/lib/tinted-theming/default.nix +++ b/subprojects/bahaghari/tests/lib/tinted-theming/default.nix @@ -1,12 +1,105 @@ { pkgs, lib }: let - sampleBase16Scheme = lib.trivial.importYAML ./sample-base16-scheme.yml; - sampleBase16Scheme' = lib.trivial.importYAML ./sample-base16-scheme-with-missing-colors.yml; - sampleBase24Scheme = lib.trivial.importYAML ./sample-base24-scheme.yml; - sampleBase24Scheme' = lib.trivial.importYAML ./sample-base24-scheme-with-missing-colors.yml; + sampleBase16Scheme = lib.tinted-theming.importScheme ./sample-base16-scheme.yml; + sampleBase16Scheme' = lib.tinted-theming.importScheme ./sample-base16-scheme-with-missing-colors.yml; + sampleBase24Scheme = lib.tinted-theming.importScheme ./sample-base24-scheme.yml; + sampleBase24Scheme' = lib.tinted-theming.importScheme ./sample-base24-scheme-with-missing-colors.yml; in pkgs.lib.runTests { + testTintedThemingSchemeImport = { + expr = lib.tinted-theming.importScheme ./sample-base16-scheme.yml; + expected = { + system = "base16"; + name = "Bark on a tree"; + author = "Gabriel Arazas (https://foodogsquared.one)"; + description = "Rusty theme resembling forestry inspired from Nord theme."; + variant = "dark"; + palette = { + base00 = "2b221f"; + base01 = "412c26"; + base02 = "5c362c"; + base03 = "a45b43"; + base04 = "e1bcb2"; + base05 = "f5ecea"; + base06 = "fefefe"; + base07 = "eb8a65"; + base08 = "d03e68"; + base09 = "df937a"; + base0A = "afa644"; + base0B = "85b26e"; + base0C = "eb914a"; + base0D = "c67f62"; + base0E = "8b7ab9"; + base0F = "7f3F83"; + }; + }; + }; + + testTintedThemingLegacyBase24SchemeImport = { + expr = lib.tinted-theming.importScheme ./sample-legacy-base24.yml; + expected = { + system = "base24"; + name = "Scheme Name"; + author = "Scheme Author"; + description = "a short description of the scheme"; + palette = { + base00 = "000000"; + base01 = "111111"; + base02 = "222222"; + base03 = "333333"; + base04 = "444444"; + base05 = "555555"; + base06 = "666666"; + base07 = "777777"; + base08 = "888888"; + base09 = "999999"; + base0A = "aaaaaa"; + base0B = "bbbbbb"; + base0C = "cccccc"; + base0D = "dddddd"; + base0E = "eeeeee"; + base0F = "ffffff"; + base10 = "000000"; + base11 = "111111"; + base12 = "222222"; + base13 = "333333"; + base14 = "444444"; + base15 = "555555"; + base16 = "666666"; + base17 = "777777"; + }; + }; + }; + + testTintedThemingLegacyBase16SchemeImport = { + expr = lib.tinted-theming.importScheme ./sample-legacy-base16.yml; + expected = { + system = "base16"; + name = "Scheme Name"; + author = "Scheme Author"; + description = "a short description of the scheme"; + palette = { + base00 = "000000"; + base01 = "111111"; + base02 = "222222"; + base03 = "333333"; + base04 = "444444"; + base05 = "555555"; + base06 = "666666"; + base07 = "777777"; + base08 = "888888"; + base09 = "999999"; + base0A = "aaaaaa"; + base0B = "bbbbbb"; + base0C = "cccccc"; + base0D = "dddddd"; + base0E = "eeeeee"; + base0F = "ffffff"; + }; + }; + }; + testIsBase16 = { expr = lib.tinted-theming.isBase16 sampleBase16Scheme.palette; expected = true; @@ -26,4 +119,14 @@ pkgs.lib.runTests { expr = lib.tinted-theming.isBase24 sampleBase24Scheme'.palette; expected = false; }; + + testIsALegacyBase16Scheme = { + expr = lib.tinted-theming.isLegacyScheme (lib.importYAML ./sample-legacy-base16.yml); + expected = true; + }; + + testIsALegacyBase24Scheme = { + expr = lib.tinted-theming.isLegacyScheme (lib.importYAML ./sample-legacy-base24.yml); + expected = true; + }; } diff --git a/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base16.yml b/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base16.yml new file mode 100644 index 00000000..2bc97fda --- /dev/null +++ b/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base16.yml @@ -0,0 +1,19 @@ +scheme: "Scheme Name" +author: "Scheme Author" +description: "a short description of the scheme" +base00: "000000" +base01: "111111" +base02: "222222" +base03: "333333" +base04: "444444" +base05: "555555" +base06: "666666" +base07: "777777" +base08: "888888" +base09: "999999" +base0A: "aaaaaa" +base0B: "bbbbbb" +base0C: "cccccc" +base0D: "dddddd" +base0E: "eeeeee" +base0F: "ffffff" diff --git a/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base24.yml b/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base24.yml new file mode 100644 index 00000000..43b68cea --- /dev/null +++ b/subprojects/bahaghari/tests/lib/tinted-theming/sample-legacy-base24.yml @@ -0,0 +1,27 @@ +scheme: "Scheme Name" +author: "Scheme Author" +description: "a short description of the scheme" +base00: "000000" +base01: "111111" +base02: "222222" +base03: "333333" +base04: "444444" +base05: "555555" +base06: "666666" +base07: "777777" +base08: "888888" +base09: "999999" +base0A: "aaaaaa" +base0B: "bbbbbb" +base0C: "cccccc" +base0D: "dddddd" +base0E: "eeeeee" +base0F: "ffffff" +base10: "000000" +base11: "111111" +base12: "222222" +base13: "333333" +base14: "444444" +base15: "555555" +base16: "666666" +base17: "777777"