diff --git a/README.md b/README.md index 3946608..2fca846 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 6bf5d5f..174f603 100644 --- a/autothemer.el +++ b/autothemer.el @@ -7,7 +7,7 @@ ;; Maintainer: Jason Milkins ;; ;; 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 . ;;; 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: | |"))) - (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 0000000..457f130 --- /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. + +function signature +```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 + +function signature +```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. + +function signature +```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. + +function signature +```lisp +(autothemer-generate-templates-filtered (regexp)) +``` + +- - - + +### autothemer-insert-color [command] + +Select and insert a color from the current autotheme palette. + +function signature +```lisp +(autothemer-insert-color) +``` + +- - - + +### autothemer-insert-color-name [command] + +Select and insert a color name from the current autotheme palette. + +function signature +```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`. + +function signature +```lisp +(autothemer-brightness-group (color &optional brightness-groups)) +``` + +- - - + +### autothemer-color-brightness + +Return the HSV brightness of `hex-color`. + +function signature +```lisp +(autothemer-color-brightness (hex-color)) +``` + +- - - + +### autothemer-color-hue + +Return the HSV hue of `hex-color`. + +function signature +```lisp +(autothemer-color-hue (hex-color)) +``` + +- - - + +### autothemer-color-sat + +Return the HSV sat of `hex-color`. + +function signature +```lisp +(autothemer-color-sat (hex-color)) +``` + +- - - + +### autothemer-color-to-group + +Group `color` using `fn`, in `groups`. + +function signature +```lisp +(autothemer-color-to-group (color fn groups)) +``` + +- - - + +### autothemer-darkest-order + +Return t if the darkness of `a` > `b`. + +function signature +```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)` + +function signature +```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` + +function signature +```lisp +(autothemer-group-colors (palette options)) +``` + +- - - + +### autothemer-group-sort + +Sort `groups` of colors using `sort-fn`. +`groups` are produced by `autothemer-group-colors`. + +function signature +```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` + +function signature +```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. + +function signature +```lisp +(autothemer-hue-group (color &optional hue-groups)) +``` + +- - - + +### autothemer-hue-order + +Return t if the hue of `a` > `b`. + +function signature +```lisp +(autothemer-hue-order (a b)) +``` + +- - - + +### autothemer-hue-sat-order + +Return t if the hue and sat of `a` > `b`. + +function signature +```lisp +(autothemer-hue-sat-order (a b)) +``` + +- - - + +### autothemer-lightest-order + +Return t if the lightness of `a` > `b`. + +function signature +```lisp +(autothemer-lightest-order (a b)) +``` + +- - - + +### autothemer-saturated-order + +Return t if the saturation of `a` > `b`. + +function signature +```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`. + +function signature +```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` + +function signature +```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`. + +function signature +```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`. + +function signature +```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`. + +function signature +```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`. + +function signature +```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`. + +function signature +```lisp +(autothemer--colorize-alist) +``` + +- - - + +### autothemer--cons-to-tree [internal] + +Turn `the-cons` into a list, unless its cdr is `unspecified`. + +function signature +```lisp +(autothemer--cons-to-tree (the-cons)) +``` + +- - - + +### autothemer--current-theme-guard [internal] + +Guard functions from executing when there's no current theme. + +function signature +```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)). + +function signature +```lisp +(autothemer--demote-heads (expr)) +``` + +- - - + +### autothemer--extract-display [internal] + +Extract from `palette` display specification #`n`. + +function signature +```lisp +(autothemer--extract-display (palette n)) +``` + +- - - + +### autothemer--extract-let-block [internal] + +Extract a variable definition block from `palette` for display type `n`. + +function signature +```lisp +(autothemer--extract-let-block (palette n)) +``` + +- - - + +### autothemer--face-to-alist [internal] + +Return the attribute alist for `face` in frame (selected-frame). + +function signature +```lisp +(autothemer--face-to-alist (face)) +``` + +- - - + +### autothemer--fill-empty-palette-slots [internal] + +Fill empty `palette` slots so each display has all color-definitions. + +function signature +```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. + +function signature +```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`. + +function signature +```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. + +function signature +```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)))). + +function signature +```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") + +function signature +```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`. + +function signature +```lisp +(autothemer--select-color (&optional prompt)) +``` + +- - - + +### autothemer--unindent [internal] + +Unindent string `s` marked with | chars. + +function signature +```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`. + +function signature +```lisp +(autothemer--unthemed-faces) +``` + +- - - diff --git a/tests/autothemer-tests.el b/tests/autothemer-tests.el index 03ab60f..e120ff6 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