rich-ruby 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +546 -0
- data/examples/demo.rb +106 -0
- data/examples/showcase.rb +420 -0
- data/examples/smoke_test.rb +41 -0
- data/examples/stress_test.rb +604 -0
- data/examples/syntax_markdown_demo.rb +166 -0
- data/examples/verify.rb +215 -0
- data/examples/visual_demo.rb +145 -0
- data/lib/rich/_palettes.rb +148 -0
- data/lib/rich/box.rb +342 -0
- data/lib/rich/cells.rb +512 -0
- data/lib/rich/color.rb +628 -0
- data/lib/rich/color_triplet.rb +220 -0
- data/lib/rich/console.rb +549 -0
- data/lib/rich/control.rb +332 -0
- data/lib/rich/json.rb +254 -0
- data/lib/rich/layout.rb +314 -0
- data/lib/rich/markdown.rb +509 -0
- data/lib/rich/markup.rb +175 -0
- data/lib/rich/panel.rb +311 -0
- data/lib/rich/progress.rb +430 -0
- data/lib/rich/segment.rb +387 -0
- data/lib/rich/style.rb +433 -0
- data/lib/rich/syntax.rb +1145 -0
- data/lib/rich/table.rb +525 -0
- data/lib/rich/terminal_theme.rb +126 -0
- data/lib/rich/text.rb +433 -0
- data/lib/rich/tree.rb +220 -0
- data/lib/rich/version.rb +5 -0
- data/lib/rich/win32_console.rb +582 -0
- data/lib/rich.rb +108 -0
- metadata +106 -0
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Visual Showcase Demo - See Rich features in action!
|
|
4
|
+
|
|
5
|
+
require_relative "../lib/rich"
|
|
6
|
+
|
|
7
|
+
console = Rich::Console.new
|
|
8
|
+
|
|
9
|
+
# Helper to pause and let user see the output
|
|
10
|
+
def pause(message = "Press Enter to continue...")
|
|
11
|
+
print "\n#{message}"
|
|
12
|
+
gets
|
|
13
|
+
puts ""
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# =============================================================================
|
|
17
|
+
# INTRO
|
|
18
|
+
# =============================================================================
|
|
19
|
+
console.clear
|
|
20
|
+
console.rule("🎨 Rich Ruby Library - Visual Showcase", style: "bold magenta")
|
|
21
|
+
puts ""
|
|
22
|
+
puts "This demo will showcase all the visual features of the Rich library."
|
|
23
|
+
puts "Watch for colors, styles, panels, tables, trees, and progress bars!"
|
|
24
|
+
pause
|
|
25
|
+
|
|
26
|
+
# =============================================================================
|
|
27
|
+
# 1. COLORS
|
|
28
|
+
# =============================================================================
|
|
29
|
+
console.clear
|
|
30
|
+
console.rule("1. Color Showcase", style: "bold cyan")
|
|
31
|
+
puts ""
|
|
32
|
+
|
|
33
|
+
# Standard colors
|
|
34
|
+
puts "Standard 16 Colors:"
|
|
35
|
+
%w[black red green yellow blue magenta cyan white].each do |color|
|
|
36
|
+
console.print(" #{color.ljust(10)}", style: color, end_str: "")
|
|
37
|
+
console.print(" bright_#{color}", style: "bright_#{color}")
|
|
38
|
+
end
|
|
39
|
+
puts ""
|
|
40
|
+
|
|
41
|
+
# 256 color palette preview
|
|
42
|
+
puts "256 Color Palette (sample):"
|
|
43
|
+
print " "
|
|
44
|
+
(0...36).each do |i|
|
|
45
|
+
style = Rich::Style.new(bgcolor: Rich::Color.parse("color(#{i * 7})"))
|
|
46
|
+
console.write(style.render + " " + "\e[0m")
|
|
47
|
+
end
|
|
48
|
+
puts ""
|
|
49
|
+
puts ""
|
|
50
|
+
|
|
51
|
+
# Truecolor gradient
|
|
52
|
+
puts "TrueColor Gradient:"
|
|
53
|
+
print " "
|
|
54
|
+
80.times do |i|
|
|
55
|
+
r = (255 * i / 80.0).to_i
|
|
56
|
+
g = (255 * (80 - i) / 80.0).to_i
|
|
57
|
+
b = 128
|
|
58
|
+
style = Rich::Style.new(bgcolor: Rich::Color.from_triplet(Rich::ColorTriplet.new(r, g, b)))
|
|
59
|
+
console.write(style.render + " " + "\e[0m")
|
|
60
|
+
end
|
|
61
|
+
puts ""
|
|
62
|
+
|
|
63
|
+
pause
|
|
64
|
+
|
|
65
|
+
# =============================================================================
|
|
66
|
+
# 2. TEXT STYLES
|
|
67
|
+
# =============================================================================
|
|
68
|
+
console.clear
|
|
69
|
+
console.rule("2. Text Styles", style: "bold cyan")
|
|
70
|
+
puts ""
|
|
71
|
+
|
|
72
|
+
styles = [
|
|
73
|
+
["bold", "Bold text - stands out!"],
|
|
74
|
+
["dim", "Dim text - subtle emphasis"],
|
|
75
|
+
["italic", "Italic text - for emphasis"],
|
|
76
|
+
["underline", "Underlined text - important"],
|
|
77
|
+
["blink", "Blinking text - attention!"],
|
|
78
|
+
["reverse", "Reversed colors"],
|
|
79
|
+
["strike", "Strikethrough - outdated"],
|
|
80
|
+
["underline2", "Double underline"],
|
|
81
|
+
["overline", "Overlined text"]
|
|
82
|
+
]
|
|
83
|
+
|
|
84
|
+
styles.each do |style, description|
|
|
85
|
+
console.print(" ", end_str: "")
|
|
86
|
+
console.print(description.ljust(35), style: style, end_str: "")
|
|
87
|
+
console.print(" [#{style}]", style: "dim")
|
|
88
|
+
end
|
|
89
|
+
puts ""
|
|
90
|
+
|
|
91
|
+
# Combined styles
|
|
92
|
+
puts "Combined Styles:"
|
|
93
|
+
combos = [
|
|
94
|
+
"bold red",
|
|
95
|
+
"italic green",
|
|
96
|
+
"bold italic underline blue",
|
|
97
|
+
"dim yellow on black",
|
|
98
|
+
"bold white on red",
|
|
99
|
+
"italic cyan on magenta"
|
|
100
|
+
]
|
|
101
|
+
|
|
102
|
+
combos.each do |combo|
|
|
103
|
+
console.print(" ", end_str: "")
|
|
104
|
+
console.print(combo.ljust(30), style: combo)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
pause
|
|
108
|
+
|
|
109
|
+
# =============================================================================
|
|
110
|
+
# 3. MARKUP
|
|
111
|
+
# =============================================================================
|
|
112
|
+
console.clear
|
|
113
|
+
console.rule("3. Rich Markup", style: "bold cyan")
|
|
114
|
+
puts ""
|
|
115
|
+
|
|
116
|
+
puts "Markup makes styling text easy!"
|
|
117
|
+
puts ""
|
|
118
|
+
|
|
119
|
+
markups = [
|
|
120
|
+
"[bold]Bold text[/bold]",
|
|
121
|
+
"[red]Red text[/red]",
|
|
122
|
+
"[bold green]Bold green[/bold green]",
|
|
123
|
+
"[italic blue on white]Italic blue on white background[/italic blue on white]",
|
|
124
|
+
"[underline magenta]Underlined magenta[/underline magenta]"
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
markups.each do |markup|
|
|
128
|
+
print " "
|
|
129
|
+
rendered = Rich::Markup.render(markup)
|
|
130
|
+
puts rendered + "\e[0m"
|
|
131
|
+
console.print(" Source: #{markup}", style: "dim")
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
pause
|
|
135
|
+
|
|
136
|
+
# =============================================================================
|
|
137
|
+
# 4. PANELS
|
|
138
|
+
# =============================================================================
|
|
139
|
+
console.clear
|
|
140
|
+
console.rule("4. Panels", style: "bold cyan")
|
|
141
|
+
puts ""
|
|
142
|
+
|
|
143
|
+
# Simple panel
|
|
144
|
+
panel1 = Rich::Panel.new(
|
|
145
|
+
"This is a simple panel with some content.\nPanels are great for highlighting information!",
|
|
146
|
+
title: "Simple Panel",
|
|
147
|
+
border_style: "green"
|
|
148
|
+
)
|
|
149
|
+
puts panel1.render(max_width: 60)
|
|
150
|
+
puts ""
|
|
151
|
+
|
|
152
|
+
# Panel with subtitle
|
|
153
|
+
panel2 = Rich::Panel.new(
|
|
154
|
+
"Panels can have both titles and subtitles.\nThey support different box styles too!",
|
|
155
|
+
title: "✨ Featured",
|
|
156
|
+
subtitle: "Look at me!",
|
|
157
|
+
border_style: "cyan",
|
|
158
|
+
title_style: "bold white"
|
|
159
|
+
)
|
|
160
|
+
puts panel2.render(max_width: 60)
|
|
161
|
+
puts ""
|
|
162
|
+
|
|
163
|
+
# Different box styles
|
|
164
|
+
puts "Box Styles:"
|
|
165
|
+
boxes = [
|
|
166
|
+
[Rich::Box::ASCII, "ASCII"],
|
|
167
|
+
[Rich::Box::ROUNDED, "Rounded"],
|
|
168
|
+
[Rich::Box::HEAVY, "Heavy"],
|
|
169
|
+
[Rich::Box::DOUBLE, "Double"]
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
boxes.each do |box, name|
|
|
173
|
+
small = Rich::Panel.new("Content", title: name, box: box, padding: 0)
|
|
174
|
+
print small.render(max_width: 20)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
pause
|
|
178
|
+
|
|
179
|
+
# =============================================================================
|
|
180
|
+
# 5. TABLES
|
|
181
|
+
# =============================================================================
|
|
182
|
+
console.clear
|
|
183
|
+
console.rule("5. Tables", style: "bold cyan")
|
|
184
|
+
puts ""
|
|
185
|
+
|
|
186
|
+
# User table
|
|
187
|
+
table1 = Rich::Table.new(title: "👥 Team Members", border_style: "blue")
|
|
188
|
+
table1.add_column("Name", header_style: "bold cyan")
|
|
189
|
+
table1.add_column("Role", header_style: "bold cyan")
|
|
190
|
+
table1.add_column("Status", header_style: "bold cyan", justify: :center)
|
|
191
|
+
|
|
192
|
+
table1.add_row("Alice Johnson", "Lead Developer", "🟢 Active")
|
|
193
|
+
table1.add_row("Bob Smith", "Designer", "🟢 Active")
|
|
194
|
+
table1.add_row("Carol Williams", "DevOps", "🟡 Away")
|
|
195
|
+
table1.add_row("David Brown", "QA Engineer", "🔴 Offline")
|
|
196
|
+
|
|
197
|
+
puts table1.render(max_width: 65)
|
|
198
|
+
puts ""
|
|
199
|
+
|
|
200
|
+
# Performance table
|
|
201
|
+
table2 = Rich::Table.new(title: "📊 Performance Metrics", border_style: "green", box: Rich::Box::DOUBLE)
|
|
202
|
+
table2.add_column("Metric", header_style: "bold")
|
|
203
|
+
table2.add_column("Value", justify: :right, style: "cyan")
|
|
204
|
+
table2.add_column("Change", justify: :right)
|
|
205
|
+
|
|
206
|
+
table2.add_row("Response Time", "45ms", "↓ 12%")
|
|
207
|
+
table2.add_row("Throughput", "1,234 req/s", "↑ 23%")
|
|
208
|
+
table2.add_row("Error Rate", "0.02%", "↓ 5%")
|
|
209
|
+
table2.add_row("CPU Usage", "67%", "→ 0%")
|
|
210
|
+
|
|
211
|
+
puts table2.render(max_width: 55)
|
|
212
|
+
|
|
213
|
+
pause
|
|
214
|
+
|
|
215
|
+
# =============================================================================
|
|
216
|
+
# 6. TREES
|
|
217
|
+
# =============================================================================
|
|
218
|
+
console.clear
|
|
219
|
+
console.rule("6. Trees", style: "bold cyan")
|
|
220
|
+
puts ""
|
|
221
|
+
|
|
222
|
+
# File tree
|
|
223
|
+
tree1 = Rich::Tree.new("📁 project/", style: "bold yellow")
|
|
224
|
+
src = tree1.add("📁 src/", style: "bold")
|
|
225
|
+
src.add("📄 main.rb", style: "green")
|
|
226
|
+
src.add("📄 config.rb", style: "green")
|
|
227
|
+
models = src.add("📁 models/", style: "bold")
|
|
228
|
+
models.add("📄 user.rb", style: "green")
|
|
229
|
+
models.add("📄 post.rb", style: "green")
|
|
230
|
+
|
|
231
|
+
lib = tree1.add("📁 lib/", style: "bold")
|
|
232
|
+
lib.add("📄 utils.rb", style: "green")
|
|
233
|
+
lib.add("📄 helpers.rb", style: "green")
|
|
234
|
+
|
|
235
|
+
tree1.add("📄 Gemfile", style: "cyan")
|
|
236
|
+
tree1.add("📄 README.md", style: "cyan")
|
|
237
|
+
|
|
238
|
+
puts tree1.render
|
|
239
|
+
puts ""
|
|
240
|
+
|
|
241
|
+
# Different tree styles
|
|
242
|
+
puts "Tree Guide Styles:"
|
|
243
|
+
[
|
|
244
|
+
[Rich::TreeGuide::UNICODE, "Unicode"],
|
|
245
|
+
[Rich::TreeGuide::ROUNDED, "Rounded"],
|
|
246
|
+
[Rich::TreeGuide::BOLD, "Bold"],
|
|
247
|
+
[Rich::TreeGuide::ASCII, "ASCII"]
|
|
248
|
+
].each do |guide, name|
|
|
249
|
+
small_tree = Rich::Tree.new(name, guide: guide)
|
|
250
|
+
small_tree.add("Child 1")
|
|
251
|
+
small_tree.add("Child 2")
|
|
252
|
+
puts small_tree.render
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
pause
|
|
256
|
+
|
|
257
|
+
# =============================================================================
|
|
258
|
+
# 7. PROGRESS BAR
|
|
259
|
+
# =============================================================================
|
|
260
|
+
console.clear
|
|
261
|
+
console.rule("7. Progress Bars", style: "bold cyan")
|
|
262
|
+
puts ""
|
|
263
|
+
|
|
264
|
+
puts "Simulating file download...\n"
|
|
265
|
+
|
|
266
|
+
# Animated progress bar
|
|
267
|
+
bar = Rich::ProgressBar.new(total: 100, width: 50, complete_style: "green", incomplete_style: "dim")
|
|
268
|
+
|
|
269
|
+
console.hide_cursor
|
|
270
|
+
101.times do |i|
|
|
271
|
+
bar.update(i)
|
|
272
|
+
print "\r Downloading: "
|
|
273
|
+
print bar.render
|
|
274
|
+
print " " * 10
|
|
275
|
+
sleep(0.02)
|
|
276
|
+
end
|
|
277
|
+
console.show_cursor
|
|
278
|
+
puts "\n ✓ Download complete!"
|
|
279
|
+
puts ""
|
|
280
|
+
|
|
281
|
+
# Multiple progress bars
|
|
282
|
+
puts "Multiple Operations:"
|
|
283
|
+
operations = [
|
|
284
|
+
["Compiling", 100],
|
|
285
|
+
["Testing", 75],
|
|
286
|
+
["Deploying", 50],
|
|
287
|
+
["Verifying", 25]
|
|
288
|
+
]
|
|
289
|
+
|
|
290
|
+
operations.each do |name, progress|
|
|
291
|
+
op_bar = Rich::ProgressBar.new(total: 100, completed: progress, width: 30)
|
|
292
|
+
style = progress >= 100 ? "green" : (progress >= 50 ? "yellow" : "red")
|
|
293
|
+
print " #{name.ljust(12)}: "
|
|
294
|
+
print op_bar.render
|
|
295
|
+
puts ""
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
pause
|
|
299
|
+
|
|
300
|
+
# =============================================================================
|
|
301
|
+
# 8. SPINNERS
|
|
302
|
+
# =============================================================================
|
|
303
|
+
console.clear
|
|
304
|
+
console.rule("8. Spinners", style: "bold cyan")
|
|
305
|
+
puts ""
|
|
306
|
+
|
|
307
|
+
spinners = [
|
|
308
|
+
[Rich::ProgressStyle::DOTS, "Dots"],
|
|
309
|
+
[Rich::ProgressStyle::LINE, "Line"],
|
|
310
|
+
[Rich::ProgressStyle::CIRCLE, "Circle"],
|
|
311
|
+
[Rich::ProgressStyle::BOUNCE, "Bounce"]
|
|
312
|
+
]
|
|
313
|
+
|
|
314
|
+
puts "Spinner Styles (watch for 2 seconds each):"
|
|
315
|
+
puts ""
|
|
316
|
+
|
|
317
|
+
console.hide_cursor
|
|
318
|
+
spinners.each do |frames, name|
|
|
319
|
+
spinner = Rich::Spinner.new(frames: frames, speed: 0.08)
|
|
320
|
+
print " #{name.ljust(10)}: "
|
|
321
|
+
|
|
322
|
+
20.times do
|
|
323
|
+
print "\r #{name.ljust(10)}: #{spinner.frame} Processing..."
|
|
324
|
+
spinner.advance
|
|
325
|
+
sleep(0.1)
|
|
326
|
+
end
|
|
327
|
+
puts "\r #{name.ljust(10)}: ✓ Done! "
|
|
328
|
+
end
|
|
329
|
+
console.show_cursor
|
|
330
|
+
|
|
331
|
+
pause
|
|
332
|
+
|
|
333
|
+
# =============================================================================
|
|
334
|
+
# 9. JSON HIGHLIGHTING
|
|
335
|
+
# =============================================================================
|
|
336
|
+
console.clear
|
|
337
|
+
console.rule("9. JSON Highlighting", style: "bold cyan")
|
|
338
|
+
puts ""
|
|
339
|
+
|
|
340
|
+
data = {
|
|
341
|
+
"name" => "Rich Ruby",
|
|
342
|
+
"version" => "0.1.0",
|
|
343
|
+
"features" => ["colors", "styles", "tables", "trees"],
|
|
344
|
+
"config" => {
|
|
345
|
+
"color_system" => "truecolor",
|
|
346
|
+
"unicode" => true,
|
|
347
|
+
"windows_support" => true
|
|
348
|
+
},
|
|
349
|
+
"stats" => {
|
|
350
|
+
"tests_passed" => 51,
|
|
351
|
+
"coverage" => 95.5
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
puts Rich::JSON.to_s(data)
|
|
356
|
+
|
|
357
|
+
pause
|
|
358
|
+
|
|
359
|
+
# =============================================================================
|
|
360
|
+
# 10. PRETTY PRINTING
|
|
361
|
+
# =============================================================================
|
|
362
|
+
console.clear
|
|
363
|
+
console.rule("10. Pretty Printing Ruby Objects", style: "bold cyan")
|
|
364
|
+
puts ""
|
|
365
|
+
|
|
366
|
+
obj = {
|
|
367
|
+
string: "hello world",
|
|
368
|
+
number: 42,
|
|
369
|
+
float: 3.14159,
|
|
370
|
+
boolean: true,
|
|
371
|
+
nil_value: nil,
|
|
372
|
+
symbol: :example,
|
|
373
|
+
array: [1, 2, 3, [4, 5]],
|
|
374
|
+
nested: {
|
|
375
|
+
deep: {
|
|
376
|
+
value: "found!"
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
puts Rich::Pretty.to_s(obj)
|
|
382
|
+
|
|
383
|
+
pause
|
|
384
|
+
|
|
385
|
+
# =============================================================================
|
|
386
|
+
# FINALE
|
|
387
|
+
# =============================================================================
|
|
388
|
+
console.clear
|
|
389
|
+
console.rule("🎉 Demo Complete!", style: "bold green")
|
|
390
|
+
puts ""
|
|
391
|
+
|
|
392
|
+
finale = Rich::Panel.new(
|
|
393
|
+
"Thank you for exploring the Rich Ruby Library!\n\n" \
|
|
394
|
+
"Features demonstrated:\n" \
|
|
395
|
+
" • 16-color, 256-color, and TrueColor support\n" \
|
|
396
|
+
" • 13 text style attributes\n" \
|
|
397
|
+
" • Rich markup syntax\n" \
|
|
398
|
+
" • Panels with titles and borders\n" \
|
|
399
|
+
" • Tables with alignment and styling\n" \
|
|
400
|
+
" • Tree views with multiple guides\n" \
|
|
401
|
+
" • Animated progress bars\n" \
|
|
402
|
+
" • Multiple spinner styles\n" \
|
|
403
|
+
" • JSON syntax highlighting\n" \
|
|
404
|
+
" • Ruby object pretty printing\n\n" \
|
|
405
|
+
"All 51 stress tests pass! Ready for production.",
|
|
406
|
+
title: "✨ Rich Ruby Library",
|
|
407
|
+
subtitle: "Pure Ruby • Zero Dependencies • Windows Ready",
|
|
408
|
+
border_style: "bold green",
|
|
409
|
+
title_style: "bold white on green"
|
|
410
|
+
)
|
|
411
|
+
|
|
412
|
+
puts finale.render(max_width: 65)
|
|
413
|
+
puts ""
|
|
414
|
+
|
|
415
|
+
console.print("Run ", end_str: "")
|
|
416
|
+
console.print("examples/demo.rb", style: "cyan")
|
|
417
|
+
console.print(" for a quick demo, or ", end_str: "")
|
|
418
|
+
console.print("examples/stress_test.rb", style: "cyan")
|
|
419
|
+
console.print(" for tests.")
|
|
420
|
+
puts ""
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Smoke test for Rich library
|
|
4
|
+
|
|
5
|
+
require_relative "../lib/rich"
|
|
6
|
+
|
|
7
|
+
puts "1. Testing library load..."
|
|
8
|
+
puts " Rich library loaded successfully!"
|
|
9
|
+
|
|
10
|
+
puts "\n2. Testing Console..."
|
|
11
|
+
console = Rich::Console.new
|
|
12
|
+
puts " Color system: #{console.color_system}"
|
|
13
|
+
puts " Terminal size: #{console.width}x#{console.height}"
|
|
14
|
+
puts " Is terminal: #{console.terminal?}"
|
|
15
|
+
|
|
16
|
+
puts "\n3. Testing Color parsing..."
|
|
17
|
+
red = Rich::Color.parse("red")
|
|
18
|
+
puts " Parsed 'red': #{red.inspect}"
|
|
19
|
+
|
|
20
|
+
hex = Rich::Color.parse("#ff5500")
|
|
21
|
+
puts " Parsed '#ff5500': #{hex.inspect}"
|
|
22
|
+
|
|
23
|
+
puts "\n4. Testing Style parsing..."
|
|
24
|
+
style = Rich::Style.parse("bold red on white")
|
|
25
|
+
puts " Parsed 'bold red on white': #{style.inspect}"
|
|
26
|
+
|
|
27
|
+
puts "\n5. Testing ColorTriplet..."
|
|
28
|
+
triplet = Rich::ColorTriplet.new(255, 128, 0)
|
|
29
|
+
puts " Triplet: #{triplet.hex} / #{triplet.rgb}"
|
|
30
|
+
|
|
31
|
+
puts "\n6. Testing Cells width..."
|
|
32
|
+
puts " Width of 'Hello': #{Rich::Cells.cell_len('Hello')}"
|
|
33
|
+
puts " Width of '你好': #{Rich::Cells.cell_len('你好')}"
|
|
34
|
+
|
|
35
|
+
puts "\n7. Testing basic output..."
|
|
36
|
+
console.print("Hello from Rich!", style: "bold green")
|
|
37
|
+
|
|
38
|
+
puts "\n8. Testing markup..."
|
|
39
|
+
console.print_markup("[bold]Bold[/bold] and [red]Red[/red] text")
|
|
40
|
+
|
|
41
|
+
puts "\n✓ Smoke test complete!"
|