emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/autothemer 97f7276eb1 28/29: Merge Pull request #23 from d


From: ELPA Syncer
Subject: [nongnu] elpa/autothemer 97f7276eb1 28/29: Merge Pull request #23 from develop
Date: Sun, 28 Aug 2022 22:58:47 -0400 (EDT)

branch: elpa/autothemer
commit 97f7276eb1010387202214ccf2721f20a21012e7
Merge: 96ca493b9f 1bc52d721d
Author: Jason Milkins <jasonm23@users.noreply.github.com>
Commit: GitHub <noreply@github.com>

    Merge Pull request #23 from develop
    
    - Add  more tests / github actions CI
    - Add autothemer-colorize
    - Add more info to README
    - Add  Bug and Feature issue templates
    - Update contribution notes
---
 .github/ISSUE_TEMPLATE/BUG-REPORT.yml      |  90 +++++++++
 .github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml |  55 ++++++
 .github/ISSUE_TEMPLATE/config.yml          |   1 +
 .github/workflows/test.yml                 |  33 ++++
 CONTRIBUTING.md                            |  38 ++++
 readme.md => README.md                     | 189 ++++++++++++------
 autothemer.el                              | 295 +++++++++++++++++++++++------
 bin/setup                                  |  21 ++
 bin/test                                   |  40 ++++
 tests/autothemer-tests.el                  | 214 +++++++++++++++++----
 10 files changed, 823 insertions(+), 153 deletions(-)

