[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/autothemer 48bcecadf1 1/2: 0.2.13 autothemer-insert-missin
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/autothemer 48bcecadf1 1/2: 0.2.13 autothemer-insert-missing-face + CIE DE2000 |
Date: |
Mon, 5 Sep 2022 06:58:23 -0400 (EDT) |
branch: elpa/autothemer
commit 48bcecadf1a1547c80a02807a10632097bdc798e
Author: Jason Milkins <jasonm23@gmail.com>
Commit: Jason Milkins <jasonm23@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 <jasonm23@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."