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