Source code for pylav.helpers.format.ascii

from __future__ import annotations

from math import sqrt

from pylav.constants.misc import ASCII_COLOURS
from pylav.type_hints.generics import SupportsStr


class _BackgroundColourCodes:
    """Background colour codes for ANSI escape sequences."""

    dark_blue = "40"
    orange = "41"
    blue = "42"
    turquoise = "43"
    gray = "44"
    indigo = "45"
    light_gray = "46"
    white = "47"


[docs] class EightBitANSI: """Eight-bit ANSI escape sequences.""" escape = "\u001b[" black = "30" red = "31" green = "32" yellow = "33" blue = "34" magenta = "35" cyan = "36" white = "37" normal = reset = "0" bold = "1" italic = "3" underline = "4" default = "39" background = _BackgroundColourCodes
[docs] @classmethod def colorize( cls, text: SupportsStr, color: str, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Colorize a string with ANSI escape sequences.""" colour = [getattr(cls, color, "39")] if background and (background := getattr(cls.background, background, None)): colour.append(background) if bold: colour.append(cls.bold) if italic: colour.append(cls.italic) if underline: colour.append(cls.underline) colour_code = f"{cls.escape}{';'.join(colour)}m" colour_reset = f"{cls.escape}{cls.reset}m" text = f"{text}".replace("\n", f"{colour_reset}\n{colour_code}") return f"{colour_code}{text}{colour_reset}"
[docs] @classmethod def paint_black( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string black.""" return cls.colorize(text, "black", bold, underline, background, italic)
[docs] @classmethod def paint_red( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string red.""" return cls.colorize(text, "red", bold, underline, background, italic)
[docs] @classmethod def paint_green( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string green.""" return cls.colorize(text, "green", bold, underline, background, italic)
[docs] @classmethod def paint_yellow( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string yellow.""" return cls.colorize(text, "yellow", bold, underline, background, italic)
[docs] @classmethod def paint_blue( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string blue.""" return cls.colorize(text, "blue", bold, underline, background, italic)
[docs] @classmethod def paint_magenta( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string magenta.""" return cls.colorize(text, "magenta", bold, underline, background, italic)
[docs] @classmethod def paint_cyan( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string cyan.""" return cls.colorize(text, "cyan", bold, underline, background, italic)
[docs] @classmethod def paint_white( cls, text: SupportsStr, bold: bool = False, underline: bool = False, background: str = None, italic: bool = False, ) -> str: """Paint a string white.""" return cls.colorize(text, "white", bold, underline, background, italic)
[docs] @classmethod def closest_from_rgb(cls, r: int, g: int, b: int) -> str: """Get the closest 4-bit ANSI colour from a given RGB value.""" return cls.closest_color(r, g, b)
[docs] @classmethod def closest_from_hex(cls, value: str) -> str: """Get the closest 4-bit ANSI colour from a given hex value.""" value = value.lstrip("#") lv = len(value) return cls.closest_color(*tuple(int(value[i : i + lv // 3], 16) for i in range(0, lv, lv // 3)))
[docs] @classmethod def closest_color(cls, red: int, green: int, blue: int) -> str: """Get the closest 4-bit ANSI colour from a given RGB value.""" color_diffs = [] for name, color in ASCII_COLOURS.items(): cr, cg, cb = color color_diff = sqrt((red - cr) ** 2 + (green - cg) ** 2 + (blue - cb) ** 2) color_diffs.append((color_diff, name)) return min(color_diffs)[1]