Merge pull request #474 from AmitPr/master

Add ability to run functions on colors from templates
This commit is contained in:
dylan 2020-01-23 10:33:47 +02:00 committed by GitHub
commit ca389ce114
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 8 deletions

View File

@ -11,7 +11,7 @@
<img src="https://i.imgur.com/HhK3LDv.jpg" alt="img" align="right" width="400px"> <img src="https://i.imgur.com/HhK3LDv.jpg" alt="img" align="right" width="400px">
Pywal is a tool that generates a color palette from the dominant colors in an image. It then applies the colors system-wide and on-the-fly in all of your favourite programs. Pywal is a tool that generates a color palette from the dominant colors in an image. It then applies the colors system-wide and on-the-fly in all of your favourite programs.
There are currently 5 supported color generation backends, each providing a different palette of colors from each image. You're bound to find an appealing color-scheme. There are currently 5 supported color generation backends, each providing a different palette of colors from each image. You're bound to find an appealing color-scheme.
@ -21,4 +21,4 @@ The goal of Pywal was to be as out of the way as possible. It doesn't modify any
Terminal emulators and TTYs have their color-schemes updated in real-time with no delay. With minimal configuration this functionality can be extended to almost anything running on your system. Terminal emulators and TTYs have their color-schemes updated in real-time with no delay. With minimal configuration this functionality can be extended to almost anything running on your system.
### More: \[[Installation](https://github.com/dylanaraps/pywal/wiki/Installation)\] \[[Getting Started](https://github.com/dylanaraps/pywal/wiki/Getting-Started)\] \[[Customization](https://github.com/dylanaraps/pywal/wiki/Customization)\] \[[Wiki](https://github.com/dylanaraps/pywal/wiki)\] \[[Screenshots](https://www.reddit.com/r/unixporn/search?q=wal&restrict_sr=on&sort=relevance&t=all)\] ### More: \[[Installation](https://github.com/dylanaraps/pywal/wiki/Installation)] \[[Getting Started](https://github.com/dylanaraps/pywal/wiki/Getting-Started)] \[[Customization](https://github.com/dylanaraps/pywal/wiki/Customization)] \[[Wiki](https://github.com/dylanaraps/pywal/wiki)] \[[Screenshots](https://www.reddit.com/r/unixporn/search?q=wal&restrict_sr=on&sort=relevance&t=all)]

View File

@ -3,22 +3,60 @@ Export colors in various formats.
""" """
import logging import logging
import os import os
import re
from .settings import CACHE_DIR, MODULE_DIR, CONF_DIR
from . import util from . import util
from .settings import CACHE_DIR, CONF_DIR, MODULE_DIR
def template(colors, input_file, output_file=None): def template(colors, input_file, output_file=None):
"""Read template file, substitute markers and """Read template file, substitute markers and
save the file elsewhere.""" save the file elsewhere."""
template_data = util.read_file_raw(input_file) template_data = util.read_file_raw(input_file)
for i, l in enumerate(template_data):
for match in re.finditer(r"(?<=(?<!\{))(\{([^{}]+)\})(?=(?!\}))", l):
# Get the color, and the functions associated with it
cname, _, funcs = match.group(2).partition(".")
# Check that functions are needed for this color
if len(funcs) == 0:
continue
# Build up a string which will be replaced with the new color
replace_str = cname
# Color to be modified copied into new one
new_color = util.Color(colors[cname].hex_color)
# Execute each function to be done
for func in filter(None, funcs.split(")")):
# Get function name and arguments
func = func.split("(")
fname = func[0]
if fname[0] == '.':
fname = fname[1:]
if not hasattr(new_color, fname):
logging.error(
"Syntax error in template file '%s' on line '%s'",
input_file, i)
function = getattr(new_color, fname)
# If the function is callable, call it
if callable(function):
if len(func) > 1:
new_color = function(*func[1].split(","))
else:
new_color = function()
# string to replace generated colors
if func[0] != '.':
replace_str += "."
replace_str += "(".join(func) + ")"
# If the color was changed, replace with a unique identifier.
if new_color is not colors[cname]:
template_data[i] = l.replace(
replace_str, "color" + new_color.strip)
colors["color" + new_color.strip] = new_color
try: try:
template_data = "".join(template_data).format(**colors) template_data = "".join(template_data).format(**colors)
except ValueError: except ValueError:
logging.error("Syntax error in template file '%s'.", input_file) logging.error("Syntax error in template file '%s'.", input_file)
return return
util.save_file(template_data, output_file) util.save_file(template_data, output_file)

View File

@ -5,10 +5,11 @@ import colorsys
import json import json
import logging import logging
import os import os
import platform
import re
import shutil import shutil
import subprocess import subprocess
import sys import sys
import platform
class Color: class Color:
@ -35,7 +36,7 @@ class Color:
def rgba(self): def rgba(self):
"""Convert a hex color to rgba.""" """Convert a hex color to rgba."""
return "rgba(%s,%s,%s,%s)" % (*hex_to_rgb(self.hex_color), return "rgba(%s,%s,%s,%s)" % (*hex_to_rgb(self.hex_color),
int(self.alpha_num)/100) int(self.alpha_num) / 100)
@property @property
def alpha(self): def alpha(self):
@ -57,6 +58,21 @@ class Color:
"""Strip '#' from color.""" """Strip '#' from color."""
return self.hex_color[1:] return self.hex_color[1:]
def lighten(self, percent):
"""Lighten color by percent"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(lighten_color(self.hex_color, percent / 100))
def darken(self, percent):
"""Darken color by percent"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(darken_color(self.hex_color, percent / 100))
def saturate(self, percent):
"""Saturate a color"""
percent = float(re.sub(r'[\D\.]', '', str(percent)))
return Color(saturate_color(self.hex_color, percent / 100))
def read_file(input_file): def read_file(input_file):
"""Read data from a file and trim newlines.""" """Read data from a file and trim newlines."""
@ -156,11 +172,11 @@ def blend_color(color, color2):
def saturate_color(color, amount): def saturate_color(color, amount):
"""Saturate a hex color.""" """Saturate a hex color."""
r, g, b = hex_to_rgb(color) r, g, b = hex_to_rgb(color)
r, g, b = [x/255.0 for x in (r, g, b)] r, g, b = [x / 255.0 for x in (r, g, b)]
h, l, s = colorsys.rgb_to_hls(r, g, b) h, l, s = colorsys.rgb_to_hls(r, g, b)
s = amount s = amount
r, g, b = colorsys.hls_to_rgb(h, l, s) r, g, b = colorsys.hls_to_rgb(h, l, s)
r, g, b = [x*255.0 for x in (r, g, b)] r, g, b = [x * 255.0 for x in (r, g, b)]
return rgb_to_hex((int(r), int(g), int(b))) return rgb_to_hex((int(r), int(g), int(b)))