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.
@@ -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!"