branch: elpa/autothemer commit 48bcecadf1a1547c80a02807a10632097bdc798e Author: Jason Milkins <jason...@gmail.com> Commit: Jason Milkins <jason...@gmail.com>
0.2.13 autothemer-insert-missing-face + CIE DE2000 - Command: autothemer-insert-missing-face - Color distance is now measured by CIE DE2000 - Unthemed faces with colors set by name will be more appropriately matched to the theme palette, when generating face specs. --- autothemer.el | 99 ++++++++---- tests/autothemer-tests.el | 385 ++++++++++++++++++++++++---------------------- 2 files changed, 267 insertions(+), 217 deletions(-) diff --git a/autothemer.el b/autothemer.el index 2b848cbbf1..7aa67762e4 100644 --- a/autothemer.el +++ b/autothemer.el @@ -7,7 +7,7 @@ ;; Maintainer: Jason Milkins <jason...@gmail.com> ;; ;; URL: https://github.com/jasonm23/autothemer -;; Version: 0.2.12 +;; Version: 0.2.13 ;; Package-Requires: ((dash "2.10.0") (emacs "26.1")) ;; ;;; License: @@ -46,6 +46,7 @@ (require 'cl-lib) (require 'dash) (require 'lisp-mnt) +(require 'color) (require 'subr-x) (cl-defstruct @@ -154,7 +155,9 @@ This is the default `autothemer-brightness-group'.") For example: - (autothemer--reduced-spec-to-facespec '(min-colors 60) '(button (:underline t :foreground red))) + (autothemer--reduced-spec-to-facespec + '(min-colors 60) + '(button (:underline t :foreground red))) ;; => `(button (((min-colors 60) (:underline ,t :foreground ,red))))." (let* ((face (elt reduced-specs 0)) (properties (elt reduced-specs 1)) @@ -166,8 +169,9 @@ For example: E.g., (a (b c d) e (f g)) -> (list a (list b c d) e (list f g))." (if (listp expr) `(list ,@(mapcar - (lambda (it) (if (and (listp it) (not (eq (car it) 'quote))) - (autothemer--demote-heads it) it)) + (lambda (it) + (if (and (listp it) (not (eq (car it) 'quote))) + (autothemer--demote-heads it) it)) expr)) expr)) @@ -229,23 +233,34 @@ bindings within both the REDUCED-SPECS and the BODY." (elt ,face-specs ,temp-n)))))) face-customizer)) -(defun autothemer--color-distance (color autothemer-color) - "Return the distance in rgb space between COLOR and AUTOTHEMER-COLOR. -Here, COLOR is an Emacs color specification and AUTOTHEMER-COLOR is of +(defun autothemer--color-distance (color palette-color) + "Return the distance in rgb space between COLOR and PALETTE-COLOR. +Here, COLOR is an Emacs color specification and PALETTE-COLOR is of type `autothemer--color'." + (declare (obsolete 'autothemer--cie-de2000 "0.2.13")) (let ((rgb-1 (autothemer-hex-to-rgb color)) - (rgb-2 (autothemer-hex-to-rgb (autothemer--color-value autothemer-color)))) + (rgb-2 (autothemer-hex-to-rgb palette-color))) (-sum (--zip-with (abs (- it other)) rgb-1 rgb-2)))) +(defun autothemer-cie-de2000 (color-a color-b) + "Return the color distance in CIE Lab space, between COLOR-A and COLOR-B. +Using the CIE-DE2000 algorithm." + (let ((lab-1 (apply 'color-srgb-to-lab (autothemer-hex-to-srgb color-a))) + (lab-2 (apply 'color-srgb-to-lab (autothemer-hex-to-srgb color-b)))) + (color-cie-de2000 lab-1 lab-2))) + (defun autothemer--find-closest-color (colors color) - "Return the element of COLORS that is closest in rgb space to COLOR. + "Return the element of COLORS that is closest in CIE Lab space to COLOR. Here, COLOR is an Emacs color specification and COLORS is a list of `autothemer--color' structs." (let ((min-distance 0) + (color (if (string-match-p "#[[:xdigit:]]\\{6\\}" color) + color + (autothemer-rgb-to-hex (color-values color)))) (closest-color nil)) (mapc (lambda (candidate) (when (color-defined-p (autothemer--color-value candidate)) - (let ((distance (autothemer--color-distance color candidate))) + (let ((distance (autothemer-cie-de2000 color candidate))) (if (or (not closest-color) (< distance min-distance)) (setq closest-color candidate min-distance distance))))) @@ -395,6 +410,18 @@ Otherwise, append NEW-COLUMN to every element of LISTS." (if lists (inline (-zip-with #'append lists new-column)) new-column)) +(defun autothemer-insert-missing-face () + "Insert a face spec template for an unthemed face. +An approximate color from the palette will be used for +color attributes." + (interactive) + (let ((selected (completing-read "Select an un-themed face: " (autothemer--unthemed-faces)))) + (insert + (pp + (autothemer--approximate-spec + (autothemer--alist-to-reduced-spec (intern selected) (autothemer--face-to-alist (intern selected))) + autothemer-current-theme))))) + (defun autothemer--current-theme-guard () "Guard functions from executing when there's no current theme." (unless autothemer-current-theme @@ -511,7 +538,7 @@ Colors are from `autothemer-current-theme'." (defvar autothemer--colors-font-lock-keywords nil) (defun autothemer-colorize () - "In the current buffer, colorize palette color names, from the last evaluated theme, by their color value." + "In the current buffer, colorize palette names, from the last evaluated theme." (interactive) (setq autothemer--colors-font-lock-keywords `((,(regexp-opt (mapcar 'car (autothemer--colorize-alist)) 'words) @@ -551,26 +578,40 @@ In `(h s v)' `h', `s' and `v' are `0.0..1.0'." (defun autothemer-hex-to-rgb (hex) "Convert HEX to `(r g b)'. `r', `g', `b' will be values `0..65535'" - (let ((rgb (string-to-number (substring hex 1) 16))) - (list - (* #x101 (ash (logand #xFF0000 rgb) -16)) - (* #x101 (ash (logand #xFF00 rgb) -8)) - (* #x101 (logand #xFF rgb))))) + (let* ((hex (cond ((stringp hex) hex) + ((autothemer--color-p hex) (autothemer--color-value hex)))) + (rgb (string-to-number (substring hex 1) 16))) + (list + (* #x101 (ash (logand #xFF0000 rgb) -16)) + (* #x101 (ash (logand #xFF00 rgb) -8)) + (* #x101 (logand #xFF rgb))))) + +(defun autothemer-hex-to-srgb (hex) + "Convert HEX to `(r g b)'. +`r', `g', `b' will be values `0.0..1.0'" + (let* ((hex (cond ((stringp hex) hex) + ((autothemer--color-p hex) (autothemer--color-value hex)))) + (rgb (string-to-number (substring hex 1) 16))) + (list + (/ (ash (logand #xFF0000 rgb) -16) 255.0) + (/ (ash (logand #xFF00 rgb) -8) 255.0) + (/ (logand #xFF rgb) 255.0)))) + +(defun autothemer-rgb-to-hex (rgb) + "0..65535 based RGB to hex string." + (eval `(format "#%02X%02X%02X" ,@(mapcar (lambda (it) (round (* 255 (/ it 65535.0)))) rgb)))) (defun autothemer-color-hue (color) "Return the HSV hue of COLOR (hex color or autothemer--color struct)." - (cond ((stringp color) (car (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) - ((autothemer--color-p color) (autothemer-color-hue (autothemer--color-value color))))) + (car (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) (defun autothemer-color-sat (color) "Return the HSV saturation of COLOR (hex color or autothemer--color struct)." - (cond ((stringp color) (cadr (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) - ((autothemer--color-p color) (autothemer-color-sat (autothemer--color-value color))))) + (cadr (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) (defun autothemer-color-brightness (color) "Return the HSV brightness of COLOR (hex color or autothemer--color struct)." - (cond ((stringp color) (caddr (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) - ((autothemer--color-p color) (autothemer-color-brightness (autothemer--color-value color))))) + (caddr (autothemer--color-to-hsv (autothemer-hex-to-rgb color)))) ;;; Sort/Order of autothemer--color structs. @@ -718,13 +759,14 @@ GROUPS are produced by `autothemer-group-colors'." `:group-fn' - mandatory group function `:group-args' - args for `group-fn'" (autothemer--plist-bind (group-fn group-args) options - (let* ((colors-with-groups (mapcar (lambda (color) + (let* ((group-keys (mapcar 'car group-args)) + (colors-with-groups (mapcar (lambda (color) (list (funcall group-fn (autothemer--color-value color) group-args) color)) palette)) (grouped-colors (mapcar (lambda (group) (--reduce (-flatten (cons acc (cdr it))) group)) - (--group-by (car it) colors-with-groups)))) + (-group-by 'car colors-with-groups)))) grouped-colors))) (defun autothemer-group-and-sort (palette options) @@ -793,13 +835,8 @@ to be `autothemer--color' structs. group-args sort-fn) options - (let* ((grouped-colors (autothemer-group-colors - palette - `(:group-fn ,group-fn - :group-args ,group-args))) - (sorted-groups (autothemer-group-sort - grouped-colors - sort-fn))) + (let* ((grouped-colors (autothemer-group-colors palette (list :group-fn (eval group-fn) :group-args (eval group-args)))) + (sorted-groups (autothemer-group-sort grouped-colors (eval sort-fn)))) sorted-groups))) (defun autothemer-groups-to-palette (grouped-palette) diff --git a/tests/autothemer-tests.el b/tests/autothemer-tests.el index bea4071f46..4dfd212bc1 100644 --- a/tests/autothemer-tests.el +++ b/tests/autothemer-tests.el @@ -1,6 +1,6 @@ ;; autothemer-tests.el -;; Version: 0.2.12 +;; Version: 0.2.13 ;;; Code: @@ -191,196 +191,209 @@ (should (eql (autothemer--color-distance "#000001" color-struct) 4369)) (should (eql (autothemer--color-distance "#FF0000" color-struct) 61423)))) + (ert-deftest autothemer-cie-de2000 () + "Test color distance with CIE DE2000." + (let ((color-struct (make-autothemer--color :name "Test" :value "#100000"))) + (should (eql (autothemer-cie-de2000 "#100000" color-struct) 0.0)) + (should (eql (autothemer-cie-de2000 "#100001" color-struct) 0.38178419390755014)) + (should (eql (autothemer-cie-de2000 "#000001" color-struct) 5.891618859336162)) + (should (eql (autothemer-cie-de2000 "#FF0000" color-struct) 48.817322029166725)))) + + (ert-deftest autothemer-rgb-to-hex () + (should (equal (autothemer-rgb-to-hex '(0 0 0)) "#000000")) + (should (equal (autothemer-rgb-to-hex '(65535 0 0)) "#FF0000")) + (should (equal (autothemer-rgb-to-hex '(65535 65535 65535)) "#FFFFFF"))) + ;;; Colorization - (ert-deftest autothemer--colorize-alist () - "Check autothemer-colorize-alist." - (should (equal '(("example-red" . "#781210") - ("example-green" . "#22881F") - ("example-blue" . "#212288") - ("example-purple" . "#812FFF") - ("example-yellow" . "#EFFE00") - ("example-orange" . "#E06500") - ("example-cyan" . "#22DDFF")) - (autothemer--colorize-alist)))) + (ert-deftest autothemer--colorize-alist () + "Check autothemer-colorize-alist." + (should (equal '(("example-red" . "#781210") + ("example-green" . "#22881F") + ("example-blue" . "#212288") + ("example-purple" . "#812FFF") + ("example-yellow" . "#EFFE00") + ("example-orange" . "#E06500") + ("example-cyan" . "#22DDFF")) + (autothemer--colorize-alist)))) ;;; Color/Palette grouping & sorting - (ert-deftest autothemer-color-hue-group () - "Test autothemer-color-hue-group." - (should (equal (autothemer-hue-group "#FF0005") 'red)) - (should (equal (autothemer-hue-group "#00FF00") 'green)) - (should (equal (autothemer-hue-group "#FF00FF") 'magenta)) - (should (equal (autothemer-hue-group "#00FFFF") 'cyan)) - (should (equal (autothemer-hue-group "#0000FF") 'blue-magenta)) - (should (equal (autothemer-hue-group "#FFFF00") 'yellow-green)) - (should (equal (autothemer-hue-group "#FFFF00" autothemer-hue-groups) 'yellow-green)) - (should (equal (autothemer-hue-group "#FFFF00" autothemer-simple-hue-groups) 'green))) - - (ert-deftest autothemer-brightness-group () - "Test autothemer-brightness-group." - (should (equal (autothemer-brightness-group "#FF0005") 'brightness-080-100-percent)) - (should (equal (autothemer-brightness-group "#007700") 'brightness-040-060-percent)) - (should (equal (autothemer-brightness-group "#FF55FF") 'brightness-080-100-percent)) - (should (equal (autothemer-brightness-group "#004444") 'brightness-020-040-percent)) - (should (equal (autothemer-brightness-group "#020202") 'brightness-000-020-percent)) - (should (equal (autothemer-brightness-group - "#020202" - autothemer-dark-mid-light-brightness-groups) - 'dark)) - (should (equal (autothemer-brightness-group - "#777777" - autothemer-dark-mid-light-brightness-groups) - 'mid))) - - (ert-deftest autothemer-saturation-group () - "Test autothemer-saturation-group." - (should (equal (autothemer-saturation-group "#FF0005") 'saturation-080-100-percent)) - (should (equal (autothemer-saturation-group "#007700") 'saturation-080-100-percent)) - (should (equal (autothemer-saturation-group "#FF55FF") 'saturation-060-080-percent)) - (should (equal (autothemer-saturation-group "#004444") 'saturation-080-100-percent)) - (should (equal (autothemer-saturation-group "#020202") 'saturation-000-020-percent)) - (should (equal (autothemer-saturation-group - "#020202" - autothemer-low-mid-high-saturation-groups) - 'low)) - (should (equal (autothemer-saturation-group - "#336677" - autothemer-low-mid-high-saturation-groups) - 'mid))) - - (ert-deftest autothemer-group-colors () - "Group colors into a plist of color lists, with group names as keys." - (should (equal - (autothemer-group-colors - (list - (make-autothemer--color :name 'example-color-005 :value "#112063") - (make-autothemer--color :name 'example-color-006 :value "#88DDCC") - (make-autothemer--color :name 'example-color-006 :value "#99DDCC") - (make-autothemer--color :name 'example-color-006 :value "#FFDDCC") - (make-autothemer--color :name 'example-color-006 :value "#FFEECC") - (make-autothemer--color :name 'example-color-007 :value "#281993") - (make-autothemer--color :name 'example-color-010 :value "#240933")) - (list :group-fn 'autothemer-saturation-group - :group-args autothemer-low-mid-high-saturation-groups)) - '((high - #s(autothemer--color example-color-005 "#112063") - #s(autothemer--color example-color-007 "#281993") - #s(autothemer--color example-color-010 "#240933")) - (mid - #s(autothemer--color example-color-006 "#88DDCC")) - (low - #s(autothemer--color example-color-006 "#99DDCC") - #s(autothemer--color example-color-006 "#FFDDCC") - #s(autothemer--color example-color-006 "#FFEECC")))))) - - (ert-deftest autothemer-group-and-sort () - "Group and sort a palette of `autothemer--color' structs." - (should (equal (autothemer-group-and-sort - (mapcar - 'name-color-to-struct - '((example-color-001 . "#702414") - (example-color-002 . "#642C12") - (example-color-003 . "#583410") - (example-color-004 . "#191204") - (example-color-005 . "#181818") - (example-color-006 . "#191904") - (example-color-007 . "#373D0A") - (example-color-008 . "#243108") - (example-color-009 . "#162506") - (example-color-010 . "#224C0E") - (example-color-011 . "#287C16") - (example-color-012 . "#0E4C0E") - (example-color-013 . "#147024") - (example-color-014 . "#0E4C22") - (example-color-015 . "#167C49") - (example-color-016 . "#20BE87") - (example-color-017 . "#28E4C4") - (example-color-018 . "#1AA4A4") - (example-color-019 . "#178297") - (example-color-020 . "#2391CB") - (example-color-021 . "#13416F") - (example-color-022 . "#13306F") - (example-color-023 . "#112063") - (example-color-024 . "#0D0D4B") - (example-color-025 . "#281993") - (example-color-026 . "#170933") - (example-color-027 . "#620FA9") - (example-color-028 . "#240933") - (example-color-029 . "#63136F") - (example-color-030 . "#330933") - (example-color-031 . "#971782") - (example-color-032 . "#D62499") - (example-color-033 . "#A41A5F") - (example-color-034 . "#D82662") - (example-color-035 . "#B11D37") - (example-color-036 . "#E52929"))) - '(:group-fn autothemer-hue-group - :group-args autothemer-simple-hue-groups - :sort-fn autothemer-darkest-order)) - - '((red - #s(autothemer--color example-color-005 "#181818") - #s(autothemer--color example-color-002 "#642C12") - #s(autothemer--color example-color-001 "#702414") - #s(autothemer--color example-color-035 "#B11D37") - #s(autothemer--color example-color-036 "#E52929")) - (orange - #s(autothemer--color example-color-004 "#191204") - #s(autothemer--color example-color-003 "#583410")) - (green - #s(autothemer--color example-color-006 "#191904") - #s(autothemer--color example-color-009 "#162506") - #s(autothemer--color example-color-008 "#243108") - #s(autothemer--color example-color-007 "#373D0A") - #s(autothemer--color example-color-010 "#224C0E") - #s(autothemer--color example-color-012 "#0E4C0E") - #s(autothemer--color example-color-014 "#0E4C22") - #s(autothemer--color example-color-013 "#147024") - #s(autothemer--color example-color-011 "#287C16")) - (cyan - #s(autothemer--color example-color-021 "#13416F") - #s(autothemer--color example-color-015 "#167C49") - #s(autothemer--color example-color-019 "#178297") - #s(autothemer--color example-color-018 "#1AA4A4") - #s(autothemer--color example-color-016 "#20BE87") - #s(autothemer--color example-color-020 "#2391CB") - #s(autothemer--color example-color-017 "#28E4C4")) - (blue - #s(autothemer--color example-color-026 "#170933") - #s(autothemer--color example-color-028 "#240933") - #s(autothemer--color example-color-024 "#0D0D4B") - #s(autothemer--color example-color-023 "#112063") - #s(autothemer--color example-color-022 "#13306F") - #s(autothemer--color example-color-025 "#281993") - #s(autothemer--color example-color-027 "#620FA9")) - (magenta - #s(autothemer--color example-color-030 "#330933") - #s(autothemer--color example-color-029 "#63136F") - #s(autothemer--color example-color-031 "#971782") - #s(autothemer--color example-color-033 "#A41A5F") - #s(autothemer--color example-color-032 "#D62499") - #s(autothemer--color example-color-034 "#D82662")))))) - - (ert-deftest autothemer-groups-to-palette () - "Flatten a grouped palette (keeping order)." - (should (equal (autothemer-groups-to-palette '((high - #s(autothemer--color example-color-005 "#112063") - #s(autothemer--color example-color-007 "#281993") - #s(autothemer--color example-color-010 "#240933")) - (mid - #s(autothemer--color example-color-006 "#88DDCC")) - (low - #s(autothemer--color example-color-006 "#99DDCC") - #s(autothemer--color example-color-006 "#FFDDCC") - #s(autothemer--color example-color-006 "#FFEECC")))) - '( #s(autothemer--color example-color-005 "#112063") - #s(autothemer--color example-color-007 "#281993") - #s(autothemer--color example-color-010 "#240933") - #s(autothemer--color example-color-006 "#88DDCC") - #s(autothemer--color example-color-006 "#99DDCC") - #s(autothemer--color example-color-006 "#FFDDCC") - #s(autothemer--color example-color-006 "#FFEECC")))))) + (ert-deftest autothemer-color-hue-group () + "Test autothemer-color-hue-group." + (should (equal (autothemer-hue-group "#FF0005") 'red)) + (should (equal (autothemer-hue-group "#00FF00") 'green)) + (should (equal (autothemer-hue-group "#FF00FF") 'magenta)) + (should (equal (autothemer-hue-group "#00FFFF") 'cyan)) + (should (equal (autothemer-hue-group "#0000FF") 'blue-magenta)) + (should (equal (autothemer-hue-group "#FFFF00") 'yellow-green)) + (should (equal (autothemer-hue-group "#FFFF00" autothemer-hue-groups) 'yellow-green)) + (should (equal (autothemer-hue-group "#FFFF00" autothemer-simple-hue-groups) 'green))) + + (ert-deftest autothemer-brightness-group () + "Test autothemer-brightness-group." + (should (equal (autothemer-brightness-group "#FF0005") 'brightness-080-100-percent)) + (should (equal (autothemer-brightness-group "#007700") 'brightness-040-060-percent)) + (should (equal (autothemer-brightness-group "#FF55FF") 'brightness-080-100-percent)) + (should (equal (autothemer-brightness-group "#004444") 'brightness-020-040-percent)) + (should (equal (autothemer-brightness-group "#020202") 'brightness-000-020-percent)) + (should (equal (autothemer-brightness-group + "#020202" + autothemer-dark-mid-light-brightness-groups) + 'dark)) + (should (equal (autothemer-brightness-group + "#777777" + autothemer-dark-mid-light-brightness-groups) + 'mid))) + + (ert-deftest autothemer-saturation-group () + "Test autothemer-saturation-group." + (should (equal (autothemer-saturation-group "#FF0005") 'saturation-080-100-percent)) + (should (equal (autothemer-saturation-group "#007700") 'saturation-080-100-percent)) + (should (equal (autothemer-saturation-group "#FF55FF") 'saturation-060-080-percent)) + (should (equal (autothemer-saturation-group "#004444") 'saturation-080-100-percent)) + (should (equal (autothemer-saturation-group "#020202") 'saturation-000-020-percent)) + (should (equal (autothemer-saturation-group + "#020202" + autothemer-low-mid-high-saturation-groups) + 'low)) + (should (equal (autothemer-saturation-group + "#336677" + autothemer-low-mid-high-saturation-groups) + 'mid))) + + (ert-deftest autothemer-group-colors () + "Group colors into a plist of color lists, with group names as keys." + (should (equal + (autothemer-group-colors + (list + (make-autothemer--color :name 'example-color-005 :value "#112063") + (make-autothemer--color :name 'example-color-006 :value "#88DDCC") + (make-autothemer--color :name 'example-color-006 :value "#99DDCC") + (make-autothemer--color :name 'example-color-006 :value "#FFDDCC") + (make-autothemer--color :name 'example-color-006 :value "#FFEECC") + (make-autothemer--color :name 'example-color-007 :value "#281993") + (make-autothemer--color :name 'example-color-010 :value "#240933")) + (list :group-fn 'autothemer-saturation-group + :group-args autothemer-low-mid-high-saturation-groups)) + '((high + #s(autothemer--color example-color-005 "#112063") + #s(autothemer--color example-color-007 "#281993") + #s(autothemer--color example-color-010 "#240933")) + (mid + #s(autothemer--color example-color-006 "#88DDCC")) + (low + #s(autothemer--color example-color-006 "#99DDCC") + #s(autothemer--color example-color-006 "#FFDDCC") + #s(autothemer--color example-color-006 "#FFEECC")))))) + + (ert-deftest autothemer-group-and-sort () + "Group and sort a palette of `autothemer--color' structs." + (should (equal (autothemer-group-and-sort + (mapcar + 'name-color-to-struct + '((example-color-001 . "#702414") + (example-color-002 . "#642C12") + (example-color-003 . "#583410") + (example-color-004 . "#191204") + (example-color-005 . "#181818") + (example-color-006 . "#191904") + (example-color-007 . "#373D0A") + (example-color-008 . "#243108") + (example-color-009 . "#162506") + (example-color-010 . "#224C0E") + (example-color-011 . "#287C16") + (example-color-012 . "#0E4C0E") + (example-color-013 . "#147024") + (example-color-014 . "#0E4C22") + (example-color-015 . "#167C49") + (example-color-016 . "#20BE87") + (example-color-017 . "#28E4C4") + (example-color-018 . "#1AA4A4") + (example-color-019 . "#178297") + (example-color-020 . "#2391CB") + (example-color-021 . "#13416F") + (example-color-022 . "#13306F") + (example-color-023 . "#112063") + (example-color-024 . "#0D0D4B") + (example-color-025 . "#281993") + (example-color-026 . "#170933") + (example-color-027 . "#620FA9") + (example-color-028 . "#240933") + (example-color-029 . "#63136F") + (example-color-030 . "#330933") + (example-color-031 . "#971782") + (example-color-032 . "#D62499") + (example-color-033 . "#A41A5F") + (example-color-034 . "#D82662") + (example-color-035 . "#B11D37") + (example-color-036 . "#E52929"))) + '(:group-fn 'autothemer-hue-group + :group-args autothemer-simple-hue-groups + :sort-fn 'autothemer-darkest-order)) + + '((red + #s(autothemer--color example-color-005 "#181818") + #s(autothemer--color example-color-002 "#642C12") + #s(autothemer--color example-color-001 "#702414") + #s(autothemer--color example-color-035 "#B11D37") + #s(autothemer--color example-color-036 "#E52929")) + (orange + #s(autothemer--color example-color-004 "#191204") + #s(autothemer--color example-color-003 "#583410")) + (green + #s(autothemer--color example-color-006 "#191904") + #s(autothemer--color example-color-009 "#162506") + #s(autothemer--color example-color-008 "#243108") + #s(autothemer--color example-color-007 "#373D0A") + #s(autothemer--color example-color-010 "#224C0E") + #s(autothemer--color example-color-012 "#0E4C0E") + #s(autothemer--color example-color-014 "#0E4C22") + #s(autothemer--color example-color-013 "#147024") + #s(autothemer--color example-color-011 "#287C16")) + (cyan + #s(autothemer--color example-color-021 "#13416F") + #s(autothemer--color example-color-015 "#167C49") + #s(autothemer--color example-color-019 "#178297") + #s(autothemer--color example-color-018 "#1AA4A4") + #s(autothemer--color example-color-016 "#20BE87") + #s(autothemer--color example-color-020 "#2391CB") + #s(autothemer--color example-color-017 "#28E4C4")) + (blue + #s(autothemer--color example-color-026 "#170933") + #s(autothemer--color example-color-028 "#240933") + #s(autothemer--color example-color-024 "#0D0D4B") + #s(autothemer--color example-color-023 "#112063") + #s(autothemer--color example-color-022 "#13306F") + #s(autothemer--color example-color-025 "#281993") + #s(autothemer--color example-color-027 "#620FA9")) + (magenta + #s(autothemer--color example-color-030 "#330933") + #s(autothemer--color example-color-029 "#63136F") + #s(autothemer--color example-color-031 "#971782") + #s(autothemer--color example-color-033 "#A41A5F") + #s(autothemer--color example-color-032 "#D62499") + #s(autothemer--color example-color-034 "#D82662")))))) + + (ert-deftest autothemer-groups-to-palette () + "Flatten a grouped palette (keeping order)." + (should (equal (autothemer-groups-to-palette '((high + #s(autothemer--color example-color-005 "#112063") + #s(autothemer--color example-color-007 "#281993") + #s(autothemer--color example-color-010 "#240933")) + (mid + #s(autothemer--color example-color-006 "#88DDCC")) + (low + #s(autothemer--color example-color-006 "#99DDCC") + #s(autothemer--color example-color-006 "#FFDDCC") + #s(autothemer--color example-color-006 "#FFEECC")))) + '( #s(autothemer--color example-color-005 "#112063") + #s(autothemer--color example-color-007 "#281993") + #s(autothemer--color example-color-010 "#240933") + #s(autothemer--color example-color-006 "#88DDCC") + #s(autothemer--color example-color-006 "#99DDCC") + #s(autothemer--color example-color-006 "#FFDDCC") + #s(autothemer--color example-color-006 "#FFEECC")))))) (defun autothemer-groups-to-palette (grouped-palette) "Flatten a GROUPED-PALETTE from `autothemer-group-and-sort' to a single list."