Skip to content

Commit b5cc473

Browse files
authored
Add files via upload
1 parent 3dc56ac commit b5cc473

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

termicol/__init__.py

Whitespace-only changes.

termicol/termicol.py

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
#Imports
2+
from re import findall as refindall
3+
4+
5+
6+
7+
#Variables
8+
__Colors = {
9+
'white' : (255, 255, 255),
10+
'grey' : (125, 125, 125),
11+
'black' : (0, 0, 0),
12+
'red' : (200, 0, 0),
13+
'green' : (0, 200, 0),
14+
'blue': (0, 0, 200),
15+
'purple': (200, 0, 200),
16+
'yellow' : (200, 200, 0),
17+
'orange' : (200, 100, 0),
18+
19+
'brightred' : (255, 0, 0),
20+
'brightgreen' : (0, 255, 0),
21+
'brightblue': (0, 0, 255),
22+
'brightpurple': (255, 0, 255),
23+
'brightyellow' : (255, 255, 0),
24+
'brightorange' : (255, 175, 0),
25+
26+
'lightgrey' : (200, 200, 200),
27+
'lightred' : (200, 100, 100),
28+
'lightgreen' : (100, 200, 100),
29+
'lightblue': (100, 100, 200),
30+
'lightpurple': (200, 100, 200),
31+
'lightyellow' : (200, 200, 100),
32+
'lightorange' : (200, 150, 100),
33+
34+
'darkgrey' : (10, 10, 10),
35+
'darkred' : (100, 0, 0),
36+
'darkgreen' : (0, 100, 0),
37+
'darkblue': (0, 0, 100),
38+
'darkpurple': (100, 0, 100),
39+
'darkyellow' : (100, 100, 0),
40+
'darkorange' : (100, 50, 0),
41+
}
42+
43+
__Decorations = {
44+
'bold' : '1',
45+
'italic' : '3',
46+
'underline' : '4',
47+
'inverted' : '7',
48+
'doubleunderline' : '21'
49+
}
50+
51+
__Codes = {
52+
'textcolor' : ['<t', '<textcolor'],
53+
'backgroundcolor' : ['<b', '<bgcolor', '<backgroundcolor'],
54+
'decorations' : ['<d', '<deco', '<decorations']
55+
}
56+
57+
58+
59+
60+
61+
62+
#Private Functions
63+
def __validateRGB(rgb: tuple, content: str) -> None:
64+
if type(rgb) != tuple: raise SystemExit(f'The rgb value "{rgb}" is not a tuple at "{content}".')
65+
if len(rgb) < 3: raise SystemExit(f'The rgb value "{rgb}" does not contain all needed values at "{content}".')
66+
if len(rgb) > 3: raise SystemExit(f'The rgb value "{rgb}" contains too many values at "{content}".')
67+
if any([True for i in rgb if not type(i) is int]): raise SystemExit(f'The rgb value "{rgb}" contains a non integer value at "{content}".')
68+
if any([True for i in rgb if i < 0 or i > 255]): raise SystemExit(f'The rgb value "{rgb}" contains a value that is out of bounds for an rgb value at "{content}".')
69+
70+
71+
72+
def __validateDecoration(deco: str, content: str) -> None:
73+
global __Decorations
74+
if deco not in __Decorations: raise SystemExit(f'The decoration {deco} provided is not a valid decoration at "{content}".')
75+
76+
77+
78+
def __createColor(rgb: tuple, content: str) -> str:
79+
__validateRGB(rgb, content)
80+
red = str(rgb[0])
81+
green = str(rgb[1])
82+
blue = str(rgb[2])
83+
84+
return red + ';' + green + ';' + blue
85+
86+
87+
88+
def __constructEscapeString(textColor: str, backgroundColor: str = '', decorations: list = []) -> str:
89+
escapeString = '\033[38;2;' + textColor
90+
if backgroundColor: escapeString += ';48;2;' + backgroundColor
91+
for decoration in decorations: escapeString += ';' + decoration
92+
return escapeString + 'm'
93+
94+
95+
96+
def __mergeList(a: list, b: list):
97+
newlist = []
98+
for i in range(min(len(a), len(b))): newlist += [a[i], b[i]]
99+
if len(a) < len(b): return newlist + b[min(len(a), len(b)):]
100+
return newlist + a[min(len(a), len(b)):]
101+
102+
103+
104+
def __parseContent(content: str):
105+
if not content.endswith('<r>'): content += '<r>'
106+
codes = [f'<{i}>' for i in refindall(r'\<(.*?)\>', content)]
107+
if codes: text = refindall(r'\>(.*?)\<', content)
108+
mergedList = __mergeList(codes, text)
109+
while '' in mergedList: mergedList.remove('')
110+
return mergedList
111+
112+
113+
114+
def __convertParsedContent(content: list):
115+
global __Codes
116+
global __Colors
117+
118+
textColor = ''
119+
bgColor = ''
120+
decorations = []
121+
122+
newcontent = []
123+
for i in range(len(content)):
124+
if '<r' in content[i]:
125+
if content[i] == '<r>':
126+
textColor = ''
127+
bgColor = ''
128+
decorations = []
129+
else:
130+
reset = content[i].split('=')[1].replace('>','')
131+
if 't' in reset: textColor = ''
132+
if 'b' in reset: bgColor = ''
133+
if 'd' in reset: decorations = []
134+
newcontent.append('\033[0m')
135+
136+
elif any([True for code in __Codes['textcolor'] if code in content[i]]):
137+
color = content[i].split('=')[1].replace('>','')
138+
if color in __Colors: textColor = __createColor(__Colors[color], content[i])
139+
else:
140+
color = color.split(',')
141+
try: color = tuple([int(i) for i in color])
142+
except Exception as exception: raise SystemExit(f'{exception}\n\n"{content[i]}" Has caused this issue with an invalid value being passed.')
143+
textColor = __createColor(color, content[i])
144+
145+
elif any(True for code in __Codes['backgroundcolor'] if code in content[i]):
146+
color = content[i].split('=')[1].replace('>','')
147+
if color in __Colors: bgColor = __createColor(__Colors[color], content[i])
148+
else:
149+
color = color.split(',')
150+
try: color = tuple([int(i) for i in color])
151+
except Exception as exception: raise SystemExit(f'{exception}\n\n"{content[i]}" Has caused this issue with an invalid value being passed.')
152+
bgColor = __createColor(color, content[i])
153+
154+
elif any(True for code in __Codes['decorations'] if code in content[i]):
155+
deco = content[i].split('=')[1].replace('>','')
156+
if ',' in deco: deco.split(',')
157+
else: deco = [deco]
158+
for d in deco: __validateDecoration(d, content[i])
159+
decorations = [__Decorations[d] for d in deco]
160+
161+
else:
162+
newcontent.append(__constructEscapeString(textColor, bgColor, decorations))
163+
newcontent.append(content[i])
164+
165+
return ''.join(newcontent)
166+
167+
168+
169+
170+
171+
172+
#Public Functions
173+
def showColorList() -> None:
174+
'''
175+
Prints off list of valid arguments for color.
176+
'''
177+
global __Colors
178+
for color in __Colors: print(color)
179+
180+
181+
182+
def showDecorationList() -> None:
183+
'''
184+
Prints off list of valid arguments for decoration.
185+
'''
186+
global __Decorations
187+
for decoration in __Decorations: print(decoration)
188+
189+
190+
191+
192+
193+
194+
#Primary Function
195+
def tprint(content: str, end = '\n') -> None:
196+
'''
197+
Sends content to python's print function after additional parsing and reconstructing.
198+
'''
199+
print(__convertParsedContent(__parseContent(content)), end = end)

0 commit comments

Comments
 (0)