Compare commits

..

21 commits
v1.1 ... main

Author SHA1 Message Date
jaseg
1212a9cc6c Correct DESTDIR/PREFIX usage in Makefile
Closes #56
2024-07-16 11:43:44 +02:00
jaseg
621b604edd Add CPPFLAGS and LDFLAGS to compiler invocation
Fixes #57
2024-07-16 11:39:09 +02:00
jaseg
1ea54a14d5 Make images embedded in README use relative paths
Fixes #59
2024-07-16 11:36:46 +02:00
jaseg
e460e3d132 Add a little release script to keep the version numbers in sync
Fixes #58
2024-07-16 11:35:08 +02:00
jaseg
10b56bcdc2 Fix version number in autotools and PKGBUILD build scripts 2024-07-16 11:24:39 +02:00
Ellam ByDefault
bfd7446198 ignore lolcat and censor, add Debian dependency 2024-07-16 11:16:39 +02:00
jaseg
a9ab81839f Bump version to v1.5 2024-07-04 11:49:59 +02:00
jaseg
f2c26ed7a7 Make lolcat interleave nicely with non-colored stderr
This works by making lolcat always reset the color at the end of a line
on its input, and only setting a new color immediately before printing
the first character on the next line. This way, assuming that whatever
process is piped into lolcat follow the standard convention where stdout
is buffered line-wise, and only writes full lines to stderr, a process
that outputs to both stdout and stderr but that has only stdout piped
through lolcat (as most people would do) would have it's stderr output
interleave nicely uncolored with the lolcat-colored stdout output.

This won't always work, but it gets us most of the way there with little
effort and negligible (2 extra escape sequences per line of output)
performance overhead.

Thanks to github user @kolayne for reporting this as an issue!
2024-07-04 11:45:58 +02:00
jaseg
dc3ddf3950 Bump version to v1.4 2023-02-26 18:57:20 +01:00
jaseg
f25a84cc4d Fix handling of repeated escape sequences and certain XTERM title sequences 2023-02-26 18:56:57 +01:00
jaseg
a087460a99 Bump version to v1.3 2022-11-19 17:40:06 +01:00
jaseg
8241091f59 Extend escape sequence parser to support various ST-terminated sequences
This improves interactions with programs using them to set the terminal
window title or display images among other things.

Closes #42.
2022-11-19 17:31:34 +01:00
jaseg
4d7a6c3bba Remove redundant code 2022-11-19 14:24:45 +01:00
jaseg
8ed4ce20a5 Add --gradient option, allow specification of custom gradients.
Closes #47
2022-11-19 14:24:04 +01:00
Nor Khasyatillah
6db5a0fa50 Add new option --invert. 2022-11-19 13:00:17 +01:00
Nor Khasyatillah
37bb84e297 Add new option --seed 2022-11-19 12:49:46 +01:00
jaseg
2a23642da7 Add 16-color mode for limited terminals
closes #43
2022-11-19 12:41:00 +01:00
Daniel Santos
8173ed8cb6 build: Add autotools option for those who want it
Closes #40.
2021-10-14 23:11:20 +02:00
Thomas Friese
1d52554cb1 Add manual start color offset 2021-07-28 13:00:07 +02:00
jaseg
6a2ab611a7 Bump version to v1.2 2021-01-16 13:23:22 +01:00
jaseg
0039b3f832 Fix linker argument order (fixes #36)
Thanks @elig0n !
2021-01-16 13:21:53 +01:00
12 changed files with 662 additions and 41 deletions

2
.gitignore vendored
View file

@ -1,2 +1,4 @@
lolcat.o
censor.o
lolcat
censor

View file

@ -1,10 +1,9 @@
CC ?= gcc
LOLCAT_SRC ?= lolcat.c
CENSOR_SRC ?= censor.c
CFLAGS ?= -std=c11 -Wall -Wextra -O3 -Wno-sign-compare -lm
CFLAGS ?= -std=c11 -Wall -Wextra -O3 -Wno-sign-compare
LIBS := -lm
DESTDIR ?= /usr/local/bin
PREFIX ?= /usr/local
all: lolcat censor
@ -13,15 +12,18 @@ debug: all
.PHONY: install clean debug
lolcat: $(LOLCAT_SRC)
$(CC) $(CFLAGS) -o $@ $^
xterm256lut.h: xterm256lut_gen.py
python $< > $@
censor: $(CENSOR_SRC)
$(CC) $(CFLAGS) -o $@ $^
lolcat: lolcat.c xterm256lut.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
censor: censor.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS)
install: lolcat censor
install lolcat $(DESTDIR)/lolcat
install censor $(DESTDIR)/censor
install lolcat $(DESTDIR)$(PREFIX)/bin/lolcat
install censor $(DESTDIR)$(PREFIX)/bin/censor
clean:
rm -f lolcat censor

