···
1
1
-
#!/bin/sh -f
2
2
-
#
3
3
-
# pywalesque posix sh alternative.
4
4
-
5
5
-
img() {
6
6
-
[ -d "$1" ] && {
7
7
-
set +f
8
8
-
set -f -- "$1/"*
9
9
-
int="$(shuf -i "1-$#" -n 1)"
10
10
-
shift $(expr $int - 1)
11
11
-
}
12
12
-
13
13
-
[ -f "${img:=$1}" ] || exit 1
14
14
-
15
15
-
printf '%s\n' "$img"
16
16
-
}
17
17
-
18
18
-
hex2rgb() {
19
19
-
set -- "${1##\#}"
20
20
-
21
21
-
r=${1%%????}
22
22
-
g=${1##??}
23
23
-
g=${g%%??}
24
24
-
b=${1##????}
25
25
-
26
26
-
r=$((0x$r))
27
27
-
g=$((0x$g))
28
28
-
b=$((0x$b))
29
29
-
}
30
30
-
31
31
-
mod() {
32
32
-
hex2rgb "$2"
33
33
-
34
34
-
# The operator is stored in a variable
35
35
-
# which makes shellcheck freak out.
36
36
-
# shellcheck disable=1102,2086
37
37
-
{
38
38
-
r=$((r $3 $4))
39
39
-
g=$((g $3 $4))
40
40
-
b=$((b $3 $4))
41
41
-
}
42
42
-
43
43
-
r=$((r > 255 ? 255 : r < 0 ? 0 : r))
44
44
-
g=$((g > 255 ? 255 : g < 0 ? 0 : g))
45
45
-
b=$((b > 255 ? 255 : b < 0 ? 0 : b))
46
46
-
47
47
-
export "$1=$(printf '%02x%02x%02x' "$r" "$g" "$b")"
48
48
-
}
49
49
-
50
50
-
col() {
51
51
-
cache_file=$(printf %s "$img" | base64)
52
52
-
53
53
-
# Backticks need to be used here to fix bugs in
54
54
-
# some specific POSIX shells.
55
55
-
#
56
56
-
# Word splitting is also intentional and safe here.
57
57
-
# shellcheck disable=2046,2006
58
58
-
if [ -f "$cache_dir/$cache_file" ]; then
59
59
-
paleta < "$cache_dir/$cache_file" &
60
60
-
61
61
-
else
62
62
-
set -- `\
63
63
-
convert "$img" \
64
64
-
-alpha off \
65
65
-
-resize 64x64 \
66
66
-
-posterize 16 \
67
67
-
-fill white \
68
68
-
-colorize 30% \
69
69
-
-modulate 125,175,100 \
70
70
-
-unique-colors \
71
71
-
txt:- |
72
72
-
while IFS='# ' read -r _ _ col _; do
73
73
-
i=$((i+1))
74
74
-
[ "$i" -lt 11 ] && continue
75
75
-
[ "$i" -gt 16 ] && continue
76
76
-
printf '%s\n' "$col"
77
77
-
done
78
78
-
`
79
79
-
80
80
-
# These variables are dynamically defined,
81
81
-
# ignore undeclared variable warnings.
82
82
-
# shellcheck disable=2154
83
83
-
{
84
84
-
mod bg "$2" / 4
85
85
-
mod fg "$2" + 150
86
86
-
mod co "$bg" + 125
87
87
-
88
88
-
set -- "$bg" "$@" "$fg" "$co" "$@" "$fg"
89
89
-
}
90
90
-
91
91
-
printf '%s\n' "$@" | paleta &
92
92
-
printf '%s\n' "$@" > "$cache_dir/$cache_file"
93
93
-
fi
94
94
-
}
95
95
-
96
96
-
main() {
97
97
-
mkdir -p "${cache_dir:=${XDG_CACHE_HOME:=${HOME}/.cache}/bud}"
98
98
-
99
99
-
img "$1"
100
100
-
101
101
-
display \
102
102
-
-page 3200x \
103
103
-
-sample 3200x \
104
104
-
-window root \
105
105
-
"$img" &
106
106
-
107
107
-
col &
108
108
-
}
109
109
-
110
110
-
main "$1"
···
1
1
-
#!/usr/bin/env bash
2
2
-
#
3
3
-
# paleta - change terminal colors on the fly.
4
4
-
5
5
-
read_input() {
6
6
-
[[ $1 == -v ]] && {
7
7
-
printf 'paleta 1.0.0\n'
8
8
-
exit
9
9
-
}
10
10
-
11
11
-
[[ $1 == -r ]] && {
12
12
-
load_sequences
13
13
-
exit
14
14
-
}
15
15
-
16
16
-
# Input from space separated arguments.
17
17
-
[[ $1 ]] && {
18
18
-
input=("$@")
19
19
-
20
20
-
# Input from single string.
21
21
-
((${#input[@]} == 1 && ${#input[0]} > 7)) &&
22
22
-
read -ra input <<< "${input[*]}"
23
23
-
24
24
-
# Input from file argument.
25
25
-
(($# == 1)) && [[ -f $1 ]] &&
26
26
-
IFS=$'\n ' read -d "" -ra input < "$1"
27
27
-
}
28
28
-
29
29
-
# Input from stdin.
30
30
-
[[ $1 ]] || IFS=$'\n ' read -d "" -ra input </dev/stdin
31
31
-
32
32
-
[[ $* == *-* || -z $1 && -z ${input[0]} ]] && {
33
33
-
printf 'usage: paleta -r, paleta [colors], paleta file\n'
34
34
-
printf ' - [colors] a space separated list of hex colors.\n'
35
35
-
exit 1
36
36
-
}
37
37
-
}
38
38
-
39
39
-
parse_colors() {
40
40
-
((${#input[@]} > 16)) &&
41
41
-
printf 'warn: Too many colors specified, ignoring past 16th.\n' >&2
42
42
-
43
43
-
((${#input[@]} < 16)) &&
44
44
-
printf 'warn: Too few colors given, repeating last color.\n' >&2
45
45
-
46
46
-
for ((i=0; i<16; i++)); {
47
47
-
[[ ${input[i]:-000000} =~ ^#?[a-fA-F0-9]{6}$ ]] || {
48
48
-
printf '%s\n' "error: Color [$((i+1))] isn't a valid hex color." >&2
49
49
-
exit 1
50
50
-
}
51
51
-
52
52
-
# Use the last defined color for all colors if less than
53
53
-
# 16 colors were given as input.
54
54
-
colors[i]=${input[i]:-${input[-1]}}
55
55
-
colors[i]=\#${colors[i]//\#}
56
56
-
}
57
57
-
}
58
58
-
59
59
-
make_sequences() {
60
60
-
# Colors 0-15.
61
61
-
for ((i=0;i<${#colors[@]};i++)) {
62
62
-
sequences+="]4;${i};${colors[i]}\\"
63
63
-
}
64
64
-
65
65
-
# 10: Foreground color,
66
66
-
# 11: Background color,
67
67
-
# 12: Cursor Foreground color.
68
68
-
# Source: https://goo.gl/KcoQgP
69
69
-
sequences+="]10;${colors[15]}\\"
70
70
-
sequences+="]11;${colors[0]}\\"
71
71
-
sequences+="]12;${colors[15]}\\"
72
72
-
73
73
-
# Border Background color (URxvt).
74
74
-
# (VTE doesn't handle unknown sequences very well.
75
75
-
# Skip this sequence if running in VTE.)
76
76
-
[[ $VTE_VERSION ]] || sequences+="]708;${colors[0]}\\"
77
77
-
}
78
78
-
79
79
-
send_sequences() {
80
80
-
for tty in /dev/pts/[0-9]*; do
81
81
-
[[ -w $tty ]] && printf %b "$sequences" > "$tty" &
82
82
-
done
83
83
-
84
84
-
printf %b "$sequences" > "$cache_dir/colors"
85
85
-
}
86
86
-
87
87
-
load_sequences() {
88
88
-
[[ -f $cache_dir/colors ]] &&
89
89
-
printf %b "$(< "${cache_dir}/colors")"
90
90
-
}
91
91
-
92
92
-
main() {
93
93
-
mkdir -p "${cache_dir:=${XDG_CACHE_HOME:=${HOME}/.cache}/paleta}"
94
94
-
95
95
-
read_input "$@"
96
96
-
parse_colors
97
97
-
make_sequences
98
98
-
send_sequences &
99
99
-
}
100
100
-
101
101
-
main "$@"