mirror of
https://github.com/powerline/powerline.git
synced 2025-04-08 19:25:04 +02:00
Now imports follow the following structure: 1. __future__ line: exactly one line allowed: from __future__ import (unicode_literals, division, absolute_import, print_function) (powerline.shell is the only exception due to problems with argparse). 2. Standard python library imports in a form `import X`. 3. Standard python library imports in a form `from X import Y`. 4. and 5. 2. and 3. for third-party (non-python and non-powerline imports). 6. 3. for powerline non-test imports. 7. and 8. 2. and 3. for powerline testing module imports. Each list entry is separated by exactly one newline from another import. If there is module docstring it goes between `# vim:` comment and `__future__` import. So the structure containing all items is the following: #!/usr/bin/env python # vim:fileencoding=utf-8:noet '''Powerline super module''' import sys from argparse import ArgumentParser import psutil from colormath.color_diff import delta_e_cie2000 from powerline.lib.unicode import u import tests.vim as vim_module from tests import TestCase .
218 lines
5.9 KiB
Python
Executable File
218 lines
5.9 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# vim:fileencoding=utf-8:noet
|
|
|
|
'''Gradients generator
|
|
'''
|
|
|
|
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
|
|
|
import sys
|
|
import json
|
|
import argparse
|
|
|
|
from itertools import groupby
|
|
|
|
from colormath.color_objects import sRGBColor, LabColor
|
|
from colormath.color_conversions import convert_color
|
|
from colormath.color_diff import delta_e_cie2000
|
|
|
|
from powerline.colorscheme import cterm_to_hex
|
|
|
|
|
|
def num2(s):
|
|
try:
|
|
return (True, [int(v) for v in s.partition(' ')[::2]])
|
|
except TypeError:
|
|
return (False, [float(v) for v in s.partition(' ')[::2]])
|
|
|
|
|
|
def rgbint_to_lab(rgbint):
|
|
rgb = sRGBColor(
|
|
(rgbint >> 16) & 0xFF, (rgbint >> 8) & 0xFF, rgbint & 0xFF,
|
|
is_upscaled=True
|
|
)
|
|
return convert_color(rgb, LabColor)
|
|
|
|
|
|
cterm_to_lab = tuple((rgbint_to_lab(v) for v in cterm_to_hex))
|
|
|
|
|
|
def color(s):
|
|
if len(s) <= 3:
|
|
return cterm_to_lab[int(s)]
|
|
else:
|
|
return rgbint_to_lab(int(s, 16))
|
|
|
|
|
|
def nums(s):
|
|
return [int(i) for i in s.split()]
|
|
|
|
|
|
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 lab_gradient(slab, elab, soff, eoff, off):
|
|
svals = slab.get_value_tuple()
|
|
evals = elab.get_value_tuple()
|
|
return LabColor(*[
|
|
linear_gradient(start_value, end_value, soff, eoff, off)
|
|
for start_value, end_value in zip(svals, evals)
|
|
])
|
|
|
|
|
|
def generate_gradient_function(DATA):
|
|
def gradient_function(y):
|
|
initial_offset = 0
|
|
for offset, start, end in DATA:
|
|
if y <= offset:
|
|
return lab_gradient(start, end, initial_offset, offset, y)
|
|
initial_offset = offset
|
|
return gradient_function
|
|
|
|
|
|
def get_upscaled_values(rgb):
|
|
return [min(max(0, i), 255) for i in rgb.get_upscaled_value_tuple()]
|
|
|
|
|
|
def get_rgb(lab):
|
|
rgb = convert_color(lab, sRGBColor)
|
|
rgb = sRGBColor(*get_upscaled_values(rgb), is_upscaled=True)
|
|
return rgb.get_rgb_hex()[1:]
|
|
|
|
|
|
def find_color(ulab, colors, ctrans):
|
|
cur_distance = float('inf')
|
|
cur_color = None
|
|
i = 0
|
|
for clab in colors:
|
|
dist = delta_e_cie2000(ulab, clab)
|
|
if dist < cur_distance:
|
|
cur_distance = dist
|
|
cur_color = (ctrans(i), clab)
|
|
i += 1
|
|
return cur_color
|
|
|
|
|
|
def print_color(color):
|
|
if type(color) is int:
|
|
colstr = '5;' + str(color)
|
|
else:
|
|
rgb = convert_color(color, sRGBColor)
|
|
colstr = '2;' + ';'.join((str(i) for i in get_upscaled_values(rgb)))
|
|
sys.stdout.write('\033[48;' + colstr + 'm ')
|
|
|
|
|
|
def print_colors(colors, num):
|
|
for i in range(num):
|
|
color = colors[int(round(i * (len(colors) - 1) / num))]
|
|
print_color(color)
|
|
sys.stdout.write('\033[0m\n')
|
|
|
|
|
|
def dec_scale_generator(num):
|
|
j = 0
|
|
r = ''
|
|
while num:
|
|
r += '\033[{0}m'.format(j % 2)
|
|
for i in range(10):
|
|
r += str(i)
|
|
num -= 1
|
|
if not num:
|
|
break
|
|
j += 1
|
|
r += '\033[0m\n'
|
|
return r
|
|
|
|
|
|
def compute_steps(gradient, weights):
|
|
maxweight = len(gradient) - 1
|
|
if weights:
|
|
weight_sum = sum(weights)
|
|
norm_weights = [100.0 * weight / weight_sum for weight in weights]
|
|
steps = [0]
|
|
for weight in norm_weights:
|
|
steps.append(steps[-1] + weight)
|
|
steps.pop(0)
|
|
steps.pop(0)
|
|
else:
|
|
step = m / maxweight
|
|
steps = [i * step for i in range(1, maxweight + 1)]
|
|
return steps
|
|
|
|
|
|
palettes = {
|
|
'16': (cterm_to_lab[:16], lambda c: c),
|
|
'256': (cterm_to_lab, lambda c: c),
|
|
None: (cterm_to_lab[16:], lambda c: c + 16),
|
|
}
|
|
|
|
|
|
def show_scale(rng, num_output):
|
|
if not rng and num_output >= 32 and (num_output - 1) // 10 >= 4 and (num_output - 1) % 10 == 0:
|
|
sys.stdout.write('0')
|
|
sys.stdout.write(''.join(('%*u' % (num_output // 10, i) for i in range(10, 101, 10))))
|
|
sys.stdout.write('\n')
|
|
else:
|
|
if rng:
|
|
vmin, vmax = rng[1]
|
|
isint = rng[0]
|
|
else:
|
|
isint = True
|
|
vmin = 0
|
|
vmax = 100
|
|
s = ''
|
|
lasts = ' ' + str(vmax)
|
|
while len(s) + len(lasts) < num_output:
|
|
curpc = len(s) + 1 if s else 0
|
|
curval = vmin + curpc * (vmax - vmin) / num_output
|
|
if isint:
|
|
curval = int(round(curval))
|
|
s += str(curval) + ' '
|
|
sys.stdout.write(s[:-1] + lasts + '\n')
|
|
sys.stdout.write(dec_scale_generator(num_output) + '\n')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
p = argparse.ArgumentParser(description=__doc__)
|
|
p.add_argument('gradient', nargs='*', metavar='COLOR', type=color, help='List of colors (either indexes from 8-bit palette or 24-bit RGB in hexadecimal notation)')
|
|
p.add_argument('-n', '--num_items', metavar='INT', type=int, help='Number of items in resulting list', default=101)
|
|
p.add_argument('-N', '--num_output', metavar='INT', type=int, help='Number of characters in sample', default=101)
|
|
p.add_argument('-r', '--range', metavar='V1 V2', type=num2, help='Use this range when outputting scale')
|
|
p.add_argument('-s', '--show', action='store_true', help='If present output gradient sample')
|
|
p.add_argument('-p', '--palette', choices=('16', '256'), help='Use this palette. Defaults to 240-color palette (256 colors without first 16)')
|
|
p.add_argument('-w', '--weights', metavar='INT INT ...', type=nums, help='Adjust weights of colors. Number of weights must be equal to number of colors')
|
|
p.add_argument('-C', '--omit-terminal', action='store_true', help='If present do not compute values for terminal')
|
|
|
|
args = p.parse_args()
|
|
|
|
m = args.num_items
|
|
|
|
steps = compute_steps(args.gradient, args.weights)
|
|
|
|
data = [
|
|
(weight, args.gradient[i - 1], args.gradient[i])
|
|
for weight, i in zip(steps, range(1, len(args.gradient)))
|
|
]
|
|
gr_func = generate_gradient_function(data)
|
|
gradient = [gr_func(y) for y in range(0, m)]
|
|
|
|
r = [get_rgb(lab) for lab in gradient]
|
|
if not args.omit_terminal:
|
|
r2 = [find_color(lab, *palettes[args.palette])[0] for lab in gradient]
|
|
r3 = [i[0] for i in groupby(r2)]
|
|
|
|
if not args.omit_terminal:
|
|
print(json.dumps(r3) + ',')
|
|
print(json.dumps(r2) + ',')
|
|
print(json.dumps(r))
|
|
|
|
if args.show:
|
|
print_colors(args.gradient, args.num_output)
|
|
if not args.omit_terminal:
|
|
print_colors(r3, args.num_output)
|
|
print_colors(r2, args.num_output)
|
|
print_colors(gradient, args.num_output)
|
|
|
|
show_scale(args.range, args.num_output)
|