Source code for arsenal.terminal

# -*- coding: utf-8 -*-
import sys, os
from glob import glob
from subprocess import Popen, PIPE


[docs]def ansi2html(x): p = Popen('ansi2html.sh', stdout=PIPE, stdin=PIPE, stderr=PIPE) p.stdin.write(str(x).encode('utf-8')) return p.communicate()[0].decode('utf-8')
[docs]def overline(xs): return ''.join(f'{x}\u0305' for x in xs)
partial = '∂'
[docs]class bb: A = '𝔸' B = '𝔹' C = 'ℂ' D = '𝔻' E = '𝔼' F = '𝔽' G = '𝔾' H = 'ℍ' I = '𝕀' J = '𝕁' K = '𝕂' L = '𝕃' M = '𝕄' N = 'ℕ' O = '𝕆' P = 'ℙ' Q = 'ℚ' R = 'ℝ' S = '𝕊' T = '𝕋' U = '𝕌' V = '𝕍' W = '𝕎' X = '𝕏' Y = '𝕐' Z = 'ℤ'
# https://stackoverflow.com/questions/8651361/how-do-you-print-superscript-in-python superscript_map = { "0": "⁰", "1": "¹", "2": "²", "3": "³", "4": "⁴", "5": "⁵", "6": "⁶", "7": "⁷", "8": "⁸", "9": "⁹", 0: "⁰", 1: "¹", 2: "²", 3: "³", 4: "⁴", 5: "⁵", 6: "⁶", 7: "⁷", 8: "⁸", 9: "⁹", "a": "ᵃ", "b": "ᵇ", "c": "ᶜ", "d": "ᵈ", "e": "ᵉ", "f": "ᶠ", "g": "ᵍ", "h": "ʰ", "i": "ᶦ", "j": "ʲ", "k": "ᵏ", "l": "ˡ", "m": "ᵐ", "n": "ⁿ", "o": "ᵒ", "p": "ᵖ", "q": "۹", "r": "ʳ", "s": "ˢ", "t": "ᵗ", "u": "ᵘ", "v": "ᵛ", "w": "ʷ", "x": "ˣ", "y": "ʸ", "z": "ᶻ", "A": "ᴬ", "B": "ᴮ", "C": "ᶜ", "D": "ᴰ", "E": "ᴱ", "F": "ᶠ", "G": "ᴳ", "H": "ᴴ", "I": "ᴵ", "J": "ᴶ", "K": "ᴷ", "L": "ᴸ", "M": "ᴹ", "N": "ᴺ", "O": "ᴼ", "P": "ᴾ", "Q": "Q", "R": "ᴿ", "S": "ˢ", "T": "ᵀ", "U": "ᵁ", "V": "ⱽ", "W": "ᵂ", "X": "ˣ", "Y": "ʸ", "Z": "ᶻ", "+": "⁺", "-": "⁻", "=": "⁼", "(": "⁽", ")": "⁾", } subscript_map = { "0": "₀", "1": "₁", "2": "₂", "3": "₃", "4": "₄", "5": "₅", "6": "₆", "7": "₇", "8": "₈", "9": "₉", 0: "₀", 1: "₁", 2: "₂", 3: "₃", 4: "₄", 5: "₅", 6: "₆", 7: "₇", 8: "₈", 9: "₉", "a": "ₐ", "b": "♭", "c": "꜀", "d": "ᑯ", "e": "ₑ", "f": "բ", "g": "₉", "h": "ₕ", "i": "ᵢ", "j": "ⱼ", "k": "ₖ", "l": "ₗ", "m": "ₘ", "n": "ₙ", "o": "ₒ", "p": "ₚ", "q": "૧", "r": "ᵣ", "s": "ₛ", "t": "ₜ", "u": "ᵤ", "v": "ᵥ", "w": "w", "x": "ₓ", "y": "ᵧ", "z": "₂", "A": "ₐ", "B": "₈", "C": "C", "D": "D", "E": "ₑ", "F": "բ", "G": "G", "H": "ₕ", "I": "ᵢ", "J": "ⱼ", "K": "ₖ", "L": "ₗ", "M": "ₘ", "N": "ₙ", "O": "ₒ", "P": "ₚ", "Q": "Q", "R": "ᵣ", "S": "ₛ", "T": "ₜ", "U": "ᵤ", "V": "ᵥ", "W": "w", "X": "ₓ", "Y": "ᵧ", "Z": "Z", "+": "₊", "-": "₋", "=": "₌", "(": "₍", ")": "₎", }
[docs]class arrow: u = up = '↑' ur = '↗', r = right = '→' dr = '↘', dl = '↙' d = down = '↓' l = left = '←' ul = '↖'
[docs] class long: right = r = '⟶' leftright = lr = '⟷' left = l = '⟵'
[docs] class Long: leftright = lr = '⟺' left = l = '⟸' right = r = '⟹'
[docs] class squiggle: right = r = '⟿'
arrows = arrow.__dict__
[docs]def superscript(x): return "".join(superscript_map[i] for i in str(x))
[docs]def subscript(x): return "".join(subscript_map[i] for i in str(x))
[docs]def complete_filenames(text, line, begidx, endidx): "Util for filename completion." before_arg = line.rfind(" ", 0, begidx) if before_arg == -1: return # arg not found fixed = line[before_arg+1:begidx] # fixed portion of the arg completions = [] for p in glob(line[before_arg+1:endidx] + '*'): p = p + (os.sep if p and os.path.isdir(p) and p[-1] != os.sep else '') completions.append(p.replace(fixed, "", 1)) return completions
[docs]def ansi(color=None, light=None, bg=3): return '\x1b[%s;%s%sm' % (light, bg, color)
_reset = '\x1b[0m'
[docs]def colorstring(s, c): return c + s + _reset
_arrow = arrow
[docs]class colors: arrow = _arrow black, red, green, yellow, blue, magenta, cyan, white = \ [colorstring('%s', ansi(c, 0)) for c in range(8)]
[docs] class light: black, red, green, yellow, blue, magenta, cyan, white = \ [colorstring('%s', ansi(c, 1)) for c in range(8)]
[docs] class dark: black, red, green, yellow, blue, magenta, cyan, white = \ [colorstring('%s', ansi(c, 2)) for c in range(8)]
[docs] class bg: black, red, green, yellow, blue, magenta, cyan, white = \ [colorstring('%s', ansi(c, 0, bg=4)) for c in range(8)]
[docs] def rgb(r,g,b): return f"\x1b[48;2;{r};{g};{b}m%s\x1b[0m"
orange = rgb(255, 165, 0) rgb = staticmethod(rgb)
[docs] def rgb(r,g,b): return f"\x1b[38;2;{r};{g};{b}m%s\x1b[0m"
orange = rgb(255, 165, 0) rgb = staticmethod(rgb) normal = '\x1b[0m%s\x1b[0m' bold = '\x1b[1m%s\x1b[0m' italic = "\x1b[3m%s\x1b[0m" underline = "\x1b[4m%s\x1b[0m" strike = "\x1b[9m%s\x1b[0m" #overline = lambda x: (u''.join(unicode(c) + u'\u0305' for c in unicode(x))).encode('utf-8') leftarrow = '←' rightarrow = '→' reset = _reset ansi2html = ansi2html
[docs] @staticmethod def line(n): return '─'*(n)
[docs] @staticmethod def thick_line(n): return ('━'*80)
[docs] @staticmethod def mark_(x): return '✔' if x else '✘'
#def padr(w): # "get format to pad right elements" # return '%%%ss' % w #pad = padr #def padl(w): # "get format to pad left elements" # return '%%-%ss' % w #def getwidth(a): # "Find maximum width of the string representations of the elements of ``a``." # return max(len(str(z)) for z in a) def check(x, t='pass', f='fail'): return colors.green % t if x else colors.red % f #def color01(x, fmt='%.10f', min_color=235, max_color=255): # "Colorize numbers in [0,1] based on value; darker means smaller value." # import colored # if not (0 <= x <= 1 + 1e-10): # return colors.red % fmt % x # width = max_color - min_color # color = min_color + int(round(x*width)) # return '%s%s%s' % (colored.fg(color), (fmt % x), colored.attr('reset'))
[docs]def console_width(minimum=None, default=80): "Return width of available window area." from tqdm.utils import _screen_shape_wrapper x = _screen_shape_wrapper()(sys.stdout)[0] return max(minimum or 0, x or default)
[docs]def marquee(msg=''): return ('{0:*^%s}' % console_width()).format(msg)
import re
[docs]def render(y, **kwargs): """ Render colorful string using 'reset' to mean 'pop the color stack' rather than go directly 'normal' color. """ return rendering(y, **kwargs).value
[docs]class rendering: def __init__(self, y, debug=False): y = str(y) xs = re.split('(\x1b\[[0-9;]+m)', y) # tokenize. if debug: msg = lambda *args: print(f'[render]{" "*len(s)}', *args) s = [_reset] # stack b = [] # buffer prefix = '\x1b[' # control code prefix c = _reset # current color for x in xs: if debug: msg('current token', repr(x)) if x.startswith(prefix): if x == _reset: if debug: msg(' ^ pop') c = s.pop() if len(s) else _reset else: if debug: msg(' ^ control code', x + repr(x) + _reset) s.append(c) c = x continue else: if debug: msg(' ^ color', c + repr(x) + _reset) b.append(c) b.append(x + _reset) b.append(_reset) # always end on reset. self.xs = xs self.value = ''.join(b) def __len__(self): return sum(len(x) for x in self.xs if not x.startswith('\x1b[')) # control code prefix def __str__(self): return self.value def __repr__(self): return self.value def __format__(self, spec): [(pad, fmt)] = re.findall('^(-?\d*)(s)$', spec) pad = int(pad) if pad > 0: return self.value + ' '*max(0, pad - len(self)) else: return ' '*max(0, abs(pad) - len(self)) + self.value
colors.render = render colors.rendering = rendering ok = colors.green % 'ok' warn = colors.yellow % 'warn' fail = colors.light.red % 'fail' bad = colors.light.red % 'bad' error = colors.light.red % 'error' thumbs_up = '👍' thumbs_down = '👎' poop = poo = turd = '💩' timeout = '⌛' colors.poop = poop colors.ok = ok colors.warn = warn colors.fail = fail colors.bad = bad colors.timeout = timeout colors.thumbs_up = '👍' colors.thumbs_down = '👎' check = colors.green % '✔' #'✓' xmark = colors.dark.red % '✘' # ☒ - Unicode Character Table
[docs]def mark(x): return check if x else xmark
colors.mark = mark colors.check = check colors.xmark = xmark
[docs]def tests(): for c in 'black, red, green, yellow, blue, magenta, cyan, white'.split(', '): print('%18s %24s %23s %21s' % (getattr(colors, c) % c, getattr(colors.light, c) % f'light.{c}', getattr(colors.dark, c) % f'dark.{c}', getattr(colors.bg, c) % f'bg.{c}')) print(colors.underline % 'underline') print(colors.italic % 'italic') print(colors.strike % 'strike') #import numpy as np #for x in np.linspace(0, 1, 15): # print(color01(x, fmt='%.2f'), end=' ') #print() w = console_width() print('Console width:', w, sep=' ') print('='*w) print(marquee(' marquee ')) print() print('Stack-based rendering') print('=====================') g = colors.green % 'green' b = colors.blue % f'blue {g} blue' r = colors.red % f'red {b} red {b} red' x = colors.normal % f'normal {r} normal' print(render(x)) # SDD: make sure we reset after dark print(render( (colors.light.blue % 'light %s light' % colors.dark.blue % 'dark %s dark' % colors.blue % 'regular'), #debug = True, )) print(thumbs_up, thumbs_down)
if __name__ == '__main__': tests()