View file

@ -1,7 +1,7 @@
# Maintainer: Ricardo (XenGi) Band <email@ricardo.band>
pkgname=c-lolcat
pkgver=r26.502d379
pkgver=v1.5
pkgrel=1
pkgdesc="High-performance implementation of lolcat"
arch=('i686' 'x86_64')

View file

@ -1,10 +1,10 @@
# What?
![](https://raw.githubusercontent.com/jaseg/lolcat/master/LOLCat-Rainbow.jpg)
![](./LOLCat-Rainbow.jpg)
## Screenshot
![](https://raw.githubusercontent.com/jaseg/lolcat/master/screenshot.png)
![](./screenshot.png)
![](./sl.gif)
@ -44,6 +44,8 @@ $ make lolcat
### Others
Note: Debian users may need the `python-is-python3` package.
```bash
$ make && sudo make install
```

7
autotools/Makefile.am Normal file
View file

@ -0,0 +1,7 @@
bin_PROGRAMS = lolcat censor
lolcat_SOURCES = ../lolcat.c
censor_SOURCES = ../censor.c
LIBS += -lm
CFLAGS ?= -O3
AM_CFLAGS = -std=c11 -Wall -Wextra -Wno-sign-compare -Werror=implicit

7
autotools/README Normal file
View file

@ -0,0 +1,7 @@
This directory contains an autotools config for building lolcat for those who need it. This is an alternative to the
Makefile provided in the git root. Run it like so:
cd autotools # go here
./autogen.sh
./configure
make

36
autotools/autogen.sh Executable file
View file

@ -0,0 +1,36 @@
#!/bin/bash
auxdir=autoscripts
set -x
# aclocal generated files
rm -rf aclocal.m4 autom4te.cache
# autoheader generated files
rm -f config.h.in
# autoconf generated files
rm -f configure
# automake generated files
rm -f ${auxdir}/{config.guess,config.sub,depcomp,install-sh,missing}
rm -f Makefile.in
# configure generated files
rm -f config.h config.log config.status Makefile Makefile.in stamp-h1
rm -f $(find ${auxdir} -type l 2>/dev/null)
rmdir ${auxdir} 2>/dev/null
if [[ "$1" == clean ]]; then
exit 0
fi
mkdir ${auxdir} 2>/dev/null
aclocal
autoheader
autoconf
automake --add-missing

35
autotools/configure.ac Normal file
View file

@ -0,0 +1,35 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([lolcat], [1.5], [jaseg <github@jaseg.de>])
AC_CONFIG_SRCDIR([../lolcat.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_AUX_DIR([autoscripts])
AC_CANONICAL_TARGET
AC_CANONICAL_HOST
# Automake
AM_INIT_AUTOMAKE([foreign subdir-objects])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for libraries.
AC_CHECK_LIB([m], [cos])
# Checks for header files.
AC_CHECK_HEADERS([locale.h stdint.h stdlib.h string.h sys/time.h unistd.h wchar.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
AC_CHECK_HEADER_STDBOOL
AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_STRTOD
AC_CHECK_FUNCS([gettimeofday setlocale strchr strerror strstr wcwidth])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

31
do_release.sh Executable file
View file

@ -0,0 +1,31 @@
#!/bin/sh
set -e
if [ $# -lt 1 ]; then
echo "do_release.sh must be called with a version number as its first argument."
exit 1
fi
if [ -n "$(git status --porcelain|grep -v '^??')" ]; then
echo "do_release.sh must be called from a clean working directory."
exit 2
fi
VER="$1"
if echo "$VER" | grep -v '^[0-9]\+\.[0-9]\+$'; then
echo "do_release.sh must be called with a version number formatted like "1.23" as its first argument, with no leading \"v\"."
exit 1
fi
echo "Updating files for version v$VER"
sed -i "/L\"lolcat version [0-9.]\+, (c) [0-9]\+ jaseg\\\\n\"/s/version [0-9.]\+/version $VER/" lolcat.c
sed -i "s/^pkgver=v[0-9.]\+/pkgver=v$VER/" PKGBUILD
sed -i "/^AC_INIT/s/\[[0-9.]\+\]/[$VER]/" autotools/configure.ac
git add lolcat.c PKGBUILD autotools/configure.ac
git commit -m 'Bump version to v$VER'
git tag "v$VER"
echo "Success."

288
lolcat.c
View file

@ -24,7 +24,9 @@
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/param.h>
#include <unistd.h>
#include <limits.h>
#include <wchar.h>
#include <time.h>
#include "math.h"
@ -41,8 +43,15 @@ static char helpstr[] = "\n"
" --no-force-locale, -l: Use encoding from system locale instead of\n"
" assuming UTF-8\n"
" --random, -r: Random colors\n"
" --seed <d>, -s <d>: Random colors based on given seed,\n"
" implies --random\n"
" --color_offset <d>, -o <d>: Start with a different color\n"
" --gradient <g>, -g <g>: Use color gradient from given start to end color,\n"
" format: -g ff4444:00ffff\n"
" --24bit, -b: Output in 24-bit \"true\" RGB mode (slower and\n"
" not supported by all terminals)\n"
" --16color, -x: Output in 16-color mode for basic terminals\n"
" --invert, -i: Invert foreground and background\n"
" --version: Print version and exit\n"
" --help: Show this message\n"
"\n"
@ -57,28 +66,121 @@ static char helpstr[] = "\n"
#define ARRAY_SIZE(foo) (sizeof(foo) / sizeof(foo[0]))
const unsigned char codes[] = { 39, 38, 44, 43, 49, 48, 84, 83, 119, 118, 154, 148, 184, 178, 214, 208, 209, 203, 204, 198, 199, 163, 164, 128, 129, 93, 99, 63, 69, 33 };
const unsigned char codes16[] = {31, 33, 32, 36, 34, 35, 95, 94, 96, 92, 93, 91};
unsigned int codes_gradient[128];
static void find_escape_sequences(wint_t c, int* state)
union rgb_c {
struct {
unsigned char b;
unsigned char g;
unsigned char r;
};
unsigned int i;
};
#include "xterm256lut.h"
int xterm256lookup(union rgb_c *in) {
size_t min_i;
int min_v = INT_MAX;
for (size_t i=0; i<ARRAY_SIZE(xterm256lut); i++) {
int dr = in->r - xterm256lut[i].r;
int dg = in->g - xterm256lut[i].g;
int db = in->b - xterm256lut[i].b;
int d = dr*dr + dg*dg + db*db;
if (d < min_v) {
min_v = d;
min_i = i;
}
}
return 16 + min_i;
}
void rgb_interpolate(union rgb_c *start, union rgb_c *end, union rgb_c *out, double f) {
out->r = start->r + (end->r - start->r)*f;
out->g = start->g + (end->g - start->g)*f;
out->b = start->b + (end->b - start->b)*f;
}
enum esc_st {
ST_NONE=0,
ST_ESC_BEGIN,
ST_ESC_STRING,
ST_ESC_CSI,
ST_ESC_STRING_TERM,
ST_ESC_CSI_TERM,
ST_ESC_TERM,
NUM_ST
};
const char * esc_st_names[NUM_ST] = {
[ST_NONE] = "NONE",
[ST_ESC_BEGIN] = "BEGIN",
[ST_ESC_STRING] = "STRING",
[ST_ESC_CSI] = "CSI",
[ST_ESC_STRING_TERM] = "STRING_TERM",
[ST_ESC_CSI_TERM] = "CSI_TERM",
[ST_ESC_TERM] = "TERM",
};
static enum esc_st find_escape_sequences(wint_t c, enum esc_st st)
{
if (c == '\033') { /* Escape sequence YAY */
*state = 1;
} else if (*state == 1) {
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'))
*state = 2;
if (st == ST_NONE || st == ST_ESC_CSI_TERM) {
if (c == '\033') { /* Escape sequence YAY */
return ST_ESC_BEGIN;
} else {
return ST_NONE;
}
} else if (st == ST_ESC_BEGIN) {
if (c == '[') {
return ST_ESC_CSI;
} else if (c == 'P' || c == ']' || c == 'X' || c == '^' || c == '_') {
return ST_ESC_STRING;
} else {
return ST_ESC_TERM;
}
} else if (st == ST_ESC_CSI) {
if (0x40 <= c && c <= 0x7e) {
return ST_ESC_CSI_TERM;
} else {
return st;
}
} else if (st == ST_ESC_STRING) {
if (c == '\007') {
return ST_NONE;
} else if (c == '\033') {
return ST_ESC_STRING_TERM;
} else {
return st;
}
} else if (st == ST_ESC_STRING_TERM) {
if (c == '\\') {
return ST_NONE;
} else {
return ST_ESC_STRING;
}
} else {
*state = 0;
return ST_NONE;
}
}
static void usage(void)
{
wprintf(L"Usage: lolcat [-h horizontal_speed] [-v vertical_speed] [--] [FILES...]\n");
exit(1);
wprintf(L"\n");
wprintf(L"Use lolcat --help to print the full help text.\n");
exit(2);
}
static void version(void)
{
wprintf(L"lolcat version 1.1, (c) 2020 jaseg\n");
wprintf(L"lolcat version 1.5, (c) 2024 jaseg\n");
exit(0);
}
@ -101,7 +203,13 @@ int main(int argc, char** argv)
int colors = isatty(STDOUT_FILENO);
int force_locale = 1;
int random = 0;
unsigned int seed = time(NULL);
int start_color = 0;
int rgb = 0;
int ansi16 = 0;
int invert = 0;
int gradient = 0;
union rgb_c rgb_start, rgb_end;
double freq_h = 0.23, freq_v = 0.1;
struct timeval tv;
@ -132,8 +240,53 @@ int main(int argc, char** argv)
force_locale = 0;
} else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--random")) {
random = 1;
} else if (!strcmp(argv[i], "-S") || !strcmp(argv[i], "--seed")) {
random = 1;
if ((++i) < argc) {
seed = strtoul(argv[i], &endptr, 10);
if (*endptr)
usage();
} else {
usage();
}
} else if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--color_offset")) {
if ((++i) < argc) {
start_color = strtod(argv[i], &endptr);
if (*endptr)
usage();
} else {
usage();
}
} else if (!strcmp(argv[i], "-b") || !strcmp(argv[i], "--24bit")) {
rgb = 1;
} else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--16color")) {
ansi16 = 1;
} else if (!strcmp(argv[i], "-i") || !strcmp(argv[i], "--invert")) {
invert = 1;
} else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--gradient")) {
if ((++i) >= argc) {
usage();
}
if (strlen(argv[i]) != 6+1+6 || argv[i][6] != ':') {
wprintf(L"Invalid format for --gradient\n");
usage();
}
argv[i][6] = '\0';
rgb_start.i = strtoul(argv[i], &endptr, 16);
if (*endptr) {
wprintf(L"Invalid format for --gradient\n");
usage();
}
rgb_end.i = strtoul(argv[i]+6+1, &endptr, 16);
if (*endptr) {
wprintf(L"Invalid format for --gradient\n");
usage();
}
gradient = 1;
} else if (!strcmp(argv[i], "--version")) {
version();
} else {
@ -143,11 +296,44 @@ int main(int argc, char** argv)
}
}
if (rgb && ansi16) {
wprintf(L"Only one of --24bit and --16color can be given at a time\n");
usage();
}
if (gradient) {
if (ansi16) {
wprintf(L"--gradient and --16color are mutually exclusive\n");
usage();
}
if (!rgb) {
double correction_factor =(2*ARRAY_SIZE(codes_gradient)) / (double)ARRAY_SIZE(codes);
freq_h *= correction_factor;
freq_v *= correction_factor;
for (size_t i=0; i<ARRAY_SIZE(codes_gradient); i++) {
double f = i / (double)(ARRAY_SIZE(codes_gradient) - 1);
union rgb_c rgb_intermediate;
rgb_interpolate(&rgb_start, &rgb_end, &rgb_intermediate, f);
codes_gradient[i] = xterm256lookup(&rgb_intermediate);
}
}
}
if (invert) {
if (ansi16) {
wprintf(L"\033[30m\n");
} else {
wprintf(L"\033[38;5;16m\n");
}
}
int rand_offset = 0;
if (random) {
srand(time(NULL));
srand(seed);
rand_offset = rand();
}
char** inputs = argv + i;
char** inputs_end = argv + argc;
if (inputs == inputs_end) {
@ -168,7 +354,7 @@ int main(int argc, char** argv)
for (char** filename = inputs; filename < inputs_end; filename++) {
wint_t (*this_file_read_wchar)(FILE*); /* Used for --help because fmemopen is universally broken when used with fgetwc */
FILE* f;
int escape_state = 0;
int escape_state = ST_NONE;
if (!strcmp(*filename, "--help")) {
this_file_read_wchar = &helpstr_hack;
@ -189,41 +375,87 @@ int main(int argc, char** argv)
while ((c = this_file_read_wchar(f)) != WEOF) {
if (colors) {
find_escape_sequences(c, &escape_state);
if (!escape_state) {
escape_state = find_escape_sequences(c, escape_state);
#ifdef ESC_DEBUG
fprintf(stderr, "%02x %c %s\n", c, c > 32 ? c : '.', esc_st_names[escape_state]);
#endif
if (escape_state == ST_ESC_CSI_TERM) {
putwchar(c);
}
if (escape_state == ST_NONE || escape_state == ST_ESC_CSI_TERM) {
if (c == '\n') {
l++;
i = 0;
cc = -1;
if (invert) {
wprintf(L"\033[49m");
} else {
wprintf(L"\033[0m");
}
} else {
if (rgb) {
if (escape_state == ST_NONE) {
i += wcwidth(c);
float theta = i * freq_h / 5.0f + l * freq_v + (offx + 2.0f * rand_offset / RAND_MAX) * M_PI;
float offset = 0.1;
}
uint8_t red = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 0 ))) * 255.0f);
uint8_t green = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 2 * M_PI / 3 ))) * 255.0f);
uint8_t blue = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 4 * M_PI / 3 ))) * 255.0f);
wprintf(L"\033[38;2;%d;%d;%dm", red, green, blue);
if (rgb) {
float theta = i * freq_h / 5.0f + l * freq_v + (offx + 2.0f * (rand_offset + start_color) / RAND_MAX)*M_PI;
union rgb_c c;
if (gradient) {
theta = fmodf(theta/2.0/M_PI, 2.0f);
if (theta > 1.0f) {
theta = 2.0f - theta;
}
rgb_interpolate(&rgb_start, &rgb_end, &c, theta);
} else {
float offset = 0.1;
c.r = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 0 ))) * 255.0f);
c.g = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 2 * M_PI / 3 ))) * 255.0f);
c.b = lrintf((offset + (1.0f - offset) * (0.5f + 0.5f * sin(theta + 4 * M_PI / 3 ))) * 255.0f);
}
wprintf(L"\033[%d;2;%d;%d;%dm", (invert ? 48 : 38), c.r, c.g, c.b);
} else if (ansi16) {
int ncc = offx * ARRAY_SIZE(codes16) + (int)(i * freq_h + l * freq_v);
if (cc != ncc || escape_state == ST_ESC_CSI_TERM) {
wprintf(L"\033[%hhum", (invert ? 10 : 0) + codes16[(rand_offset + start_color + (cc = ncc)) % ARRAY_SIZE(codes16)]);
}
} else {
int ncc = offx * ARRAY_SIZE(codes) + (int)((i += wcwidth(c)) * freq_h + l * freq_v);
if (cc != ncc)
wprintf(L"\033[38;5;%hhum", codes[(rand_offset + (cc = ncc)) % ARRAY_SIZE(codes)]);
if (gradient) {
int ncc = offx * ARRAY_SIZE(codes_gradient) + (int)(i * freq_h + l * freq_v);
if (cc != ncc || escape_state == ST_ESC_CSI_TERM) {
size_t lookup = (rand_offset + start_color + (cc = ncc)) % (2*ARRAY_SIZE(codes_gradient));
if (lookup >= ARRAY_SIZE(codes_gradient)) {
lookup = 2*ARRAY_SIZE(codes_gradient) - 1 - lookup;
}
wprintf(L"\033[%d;5;%hhum", (invert ? 48 : 38), codes_gradient[lookup]);
}
} else {
int ncc = offx * ARRAY_SIZE(codes) + (int)(i * freq_h + l * freq_v);
if (cc != ncc || escape_state == ST_ESC_CSI_TERM) {
wprintf(L"\033[%d;5;%hhum", (invert ? 48 : 38), codes[(rand_offset + start_color + (cc = ncc)) % ARRAY_SIZE(codes)]);
}
}
}
}
}
}
putwchar(c);
if (escape_state == 2) /* implies "colors" */
wprintf(L"\033[38;5;%hhum", codes[(rand_offset + cc) % ARRAY_SIZE(codes)]);
if (escape_state != ST_ESC_CSI_TERM) {
putwchar(c);
}
}
if (colors)
if (colors) {
wprintf(L"\033[0m");
}
cc = -1;

