diff --git a/themes/Makefile b/themes/Makefile
index 90b8a5d..f445a40 100644
--- a/themes/Makefile
+++ b/themes/Makefile
@@ -1,5 +1,5 @@
# env
-# Written in 2019 by Lucas
+# Written in 2019-2020 by Lucas
# CC0 1.0 Universal/Public domain - No rights reserved
#
# To the extent possible under law, the author(s) have dedicated all
@@ -10,25 +10,21 @@
# .
.POSIX:
.SUFFIXES:
-.SUFFIXES: .c .in .txt .png
+.SUFFIXES: .in .txt .png
-LDLIBS= -lm
THEMES= blueie brightie brightie2 brightie3 brightie4
-.c:
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
-
.in.txt:
- ./colorscheme <"$<" >"$@"
+ perl colorscheme.pl <"$<" >"$@"
.in.png:
- ./colorscheme -i <"$<" | pnmtopng >"$@"
+ perl colorscheme.pl -i <"$<" | pnmtopng >"$@"
-all: colorscheme
+all: colorscheme.pl
clean:
- rm -f colorscheme $(THEMES:=.png) $(THEMES:=.txt)
+ rm -f $(THEMES:=.png) $(THEMES:=.txt)
-show: $(THEMES:=.png) $(THEMES:=.txt)
+show: $(THEMES:=.txt) $(THEMES:=.png)
-$(THEMES:=.png) $(THEMES:=.txt): all
+$(THEMES:=.txt) $(THEMES:=.png): all
diff --git a/themes/colorscheme.c b/themes/colorscheme.c
deleted file mode 100644
index 536f1d0..0000000
--- a/themes/colorscheme.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * env
- * Written in 2019 by Lucas
- * CC0 1.0 Universal/Public domain - No rights reserved
- *
- * To the extent possible under law, the author(s) have dedicated all
- * copyright and related and neighboring rights to this software to the
- * public domain worldwide. This software is distributed without any
- * warranty. You should have received a copy of the CC0 Public Domain
- * Dedication along with this software. If not, see
- * .
- */
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define LENGTH 50
-
-#define INRANGE(x, a, b) ((a) <= (x) && (x) <= (b))
-
-static void
-hsvtorgb(double hsv[3], uint8_t rgb[3])
-{
- double c, hh, m, x;
- double r, g, b;
-
- c = hsv[2] * hsv[1];
- hh = hsv[0] / 60.0;
- x = c * (1.0 - fabs(fmod(hh, 2.0) - 1.0));
-
- switch ((int)floor(hh == 6.0 ? 0.0 : hh)) {
- case 0: r = c; g = x; b = 0; break;
- case 1: r = x; g = c; b = 0; break;
- case 2: r = 0; g = c; b = x; break;
- case 3: r = 0; g = x; b = c; break;
- case 4: r = x; g = 0; b = c; break;
- case 5: r = c; g = 0; b = x; break;
- }
-
- m = hsv[2] - c;
- r += m; g += m; b += m;
-
- rgb[0] = round(255 * r);
- rgb[1] = round(255 * g);
- rgb[2] = round(255 * b);
-}
-
-static void
-hsltorgb(double hsl[3], uint8_t rgb[3])
-{
- double c, hh, m, x;
- double r, g, b;
-
- c = (1.0 - fabs(2.0 * hsl[2] - 1.0)) * hsl[1];
- hh = hsl[0] / 60.0;
- x = c * (1.0 - fabs(fmod(hh, 2.0) - 1.0));
-
- switch ((int)floor(hh == 6.0 ? 0.0 : hh)) {
- case 0: r = c; g = x; b = 0; break;
- case 1: r = x; g = c; b = 0; break;
- case 2: r = 0; g = c; b = x; break;
- case 3: r = 0; g = x; b = c; break;
- case 4: r = x; g = 0; b = c; break;
- case 5: r = c; g = 0; b = x; break;
- }
-
- m = hsl[2] - c / 2.0;
- r += m; g += m; b += m;
-
- rgb[0] = round(255 * r);
- rgb[1] = round(255 * g);
- rgb[2] = round(255 * b);
-}
-
-static void
-parsecolorline(const char *s, size_t n, uint8_t rgb[3])
-{
- double d[3];
- unsigned int u[3];
-
- if (sscanf(s, "hsv %lf %lf %lf", &d[0], &d[1], &d[2]) == 3) {
- if (!INRANGE(d[0], 0, 360) || !INRANGE(d[1], 0, 1)
- || !INRANGE(d[2], 0, 1))
- goto err;
- hsvtorgb(d, rgb);
- } else if (sscanf(s, "hsl %lf %lf %lf", &d[0], &d[1], &d[2]) == 3) {
- if (!INRANGE(d[0], 0, 360) || !INRANGE(d[1], 0, 1)
- || !INRANGE(d[2], 0, 1))
- goto err;
- hsltorgb(d, rgb);
- } else if (sscanf(s, "rgb %u %u %u", &u[0], &u[1], &u[2]) == 3) {
- if (!INRANGE(u[0], 0, 255) || !INRANGE(u[1], 0, 255)
- || !INRANGE(u[2], 0, 255))
- goto err;
- rgb[0] = u[0]; rgb[1] = u[1]; rgb[2] = u[2];
- } else if (sscanf(s, "rgbhex %x %x %x", &u[0], &u[1], &u[2]) == 3) {
- if (!INRANGE(u[0], 0, 255) || !INRANGE(u[1], 0, 255)
- || !INRANGE(u[2], 0, 255))
- goto err;
- rgb[0] = u[0]; rgb[1] = u[1]; rgb[2] = u[2];
- } else {
-err:
- fprintf(stderr, "Invalid input: \"%s\".", s);
- exit(1);
- }
-}
-
-static void
-readcolorscheme(uint8_t colorscheme[18][3])
-{
- char *line = NULL;
- size_t linesize = 0;
- ssize_t linelen;
- int nlines = 0;
-
- while ((linelen = getline(&line, &linesize, stdin)) != -1
- && nlines < 18) {
- if (linelen == 0 || line[0] == '\n' || line[0] == '#')
- continue;
- parsecolorline(line, linelen, colorscheme[nlines]);
- nlines++;
- }
- free(line);
- if (ferror(stdin)) {
- fputs("Input error.\n", stderr);
- exit(1);
- }
- if (nlines < 18) {
- fputs("Not enought colors.\n", stderr);
- exit(1);
- }
-}
-
-static void
-writecolor(uint8_t rgb[3], int l)
-{
- int i;
- for (i = 0; i < l; i++) {
- if (fwrite(rgb, sizeof(rgb[0]), 3, stdout) != 3) {
- fputs("Short write.\n", stderr);
- exit(1);
- }
- }
-}
-
-static void
-do_image(uint8_t colorscheme[18][3])
-{
- int i, n;
-
- printf("P6\n%u %u 255\n", 9 * LENGTH, 2 * LENGTH);
- for (i = 0; i < LENGTH; i++)
- for (n = 0; n < 9; n++)
- writecolor(colorscheme[n], LENGTH);
- for (i = 0; i < LENGTH; i++)
- for (n = 9; n < 18; n++)
- writecolor(colorscheme[n], LENGTH);
-}
-
-static void
-do_colors(uint8_t colorscheme[18][3])
-{
- int n;
- for (n = 0; n < 18; n++)
- printf("#%02x%02x%02x\n", colorscheme[n][0],
- colorscheme[n][1], colorscheme[n][2]);
-}
-
-int
-main(int argc, char *argv[])
-{
- uint8_t colorscheme[18][3];
- int iflag = 0;
-
- if (argc > 2)
- goto usage;
- if (argc == 2) {
- if (strncmp(argv[1], "-i", 3) != 0)
- goto usage;
- iflag = 1;
- }
-
- readcolorscheme(colorscheme);
-
- if (iflag)
- do_image(colorscheme);
- else
- do_colors(colorscheme);
-
- return 0;
-
-usage:
- fprintf(stderr, "Usage: %s [-i]\n", argv[0]);
- return 1;
-}
diff --git a/themes/colorscheme.pl b/themes/colorscheme.pl
new file mode 100644
index 0000000..65fd3a7
--- /dev/null
+++ b/themes/colorscheme.pl
@@ -0,0 +1,175 @@
+#!/usr/bin/env perl
+# colorscheme.pl
+#
+# Written in 2020 by Lucas
+#
+# To the extent possible under law, the author(s) have dedicated all
+# copyright and related and neighboring rights to this software to the
+# public domain worldwide. This software is distributed without any
+# warranty.
+#
+# You should have received a copy of the CC0 Public Domain Dedication
+# along with this software. If not, see
+# .
+
+use v5.12;
+use strict;
+use warnings;
+
+use Getopt::Std;
+use POSIX qw(fmod);
+
+use constant {
+ LENGTH => 50,
+};
+
+my $progname = $0;
+$progname =~ s@.*/@@;
+
+sub err (@)
+{
+ say STDERR "$progname: @_";
+ exit 1;
+}
+
+sub usage ()
+{
+ say STDERR "Usage: $progname [-i]";
+ exit 1;
+}
+
+sub validhsv ($$$)
+{
+ my ($h, $s, $v) = @_;
+ return $h >= 0.0 && $h <= 360.0 && $s >= 0.0 && $s <= 1.0 &&
+ $v >= 0.0 && $v <= 1.0;
+}
+
+sub validhsl ($$$)
+{
+ my ($h, $s, $l) = @_;
+ return $h >= 0.0 && $h <= 360.0 && $s >= 0.0 && $s <= 1.0 &&
+ $l >= 0.0 && $l <= 1.0;
+}
+
+sub validrgb ($$$)
+{
+ my ($r, $g, $b) = @_;
+ return $r >= 0 && $r <= 255 && $g >= 0 && $g <= 255 &&
+ $b >= 0 && $b <= 255;
+}
+
+sub validrgbhex ($$$)
+{
+ my ($r, $g, $b) = @_;
+ return $r =~ /^[0-9A-Fa-f]{2}$/ && $g =~ /^[0-9A-Fa-f]{2}$/ &&
+ $b =~ /^[0-9A-Fa-f]{2}$/;
+}
+
+sub hsvtorgb ($$$)
+{
+ my ($h, $s, $v) = @_;
+
+ my $c = $s * $v;
+ my $hh = $h == 360.0 ? 0.0 : $h / 60.0;
+ my $x = $c * (1.0 - abs(fmod($hh, 2.0) - 1.0));
+
+ my ($r, $g, $b);
+ for (int($hh)) {
+ ($r, $g, $b) = ($c, $x, 0) if $_ == 0;
+ ($r, $g, $b) = ($x, $c, 0) if $_ == 1;
+ ($r, $g, $b) = (0, $c, $x) if $_ == 2;
+ ($r, $g, $b) = (0, $x, $c) if $_ == 3;
+ ($r, $g, $b) = ($x, 0, $c) if $_ == 4;
+ ($r, $g, $b) = ($c, 0, $x) if $_ == 5;
+ }
+
+ my $m = $v - $c;
+ return map {255 * ($_ + $m)} $r, $g, $b;
+}
+
+sub hsltorgb ($$$)
+{
+ my ($h, $s, $l) = @_;
+
+ my $c = (1.0 - abs(2.0 * $l - 1.0)) * $s;
+ my $hh = $h == 360.0 ? 0.0 : $h / 60.0;
+ my $x = $c * (1.0 - abs(fmod($hh, 2.0) - 1.0));
+
+ my ($r, $g, $b);
+ for (int($hh)) {
+ ($r, $g, $b) = ($c, $x, 0) if $_ == 0;
+ ($r, $g, $b) = ($x, $c, 0) if $_ == 1;
+ ($r, $g, $b) = (0, $c, $x) if $_ == 2;
+ ($r, $g, $b) = (0, $x, $c) if $_ == 3;
+ ($r, $g, $b) = ($x, 0, $c) if $_ == 4;
+ ($r, $g, $b) = ($c, 0, $x) if $_ == 5;
+ }
+
+ my $m = $l - $c / 2.0;
+ return map {255 * ($_ + $m)} $r, $g, $b;
+}
+
+sub parseinput ()
+{
+ my @colors;
+
+ while (my $line = ) {
+ chomp $line;
+ next if $line =~ /^#|^$/;
+ my ($t, $x, $y, $z, undef) = split(/\s+/, $line, 5);
+
+ my @v;
+ if ($t eq "hsv") {
+ die "invalid input: $line" unless validhsv($x, $y, $z);
+ @v = map {int} hsvtorgb($x, $y, $z);
+ } elsif ($t eq "hsl") {
+ die "invalid input: $line" unless validhsl($x, $y, $z);
+ @v = map {int} hsltorgb($x, $y, $z);
+ } elsif ($t eq "rgb") {
+ die "invalid input: $line" unless validrgb($x, $y, $z);
+ @v = map {int} ($x, $y, $z);
+ } elsif ($t eq "rgbhex") {
+ die "invalid input: $line"
+ unless validrgbhex($x, $y, $z);
+ @v = map {hex} ($x, $y, $z);
+ } else {
+ die "invalid input: $line";
+ }
+ push(@colors, \@v);
+ }
+
+ return @colors;
+}
+
+sub main ()
+{
+ my %opts;
+
+ getopts("i", \%opts) or usage;
+
+ my @colors = parseinput();
+
+ if (defined($opts{"i"})) {
+ err "Colorscheme doesn't have 18 colors"
+ if scalar(@colors) != 18;
+
+ printf "P6\n%u %u 255\n", 9 * LENGTH, 2 * LENGTH;
+ for (0..LENGTH - 1) {
+ for (0..8) {
+ print pack("CCC", @{$colors[$_]}) x LENGTH;
+ }
+ }
+ for (0..LENGTH - 1) {
+ for (9..17) {
+ print pack("CCC", @{$colors[$_]}) x LENGTH;
+ }
+ }
+ } else {
+ foreach (@colors) {
+ say "#", (map {sprintf "%02x", $_} @$_);
+ }
+ }
+}
+
+main();