Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/rich/rule.py: 45%

69 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:07 +0000

1from typing import Union 

2 

3from .align import AlignMethod 

4from .cells import cell_len, set_cell_size 

5from .console import Console, ConsoleOptions, RenderResult 

6from .jupyter import JupyterMixin 

7from .measure import Measurement 

8from .style import Style 

9from .text import Text 

10 

11 

12class Rule(JupyterMixin): 

13 """A console renderable to draw a horizontal rule (line). 

14 

15 Args: 

16 title (Union[str, Text], optional): Text to render in the rule. Defaults to "". 

17 characters (str, optional): Character(s) used to draw the line. Defaults to "─". 

18 style (StyleType, optional): Style of Rule. Defaults to "rule.line". 

19 end (str, optional): Character at end of Rule. defaults to "\\\\n" 

20 align (str, optional): How to align the title, one of "left", "center", or "right". Defaults to "center". 

21 """ 

22 

23 def __init__( 

24 self, 

25 title: Union[str, Text] = "", 

26 *, 

27 characters: str = "─", 

28 style: Union[str, Style] = "rule.line", 

29 end: str = "\n", 

30 align: AlignMethod = "center", 

31 ) -> None: 

32 if cell_len(characters) < 1: 

33 raise ValueError( 

34 "'characters' argument must have a cell width of at least 1" 

35 ) 

36 if align not in ("left", "center", "right"): 

37 raise ValueError( 

38 f'invalid value for align, expected "left", "center", "right" (not {align!r})' 

39 ) 

40 self.title = title 

41 self.characters = characters 

42 self.style = style 

43 self.end = end 

44 self.align = align 

45 

46 def __repr__(self) -> str: 

47 return f"Rule({self.title!r}, {self.characters!r})" 

48 

49 def __rich_console__( 

50 self, console: Console, options: ConsoleOptions 

51 ) -> RenderResult: 

52 width = options.max_width 

53 

54 characters = ( 

55 "-" 

56 if (options.ascii_only and not self.characters.isascii()) 

57 else self.characters 

58 ) 

59 

60 chars_len = cell_len(characters) 

61 if not self.title: 

62 yield self._rule_line(chars_len, width) 

63 return 

64 

65 if isinstance(self.title, Text): 

66 title_text = self.title 

67 else: 

68 title_text = console.render_str(self.title, style="rule.text") 

69 

70 title_text.plain = title_text.plain.replace("\n", " ") 

71 title_text.expand_tabs() 

72 

73 required_space = 4 if self.align == "center" else 2 

74 truncate_width = max(0, width - required_space) 

75 if not truncate_width: 

76 yield self._rule_line(chars_len, width) 

77 return 

78 

79 rule_text = Text(end=self.end) 

80 if self.align == "center": 

81 title_text.truncate(truncate_width, overflow="ellipsis") 

82 side_width = (width - cell_len(title_text.plain)) // 2 

83 left = Text(characters * (side_width // chars_len + 1)) 

84 left.truncate(side_width - 1) 

85 right_length = width - cell_len(left.plain) - cell_len(title_text.plain) 

86 right = Text(characters * (side_width // chars_len + 1)) 

87 right.truncate(right_length) 

88 rule_text.append(left.plain + " ", self.style) 

89 rule_text.append(title_text) 

90 rule_text.append(" " + right.plain, self.style) 

91 elif self.align == "left": 

92 title_text.truncate(truncate_width, overflow="ellipsis") 

93 rule_text.append(title_text) 

94 rule_text.append(" ") 

95 rule_text.append(characters * (width - rule_text.cell_len), self.style) 

96 elif self.align == "right": 

97 title_text.truncate(truncate_width, overflow="ellipsis") 

98 rule_text.append(characters * (width - title_text.cell_len - 1), self.style) 

99 rule_text.append(" ") 

100 rule_text.append(title_text) 

101 

102 rule_text.plain = set_cell_size(rule_text.plain, width) 

103 yield rule_text 

104 

105 def _rule_line(self, chars_len: int, width: int) -> Text: 

106 rule_text = Text(self.characters * ((width // chars_len) + 1), self.style) 

107 rule_text.truncate(width) 

108 rule_text.plain = set_cell_size(rule_text.plain, width) 

109 return rule_text 

110 

111 def __rich_measure__( 

112 self, console: Console, options: ConsoleOptions 

113 ) -> Measurement: 

114 return Measurement(1, 1) 

115 

116 

117if __name__ == "__main__": # pragma: no cover 

118 import sys 

119 

120 from rich.console import Console 

121 

122 try: 

123 text = sys.argv[1] 

124 except IndexError: 

125 text = "Hello, World" 

126 console = Console() 

127 console.print(Rule(title=text)) 

128 

129 console = Console() 

130 console.print(Rule("foo"), width=4)