Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/formatted_text/utils.py: 37%
27 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:07 +0000
1"""
2Utilities for manipulating formatted text.
4When ``to_formatted_text`` has been called, we get a list of ``(style, text)``
5tuples. This file contains functions for manipulating such a list.
6"""
7from __future__ import annotations
9from typing import Iterable, cast
11from prompt_toolkit.utils import get_cwidth
13from .base import (
14 AnyFormattedText,
15 OneStyleAndTextTuple,
16 StyleAndTextTuples,
17 to_formatted_text,
18)
20__all__ = [
21 "to_plain_text",
22 "fragment_list_len",
23 "fragment_list_width",
24 "fragment_list_to_text",
25 "split_lines",
26]
29def to_plain_text(value: AnyFormattedText) -> str:
30 """
31 Turn any kind of formatted text back into plain text.
32 """
33 return fragment_list_to_text(to_formatted_text(value))
36def fragment_list_len(fragments: StyleAndTextTuples) -> int:
37 """
38 Return the amount of characters in this text fragment list.
40 :param fragments: List of ``(style_str, text)`` or
41 ``(style_str, text, mouse_handler)`` tuples.
42 """
43 ZeroWidthEscape = "[ZeroWidthEscape]"
44 return sum(len(item[1]) for item in fragments if ZeroWidthEscape not in item[0])
47def fragment_list_width(fragments: StyleAndTextTuples) -> int:
48 """
49 Return the character width of this text fragment list.
50 (Take double width characters into account.)
52 :param fragments: List of ``(style_str, text)`` or
53 ``(style_str, text, mouse_handler)`` tuples.
54 """
55 ZeroWidthEscape = "[ZeroWidthEscape]"
56 return sum(
57 get_cwidth(c)
58 for item in fragments
59 for c in item[1]
60 if ZeroWidthEscape not in item[0]
61 )
64def fragment_list_to_text(fragments: StyleAndTextTuples) -> str:
65 """
66 Concatenate all the text parts again.
68 :param fragments: List of ``(style_str, text)`` or
69 ``(style_str, text, mouse_handler)`` tuples.
70 """
71 ZeroWidthEscape = "[ZeroWidthEscape]"
72 return "".join(item[1] for item in fragments if ZeroWidthEscape not in item[0])
75def split_lines(fragments: StyleAndTextTuples) -> Iterable[StyleAndTextTuples]:
76 """
77 Take a single list of (style_str, text) tuples and yield one such list for each
78 line. Just like str.split, this will yield at least one item.
80 :param fragments: List of (style_str, text) or (style_str, text, mouse_handler)
81 tuples.
82 """
83 line: StyleAndTextTuples = []
85 for style, string, *mouse_handler in fragments:
86 parts = string.split("\n")
88 for part in parts[:-1]:
89 if part:
90 line.append(cast(OneStyleAndTextTuple, (style, part, *mouse_handler)))
91 yield line
92 line = []
94 line.append(cast(OneStyleAndTextTuple, (style, parts[-1], *mouse_handler)))
96 # Always yield the last line, even when this is an empty line. This ensures
97 # that when `fragments` ends with a newline character, an additional empty
98 # line is yielded. (Otherwise, there's no way to differentiate between the
99 # cases where `fragments` does and doesn't end with a newline.)
100 yield line