diff --git a/.github/ISSUE_TEMPLATE/BUG-REPORT.yml 
b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
new file mode 100644
index 0000000000..b05f938bc7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/BUG-REPORT.yml
@@ -0,0 +1,90 @@
+name: "🪲 Bug Report"
+description: Create a new issue for a bug.
+title: "🪲 [BUG] - <title>"
+labels: [
+  "bug"
+]
+body:
+  - type: textarea
+    id: description
+    attributes:
+      label: "Description"
+      description: Please enter a short/clear description of your issue
+      placeholder: Enter a short/clear description of your issue.
+    validations:
+      required: true
+  - type: textarea
+    id: reprod
+    attributes:
+      label: "Steps to Reproduce the issue. (Issues that cannot be reproduced 
will be closed.)"
+      description: Please enter accurate steps to reproduce the issue.
+      value: |
+        1. Open foobar.rs '...'
+        2. M-x doctor'....'
+        3. Doctor says: What seems to be the problem? '....'
+        4. Debugger opens with error 'void function foo-bae'
+      render: bash
+    validations:
+      required: true
+  - type: textarea
+    id: screenshot
+    attributes:
+      label: "Screenshots"
+      description: If applicable, add screenshots to help explain your 
problem. (link to or drag and drop an image.)
+      value: |
+        ![DESCRIPTION](LINK.png)
+      render: bash
+    validations:
+      required: false
+  - type: textarea
+    id: logs
+    attributes:
+      label: "Logs"
+      description: Please copy and paste any relevant log or debug output. 
This will be automatically formatted into code, so no need for backticks.
+      render: bash
+    validations:
+      required: false
+  - type: dropdown
+    id: browsers
+    attributes:
+      label: "Emacs version"
+      description: What Emacs version are you seeing the problem on ?
+      multiple: true
+      options:
+        - 26.1
+        - 26.2
+        - 26.3
+        - 27.1
+        - 27.2
+        - 28.1
+        - snapshot
+    validations:
+      required: false
+  - type: dropdown
+    id: display
+    attributes:
+      label: "Emacs running on GUI, Terminal or Daemon?"
+      description: How was Emacs being run? GUI, Terminal or Daemon?
+      multiple: true
+      options:
+        - "GUI"
+        - "Terminal COLORTERM=truecolor"
+        - "Terminal TERM=xterm256colors"
+        - "Terminal other (tell us about it in the description.)"
+        - "Daemon"
+    validations:
+      required: false  - type: dropdown
+    id: os
+    attributes:
+      label: "OS"
+      description: What is the impacted environment ?
+      multiple: true
+      options:
+        - Windows
+        - Linux
+        - Mac
+        - Solaris
+        - AiX
+        - HP/UX
+    validations:
+      required: false
diff --git a/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml 
b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
new file mode 100644
index 0000000000..0e179cc4a2
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/FEATURE-REQUEST.yml
@@ -0,0 +1,55 @@
+name: "🐣 Feature Request"
+description: Create a new issue for a new feature request
+title: "🐣 [REQUEST] - <title>"
+labels: [
+  "question"
+]
+body:
+  - type: textarea
+    id: implementation_pr
+    attributes:
+      label: "Implementation PR"
+      description: Pull request used
+      placeholder: "#Pull Request ID"
+    validations:
+      required: false
+  - type: textarea
+    id: reference_issues
+    attributes:
+      label: "Reference Issues"
+      description: Common issues
+      placeholder: "#Issues IDs"
+    validations:
+      required: false
+  - type: textarea
+    id: summary
+    attributes:
+      label: "Summary"
+      description: Provide a brief explanation of the feature
+      placeholder: Describe in a few lines your feature request
+    validations:
+      required: true
+  - type: textarea
+    id: basic_example
+    attributes:
+      label: "Basic Example"
+      description: Indicate here some basic examples of your feature. If the 
feature exists in another product, this is a good place to mention and link to 
it.
+      placeholder: A few specific words about your feature request.
+    validations:
+      required: true
+  - type: textarea
+    id: drawbacks
+    attributes:
+      label: "Drawbacks"
+      description: What are the drawbacks/impacts of your feature request ?
+      placeholder: Identify the drawbacks and impacts while being neutral on 
your feature request
+    validations:
+      required: true
+  - type: textarea
+    id: unresolved_question
+    attributes:
+      label: "Unresolved questions"
+      description: What questions still remain unresolved ?
+      placeholder: Any unresolved issues?
+    validations:
+      required: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml 
b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000000..3ba13e0cec
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1 @@
+blank_issues_enabled: false
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000000..6a2f8ec3a2
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,33 @@
+name: Autothemer Tests
+
+on:
+  push:
+    branches: 
+      - master
+  pull_request:
+
+jobs:
+  test:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        emacs_version:
+          - 26.1
+          - 26.2
+          - 26.3
+          - 27.1
+          - 27.2
+          - 28.1
+          - snapshot
+      fail-fast: false
+    steps:
+    - uses: actions/checkout@v3
+    - name: Set up Emacs
+      uses: purcell/setup-emacs@v3.0
+      with:
+        version: ${{ matrix.emacs_version }}
+
+    - name: Test
+      run: |
+        bin/setup
+        bin/test
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000000..dab95f0cbf
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,38 @@
+# Contributing
+
+Welcome to Emacs AutoThemer. You can contribute to the project in the 
following ways:
+
+- **Bug reports:** One liner reports are difficult to understand and review.
+       - Follow the bug reporting issue template and provide clear, concise 
descriptions and steps to reproduce the bug.
+       - Ensure that you have searched the existing issues to avoid duplicates.
+       - Maintainers may close unclear issues that lack enough information to 
reproduce a bug. [Report a bug 
here](https://github.com/jasonm23/autothemer/issues/new/choose).
+    - Maintainers WILL close issues if they cannot be reliably and repeatedly 
reproduced, without loading your config.
+
+- **Feature suggestions:** If you feel there is a nice enhancement or feature 
that can benefit many users, please open a feature request issue.
+       - Ensure that you have searched the existing issues to avoid duplicates.
+       - What makes sense for the project, what suits its scope and goals, and 
its future direction are at the discretion of the maintainers who put in the 
time, effort, and energy in building and maintaining the project for free. 
Please be respectful of this and keep discussions friendly and fruitful.
+       - It is the responsibility of the requester to clearly explain and 
justify why a change is warranted. It is not the responsibility of the 
maintainers to coax this information out of a requester. So, please post well 
researched, well thought out, and detailed feature requests saving everyone 
time.
+       - Maintainers may close unclear feature requests that lack enough 
information. [Suggest a feature 
here](https://github.com/jasonm23/autothemer/issues/new/choose).
+
+- **Pull requests**
+  This is a tricky one for many reasons. A PR, be it a new feature or a small 
enhancement, has to make sense to the project's overall scope, goals, and 
technical aspects. The quality, style, and conventions of the code have to 
conform to that of the project's. Performance, usability, stability and other 
kinds of impacts of a PR should be well understood.
+
+  This makes reviewing PRs a difficult and time consuming task. The bigger a 
PR, the more difficult it is to understand. Reviewing a PR in detail, engaging 
in back and forth discussions to improve it, and deciding that it is meaningful 
and safe to merge can often require more time and effort than what has gone 
into creating a PR. Thus, ultimately, whether a PR gets accepted or not, for 
whatever reason, is at the discretion of the maintainers. Please be respectful 
of the fact that maintai [...]
+
+  To keep the process smooth **send small PRs:** Whenever possible, send small 
PRs with well defined scopes. The smaller the PR, the easier it is to review 
and test. Bundling multiple features into a single PR is highly discouraged.
+
+- **Be respectful**
+  Remember, most FOSS projects are fruits of love and labour of maintainers 
who share them with the world for free with no expectations of any returns. 
Free as in freedom, and free as in beer too. Really, *some people just want to 
watch the world turn*.
+
+### So:
+
+- Please be respectful and refrain from using aggressive or snarky language. 
It wastes time, energy, cognitive bandwidth, and goodwill.
+- Please refrain from demanding. How badly you want a feature has no bearing 
on whether it warrants a maintainer's time or attention. It is entirely up to 
the maintainers, if, how, and when they want to implement something.
+- Please do not nitpick and generate unnecessary discussions that waste time.
+- Please make sure you have searched the docs and issues before asking support 
questions.
+- **Please remember, FOSS project maintainers owe you nothing** (unless you 
have an explicit agreement with them, of course) including their time in 
responding to your messages or providing free customer support. If you want to 
be heard, please be respectful and establish goodwill.
+- If these are unacceptable to you 
+   - You don't have to use the project 
+   - You can always fork the project and change it to your liking while 
adhering to the terms of the license. That is the beauty of FOSS, afterall.
+
+Thank you
diff --git a/readme.md b/README.md
similarity index 64%
rename from readme.md
rename to README.md
index 531324bb9f..59eaf548b6 100644
--- a/readme.md
+++ b/README.md
@@ -1,15 +1,34 @@
 # Autothemer
+
+[![Autothemer 
Tests](https://github.com/jasonm23/autothemer/actions/workflows/test.yml/badge.svg)](https://github.com/jasonm23/autothemer/actions/workflows/test.yml)
+
 [![NonGNU 
ELPA](https://elpa.nongnu.org/nongnu/autothemer.svg)](https://elpa.nongnu.org/nongnu/autothemer.html)
+[![MELPA](https://melpa.org/packages/autothemer-badge.svg)](https://melpa.org/#/autothemer)
+[![MELPA 
Stable](https://stable.melpa.org/packages/autothemer-badge.svg)](https://stable.melpa.org/#/autothemer)
+
+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.
+
+## News
+
+We've added new things to AutoThemer in recent weeks:
 
-Autothemer provides a thin layer on top of `deftheme` and
-`custom-theme-set-faces` that creates a new custom color theme.
+- [Updates to the list of themes using autothemer](#themes-using-autothemer) 
(More to come...)
+- [Theme Variant Architecture/TVA](#tva) A convention for developing themes 
with multiple versions.
+- [Generate a cool SVG Palette image](#generate-a-svg-image-of-the-palette) 
Generate a cool SVG Palette image [like this 
one...](https://raw.githubusercontent.com/emacsfodder/emacs-theme-orangey-bits/master/palette.svg)
+- [Select colors from the theme in 
development](#select-colors-from-the-palette) Select, and insert a palette 
color name, or it's color value.
+- [Colorize palette color names](#colorize-color-names-from-the-palette)
+- [`autothemer-let-palette`](#let-palette)
+- [Generate missing specs, updated to allow 
filtering](#auto-generating-missing-specs)
 
-## Usage
+## Overview
 
-Autothemer requires a set of color classes, a color palette and
-simplified face specifications to be applied to Emacs.
+`autothemer-deftheme` uses a color class(es)/palette(s) which simplify the 
`deftheme` style and
+simplified face specifications to be applied to Emacs faces.
 
-Take a look at the example below.
+See the example below.
 
 ```lisp
 (autothemer-deftheme example-name "Autothemer example..."
@@ -18,7 +37,7 @@ Take a look at the example below.
   ((((class color) (min-colors #xFFFFFF))
     ((class color) (min-colors #xFF)))
 
-    ;; Specify the color palette for each of the classes above.
+    ;; Specify the color palette, color columns correspond to each of the 
classes above.
     (example-red    "#781210" "#FF0000")
     (example-green  "#22881F" "#00D700")
     (example-blue   "#212288" "#0000FF")
@@ -27,12 +46,15 @@ Take a look at the example below.
     (example-orange "#E06500" "#FF6600")
     (example-cyan   "#22DDFF" "#00FFFF"))
 
-    ;; specifications for Emacs faces.
+    ;; Specifications for Emacs faces.
+    ;; Simpler than deftheme, just specify a face name and 
+    ;; a plist of face definitions (nested for :underline, :box etc.)
     ((button (:underline t :weight 'bold :foreground example-yellow))
      (error  (:foreground example-red)))
 
     ;; Forms after the face specifications are evaluated.
     ;; (palette vars can be used, read below for details.)
+    
     (custom-theme-set-variables 'example-name
         `(ansi-color-names-vector [,example-red
                                    ,example-green
@@ -45,22 +67,32 @@ Take a look at the example below.
 
 ## Faces and Color Classes
 
-One of the things that makes writing themes for Emacs difficult is the syntax 
of `defface`, the macro used to configre Emacs `face` definitions.
+One of the things that makes writing themes for Emacs painful is the syntax of 
`defface`, 
+the macro used to configre Emacs `face` definitions.
 
-Because the syntax isn't particularly developer friendly, it usually results 
in themes with limited support for different color displays, usually GUI / 
24bit themes are made, and the results in the terminal are often sub par.  On 
occassion a theme does appear that provides better support for multiple display 
types, but due to the manual work involved in adding face specs, mode support 
is limited and development often stalls.
+Because the syntax isn't developer friendly it usually results in themes with 
limited support. Especially for
+different color displays. Usually GUI / 24bit themes are made, and the results 
in the terminal are often sub par.
+On occassion a theme does appear that provides better support for multiple 
display types, but due to the manual work
+involved in adding face specs, mode support is limited and development often 
stalls.
 
-On the plus side the complexity of face specifcations means we can in theory 
design themes that support any display with any number of colors, we can 
support dark and light background modes.  Until now it's been hard to fully 
exploit the potential.
+On the plus side the complexity of face specifcations means we can in theory 
design themes that support any display
+with any number of colors, we can support dark and light background modes.  
Until now it's been hard to fully 
+exploit the potential.
 
-Autothemer solves most of the problems that a theme developer would face.
+Autothemer attempts to solve the problems that a theme developer faces. By 
defining a simple set of
+color class rules we can remove repetitive face specs.  
 
-By defining a simple set of color class rules we can remove swathes of 
repetitive face specs.  Looking again at the example above.
+Looking again at the example above.
 
 ```lisp
 (((class color) (min-colors #xFFFFFF))
  ((class color) (min-colors #xFF)))
 ```
 
-Here we've setup a color class for 16.8million (0xFFFFFF) color display i.e. 
24bit,  which will be read from first column in the palette.  We've then setup 
a color class for 256 (0xFF) color displays i.e. Xterm-256color, this will be 
read from the second column.
+Here we've setup a color class for 16.8million (0xFFFFFF) color display i.e. 
24bit,  
+which will be read from first column in the palette.  Next we setup a color 
class for 256 (0xFF) color 
+displays i.e. `xterm-256color`, the color palette values for this will be read 
from 
+the corresponding second column.
 
 We can setup as many columns as we'd like to support, here's a few more 
examples.
 
@@ -82,11 +114,14 @@ For a dark background 24bit
 ((class color) (min-colors #xFFFFFF) (background dark))
 ```
 
-You can read more about defining faces in the Emacs manual, [display types and 
class color is covered 
here.](https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Faces.html)
+You can read more about defining faces in the Emacs manual, 
+[display types and class color is covered 
here.](https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Faces.html)
 
 ### Palette
 
-The palette definition is specified as a list of lists, each of the nested 
lists is a color name and then color values that correspond to each of the 
display/color classes defined above.
+The palette definition is specified as a list of lists, each of the nested 
lists is a
+color name and then color values that correspond to each of the display/color 
classes 
+defined above.
 
 You can set color values as nil and the first color to the left will be used.
 
@@ -102,8 +137,8 @@ For example, if we have three display classes defined, 256, 
24bit, 16 color:
 ```
 
 Note we only specify 256 color mode's `my-red` value, and leave the
-others as nil.  Autothemer will set the others with the value
-`#FF0000`.
+others as nil.  Autothemer will copy the value  `#FF0000` to the other
+color classes at the same paletee index if they are nil.
 
 ### Simplified face specs
 
@@ -133,7 +168,8 @@ affected.
 - `:slant`
 - `:style`
 
-(NOTE: there may be others I have missed!)
+(NOTE: there may be others I have missed. Please open an [issue] if you find
+another attribute that needs quoting.)
 
 ### Body / Evaluated Forms
 
@@ -141,27 +177,27 @@ After defining the display specs, palette and simplified 
face specs,
 you can include other code to be evaluated.
 
 Be aware that colors named in the palette will need to be `,`
-comma-ed.  For example if you wanted to use the color `my-red` in a
-form, you would refer to it as `,my-red`, so that it's evaluated
-properly.
-
-(This section of the README will be updated as I find any other
-gotchas.)
+comma-ed so they evaluate correctly.  For example if you wanted to use 
+the color `my-red` somewhere in the `body` section, you would refer to it
+as `,my-red`, so that it's evaluated properly.
 
 ### Auto generating missing specs
 
 You can automatically generate specs for faces that are not in your
 theme using the command
 
-`M-x autothemer-generate-templates`
+```
+M-x autothemer-generate-templates
+```
+There's an alternative command to use if you'd like to filter by regexp.
 
-This will create a new buffer with simplified specs for all unthemed
-faces.  Colors will be selected from the theme palette based on the
-nearest RGB distance to the un-themed color.
+```
+M-x autothemer-generate-templates-filtered
+```
 
-We recommend thoroughly reviewing the auto generated themes so that
-you produce a high quality theme.  Autothemer doesn't replace good
-judgement and taste!
+These commands will create a new buffer with simplified specs for all the 
+unthemed faces (or the subset you filtered by).  Colors will be selected from 
the theme palette based on the
+nearest RGB distance to the un-themed color.
 
 ### Re-using the color palette
 
@@ -175,38 +211,69 @@ use, you can define simple advice on 
`autothemer-deftheme` to do so:
                   (cadr e)))
           (cdr palette)))
 ```
+
 If you place the advice definition before the autothemer-generated theme
 is loaded, e.g. `my-red` from the example above will be available as a 
 variable that can be used in other parts of your emacs configuration.
 
+### Let palette
+
+Alternatively you can create a let-like block using the macro 
`autothemer-let-palette`.  
+You will need to load/eval the required autothemer theme source (not 
byte-compiled), before
+executing it.
+
+The palette color values will autocomplete, and you can check the palette 
+with `M-x  macrostep-expand`(place the cursor to the left of the macro call.)
+
+![macrostep-expand on 
autothemer-let-palette](https://user-images.githubusercontent.com/71587/187093078-dfffa28b-25c4-4e0f-a5b4-158e1cbdde16.png)
+
+### Colorize color-names from the palette
+
+Color names in the palette can be colorized, in any buffer.  
+Make sure there's a current theme in `autothemer--current-theme` (eval your 
autothemer based theme from source, not byte-code) and use:
+
+```
+M-x autothemer-colorize
+```
+For example, with [Soothe 
Theme](https://github.com/emacsfodder/emacs-soothe-theme) viewing 
`soothe-tva.el`:
+
+![colorize](https://user-images.githubusercontent.com/71587/187092780-d97cab25-ddb7-424f-aab7-a366584be0e4.png)
+
+For even more feedback, install and use the excellet 
[Fontify-Face](https://github.com/Fuco1/fontify-face) so you 
+can see the current face definitions too.
+
+![fontify-face](https://user-images.githubusercontent.com/71587/187092952-10e5de99-26e9-4248-a18b-10a1ab2a54f5.png)
+
+In these images `rainbow-mode` is also swiched on, so we can see hex colors 
and system palette names colorized.
+
+```
+M-x rainbow-mode
+```
+
+To edit colors interatively 
[Kurecolor](https://github.com/emacsfodder/kurecolor) will serve you well.
+
 ### Select colors from the palette
 
 Since version 0.2.8 it is possible to select a color from the palette (using 
the `completing-read` style.) 
 
 `autothemer-select-color` returns an `autothemer--color` struct 
(`name`,`value`)
 
-![](https://raw.githubusercontent.com/jasonm23/autothemer/master/autothemer-select-color-01.png)
+![](https://raw.githubusercontent.com/jasonm23/autothemer/images/autothemer-select-color-01.png)
 
-You'd need to do something like this to insert a color name or color value: 
+There are also commands to insert a selected color name or it's value.
 
-```lisp
-(require 'autothemer)
+```
+M-x  autothemer-insert-color-name
+```
+and...
 
-(defun insert-autothemer-color-value () 
-  "Select and insert a color value from `autothemer--current-theme`.")
-  (interactive)
-  (insert (autothemer--color-value (autothemer-select-color)))
-  
-(defun insert-autothemer-color-name)
-  "Select and insert a color name from `autothemer--current-theme`.")
-  (interactive)
-  (insert (autothemer--color-name (autothemer-select-color)))
+```
+M-x  autothemer-insert-color
 ```
 
 If `autothemer--current-theme` is `nil`, you'll need to eval an autothemer 
based
 theme before use.
 
-
 ### Generate a SVG image of the palette
 
 Since version 0.2.8 you can generate a SVG image of a theme palette. (see this 
example for the [Sakura 
theme](https://raw.githubusercontent.com/emacsfodder/emacs-theme-sakura/master/sakura.svg))
@@ -422,26 +489,32 @@ Once this is done you test your theme.
 (I use `disable-theme` and `enable-theme` to test/use themes under 
development.  
 Make sure you eval all the theme's elisp files before enabling the theme.)
 
-
-
 ### Themes using Autothemer
 
-- [Gruvbox](https://github.com/greduan/emacs-theme-gruvbox)
-- [Darktooth](https://github.com/emacsfodder/emacs-theme-darktooth)
-- [Creamsody](https://github.com/emacsfodder/emacs-theme-creamsody)
-- [Sakura](https://github.com/emacsfodder/emacs-theme-sakura)
-- [Cyanometric](https://github.com/emacsfodder/emacs-theme-cyanometric)
-- [Orangey Bits](https://github.com/emacsfodder/emacs-theme-orangey-bits)
-- [Vegetative](https://github.com/emacsfodder/emacs-theme-vegetative)
-
-If you are creating themes with Autothemer, please let us know (you can email 
the maintainer.)
+- [greduan/Gruvbox](https://github.com/greduan/emacs-theme-gruvbox)
+- [thongpv87/Rose Pine](https://github.com/thongpv87/rose-pine-emacs)
+- [ogdenwebb/Kaolin](https://github.com/ogdenwebb/emacs-kaolin-themes)
+- [mtreca/Sorcery](https://github.com/mtreca/emacs-theme-sorcery)
+- [ajgrf/Parchment](https://github.com/ajgrf/parchment/)
+- [emacsfodder/Darktooth](https://github.com/emacsfodder/emacs-theme-darktooth)
+- [emacsfodder/Soothe](https://github.com/emacsfodder/emacs-soothe-theme)
+- [emacsfodder/Creamsody](https://github.com/emacsfodder/emacs-theme-creamsody)
+- [emacsfodder/Sakura](https://github.com/emacsfodder/emacs-theme-sakura)
+- [emacsfodder/Orangey 
Bits](https://github.com/emacsfodder/emacs-theme-orangey-bits)
+- 
[emacsfodder/Cyanometric](https://github.com/emacsfodder/emacs-theme-cyanometric)
+- 
[emacsfodder/Vegetative](https://github.com/emacsfodder/emacs-theme-vegetative)
+
+If you are creating themes with Autothemer, please let us know, you can add the
+theme info to README and open a pull request. If you haven't released it as a
+package, via a common source, open an [issue], we can help.
 
 ### Contributing
 
-We welcome all issues and pull requests, for review by the project author.
+See [CONTRIBUTING](CONTRIBUTING.md)
 
 ### Licence
 
 See [LICENCE](LICENCE)
 
 [Autothemer]: https://github.com/jasonm23/autothemer
+[issue]: https://github.com/jasonm23/autothemer/issues/new/choose
diff --git a/autothemer.el b/autothemer.el
index 09660c5ded..a283e65389 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.9
+;; Version: 0.2.10
 ;; Package-Requires: ((dash "2.10.0") (emacs "26.1"))
 ;;
 ;;; License:
@@ -36,9 +36,17 @@
 (require 'lisp-mnt)
 (require 'subr-x)
 
-(cl-defstruct autothemer--color name value)
+(cl-defstruct
+    autothemer--color
+  name
+  value)
 
-(cl-defstruct autothemer--theme colors defined-faces name description)
+(cl-defstruct
+    autothemer--theme
+  colors
+  defined-faces
+  name
+  description)
 
 (defvar autothemer--current-theme nil
   "Internal variable of type `autothemer--theme' used by autothemer.
@@ -128,8 +136,8 @@ bindings within both the REDUCED-SPECS and the BODY."
   "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'."
-  (let ((rgb-1 (color-values color))
-        (rgb-2 (color-values (autothemer--color-value autothemer-color))))
+  (let ((rgb-1 (autothemer-hex-to-rgb color))
+        (rgb-2 (autothemer-hex-to-rgb (autothemer--color-value 
autothemer-color))))
     (-sum (--zip-with (abs (- it other)) rgb-1 rgb-2))))
 
 (defun autothemer--find-closest-color (colors color)
@@ -308,7 +316,9 @@ Otherwise, append NEW-COLUMN to every element of LISTS."
 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'."
+See also `autothemer--color-p',
+         `autothemer--color-name',
+         `autothemer--color-value'."
   (autothemer--current-theme-guard)
   (--find
    (eql (intern color-name)
@@ -321,7 +331,9 @@ 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'."
+See also `autothemer--color-p',
+         `autothemer--color-name',
+         `autothemer--color-value'."
   (autothemer--current-theme-guard)
   (let*
       ((selected
@@ -345,7 +357,7 @@ See also `autothemer--color-p', `autothemer--color-name', 
`autothemer--color-val
     (autothemer--get-color color-name)))
 
 (defun autothemer-insert-color ()
-  "Interactively select and insert a color from the current autotheme palette."
+  "Select and insert a color from the current autotheme palette."
   (interactive)
   (autothemer--current-theme-guard)
   (let ((color (autothemer--color-value
@@ -353,7 +365,7 @@ See also `autothemer--color-p', `autothemer--color-name', 
`autothemer--color-val
     (insert color)))
 
 (defun autothemer-insert-color-name ()
-  "Interactively select and insert a color name from the current autotheme 
palette."
+  "Select and insert a color name from the current autotheme palette."
   (interactive)
   (autothemer--current-theme-guard)
   (let ((color-name (autothemer--color-name
@@ -379,12 +391,143 @@ If PLIST is nil, ARGS are bound to BODY nil values."
   "Unindent string S marked with | chars."
   (replace-regexp-in-string "^ *|" "" s))
 
+;;; let palette...
+(defmacro autothemer-let-palette (&rest body)
+  "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'."
+  (autothemer--current-theme-guard)
+  `(let ,(--map (list (autothemer--color-name it) (autothemer--color-value it))
+                (autothemer--theme-colors autothemer--current-theme))
+     ,@body))
+
+;;; Colorize alist for rainbow-mode
+(defun autothemer-colorize-alist ()
+  "Generate an alist for use with rainbow-mode.
+
+To colorize use:
+
+    (rainbow-colorize-by-assoc (autothemer-colorize-alist))
+
+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)))
+
+(defvar autothemer--colors-font-lock-keywords nil)
+
+(defun autothemer-colorize ()
+  "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))))))
+  (font-lock-add-keywords nil autothemer--colors-font-lock-keywords t))
+
+(defun autothemer--color-to-hsv (rgb)
+  "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'."
+  (cl-destructuring-bind
+      (r g b) rgb
+    (let*
+        ((bri (max r g b))
+         (delta (- bri (min r g b)))
+         (sat (if (cl-plusp bri)
+                  (/ delta bri)
+                0.0))
+         (normalize #'(lambda
+                        (constant right left)
+                        (let ((hue (+ constant (/ (* 60.0 (- right left)) 
delta))))
+                          (if (cl-minusp hue)
+                              (+ hue 360.0)
+                            hue)))))
+      (list (/ (cond
+                ((zerop sat) 0.0)
+                ((= r bri) (funcall normalize 0.0 g b)) ; dominant r
+                ((= g bri) (funcall normalize 120.0 b r)) ; dominant g
+                (t (funcall normalize 240.0 r g))) ; dominant b
+               360.0)
+            sat
+            bri))))
+
+(defun autothemer-hex-to-rgb (hex)
+  "Fast convert HEX to `(r g b)'.
+(Perf equal to wx color values C function.)
+`r', `g', `b' will be values `0..65535'"
+  (let ((rgb (string-to-number (substring hex 1) 16)))
+    (list
+     (* #x101 (ash (logand #xFF0000 rgb) -16))
+     (* #x101 (ash (logand #xFF00 rgb) -8))
+     (* #x101 (logand #xFF rgb)))))
+
+(defun autothemer-color-hue (hex-color)
+  "Return the HSV hue of HEX-COLOR."
+  (car (autothemer--color-to-hsv (autothemer-hex-to-rgb hex-color))))
+
+(defun autothemer-color-sat (hex-color)
+  "Return the HSV sat of HEX-COLOR."
+  (cadr (autothemer--color-to-hsv (autothemer-hex-to-rgb hex-color))))
+
+(defun autothemer-color-brightness (hex-color)
+  "Return the HSV brightness of HEX-COLOR."
+  (caddr (autothemer--color-to-hsv (autothemer-hex-to-rgb hex-color))))
+
+(defun autothemer-darkest-order (a b)
+  "Return t if the darkness of A > B."
+  (let ((a (autothemer-color-brightness (autothemer--color-value a)))
+        (b (autothemer-color-brightness (autothemer--color-value b))))
+    (> b a)))
+
+(defun autothemer-lightest-order (a b)
+  "Return t if the lightness of A > B."
+  (let ((a (autothemer-color-brightness (autothemer--color-value a)))
+        (b (autothemer-color-brightness (autothemer--color-value b))))
+      (> a b)))
+
+(defun autothemer-saturated-order (a b)
+  "Return t if the saturation of A > B."
+  (let ((a (autothemer-color-sat (autothemer--color-value a)))
+        (b (autothemer-color-sat (autothemer--color-value b))))
+      (> a b)))
+
+(defun autothemer-hue-order (a b)
+  "Return t if the hue of A > B."
+  (let ((a (autothemer-color-hue (autothemer--color-value a)))
+        (b (autothemer-color-hue (autothemer--color-value b))))
+      (> a b)))
+
+(defun autothemer-hue-sat-order (a b)
+  "Return t if the hue and sat of A > B."
+  (let ((a-hue (autothemer-color-hue (autothemer--color-value a)))
+        (b-hue (autothemer-color-hue (autothemer--color-value b)))
+        (a-sat (autothemer-color-sat (autothemer--color-value a)))
+        (b-sat (autothemer-color-sat (autothemer--color-value b)))
+        (sort-hash-fmt "%016s-%016s"))
+    (string> (format sort-hash-fmt a-hue a-sat)
+             (format sort-hash-fmt b-hue b-sat))))
+
+(defun autothemer-sort-palette (theme-colors &optional fn)
+  "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'"
+  (let ((fn (or fn 'autothemer-darkest-order)))
+     (-sort fn theme-colors)))
+
 ;;; SVG Palette generator...
 
 (defun autothemer-generate-palette-svg (&optional options)
   "Create an SVG palette image for a theme.
 
-Optionally supply OPTIONS, a plist (all keys are optional):
+Optionally supply a plist of OPTIONS (all keys are optional, 
+required values will default or prompt interactively.):
 
     :theme-file - theme filename
     :theme-name - override the title found in :theme-file
@@ -392,14 +535,23 @@ Optionally supply OPTIONS, a plist (all keys are 
optional):
     :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 - background color
-    :text-color - text color
-    :text-accent-color - text color
-    :svg-out-file - SVG output filename
+    :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.
@@ -423,15 +575,40 @@ Swatch Template parameters:
 
     %1$s - x
     %2$s - y
-    %3$s - swatch-color
-    %4$s - text-color
-    %5$s - swatch-color-name"
+    %3$s - swatch-border-color
+    %4$s - swatch-color
+    %5$s - text-accent-color
+    %6$s - swatch-color-name"
   (interactive)
   (autothemer--plist-bind
-    (theme-file theme-name theme-description theme-url
-     swatch-width swatch-height columns page-template
-     swatch-template font-family bg-color
-     text-color text-accent-color svg-out-file)
+    (theme-file
+     theme-name
+     theme-description
+     theme-url
+
+     sort-palette
+     swatch-width
+     swatch-height
+     swatch-rotate
+     columns
+
+     page-top-margin
+     page-right-margin
+     page-bottom-margin
+     page-left-margin
+
+     page-template
+     swatch-template
+
+     font-family
+
+     bg-color
+     text-color
+     text-accent-color
+     swatch-border-color
+     h-space
+     v-space
+     svg-out-file)
     options
    (let ((theme-file (or theme-file (read-file-name "Select autothemer theme 
.el file: "))))
      (load-file theme-file) ;; make it the current-theme
@@ -459,50 +636,54 @@ Swatch Template parameters:
                          |    </a>
                          |  </g>
                          |  <g transform=\"translate(70,-40)\">
-                         |  %10$s
+                         |    %10$s
                          |  </g>
                          |</svg>
                          |")))
 
             (swatch-template
              (or swatch-template
-              (autothemer--unindent "<g 
transform=\"translate(%1$s,%2$s),rotate(45)\">
+              (autothemer--unindent "<g 
transform=\"translate(%1$s,%2$s),rotate(%9$s)\">
                          | <ellipse cx=\"70\" cy=\"70\" rx=\"45\" ry=\"45\" 
id=\"background-color\" fill=\"%3$s\"/>
                          | <ellipse cx=\"70\" cy=\"70\" rx=\"42\" ry=\"42\" 
id=\"color\" fill=\"%4$s\"/>
                          | <text style=\"font-size:7pt\" font-weight=\"bold\" 
x=\"52\" y=\"125\" id=\"color-name\">%6$s</text>
                          | <text style=\"font-size:7pt; fill:%5$s;\" 
font-weight=\"bold\" x=\"52\" y=\"134\" id=\"color\">%4$s</text>
+                         | <!-- Rect below is for debug set stroke width to be 
visible -->
+                         |   <rect x=\"0\" y=\"0\" width=\"%7$spx\" 
height=\"%8$spx\" class=\"debug-rect\" fill-opacity=\"0.0\" 
stroke-width=\"0.0mm\" stroke=\"#FF8000\"/>
                          |</g>
                          |")))
 
             (autotheme-name (autothemer--theme-name 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/";)))
             (colors (autothemer--theme-colors autothemer--current-theme))
-            (font-family  (or font-family
-                           (read-string "Font family name: " "Helvetica 
Neue")))
-            (swatch-width (or swatch-width
-                              100))
-            (swatch-height (or swatch-height
-                               150))
-            (columns (or columns
-                         6))
-            ;; TODO: Width and Height padding (55, 120) parameterized?
-            (width (+ 55 (* columns swatch-width)))
-            (height (+ 120 (* (/ (length colors) columns) swatch-height)))
-            (background-color (or bg-color
-                                  (autothemer--color-value
-                                   (autothemer--select-color "Select 
Background color: "))))
-            (text-color (or text-color
-                            (autothemer--color-value
-                             (autothemer--select-color "Select Text color: 
"))))
-            (text-accent-color (or text-accent-color
-                                   (autothemer--color-value
-                                    (autothemer--select-color "Select Text 
accent color: "))))
+            (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")))
+            (swatch-width       (or swatch-width       (read-number "Swatch 
width: " 100)))
+            (swatch-height      (or swatch-height      (read-number "Swatch 
height: " 150)))
+            (swatch-rotate      (or swatch-rotate      (read-number "Swatch 
rotate: " 45)))
+            (columns            (or columns            (read-number "Number or 
columns: " 6)))
+            (page-top-margin    (or page-top-margin    (read-number "Page Top 
margin: " 120)))
+            (page-bottom-margin (or page-bottom-margin (read-number "Page 
Bottom margin: " 60)))
+            (page-left-margin   (or page-left-margin   (read-number "Page Left 
margin: " 30)))
+            (page-right-margin  (or page-right-margin  (read-number "Page 
Right margin: " 30)))
+            (h-space            (or h-space            (read-number "Swatch 
horiztonal spacing: " 10)))
+            (v-space            (or v-space            (read-number "Swatch 
vertical spacing: " 10)))
+
+            (rows (/ (length colors) columns))
+            (width (+ page-right-margin page-left-margin
+                      (* h-space columns)
+                      (* swatch-width columns)))
+            (height (+ page-top-margin page-bottom-margin
+                       (* v-space rows)
+                       (* swatch-height (+ 1 rows))))
+
+            (background-color    (or bg-color            
(autothemer--color-value (autothemer--select-color "Select Background color: 
"))))
+            (text-color          (or text-color          
(autothemer--color-value (autothemer--select-color "Select Text color: "))))
+            (text-accent-color   (or text-accent-color   
(autothemer--color-value (autothemer--select-color "Select Text accent color: 
"))))
+            (swatch-border-color (or swatch-border-color 
(autothemer--color-value (autothemer--select-color "Select swatch border color: 
"))))
+
             (svg-out-file (or svg-out-file (read-file-name (format "Enter a 
Filename to save SVG palette for %s." theme-name))))
             (svg-swatches (string-join
                             (-map-indexed
@@ -512,16 +693,20 @@ Swatch Template parameters:
                                                  (replace-regexp-in-string
                                                   (concat autotheme-name "-") 
""
                                                   (format "%s" 
(autothemer--color-name it)))))
-                                         (x (+ 20 (* swatch-width (% index 
columns))))
-                                         (y (+ 90 (* swatch-height (/ index 
columns)))))
+                                         (x (+ page-left-margin (* (+ h-space 
swatch-width) (% index columns))))
+                                         (y (+ page-top-margin (* (+ v-space 
swatch-height) (/ index columns)))))
                                      (format swatch-template
                                              x
                                              y
-                                             background-color
+                                             swatch-border-color
                                              color
                                              text-accent-color
-                                             name)))
-                             colors)
+                                             name swatch-width swatch-height 
swatch-rotate)))
+                             (if sort-palette
+                                 (if (eql t sort-palette)
+                                     (autothemer-sort-palette colors)
+                                   (autothemer-sort-palette colors (intern 
sort-palette)))
+                                 colors))
                             "\n")))
        (with-temp-file svg-out-file
          (insert
diff --git a/bin/setup b/bin/setup
new file mode 100755
index 0000000000..7f5fec1a76
--- /dev/null
+++ b/bin/setup
@@ -0,0 +1,21 @@
+#!/bin/sh -e
+# For CI / Github Actions
+
+EMACS="${EMACS:=emacs}"
+
+NEEDED_PACKAGES="dash"
+
+INIT_PACKAGE_EL="(progn \
+  (require 'package) \
+  (push '(\"melpa\" . \"https://melpa.org/packages/\";) package-archives) \
+  (package-initialize) \
+  (unless package-archive-contents \
+     (package-refresh-contents)) \
+  (dolist (pkg '(${NEEDED_PACKAGES})) \
+    (unless (package-installed-p pkg) \
+      (package-install pkg))))"
+
+# Refresh package archives, because the test suite needs to see at least
+# package-lint and cl-lib.
+"$EMACS" -batch \
+         --eval "$INIT_PACKAGE_EL"
diff --git a/bin/test b/bin/test
new file mode 100755
index 0000000000..a2ff50bf3b
--- /dev/null
+++ b/bin/test
@@ -0,0 +1,40 @@
+#!/bin/sh
+dash="$(dirname "$(find ~/.emacs.d | grep "/dash.el$" | tail -1)")"
+
+EMACS="${EMACS:=emacs}"
+
+cat <<INFO
+════════════════════════════════════════════════════════════════════════════════
+    _         _      _____ _
+   / \  _   _| |_ __|_   _| |__   ___ _ __ ___   ___ _ __
+  / _ \| | | | __/ _ \| | | '_ \ / _ \ '_ ' _ \ / _ \ '__|
+ / ___ \ |_| | || (_) | | | | | |  __/ | | | | |  __/ |
+/_/   \_\__,_|\__\___/|_| |_| |_|\___|_| |_| |_|\___|_|
+ _____         _
+|_   _|__  ___| |_ ___
+  | |/ _ \/ __| __/ __|
+  | |  __/\__ \ |_\__ \\
+  |_|\___||___/\__|___/
+
+────────────────────────────────────────────────────────────────────────────────
+Required packages present:
+Dash: $dash
+════════════════════════════════════════════════════════════════════════════════
+$("$EMACS" --version)
+════════════════════════════════════════════════════════════════════════════════
+INFO
+
+"$EMACS" --batch \
+  -eval "(setq load-prefer-newer t)" \
+  -eval "(add-to-list 'load-path \"${dash}\")" \
+  -eval "(add-to-list 'load-path \".\")" \
+  -l ert \
+  -l dash \
+  -l autothemer.el \
+  -l tests/autothemer-tests.el \
+  -f ert-run-tests-batch-and-exit
+exitcode=$?
+
+echo "
+════════════════════════════════════════════════════════════════════════════════"
+exit ${exitcode}
diff --git a/tests/autothemer-tests.el b/tests/autothemer-tests.el
index 5699122967..03ab60faac 100644
--- a/tests/autothemer-tests.el
+++ b/tests/autothemer-tests.el
@@ -1,43 +1,177 @@
-;; theme-example.el
+;; autothemer-tests.el
 
 ;;; Code:
 
-(load-file "autothemer.el")
-
-(autothemer-deftheme
- theme-example
- "Autothemer example..."
-
-  ;; Specify the color classes used by the theme
-  ((((class color) (min-colors #xFFFFFF))
-    ((class color) (min-colors #xFF)))
-
-   ;; Specify the color palette for each of the classes above.
-   (example-red    "#781210" "#FF0000")
-   (example-green  "#22881F" "#00D700")
-   (example-blue   "#212288" "#0000FF")
-   (example-purple "#812FFF" "#Af00FF")
-   (example-yellow "#EFFE00" "#FFFF00")
-   (example-orange "#E06500" "#FF6600")
-   (example-cyan   "#22DDFF" "#00FFFF"))
-
-  ;; specifications for Emacs faces.
-  ((button (:underline t :weight 'bold :foreground example-yellow))
-   (error  (:foreground example-red)))
-
-  ;; Forms after the face specifications are evaluated.
-  ;; (palette vars can be used, read below for details.)
-  (custom-theme-set-variables
-   'theme-example
-   `(ansi-color-names-vector
-     [,example-red
-      ,example-green
-      ,example-blue
-      ,example-purple
-      ,example-yellow
-      ,example-orange
-      ,example-cyan])))
-
-;; Eval buffer and use as a test sandox.
-
-;;; theme-example.el ends here
+(require 'autothemer)
+
+(progn "Test autothemer-deftheme"
+  (autothemer-deftheme theme-example
+   "Autothemer example..."
+
+    ;; Specify the color classes used by the theme
+    ((((class color) (min-colors #xFFFFFF))
+      ((class color) (min-colors #xFF)))
+
+     ;; Specify the color palette for each of the classes above.
+     (example-red    "#781210" "#FF0000")
+     (example-green  "#22881F" "#00D700")
+     (example-blue   "#212288" "#0000FF")
+     (example-purple "#812FFF" "#Af00FF")
+     (example-yellow "#EFFE00" "#FFFF00")
+     (example-orange "#E06500" "#FF6600")
+     (example-cyan   "#22DDFF" "#00FFFF"))
+
+    ;; specifications for Emacs faces.
+    ((button (:underline t :weight 'bold :foreground example-yellow))
+     (error  (:foreground example-red)))
+
+    ;; Forms after the face specifications are evaluated.
+    ;; (palette vars can be used, read below for details.)
+    (custom-theme-set-variables
+     'theme-example
+     `(ansi-color-names-vector
+       [,example-red
+        ,example-green
+        ,example-blue
+        ,example-purple
+        ,example-yellow
+        ,example-orange
+        ,example-cyan])))
+
+  (ert-deftest current-theme ()
+    "Test current theme is available."
+    (should (not (null
+                  autothemer--current-theme))))
+
+  (ert-deftest theme-has-colors ()
+    "Check theme has colors."
+    (should (eql 7 (length (autothemer--theme-colors
+                            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)))))
+
+  (ert-deftest color-value ()
+    "Check color value."
+    (should (string= "#781210"
+                     (autothemer--color-value
+                      (car (autothemer--theme-colors
+                            autothemer--current-theme))))))
+
+  (ert-deftest color-name ()
+    "Check color name."
+    (should (string= "example-red"
+                     (autothemer--color-name
+                      (car (autothemer--theme-colors
+                            autothemer--current-theme))))))
+
+  (ert-deftest spec-name ()
+    "Check spec name."
+    (should (equal 'button
+                      (car (autothemer--theme-defined-faces
+                                  autothemer--current-theme)))))
+
+  (ert-deftest theme-has-description ()
+    "Check theme description."
+    (should (string=
+             "Autothemer example..."
+             (autothemer--theme-description
+              autothemer--current-theme))))
+
+  (ert-deftest theme-has-name ()
+    "Check theme name."
+    (should (string=
+             "theme-example"
+             (autothemer--theme-name
+              autothemer--current-theme))))
+
+  (ert-deftest let-palette ()
+    "Check autothemer-let-palette"
+    (should (string=
+             "#781210"
+             (autothemer-let-palette example-red))))
+
+  (ert-deftest unindent ()
+    "Test unindent."
+    (should
+      (string=
+        (autothemer--unindent "|Hello world
+                               |  Foo bar
+                               |  Indent
+                               |")
+        "Hello world\n  Foo bar\n  Indent\n")))
+
+  (ert-deftest autothemer-plist-bind ()
+    "Test plist-bind."
+    (autothemer--plist-bind (a b) '(:a 1 :b 2)
+     (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..."))
+
+;;; autothemer-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]