Created
June 23, 2023 19:40
-
-
Save facelessuser/0b129c1faf7f3f59c0de40eeaaab5691 to your computer and use it in GitHub Desktop.
Custom sRGB with special color names
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# pragma: init | |
"""Custom sRGB color class.""" | |
from coloraide import Color as Base | |
from coloraide.spaces.srgb.css import sRGB | |
from coloraide.css import serialize | |
from coloraide import algebra as alg | |
import re | |
RE_CUSTOM = re.compile(r'(?i)\b([a-z][a-z_]{2,})\b') | |
CUSTOM_NAME_MAP = { | |
'correct_green': (0.0, 255.0, 0.0, 255.0), | |
'incorrect_red': (250.0, 0.0, 0.0, 255.0), | |
} | |
CUSTOM_VALUE_MAP = dict([(v, k) for k, v in CUSTOM_NAME_MAP.items()]) | |
class sRGBCustom(sRGB): | |
"""Custom sRGB class.""" | |
def match( | |
self, | |
string, | |
start = 0, | |
fullmatch = True | |
): | |
"""Match a color string.""" | |
# Match the string using fullmatch if requested | |
m = RE_CUSTOM.fullmatch(string, start) if fullmatch else RE_CUSTOM.match(string, start) | |
if m: | |
# See if we can find the name | |
name = m.group(1) | |
values = CUSTOM_NAME_MAP.get(name.lower(), None) | |
if values is not None: | |
# Normalize back to 0 - 1 | |
values = [c / 255 for c in values] | |
# Return the coordinates and transparency separate, | |
# also include the match end position. | |
return (values[:-1], values[-1]), m.end(1) | |
# Couldn't find custom colors, so use the default color matching. | |
return super().match(string, start, fullmatch) | |
def to_string( | |
self, | |
parent, | |
*, | |
alpha = None, | |
precision = None, | |
fit = True, | |
none = False, | |
color = False, | |
hex = False, | |
names = False, | |
comma = False, | |
upper = False, | |
percent = False, | |
compress = False, | |
**kwargs | |
) -> str: | |
"""Convert to string.""" | |
if names: | |
# Get alpha and coordinates resolving undefined values as required | |
a = serialize.get_alpha(parent, alpha, False, False) | |
if a is None: | |
a = 1 | |
coords = serialize.get_coords(parent, fit, False, False) + [a] | |
# See if the color value is a match, if so, return the string | |
result = CUSTOM_VALUE_MAP.get(tuple([alg.round_half_up(c * 255) for c in coords]), None) | |
if result is not None: | |
return result | |
# Color name not requested, or there was no color match, use default serialization. | |
return super().to_string( | |
parent, | |
alpha=alpha, | |
precision=precision, | |
fit=fit, | |
none=none, | |
color=color, | |
hex=hex, | |
names=names, | |
comma=comma, | |
upper=upper, | |
percent=percent, | |
compress=compress, | |
**kwargs | |
) | |
class Color(Base): ... | |
Color.register(sRGBCustom(), overwrite=True) | |
# pragma: init | |
Color('correct_green') | |
Color('incorrect_red') | |
Color('correct_green').to_string(names=True) | |
Color.match('correct_green incorrect_red', 0, fullmatch=False) | |
Color.match('correct_green incorrect_red', 14, fullmatch=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment