Last active
July 31, 2024 17:46
-
-
Save DirectXMan12/4c1f9ce3d328c63a9b62 to your computer and use it in GitHub Desktop.
ANSI Escape Sequences Tester
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import print_function | |
import sys | |
import six | |
import contextlib | |
import os | |
try: | |
from __builtin__ import raw_input | |
except ImportError: | |
raw_input = input | |
_ESC = '\x1b' | |
_CSI = _ESC + '[' | |
_SHIFT_OUT = "\x0E" | |
_SHIFT_IN = "\x0F" | |
def with_codes(text, *codes): | |
str_codes = [str(code) for code in codes] | |
return _CSI + (';'.join(str_codes)) + 'm' + text + _CSI + '0m' | |
class BoxMaker(object): | |
def __init__(self, width, to=sys.stdout): | |
self.width = width | |
self.amt = 0 | |
self.output = to | |
def __enter__(self): | |
self.output.write(_SHIFT_OUT + 'l' + ('q' * self.width) + 'k' + _SHIFT_IN + '\n') | |
return self | |
def __exit__(self, exc_type, exc_val, exc_tb): | |
if self.amt > 0 and self.amt < self.width: | |
self.output.write(' ' * (self.width - self.amt)) | |
self.output.write(_SHIFT_OUT + 'x' + _SHIFT_IN + '\n') | |
self.output.write(_SHIFT_OUT + 'm' + ('q' * self.width) + 'j' + _SHIFT_IN + '\n') | |
return False | |
def write(self, contents, contents_len=None): | |
if contents_len is not None and contents_len < 0: | |
contents_len = self.width | |
if self.amt == 0: | |
self.output.write(_SHIFT_OUT + 'x' + _SHIFT_IN) | |
if contents_len is None: | |
contents_len = len([x for x in contents if ord(x) >= 32]) | |
if self.amt + contents_len <= self.width: | |
self.output.write(contents) | |
self.amt += contents_len | |
if self.amt == self.width: | |
self.output.write(_SHIFT_OUT + 'x' + _SHIFT_IN + '\n') | |
self.amt = 0 | |
else: | |
self.output.write(_SHIFT_OUT + 'x' + _SHIFT_IN + '\n') | |
self.amt = 0 | |
self.output.write(contents) | |
# enable the alternate character set | |
sys.stdout.write(_ESC + ')0') | |
# alternate character set | |
print('Alternate character set:\n') | |
with BoxMaker(50) as maker: | |
for g in range(33, 127, 10): | |
for c in range(g, g+10): | |
if c > 126: | |
maker.write(' ' * 5) | |
else: | |
maker.write(' {chr:c}{so}:{chr:c}{si} '.format(chr=c, so=_SHIFT_OUT, si=_SHIFT_IN)) | |
# normal formatting | |
FEATURE_WIDTH = 60 | |
print('\nFormatting\n') | |
def feature(name, *nums): | |
base_str = '%s [%s]' % (';'.join(str(num) for num in nums), name) | |
return with_codes(base_str.ljust(FEATURE_WIDTH), *nums) | |
with BoxMaker(FEATURE_WIDTH) as maker: | |
maker.write(feature('Normal', 0), -1) | |
maker.write(feature('Bold', 1), -1) | |
maker.write(feature('Faint', 2), -1) | |
maker.write(feature('Italic', 3), -1) | |
maker.write(feature('Underline', 4), -1) | |
maker.write(feature('Blink (slow)', 5), -1) | |
maker.write(feature('Blink (fast)', 6), -1) | |
maker.write(feature('Negative Image', 7), -1) | |
maker.write(feature('Conceal', 8), -1) | |
maker.write(feature('Strikethrough', 9), -1) | |
maker.write(feature('Primary Font', 10), -1) | |
maker.write(feature('1st Alternate Font', 11), -1) | |
maker.write(feature('2nd Alternate Font', 12), -1) | |
maker.write(feature('3rd Alternate Font', 13), -1) | |
for n in range(14, 20): | |
maker.write(feature('{0}th Alternate Font'.format(n - 10), n), -1) | |
maker.write(feature('Fraktur', 20), -1) | |
maker.write(feature('Not Bold/Double Underline', 21), -1) | |
maker.write(feature('Normal Color/Intensity', 22), -1) | |
maker.write(feature('Not Italic/Fraktur', 23), -1) | |
maker.write(feature('Not Underlined', 24), -1) | |
maker.write(feature('No Blink', 25), -1) | |
maker.write(feature('Reserved', 26), -1) | |
maker.write(feature('Positive Image', 27), -1) | |
maker.write(feature('Reveal (Not Concealed)', 28), -1) | |
maker.write(feature('Not Struck Through', 29), -1) | |
maker.write(' ' * FEATURE_WIDTH, -1) | |
maker.write('30 - 37 set the foreground color'.ljust(FEATURE_WIDTH), -1) | |
maker.write('38 sets the foreground color (256 colors or 24-bit color)'.ljust(FEATURE_WIDTH), -1) | |
maker.write(' ' * FEATURE_WIDTH, -1) | |
maker.write(feature('Default Foreground Color', 39), -1) | |
maker.write(' ' * FEATURE_WIDTH, -1) | |
maker.write('40 - 47 set the background color'.ljust(FEATURE_WIDTH), -1) | |
maker.write('48 sets the background color (256 colors or 24-bit color)'.ljust(FEATURE_WIDTH), -1) | |
maker.write(' ' * FEATURE_WIDTH, -1) | |
maker.write(feature('Default Background Color', 49), -1) | |
maker.write(feature('Reserved', 50), -1) | |
maker.write(feature('Framed', 51), -1) | |
maker.write(feature('Encircled', 52), -1) | |
maker.write(feature('Overlined', 53), -1) | |
maker.write(feature('Not Framed/Encircled', 54), -1) | |
maker.write(feature('Not Overlined', 55), -1) | |
for i in range(56, 60): | |
maker.write(feature('Reserved', i), -1) | |
maker.write(feature('Ideogram Underline/Right Side Line', 60), -1) | |
maker.write(feature('Ideogram Double Underline/Double Right Side Line', 61), -1) | |
maker.write(feature('Ideogram Overline/Left Side Line', 62), -1) | |
maker.write(feature('Ideogram Double Overline/Double Left Side Line', 63), -1) | |
maker.write(feature('Ideogram Stress Marking', 64), -1) | |
maker.write(feature('No Ideogram Attributes', 65), -1) | |
maker.write(' ' * FEATURE_WIDTH, -1) | |
maker.write('90 - 97 set the high intensity foreground color (aixterm)'.ljust(FEATURE_WIDTH), -1) | |
maker.write('100 - 107 set the high intensity background color (aixterm)'.ljust(FEATURE_WIDTH), -1) | |
# basic colors | |
print('\nBasic Colors\n') | |
with BoxMaker(44) as maker: | |
maker.write('Background'.center(12)) | |
for c in range(40, 48): | |
maker.write(with_codes(" {0} ".format(c), c), 4) | |
maker.write('Faint'.center(12)) | |
for c in range(30, 38): | |
maker.write(with_codes(" {0} ".format(c), c, 2), 4) | |
maker.write('Normal'.center(12)) | |
for c in range(30, 38): | |
maker.write(with_codes(" {0} ".format(c), c), 4) | |
maker.write('Bright'.center(12)) | |
for c in range(30, 38): | |
maker.write(with_codes(" {0} ".format(c), c, 1), 4) | |
print('\nHigh Intensity (AIXTerm) Colors\n') | |
with BoxMaker(52) as maker: | |
maker.write('Foreground'.center(12)) | |
for c in range(90, 98): | |
maker.write(with_codes(" {0} ".format(c), c), 5) | |
maker.write('Background'.center(12)) | |
for c in range(100, 108): | |
maker.write(with_codes(" {0} ".format(c), c, 1), 5) | |
# color combos | |
# 256 color | |
print('\n256 Color Support:\n') | |
with BoxMaker(40) as maker: | |
for c in range(0x00, 0x08): # "normal colors" | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 5) | |
for c in range(0x08, 0x10): | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 5) | |
color256_all = six.StringIO() | |
with BoxMaker(36, to=color256_all) as maker: | |
for c in range(0x10, 0xe8): | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
color256_pure = six.StringIO() | |
with BoxMaker(36, to=color256_pure) as maker: | |
base = 0x10 | |
# blue - green | |
for c in range(base+0, base+36): | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
for c in range(base+0, base+216, 6): | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
for b in range(0, 6): | |
for r in range(0, 6): | |
c = base + b + r * 36 | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
#for b in range(1, 6): | |
# for g in range(1, 6): | |
# for r in range(1, 6): | |
# c = base + b + g*6 + r * 36 | |
# maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
# maker.write(' ' * 6) | |
with BoxMaker(36, to=color256_pure) as maker: | |
base = 0x10 | |
for b in range(0, 6): | |
for i in range(0, 6): | |
c = base + b + i*6 + i*36 | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
for g in range(0, 6): | |
for i in range(0, 6): | |
c = base + i + g*6 + i*36 | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
for r in range(0, 6): | |
for i in range(0, 6): | |
c = base + i + i*6 + r*36 | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
lines1 = color256_all.getvalue().split('\n')[:-1] | |
lines2 = color256_pure.getvalue().split('\n') | |
while len(lines1) < len(lines2): | |
lines1.append(' ' * 38) | |
for p1, p2 in zip(lines1, lines2): | |
sys.stdout.write(p1) | |
sys.stdout.write(' ') | |
sys.stdout.write(p2) | |
sys.stdout.write('\n') | |
with BoxMaker(72) as maker: | |
for c in range(0xE8, 256): # 256 means we include 0xFF | |
maker.write(with_codes(" {0:#0x} ".format(c), 48, 5, c), 6) | |
def pause(): | |
os.system("stty -echo") | |
six.moves.input() | |
os.system("stty echo") | |
show_24bit = raw_input('Show 24-bit color table? ') in ('y', 'yes') | |
if show_24bit: | |
increment = int(raw_input('Color value increment: ')) | |
print('24-bit color support (shown in increments of {0}):\n'.format(increment)) | |
with BoxMaker(100) as maker: | |
for r in six.moves.range(0, 0xff, increment): | |
for g in six.moves.range(0, 0xff, increment): | |
for b in six.moves.range(0, 0xff, increment): | |
try: | |
maker.write(with_codes(" 0x{0:0^2x}{1:0^2x}{2:0^2x} ".format(r, g, b), 48, 2, r, g, b), 10) | |
except KeyboardInterrupt: | |
pause() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment