__main__.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import colorsys
  2. import io
  3. from time import process_time
  4. from rich import box
  5. from rich.color import Color
  6. from rich.console import Console, ConsoleOptions, Group, RenderableType, RenderResult
  7. from rich.markdown import Markdown
  8. from rich.measure import Measurement
  9. from rich.pretty import Pretty
  10. from rich.segment import Segment
  11. from rich.style import Style
  12. from rich.syntax import Syntax
  13. from rich.table import Table
  14. from rich.text import Text
  15. class ColorBox:
  16. def __rich_console__(
  17. self, console: Console, options: ConsoleOptions
  18. ) -> RenderResult:
  19. for y in range(0, 5):
  20. for x in range(options.max_width):
  21. h = x / options.max_width
  22. l = 0.1 + ((y / 5) * 0.7)
  23. r1, g1, b1 = colorsys.hls_to_rgb(h, l, 1.0)
  24. r2, g2, b2 = colorsys.hls_to_rgb(h, l + 0.7 / 10, 1.0)
  25. bgcolor = Color.from_rgb(r1 * 255, g1 * 255, b1 * 255)
  26. color = Color.from_rgb(r2 * 255, g2 * 255, b2 * 255)
  27. yield Segment("▄", Style(color=color, bgcolor=bgcolor))
  28. yield Segment.line()
  29. def __rich_measure__(
  30. self, console: "Console", options: ConsoleOptions
  31. ) -> Measurement:
  32. return Measurement(1, options.max_width)
  33. def make_test_card() -> Table:
  34. """Get a renderable that demonstrates a number of features."""
  35. table = Table.grid(padding=1, pad_edge=True)
  36. table.title = "Rich features"
  37. table.add_column("Feature", no_wrap=True, justify="center", style="bold red")
  38. table.add_column("Demonstration")
  39. color_table = Table(
  40. box=None,
  41. expand=False,
  42. show_header=False,
  43. show_edge=False,
  44. pad_edge=False,
  45. )
  46. color_table.add_row(
  47. (
  48. "✓ [bold green]4-bit color[/]\n"
  49. "✓ [bold blue]8-bit color[/]\n"
  50. "✓ [bold magenta]Truecolor (16.7 million)[/]\n"
  51. "✓ [bold yellow]Dumb terminals[/]\n"
  52. "✓ [bold cyan]Automatic color conversion"
  53. ),
  54. ColorBox(),
  55. )
  56. table.add_row("Colors", color_table)
  57. table.add_row(
  58. "Styles",
  59. "All ansi styles: [bold]bold[/], [dim]dim[/], [italic]italic[/italic], [underline]underline[/], [strike]strikethrough[/], [reverse]reverse[/], and even [blink]blink[/].",
  60. )
  61. lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque in metus sed sapien ultricies pretium a at justo. Maecenas luctus velit et auctor maximus."
  62. lorem_table = Table.grid(padding=1, collapse_padding=True)
  63. lorem_table.pad_edge = False
  64. lorem_table.add_row(
  65. Text(lorem, justify="left", style="green"),
  66. Text(lorem, justify="center", style="yellow"),
  67. Text(lorem, justify="right", style="blue"),
  68. Text(lorem, justify="full", style="red"),
  69. )
  70. table.add_row(
  71. "Text",
  72. Group(
  73. Text.from_markup(
  74. """Word wrap text. Justify [green]left[/], [yellow]center[/], [blue]right[/] or [red]full[/].\n"""
  75. ),
  76. lorem_table,
  77. ),
  78. )
  79. def comparison(renderable1: RenderableType, renderable2: RenderableType) -> Table:
  80. table = Table(show_header=False, pad_edge=False, box=None, expand=True)
  81. table.add_column("1", ratio=1)
  82. table.add_column("2", ratio=1)
  83. table.add_row(renderable1, renderable2)
  84. return table
  85. table.add_row(
  86. "Asian\nlanguage\nsupport",
  87. ":flag_for_china: 该库支持中文,日文和韩文文本!\n:flag_for_japan: ライブラリは中国語、日本語、韓国語のテキストをサポートしています\n:flag_for_south_korea: 이 라이브러리는 중국어, 일본어 및 한국어 텍스트를 지원합니다",
  88. )
  89. markup_example = (
  90. "[bold magenta]Rich[/] supports a simple [i]bbcode[/i]-like [b]markup[/b] for [yellow]color[/], [underline]style[/], and emoji! "
  91. ":+1: :apple: :ant: :bear: :baguette_bread: :bus: "
  92. )
  93. table.add_row("Markup", markup_example)
  94. example_table = Table(
  95. show_edge=False,
  96. show_header=True,
  97. expand=False,
  98. row_styles=["none", "dim"],
  99. box=box.SIMPLE,
  100. )
  101. example_table.add_column("[green]Date", style="green", no_wrap=True)
  102. example_table.add_column("[blue]Title", style="blue")
  103. example_table.add_column(
  104. "[cyan]Production Budget",
  105. style="cyan",
  106. justify="right",
  107. no_wrap=True,
  108. )
  109. example_table.add_column(
  110. "[magenta]Box Office",
  111. style="magenta",
  112. justify="right",
  113. no_wrap=True,
  114. )
  115. example_table.add_row(
  116. "Dec 20, 2019",
  117. "Star Wars: The Rise of Skywalker",
  118. "$275,000,000",
  119. "$375,126,118",
  120. )
  121. example_table.add_row(
  122. "May 25, 2018",
  123. "[b]Solo[/]: A Star Wars Story",
  124. "$275,000,000",
  125. "$393,151,347",
  126. )
  127. example_table.add_row(
  128. "Dec 15, 2017",
  129. "Star Wars Ep. VIII: The Last Jedi",
  130. "$262,000,000",
  131. "[bold]$1,332,539,889[/bold]",
  132. )
  133. example_table.add_row(
  134. "May 19, 1999",
  135. "Star Wars Ep. [b]I[/b]: [i]The phantom Menace",
  136. "$115,000,000",
  137. "$1,027,044,677",
  138. )
  139. table.add_row("Tables", example_table)
  140. code = '''\
  141. def iter_last(values: Iterable[T]) -> Iterable[Tuple[bool, T]]:
  142. """Iterate and generate a tuple with a flag for last value."""
  143. iter_values = iter(values)
  144. try:
  145. previous_value = next(iter_values)
  146. except StopIteration:
  147. return
  148. for value in iter_values:
  149. yield False, previous_value
  150. previous_value = value
  151. yield True, previous_value'''
  152. pretty_data = {
  153. "foo": [
  154. 3.1427,
  155. (
  156. "Paul Atreides",
  157. "Vladimir Harkonnen",
  158. "Thufir Hawat",
  159. ),
  160. ],
  161. "atomic": (False, True, None),
  162. }
  163. table.add_row(
  164. "Syntax\nhighlighting\n&\npretty\nprinting",
  165. comparison(
  166. Syntax(code, "python3", line_numbers=True, indent_guides=True),
  167. Pretty(pretty_data, indent_guides=True),
  168. ),
  169. )
  170. markdown_example = """\
  171. # Markdown
  172. Supports much of the *markdown* __syntax__!
  173. - Headers
  174. - Basic formatting: **bold**, *italic*, `code`
  175. - Block quotes
  176. - Lists, and more...
  177. """
  178. table.add_row(
  179. "Markdown", comparison("[cyan]" + markdown_example, Markdown(markdown_example))
  180. )
  181. table.add_row(
  182. "+more!",
  183. """Progress bars, columns, styled logging handler, tracebacks, etc...""",
  184. )
  185. return table
  186. if __name__ == "__main__": # pragma: no cover
  187. console = Console(
  188. file=io.StringIO(),
  189. force_terminal=True,
  190. )
  191. test_card = make_test_card()
  192. # Print once to warm cache
  193. start = process_time()
  194. console.print(test_card)
  195. pre_cache_taken = round((process_time() - start) * 1000.0, 1)
  196. console.file = io.StringIO()
  197. start = process_time()
  198. console.print(test_card)
  199. taken = round((process_time() - start) * 1000.0, 1)
  200. c = Console(record=True)
  201. c.print(test_card)
  202. print(f"rendered in {pre_cache_taken}ms (cold cache)")
  203. print(f"rendered in {taken}ms (warm cache)")
  204. from rich.panel import Panel
  205. console = Console()
  206. sponsor_message = Table.grid(padding=1)
  207. sponsor_message.add_column(style="green", justify="right")
  208. sponsor_message.add_column(no_wrap=True)
  209. sponsor_message.add_row(
  210. "Textualize",
  211. "[u blue link=https://github.com/textualize]https://github.com/textualize",
  212. )
  213. sponsor_message.add_row(
  214. "Twitter",
  215. "[u blue link=https://twitter.com/willmcgugan]https://twitter.com/willmcgugan",
  216. )
  217. intro_message = Text.from_markup(
  218. """\
  219. We hope you enjoy using Rich!
  220. Rich is maintained with [red]:heart:[/] by [link=https://www.textualize.io]Textualize.io[/]
  221. - Will McGugan"""
  222. )
  223. message = Table.grid(padding=2)
  224. message.add_column()
  225. message.add_column(no_wrap=True)
  226. message.add_row(intro_message, sponsor_message)
  227. console.print(
  228. Panel.fit(
  229. message,
  230. box=box.ROUNDED,
  231. padding=(1, 2),
  232. title="[b red]Thanks for trying out Rich!",
  233. border_style="bright_blue",
  234. ),
  235. justify="center",
  236. )