web-colors

Project / Source Code Repository
https://gitlab.com/jcroisant/chicken-web-colors
Issue Tracker
https://gitlab.com/jcroisant/chicken-web-colors/issues
Maintainer
John Croisant
License
BSD 2-Clause

This library can parse and write colors in a variety of formats used in HTML/CSS:

This library does not provide color math or color space conversion. It is intended to be used with other libraries.

Table of Contents

  1. web-colors
    1. Usage
    2. Data representation
    3. Parsing
    4. Writing
    5. Other
    6. Version History

Usage

(import web-colors)

(parse-web-color "#B64926") ; → (rgb 182 73 38 1)
(web-color->string '(rgb 182 73 38 1)) ; → "#b64926"

(parse-web-color "rgb(93 152 121 / 51%)") ; → (rgb 93 152 121 51/100)
(web-color->string '(rgb 93 152 121 51/100)) ; → "rgba(93, 152, 121, 0.51)"

(parse-web-color "rgba( 100%, 72.9%, 33%, 0.5 )") ; → (rgb% 1 0.729 33/100 0.5)
(web-color->string '(rgb% 1 0.729 33/100 0.5)) ; → "rgba(100%, 72.9%, 33%, 0.5)"

(parse-web-color "hsl(210 51% 87% / 77%)") ; → (hsl 210 51/100 87/100 77/100)
(web-color->string '(hsl 210 51/100 87/100 77/100)) ; → "hsla(210, 51%, 87%, 0.77)"

(parse-web-color "indigo") ; → (rgb 75 0 130 1)
(web-color->string '(rgb 75 0 130 1)) ; → "#4b0082"
(web-color-name '(rgb 75 0 130 1)) ; → "indigo"

;; Create file styles.css containing "body { color: #010203; }"
(call-with-output-file "styles.css"
  (lambda (port)
    (display "body { color: " port)
    (write-web-color '(rgb 1 2 3 1) port)
    (display "; }" port)))

;; Use with other libraries
(import (prefix sdl2 "sdl2:"))
(apply sdl2:make-color
 (rgb-color->bytes (parse-web-color "indigo")))
;; → #<sdl2:color (75 0 130 255)>

Data representation

Colors are represented as a list starting with a symbol indicating the color type, followed by the color components. See above for examples. The semantics of each component depends on the color type:

TYPE   COMPONENT   TYPICAL RANGE

rgb
       red         [0, 255]
       green       [0, 255]
       blue        [0, 255]
       alpha       [0, 1]

rgb%
       red         [0, 1]
       green       [0, 1]
       blue        [0, 1]
       alpha       [0, 1]

hsl
       hue         [0, 360)  see below
       satur.      [0, 1]
       lumin.      [0, 1]
       alpha       [0, 1]

Values with a typical range of [0, 1] are usually represented with floating point numbers or ratios. Values with a larger range are usually represented with integers, but floating point numbers or ratios are allowed.

Values outside of the typical range are allowed. You can use normalize-web-color to clamp/wrap values to their typical range.

In CSS Color Module Level 4, the hue component can optionally have a unit: deg, rad, grad, or turn. The parser converts the hue to degrees, and the writer assumes it is in degrees.

Parsing

[procedure] (parse-web-color string) → color-list
[procedure] (parse-hex-color string) → color-list
[procedure] (parse-named-color string) → color-list
[procedure] (parse-rgb-color string) → color-list
[procedure] (parse-hsl-color string) → color-list

The parse-web-color procedure parses any type of color from a string. It returns an rgb, rgb%, or hsl color list depending on the input.

The other procedures can only parse certain types of colors, but are more efficient if you only need to parse those types.

These procedures signal an error if parsing fails.

Writing

[procedure] (write-web-color color-list #!optional port)
[procedure] (write-hex-color color-list #!optional port)
[procedure] (write-rgb-color color-list #!optional port)
[procedure] (write-hsl-color color-list #!optional port)

The write-web-color procedure writes any type of color to port (by default, the current output port). Its behavior is as follows:

The other procedures can only write certain types of colors, but are more efficient if only need to write one color type. You can also use them to write in a format that write-web-color would not use. For example, write-hex-color will write an 8 digit hex color if given an rgb or rgb% color list with alpha other than 1, whereas write-web-color would write a rgba() color.

write-hex-color and write-rgb-color accept rgb or rgb% color lists. write-hsl-color accepts hsl color lists.

These procedures signal an error if the color list is invalid or an unsupported type.

[procedure] (web-color->string color-list) → string
[procedure] (rgb-color->hex-string color-list) → string
[procedure] (rgb-color->string color-list) → string
[procedure] (hsl-color->string color-list) → string

Like write-web-color, etc. except that the color is written to a string and returned. Equivalent to:

(call-with-output-string
  (lambda (port)
    (write-web-color color-list port)))
[procedure] (web-color-name color-list) → string or #f

Attempts to find a named color exactly matching the given color list. Returns the color name string if found, or #f if not found.

The colors are compared with equal?, so the given color list should be a rgb type with exact integers, not ratios or floats. Alpha should usually be 1, except "transparent" which has alpha 0.

Note that some colors are synonyms (e.g. "aqua" and "cyan"). In such cases only the first match is returned. (By default, color names are ordered alphabetically, but this can be overridden with the *web-color-names* parameter.)

Other

[constant] +web-color-types+

A list of symbols for the color types supported by this library: '(rgb rgb% hsl). This may be expanded in future versions.

[procedure] (color-list? x #!optional types) → boolean

Returns #t if x is a valid color list, i.e. a list containing a color type symbol and 4 numbers. It does not check that the numbers are in the typical range.

types can be a list of symbols to check that x is one of the specified color types. If types is omitted it defaults to +web-color-types+, so it checks for any supported color type.

(color-list? '(hsl 1 2 3 4))  ; → #t
(color-list? '(hsl 1 2 3 4) '(rgb rgb%))  ; → #f
[procedure] (rgb-color->bytes color-list) → (r g b a)

Converts a rgb or rgb% color list into a list containing the RGBA color components as exact integers in the range [0, 255].

(rgb-color->bytes '(rgb 123 256 -1 50/100)) ; → (123 255 0 128)
(rgb-color->bytes '(rgb% 0.4 1.1 -0.1 0.25)) ; → (102 255 0 128)
[procedure] (normalize-web-color color-list) → color-list

Returns a normalized copy of the given color list. All values are clamped or wrapped to their typical range.

Signals an error if the color list is invalid.

[parameter] *web-color-names*

Contains a list of (symbol . list) pairs for named colors. You can override this parameter to change the color names recognized by parse-web-color, parse-named-color, and web-color-name. Color names should contain only lower-case letters, numbers, and hyphens.

;; Add the colors "amaranth" and "viridian".
(*web-color-names*
 `((amaranth . (rgb 229 43 80 1))
   (viridian . (rgb 64 130 109 1))
   ,@(*web-color-names*)))

(parse-web-color "amaranth")
; → (rgb 229 43 80 1)

(web-color-name '(rgb 64 130 109 1))
; → "viridian"

Version History

1.0.0 (2019-12-31)
Initial release.