243
xterm256lut.h Normal file
View file

@ -0,0 +1,243 @@
/* GENERATED HEADER FILE DO NOT EDIT */
union rgb_c xterm256lut[256-16] = {
{{0x00, 0x00, 0x00}},
{{0x5f, 0x00, 0x00}},
{{0x87, 0x00, 0x00}},
{{0xaf, 0x00, 0x00}},
{{0xd7, 0x00, 0x00}},
{{0xff, 0x00, 0x00}},
{{0x00, 0x5f, 0x00}},
{{0x5f, 0x5f, 0x00}},
{{0x87, 0x5f, 0x00}},
{{0xaf, 0x5f, 0x00}},
{{0xd7, 0x5f, 0x00}},
{{0xff, 0x5f, 0x00}},
{{0x00, 0x87, 0x00}},
{{0x5f, 0x87, 0x00}},
{{0x87, 0x87, 0x00}},
{{0xaf, 0x87, 0x00}},
{{0xd7, 0x87, 0x00}},
{{0xff, 0x87, 0x00}},
{{0x00, 0xaf, 0x00}},
{{0x5f, 0xaf, 0x00}},
{{0x87, 0xaf, 0x00}},
{{0xaf, 0xaf, 0x00}},
{{0xd7, 0xaf, 0x00}},
{{0xff, 0xaf, 0x00}},
{{0x00, 0xd7, 0x00}},
{{0x5f, 0xd7, 0x00}},
{{0x87, 0xd7, 0x00}},
{{0xaf, 0xd7, 0x00}},
{{0xd7, 0xd7, 0x00}},
{{0xff, 0xd7, 0x00}},
{{0x00, 0xff, 0x00}},
{{0x5f, 0xff, 0x00}},
{{0x87, 0xff, 0x00}},
{{0xaf, 0xff, 0x00}},
{{0xd7, 0xff, 0x00}},
{{0xff, 0xff, 0x00}},
{{0x00, 0x00, 0x5f}},
{{0x5f, 0x00, 0x5f}},
{{0x87, 0x00, 0x5f}},
{{0xaf, 0x00, 0x5f}},
{{0xd7, 0x00, 0x5f}},
{{0xff, 0x00, 0x5f}},
{{0x00, 0x5f, 0x5f}},
{{0x5f, 0x5f, 0x5f}},
{{0x87, 0x5f, 0x5f}},
{{0xaf, 0x5f, 0x5f}},
{{0xd7, 0x5f, 0x5f}},
{{0xff, 0x5f, 0x5f}},
{{0x00, 0x87, 0x5f}},
{{0x5f, 0x87, 0x5f}},
{{0x87, 0x87, 0x5f}},
{{0xaf, 0x87, 0x5f}},
{{0xd7, 0x87, 0x5f}},
{{0xff, 0x87, 0x5f}},
{{0x00, 0xaf, 0x5f}},
{{0x5f, 0xaf, 0x5f}},
{{0x87, 0xaf, 0x5f}},
{{0xaf, 0xaf, 0x5f}},
{{0xd7, 0xaf, 0x5f}},
{{0xff, 0xaf, 0x5f}},
{{0x00, 0xd7, 0x5f}},
{{0x5f, 0xd7, 0x5f}},
{{0x87, 0xd7, 0x5f}},
{{0xaf, 0xd7, 0x5f}},
{{0xd7, 0xd7, 0x5f}},
{{0xff, 0xd7, 0x5f}},
{{0x00, 0xff, 0x5f}},
{{0x5f, 0xff, 0x5f}},
{{0x87, 0xff, 0x5f}},
{{0xaf, 0xff, 0x5f}},
{{0xd7, 0xff, 0x5f}},
{{0xff, 0xff, 0x5f}},
{{0x00, 0x00, 0x87}},
{{0x5f, 0x00, 0x87}},
{{0x87, 0x00, 0x87}},
{{0xaf, 0x00, 0x87}},
{{0xd7, 0x00, 0x87}},
{{0xff, 0x00, 0x87}},
{{0x00, 0x5f, 0x87}},
{{0x5f, 0x5f, 0x87}},
{{0x87, 0x5f, 0x87}},
{{0xaf, 0x5f, 0x87}},
{{0xd7, 0x5f, 0x87}},
{{0xff, 0x5f, 0x87}},
{{0x00, 0x87, 0x87}},
{{0x5f, 0x87, 0x87}},
{{0x87, 0x87, 0x87}},
{{0xaf, 0x87, 0x87}},
{{0xd7, 0x87, 0x87}},
{{0xff, 0x87, 0x87}},
{{0x00, 0xaf, 0x87}},
{{0x5f, 0xaf, 0x87}},
{{0x87, 0xaf, 0x87}},
{{0xaf, 0xaf, 0x87}},
{{0xd7, 0xaf, 0x87}},
{{0xff, 0xaf, 0x87}},
{{0x00, 0xd7, 0x87}},
{{0x5f, 0xd7, 0x87}},
{{0x87, 0xd7, 0x87}},
{{0xaf, 0xd7, 0x87}},
{{0xd7, 0xd7, 0x87}},
{{0xff, 0xd7, 0x87}},
{{0x00, 0xff, 0x87}},
{{0x5f, 0xff, 0x87}},
{{0x87, 0xff, 0x87}},
{{0xaf, 0xff, 0x87}},
{{0xd7, 0xff, 0x87}},
{{0xff, 0xff, 0x87}},
{{0x00, 0x00, 0xaf}},
{{0x5f, 0x00, 0xaf}},
{{0x87, 0x00, 0xaf}},
{{0xaf, 0x00, 0xaf}},
{{0xd7, 0x00, 0xaf}},
{{0xff, 0x00, 0xaf}},
{{0x00, 0x5f, 0xaf}},
{{0x5f, 0x5f, 0xaf}},
{{0x87, 0x5f, 0xaf}},
{{0xaf, 0x5f, 0xaf}},
{{0xd7, 0x5f, 0xaf}},
{{0xff, 0x5f, 0xaf}},
{{0x00, 0x87, 0xaf}},
{{0x5f, 0x87, 0xaf}},
{{0x87, 0x87, 0xaf}},
{{0xaf, 0x87, 0xaf}},
{{0xd7, 0x87, 0xaf}},
{{0xff, 0x87, 0xaf}},
{{0x00, 0xaf, 0xaf}},
{{0x5f, 0xaf, 0xaf}},
{{0x87, 0xaf, 0xaf}},
{{0xaf, 0xaf, 0xaf}},
{{0xd7, 0xaf, 0xaf}},
{{0xff, 0xaf, 0xaf}},
{{0x00, 0xd7, 0xaf}},
{{0x5f, 0xd7, 0xaf}},
{{0x87, 0xd7, 0xaf}},
{{0xaf, 0xd7, 0xaf}},
{{0xd7, 0xd7, 0xaf}},
{{0xff, 0xd7, 0xaf}},
{{0x00, 0xff, 0xaf}},
{{0x5f, 0xff, 0xaf}},
{{0x87, 0xff, 0xaf}},
{{0xaf, 0xff, 0xaf}},
{{0xd7, 0xff, 0xaf}},
{{0xff, 0xff, 0xaf}},
{{0x00, 0x00, 0xd7}},
{{0x5f, 0x00, 0xd7}},
{{0x87, 0x00, 0xd7}},
{{0xaf, 0x00, 0xd7}},
{{0xd7, 0x00, 0xd7}},
{{0xff, 0x00, 0xd7}},
{{0x00, 0x5f, 0xd7}},
{{0x5f, 0x5f, 0xd7}},
{{0x87, 0x5f, 0xd7}},
{{0xaf, 0x5f, 0xd7}},
{{0xd7, 0x5f, 0xd7}},
{{0xff, 0x5f, 0xd7}},
{{0x00, 0x87, 0xd7}},
{{0x5f, 0x87, 0xd7}},
{{0x87, 0x87, 0xd7}},
{{0xaf, 0x87, 0xd7}},
{{0xd7, 0x87, 0xd7}},
{{0xff, 0x87, 0xd7}},
{{0x00, 0xaf, 0xd7}},
{{0x5f, 0xaf, 0xd7}},
{{0x87, 0xaf, 0xd7}},
{{0xaf, 0xaf, 0xd7}},
{{0xd7, 0xaf, 0xd7}},
{{0xff, 0xaf, 0xd7}},
{{0x00, 0xd7, 0xd7}},
{{0x5f, 0xd7, 0xd7}},
{{0x87, 0xd7, 0xd7}},
{{0xaf, 0xd7, 0xd7}},
{{0xd7, 0xd7, 0xd7}},
{{0xff, 0xd7, 0xd7}},
{{0x00, 0xff, 0xd7}},
{{0x5f, 0xff, 0xd7}},
{{0x87, 0xff, 0xd7}},
{{0xaf, 0xff, 0xd7}},
{{0xd7, 0xff, 0xd7}},
{{0xff, 0xff, 0xd7}},
{{0x00, 0x00, 0xff}},
{{0x5f, 0x00, 0xff}},
{{0x87, 0x00, 0xff}},
{{0xaf, 0x00, 0xff}},
{{0xd7, 0x00, 0xff}},
{{0xff, 0x00, 0xff}},
{{0x00, 0x5f, 0xff}},
{{0x5f, 0x5f, 0xff}},
{{0x87, 0x5f, 0xff}},
{{0xaf, 0x5f, 0xff}},
{{0xd7, 0x5f, 0xff}},
{{0xff, 0x5f, 0xff}},
{{0x00, 0x87, 0xff}},
{{0x5f, 0x87, 0xff}},
{{0x87, 0x87, 0xff}},
{{0xaf, 0x87, 0xff}},
{{0xd7, 0x87, 0xff}},
{{0xff, 0x87, 0xff}},
{{0x00, 0xaf, 0xff}},
{{0x5f, 0xaf, 0xff}},
{{0x87, 0xaf, 0xff}},
{{0xaf, 0xaf, 0xff}},
{{0xd7, 0xaf, 0xff}},
{{0xff, 0xaf, 0xff}},
{{0x00, 0xd7, 0xff}},
{{0x5f, 0xd7, 0xff}},
{{0x87, 0xd7, 0xff}},
{{0xaf, 0xd7, 0xff}},
{{0xd7, 0xd7, 0xff}},
{{0xff, 0xd7, 0xff}},
{{0x00, 0xff, 0xff}},
{{0x5f, 0xff, 0xff}},
{{0x87, 0xff, 0xff}},
{{0xaf, 0xff, 0xff}},
{{0xd7, 0xff, 0xff}},
{{0xff, 0xff, 0xff}},
{{0x00, 0x00, 0x00}},
{{0x12, 0x12, 0x12}},
{{0x1c, 0x1c, 0x1c}},
{{0x26, 0x26, 0x26}},
{{0x30, 0x30, 0x30}},
{{0x3a, 0x3a, 0x3a}},
{{0x44, 0x44, 0x44}},
{{0x4e, 0x4e, 0x4e}},
{{0x58, 0x58, 0x58}},
{{0x62, 0x62, 0x62}},
{{0x6c, 0x6c, 0x6c}},
{{0x76, 0x76, 0x76}},
{{0x80, 0x80, 0x80}},
{{0x8a, 0x8a, 0x8a}},
{{0x94, 0x94, 0x94}},
{{0x9e, 0x9e, 0x9e}},
{{0xa8, 0xa8, 0xa8}},
{{0xb2, 0xb2, 0xb2}},
{{0xbc, 0xbc, 0xbc}},
{{0xc6, 0xc6, 0xc6}},
{{0xd0, 0xd0, 0xd0}},
{{0xda, 0xda, 0xda}},
{{0xe4, 0xe4, 0xe4}},
{{0xee, 0xee, 0xee}},
};

24
xterm256lut_gen.py Normal file
View file

@ -0,0 +1,24 @@
xterm_colors = []
# This is ripped out of pygments
# I leave out the 16 standard colors since people tend to re-define them to their liking.
# colors 16..232: the 6x6x6 color cube
_valuerange = (0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff)
for i in range(217):
r = _valuerange[(i // 36) % 6]
g = _valuerange[(i // 6) % 6]
b = _valuerange[i % 6]
xterm_colors.append((r, g, b))
# colors 233..253: grayscale
for i in range(1, 24):
v = 8 + i * 10
xterm_colors.append((v, v, v))
print('/* GENERATED HEADER FILE DO NOT EDIT */')
print('union rgb_c xterm256lut[256-16] = {')
for r,g,b in xterm_colors:
print(f' {{{{0x{b:02x}, 0x{g:02x}, 0x{r:02x}}}}},');
print('};');