|
64 | 64 | # Distributed under the BSD 3-Clause license.
|
65 | 65 | #
|
66 | 66 |
|
67 |
| -# stdlib |
68 |
| -import re |
69 |
| -from abc import ABC |
70 |
| -from typing import List, Pattern |
71 | 67 |
|
72 |
| -# 3rd party |
73 |
| -from colorama import init # type: ignore |
74 |
| -from typing_extensions import Final |
| 68 | +from consolekit.terminal_colours import ( |
| 69 | + CSI, |
| 70 | + OSC, |
| 71 | + BEL, |
| 72 | + code_to_chars, |
| 73 | + set_title, |
| 74 | + clear_line, |
| 75 | + Colour, |
| 76 | + AnsiCodes, |
| 77 | + AnsiCursor, |
| 78 | + AnsiFore, |
| 79 | + AnsiBack, |
| 80 | + AnsiStyle, |
| 81 | + Fore, |
| 82 | + Back, |
| 83 | + Style, |
| 84 | + Cursor, |
| 85 | + strip_ansi, |
| 86 | + fore_stack, |
| 87 | + back_stack, |
| 88 | + style_stack, |
| 89 | + ) |
75 | 90 |
|
76 | 91 | __all__ = [
|
77 | 92 | "CSI",
|
|
94 | 109 | "strip_ansi",
|
95 | 110 | ]
|
96 | 111 |
|
97 |
| -init() |
98 |
| - |
99 |
| -CSI: Final[str] = "\033[" |
100 |
| -OSC: Final[str] = "\033]" |
101 |
| -BEL: Final[str] = "\a" |
102 |
| - |
103 |
| -fore_stack: List[str] = [] |
104 |
| -back_stack: List[str] = [] |
105 |
| -style_stack: List[str] = [] |
106 |
| - |
107 |
| - |
108 |
| -def code_to_chars(code) -> str: |
109 |
| - return CSI + str(code) + 'm' |
110 |
| - |
111 |
| - |
112 |
| -def set_title(title: str) -> str: |
113 |
| - return OSC + "2;" + title + BEL |
114 |
| - |
115 | 112 |
|
116 | 113 | def clear_screen(mode: int = 2) -> str:
|
117 | 114 | return CSI + str(mode) + 'J'
|
118 |
| - |
119 |
| - |
120 |
| -def clear_line(mode: int = 2) -> str: |
121 |
| - return CSI + str(mode) + 'K' |
122 |
| - |
123 |
| - |
124 |
| -_ansi_re: Pattern[str] = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") |
125 |
| - |
126 |
| - |
127 |
| -def strip_ansi(value: str) -> str: |
128 |
| - """ |
129 |
| - Strip ANSI colour codes from the given string to return a plaintext output. |
130 |
| -
|
131 |
| - :param value: |
132 |
| -
|
133 |
| - :rtype: |
134 |
| -
|
135 |
| - .. versionadded:: 1.1.0 |
136 |
| - """ |
137 |
| - |
138 |
| - return _ansi_re.sub('', value) |
139 |
| - |
140 |
| - |
141 |
| -class Colour(str): |
142 |
| - r""" |
143 |
| - An ANSI escape sequence representing a colour. |
144 |
| -
|
145 |
| - The colour can be used as a context manager, a string, or a function. |
146 |
| -
|
147 |
| - :param style: Escape sequence representing the style. |
148 |
| - :type style: :class:`str` |
149 |
| - :param stack: The stack to place the escape sequence on. |
150 |
| - :type stack: :class:`~typing.List`\[:class:`str`\] |
151 |
| - :param reset: The escape sequence to reset the style. |
152 |
| - :type reset: :class:`str` |
153 |
| - """ |
154 |
| - |
155 |
| - style: str |
156 |
| - reset: str |
157 |
| - stack: List[str] |
158 |
| - |
159 |
| - def __new__(cls, style: str, stack: List[str], reset: str) -> "Colour": # noqa D102 |
160 |
| - color = super().__new__(cls, style) # type: ignore |
161 |
| - color.style = style |
162 |
| - color.stack = stack |
163 |
| - color.reset = reset |
164 |
| - |
165 |
| - return color |
166 |
| - |
167 |
| - def __enter__(self) -> None: |
168 |
| - print(self.style, end='') |
169 |
| - self.stack.append(self.style) |
170 |
| - |
171 |
| - def __exit__(self, exc_type, exc_val, exc_tb) -> None: |
172 |
| - if self.style == self.stack[-1]: |
173 |
| - self.stack.pop() |
174 |
| - print(self.stack[-1], end='') |
175 |
| - |
176 |
| - def __call__(self, text) -> str: |
177 |
| - """ |
178 |
| - Returns the given text in this colour. |
179 |
| - """ |
180 |
| - |
181 |
| - return f"{self}{text}{self.reset}" |
182 |
| - |
183 |
| - |
184 |
| -class AnsiCodes(ABC): |
185 |
| - """ |
186 |
| - Abstract base class for ANSI Codes. |
187 |
| - """ |
188 |
| - |
189 |
| - _stack: List[str] |
190 |
| - _reset: str |
191 |
| - |
192 |
| - def __init__(self) -> None: |
193 |
| - """ |
194 |
| - The subclasses declare class attributes which are numbers. |
195 |
| -
|
196 |
| - Upon instantiation we define instance attributes, which are the same |
197 |
| - as the class attributes but wrapped with the ANSI escape sequence. |
198 |
| - """ |
199 |
| - |
200 |
| - for name in dir(self): |
201 |
| - if not name.startswith('_'): |
202 |
| - value = getattr(self, name) |
203 |
| - setattr(self, name, Colour(code_to_chars(value), self._stack, self._reset)) |
204 |
| - |
205 |
| - |
206 |
| -class AnsiCursor: |
207 |
| - |
208 |
| - def UP(self, n: int = 1) -> str: |
209 |
| - """ |
210 |
| -
|
211 |
| - :param n: |
212 |
| - """ |
213 |
| - |
214 |
| - return f"{CSI}{str(n)}A" |
215 |
| - |
216 |
| - def DOWN(self, n: int = 1) -> str: |
217 |
| - """ |
218 |
| -
|
219 |
| - :param n: |
220 |
| - """ |
221 |
| - |
222 |
| - return f"{CSI}{str(n)}B" |
223 |
| - |
224 |
| - def FORWARD(self, n: int = 1) -> str: |
225 |
| - """ |
226 |
| -
|
227 |
| - :param n: |
228 |
| - """ |
229 |
| - |
230 |
| - return f"{CSI}{str(n)}C" |
231 |
| - |
232 |
| - def BACK(self, n: int = 1) -> str: |
233 |
| - """ |
234 |
| -
|
235 |
| - :param n: |
236 |
| - """ |
237 |
| - |
238 |
| - return f"{CSI}{str(n)}D" |
239 |
| - |
240 |
| - def POS(self, x: int = 1, y: int = 1) -> str: |
241 |
| - """ |
242 |
| -
|
243 |
| - :param x: |
244 |
| - :param y: |
245 |
| - """ |
246 |
| - |
247 |
| - return f"{CSI}{str(y)};{str(x)}H" |
248 |
| - |
249 |
| - |
250 |
| -class AnsiFore(AnsiCodes): |
251 |
| - """ |
252 |
| - ANSI Colour Codes for foreground colour. |
253 |
| -
|
254 |
| - The colours can be used as a context manager, a string, or a function. |
255 |
| -
|
256 |
| - Valid values are: |
257 |
| -
|
258 |
| - * BLACK |
259 |
| - * RED |
260 |
| - * GREEN |
261 |
| - * YELLOW |
262 |
| - * BLUE |
263 |
| - * MAGENTA |
264 |
| - * CYAN |
265 |
| - * WHITE |
266 |
| - * RESET |
267 |
| - * LIGHTBLACK_EX |
268 |
| - * LIGHTRED_EX |
269 |
| - * LIGHTGREEN_EX |
270 |
| - * LIGHTYELLOW_EX |
271 |
| - * LIGHTBLUE_EX |
272 |
| - * LIGHTMAGENTA_EX |
273 |
| - * LIGHTCYAN_EX |
274 |
| - * LIGHTWHITE_EX |
275 |
| - """ |
276 |
| - |
277 |
| - _stack = fore_stack |
278 |
| - _reset = "\033[39m" |
279 |
| - |
280 |
| - BLACK = 30 |
281 |
| - RED = 31 |
282 |
| - GREEN = 32 |
283 |
| - YELLOW = 33 |
284 |
| - BLUE = 34 |
285 |
| - MAGENTA = 35 |
286 |
| - CYAN = 36 |
287 |
| - WHITE = 37 |
288 |
| - RESET = 39 |
289 |
| - |
290 |
| - # These are fairly well supported, but not part of the standard. |
291 |
| - LIGHTBLACK_EX = 90 |
292 |
| - LIGHTRED_EX = 91 |
293 |
| - LIGHTGREEN_EX = 92 |
294 |
| - LIGHTYELLOW_EX = 93 |
295 |
| - LIGHTBLUE_EX = 94 |
296 |
| - LIGHTMAGENTA_EX = 95 |
297 |
| - LIGHTCYAN_EX = 96 |
298 |
| - LIGHTWHITE_EX = 97 |
299 |
| - |
300 |
| - |
301 |
| -class AnsiBack(AnsiCodes): |
302 |
| - """ |
303 |
| - ANSI Colour Codes for background colour. |
304 |
| -
|
305 |
| - The colours can be used as a context manager, a string, or a function. |
306 |
| -
|
307 |
| - Valid values are: |
308 |
| -
|
309 |
| - * BLACK |
310 |
| - * RED |
311 |
| - * GREEN |
312 |
| - * YELLOW |
313 |
| - * BLUE |
314 |
| - * MAGENTA |
315 |
| - * CYAN |
316 |
| - * WHITE |
317 |
| - * RESET |
318 |
| - * LIGHTBLACK_EX |
319 |
| - * LIGHTRED_EX |
320 |
| - * LIGHTGREEN_EX |
321 |
| - * LIGHTYELLOW_EX |
322 |
| - * LIGHTBLUE_EX |
323 |
| - * LIGHTMAGENTA_EX |
324 |
| - * LIGHTCYAN_EX |
325 |
| - * LIGHTWHITE_EX |
326 |
| - """ |
327 |
| - |
328 |
| - _stack = back_stack |
329 |
| - _reset = "\033[49m" |
330 |
| - |
331 |
| - BLACK = 40 |
332 |
| - RED = 41 |
333 |
| - GREEN = 42 |
334 |
| - YELLOW = 43 |
335 |
| - BLUE = 44 |
336 |
| - MAGENTA = 45 |
337 |
| - CYAN = 46 |
338 |
| - WHITE = 47 |
339 |
| - RESET = 49 |
340 |
| - |
341 |
| - # These are fairly well supported, but not part of the standard. |
342 |
| - LIGHTBLACK_EX = 100 |
343 |
| - LIGHTRED_EX = 101 |
344 |
| - LIGHTGREEN_EX = 102 |
345 |
| - LIGHTYELLOW_EX = 103 |
346 |
| - LIGHTBLUE_EX = 104 |
347 |
| - LIGHTMAGENTA_EX = 105 |
348 |
| - LIGHTCYAN_EX = 106 |
349 |
| - LIGHTWHITE_EX = 107 |
350 |
| - |
351 |
| - |
352 |
| -class AnsiStyle(AnsiCodes): |
353 |
| - """ |
354 |
| - ANSI Colour Codes for text style. |
355 |
| -
|
356 |
| - Valid values are: |
357 |
| -
|
358 |
| - * BRIGHT |
359 |
| - * DIM |
360 |
| - * NORMAL |
361 |
| -
|
362 |
| - Additionally, ``AnsiStyle.RESET_ALL`` can be used to reset the |
363 |
| - foreground and background colours as well as the text style. |
364 |
| - """ |
365 |
| - |
366 |
| - _stack = style_stack |
367 |
| - _reset = "\033[22m" |
368 |
| - |
369 |
| - BRIGHT = 1 |
370 |
| - DIM = 2 |
371 |
| - NORMAL = 22 |
372 |
| - RESET_ALL = 0 |
373 |
| - |
374 |
| - |
375 |
| -Fore = AnsiFore() |
376 |
| -Back = AnsiBack() |
377 |
| -Style = AnsiStyle() |
378 |
| -Cursor = AnsiCursor() |
379 |
| - |
380 |
| -fore_stack.append(Fore.RESET) |
381 |
| -back_stack.append(Back.RESET) |
382 |
| -style_stack.append(Style.NORMAL) |
0 commit comments