diff --git a/colorama/ansi.py b/colorama/ansi.py index 11ec695..cc29c83 100644 --- a/colorama/ansi.py +++ b/colorama/ansi.py @@ -23,15 +23,63 @@ def clear_line(mode=2): class AnsiCodes(object): + def __init__(self): # the subclasses declare class attributes which are numbers. # Upon instantiation we define instance attributes, which are the same # as the class attributes but wrapped with the ANSI escape sequence for name in dir(self): - if not name.startswith('_'): + if not name.startswith('_') and not name == 'from_rgb' and not name == 'from_hex': value = getattr(self, name) setattr(self, name, code_to_chars(value)) + @classmethod + def from_rgb(cls, r, g, b): + + if cls == AnsiFore: + + ansi_start = '38' + + elif cls == AnsiBack: + + ansi_start = '48' + + else: + + raise TypeError('The from_hex command may only be called from AnsiFore and AnsiBack objects.') + + return f'\033[{ansi_start};2;{r};{g};{b}m' + + @classmethod + def from_hex(cls, hex: str): + + hex = hex.strip('#') + + if len(hex) == 6: + + r, g, b = tuple(int(single_hex, 16) for single_hex in (hex[0:2], hex[2:4], hex[4:6])) + + elif len(hex) == 3: + + r, g, b = tuple(int(single_hex, 16) for single_hex in (hex[0]*2, hex[1]*2, hex[2]*2)) + + else: + + raise ValueError(f'Hex Error: The given hex code: {hex} is not valid. A hex code should be 6 or 3 characters long.') + + if cls == AnsiFore: + + ansi_start = '38' + + elif cls == AnsiBack: + + ansi_start = '48' + + else: + + raise TypeError('The from_hex command may only be called from AnsiFore and AnsiBack objects.') + + return f'\033[{ansi_start};2;{r};{g};{b}m' class AnsiCursor(object): def UP(self, n=1): @@ -99,4 +147,4 @@ class AnsiStyle(AnsiCodes): Fore = AnsiFore() Back = AnsiBack() Style = AnsiStyle() -Cursor = AnsiCursor() +Cursor = AnsiCursor() \ No newline at end of file