[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/autothemer 5a193c796a: 0.2.11 - develop color grouping and
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/autothemer 5a193c796a: 0.2.11 - develop color grouping and sorting. (#25) |
Date: |
Fri, 2 Sep 2022 12:58:16 -0400 (EDT) |
branch: elpa/autothemer
commit 5a193c796a5499a9b0aa0b40372d3746bc25fe39
Author: Jason Milkins <jasonm23@users.noreply.github.com>
Commit: GitHub <noreply@github.com>
0.2.11 - develop color grouping and sorting. (#25)
* 0.2.11 - develop color grouping and sorting.
---
README.md | 5 +-
autothemer.el | 362 +++++++++++++++++++++---
function-reference.md | 696 ++++++++++++++++++++++++++++++++++++++++++++++
tests/autothemer-tests.el | 321 ++++++++++++++++-----
4 files changed, 1270 insertions(+), 114 deletions(-)
diff --git a/README.md b/README.md
index 39466081d2..2fca846fb3 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,9 @@
Autothemer provides `autothemer-deftheme` a macro wrapper for `deftheme` and
`custom-theme-set-faces` which creates a custom color theme.
-The package also includes some useful theme development features... read on.
+The package also includes useful theme development features see below.
+
+---
## News
@@ -393,6 +395,7 @@ I'll add some more palette SVG templates in the Wiki, link
to any more you creat
[Wiki page here](/jasonm23/autothemer/wiki/Palette-SVG-Templates)
+### [Complete Command/Function Reference](function-reference.md)
# TVA
diff --git a/autothemer.el b/autothemer.el
index 6bf5d5f45e..174f60394e 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.10
+;; Version: 0.2.11
;; Package-Requires: ((dash "2.10.0") (emacs "26.1"))
;;
;;; License:
@@ -25,11 +25,26 @@
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
-
-;; Reduces the amount of boilerplate code needed to define custom themes. Also
-;; provides the user with an interactive command that automatically generates
-;; face customization code using the theme's color palette.
-
+;;
+;; Reduce the amount of pain and boilerplate code needed to create custom
themes using `autothemer-deftheme'.
+;;
+;; Autothemer also includes interactive commands and functions to
+;; assist with theme building, here are a few highlights...
+;;
+;; - Generate specs for unthemed faces using the theme color palette.
+;; - `autothemer-generate-templates'
+;; - `autothemer-generate-templates-filtered' (filter by regexp)
+;; - Generate a palette SVG image
+;; - `autothemer-generate-palette-svg'
+;; - Insert a color name or color from the active palette
+;; - `autothemer-insert-color-name'
+;; - `autothemer-insert-color'
+;; - Colorize/font-lock palette color names in the buffer
+;; - `autothemer-colorize' (requires `rainbow-mode' during development.)
+;;
+;;
+;; Note in the function reference, the fucntion prefix `autothemer--'
indicates internal
+;; functions.
;;; Code:
(require 'cl-lib)
(require 'dash)
@@ -48,17 +63,102 @@
name
description)
-(defvar autothemer--current-theme nil
+(defvar autothemer-current-theme nil
"Internal variable of type `autothemer--theme' used by autothemer.
Contains the color palette and the list of faces most recently
customized using `autothemer-deftheme'.")
+(defvar autothemer-hue-groups
+ '((red (345 . 10))
+ (red-orange (10 . 20))
+ (orange-brown (20 . 40))
+ (orange-yellow (40 . 50))
+ (yellow (50 . 60))
+ (yellow-green (60 . 80))
+ (green (80 . 140))
+ (green-cyan (140 . 170))
+ (cyan (170 . 200))
+ (cyan-blue (200 . 220))
+ (blue (220 . 240))
+ (blue-magenta (240 . 280))
+ (magenta (280 . 320))
+ (magenta-pink (320 . 330))
+ (pink (330 . 345)))
+ "Set of perceptual color ranges.")
+
+(defvar autothemer-simple-hue-groups
+ '((red (345 . 20))
+ (orange (20 . 50))
+ (yellow (50 . 60))
+ (green (60 . 140))
+ (cyan (140 . 220))
+ (blue (220 . 280))
+ (magenta (280 . 345)))
+ "Simple set of color groups.")
+
+(defvar autothemer-low-mid-high-saturation-groups
+ '((low (0.0 . 0.3333333333333333))
+ (mid (0.3333333333333334 . 0.6666666666666666))
+ (high (0.6666666666666667 . 1.0)))
+ "Low, mid & high saturation groups.")
+
+(defvar autothemer-20-percent-saturation-groups
+ '((saturation-000-020-percent (0.0 . 0.2))
+ (saturation-020-040-percent (0.2 . 0.4))
+ (saturation-040-060-percent (0.4 . 0.6))
+ (saturation-060-080-percent (0.6 . 0.8))
+ (saturation-080-100-percent (0.8 . 1.0)))
+ "Saturation grouping at 20% intervals.
+This is the default for `autothemer-saturation-group'.")
+
+(defvar autothemer-10-percent-saturation-groups
+ '((saturation-000-010-percent (0.0 . 0.1))
+ (saturation-010-020-percent (0.1 . 0.2))
+ (saturation-020-030-percent (0.2 . 0.3))
+ (saturation-030-040-percent (0.3 . 0.4))
+ (saturation-040-050-percent (0.4 . 0.5))
+ (saturation-050-060-percent (0.5 . 0.6))
+ (saturation-060-070-percent (0.6 . 0.7))
+ (saturation-070-080-percent (0.7 . 0.8))
+ (saturation-080-090-percent (0.8 . 0.9))
+ (saturation-090-100-percent (0.9 . 1.0)))
+ "Saturation grouping at 10% intervals.")
+
+(defvar autothemer-dark-mid-light-brightness-groups
+ '((dark (0.0 . 0.3333333333333333))
+ (mid (0.3333333333333334 . 0.6666666666666666))
+ (light (0.6666666666666667 . 1.0)))
+ "Dark, mid & light brightness groups.")
+
+(defvar autothemer-20-percent-brightness-groups
+ '((brightness-000-020-percent (0.0 . 0.2))
+ (brightness-020-040-percent (0.2 . 0.4))
+ (brightness-040-060-percent (0.4 . 0.6))
+ (brightness-060-080-percent (0.6 . 0.8))
+ (brightness-080-100-percent (0.8 . 1.0)))
+ "Brightness groups at 20% intervals.
+This is the default `autothemer-brightness-group'.")
+
+(defvar autothemer-10-percent-brightness-groups
+ '((brightness-000-010-percent (0.0 . 0.1))
+ (brightness-010-020-percent (0.1 . 0.2))
+ (brightness-020-030-percent (0.2 . 0.3))
+ (brightness-030-040-percent (0.3 . 0.4))
+ (brightness-040-050-percent (0.4 . 0.5))
+ (brightness-050-060-percent (0.5 . 0.6))
+ (brightness-060-070-percent (0.6 . 0.7))
+ (brightness-070-080-percent (0.7 . 0.8))
+ (brightness-080-090-percent (0.8 . 0.9))
+ (brightness-090-100-percent (0.9 . 1.0)))
+ "Brightness grouping at 10% intervals.")
+
(defun autothemer--reduced-spec-to-facespec (display reduced-specs)
"Create a face spec for DISPLAY, with specs REDUCED-SPECS.
-E.g., (autothemer--reduced-spec-to-facespec '(min-colors 60)
-'(button (:underline t :foreground red)))
--> `(button (((min-colors 60) (:underline ,t :foreground
-,red))))."
+
+For example:
+
+ (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))
(spec (autothemer--demote-heads `(list (,display ,properties)))))
@@ -77,7 +177,7 @@ E.g., (a (b c d) e (f g)) -> (list a (list b c d) e (list f
g))."
;;;###autoload
(defmacro autothemer-deftheme (name description palette reduced-specs &rest
body)
"Define a theme NAME with description DESCRIPTION.
-A color PALETTE can be used to define let*-like
+A color PALETTE can be used to define `let*'-like
bindings within both the REDUCED-SPECS and the BODY."
(let* ((face-names (-map #'car reduced-specs))
(color-names (-map #'car (-drop 1 palette)))
@@ -112,7 +212,7 @@ bindings within both the REDUCED-SPECS and the BODY."
in ,temp-defined-colors
collect
(make-autothemer--color :name ,temp-colorname
:value ,temp-color)))
- (setq autothemer--current-theme
+ (setq autothemer-current-theme
(make-autothemer--theme
:name ,(symbol-name name)
:description ,description
@@ -161,7 +261,7 @@ Iterate through all currently defined faces and return
those that
were left uncustomized by the most recent call to
`autothemer-deftheme'."
(let ((all-faces (face-list))
- (themed-faces (autothemer--theme-defined-faces
autothemer--current-theme)))
+ (themed-faces (autothemer--theme-defined-faces
autothemer-current-theme)))
(--filter (not (-contains? themed-faces it)) all-faces)))
(defun autothemer--face-to-alist (face)
@@ -188,7 +288,7 @@ were left uncustomized by the most recent call to
"Replace colors in REDUCED-SPEC by their closest approximations in THEME.
Replace every expression in REDUCED-SPEC that passes
`color-defined-p' by the closest approximation found in
-`autothemer--current-theme'. Also quote all face names and
+`autothemer-current-theme'. Also quote all face names and
unbound symbols, such as `normal' or `demibold'."
(let ((colors (autothemer--theme-colors theme))
(face (car reduced-spec))
@@ -270,12 +370,12 @@ Calls `autothemer-generate-templates' after user provides
REGEXP interactively."
"Autogenerate customizations for unthemed faces (optionally by REGEXP).
Generate customizations that approximate current face definitions using the
-nearest colors in the color palette of `autothemer--current-theme'.
+nearest colors in the color palette of `autothemer-current-theme'.
An error is shown when no current theme is available."
(interactive)
- (unless autothemer--current-theme
- (user-error "No autothemer--current-theme available. Please evaluate an
autothemer-deftheme"))
+ (unless autothemer-current-theme
+ (user-error "No autothemer-current-theme available. Please evaluate an
autothemer-deftheme"))
(let* ((missing-faces
(if (null regexp)
(autothemer--unthemed-faces)
@@ -288,7 +388,7 @@ An error is shown when no current theme is available."
(--map (autothemer--approximate-spec
(autothemer--alist-to-reduced-spec
it (autothemer--face-to-alist it))
- autothemer--current-theme)
+ autothemer-current-theme)
missing-faces))
(buffer
(get-buffer-create
@@ -305,7 +405,7 @@ Otherwise, append NEW-COLUMN to every element of LISTS."
(defun autothemer--current-theme-guard ()
"Guard functions from executing when there's no current theme."
- (unless autothemer--current-theme
+ (unless autothemer-current-theme
(user-error "No current theme available. Evaluate an autotheme
definition")))
;;; Get colors from theme palette
@@ -313,7 +413,7 @@ Otherwise, append NEW-COLUMN to every element of LISTS."
(defun autothemer--get-color (color-name)
"Return color palette object for (string) COLOR-NAME.
-Search the `autothemer--current-theme' color palette for COLOR-NAME
+Search the `autothemer-current-theme' color palette for COLOR-NAME
and returns a color in the form of `autothemer--color' struct.
See also `autothemer--color-p',
@@ -323,11 +423,11 @@ See also `autothemer--color-p',
(--find
(eql (intern color-name)
(autothemer--color-name it))
- (autothemer--theme-colors autothemer--current-theme)))
+ (autothemer--theme-colors autothemer-current-theme)))
(defun autothemer--select-color (&optional prompt)
"Select a color from the current palette, optionally use PROMPT.
-Current palette is read from `autothemer--current-theme'.
+Current palette is read from `autothemer-current-theme'.
The selected color will be in the form of a `autothemer--color'
@@ -352,7 +452,7 @@ See also `autothemer--color-p',
'face (list ':background color
':foreground (readable-foreground-color
color)))
name)))
- (autothemer--theme-colors autothemer--current-theme))))
+ (autothemer--theme-colors autothemer-current-theme))))
(color-name (cadr (split-string selected " " t " "))))
(autothemer--get-color color-name)))
@@ -393,28 +493,28 @@ If PLIST is nil, ARGS are bound to BODY nil values."
;;; let palette...
(defmacro autothemer-let-palette (&rest body)
- "Provide a let block for BODY from `autothemer--current-theme'.
+ "Provide a let block for BODY from `autothemer-current-theme'.
Load/eval the required autothemer theme source (not
-byte-compiled) to set `autothemer--current-theme'."
+byte-compiled) to set `autothemer-current-theme'."
(autothemer--current-theme-guard)
`(let ,(--map (list (autothemer--color-name it) (autothemer--color-value it))
- (autothemer--theme-colors autothemer--current-theme))
+ (autothemer--theme-colors autothemer-current-theme))
,@body))
;;; Colorize alist for rainbow-mode
-(defun autothemer-colorize-alist ()
+(defun autothemer--colorize-alist ()
"Generate an alist for use with rainbow-mode.
To colorize use:
- (rainbow-colorize-by-assoc (autothemer-colorize-alist))
+ (rainbow-colorize-by-assoc (autothemer--colorize-alist))
-Colors are from `autothemer--current-theme'."
+Colors are from `autothemer-current-theme'."
(autothemer--current-theme-guard)
(--map (cons (format "%s" (autothemer--color-name it))
(autothemer--color-value it))
- (autothemer--theme-colors autothemer--current-theme)))
+ (autothemer--theme-colors autothemer-current-theme)))
(defvar autothemer--colors-font-lock-keywords nil)
@@ -422,8 +522,8 @@ Colors are from `autothemer--current-theme'."
"Colorize using rainbow-mode."
(interactive)
(setq autothemer--colors-font-lock-keywords
- `((,(regexp-opt (mapcar 'car (autothemer-colorize-alist)) 'words)
- (0 (rainbow-colorize-by-assoc (autothemer-colorize-alist))))))
+ `((,(regexp-opt (mapcar 'car (autothemer--colorize-alist)) 'words)
+ (0 (rainbow-colorize-by-assoc (autothemer--colorize-alist))))))
(font-lock-add-keywords nil autothemer--colors-font-lock-keywords t))
(defun autothemer--color-to-hsv (rgb)
@@ -432,7 +532,7 @@ The `r' `g' `b' values can range between `0..65535'.
In `(h s v)' `h', `s' and `v' are `0.0..1.0'."
(cl-destructuring-bind
- (r g b) rgb
+ (r g b) (--map (/ it 65535.0) rgb)
(let*
((bri (max r g b))
(delta (- bri (min r g b)))
@@ -455,8 +555,7 @@ In `(h s v)' `h', `s' and `v' are `0.0..1.0'."
bri))))
(defun autothemer-hex-to-rgb (hex)
- "Fast convert HEX to `(r g b)'.
-(Perf equal to wx color values C function.)
+ "Convert HEX to `(r g b)'.
`r', `g', `b' will be values `0..65535'"
(let ((rgb (string-to-number (substring hex 1) 16)))
(list
@@ -476,6 +575,8 @@ In `(h s v)' `h', `s' and `v' are `0.0..1.0'."
"Return the HSV brightness of HEX-COLOR."
(caddr (autothemer--color-to-hsv (autothemer-hex-to-rgb hex-color))))
+;;; Sort/Order of autothemer--color structs.
+
(defun autothemer-darkest-order (a b)
"Return t if the darkness of A > B."
(let ((a (autothemer-color-brightness (autothemer--color-value a)))
@@ -521,12 +622,191 @@ There are also `autothemer-hue-order' and
`autothemer-saturated-order'"
(let ((fn (or fn 'autothemer-darkest-order)))
(-sort fn theme-colors)))
+;; Color Grouping
+
+(defun autothemer-color-to-group (color fn groups)
+ "Group COLOR using FN, in GROUPS."
+ (let ((value (funcall fn color)))
+ (-reduce-from
+ (lambda (acc range)
+ (let ((a (car (cadr range)))
+ (b (cdr (cadr range))))
+ (if (<= a value b)
+ (car range)
+ acc)))
+ nil
+ groups)))
+
+(defun autothemer-saturation-group (color &optional saturation-groups)
+ "Return the saturation group of COLOR.
+Functionally identical to `autothemer-hue-groups' for saturation.
+Optionally provide a list of SATURATION-GROUPS.
+The default is `autothemer-20-percent-saturation-groups'."
+ (autothemer-color-to-group
+ color
+ 'autothemer-color-sat
+ (or saturation-groups autothemer-20-percent-saturation-groups)))
+
+(defun autothemer-brightness-group (color &optional brightness-groups)
+ "Return the brightness group of COLOR.
+Functionally identical to `autothemer-hue-groups' for brightness.
+Optionally provide a list of BRIGHTNESS-GROUPS.
+The default is `autothemer-20-percent-brightness-groups'."
+ (autothemer-color-to-group
+ color
+ 'autothemer-color-brightness
+ (or brightness-groups autothemer-20-percent-brightness-groups)))
+
+(defun autothemer-hue-group (color &optional hue-groups)
+ "Return the color hue group for COLOR.
+
+Optionally provide a list of HUE-GROUPS.
+\(default uses `autothemer-hue-groups'.)
+Also available is `autothemer-simple-hue-groups',
+both are customizable, or define your own.
+
+This facilitates hue grouping & sorting by a secondary axis.
+For example sort a list of colors by some axis (brightness or
+saturation). Then group by hue groups, and sort the groups.
+The format of each group in the list is:
+
+ (group-name (n1 . n2))
+
+Where `group-name' is a symbol to name the group,
+`(n1 . n2)' is a hue range specifier (in degrees)
+low `n1' to high `n2'.
+
+A hue range which crosses the apex (i.e. `360°..0°') is permitted."
+ (let* ((init-hue-groups (or (and (listp hue-groups) hue-groups)
+ (and (listp (symbol-value hue-groups))
+ (symbol-value hue-groups))
+ autothemer-hue-groups))
+ (hue-groups (-reduce-from
+ (lambda (acc range)
+ (let* ((a (car (cadr range)))
+ (b (cdr (cadr range)))
+ (r (if (> a b) ;; hue apex check 360..0
+ `(,(list (car range) (cons a 360))
+ ,(list (car range) (cons 0 b)))
+ `(,range))))
+ (if acc
+ (cl-concatenate 'list acc r)
+ r)))
+ nil
+ init-hue-groups))
+ (hue (autothemer-color-hue color)))
+ (-reduce-from
+ (lambda (acc range)
+ (let ((a (car (cadr range)))
+ (b (cdr (cadr range))))
+ (if (<= a (* hue 360) b)
+ (car range)
+ acc)))
+ nil
+ hue-groups)))
+
+;;; Group and sort
+
+(defun autothemer-group-sort (groups sort-fn)
+ "Sort GROUPS of colors using SORT-FN.
+GROUPS are produced by `autothemer-group-colors'."
+ (mapcar
+ (lambda (group)
+ "Groups are alists with car as key, cdr as colors."
+ (let* ((name (car group))
+ (colors (cdr group))
+ (sorted-colors (--sort
+ (funcall sort-fn it other)
+ colors)))
+ (cons name sorted-colors)))
+ groups))
+
+(defun autothemer-group-colors (palette options)
+ "Group PALETTE colors into groups as defined in plist OPTIONS:
+`: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)
+ (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))))
+ grouped-colors)))
+
+(defun autothemer-group-and-sort (palette options)
+ "Group and sort PALETTE using OPTIONS.
+
+Options is a plist of:
+
+ :group-fn - mandatory group function
+ :group-args - optional group args (to use a non-default group)
+ :sort-fn - optional sort function
+
+See color grouping functions and group lists:
+
+Hue grouping:
+
+ autothemer-hue-group
+
+Builtin hue groups:
+
+ autothemer-hue-groups
+ autothemer-simple-hue-groups
+
+Brightness grouping:
+
+ autothemer-brightness-group
+
+Builtin brightness groups:
+
+ autothemer-dark-mid-light-brightness-groups
+ autothemer-10-percent-brightness-groups
+ autothemer-20-percent-brightness-groups
+
+Saturation grouping:
+
+ autothemer-saturation-group
+
+Builtin saturation groups:
+
+ autothemer-low-mid-high-saturation-groups
+ autothemer-10-percent-saturation-groups
+ autothemer-20-percent-saturation-groups
+
+- - -
+
+Sorting:
+
+The sort/ordering functions take args A and B, which are expected
+to be `autothemer--color' structs.
+
+Darkest to lightest: `(autothemer-darkest-order a b)'
+Lightest to darkest: `(autothemer-lightest-order a b)'
+Hue: `(autothemer-hue-order a b)'
+Saturated to desaturated: `(autothemer-saturated-order a b)'
+Desaturated to saturated: `(autothemer-desaturated-order a b)'"
+ (autothemer--plist-bind
+ (group-fn
+ 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)))
+ sorted-groups)))
+
;;; SVG Palette generator...
(defun autothemer-generate-palette-svg (&optional options)
"Create an SVG palette image for a theme.
-Optionally supply a plist of OPTIONS (all keys are optional,
+Optionally supply OPTIONS (a plist, all keys are optional,
required values will default or prompt interactively.):
:theme-file - theme filename
@@ -653,10 +933,10 @@ Swatch Template parameters:
|</g>
|")))
- (autotheme-name (autothemer--theme-name autothemer--current-theme))
- (colors (autothemer--theme-colors autothemer--current-theme))
- (theme-name (or theme-name (autothemer--theme-name
autothemer--current-theme)))
- (theme-description (or theme-description
(autothemer--theme-description autothemer--current-theme)))
+ (autotheme-name (autothemer--theme-name autothemer-current-theme))
+ (colors (autothemer--theme-colors autothemer-current-theme))
+ (theme-name (or theme-name (autothemer--theme-name
autothemer-current-theme)))
+ (theme-description (or theme-description
(autothemer--theme-description autothemer-current-theme)))
(theme-url (or theme-url (lm-homepage theme-file)
(read-string "Enter theme URL: " "https://github.com/")))
(font-family (or font-family (read-string "Font
family name: " "Helvetica Neue")))
diff --git a/function-reference.md b/function-reference.md
new file mode 100644
index 0000000000..457f130594
--- /dev/null
+++ b/function-reference.md
@@ -0,0 +1,696 @@
+# Autothemer
+
+Reduce the amount of pain and boilerplate code needed to create custom themes
using `autothemer-deftheme`.
+
+Autothemer also includes interactive commands and functions to
+assist with theme building, here are a few highlights...
+
+- Generate specs for unthemed faces using the theme color palette.
+ - `autothemer-generate-templates`
+ - `autothemer-generate-templates-filtered` (filter by regexp)
+- Generate a palette SVG image
+ - `autothemer-generate-palette-svg`
+- Insert a color name or color from the active palette
+ - `autothemer-insert-color-name`
+ - `autothemer-insert-color`
+- Colorize/font-lock palette color names in the buffer
+ - `autothemer-colorize` (requires `rainbow-mode` during development.)
+
+
+Note in the function reference, the fucntion prefix `autothemer--` indicates
internal
+functions.
+ - - -
+## Functions
+
+### autothemer-colorize [command]
+
+Colorize using rainbow-mode.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-colorize)
+```
+
+- - -
+
+### autothemer-generate-palette-svg [command]
+
+Create an SVG palette image for a theme.
+
+Optionally supply `options` (a plist, all keys are optional,
+required values will default or prompt interactively.):
+
+ :theme-file - theme filename
+ :theme-name - override the title found in :theme-file
+ :theme-description - override the description found in :theme-file
+ :theme-url - override the url found in :theme-file
+ :swatch-width - px spacing width of a color swatch (default: 100)
+ :swatch-height - px spacing height of a color swatch (default: 150)
+ :swatch-rotate - degrees of rotation for swatch (default: 45)
+ :columns - number of columns for each palette row (default: 6)
+ :page-template - see page-template below
+ :page-top-margin - (default 120)
+ :page-right-margin - (default 30)
+ :page-bottom-margin - (default 60)
+ :page-left-margin - (default 30)
+ :h-space - (default 10)
+ :v-space - (default 10)
+ :swatch-template - see swatch-template below
+ :font-family - font name to use in the generated SVG
+ :bg-color
+ :text-color
+ :text-accent-color
+ :swatch-border-color
+ :sort-palette
+ :svg-out-file
+
+For advanced customization the :page-template and :swatch-template can be
+used to provide customize the SVG templates.
+
+Note: Template parameters are filled by `format` so we mark them as follows:
+
+Page Template parameters:
+
+ %1$s - width
+ %2$s - height
+ %3$s - font-family
+ %4$s - text-color
+ %5$s - text-accent-color
+ %6$s - bg-color
+ %7$s - theme-name
+ %8$s - theme-description
+ %9$s - theme-url
+ %10$s - color swatches
+
+Swatch Template parameters:
+
+ %1$s - x
+ %2$s - y
+ %3$s - swatch-border-color
+ %4$s - swatch-color
+ %5$s - text-accent-color
+ %6$s - swatch-color-name
+
+<sup>function signature</sup>
+```lisp
+(autothemer-generate-palette-svg (&optional options))
+```
+
+- - -
+
+### autothemer-generate-templates [command]
+
+Autogenerate customizations for unthemed faces (optionally by `regexp`).
+
+Generate customizations that approximate current face definitions using the
+nearest colors in the color palette of `autothemer-current-theme`.
+
+An error is shown when no current theme is available.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-generate-templates (&optional regexp))
+```
+
+- - -
+
+### autothemer-generate-templates-filtered [command]
+
+Autogenerate customizations for unthemed faces matching `regexp`.
+
+Calls `autothemer-generate-templates` after user provides `regexp`
interactively.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-generate-templates-filtered (regexp))
+```
+
+- - -
+
+### autothemer-insert-color [command]
+
+Select and insert a color from the current autotheme palette.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-insert-color)
+```
+
+- - -
+
+### autothemer-insert-color-name [command]
+
+Select and insert a color name from the current autotheme palette.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-insert-color-name)
+```
+
+- - -
+
+### autothemer-brightness-group
+
+Return the brightness group of `color`.
+Functionally identical to `autothemer-hue-groups` for brightness.
+Optionally provide a list of `brightness-groups`.
+The default is `autothemer-20-percent-brightness-groups`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-brightness-group (color &optional brightness-groups))
+```
+
+- - -
+
+### autothemer-color-brightness
+
+Return the HSV brightness of `hex-color`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-color-brightness (hex-color))
+```
+
+- - -
+
+### autothemer-color-hue
+
+Return the HSV hue of `hex-color`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-color-hue (hex-color))
+```
+
+- - -
+
+### autothemer-color-sat
+
+Return the HSV sat of `hex-color`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-color-sat (hex-color))
+```
+
+- - -
+
+### autothemer-color-to-group
+
+Group `color` using `fn`, in `groups`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-color-to-group (color fn groups))
+```
+
+- - -
+
+### autothemer-darkest-order
+
+Return t if the darkness of `a` > `b`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-darkest-order (a b))
+```
+
+- - -
+
+### autothemer-group-and-sort
+
+Group and sort `palette` using `options`.
+
+Options is a plist of:
+
+ :group-fn - mandatory group function
+ :group-args - optional group args (to use a non-default group)
+ :sort-fn - optional sort function
+
+See color grouping functions and group lists:
+
+Hue grouping:
+
+ autothemer-hue-group
+
+Builtin hue groups:
+
+ autothemer-hue-groups
+ autothemer-simple-hue-groups
+
+Brightness grouping:
+
+ autothemer-brightness-group
+
+Builtin brightness groups:
+
+ autothemer-dark-mid-light-brightness-groups
+ autothemer-10-percent-brightness-groups
+ autothemer-20-percent-brightness-groups
+
+Saturation grouping:
+
+ autothemer-saturation-group
+
+Builtin saturation groups:
+
+ autothemer-low-mid-high-saturation-groups
+ autothemer-10-percent-saturation-groups
+ autothemer-20-percent-saturation-groups
+
+- - -
+
+Sorting:
+
+The sort/ordering functions take args A and B, which are expected
+to be `autothemer--color` structs.
+
+Darkest to lightest: `(autothemer-darkest-order a b)`
+Lightest to darkest: `(autothemer-lightest-order a b)`
+Hue: `(autothemer-hue-order a b)`
+Saturated to desaturated: `(autothemer-saturated-order a b)`
+Desaturated to saturated: `(autothemer-desaturated-order a b)`
+
+<sup>function signature</sup>
+```lisp
+(autothemer-group-and-sort (palette options))
+```
+
+- - -
+
+### autothemer-group-colors
+
+Group `palette` colors into groups as defined in plist `options`:
+`:group-fn` - mandatory group function
+`:group-args` - args for `group-fn`
+
+<sup>function signature</sup>
+```lisp
+(autothemer-group-colors (palette options))
+```
+
+- - -
+
+### autothemer-group-sort
+
+Sort `groups` of colors using `sort-fn`.
+`groups` are produced by `autothemer-group-colors`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-group-sort (groups sort-fn))
+```
+
+- - -
+
+### autothemer-hex-to-rgb
+
+Convert `hex` to `(r g b)`.
+`r`, `g`, `b` will be values `0..65535`
+
+<sup>function signature</sup>
+```lisp
+(autothemer-hex-to-rgb (hex))
+```
+
+- - -
+
+### autothemer-hue-group
+
+Return the color hue group for `color`.
+
+Optionally provide a list of `hue-groups`.
+(default uses `autothemer-hue-groups`.)
+Also available is `autothemer-simple-hue-groups`,
+both are customizable, or define your own.
+
+This facilitates hue grouping & sorting by a secondary axis.
+For example sort a list of colors by some axis (brightness or
+saturation). Then group by hue groups, and sort the groups.
+The format of each group in the list is:
+
+ (group-name (n1 . n2))
+
+Where `group-name` is a symbol to name the group,
+`(n1 . n2)` is a hue range specifier (in degrees)
+low `n1` to high `n2`.
+
+A hue range which crosses the apex (i.e. `360°..0°`) is permitted.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-hue-group (color &optional hue-groups))
+```
+
+- - -
+
+### autothemer-hue-order
+
+Return t if the hue of `a` > `b`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-hue-order (a b))
+```
+
+- - -
+
+### autothemer-hue-sat-order
+
+Return t if the hue and sat of `a` > `b`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-hue-sat-order (a b))
+```
+
+- - -
+
+### autothemer-lightest-order
+
+Return t if the lightness of `a` > `b`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-lightest-order (a b))
+```
+
+- - -
+
+### autothemer-saturated-order
+
+Return t if the saturation of `a` > `b`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-saturated-order (a b))
+```
+
+- - -
+
+### autothemer-saturation-group
+
+Return the saturation group of `color`.
+Functionally identical to `autothemer-hue-groups` for saturation.
+Optionally provide a list of `saturation-groups`.
+The default is `autothemer-20-percent-saturation-groups`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer-saturation-group (color &optional saturation-groups))
+```
+
+- - -
+
+### autothemer-sort-palette
+
+Produce a list of sorted `theme-colors` using `fn`.
+
+If `fn` is nil, sort by default `fn` `autothemer-darkest-order`.
+
+`autothemer-lightest-order` is available to balance the force.
+
+There are also `autothemer-hue-order` and `autothemer-saturated-order`
+
+<sup>function signature</sup>
+```lisp
+(autothemer-sort-palette (theme-colors &optional fn))
+```
+
+- - -
+
+### autothemer--alist-to-reduced-spec [internal]
+
+Generate a reduced-spec for `facename`, based on the face attribute `alist`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--alist-to-reduced-spec (facename alist))
+```
+
+- - -
+
+### autothemer--approximate-spec [internal]
+
+Replace colors in `reduced-spec` by their closest approximations in `theme`.
+Replace every expression in `reduced-spec` that passes
+`color-defined-p` by the closest approximation found in
+`autothemer-current-theme`. Also quote all face names and
+unbound symbols, such as `normal` or `demibold`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--approximate-spec (reduced-spec theme))
+```
+
+- - -
+
+### autothemer--color-distance [internal]
+
+Return the distance in rgb space between `color` and AUTOTHEMER-`color`.
+Here, `color` is an Emacs color specification and AUTOTHEMER-`color` is of
+type `autothemer--color`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--color-distance (color autothemer-color))
+```
+
+- - -
+
+### autothemer--color-to-hsv [internal]
+
+Convert `rgb`, a list of `(r g b)` to list `(h s v)`.
+The `r` `g` `b` values can range between `0..65535`.
+
+In `(h s v)` `h`, `s` and `v` are `0.0..1.0`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--color-to-hsv (rgb))
+```
+
+- - -
+
+### autothemer--colorize-alist [internal]
+
+Generate an alist for use with rainbow-mode.
+
+To colorize use:
+
+ (rainbow-colorize-by-assoc (autothemer--colorize-alist))
+
+Colors are from `autothemer-current-theme`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--colorize-alist)
+```
+
+- - -
+
+### autothemer--cons-to-tree [internal]
+
+Turn `the-cons` into a list, unless its cdr is `unspecified`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--cons-to-tree (the-cons))
+```
+
+- - -
+
+### autothemer--current-theme-guard [internal]
+
+Guard functions from executing when there's no current theme.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--current-theme-guard)
+```
+
+- - -
+
+### autothemer--demote-heads [internal]
+
+Demote every list head within `expr` by one element.
+E.g., (a (b c d) e (f g)) -> (list a (list b c d) e (list f g)).
+
+<sup>function signature</sup>
+```lisp
+(autothemer--demote-heads (expr))
+```
+
+- - -
+
+### autothemer--extract-display [internal]
+
+Extract from `palette` display specification #`n`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--extract-display (palette n))
+```
+
+- - -
+
+### autothemer--extract-let-block [internal]
+
+Extract a variable definition block from `palette` for display type `n`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--extract-let-block (palette n))
+```
+
+- - -
+
+### autothemer--face-to-alist [internal]
+
+Return the attribute alist for `face` in frame (selected-frame).
+
+<sup>function signature</sup>
+```lisp
+(autothemer--face-to-alist (face))
+```
+
+- - -
+
+### autothemer--fill-empty-palette-slots [internal]
+
+Fill empty `palette` slots so each display has all color-definitions.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--fill-empty-palette-slots (palette))
+```
+
+- - -
+
+### autothemer--find-closest-color [internal]
+
+Return the element of `colors` that is closest in rgb space to `color`.
+Here, `color` is an Emacs color specification and `colors` is a list
+of `autothemer--color` structs.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--find-closest-color (colors color))
+```
+
+- - -
+
+### autothemer--get-color [internal]
+
+Return color palette object for (string) `color-name`.
+
+Search the `autothemer-current-theme` color palette for `color-name`
+and returns a color in the form of `autothemer--color` struct.
+
+See also `autothemer--color-p`,
+ `autothemer--color-name`,
+ `autothemer--color-value`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--get-color (color-name))
+```
+
+- - -
+
+### autothemer--pad-with-nil [internal]
+
+Make sure that `row` has at least `min-number-of-elements`.
+Pad with nil if necessary.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--pad-with-nil (row min-number-of-elements))
+```
+
+- - -
+
+### autothemer--reduced-spec-to-facespec [internal]
+
+Create a face spec for `display`, with specs `reduced-specs`.
+
+For example:
+
+ (autothemer--reduced-spec-to-facespec '(min-colors 60) '(button
(:underline t :foreground red)))
+ ;; => `(button (((min-colors 60) (:underline ,t :foreground ,red)))).
+
+<sup>function signature</sup>
+```lisp
+(autothemer--reduced-spec-to-facespec (display reduced-specs))
+```
+
+- - -
+
+### autothemer--replace-nil-by-precursor [internal]
+
+Replace nil colors in `palette-row` with their precursor.
+
+`palette-row` is of the form `(name color [color ...])`
+
+Where the first `color` must be non nil.
+
+Any subsequent nil color will be replaced by the previous value.
+
+For example:
+
+ ("red-foo" "#FF0000" nil)
+
+Will become:
+
+ ("red-foo" "#FF0000" "#FF0000")
+
+<sup>function signature</sup>
+```lisp
+(autothemer--replace-nil-by-precursor (palette-row))
+```
+
+- - -
+
+### autothemer--select-color [internal]
+
+Select a color from the current palette, optionally use `prompt`.
+Current palette is read from `autothemer-current-theme`.
+
+The selected color will be in the form of a `autothemer--color`
+
+See also `autothemer--color-p`,
+ `autothemer--color-name`,
+ `autothemer--color-value`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--select-color (&optional prompt))
+```
+
+- - -
+
+### autothemer--unindent [internal]
+
+Unindent string `s` marked with | chars.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--unindent (s))
+```
+
+- - -
+
+### autothemer--unthemed-faces [internal]
+
+Find uncustomized faces.
+Iterate through all currently defined faces and return those that
+were left uncustomized by the most recent call to
+`autothemer-deftheme`.
+
+<sup>function signature</sup>
+```lisp
+(autothemer--unthemed-faces)
+```
+
+- - -
diff --git a/tests/autothemer-tests.el b/tests/autothemer-tests.el
index 03ab60faac..e120ff686d 100644
--- a/tests/autothemer-tests.el
+++ b/tests/autothemer-tests.el
@@ -1,10 +1,28 @@
;; autothemer-tests.el
+;; Version: 0.2.11
+
;;; Code:
(require 'autothemer)
+;;; Test Helpers
+
+(defun name-color-to-struct (C)
+ "Cons C with name & value to `autothemer--color` struct."
+ (make-autothemer--color :name (car C) :value (cdr C)))
+
+(defun struct-to-cons-name-color (S)
+ "S (`autothemer--color` struct) to `(cons name color)'."
+ (cons
+ (autothemer--color-name S)
+ (autothemer--color-value S)))
+
+;;; Tests
+
(progn "Test autothemer-deftheme"
+
+;;; Example theme
(autothemer-deftheme theme-example
"Autothemer example..."
@@ -38,54 +56,58 @@
,example-orange
,example-cyan])))
+;;; autothemer-current-theme is set.
+
(ert-deftest current-theme ()
"Test current theme is available."
(should (not (null
- autothemer--current-theme))))
+ autothemer-current-theme))))
(ert-deftest theme-has-colors ()
"Check theme has colors."
(should (eql 7 (length (autothemer--theme-colors
- autothemer--current-theme)))))
+ autothemer-current-theme)))))
(ert-deftest theme-has-face-specs ()
"Check theme has face specs."
(should (eql 2 (length (autothemer--theme-defined-faces
- autothemer--current-theme)))))
+ autothemer-current-theme)))))
(ert-deftest color-value ()
"Check color value."
(should (string= "#781210"
(autothemer--color-value
(car (autothemer--theme-colors
- autothemer--current-theme))))))
+ autothemer-current-theme))))))
(ert-deftest color-name ()
"Check color name."
(should (string= "example-red"
(autothemer--color-name
(car (autothemer--theme-colors
- autothemer--current-theme))))))
+ autothemer-current-theme))))))
(ert-deftest spec-name ()
"Check spec name."
(should (equal 'button
(car (autothemer--theme-defined-faces
- autothemer--current-theme)))))
+ autothemer-current-theme)))))
(ert-deftest theme-has-description ()
"Check theme description."
(should (string=
"Autothemer example..."
(autothemer--theme-description
- autothemer--current-theme))))
+ autothemer-current-theme))))
(ert-deftest theme-has-name ()
"Check theme name."
(should (string=
"theme-example"
(autothemer--theme-name
- autothemer--current-theme))))
+ autothemer-current-theme))))
+
+;;; Let palette
(ert-deftest let-palette ()
"Check autothemer-let-palette"
@@ -93,6 +115,8 @@
"#781210"
(autothemer-let-palette example-red))))
+;;; AT Helper functions
+
(ert-deftest unindent ()
"Test unindent."
(should
@@ -109,69 +133,222 @@
(should (eql a 1))
(should (eql b 2))))
- (ert-deftest autothemer-color-hue ()
- "Test get hue of hex-color."
- (= (autothemer-color-hue "#FF0000") 0)
- (= (autothemer-color-hue "#FFFF00") 0.16666666666666666)
- (= (autothemer-color-hue "#00FF00") 0.33333333333333333)
- (= (autothemer-color-hue "#0000FF") 0.66666666666666666))
-
- (ert-deftest autothemer-color-sat ()
- "Test get sat of hex-color."
- (= (autothemer-color-sat "#0000FF") 1.0)
- (= (autothemer-color-sat "#FF00FF") 1.0)
- (= (autothemer-color-sat "#778822") 0.75)
- (= (autothemer-color-sat "#772288") 0.75)
- (= (autothemer-color-sat "#112233") 0.6666666666666667))
-
- (ert-deftest autothemer-color-brightness ()
- "Test get brightness of hex-color."
- (= (autothemer-color-brightness "#0000FF") 1.0)
- (= (autothemer-color-brightness "#00FF00") 1.0)
- (= (autothemer-color-brightness "#FF00FF") 1.0)
- (= (autothemer-color-brightness "#333333") 0.2)
- (= (autothemer-color-brightness "#555555") 0.3333333333333333))
-
- (ert-deftest autothemer--color-distance ()
- "Test color distance."
- (let ((color-struct (make-autothemer--color :name "Test" :value "#100000")))
- (should (eql (autothemer--color-distance "#100000" color-struct) 0))
- (should (eql (autothemer--color-distance "#100001" color-struct) 257))
- (should (eql (autothemer--color-distance "#000001" color-struct) 4369))
- (should (eql (autothemer--color-distance "#FF0000" color-struct) 61423))))
-
- (ert-deftest autothemer-hex-to-rgb ()
- "Test hex to rgb."
- (should (equal '(0 0 0) (autothemer-hex-to-rgb "#000000")))
- (should (equal '(65535 65535 65535) (autothemer-hex-to-rgb "#FFFFFF")))
- (should (equal '(65535 0 0) (autothemer-hex-to-rgb "#FF0000")))
- (should (equal '(65535 65535 0) (autothemer-hex-to-rgb "#FFFF00")))
- (should (equal '(0 65535 0) (autothemer-hex-to-rgb "#00FF00")))
- (should (equal '(0 65535 65535) (autothemer-hex-to-rgb "#00FFFF")))
- (should (equal '(0 0 65535) (autothemer-hex-to-rgb "#0000FF")))
- (should (equal '(32896 32896 32896) (autothemer-hex-to-rgb "#808080"))))
-
- (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)))))
-
-;;; Example theme in memory:
-'(#s(autothemer--theme
- (#s(autothemer--color example-red "#781210")
- #s(autothemer--color example-green "#22881F")
- #s(autothemer--color example-blue "#212288")
- #s(autothemer--color example-purple "#812FFF")
- #s(autothemer--color example-yellow "#EFFE00")
- #s(autothemer--color example-orange "#E06500")
- #s(autothemer--color example-cyan "#22DDFF"))
- (button error)
- "theme-example" "Autothemer example..."))
+;;; Color conversion
+
+ (ert-deftest autothemer-hex-to-rgb ()
+ "Test hex to rgb."
+ (should (equal '(0 0 0) (autothemer-hex-to-rgb "#000000")))
+ (should (equal '(65535 65535 65535) (autothemer-hex-to-rgb "#FFFFFF")))
+ (should (equal '(65535 0 0) (autothemer-hex-to-rgb "#FF0000")))
+ (should (equal '(65535 65535 0) (autothemer-hex-to-rgb "#FFFF00")))
+ (should (equal '(0 65535 0) (autothemer-hex-to-rgb "#00FF00")))
+ (should (equal '(0 65535 65535) (autothemer-hex-to-rgb "#00FFFF")))
+ (should (equal '(0 0 65535) (autothemer-hex-to-rgb "#0000FF")))
+ (should (equal '(32896 32896 32896) (autothemer-hex-to-rgb "#808080"))))
+
+ (ert-deftest autothemer--color-to-hsv ()
+ "Test color to hsv conversion."
+ (should (equal (autothemer--color-to-hsv '(0 0 0)) '(0.0 0.0 0.0)))
+ (should (equal (autothemer--color-to-hsv '(65535 65535 65535)) '(0.0 0.0
1.0)))
+ (should (equal (autothemer--color-to-hsv '(0 0 65535))
'(0.6666666666666666 1.0 1.0)))
+ (should (equal (autothemer--color-to-hsv '(12896 0 32896))
'(0.7320038910505837 1.0 0.5019607843137255))))
+
+;;; HSV Color components
+
+ (ert-deftest autothemer-color-hue ()
+ "Test get hue of hex-color."
+ (should (= (autothemer-color-hue "#FF0000") 0))
+ (should (= (autothemer-color-hue "#FFFF00") 0.16666666666666666))
+ (should (= (autothemer-color-hue "#00FF00") 0.33333333333333333))
+ (should (= (autothemer-color-hue "#0000FF") 0.66666666666666666)))
+
+ (ert-deftest autothemer-color-sat ()
+ "Test get sat of hex-color."
+ (should (= (autothemer-color-sat "#0000FF") 1.0))
+ (should (= (autothemer-color-sat "#FF00FF") 1.0))
+ (should (= (autothemer-color-sat "#778822") 0.75))
+ (should (= (autothemer-color-sat "#772288") 0.75))
+ (should (= (autothemer-color-sat "#112233") 0.6666666666666667)))
+
+ (ert-deftest autothemer-color-brightness ()
+ "Test get brightness of hex-color."
+ (should (= (autothemer-color-brightness "#0000FF") 1.0))
+ (should (= (autothemer-color-brightness "#00FF00") 1.0))
+ (should (= (autothemer-color-brightness "#FF00FF") 1.0))
+ (should (= (autothemer-color-brightness "#333333") 0.2))
+ (should (= (autothemer-color-brightness "#555555") 0.3333333333333333)))
+
+;;; Color distance
+
+ (ert-deftest autothemer--color-distance ()
+ "Test color distance."
+ (let ((color-struct (make-autothemer--color :name "Test" :value
"#100000")))
+ (should (eql (autothemer--color-distance "#100000" color-struct) 0))
+ (should (eql (autothemer--color-distance "#100001" color-struct) 257))
+ (should (eql (autothemer--color-distance "#000001" color-struct) 4369))
+ (should (eql (autothemer--color-distance "#FF0000" color-struct) 61423))))
+
+;;; 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))))
+
+;;; 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")))))))
+
;;; autothemer-tests.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [nongnu] elpa/autothemer 5a193c796a: 0.2.11 - develop color grouping and sorting. (#25),
ELPA Syncer <=