aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-07-17 15:17:10 +0200
committerChloe Kudryavtsev <code@toast.bunkerlabs.net>2023-07-17 15:17:10 +0200
commit52e8b4226a6e3fb96cb6d2182bbb20a65713cbe8 (patch)
tree55bb2bc321d9c7d7024d575a5533666c974b0a2d
parenttool: add wcag test script (diff)
tests: rewrite contrast checker in pure POSIX sh
-rw-r--r--[-rwxr-xr-x]colors/ansi.sh2
-rwxr-xr-xcolors/contrast.sh74
-rw-r--r--colors/wcag.sh57
3 files changed, 76 insertions, 57 deletions
diff --git a/colors/ansi.sh b/colors/ansi.sh
index e0334f9..37fa3aa 100755..100644
--- a/colors/ansi.sh
+++ b/colors/ansi.sh
@@ -15,5 +15,7 @@ reset() { acol 0; }
# logical input processing
colsep() { echo $* | fold -w2; }
+numdec() { printf '%d\n' 0x"$1" 0x"$2" 0x"$3"; }
+coldec() { numdec $(colsep "$@"); }
fgc() { fgx $(colsep $1); }
bgc() { bgx $(colsep $1); }
diff --git a/colors/contrast.sh b/colors/contrast.sh
new file mode 100755
index 0000000..36f4f4e
--- /dev/null
+++ b/colors/contrast.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+. ./ansi.sh
+. ./colors.sh
+
+lightness() {
+ bc -l <<-EOF
+ define pow(a, b) {
+ if (scale(b) == 0) return a ^ b
+ return e(b * l(a))
+ }
+ define cprime(c) {
+ c = c/256
+ if (c <= 0.03928) return(c / 12.92)
+ return pow((c + 0.055)/1.055, 2.4)
+ }
+ define lumi(r, g, b) {
+ return (cprime(r) * 0.2126) + \
+ (cprime(g) * 0.7152) + \
+ (cprime(b) * 0.0722)
+ }
+ lumi($1, $2, $3)
+ EOF
+}
+contrast() {
+ bc <<-EOF
+ scale = 2
+ define contrast(a, b) {
+ if (a > b) {
+ return (a + 0.05) / (b + 0.05)
+ } else {
+ return (b + 0.05) / (a + 0.05)
+ }
+ }
+ contrast($(lightness $(coldec $1)), $(lightness $(coldec $2)))
+ EOF
+}
+
+[ $# -lt 0 ] || set -- \
+ red green yellow blue magenta cyan white \
+ brred brgreen bryellow brblue brmagenta brcyan brwhite
+
+# lower: error if below this
+lower=4
+# higher: warn if below this
+higher=7
+
+reprint() {
+ printf '%s%s' "$@" "$(reset)"
+}
+
+demo() {
+ reprint "$(fgc $1)$(bgc $2) demo text "
+}
+
+gt() {
+ test -n "$(printf 'if (%s > %s) 1' "$1" "$2" | bc)"
+}
+
+for i; do
+ color=$(eval echo '$'$i)
+ value=$(contrast $background $color)
+ if gt "$lower" "$value"; then
+ # fail
+ reprint "$(acol 31)fail"
+ elif gt "$higher" "$value"; then
+ # warn
+ reprint "$(acol 33)warn"
+ else
+ # pass
+ reprint "$(acol 32)pass"
+ fi
+ printf ': #%s at %s\t%s (%s)\n' \
+ "$color" "$value" "$(demo $color $background)" "$i"
+done
diff --git a/colors/wcag.sh b/colors/wcag.sh
deleted file mode 100644
index 4b8d313..0000000
--- a/colors/wcag.sh
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/bin/sh
-. ./ansi.sh
-. ./colors.sh
-
-# this uses the webaim.org contrast checker api to check all colors against
-# background.
-# depends on jo, jq, and xh
-
-[ $# -lt 0 ] || set -- \
- red green yellow blue magenta cyan white \
- brred brgreen bryellow brblue brmagenta brcyan brwhite
-
-# lower: error if below this
-lower=4.5
-# higher: warn if below this
-higher=7
-
-# reset after printing
-reprint() {
- printf '%s%s' "$@" "$(reset)"
-}
-
-prefix() {
- reprint "$(acol $1)$2"
-}
-
-demo() {
- reprint "$(fgc $color)$(bgc $background)demo text"
-}
-
-# $1 should be "fail" or "warn"
-fmt() {
- case "$1" in
- fail) printf '"%s: #%s at \(.ratio)\t%s (%s)\n"' \
- "$(prefix 31 fail)" "$color" "$(demo)" "$colnm";;
- warn) printf '"%s: #%s at \(.ratio)\t%s (%s)\n"' \
- "$(prefix 33 warn)" "$color" "$(demo)" "$colnm";;
- *) printf '""' ;;
- esac
-}
-
-# reads stdin (json) and prints information about color if it fails
-check() {
- jq -j "
- if (.ratio | tonumber) < $lower then $(fmt fail)
- elif (.ratio | tonumber) < $higher then $(fmt warn)
- else $(fmt none)
- end"
-}
-
-for i; do
- color=$(eval echo '$'$i)
- colnm=$i
- xh https://webaim.org/resources/contrastchecker/ api== \
- bcolor==$background fcolor==$color | \
- jo -f- color=$color | check
- done