2013-03-19 05:20:40 +01:00
|
|
|
#!/usr/bin/env python
|
2013-03-15 05:23:22 +01:00
|
|
|
import sys
|
|
|
|
import json
|
|
|
|
from powerline.colorscheme import cterm_to_hex
|
|
|
|
from itertools import groupby
|
|
|
|
|
2013-03-19 05:20:04 +01:00
|
|
|
try:
|
|
|
|
from __builtin__ import unicode
|
|
|
|
except ImportError:
|
|
|
|
unicode = str
|
|
|
|
|
2013-03-15 05:23:22 +01:00
|
|
|
|
2013-03-23 21:55:54 +01:00
|
|
|
if len(sys.argv) == 1 or sys.argv[1] == '--help':
|
2013-03-15 05:23:22 +01:00
|
|
|
sys.stderr.write('''
|
2013-03-19 05:17:11 +01:00
|
|
|
Usage: generate_gradients.py colors itemnum[ "show" [ min max num]]
|
2013-03-15 05:23:22 +01:00
|
|
|
|
|
|
|
colors: JSON list with either cterm ([200, 42, 6]) or RGB (["abcdef",
|
|
|
|
"feffef"]) colors.
|
|
|
|
|
|
|
|
itemnum: number of items in generated gradient.
|
|
|
|
|
|
|
|
"show": static string, determines whether gradient sample should be
|
|
|
|
printed to stdout as well.
|
2013-03-19 05:17:11 +01:00
|
|
|
|
|
|
|
min, max: floating point values.
|
|
|
|
num: integer
|
|
|
|
|
|
|
|
all of the above are used to generate sample gradient for given
|
|
|
|
range (just like the above gradients shown with "show", but with
|
|
|
|
different scale (controlled by min and max) and, possibly,
|
|
|
|
different length (controlled by num)).
|
2013-03-15 05:23:22 +01:00
|
|
|
''')
|
2013-03-23 21:55:54 +01:00
|
|
|
sys.exit(1)
|
2013-03-15 05:23:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
def linear_gradient(start_value, stop_value, start_offset, stop_offset, offset):
|
|
|
|
return start_value + ((offset - start_offset) * (stop_value - start_value) / (stop_offset - start_offset))
|
|
|
|
|
|
|
|
|
|
|
|
def gradient(DATA):
|
|
|
|
def gradient_function(y):
|
|
|
|
initial_offset = 0
|
|
|
|
for offset, start, end in DATA:
|
|
|
|
if y <= offset:
|
|
|
|
return [linear_gradient(start[i], end[i], initial_offset, offset, y) for i in range(3)]
|
|
|
|
initial_offset = offset
|
|
|
|
return gradient_function
|
|
|
|
|
|
|
|
|
|
|
|
def get_color(rgb):
|
|
|
|
if type(rgb) is unicode:
|
|
|
|
return int(rgb[:2], 16), int(rgb[2:4], 16), int(rgb[4:6], 16)
|
|
|
|
else:
|
|
|
|
return rgbint_to_rgb(cterm_to_hex[rgb])
|
|
|
|
|
|
|
|
|
|
|
|
def get_rgb(*args):
|
|
|
|
return "%02x%02x%02x" % args
|
|
|
|
|
|
|
|
|
|
|
|
def col_distance(rgb1, rgb2):
|
|
|
|
return sum(((rgb1[i] - rgb2[i]) ** 2 for i in range(3)))
|
|
|
|
|
|
|
|
|
|
|
|
def rgbint_to_rgb(rgbint):
|
|
|
|
return ((rgbint >> 16) & 0xFF, (rgbint >> 8) & 0xFF, rgbint & 0xFF)
|
|
|
|
|
|
|
|
|
|
|
|
def find_color(urgb, colors):
|
|
|
|
cur_distance = 3 * (255 ** 2 + 1)
|
|
|
|
cur_color = None
|
|
|
|
i = 0
|
|
|
|
for crgbint in colors:
|
|
|
|
crgb = rgbint_to_rgb(crgbint)
|
|
|
|
dist = col_distance(urgb, crgb)
|
|
|
|
if dist < cur_distance:
|
|
|
|
cur_distance = dist
|
|
|
|
cur_color = (i, crgb)
|
|
|
|
i += 1
|
|
|
|
return cur_color
|
|
|
|
|
|
|
|
|
|
|
|
def print_color(color):
|
|
|
|
if type(color) is int:
|
|
|
|
colstr = '5;' + str(color)
|
|
|
|
else:
|
2013-03-19 05:20:04 +01:00
|
|
|
colstr = '2;' + ';'.join((str(int(round(i))) for i in color))
|
2013-03-15 05:23:22 +01:00
|
|
|
sys.stdout.write('\033[48;' + colstr + 'm ')
|
|
|
|
|
|
|
|
|
2013-03-19 05:17:11 +01:00
|
|
|
def print_colors(colors, num=100):
|
|
|
|
for i in range(num + 1):
|
|
|
|
color = colors[int(round(i * (len(colors) - 1) / num))]
|
2013-03-15 05:23:22 +01:00
|
|
|
print_color(color)
|
|
|
|
sys.stdout.write('\033[0m\n')
|
|
|
|
|
|
|
|
|
|
|
|
c = [get_color(color) for color in json.loads(sys.argv[1])]
|
|
|
|
m = int(sys.argv[2]) if len(sys.argv) > 2 else 100
|
|
|
|
m += m % (len(c) - 1)
|
|
|
|
step = m / (len(c) - 1)
|
|
|
|
data = [(i * step, c[i - 1], c[i]) for i in range(1, len(c))]
|
|
|
|
gr_func = gradient(data)
|
|
|
|
gradient = [gr_func(y) for y in range(0, m - 1)]
|
|
|
|
r = [get_rgb(*color) for color in gradient]
|
|
|
|
r2 = [find_color(color, cterm_to_hex)[0] for color in gradient]
|
|
|
|
r3 = [i[0] for i in groupby(r2)]
|
2013-03-19 05:17:11 +01:00
|
|
|
print(json.dumps(r))
|
|
|
|
print(json.dumps(r2))
|
|
|
|
print(json.dumps(r3))
|
2013-03-15 05:23:22 +01:00
|
|
|
if len(sys.argv) > 3 and sys.argv[3] == 'show':
|
|
|
|
print_colors(gradient)
|
|
|
|
print_colors(r2)
|
|
|
|
print_colors(r3)
|
|
|
|
sys.stdout.write('0')
|
|
|
|
sys.stdout.write(''.join(('%10u' % (i * 10) for i in range(1, 11))))
|
|
|
|
sys.stdout.write('\n')
|
|
|
|
nums = (''.join((str(i) for i in range(10))))
|
|
|
|
sys.stdout.write(''.join(((('\033[1m' if j % 2 else '\033[0m') + nums) for j in range(10))))
|
|
|
|
sys.stdout.write('\033[0m0\n')
|
2013-03-19 05:17:11 +01:00
|
|
|
if len(sys.argv) > 6:
|
|
|
|
vmin = float(sys.argv[4])
|
|
|
|
vmax = float(sys.argv[5])
|
|
|
|
num = int(sys.argv[6])
|
|
|
|
print_colors(gradient, num)
|
|
|
|
s = ''
|
|
|
|
while len(s) < num:
|
|
|
|
curpc = len(s) + 1 if s else 0
|
|
|
|
curval = vmin + curpc * (vmax - vmin) / 100.0
|
|
|
|
s += str(curval) + ' '
|
|
|
|
print(s)
|