Source code for laser_cholera.sc

import re
from functools import partial


def _join(*values):
    """
    Join a series of values with semicolons. The values
    are either integers or strings, so stringify each for
    good measure. Worth breaking out as its own function
    because semicolon-joined lists are core to ANSI coding.
    """
    return ";".join(str(v) for v in values)


COLORS = ("black", "red", "green", "yellow", "blue", "magenta", "cyan", "white")
STYLES = ("none", "bold", "faint", "italic", "underline", "blink", "blink2", "negative", "concealed", "crossed")

css_colors = {
    "aliceblue": (240, 248, 255),
    "antiquewhite": (250, 235, 215),
    "aqua": (0, 255, 255),
    "aquamarine": (127, 255, 212),
    "azure": (240, 255, 255),
    "beige": (245, 245, 220),
    "bisque": (255, 228, 196),
    "black": (0, 0, 0),
    "blanchedalmond": (255, 235, 205),
    "blue": (0, 0, 255),
    "blueviolet": (138, 43, 226),
    "brown": (165, 42, 42),
    "burlywood": (222, 184, 135),
    "cadetblue": (95, 158, 160),
    "chartreuse": (127, 255, 0),
    "chocolate": (210, 105, 30),
    "coral": (255, 127, 80),
    "cornflowerblue": (100, 149, 237),
    "cornsilk": (255, 248, 220),
    "crimson": (220, 20, 60),
    "cyan": (0, 255, 255),
    "darkblue": (0, 0, 139),
    "darkcyan": (0, 139, 139),
    "darkgoldenrod": (184, 134, 11),
    "darkgray": (169, 169, 169),
    "darkgreen": (0, 100, 0),
    "darkgrey": (169, 169, 169),
    "darkkhaki": (189, 183, 107),
    "darkmagenta": (139, 0, 139),
    "darkolivegreen": (85, 107, 47),
    "darkorange": (255, 140, 0),
    "darkorchid": (153, 50, 204),
    "darkred": (139, 0, 0),
    "darksalmon": (233, 150, 122),
    "darkseagreen": (143, 188, 143),
    "darkslateblue": (72, 61, 139),
    "darkslategray": (47, 79, 79),
    "darkslategrey": (47, 79, 79),
    "darkturquoise": (0, 206, 209),
    "darkviolet": (148, 0, 211),
    "deeppink": (255, 20, 147),
    "deepskyblue": (0, 191, 255),
    "dimgray": (105, 105, 105),
    "dimgrey": (105, 105, 105),
    "dodgerblue": (30, 144, 255),
    "firebrick": (178, 34, 34),
    "floralwhite": (255, 250, 240),
    "forestgreen": (34, 139, 34),
    "fuchsia": (255, 0, 255),
    "gainsboro": (220, 220, 220),
    "ghostwhite": (248, 248, 255),
    "gold": (255, 215, 0),
    "goldenrod": (218, 165, 32),
    "gray": (128, 128, 128),
    "green": (0, 128, 0),
    "greenyellow": (173, 255, 47),
    "grey": (128, 128, 128),
    "honeydew": (240, 255, 240),
    "hotpink": (255, 105, 180),
    "indianred": (205, 92, 92),
    "indigo": (75, 0, 130),
    "ivory": (255, 255, 240),
    "khaki": (240, 230, 140),
    "lavender": (230, 230, 250),
    "lavenderblush": (255, 240, 245),
    "lawngreen": (124, 252, 0),
    "lemonchiffon": (255, 250, 205),
    "lightblue": (173, 216, 230),
    "lightcoral": (240, 128, 128),
    "lightcyan": (224, 255, 255),
    "lightgoldenrodyellow": (250, 250, 210),
    "lightgray": (211, 211, 211),
    "lightgreen": (144, 238, 144),
    "lightgrey": (211, 211, 211),
    "lightpink": (255, 182, 193),
    "lightsalmon": (255, 160, 122),
    "lightseagreen": (32, 178, 170),
    "lightskyblue": (135, 206, 250),
    "lightslategray": (119, 136, 153),
    "lightslategrey": (119, 136, 153),
    "lightsteelblue": (176, 196, 222),
    "lightyellow": (255, 255, 224),
    "lime": (0, 255, 0),
    "limegreen": (50, 205, 50),
    "linen": (250, 240, 230),
    "magenta": (255, 0, 255),
    "maroon": (128, 0, 0),
    "mediumaquamarine": (102, 205, 170),
    "mediumblue": (0, 0, 205),
    "mediumorchid": (186, 85, 211),
    "mediumpurple": (147, 112, 219),
    "mediumseagreen": (60, 179, 113),
    "mediumslateblue": (123, 104, 238),
    "mediumspringgreen": (0, 250, 154),
    "mediumturquoise": (72, 209, 204),
    "mediumvioletred": (199, 21, 133),
    "midnightblue": (25, 25, 112),
    "mintcream": (245, 255, 250),
    "mistyrose": (255, 228, 225),
    "moccasin": (255, 228, 181),
    "navajowhite": (255, 222, 173),
    "navy": (0, 0, 128),
    "oldlace": (253, 245, 230),
    "olive": (128, 128, 0),
    "olivedrab": (107, 142, 35),
    "orange": (255, 165, 0),
    "orangered": (255, 69, 0),
    "orchid": (218, 112, 214),
    "palegoldenrod": (238, 232, 170),
    "palegreen": (152, 251, 152),
    "paleturquoise": (175, 238, 238),
    "palevioletred": (219, 112, 147),
    "papayawhip": (255, 239, 213),
    "peachpuff": (255, 218, 185),
    "peru": (205, 133, 63),
    "pink": (255, 192, 203),
    "plum": (221, 160, 221),
    "powderblue": (176, 224, 230),
    "purple": (128, 0, 128),
    "rebeccapurple": (102, 51, 153),
    "red": (255, 0, 0),
    "rosybrown": (188, 143, 143),
    "royalblue": (65, 105, 225),
    "saddlebrown": (139, 69, 19),
    "salmon": (250, 128, 114),
    "sandybrown": (244, 164, 96),
    "seagreen": (46, 139, 87),
    "seashell": (255, 245, 238),
    "sienna": (160, 82, 45),
    "silver": (192, 192, 192),
    "skyblue": (135, 206, 235),
    "slateblue": (106, 90, 205),
    "slategray": (112, 128, 144),
    "slategrey": (112, 128, 144),
    "snow": (255, 250, 250),
    "springgreen": (0, 255, 127),
    "steelblue": (70, 130, 180),
    "tan": (210, 180, 140),
    "teal": (0, 128, 128),
    "thistle": (216, 191, 216),
    "tomato": (255, 99, 71),
    "turquoise": (64, 224, 208),
    "violet": (238, 130, 238),
    "wheat": (245, 222, 179),
    "white": (255, 255, 255),
    "whitesmoke": (245, 245, 245),
    "yellow": (255, 255, 0),
    "yellowgreen": (154, 205, 50),
}


