Tokenize a string in to plain text and ANSI codes. Args: ansi_text (str): A String containing ANSI codes. Yields: AnsiToken: A named tuple of (plain, sgr, osc)
(ansi_text: str)
| 26 | |
| 27 | |
| 28 | def _ansi_tokenize(ansi_text: str) -> Iterable[_AnsiToken]: |
| 29 | """Tokenize a string in to plain text and ANSI codes. |
| 30 | |
| 31 | Args: |
| 32 | ansi_text (str): A String containing ANSI codes. |
| 33 | |
| 34 | Yields: |
| 35 | AnsiToken: A named tuple of (plain, sgr, osc) |
| 36 | """ |
| 37 | |
| 38 | position = 0 |
| 39 | sgr: Optional[str] |
| 40 | osc: Optional[str] |
| 41 | for match in re_ansi.finditer(ansi_text): |
| 42 | start, end = match.span(0) |
| 43 | osc, sgr = match.groups() |
| 44 | if start > position: |
| 45 | yield _AnsiToken(ansi_text[position:start]) |
| 46 | if sgr: |
| 47 | if sgr == "(": |
| 48 | position = end + 1 |
| 49 | continue |
| 50 | if sgr.endswith("m"): |
| 51 | yield _AnsiToken("", sgr[1:-1], osc) |
| 52 | else: |
| 53 | yield _AnsiToken("", sgr, osc) |
| 54 | position = end |
| 55 | if position < len(ansi_text): |
| 56 | yield _AnsiToken(ansi_text[position:]) |
| 57 | |
| 58 | |
| 59 | SGR_STYLE_MAP = { |
no test coverage detected