Skip to content

Instantly share code, notes, and snippets.

@facelessuser
Created June 23, 2023 19:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save facelessuser/0b129c1faf7f3f59c0de40eeaaab5691 to your computer and use it in GitHub Desktop.
Save facelessuser/0b129c1faf7f3f59c0de40eeaaab5691 to your computer and use it in GitHub Desktop.
Custom sRGB with special color names
# 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