Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/rich/padding.py: 23%
69 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-06-07 06:35 +0000
1from typing import cast, List, Optional, Tuple, TYPE_CHECKING, Union
3if TYPE_CHECKING:
4 from .console import (
5 Console,
6 ConsoleOptions,
7 RenderableType,
8 RenderResult,
9 )
10from .jupyter import JupyterMixin
11from .measure import Measurement
12from .style import Style
13from .segment import Segment
16PaddingDimensions = Union[int, Tuple[int], Tuple[int, int], Tuple[int, int, int, int]]
19class Padding(JupyterMixin):
20 """Draw space around content.
22 Example:
23 >>> print(Padding("Hello", (2, 4), style="on blue"))
25 Args:
26 renderable (RenderableType): String or other renderable.
27 pad (Union[int, Tuple[int]]): Padding for top, right, bottom, and left borders.
28 May be specified with 1, 2, or 4 integers (CSS style).
29 style (Union[str, Style], optional): Style for padding characters. Defaults to "none".
30 expand (bool, optional): Expand padding to fit available width. Defaults to True.
31 """
33 def __init__(
34 self,
35 renderable: "RenderableType",
36 pad: "PaddingDimensions" = (0, 0, 0, 0),
37 *,
38 style: Union[str, Style] = "none",
39 expand: bool = True,
40 ):
41 self.renderable = renderable
42 self.top, self.right, self.bottom, self.left = self.unpack(pad)
43 self.style = style
44 self.expand = expand
46 @classmethod
47 def indent(cls, renderable: "RenderableType", level: int) -> "Padding":
48 """Make padding instance to render an indent.
50 Args:
51 renderable (RenderableType): String or other renderable.
52 level (int): Number of characters to indent.
54 Returns:
55 Padding: A Padding instance.
56 """
58 return Padding(renderable, pad=(0, 0, 0, level), expand=False)
60 @staticmethod
61 def unpack(pad: "PaddingDimensions") -> Tuple[int, int, int, int]:
62 """Unpack padding specified in CSS style."""
63 if isinstance(pad, int):
64 return (pad, pad, pad, pad)
65 if len(pad) == 1:
66 _pad = pad[0]
67 return (_pad, _pad, _pad, _pad)
68 if len(pad) == 2:
69 pad_top, pad_right = cast(Tuple[int, int], pad)
70 return (pad_top, pad_right, pad_top, pad_right)
71 if len(pad) == 4:
72 top, right, bottom, left = cast(Tuple[int, int, int, int], pad)
73 return (top, right, bottom, left)
74 raise ValueError(f"1, 2 or 4 integers required for padding; {len(pad)} given")
76 def __repr__(self) -> str:
77 return f"Padding({self.renderable!r}, ({self.top},{self.right},{self.bottom},{self.left}))"
79 def __rich_console__(
80 self, console: "Console", options: "ConsoleOptions"
81 ) -> "RenderResult":
82 style = console.get_style(self.style)
83 if self.expand:
84 width = options.max_width
85 else:
86 width = min(
87 Measurement.get(console, options, self.renderable).maximum
88 + self.left
89 + self.right,
90 options.max_width,
91 )
92 render_options = options.update_width(width - self.left - self.right)
93 if render_options.height is not None:
94 render_options = render_options.update_height(
95 height=render_options.height - self.top - self.bottom
96 )
97 lines = console.render_lines(
98 self.renderable, render_options, style=style, pad=True
99 )
100 _Segment = Segment
102 left = _Segment(" " * self.left, style) if self.left else None
103 right = (
104 [_Segment(f'{" " * self.right}', style), _Segment.line()]
105 if self.right
106 else [_Segment.line()]
107 )
108 blank_line: Optional[List[Segment]] = None
109 if self.top:
110 blank_line = [_Segment(f'{" " * width}\n', style)]
111 yield from blank_line * self.top
112 if left:
113 for line in lines:
114 yield left
115 yield from line
116 yield from right
117 else:
118 for line in lines:
119 yield from line
120 yield from right
121 if self.bottom:
122 blank_line = blank_line or [_Segment(f'{" " * width}\n', style)]
123 yield from blank_line * self.bottom
125 def __rich_measure__(
126 self, console: "Console", options: "ConsoleOptions"
127 ) -> "Measurement":
128 max_width = options.max_width
129 extra_width = self.left + self.right
130 if max_width - extra_width < 1:
131 return Measurement(max_width, max_width)
132 measure_min, measure_max = Measurement.get(console, options, self.renderable)
133 measurement = Measurement(measure_min + extra_width, measure_max + extra_width)
134 measurement = measurement.with_maximum(max_width)
135 return measurement
138if __name__ == "__main__": # pragma: no cover
139 from rich import print
141 print(Padding("Hello, World", (2, 4), style="on blue"))