[docs] def parse_rgb(s): """Convert string to an RGB color""" if not isinstance(s, str): raise ValueError(f"Could not parse color '{s}'") s = s.strip().replace(" ", "").lower() # simple lookup rgb = css_colors.get(s) if rgb is not None: return rgb # 6-digit hex match = re.match("#([a-f0-9]{6})$", s) if match: core = match.group(1) return tuple(int(core[i : i + 2], 16) for i in range(0, 6, 2)) # 3-digit hex match = re.match("#([a-f0-9]{3})$", s) if match: return tuple(int(c * 2, 16) for c in match.group(1)) # rgb(x,y,z) match = re.match(r"rgb\((\d+,\d+,\d+)\)", s) if match: return tuple(int(v) for v in match.group(1).split(",")) raise ValueError(f"Could not parse color '{s}'")
def _color_code(spec, base): """ Workhorse of encoding a color. Give preference to named colors from ANSI, then to specific numeric or tuple specs. If those don't work, try looking up look CSS color names or parsing CSS hex and rgb color specifications. "Base" is either 30 or 40, signifying the base value for color encoding (foreground and background respectively). Low values are added directly to the base. Higher values use ``base + 8`` (i.e. 38 or 48) then extended codes. Args: spec (str|int|tuple|list): Unparsed color specification base (int): see above """ if isinstance(spec, str): spec = spec.strip().lower() if spec == "default": return _join(base + 9) elif spec in COLORS: return _join(base + COLORS.index(spec)) elif isinstance(spec, int) and 0 <= spec <= 255: return _join(base + 8, 5, spec) elif isinstance(spec, (tuple, list)): return _join(base + 8, 2, _join(*spec)) else: rgb = parse_rgb(spec) # parse_rgb raises ValueError if cannot parse spec return _join(base + 8, 2, _join(*rgb))
[docs] def color(s, fg=None, bg=None, style=None): """ Add ANSI colors and styles to a string. Args: s (str): String to format. fg (str|int|tuple): Foreground color specification. bg (str|int|tuple( bg): Background color specification. style (str): Style names, separated by '+' Returns: Formatted string. """ codes = [] if fg: codes.append(_color_code(fg, 30)) if bg: codes.append(_color_code(bg, 40)) if style: for style_part in style.split("+"): if style_part in STYLES: codes.append(STYLES.index(style_part)) else: raise ValueError(f"Invalid style '{style_part}'") if codes: template = "\x1b[{0}m{1}\x1b[0m" return template.format(_join(*codes), s) else: return s
[docs] def printred(s, **kwargs): """Alias to print(colors.red(s))""" red = partial(color, fg="red") return print(red(s, **kwargs))
[docs] def printgreen(s, **kwargs): """Alias to print(colors.green(s))""" green = partial(color, fg="green") return print(green(s, **kwargs))
[docs] def printcyan(s, **kwargs): """Alias to print(colors.cyan(s))""" cyan = partial(color, fg="cyan") return print(cyan(s, **kwargs))