more functions and documentation

This commit is contained in:
filip 2021-03-12 22:33:18 +01:00
parent 8ddd20203d
commit 6f2547eb1f
21 changed files with 582 additions and 117 deletions

View File

@ -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[" return_string = "\u001b["
try: 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: except:
pass pass
return_string += ";" return_string += ";"
try: try:
return_string += coordinates["column"] return_string += args["bottom"]
except: except:
pass 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_string += "H"
return return_string return return_string
set_cursor = cursor_position #set_cursor = cursor_position
cup = cursor_position cup = cursor_position
def move_cursor(direction, *cells): 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: try:
return_string += cells[0] return_string += str(cells[0]) #cells is optional therefore it is in a try statement
except: except:
pass pass #if no argument is supplied it defaults to 1
a = {
a = { #human redable names for directions to move the cursor
"up": "A", "up": "A",
"down": "B", "down": "B",
"forward": "C", "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 return return_string
def erase_in_display(direction): 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[" return_string = "\u001b["
a = { a = {
"forward": "0", "forward": "0",
@ -53,92 +324,136 @@ erase_in_display_from_cursor = erase_in_display
ed = erase_in_display ed = erase_in_display
def erase_in_line(direction): 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[" return_string = "\u001b["
a = { a = { #human readable names
"forward": "0", "forward": "0",
"right": "0",
"backward": "1", "backward": "1",
"left": "1",
"both": "2" "both": "2"
} }
try: try:
return_string += a[direction] return_string += a[direction] #replaces the human readable name with mthe machine readable number
except: except:
return_string += direction return_string += str(direction) #makes it posible to use numbers 0-2 instead
return_string += "K" return_string += "K"
return return_string return return_string
erase_in_line_from_cursor = erase_in_line erase_in_line_from_cursor = erase_in_line
el = erase_in_line el = erase_in_line
def color(mode, ground, *args): def color(ground, *args):
return_string = "\u001b[" """
if mode == "bright": Color is complicated:
return_string += "1;" See: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
mode = "normal"
if ground == "fg": 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": #sets text color aka foreground color
return_string += "3" return_string += "3"
elif ground == "bg": elif ground == "bg": #sets background color
return_string += "4" return_string += "4"
if mode == "256": if len(args) == 1:
return_string += "8;5;" return_string += "8;5;" #SGR code for 8-bit 256 color support
return_string += args[0] color_chart = { #human readable color names instead of 0-7
return_string += "m" "black": 0,
return return_string "red": 1,
"green": 2,
elif mode == "rgb": "yellow": 3,
return_string += "8;2;" "blue": 4,
return_string = return_string + args[0] + ";" + args[1] + ";" +args[2] "magenta": 5,
return_string += "m" "cyan": 6,
return return_string "white": 7
elif mode == "normal":
color_chart = {
"black": "0",
"red": "1",
"green": "2",
"yellow": "3",
"blue": "4",
"magenta": "5",
"cyan": "6",
"white": "7"
} }
a = color_chart[args[0]] color = args[0]
return_string += a
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_string += "m"
return return_string return return_string
bell = "\u0007" bell = "\u0007"
backspace = "\u0008" backspace = "\u0008"
bs = backspace
escape = "\u001b" escape = "\u001b"
esc = escape esc = escape
csi = escape + "[" csi = escape + "["
reset = csi + "0m" """
normal = reset Device Status Report (DSR)
reset_formatting = reset 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" decaln = esc + "#8" #fills screen with E
faint = csi +"2m" decid = esc + "Z"
underline = csi + "4m"
blink = csi + "5m"
invert = csi + "7m" save_cursor = esc + "7"
reverse_video = invert decsc = save_cursor
strike = csi + "9m" restore_cursor = esc + "8"
crossed_out = strike decrc = restore_cursor
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"

49
doc/color.md Normal file
View File

@ -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")
```

49
doc/cursor.md Normal file
View File

@ -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.

38
doc/delete.md Normal file
View File

@ -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.
<!---Example:
0|1|2|3|4|5|6|7|8|9|10
:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:--
h|e|l|l|o|{cursor}|w|o|r|l|d
Here the cursor is on cell 5, if you where to run--->
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.

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
/home/filip/Documents/python3/ansi_escape/ansi_escape.py

7
examples/backspace.py Normal file
View File

@ -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)

5
examples/bell.py Normal file
View File

@ -0,0 +1,5 @@
import ansi_escape
print(ansi_escape.bell_f(10000))
a = 10
while a < 10:
print(ansi_escape.bell)

View File

@ -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"))

2
examples/dsr.py Normal file
View File

@ -0,0 +1,2 @@
import ansi_escape, sys
print(ansi_escape.cup(column=23, row=22) + ansi_escape.dsr)

View File

@ -1,2 +0,0 @@
import ansi_escape, os
print(ansi_escape.erase_from_cursor("2"))

View File

@ -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"))

3
examples/keyboard.py Normal file
View File

@ -0,0 +1,3 @@
import ansi_escape
print(ansi_escape.set_leds("reset"))
input()

View File

@ -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()

View File

@ -2,8 +2,6 @@ import ansi_escape
color = 0 color = 0
print(ansi_escape.escape + "]0;256 Color Terminal Palette" + ansi_escape.bell) print(ansi_escape.escape + "]0;256 Color Terminal Palette" + ansi_escape.bell)
while color <= 255: while color <= 255:
color = str(color) print(ansi_escape.color("bg", color) + " " + " " * ( len(str(color)) - 2 ) + str(color) + " ", end="")
print(ansi_escape.color("256", "bg", color) + " " + " " * ( len(color) - 2 ) + color + " ", end="")
color = int(color)
color += 1 color += 1
input() input()

View File

@ -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()

10
examples/simple_colors.py Normal file
View File

@ -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") + " ")

2
examples/size.py Normal file
View File

@ -0,0 +1,2 @@
import ansi_escape
print(ansi_escape.esc + "[18t")

View File

@ -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()

3
examples/title.py Normal file
View File

@ -0,0 +1,3 @@
import ansi_escape
print(ansi_escape.set_title("hello"))
input()

View File

@ -1,9 +1,23 @@
# ansi_escape ansi_escape
## A pure python3 library for ansi VT-100 escape codes ===========
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: Features:
---------
SGR (Select Graphic Rendition) SGR (Select Graphic Rendition)
SGR foreground and background color in 4-bit color, 8-bit color and 24-bit color 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 SGR text formating like; underline, overline and bold text
Easy way to use the bell character Use the bell character
Move cursor Free cursor movement
Clear parts of screen or line Clear parts of screen or line
Toggle keyboard leds