|
1 | 1 | """Main ANSI Escape sequence class""" |
2 | 2 |
|
3 | | -from typing import Any, Iterable, Optional |
| 3 | +from typing import Any, Dict, Iterable, Optional |
4 | 4 |
|
5 | | -__all__ = ('AnsiEscape',) |
| 5 | +__all__ = ('AnsiEscape', 'escape_format',) |
6 | 6 |
|
7 | 7 | _CLEAR: str = '\033[0m' |
8 | 8 |
|
@@ -30,3 +30,50 @@ def __or__(self, other: Any) -> 'AnsiEscape': |
30 | 30 |
|
31 | 31 | def __ror__(self, other: Any) -> 'AnsiEscape': |
32 | 32 | return self.__or__(other) |
| 33 | + |
| 34 | + |
| 35 | +def escape_format(string: str, escape_map: Dict[str, AnsiEscape], case_sensitive: bool=False) -> str: |
| 36 | + """ |
| 37 | + Maps a dictionary of substrings => escape sequences to the given string, |
| 38 | + returning a new string with the sequences applied to all |
| 39 | + found substrings. |
| 40 | +
|
| 41 | + Example: |
| 42 | +
|
| 43 | + COLOURS = { |
| 44 | + 'red': esc.FRED, |
| 45 | + 'green': esc.FGREEN, |
| 46 | + 'yellow': esc.FYELLOW, |
| 47 | + 'blue': esc.FBLUE, |
| 48 | + 'magenta': esc.FMAGENTA, |
| 49 | + 'cyan': esc.FCYAN, |
| 50 | + 'white': esc.FWHITE, |
| 51 | + 'black': esc.FBLACK, |
| 52 | + } |
| 53 | +
|
| 54 | + text = \"\"\"Hello, red world! The sun is bright yellow, and the sky cyan blue. |
| 55 | + Green, lush fields are all around us.\"\"\" |
| 56 | +
|
| 57 | + print(escape_format(text, COLOURS)) # Would print all mapped words in their respective colours |
| 58 | +
|
| 59 | + Inspired by: https://www.reddit.com/r/learnpython/comments/rvcg0l/print_colour_in_terminal/hr73v3f/ |
| 60 | + """ |
| 61 | + |
| 62 | + lines = string.splitlines() |
| 63 | + for line_idx, line in enumerate(lines): |
| 64 | + |
| 65 | + words = line.split(' ') |
| 66 | + for substring, escape in escape_map.items(): |
| 67 | + |
| 68 | + for idx, word in enumerate(words): |
| 69 | + |
| 70 | + if not case_sensitive: |
| 71 | + substring = substring.lower() |
| 72 | + word = word.lower() |
| 73 | + |
| 74 | + if word.startswith(substring): |
| 75 | + words[idx] = f'{escape | word[:len(substring)]}{word[len(substring):]}' |
| 76 | + |
| 77 | + lines[line_idx] = ' '.join(words) |
| 78 | + |
| 79 | + return '\n'.join(lines) |
0 commit comments