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.4.4, created at 2024-04-20 06:09 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-20 06:09 +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(
76 fragments: Iterable[OneStyleAndTextTuple],
77) -> Iterable[StyleAndTextTuples]:
78 """
79 Take a single list of (style_str, text) tuples and yield one such list for each
80 line. Just like str.split, this will yield at least one item.
82 :param fragments: Iterable of ``(style_str, text)`` or
83 ``(style_str, text, mouse_handler)`` tuples.
84 """
85 line: StyleAndTextTuples = []
87 for style, string, *mouse_handler in fragments:
88 parts = string.split("\n")
90 for part in parts[:-1]:
91 if part:
92 line.append(cast(OneStyleAndTextTuple, (style, part, *mouse_handler)))
93 yield line
94 line = []
96 line.append(cast(OneStyleAndTextTuple, (style, parts[-1], *mouse_handler)))
98 # Always yield the last line, even when this is an empty line. This ensures
99 # that when `fragments` ends with a newline character, an additional empty
100 # line is yielded. (Otherwise, there's no way to differentiate between the
101 # cases where `fragments` does and doesn't end with a newline.)
102 yield line