Source code for colorpalette.color

# -*- coding: utf-8 -*-
"""
Created on Tue Jan  1 20:56:58 2019

@author: yoelr
"""
from colorama import Style
from .utils import rgb2hex, decode_ansi, rgb_tint, rgb_shade
import numpy as np
import colors


[docs]class Color: """Create a Color object that can color/style strings. Color objects are an extension of the color function in the `ansicolors` package <https://pypi.org/project/ansicolors/>`__. Parameters ---------- ID: str Name of color. fg: str Foreground color. bg: str Background color. style: str Options include 'bold', 'underline', or None Notes ----- Both *fg* and *bg* should be one of the following [-]: * 3-element tuple or list of int, each valued 0 to 255 (e.g. (255, 218, 185)), * string containing a CSS-compatible color name (e.g. 'peachpuff'), * string containing a CSS-style hex value (e.g. '#aaa' or '#8a2be2') * string containing a CSS-style RGB notation (e.g. 'rgb(102,51,153)') * None Examples -------- :doc:`GettingStarted` """ __slots__ = ('ID', '_ansi', '_RGB', '_RGB_bg', '_style') cached = {} def __new__(self, ID='', fg=None, bg=None, style=None): if ID and fg is None and bg is None and style is None: return self.cached[ID] if isinstance(fg, np.ndarray): fg = tuple([int(i) for i in fg]) if isinstance(bg, np.ndarray): bg = tuple([int(i) for i in bg]) ansi = colors.color('', fg, bg, style).replace(Style.RESET_ALL, '') return self.from_ansi(ID, ansi) @property def ansi(self): """[str] Ansi color code.""" return self._ansi @ansi.setter def ansi(self, ansi): self._ansi = ansi if hasattr(self, '_RGB'): del self._RGB if hasattr(self, '_RGB_bg'): del self._RGB_bg if hasattr(self, '_style'): del self._style
[docs] @classmethod def from_ansi(cls, ID='', ansi=''): """Create a Color object with ansi color code string.""" self = object.__new__(cls) self._ansi = ansi if ID and ID not in cls.cached: cls.cached[ID] = self self.ID = ID return self
def __call__(self, string): return self + str(string) + Style.RESET_ALL def __add__(self, string): return self._ansi + string def __radd__(self, string): return string + self._ansi @property def RGB(self): """[array] Foreground color in RGB on a 0-255 scale.""" if not hasattr(self, '_RGB'): self._RGB, self._RGB_bg, self._style = decode_ansi(self._ansi) return self._RGB @property def RGB_bg(self): """[array] Background color in RGB on a 0-255 scale.""" if not hasattr(self, '_RGB_bg'): self._RGB, self._RGB_bg, self._style = decode_ansi(self._ansi) return self._RGB_bg @property def style(self): if not hasattr(self, '_style'): self._RGB, self._RGB_bg, self._style = decode_ansi(self._ansi) return self._style @property def RGBn(self): """[array] Foreground color in RGB on a normalized 0-1 scale.""" return self.RGB/255. @property def RGBn_bg(self): """[array] Background color in RGB on a normalized 0-1 scale.""" return self.RGB_bg/255. @property def HEX(self): """[str] Foreground color in HEX code.""" return rgb2hex(self.RGB) @property def HEX_bg(self): """[str] Background color in HEX code.""" return rgb2hex(self.RGB_bg) def tint(self, percent, ID=None): fg, bg, style = decode_ansi(self._ansi) if fg is not None: fg = rgb_tint(fg, percent) if bg is not None: bg = rgb_tint(bg, percent) if not ID: *previous_tint, ID = self.ID.split(' tinted ') if len(previous_tint) == 1: try: p, *_ = previous_tint[0].split('%') p = float(p) percent = p + (100.-p)*percent/100. except: pass ID = f'{percent}% tinted {ID}' return Color(ID, fg, bg, style) def shade(self, percent, ID=None): fg, bg, style = decode_ansi(self._ansi) if fg is not None: fg = rgb_shade(fg, percent) if bg is not None: bg = rgb_shade(bg, percent) if not ID: *previous_shade, ID = self.ID.split(' shaded ') if len(previous_shade): try: p, *_ = previous_shade[0].split('%') p = float(p) percent = p + (100.-p)*percent/100. except: pass ID = f'{percent}% shaded {ID}' return Color(ID, fg, bg, style) def _ipython_display_(self): print(repr(self)) def __str__(self): return self._ansi def __repr__(self): if self.ID: name = self.ID else: fg = self.RGB bg = self.RGB_bg style = self.style if isinstance(fg, np.ndarray): fg = tuple(fg) if isinstance(bg, np.ndarray): bg = tuple(bg) name = f"{type(self).__name__}(fg={fg}, bg={bg}, style={repr(style)})" return f'{self}{name}{Style.RESET_ALL}'
Color.cached = dict((i, Color(i, fg=i)) for i in colors.css_colors.keys()) Color.reset = Color.from_ansi('reset', Style.RESET_ALL)