diff --git a/ansi_escape.py b/ansi_escape.py index e4beebb..1892211 100644 --- a/ansi_escape.py +++ b/ansi_escape.py @@ -1,40 +1,311 @@ -def bell(): - print("\u0007") +""" +Name: ansi_escape +By: Filip Nilsen +Website: filip-nilsen.com +Sources: +https://en.wikipedia.org/wiki/ANSI_escape_code +https://terminalguide.namepad.de/seq/ +https://man7.org/linux/man-pages/man4/console_codes.4.html +""" -def cursor_position(**coordinates): +def set_title(title, *args): + """ + Set title of the terminal emulator: + \u001b]{n};{t}\u001b\\ + Where {t} is the title of the window and/or icon + Values of {n} + |0|Makes {t} title of window and minimized desktop icon + |1|Makes {t} title of just the minimized desktop icon + |2|Makes {t} title of just the terminal emulator window + """ + if len(args) == 0: + return "\u001b]0;" + title + "\u001b\\" + elif args[0] == "window": + return "\u001b]2;" + title + "\u001b\\" + elif args[0] == "icon": + return "\u001b]1;" + title + "\u001b\\" + else: + return "\u001b]" + str(args[0]) + ";" + title + "\u001b\\" + +def bell_frequency(Hz): + return "\u001b[10;" + str(Hz) + "]" +bell_freq = bell_frequency +bell_f = bell_frequency +bell_hz = bell_frequency + +def bell_duration(ms): + return "\u001b[11;" + str(ms) + "]" + +def blink_interval(ms): + return "\u001b[16;" + str(ms) + "]" + +def erase_character(*amount): + """ + Deletes from left to right --> + Does not change cursor position. + """ + try: + return "\u001b[" + str(amount[0]) + "X" + except: + return "\u001bX" + + +def delete_character(*amount): + """ + Deletes from left to right --> + Characters to the left ar shifted to the right by {amout}. + Does not change cursor position. + """ + try: + return "\u001b[" + str(amount[0]) + "P" + except: + return "\u001bP" + +def line(a, *amount): return_string = "\u001b[" try: - return_string += coordinates["row"] + return_string += str(amount[0]) + except: + pass + if a == "insert": + return return_string + "L" + elif a == "delete": + return return_string + "M" + +def set_leds(led): + a = { + "reset": "0", + "clear": "0", + "none": "0", + "scroll lock": "1", + "num lock": "2", + "caps lock": "3" + } + try: + return "\u001b[" + a[led] + "q" + except: + return "\u001b" + str(led) + "q" + +def set(attr): + a = { + "bold": "1", + "faint": "2", + "italic": "3", + "underline": "4", + "blink": "5", + "overline": "53", + "inverse": "7", + "invisible": "8", + "strike": "9" + } + try: + return "\u001b[" + a[attr] + "m" + except: + return "\u001b[" + str(attr) + "m" + +def unset(attr): + a = { + "all": "0", + "bold": "22", + "faint": "22", + "italic": "23", + "underline": "24", + "blink": "25", + "overline": "55", + "inverse": "27", + "invisible": "28", + "strike": "29", + "fg": "39", + "bg": "49" + } + try: + return "\u001b[" + a[attr] + "m" + except: + return "\u001b[" + str(attr) + "m" + + +def set_top_and_bottom_margins(**args): + return_string = "\u001b[" + try: + return_string += args["top"] except: pass return_string += ";" - try: - return_string += coordinates["column"] + return_string += args["bottom"] except: pass + return_string += "r" + return return_string + +decstbm = set_top_and_bottom_margins +set_scrolling_region = set_top_and_bottom_margins + + +def select_cursor_style(a, b): + return_string = "\u001b[" + if a == "blinking": + if b == "block": + return_string += "1" + elif b == "underline": + return_string += "3" + elif b == "bar": + return_string += "5" + elif a == "steady": + if b == "block": + return_string += "2" + elif b == "underline": + return_string += "4" + elif b == "bar": + return_string += "6" + return_string += " q" + return return_string + +decscusr = select_cursor_style + +def scroll(direction, *lines): + """ + \u001b[{n}{d} + Scrolls the display up or down by {n} lines. {n} defaults to 1. + {d} is the direction to scroll in. + Values for {d}: + |S|up + |T|down + """ + return_string = "\u001b[" + try: + return_string += str(lines[0]) + except: + pass + if direction == "up": + return_string += "S" + elif direction == "down": + return_string += "T" + return return_string + +def cursor_horisontal_absolute(*column): + """ + \u001b[{n}G + Wil move the cursor to column {n}. + {n} defaults to 1 + """ + return_string = "\u001b[" + try: + return_string += str(column[0]) #optional; therefore it is in a try: + except: + pass #defaults to 1 + return_string += "G" + return return_string + +cha = cursor_horisontal_absolute + +def cursor_line(direction, *lines): + """ + \u001b[{n}E + Will move the cursor {n} lines down and put the cursor at the beginning of that line. + If {n} is not supplied it defaults to 1. + + \u001b[{n}F + The same as above, just that the cursor wil go up. + """ + + return_string = "\u001b[" #csi + + try: + return_string += str(lines[0]) #try to add the optinal lines variable to the control sequence + except: + pass #lines are optional the standard defaults to 1 + + a = { + "next": "E", #indicates wanting to scroll down + "down": "E", + "previous": "F", #scroll up + "up": "F" + } + + try: + return_string += a[direction] #replace human readable name with variable in a{} + except: + return_string += str(direction) #makes it possible to pass E or F directly to the function + + return return_string + +def cursor_position(**coordinates): + """ + \u001b[{r};{c}H + Will move the cursor to row {r} and column {c}. + If {c} and/or {r} is not provided they will default to 1. + \u001b;H + Will therefore move the cursor to 1,1. + """ + + return_string = "\u001b[" + + try: + return_string += str(coordinates["row"]) + except: + pass + + return_string += ";" + + try: + return_string += str(coordinates["column"]) + except: + pass + return_string += "H" return return_string -set_cursor = cursor_position +#set_cursor = cursor_position cup = cursor_position def move_cursor(direction, *cells): - return_string = "\u001b[" + """ + \u001b[{c}{d} + Moves the cursor {c} cells in direction {d}. + {d} can be A, B, C, or D which means up, down, forward/right, and backward/left respectivley. + {c} can be omitted and defaults to 1. + Examples: + \u001b[3A #moves the cursor 3 cells up + \u001b[B #moves the cursor 1 cell down + """ + + return_string = "\u001b[" #csi + try: - return_string += cells[0] + return_string += str(cells[0]) #cells is optional therefore it is in a try statement except: - pass - a = { + pass #if no argument is supplied it defaults to 1 + + a = { #human redable names for directions to move the cursor "up": "A", + "down": "B", + "forward": "C", - "backward": "D" + "right": "C", + + "backward": "D", + "left": "D" } - return_string += a[direction] + + try: + return_string += a[direction] #allows human redable names to be used + except: + return_string += direction #allows the function to take A-D as parameters directly + return return_string def erase_in_display(direction): + """ + \u001b[{d}J + Erases cells on the display from the cursor to direction {d}. + {d} can be: + |0|Erases from the cursor to the end of the display. + |1|Erases from the cursor to the top of the display. + |2|Does both. + |3|On some terminals this will do both and erase the history. Since it is not supported in all terminals I do not recomend using this. + """ return_string = "\u001b[" a = { "forward": "0", @@ -53,92 +324,136 @@ erase_in_display_from_cursor = erase_in_display ed = erase_in_display def erase_in_line(direction): + """ + \u001b[{n}K + Deletes characters on the same line as the cursor in direction {n} from the cursor. + {n} can be: + |0|Deletes from the cursor to the end of the line. + |1|Deletes from the cursor to the beginning of the line. + |2|Deletes in both directions. (Clears the line) + """ return_string = "\u001b[" - a = { + a = { #human readable names "forward": "0", + "right": "0", "backward": "1", + "left": "1", "both": "2" } try: - return_string += a[direction] + return_string += a[direction] #replaces the human readable name with mthe machine readable number except: - return_string += direction + return_string += str(direction) #makes it posible to use numbers 0-2 instead return_string += "K" return return_string erase_in_line_from_cursor = erase_in_line el = erase_in_line -def color(mode, ground, *args): - return_string = "\u001b[" - if mode == "bright": - return_string += "1;" - mode = "normal" +def color(ground, *args): + """ + Color is complicated: + See: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors + + 3-bit 8 colors support: + \u001b[{g}{c}m + Where {g} can be 3 or 4 and represents if the foreground color (aka text color) or background color should be changed. + |3|Change foreground color (aka text color) + |4|Change background color + {c} is a number between 0-7 that represents the color itself + Example: + \u001b[46m #makes the text background color cyan + + Brighter/lighter/"more intense" variants of the 3-bit colors (4-bit color): + \u001b[{g}{c}m + Here the values of {g} are different: + |9 |Foreground color + |10|Background color + {c} is the same as 3-bit + Example: + \u001b[100m #sets background color to bright black (esentially grey) + + 8-bit 256 color support: + See: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit for list of colors + \u001b[{g}8;5;{c}m + {g} uses the same values as 3-bit color. + {c} is a number between 0-255 that represent the color. + Values for {c}: + |0-7 |Same numbers as those used for 3-bit colors + |8-15 |Brighter 3-bit colors + |16-231 |Colors + |232-255|Grayscale + Example: + \001b[48;5;34m #sets a light green background color + + 24-bit True color: + \u001b[8;2;{r};{g};{b}m + Variables {r}, {g}, and {b} are rgb values + """ + + return_string = "\u001b[" #csi - if ground == "fg": + if ground == "fg": #sets text color aka foreground color return_string += "3" - elif ground == "bg": + elif ground == "bg": #sets background color return_string += "4" - if mode == "256": - return_string += "8;5;" - return_string += args[0] - return_string += "m" - return return_string - - elif mode == "rgb": - return_string += "8;2;" - return_string = return_string + args[0] + ";" + args[1] + ";" +args[2] - return_string += "m" - return return_string - - elif mode == "normal": - color_chart = { - "black": "0", - "red": "1", - "green": "2", - "yellow": "3", - "blue": "4", - "magenta": "5", - "cyan": "6", - "white": "7" + if len(args) == 1: + return_string += "8;5;" #SGR code for 8-bit 256 color support + color_chart = { #human readable color names instead of 0-7 + "black": 0, + "red": 1, + "green": 2, + "yellow": 3, + "blue": 4, + "magenta": 5, + "cyan": 6, + "white": 7 } - a = color_chart[args[0]] - return_string += a + color = args[0] + + if type(color) == str: #human readable name + if "bright-" in color: + color = color.replace("bright-", "") + color = color_chart[color] + 8 + else: + color = color_chart[color] + + return_string += str(color) + return_string += "m" + return return_string + + elif len(args) == 3: + return_string += "8;2;" #SGR code for 24-bit RGB + return_string = return_string + str(args[0]) + ";" + str(args[1]) + ";" + str(args[2]) #r;g;b return_string += "m" return return_string bell = "\u0007" + backspace = "\u0008" +bs = backspace escape = "\u001b" esc = escape csi = escape + "[" -reset = csi + "0m" -normal = reset -reset_formatting = reset +""" +Device Status Report (DSR) +Returns cursor position to the application +\u001b[{r};{c}R +{r} is the row +{c} is the column +""" +device_status_report = csi + "6n" +dsr = device_status_report -bold = csi + "1m" -faint = csi +"2m" -underline = csi + "4m" -blink = csi + "5m" +decaln = esc + "#8" #fills screen with E +decid = esc + "Z" -invert = csi + "7m" -reverse_video = invert +save_cursor = esc + "7" +decsc = save_cursor -strike = csi + "9m" -crossed_out = strike - -normal_intensity = csi + "22m" -#no_italic = csi + "23m" #not vidley supported -no_blink = csi + "25m" -no_strike = csi + "29m" -reset_fg = csi + "39m" -reset_bg = csi + "49m" -overline = csi + "53m" -no_overline = csi + "55m" -frame = csi + "51m" -encircle = csi + "52m" -no_frame = csi + "54m" \ No newline at end of file +restore_cursor = esc + "8" +decrc = restore_cursor \ No newline at end of file diff --git a/doc/color.md b/doc/color.md new file mode 100644 index 0000000..102c0dc --- /dev/null +++ b/doc/color.md @@ -0,0 +1,49 @@ +Color +===== +256 8-bit colors +---------------- +```python +print(ansi_escape.color("fg", "red") + "red text") +``` +Makes the color of the text itself (aka the foreground color) red. + +```python +print(ansi_escape.color("bg", "bright-cyan") + "bright cyan text background") +``` +This will make the background color bright cyan. + +ansi_escape.color() also supports the numbers 0-255 [here is a list explaining each number.](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) + +```python +print(ansi_escape.color("bg", 33) + "text") +``` + +You can also use the following human readable names insteead of 0-16: + +| Instead of | Use | +| ---------: | :------------- | +| 0|"black" | +| 1|"red" | +| 2|"green" | +| 3|"yellow" | +| 4|"blue" | +| 5|"magenta" | +| 6|"cyan" | +| 7|"white" | +| 8|"bright-black" | +| 9|"bright-red" | +| 10|"bright-green" | +| 11|"bright-yellow" | +| 12|"bright-blue" | +| 13|"bright-magenta"| +| 14|"bright-cyan" | +| 15|"bright-white" | + +24-bit True Color +----------------- +To do this provide ansi_escape.color() with "fg" or "bg" + 3 comma reperated values for r, g, and b respectivley, each rgb value can be a number between 0-255. + +```python +print(ansi_escape.color("bg", 128, 0, 255) + "bg for background color") +print(ansi_escape.color("fg", 255, 69, 128) + "fg for foreground color") +``` diff --git a/doc/cursor.md b/doc/cursor.md new file mode 100644 index 0000000..e168d89 --- /dev/null +++ b/doc/cursor.md @@ -0,0 +1,49 @@ +Cursor control +============== +Move to spesific coordinates +---------------------------- +To move the terminal cursor using positional coordinates use the following function: + +```python +ansi_escape.cursor_position() +``` +If the function name is to long you can use: + +```python +ansi_escape.cup() +``` +instead. + +```python +ansi_escape.cup() #sets position to 1,1 +ansi_escape.cursor_position(row=5) #sets cursor position to row 5 and column 1 +ansi_escape.cup(column=16) #sets cursor position to column 16 and row 1 +ansi_escape.cursor_position(row=30, column=3) #sets cursor position to row 30 and column 3 +``` +Move cursor from current position +--------------------------------- +For relative movements use: + +```python +ansi_escape(direction, cells) +``` +direction can be: + - "up" + - "down" + - "forward" + - "backward" +It is the direction the cursor moves towards. + +cells is an optional argumant which specifies how many character cells you want to move the cursor. + +Move cursor to spesific horisontal position +------------------------------------------- +Use: + +```python +ansi_escape.cursor_horisontal_absolute(column) +#or +ansi_escape.cha(column) +``` +column can be omitted and will then default to 1. +This will not affect the vertical coordinates of the cursor. \ No newline at end of file diff --git a/doc/delete.md b/doc/delete.md new file mode 100644 index 0000000..20881f4 --- /dev/null +++ b/doc/delete.md @@ -0,0 +1,38 @@ +Character deletion +================== +Erase character +--------------- +```python +ansi_escape.erase_character(n) +``` +Will erase n amount of characters from the cursor to the right of the cursor. +amount defaults to 1. + +Delete character +---------------- +```python +ansi_escape.delete_character(n) +``` +Works just like erase_character(), but after deleting the characters it wil shift any remaining characters to the left of the cursor by n amount. +If n is omitted it defaults to 1. +Erase in display +---------------- +```python +ansi_escape.erase_in_display(n) +#or +ansi_escape.ed(n) +``` +Will erase in the display from the cursor. +n is the direction from the cursor to erase in and can be : forward, backward, or both. n can also be "history" which works like "both", but will also include the buffered history of the terminal. I do not reccomend using history since it is not widley supported. +Erase in line +------------- +```python +ansi_escape.erase_in_line(n) +#or +ansi_escape.el(n) +``` +Like erase in display, but limited to one line. The n variable works the same way, minus the history option. \ No newline at end of file diff --git a/examples/a.txt b/examples/a.txt deleted file mode 100644 index 1913cf0..0000000 --- a/examples/a.txt +++ /dev/null @@ -1,2 +0,0 @@ -]0;256 Color Terminal Palette - 0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99  100  101  102  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119  120  121  122  123  124  125  126  127  128  129  130  131  132  133  134  135  136  137  138  139  140  141  142  143  144  145  146  147  148  149  150  151  152  153  154  155  156  157  158  159  160  161  162  163  164  165  166  167  168  169  170  171  172  173  174  175  176  177  178  179  180  181  182  183  184  185  186  187  188  189  190  191  192  193  194  195  196  197  198  199  200  201  202  203  204  205  206  207  208  209  210  211  212  213  214  215  216  217  218  219  220  221  222  223  224  225  226  227  228  229  230  231  232  233  234  235  236  237  238  239  240  241  242  243  244  245  246  247  248  249  250  251  252  253  254  255 \ No newline at end of file diff --git a/examples/ansi_escape.py b/examples/ansi_escape.py deleted file mode 120000 index 95d8672..0000000 --- a/examples/ansi_escape.py +++ /dev/null @@ -1 +0,0 @@ -/home/filip/Documents/python3/ansi_escape/ansi_escape.py \ No newline at end of file diff --git a/examples/backspace.py b/examples/backspace.py new file mode 100644 index 0000000..9975e1c --- /dev/null +++ b/examples/backspace.py @@ -0,0 +1,7 @@ +import ansi_escape, sys, time +print("Hello World!!", end='') +time.sleep(1) +a = 0 +while a < 5: + a += 1 + sys.stdout.write(ansi_escape.backspace) \ No newline at end of file diff --git a/examples/bell.py b/examples/bell.py new file mode 100644 index 0000000..b7a3c7d --- /dev/null +++ b/examples/bell.py @@ -0,0 +1,5 @@ +import ansi_escape +print(ansi_escape.bell_f(10000)) +a = 10 +while a < 10: + print(ansi_escape.bell) \ No newline at end of file diff --git a/examples/choose_line_to_erase.py b/examples/choose_line_to_erase.py deleted file mode 100644 index e51b742..0000000 --- a/examples/choose_line_to_erase.py +++ /dev/null @@ -1,8 +0,0 @@ -import ansi_escape -a = 0 -while a < 10: - a += 1 - print("Hello World!!") - -a = input() -print(ansi_escape.move_cursor("up", str(a)) + ansi_escape.el("both")) \ No newline at end of file diff --git a/examples/dsr.py b/examples/dsr.py new file mode 100644 index 0000000..be19975 --- /dev/null +++ b/examples/dsr.py @@ -0,0 +1,2 @@ +import ansi_escape, sys +print(ansi_escape.cup(column=23, row=22) + ansi_escape.dsr) \ No newline at end of file diff --git a/examples/erase.py b/examples/erase.py deleted file mode 100644 index be99cb7..0000000 --- a/examples/erase.py +++ /dev/null @@ -1,2 +0,0 @@ -import ansi_escape, os -print(ansi_escape.erase_from_cursor("2")) \ No newline at end of file diff --git a/examples/garble_display.py b/examples/garble_display.py new file mode 100644 index 0000000..9238c2c --- /dev/null +++ b/examples/garble_display.py @@ -0,0 +1,7 @@ +import ansi_escape +from random import randint as randint +while 1: + print(ansi_escape.cup(column=randint(1, 80), row=randint(1, 30)) + + ansi_escape.color("bg", randint(0, 255), randint(0, 255), randint(0, 255)) + + " " + + ansi_escape.unset("all")) \ No newline at end of file diff --git a/examples/keyboard.py b/examples/keyboard.py new file mode 100644 index 0000000..4a7407d --- /dev/null +++ b/examples/keyboard.py @@ -0,0 +1,3 @@ +import ansi_escape +print(ansi_escape.set_leds("reset")) +input() \ No newline at end of file diff --git a/examples/move_cursor.py b/examples/move_cursor.py deleted file mode 100644 index c7dc9a5..0000000 --- a/examples/move_cursor.py +++ /dev/null @@ -1,7 +0,0 @@ -import keyboard, ansi_escape -print(ansi_escape.erase_from_cursor("both")) -keyboard.add_hotkey('up', ansi_escape.cursor, args=('up')) -keyboard.add_hotkey('down', ansi_escape.cursor, args=('down')) -keyboard.add_hotkey('left', ansi_escape.cursor, args=('backward')) -keyboard.add_hotkey('right', ansi_escape.cursor, args=('forward')) -keyboard.wait() \ No newline at end of file diff --git a/examples/palette.py b/examples/palette.py index d7d90bc..1852c19 100644 --- a/examples/palette.py +++ b/examples/palette.py @@ -2,8 +2,6 @@ import ansi_escape color = 0 print(ansi_escape.escape + "]0;256 Color Terminal Palette" + ansi_escape.bell) while color <= 255: - color = str(color) - print(ansi_escape.color("256", "bg", color) + " " + " " * ( len(color) - 2 ) + color + " ", end="") - color = int(color) + print(ansi_escape.color("bg", color) + " " + " " * ( len(str(color)) - 2 ) + str(color) + " ", end="") color += 1 input() \ No newline at end of file diff --git a/examples/random_cursor_positions.py b/examples/random_cursor_positions.py deleted file mode 100644 index c61b615..0000000 --- a/examples/random_cursor_positions.py +++ /dev/null @@ -1,4 +0,0 @@ -import ansi_escape, random -while 1: - print(ansi_escape.set_cursor(row=str(random.randint(1,20)), column=str(random.randint(1,20))) + ansi_escape.color("normal", "bg", "red") + " " + ansi_escape.reset) - input() \ No newline at end of file diff --git a/examples/simple_colors.py b/examples/simple_colors.py new file mode 100644 index 0000000..458130d --- /dev/null +++ b/examples/simple_colors.py @@ -0,0 +1,10 @@ +import ansi_escape +print(ansi_escape.set("underline")) +print(ansi_escape.color("ul", "bright-black") + "aa") +print(ansi_escape.color("bg", "bright-red") + " ") +print(ansi_escape.color("bg", "bright-green") + " ") +print(ansi_escape.color("bg", "bright-yellow") + " ") +print(ansi_escape.color("bg", "bright-blue") + " ") +print(ansi_escape.color("bg", "bright-magenta") + " ") +print(ansi_escape.color("bg", "bright-cyan") + " ") +print(ansi_escape.color("bg", "bright-white") + " ") \ No newline at end of file diff --git a/examples/size.py b/examples/size.py new file mode 100644 index 0000000..c09293f --- /dev/null +++ b/examples/size.py @@ -0,0 +1,2 @@ +import ansi_escape +print(ansi_escape.esc + "[18t") \ No newline at end of file diff --git a/examples/test.py b/examples/test.py deleted file mode 100644 index 5ebee2d..0000000 --- a/examples/test.py +++ /dev/null @@ -1,13 +0,0 @@ -import ansi_escape -a = 0 -while a < 256: - b = str(a) - print(ansi_escape.color("256", "bg", b) + " " + b + " " + ansi_escape.reset, end='') - a += 1 - -print(ansi_escape.escape + "]0;Demo" + ansi_escape.escape + "\\") -input() -print("hello" + ansi_escape.move_cursor("up", "2")) -input() -print(ansi_escape.erase_from_cursor("forward")) -input() \ No newline at end of file diff --git a/examples/title.py b/examples/title.py new file mode 100644 index 0000000..13849d0 --- /dev/null +++ b/examples/title.py @@ -0,0 +1,3 @@ +import ansi_escape +print(ansi_escape.set_title("hello")) +input() \ No newline at end of file diff --git a/readme.md b/readme.md index 3ef13e9..c09975d 100644 --- a/readme.md +++ b/readme.md @@ -1,9 +1,23 @@ -# ansi_escape -## A pure python3 library for ansi VT-100 escape codes +ansi_escape +=========== +A pure python3 library for ansi VT-100 escape codes +--------------------------------------------------- +See the doc/ folder and ansi_escape.py for documentation (WIP) +See the examples directory for examples/ You need to copy the ansi_escape.py file to the example/ directory to run the examples. +Since this library wraps around text sent to the terminal it only returns strings that need to be put inside a print() statement, example: + +```python +print(ansi_escape.color("fg", "red") + "Hello") +``` +On the positive side that means that you easily can send + output to a file using .write() or write it to the terminal using sys.stdout.write(). +You are not limited by the limitations of print(). Features: - SGR (Select Graphic Rendition) -SGR foreground and background color in 4-bit color, 8-bit color and 24-bit color +--------- +SGR (Select Graphic Rendition) +SGR foreground and background color support with support for 256 8-bit colors and 24-bit true color SGR text formating like; underline, overline and bold text -Easy way to use the bell character -Move cursor -Clear parts of screen or line \ No newline at end of file +Use the bell character +Free cursor movement +Clear parts of screen or line +Toggle keyboard leds \ No newline at end of file