formatador 0.2.5 → 1.2.3

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZmFhYzcyNjZlYTkzM2RmZTBhYmY1OWJmN2ViOWUyMzYyNmIyYzdiMw==
5
- data.tar.gz: !binary |-
6
- MGRkYmM5ZGM0OTliYjI4NjEwY2M3NDZmYWI2NWYwOTZjM2ZkOWExMw==
2
+ SHA256:
3
+ metadata.gz: 5fe34f9dc5c0f7ecda25c5d1a6b486befaed871f0ea3b2d1b2811e82b3c1656b
4
+ data.tar.gz: 1e2580cb52975afa3a63f34e86a46b4e7c48b4d501cc0b126f21b0d60133fdc9
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- Y2VhYjM0NzZkYmExYmQ5OTMwZjI5ZmZhYTllNTBmNzdlMDEzNDk4NWVmZTVj
10
- MmU0ZjEwZTVhOTdlZWU3ZGYyOTE5YTc3YTA4Y2MxNDM3MDQyYmY0ZjMzNmY3
11
- YTIxNDY1MDMwM2ZiOGI1MzQ3ODJiYWRlZmNiMzIyOWFmNzBiZDY=
12
- data.tar.gz: !binary |-
13
- YzcyNzFhYTk2ODI2YjUzZTlhZTAxNWI0MTYzZmJlNGY2MjU2Y2M5MTAxY2Fl
14
- OTViZGRlMWVlODgwMWNmOWExNTZlYWY5YzFhNjc4Yzg3Y2IxZDQ5YjJjN2Iw
15
- OWUyYjI5ZjAyNDg3Mzk0YmVlMDA5MmU0ZDU3ZmMxOTUyYzRjNjI=
6
+ metadata.gz: 37e1cef3d87ee2c5b90f781f526eea22444de15db0f8fa827eeffc790aaae3f5b935314013ebaab9bbd49f605c7057633683e6f606f503f0c978355260a29ca4
7
+ data.tar.gz: 24566111d7be71a3cbb6cb834f0fe439d34df11fc9e78aca14540ad54e903eabf4691c76d56ae21dab213b836e9cc4b7ad5221ca3aebe938a0a664c8558568bf
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2009-2013 [CONTRIBUTORS.md](https://github.com/geemus/formatador/blob/master/CONTRIBUTORS.md)
3
+ Copyright (c) 2009-2022 [CONTRIBUTORS.md](https://github.com/geemus/formatador/blob/master/CONTRIBUTORS.md)
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
@@ -1,101 +1,129 @@
1
- = formatador
1
+ # formatador
2
2
 
3
3
  STDOUT text formatting
4
4
 
5
- == Quick and dirty
5
+ [![Build Status](https://github.com/geemus/formatador/actions/workflows/ruby.yml/badge.svg)](https://github.com/geemus/formatador/actions/workflows/ruby.yml)
6
+
7
+ ## Quick and dirty
6
8
 
7
9
  You can call class methods to print out single lines like this:
8
10
 
9
- Formatador.display_line('Hello World')
11
+ ```ruby
12
+ Formatador.display_line('Hello World')
13
+ ```
10
14
 
11
15
  You use tags, similar to html, to set formatting options:
12
16
 
13
- Formatador.display_line('[green]Hello World[/]')
17
+ ```ruby
18
+ Formatador.display_line('[green]Hello World[/]')
19
+ ```
14
20
 
15
- [/] resets everything to normal, colors are supported and [_color_] sets the background color.
21
+ `[/]` resets everything to normal, colors are supported and `[_color_]` sets the background color.
16
22
 
17
- == Standard options
23
+ ## Standard options
18
24
 
19
25
  * format - and adds color codes if STDOUT.tty? is true
20
26
  * display - calls format on the input and prints it
21
27
  * display_line - calls display, but adds on a newline (\n)
22
28
  * redisplay - Displays text, prepended with \r which will overwrite the last existing line
23
29
 
24
- == Extensions
30
+ ## Extensions
25
31
 
26
32
  * display_table: takes an array of hashes. Each hash is a row, with the keys being the headers and values being the data. An optional second argument can specify which headers/columns to include and in what order they should appear.
27
33
  * display_compact_table: Same as display_table, execpt that split lines are not drawn by default in the body of the table. If you need a split line, put a :split constant in the body array.
28
34
  * redisplay_progressbar: takes the current and total values as its first two arguments and redisplays a progressbar (until current = total and then it display_lines). An optional third argument represents the start time and will add an elapsed time counter.
29
35
 
30
- === Progress Bar examples
31
-
32
- total = 1000
33
- progress = ProgressBar.new(total)
34
- 1000.times do
35
- progress.increment
36
- end
37
-
38
- 978/1000 |************************************************* |
39
-
40
- # Change the color of the bar
41
-
42
- total = 1000
43
- progress = ProgressBar.new(total, :color => "light_blue")
44
- 1000.times do
45
- progress.increment
46
- end
47
-
48
- # Change the color of a completed progress bar
49
-
50
- total = 1000
51
- progress = ProgressBar.new(total) { |b| b.opts[:color] = "green" }
52
- 1000.times do
53
- progress.increment
54
- end
55
-
56
- === Table examples
57
-
58
- table_data = [{:name => "Joe", :food => "Burger"}, {:name => "Bill", :food => "French fries"}]
59
- Formatador.display_table(table_data)
60
-
61
- +------+--------------+
62
- | name | food |
63
- +------+--------------+
64
- | Joe | Burger |
65
- +------+--------------+
66
- | Bill | French fries |
67
- +------+--------------+
68
-
69
- table_data = [
70
- {:name => "Joe", :meal => {:main_dish => "Burger", :drink => "water"}},
71
- {:name => "Bill", :meal => {:main_dish => "Chicken", :drink => "soda"}}
72
- ]
73
- Formatador.display_table(table_data, [:name, :"meal.drink"])
36
+ ### Progress Bar examples
37
+
38
+ ```ruby
39
+ total = 1000
40
+ progress = Formatador::ProgressBar.new(total)
41
+
42
+ 1000.times do
43
+ progress.increment
44
+ end
45
+
46
+ #=> 978/1000 |************************************************* |
47
+
48
+ # Change the color of the bar
49
+ total = 1000
50
+ progress = Formatador::ProgressBar.new(total, :color => "light_blue")
51
+
52
+ 1000.times do
53
+ progress.increment
54
+ end
55
+
56
+ # Change the color of a completed progress bar
57
+ total = 1000
58
+ progress = Formatador::ProgressBar.new(total) { |b| b.opts[:color] = "green" }
59
+
60
+ 1000.times do
61
+ progress.increment
62
+ end
63
+ ```
64
+
65
+ ### Table examples
66
+
67
+ ```ruby
68
+ table_data = [
69
+ { :name => "Joe", :food => "Burger" },
70
+ { :name => "Bill", :food => "French fries" }
71
+ ]
72
+ Formatador.display_table(table_data)
73
+
74
+ #=> +------+--------------+
75
+ # | name | food |
76
+ # +------+--------------+
77
+ # | Joe | Burger |
78
+ # +------+--------------+
79
+ # | Bill | French fries |
80
+ # +------+--------------+
81
+
82
+ table_data = [
83
+ {
84
+ :name => "Joe",
85
+ :meal => {
86
+ :main_dish => "Burger",
87
+ :drink => "water"
88
+ }
89
+ },
90
+ {
91
+ :name => "Bill",
92
+ :meal => {
93
+ :main_dish => "Chicken",
94
+ :drink => "soda"
95
+ }
96
+ }
97
+ ]
98
+ Formatador.display_table(table_data, [:name, :"meal.drink"])
74
99
 
75
- +------+------------+
76
- | name | meal.drink |
77
- +------+------------+
78
- | Joe | water |
79
- +------+------------+
80
- | Bill | soda |
81
- +------+------------+
100
+ #=> +------+------------+
101
+ # | name | meal.drink |
102
+ # +------+------------+
103
+ # | Joe | water |
104
+ # +------+------------+
105
+ # | Bill | soda |
106
+ # +------+------------+
107
+ ```
82
108
 
83
- == Indentation
109
+ ## Indentation
84
110
 
85
111
  By initializing a formatador object you can keep track of indentation:
86
112
 
87
- formatador = Formatador.new
88
- formatador.display_line('one level of indentation')
89
- formatador.indent {
90
- formatador.display_line('two levels of indentation')
91
- }
92
- formatador.display_line('one level of indentation')
113
+ ```ruby
114
+ formatador = Formatador.new
115
+ formatador.display_line('one level of indentation')
116
+ formatador.indent {
117
+ formatador.display_line('two levels of indentation')
118
+ }
119
+ formatador.display_line('one level of indentation')
120
+ ```
93
121
 
94
- == Copyright
122
+ ## Copyright
95
123
 
96
124
  (The MIT License)
97
125
 
98
- Copyright (c) 2009 {geemus (Wesley Beary)}[http://github.com/geemus]
126
+ Copyright (c) 2022 [geemus (Wesley Beary)](http://github.com/geemus)
99
127
 
100
128
  Permission is hereby granted, free of charge, to any person obtaining
101
129
  a copy of this software and associated documentation files (the
data/Rakefile CHANGED
@@ -21,10 +21,6 @@ def date
21
21
  Date.today.to_s
22
22
  end
23
23
 
24
- def rubyforge_project
25
- name
26
- end
27
-
28
24
  def gemspec_file
29
25
  "#{name}.gemspec"
30
26
  end
@@ -56,7 +52,7 @@ task :coverage do
56
52
  sh "open coverage/index.html"
57
53
  end
58
54
 
59
- require 'rake/rdoctask'
55
+ require 'rdoc/task'
60
56
  Rake::RDocTask.new do |rdoc|
61
57
  rdoc.rdoc_dir = 'rdoc'
62
58
  rdoc.title = "#{name} #{version}"
@@ -88,7 +84,7 @@ task :release => :build do
88
84
  puts "You must be on the master branch to release!"
89
85
  exit!
90
86
  end
91
- sh "sudo gem install pkg/#{name}-#{version}.gem"
87
+ sh "gem install pkg/#{name}-#{version}.gem"
92
88
  sh "git commit --allow-empty -a -m 'Release #{version}'"
93
89
  sh "git tag v#{version}"
94
90
  sh "git push origin master"
@@ -111,8 +107,6 @@ task :gemspec => :validate do
111
107
  replace_header(head, :name)
112
108
  replace_header(head, :version)
113
109
  replace_header(head, :date)
114
- #comment this out if your rubyforge_project has a different name
115
- replace_header(head, :rubyforge_project)
116
110
 
117
111
  # determine file list from git ls-files
118
112
  files = `git ls-files`.
data/SECURITY.md ADDED
@@ -0,0 +1,6 @@
1
+ ## Security contact information
2
+
3
+ To report a security vulnerability, please contact
4
+ [Tidelift security](https://tidelift.com/security).
5
+
6
+ Tidelift will coordinate the fix and disclosure.
data/changelog.txt CHANGED
@@ -1,3 +1,76 @@
1
+ v1.2.3 11/10/25
2
+ ===============
3
+
4
+ add set_title to set terminal title via escape sequences
5
+
6
+ v1.2.2 10/28/25
7
+ ===============
8
+
9
+ add faint
10
+
11
+ v1.2.1 09/17/25
12
+ ===============
13
+
14
+ add color output support for github actions
15
+ fix most lints
16
+
17
+ v1.2.0 08/08/25
18
+ ===============
19
+
20
+ switch to reline for table-width calculations
21
+
22
+ v1.1.1 07/11/25
23
+ ===============
24
+
25
+ update actions/stale
26
+ update actions/checkout
27
+ improve unicode support
28
+ update ruby versions in test matrix
29
+ add funding info
30
+ move scheduled CI to weekly
31
+ update tested ruby versions
32
+ more consistently use length method in tables
33
+ adjust expected test output for Ruby 3.4+
34
+
35
+ v1.1.0 01/24/22
36
+ ===============
37
+
38
+ fixes to support ruby 3+
39
+ add options for right justifying numerics
40
+ drop unused gemspec directive
41
+ use https for rubygems.org in gemspec
42
+ drop duplicate bundle install from CI setup
43
+
44
+ v1.0.0 01/20/21
45
+ ===============
46
+
47
+ release v1, it's been stable for ages
48
+
49
+ v0.3.0 06/17/21
50
+ ===============
51
+
52
+ add travis badge to readme
53
+ change readme to md
54
+ fix markdown readme
55
+ fix travis badge
56
+ monkey-patch StringIO to try and fix jruby build
57
+ override tty? for jruby build
58
+ fix copyright statement
59
+ use unicode.width instead of string.length
60
+ remove unicode from requirements, use only if loaded
61
+ display datum who's value is a FalseClass
62
+ more colors with syntax-specific code/length limitations
63
+ better code visualization in readme
64
+ update readme
65
+ remove broken rubinius build from CI
66
+ fix length method to detect multibyte char width
67
+ fix test for table with multi byte chars
68
+ support multibyte characters
69
+ update CI to 2.2.7, 2.3.4, and 2.4.1
70
+ drop rubyforge_project from gemspec and rakefile
71
+ change github reference to https
72
+ change readme.rdoc to readme.md in gemspec
73
+
1
74
  v0.2.5 05/23/14
2
75
  ===============
3
76
 
data/formatador.gemspec CHANGED
@@ -7,15 +7,14 @@
7
7
  Gem::Specification.new do |s|
8
8
  s.specification_version = 2 if s.respond_to? :specification_version=
9
9
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
10
- s.rubygems_version = '1.3.5'
10
+ s.rubygems_version = '3.6.9'
11
11
 
12
12
  ## Leave these as is they will be modified for you by the rake gemspec task.
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'formatador'
16
- s.version = '0.2.5'
17
- s.date = '2014-05-23'
18
- s.rubyforge_project = 'formatador'
16
+ s.version = '1.2.3'
17
+ s.date = '2025-11-10'
19
18
 
20
19
  ## Make sure your summary is short. The description may be as long
21
20
  ## as you like.
@@ -27,7 +26,8 @@ Gem::Specification.new do |s|
27
26
  ## a custom homepage, consider using your GitHub URL or the like.
28
27
  s.authors = ["geemus (Wesley Beary)"]
29
28
  s.email = 'geemus@gmail.com'
30
- s.homepage = "http://github.com/geemus/#{s.name}"
29
+ s.homepage = "https://github.com/geemus/#{s.name}"
30
+ s.license = 'MIT'
31
31
 
32
32
  ## This gets added to the $LOAD_PATH so that 'lib/NAME.rb' can be required as
33
33
  ## require 'NAME.rb' or'/lib/NAME/file.rb' can be as require 'NAME/file.rb'
@@ -44,15 +44,17 @@ Gem::Specification.new do |s|
44
44
  ## Specify any RDoc options here. You'll want to add your README and
45
45
  ## LICENSE files to the extra_rdoc_files list.
46
46
  s.rdoc_options = ["--charset=UTF-8"]
47
- s.extra_rdoc_files = %w[README.rdoc]
47
+ s.extra_rdoc_files = %w[README.md]
48
48
 
49
49
  ## List your runtime dependencies here. Runtime dependencies are those
50
50
  ## that are needed for an end user to actually USE your code.
51
51
  # s.add_dependency('DEPNAME', [">= 1.1.0", "< 2.0.0"])
52
+ s.add_dependency('reline')
52
53
 
53
54
  ## List your development dependencies here. Development dependencies are
54
55
  ## those that are only needed during development
55
56
  s.add_development_dependency('rake')
57
+ s.add_development_dependency('rdoc')
56
58
  s.add_development_dependency('shindo')
57
59
 
58
60
  ## Leave this section as-is. It will be automatically generated from the
@@ -64,8 +66,9 @@ Gem::Specification.new do |s|
64
66
  CONTRIBUTORS.md
65
67
  Gemfile
66
68
  LICENSE.md
67
- README.rdoc
69
+ README.md
68
70
  Rakefile
71
+ SECURITY.md
69
72
  changelog.txt
70
73
  formatador.gemspec
71
74
  lib/formatador.rb
@@ -76,8 +79,4 @@ Gem::Specification.new do |s|
76
79
  tests/tests_helper.rb
77
80
  ]
78
81
  # = MANIFEST =
79
-
80
- ## Test files will be grabbed from the file list. Make sure the path glob
81
- ## matches what you actually use.
82
- s.test_files = s.files.select { |path| path =~ /^[spec|tests]\/.*_[spec|tests]\.rb/ }
83
82
  end
@@ -1,20 +1,20 @@
1
1
  class Formatador
2
- def display_table(hashes, keys = nil, &block)
2
+ def display_table(hashes, keys = nil, **options, &block)
3
3
  new_hashes = hashes.inject([]) do |accum,item|
4
4
  accum << :split unless accum.empty?
5
5
  accum << item
6
6
  end
7
- display_compact_table(new_hashes, keys, &block)
7
+ display_compact_table(new_hashes, keys, **options, &block)
8
8
  end
9
9
 
10
- def display_compact_table(hashes, keys = nil, &block)
10
+ def display_compact_table(hashes, keys = nil, **options, &block)
11
11
  headers = keys || []
12
12
  widths = {}
13
13
 
14
14
  # Calculate Widths
15
15
  if hashes.empty? && keys
16
16
  keys.each do |key|
17
- widths[key] = key.to_s.length
17
+ widths[key] = length(key)
18
18
  end
19
19
  else
20
20
  hashes.each do |hash|
@@ -24,7 +24,7 @@ class Formatador
24
24
  if !keys
25
25
  headers << key
26
26
  end
27
- widths[key] = [ length(key), widths[key] || 0, length(calculate_datum(key, hash)) || 0].max
27
+ widths[key] = [length(key), widths[key] || 0, length(calculate_datum(key, hash)) || 0].max
28
28
  end
29
29
  headers = headers.uniq
30
30
  end
@@ -52,25 +52,25 @@ class Formatador
52
52
  # Display data row
53
53
  columns = []
54
54
  headers.each do |header|
55
- columns << "[bold]#{header}[/]#{' ' * (widths[header] - header.to_s.length)}"
55
+ columns << "[bold]#{header}[/]#{' ' * (widths[header] - length(header))}"
56
56
  end
57
57
  display_line("| #{columns.join(' | ')} |")
58
58
  display_line(split)
59
59
 
60
60
  hashes.each do |hash|
61
61
  if hash.respond_to? :keys
62
- columns = []
63
- headers.each do |header|
62
+ columns = headers.map do |header|
64
63
  datum = calculate_datum(header, hash)
65
64
  width = widths[header] - length(datum)
66
65
  width = width < 0 ? 0 : width
67
- columns << "#{datum}#{' ' * width}"
66
+
67
+ datum.is_a?(Numeric) && options[:numeric_rjust] ? "#{' ' * width}#{datum}" : "#{datum}#{' ' * width}"
68
68
  end
69
69
  display_line("| #{columns.join(' | ')} |")
70
70
  else
71
71
  if hash == :split
72
72
  display_line(split)
73
- end
73
+ end
74
74
  end
75
75
  nil
76
76
  end
@@ -80,7 +80,10 @@ class Formatador
80
80
  private
81
81
 
82
82
  def length(value)
83
- value.to_s.gsub(PARSE_REGEX, '').length
83
+ Reline::Unicode.calculate_width(value.to_s.gsub(PARSE_REGEX, ''))
84
+
85
+ rescue NotImplementedError
86
+ value.to_s.gsub(PARSE_REGEX, '').chars.reduce(0) { |sum, char| sum += char.bytesize > 1 ? 2 : 1 }
84
87
  end
85
88
 
86
89
  def calculate_datum(header, hash)
@@ -91,7 +94,7 @@ class Formatador
91
94
  datum = d[split] || d[split.to_sym] || ''
92
95
  end
93
96
  else
94
- datum = hash[header] || ''
97
+ datum = hash.fetch(header, '')
95
98
  end
96
99
  datum
97
100
  end
data/lib/formatador.rb CHANGED
@@ -1,60 +1,64 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.join(File.dirname(__FILE__), 'formatador', 'table')
2
4
  require File.join(File.dirname(__FILE__), 'formatador', 'progressbar')
3
5
 
4
- class Formatador
6
+ require 'reline' # for table char width calculations
5
7
 
6
- VERSION = '0.2.5'
8
+ class Formatador
9
+ VERSION = '1.2.3'
7
10
 
8
11
  STYLES = {
9
- :"\/" => "0",
10
- :reset => "0",
11
- :bold => "1",
12
- :underline => "4",
13
- :blink_slow => "5",
14
- :blink_fast => "6",
15
- :negative => "7", # invert color/color
16
- :normal => "22",
17
- :underline_none => "24",
18
- :blink_off => "25",
19
- :positive => "27", # revert color/color
20
- :_black_ => "40",
21
- :_red_ => "41",
22
- :_green_ => "42",
23
- :_yellow_ => "43",
24
- :_blue_ => "44",
25
- :_magenta_ => "45",
26
- :_purple_ => "45",
27
- :_cyan_ => "46",
28
- :_white_ => "47",
29
- :_light_black_ => "100",
30
- :_light_red_ => "101",
31
- :_light_green_ => "102",
32
- :_light_yellow_ => "103",
33
- :_light_blue_ => "104",
34
- :_light_magenta_ => "105",
35
- :_light_purple_ => "105",
36
- :_light_cyan_ => "106",
37
- :black => "30",
38
- :red => "31",
39
- :green => "32",
40
- :yellow => "33",
41
- :blue => "34",
42
- :magenta => "35",
43
- :purple => "35",
44
- :cyan => "36",
45
- :white => "37",
46
- :light_black => "90",
47
- :light_red => "91",
48
- :light_green => "92",
49
- :light_yellow => "93",
50
- :light_blue => "94",
51
- :light_magenta => "95",
52
- :light_purple => "95",
53
- :light_cyan => "96",
54
- }
55
-
56
- PARSE_REGEX = /\[(#{ STYLES.keys.join('|') })\]/ix
57
- INDENT_REGEX = /\[indent\]/ix
12
+ "\/": '0',
13
+ reset: '0',
14
+ bold: '1',
15
+ faint: '2',
16
+ underline: '4',
17
+ blink_slow: '5',
18
+ blink_fast: '6',
19
+ negative: '7', # invert color/color
20
+ normal: '22',
21
+ underline_none: '24',
22
+ blink_off: '25',
23
+ positive: '27', # revert color/color
24
+ _black_: '40',
25
+ _red_: '41',
26
+ _green_: '42',
27
+ _yellow_: '43',
28
+ _blue_: '44',
29
+ _magenta_: '45',
30
+ _purple_: '45',
31
+ _cyan_: '46',
32
+ _white_: '47',
33
+ _light_black_: '100',
34
+ _light_red_: '101',
35
+ _light_green_: '102',
36
+ _light_yellow_: '103',
37
+ _light_blue_: '104',
38
+ _light_magenta_: '105',
39
+ _light_purple_: '105',
40
+ _light_cyan_: '106',
41
+ black: '30',
42
+ red: '31',
43
+ green: '32',
44
+ yellow: '33',
45
+ blue: '34',
46
+ magenta: '35',
47
+ purple: '35',
48
+ cyan: '36',
49
+ white: '37',
50
+ light_black: '90',
51
+ light_red: '91',
52
+ light_green: '92',
53
+ light_yellow: '93',
54
+ light_blue: '94',
55
+ light_magenta: '95',
56
+ light_purple: '95',
57
+ light_cyan: '96'
58
+ }.freeze
59
+
60
+ PARSE_REGEX = /\[(#{STYLES.keys.join('|')})\]/ix.freeze
61
+ INDENT_REGEX = /\[indent\]/ix.freeze
58
62
 
59
63
  def initialize
60
64
  @indent = 1
@@ -62,7 +66,7 @@ class Formatador
62
66
 
63
67
  def display(string = '')
64
68
  print(parse("[indent]#{string}"))
65
- STDOUT.flush
69
+ $stdout.flush
66
70
  nil
67
71
  end
68
72
 
@@ -73,21 +77,21 @@ class Formatador
73
77
  end
74
78
 
75
79
  def display_lines(lines = [])
76
- for line in [*lines]
80
+ [*lines].each do |line|
77
81
  display_line(line)
78
82
  end
79
83
  nil
80
84
  end
81
85
 
82
86
  def parse(string)
83
- if STDOUT.tty?
84
- string.gsub(PARSE_REGEX) { "\e[#{STYLES[$1.to_sym]}m" }.gsub(INDENT_REGEX) { indentation }
87
+ if color_support
88
+ string.gsub(PARSE_REGEX) { "\e[#{STYLES[::Regexp.last_match(1).to_sym]}m" }.gsub(INDENT_REGEX) { indentation }
85
89
  else
86
90
  strip(string)
87
91
  end
88
92
  end
89
93
 
90
- def indent(&block)
94
+ def indent
91
95
  @indent += 1
92
96
  yield
93
97
  ensure
@@ -100,7 +104,7 @@ class Formatador
100
104
 
101
105
  def redisplay(string = '', width = 120)
102
106
  print("\r#{' ' * width}\r")
103
- display("#{string}")
107
+ display(string.to_s)
104
108
  nil
105
109
  end
106
110
 
@@ -115,11 +119,17 @@ class Formatador
115
119
  nil
116
120
  end
117
121
 
122
+ def set_title(title)
123
+ print("\033]0;#{title}\007")
124
+ $stdout.flush
125
+ nil
126
+ end
127
+
118
128
  def strip(string)
119
129
  string.gsub(PARSE_REGEX, '').gsub(INDENT_REGEX) { indentation }
120
130
  end
121
131
 
122
- %w{display display_line display_lines display_table display_compact_table indent parse redisplay redisplay_line new_line redisplay_progressbar}.each do |method|
132
+ %w[display display_line display_lines indent parse redisplay redisplay_line new_line redisplay_progressbar set_title].each do |method|
123
133
  eval <<-DEF
124
134
  def self.#{method}(*args, &block)
125
135
  Thread.current[:formatador] ||= new
@@ -128,4 +138,18 @@ class Formatador
128
138
  DEF
129
139
  end
130
140
 
141
+ %w[display_table display_compact_table].each do |method|
142
+ eval <<-DEF
143
+ def self.#{method}(*args, **kwargs, &block)
144
+ Thread.current[:formatador] ||= new
145
+ Thread.current[:formatador].#{method}(*args, **kwargs, &block)
146
+ end
147
+ DEF
148
+ end
149
+
150
+ private
151
+
152
+ def color_support
153
+ @color_support ||= $stdout.tty? || ENV['GITHUB_ACTIONS'] == 'true'
154
+ end
131
155
  end
data/tests/table_tests.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # coding: utf-8
1
2
  Shindo.tests("Formatador: tables") do
2
3
 
3
4
  output = <<-OUTPUT
@@ -63,6 +64,16 @@ output = Formatador.parse(output)
63
64
  end
64
65
  end
65
66
 
67
+
68
+ if (RUBY_VERSION.split('.').map(&:to_i) <=> [3, 4, 0]).positive?
69
+ output = <<-OUTPUT
70
+ +---+----------------+
71
+ | [bold]a[/] | [bold]nested[/] |
72
+ +---+----------------+
73
+ | 1 | {key: "value"} |
74
+ +---+----------------+
75
+ OUTPUT
76
+ else
66
77
  output = <<-OUTPUT
67
78
  +---+-----------------+
68
79
  | [bold]a[/] | [bold]nested[/] |
@@ -70,6 +81,7 @@ output = <<-OUTPUT
70
81
  | 1 | {:key=>"value"} |
71
82
  +---+-----------------+
72
83
  OUTPUT
84
+ end
73
85
  output = Formatador.parse(output)
74
86
 
75
87
  tests("#display_table([{:a => 1, :nested => {:key => 'value'}}])").returns(output) do
@@ -93,4 +105,70 @@ output = Formatador.parse(output)
93
105
  end
94
106
  end
95
107
 
96
- end
108
+ output = <<-OUTPUT
109
+ +-------------------------+----------------+
110
+ | [bold]right-justify a numeric[/] | [bold]standard value[/] |
111
+ +-------------------------+----------------+
112
+ | 12345 | value |
113
+ +-------------------------+----------------+
114
+ OUTPUT
115
+ output = Formatador.parse(output)
116
+
117
+ tests("#display_table([{'right-justify a numeric' => 12345, 'standard value' => 'standard value'}], numeric_rjust: true)").returns(output) do
118
+ capture_stdout do
119
+ Formatador.display_table([{'right-justify a numeric' => 12345, 'standard value' => 'value'}], numeric_rjust: true)
120
+ end
121
+ end
122
+
123
+ output = <<-OUTPUT
124
+ +--------+------------+
125
+ | [bold]header[/] | [bold]nested.key[/] |
126
+ +--------+------------+
127
+ | 12345 | value |
128
+ +--------+------------+
129
+ OUTPUT
130
+ output = Formatador.parse(output)
131
+
132
+ tests("#display_table([{:header => 12345, :nested => {:key => value}}], [:header, :'nested.key'], numeric_rjust: true)").returns(output) do
133
+ capture_stdout do
134
+ Formatador.display_table([{:header => 12345, :nested => {:key => 'value'}}], [:header, :'nested.key'], numeric_rjust: true)
135
+ end
136
+ end
137
+
138
+
139
+ output = <<-OUTPUT
140
+ +------+
141
+ | [bold]a[/] |
142
+ +------+
143
+ | 1 |
144
+ +------+
145
+ | 震度 |
146
+ +------+
147
+ OUTPUT
148
+ output = Formatador.parse(output)
149
+
150
+ tests("#display_table([{:a => 1}, {:a => '震度'}])").returns(output) do
151
+ capture_stdout do
152
+ Formatador.display_table([{:a => 1}, {:a => "震度"}])
153
+ end
154
+ end
155
+
156
+ output = <<-OUTPUT
157
+ +----+
158
+ | [bold]a[/] |
159
+ +----+
160
+ | 1 |
161
+ +----+
162
+ | 🤷 |
163
+ +----+
164
+ OUTPUT
165
+ output = Formatador.parse(output)
166
+
167
+ tests("#display_table([{:a => 1}, {:a => '🤷'}])").returns(output) do
168
+ capture_stdout do
169
+ Formatador.display_table([{:a => 1}, {:a => '🤷'}])
170
+ end
171
+ end
172
+
173
+
174
+ end
@@ -5,6 +5,18 @@ require 'rubygems'
5
5
  require 'shindo'
6
6
  require 'stringio'
7
7
 
8
+ class IO
9
+ def tty?
10
+ true
11
+ end
12
+ end
13
+
14
+ class StringIO
15
+ def tty?
16
+ true
17
+ end
18
+ end
19
+
8
20
  def capture_stdout
9
21
  old_stdout = $stdout
10
22
  new_stdout = StringIO.new
metadata CHANGED
@@ -1,41 +1,68 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: formatador
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - geemus (Wesley Beary)
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2014-05-23 00:00:00.000000000 Z
10
+ date: 2025-11-10 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: reline
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: rake
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
- - - ! '>='
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rdoc
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
18
45
  - !ruby/object:Gem::Version
19
46
  version: '0'
20
47
  type: :development
21
48
  prerelease: false
22
49
  version_requirements: !ruby/object:Gem::Requirement
23
50
  requirements:
24
- - - ! '>='
51
+ - - ">="
25
52
  - !ruby/object:Gem::Version
26
53
  version: '0'
27
54
  - !ruby/object:Gem::Dependency
28
55
  name: shindo
29
56
  requirement: !ruby/object:Gem::Requirement
30
57
  requirements:
31
- - - ! '>='
58
+ - - ">="
32
59
  - !ruby/object:Gem::Version
33
60
  version: '0'
34
61
  type: :development
35
62
  prerelease: false
36
63
  version_requirements: !ruby/object:Gem::Requirement
37
64
  requirements:
38
- - - ! '>='
65
+ - - ">="
39
66
  - !ruby/object:Gem::Version
40
67
  version: '0'
41
68
  description: STDOUT text formatting
@@ -43,14 +70,15 @@ email: geemus@gmail.com
43
70
  executables: []
44
71
  extensions: []
45
72
  extra_rdoc_files:
46
- - README.rdoc
73
+ - README.md
47
74
  files:
48
75
  - CONTRIBUTING.md
49
76
  - CONTRIBUTORS.md
50
77
  - Gemfile
51
78
  - LICENSE.md
52
- - README.rdoc
79
+ - README.md
53
80
  - Rakefile
81
+ - SECURITY.md
54
82
  - changelog.txt
55
83
  - formatador.gemspec
56
84
  - lib/formatador.rb
@@ -59,29 +87,26 @@ files:
59
87
  - tests/basic_tests.rb
60
88
  - tests/table_tests.rb
61
89
  - tests/tests_helper.rb
62
- homepage: http://github.com/geemus/formatador
63
- licenses: []
90
+ homepage: https://github.com/geemus/formatador
91
+ licenses:
92
+ - MIT
64
93
  metadata: {}
65
- post_install_message:
66
94
  rdoc_options:
67
- - --charset=UTF-8
95
+ - "--charset=UTF-8"
68
96
  require_paths:
69
97
  - lib
70
98
  required_ruby_version: !ruby/object:Gem::Requirement
71
99
  requirements:
72
- - - ! '>='
100
+ - - ">="
73
101
  - !ruby/object:Gem::Version
74
102
  version: '0'
75
103
  required_rubygems_version: !ruby/object:Gem::Requirement
76
104
  requirements:
77
- - - ! '>='
105
+ - - ">="
78
106
  - !ruby/object:Gem::Version
79
107
  version: '0'
80
108
  requirements: []
81
- rubyforge_project: formatador
82
- rubygems_version: 2.2.2
83
- signing_key:
109
+ rubygems_version: 3.6.9
84
110
  specification_version: 2
85
111
  summary: Ruby STDOUT text formatting
86
112
  test_files: []
87
- has_rdoc: