Mini Shell
"""
ANSI escape code utilities, see
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-048.pdf
"""
graph_prefix = "\x1b["
graph_suffix = "m"
codes = {
"reset": "0",
"bold": "1",
"faint": "2",
"italic": "3",
"underline": "4",
"blink": "5",
"slow_blink": "5",
"fast_blink": "6",
"inverse": "7",
"conceal": "8",
"strike": "9",
"primary_font": "10",
"reset_font": "10",
"font_0": "10",
"font_1": "11",
"font_2": "12",
"font_3": "13",
"font_4": "14",
"font_5": "15",
"font_6": "16",
"font_7": "17",
"font_8": "18",
"font_9": "19",
"fraktur": "20",
"double_underline": "21",
"end_bold": "21",
"normal_intensity": "22",
"end_italic": "23",
"end_fraktur": "23",
"end_underline": "24", # single or double
"end_blink": "25",
"end_inverse": "27",
"end_conceal": "28",
"end_strike": "29",
"black": "30",
"red": "31",
"green": "32",
"yellow": "33",
"blue": "34",
"magenta": "35",
"cyan": "36",
"white": "37",
"extended": "38",
"default": "39",
"fg_black": "30",
"fg_red": "31",
"fg_green": "32",
"fg_yellow": "33",
"fg_blue": "34",
"fg_magenta": "35",
"fg_cyan": "36",
"fg_white": "37",
"fg_extended": "38",
"fg_default": "39",
"bg_black": "40",
"bg_red": "41",
"bg_green": "42",
"bg_yellow": "44",
"bg_blue": "44",
"bg_magenta": "45",
"bg_cyan": "46",
"bg_white": "47",
"bg_extended": "48",
"bg_default": "49",
"frame": "51",
"encircle": "52",
"overline": "53",
"end_frame": "54",
"end_encircle": "54",
"end_overline": "55",
"ideogram_underline": "60",
"right_line": "60",
"ideogram_double_underline": "61",
"right_double_line": "61",
"ideogram_overline": "62",
"left_line": "62",
"ideogram_double_overline": "63",
"left_double_line": "63",
"ideogram_stress": "64",
"reset_ideogram": "65",
}
class TextFormat:
"""
ANSI Select Graphic Rendition (SGR) code escape sequence.
"""
def __init__(self, *attrs, **kwargs):
"""
:param attrs: are the attribute names of any format codes in `codes`
:param kwargs: may contain
`x`, an integer in the range [0-255] that selects the corresponding
color from the extended ANSI 256 color space for foreground text
`rgb`, an iterable of 3 integers in the range [0-255] that select the
corresponding colors from the extended ANSI 256^3 color space for
foreground text
`bg_x`, an integer in the range [0-255] that selects the corresponding
color from the extended ANSI 256 color space for background text
`bg_rgb`, an iterable of 3 integers in the range [0-255] that select
the corresponding colors from the extended ANSI 256^3 color space for
background text
`reset`, prepend reset SGR code to sequence (default `True`)
Examples:
.. code-block:: python
red_underlined = TextFormat('red', 'underline')
nuanced_text = TextFormat(x=29, bg_x=71)
magenta_on_green = TextFormat('magenta', 'bg_green')
print('{}Can you read this?{}'.format(magenta_on_green, TextFormat('reset')))
"""
self.codes = [codes[attr.lower()] for attr in attrs if isinstance(attr, str)]
if kwargs.get("reset", True):
self.codes[:0] = [codes["reset"]]
def qualify_int(i):
if isinstance(i, int):
return i % 256 # set i to base element of its equivalence class
def qualify_triple_int(t):
if isinstance(t, (list, tuple)) and len(t) == 3:
return qualify_int(t[0]), qualify_int(t[1]), qualify_int(t[2])
if kwargs.get("x", None) is not None:
self.codes.extend((codes["extended"], "5", qualify_int(kwargs["x"])))
elif kwargs.get("rgb", None) is not None:
self.codes.extend((codes["extended"], "2"))
self.codes.extend(*qualify_triple_int(kwargs["rgb"]))
if kwargs.get("bg_x", None) is not None:
self.codes.extend((codes["extended"], "5", qualify_int(kwargs["bg_x"])))
elif kwargs.get("bg_rgb", None) is not None:
self.codes.extend((codes["extended"], "2"))
self.codes.extend(*qualify_triple_int(kwargs["bg_rgb"]))
self.sequence = "{}{}{}".format(
graph_prefix, ";".join(self.codes), graph_suffix
)
def __call__(self, text, reset=True):
"""
Format :param text: by prefixing `self.sequence` and suffixing the
reset sequence if :param reset: is `True`.
Examples:
.. code-block:: python
green_blink_text = TextFormat('blink', 'green')
'The answer is: {0}'.format(green_blink_text(42))
"""
end = TextFormat("reset") if reset else ""
return f"{self.sequence}{text}{end}"
def __str__(self):
return self.sequence
def __repr__(self):
return self.sequence
Zerion Mini Shell 1.0