columnist 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0fa0309605840f3f0d3703adf7b0aeec35c32458
4
- data.tar.gz: da7cd50f03f621888fedd2cb2ac4a42243c098b3
3
+ metadata.gz: 8962f15088195abd57cc2343cff652e21cdf6cfa
4
+ data.tar.gz: cbd0348c061ef751a9fe77c772603ccfe34a2f13
5
5
  SHA512:
6
- metadata.gz: d1b9986c7cf20d37fad2b7dc5e52f55571caa290a955c459d4051c42522f4d831a74b37dfa3671d260981849330655dc1510f8fb1224f51d912eb4df43d0f35f
7
- data.tar.gz: 6c12a03ec438fffffbce01633cea2052c1f3f23fb3231bf72955305b7ed54206064427ab9ce98a112297da9dda5239de74655855b19955bf48c0525f39feaa84
6
+ metadata.gz: 6440fd90b250f7c050f588b8c139e12e892d653e3388898663489225f8fafa0fe5e3e3d641ceef1da5dbdef0ed3937b5fb3545f696bb6972d220678949c94f00
7
+ data.tar.gz: 2006cfcb0515993cc9940c58f5b5062de17cceceb5e092b9b8f62b5b785902224ae7631537ef3a8174d6116b0c39f18e69afe16bf393dd7ebfacb7920331caa5
@@ -5,19 +5,19 @@ module Columnist
5
5
  include OptionsValidator
6
6
 
7
7
  VALID_OPTIONS = [:width, :padding, :align, :color, :bold, :underline, :reversed]
8
- attr_accessor :text, :size, *VALID_OPTIONS
8
+ attr_accessor :text, :text_without_colors, :size, *VALID_OPTIONS
9
9
 
10
10
  def initialize(text = nil, options = {})
11
11
  self.validate_options(options, *VALID_OPTIONS)
12
- self.text = text.to_s
13
- self.width = options[:width] || 10
14
- self.align = options[:align] || 'left'
15
- self.padding = options[:padding] || 0
16
- self.color = options[:color] || nil
17
- self.bold = options[:bold] || false
18
- self.underline = options[:underline] || false
19
- self.reversed = options[:reversed] || false
20
-
12
+ self.text_without_colors = text.to_s.gsub(/(.)\[\d{1,3};\d{1,3};\d{1,3}m/, '')
13
+ self.text = text.to_s
14
+ self.width = options[:width] || 10
15
+ self.align = options[:align] || 'left'
16
+ self.padding = options[:padding] || 0
17
+ self.color = options[:color] || nil
18
+ self.bold = options[:bold] || false
19
+ self.underline = options[:underline] || false
20
+ self.reversed = options[:reversed] || false
21
21
  raise ArgumentError unless self.width > 0
22
22
  raise ArgumentError unless self.padding.to_s.match(/^\d+$/)
23
23
  end
@@ -27,14 +27,37 @@ module Columnist
27
27
  end
28
28
 
29
29
  def required_width
30
- self.text.to_s.size + 2 * self.padding
30
+ self.text_without_colors.to_s.size + 2 * self.padding
31
31
  end
32
32
 
33
33
  def screen_rows
34
- if self.text.nil? || self.text.empty?
34
+ if self.text_without_colors.nil? || self.text_without_colors.empty?
35
35
  [' ' * self.width]
36
36
  else
37
- self.text.scan(/.{1,#{self.size}}/m).map { |s| to_cell(s) }
37
+ x = self.text.scan(/.{1,#{self.size}}/).map { |s| to_cell(s) }
38
+ if x.length > 1
39
+ actual_length = 0
40
+ x.each do |z|
41
+ z = z.gsub(/\A(.)\[\d{1,3};\d{1,3};\d{1,3}m/, '').gsub(/\s+(.)\[\d{1,3};\d{1,3};\d{1,3}m\z/, '')
42
+ characters_to_ignore = 0
43
+ matches_to_ignore = z.scan(/\[\d{1,3};\d{1,3};\d{1,3}m/)
44
+ matches_to_ignore.each do |match|
45
+ characters_to_ignore += match.length + 1
46
+ end
47
+ actual_length += z.length - characters_to_ignore
48
+ end
49
+ if actual_length < self.size
50
+ y = []
51
+ x.each do |z|
52
+ y << z.gsub(/\A(.)\[\d{1,3};\d{1,3};\d{1,3}m/, '').gsub(/\s+(.)\[\d{1,3};\d{1,3};\d{1,3}m\z/, '')
53
+ end
54
+ y = ["#{y.join}#{' ' * (self.size - actual_length)}"]
55
+ return y
56
+ end
57
+ return [x[0]]
58
+ else
59
+ return x
60
+ end
38
61
  end
39
62
  end
40
63
 
@@ -44,7 +67,7 @@ module Columnist
44
67
  # NOTE: For making underline and reversed work Change so that based on the
45
68
  # unformatted text it determines how much spacing to add left and right
46
69
  # then colorize the cell text
47
- cell = str.empty? ? blank_cell : aligned_cell(str)
70
+ cell = str.empty? ? blank_cell : aligned_cell(str)
48
71
  padding_str = ' ' * self.padding
49
72
  padding_str + colorize(cell) + padding_str
50
73
  end
@@ -2,69 +2,69 @@ require 'singleton'
2
2
  require 'colored'
3
3
 
4
4
  module Columnist
5
- class NestedFormatter
6
- include Singleton
7
- include OptionsValidator
5
+ class NestedFormatter
6
+ include Singleton
7
+ include OptionsValidator
8
8
 
9
- VALID_OPTIONS = [:message, :type, :complete, :indent_size, :color, :bold]
10
- attr_accessor :indent_size, :complete_string, :message_string, :color, :bold
9
+ VALID_OPTIONS = [:message, :type, :complete, :indent_size, :color, :bold]
10
+ attr_accessor :indent_size, :complete_string, :message_string, :color, :bold
11
11
 
12
- def format(options, block)
13
- self.validate_options(options, *VALID_OPTIONS)
12
+ def format(options, block)
13
+ self.validate_options(options, *VALID_OPTIONS)
14
14
 
15
- indent_level :incr
15
+ indent_level :incr
16
16
 
17
- padding = ' ' * @indent_level * (options[:indent_size] || self.indent_size)
17
+ padding = ' ' * @indent_level * (options[:indent_size] || self.indent_size)
18
18
 
19
- message_str = padding + (options[:message] || self.message_string)
20
- complete_str = options[:complete] || self.complete_string
19
+ message_str = padding + (options[:message] || self.message_string)
20
+ complete_str = options[:complete] || self.complete_string
21
21
 
22
- if options[:type] == 'inline'
23
- colorize("#{message_str}...", true, options)
24
- else
25
- colorize(message_str, false, options)
26
- complete_str = padding + complete_str
27
- end
22
+ if options[:type] == 'inline'
23
+ colorize("#{message_str}...", true, options)
24
+ else
25
+ colorize(message_str, false, options)
26
+ complete_str = padding + complete_str
27
+ end
28
28
 
29
- block.call
29
+ block.call
30
30
 
31
- colorize(complete_str, false, options)
31
+ colorize(complete_str, false, options)
32
32
 
33
- indent_level :decr
34
- end
33
+ indent_level :decr
34
+ end
35
35
 
36
- def message_string
37
- @message_string ||= 'working'
38
- end
36
+ def message_string
37
+ @message_string ||= 'working'
38
+ end
39
39
 
40
- def complete_string
41
- @complete_string ||= 'complete'
42
- end
40
+ def complete_string
41
+ @complete_string ||= 'complete'
42
+ end
43
43
 
44
- def indent_size
45
- @indent_size ||= 2
46
- end
44
+ def indent_size
45
+ @indent_size ||= 2
46
+ end
47
47
 
48
- private
48
+ private
49
49
 
50
- def colorize(str, inline, options)
51
- str = str.send(options[:color]) if options[:color]
52
- str = str.bold if options[:bold]
50
+ def colorize(str, inline, options)
51
+ str = str.send(options[:color]) if options[:color]
52
+ str = str.bold if options[:bold]
53
53
 
54
- if inline
55
- print str
56
- else
57
- puts str
58
- end
59
- end
54
+ if inline
55
+ print str
56
+ else
57
+ puts str
58
+ end
59
+ end
60
60
 
61
- def indent_level(value)
62
- case value
63
- when :incr
64
- @indent_level = (@indent_level) ? @indent_level + 1 : 0
65
- when :decr
66
- @indent_level -= 1
67
- end
61
+ def indent_level(value)
62
+ case value
63
+ when :incr
64
+ @indent_level = (@indent_level) ? @indent_level + 1 : 0
65
+ when :decr
66
+ @indent_level -= 1
67
+ end
68
+ end
68
69
  end
69
- end
70
70
  end
@@ -2,36 +2,36 @@ require 'singleton'
2
2
  require 'colored'
3
3
 
4
4
  module Columnist
5
- class ProgressFormatter
6
- include Singleton
7
- include OptionsValidator
5
+ class ProgressFormatter
6
+ include Singleton
7
+ include OptionsValidator
8
8
 
9
- VALID_OPTIONS = [:indicator, :color, :bold]
10
- attr_accessor *VALID_OPTIONS
9
+ VALID_OPTIONS = [:indicator, :color, :bold]
10
+ attr_accessor *VALID_OPTIONS
11
11
 
12
- def format(options, block)
13
- self.validate_options(options, *VALID_OPTIONS)
12
+ def format(options, block)
13
+ self.validate_options(options, *VALID_OPTIONS)
14
14
 
15
- self.indicator = options[:indicator] if options[:indicator]
16
- self.color = options[:color]
17
- self.bold = options[:bold] || false
15
+ self.indicator = options[:indicator] if options[:indicator]
16
+ self.color = options[:color]
17
+ self.bold = options[:bold] || false
18
18
 
19
- block.call
19
+ block.call
20
20
 
21
- puts
22
- end
21
+ puts
22
+ end
23
23
 
24
- def progress(override = nil)
25
- str = override || self.indicator
24
+ def progress(override = nil)
25
+ str = override || self.indicator
26
26
 
27
- str = str.send(self.color) if self.color
28
- str = str.send('bold') if self.bold
27
+ str = str.send(self.color) if self.color
28
+ str = str.send('bold') if self.bold
29
29
 
30
- print str
31
- end
30
+ print str
31
+ end
32
32
 
33
- def indicator
34
- @indicator ||= '.'
33
+ def indicator
34
+ @indicator ||= '.'
35
+ end
35
36
  end
36
- end
37
37
  end
@@ -1,5 +1,5 @@
1
1
  module OptionsValidator
2
- def validate_options(provided, *allowed_keys)
3
- raise(ArgumentError, "Valid options: #{allowed_keys}") unless (provided.keys - allowed_keys).empty?
4
- end
2
+ def validate_options(provided, *allowed_keys)
3
+ raise(ArgumentError, "Valid options: #{allowed_keys}") unless (provided.keys - allowed_keys).empty?
4
+ end
5
5
  end
data/lib/columnist/row.rb CHANGED
@@ -7,13 +7,13 @@ module Columnist
7
7
 
8
8
  def initialize(options = {})
9
9
  self.validate_options(options, *VALID_OPTIONS)
10
- self.columns = []
11
- self.border = false
12
- self.header = options[:header] || false
13
- self.color = options[:color]
10
+ self.columns = []
11
+ self.border = false
12
+ self.header = options[:header] || false
13
+ self.color = options[:color]
14
14
  self.border_color = options[:border_color]
15
- self.bold = options[:bold] || false
16
- self.encoding = options[:encoding] || :unicode
15
+ self.bold = options[:bold] || false
16
+ self.encoding = options[:encoding] || :unicode
17
17
  end
18
18
 
19
19
  def add(column)
@@ -32,7 +32,7 @@ module Columnist
32
32
  screen_count.times do |sr|
33
33
  border_char = use_utf8? ? "\u2503" : '|'
34
34
  border_char = colorize(border_char, self.border_color)
35
- line = (self.border) ? "#{border_char} " : ''
35
+ line = (self.border) ? "#{border_char} " : ''
36
36
  self.columns.size.times do |mc|
37
37
  col = self.columns[mc]
38
38
  # Account for the fact that some columns will have more screen rows than their
@@ -7,17 +7,17 @@ module Columnist
7
7
 
8
8
  def initialize(options = {})
9
9
  self.validate_options(options, *VALID_OPTIONS)
10
- self.border = options[:border] || false
10
+ self.border = options[:border] || false
11
11
  self.border_color = options[:border_color] || false
12
- self.width = options[:width] || false
13
- self.encoding = options[:encoding] || Columnist::DEFAULTS[:encoding]
14
- @rows = []
12
+ self.width = options[:width] || false
13
+ self.encoding = options[:encoding] || Columnist::DEFAULTS[:encoding]
14
+ @rows = []
15
15
  raise ArgumentError, 'Invalid encoding' unless [:ascii, :unicode].include? self.encoding
16
16
  end
17
17
 
18
18
  def add(row)
19
19
  # Inheritance from the table
20
- row.border = self.border
20
+ row.border = self.border
21
21
  row.border_color = self.border_color
22
22
 
23
23
  # Inherit properties from the appropriate row
@@ -58,8 +58,8 @@ module Columnist
58
58
 
59
59
  def separator(type = 'middle')
60
60
  left, center, right, bar = use_utf8? ? utf8_separator(type) : ascii_separator
61
- separator_str = left + self.rows[0].columns.map { |c| bar * (c.width + 2) }.join(center) + right
62
- separator_str = colorize(separator_str, self.border_color)
61
+ separator_str = left + self.rows[0].columns.map { |c| bar * (c.width + 2) }.join(center) + right
62
+ separator_str = colorize(separator_str, self.border_color)
63
63
  end
64
64
 
65
65
  def use_utf8?
@@ -68,7 +68,7 @@ module Columnist
68
68
 
69
69
  def ascii_separator
70
70
  left = right = center = '+'
71
- bar = '-'
71
+ bar = '-'
72
72
  [left, right, center, bar]
73
73
  end
74
74
 
data/lib/columnist.rb CHANGED
@@ -8,166 +8,166 @@ require 'columnist/column'
8
8
  require 'columnist/table'
9
9
 
10
10
  module Columnist
11
- include OptionsValidator
12
-
13
- attr_reader :formatter
14
-
15
- DEFAULTS = {
16
- :width => 100,
17
- :align => 'left',
18
- :formatter => 'nested',
19
- :encoding => :unicode,
20
- }
11
+ include OptionsValidator
12
+
13
+ attr_reader :formatter
14
+
15
+ DEFAULTS = {
16
+ :width => 100,
17
+ :align => 'left',
18
+ :formatter => 'nested',
19
+ :encoding => :unicode,
20
+ }
21
+
22
+ def capture_output
23
+ $stdout.rewind
24
+ $stdout.read
25
+ ensure
26
+ $stdout = STDOUT
27
+ end
21
28
 
22
- def capture_output
23
- $stdout.rewind
24
- $stdout.read
25
- ensure
26
- $stdout = STDOUT
27
- end
28
-
29
- def suppress_output
30
- $stdout = StringIO.new
31
- end
32
-
33
- def restore_output
34
- $stdout = STDOUT
35
- end
36
-
37
- def formatter=(type = 'nested')
38
- name = type.capitalize + 'Formatter'
39
- klass = %W{Columnist #{name}}.inject(Kernel) {|s,c| s.const_get(c)}
40
-
41
- # Each formatter is a singleton that responds to #instance
42
- @formatter = klass.instance
43
- rescue
44
- raise ArgumentError, 'Invalid formatter specified'
45
- end
46
-
47
- def header(options = {})
48
- section(:header, options)
49
- end
50
-
51
- def report(options = {}, &block)
52
- self.formatter ||= DEFAULTS[:formatter]
53
- self.formatter.format(options, block)
54
- end
29
+ def suppress_output
30
+ $stdout = StringIO.new
31
+ end
55
32
 
56
- def progress(override = nil)
57
- self.formatter.progress(override)
58
- end
33
+ def restore_output
34
+ $stdout = STDOUT
35
+ end
59
36
 
60
- def footer(options = {})
61
- section(:footer, options)
62
- end
37
+ def formatter=(type = 'nested')
38
+ name = type.capitalize + 'Formatter'
39
+ klass = %W{Columnist #{name}}.inject(Kernel) { |s, c| s.const_get(c) }
63
40
 
64
- def horizontal_rule(options = {})
65
- validate_options(options, :char, :width, :color, :bold)
41
+ # Each formatter is a singleton that responds to #instance
42
+ @formatter = klass.instance
43
+ rescue
44
+ raise ArgumentError, 'Invalid formatter specified'
45
+ end
66
46
 
67
- # Got unicode?
68
- use_char = "\u2501" == 'u2501' ? '-' : "\u2501"
47
+ def header(options = {})
48
+ section(:header, options)
49
+ end
69
50
 
70
- char = options[:char].is_a?(String) ? options[:char] : use_char
71
- width = options[:width] || DEFAULTS[:width]
51
+ def report(options = {}, &block)
52
+ self.formatter ||= DEFAULTS[:formatter]
53
+ self.formatter.format(options, block)
54
+ end
72
55
 
73
- aligned(char * width, :width => width, :color => options[:color], :bold => options[:bold])
74
- end
56
+ def progress(override = nil)
57
+ self.formatter.progress(override)
58
+ end
75
59
 
76
- def vertical_spacing(lines = 1)
77
- puts "\n" * lines
78
- rescue
79
- raise ArgumentError
80
- end
60
+ def footer(options = {})
61
+ section(:footer, options)
62
+ end
81
63
 
82
- def datetime(options = {})
83
- validate_options(options, :align, :width, :format, :color, :bold)
64
+ def horizontal_rule(options = {})
65
+ validate_options(options, :char, :width, :color, :bold)
84
66
 
85
- format = options[:format] || '%Y-%m-%d - %l:%M:%S%p'
86
- align = options[:align] || DEFAULTS[:align]
87
- width = options[:width] || DEFAULTS[:width]
67
+ # Got unicode?
68
+ use_char = "\u2501" == 'u2501' ? '-' : "\u2501"
88
69
 
89
- text = Time.now.strftime(format)
70
+ char = options[:char].is_a?(String) ? options[:char] : use_char
71
+ width = options[:width] || DEFAULTS[:width]
90
72
 
91
- raise Exception if text.size > width
73
+ aligned(char * width, :width => width, :color => options[:color], :bold => options[:bold])
74
+ end
92
75
 
93
- aligned(text, :align => align, :width => width, :color => options[:color], :bold => options[:bold])
94
- end
76
+ def vertical_spacing(lines = 1)
77
+ puts "\n" * lines
78
+ rescue
79
+ raise ArgumentError
80
+ end
95
81
 
96
- def aligned(text, options = {})
97
- validate_options(options, :align, :width, :color, :bold)
82
+ def datetime(options = {})
83
+ validate_options(options, :align, :width, :format, :color, :bold)
98
84
 
99
- align = options[:align] || DEFAULTS[:align]
100
- width = options[:width] || DEFAULTS[:width]
101
- color = options[:color]
102
- bold = options[:bold] || false
85
+ format = options[:format] || '%Y-%m-%d - %l:%M:%S%p'
86
+ align = options[:align] || DEFAULTS[:align]
87
+ width = options[:width] || DEFAULTS[:width]
103
88
 
104
- line = case align
105
- when 'left'
106
- text
107
- when 'right'
108
- text.rjust(width)
109
- when 'center'
110
- text.rjust((width - text.size)/2 + text.size)
111
- else
112
- raise ArgumentError
113
- end
89
+ text = Time.now.strftime(format)
114
90
 
115
- line = line.send(color) if color
116
- line = line.send('bold') if bold
117
-
118
- puts line
119
- end
91
+ raise Exception if text.size > width
120
92
 
121
- def table(options = {})
122
- @table = Columnist::Table.new(options)
123
- yield
124
- @table.output
125
- end
93
+ aligned(text, :align => align, :width => width, :color => options[:color], :bold => options[:bold])
94
+ end
126
95
 
127
- def row(options = {})
128
- options[:encoding] ||= @table.encoding
129
- @row = Columnist::Row.new(options)
130
- yield
131
- @table.add(@row)
132
- end
96
+ def aligned(text, options = {})
97
+ validate_options(options, :align, :width, :color, :bold)
98
+
99
+ align = options[:align] || DEFAULTS[:align]
100
+ width = options[:width] || DEFAULTS[:width]
101
+ color = options[:color]
102
+ bold = options[:bold] || false
103
+
104
+ line = case align
105
+ when 'left'
106
+ text
107
+ when 'right'
108
+ text.rjust(width)
109
+ when 'center'
110
+ text.rjust((width - text.size)/2 + text.size)
111
+ else
112
+ raise ArgumentError
113
+ end
114
+
115
+ line = line.send(color) if color
116
+ line = line.send('bold') if bold
117
+
118
+ puts line
119
+ end
133
120
 
134
- def column(text, options = {})
135
- col = Columnist::Column.new(text, options)
136
- @row.add(col)
137
- end
121
+ def table(options = {})
122
+ @table = Columnist::Table.new(options)
123
+ yield
124
+ @table.output
125
+ end
138
126
 
139
- private
127
+ def row(options = {})
128
+ options[:encoding] ||= @table.encoding
129
+ @row = Columnist::Row.new(options)
130
+ yield
131
+ @table.add(@row)
132
+ end
140
133
 
141
- def section(type, options)
142
- title, width, align, lines, color, bold = assign_section_properties(options)
134
+ def column(text, options = {})
135
+ col = Columnist::Column.new(text, options)
136
+ @row.add(col)
137
+ end
143
138
 
144
- # This also ensures that width is a Fixnum
145
- raise ArgumentError if title.size > width
139
+ private
146
140
 
147
- if type == :footer
148
- vertical_spacing(lines)
149
- horizontal_rule(:char => options[:rule], :width => width, :color => color, :bold => bold) if options[:rule]
150
- end
141
+ def section(type, options)
142
+ title, width, align, lines, color, bold = assign_section_properties(options)
143
+
144
+ # This also ensures that width is a Fixnum
145
+ raise ArgumentError if title.size > width
151
146
 
152
- aligned(title, :align => align, :width => width, :color => color, :bold => bold)
153
- datetime(:align => align, :width => width, :color => color, :bold => bold) if options[:timestamp]
147
+ if type == :footer
148
+ vertical_spacing(lines)
149
+ horizontal_rule(:char => options[:rule], :width => width, :color => color, :bold => bold) if options[:rule]
150
+ end
154
151
 
155
- if type == :header
156
- horizontal_rule(:char => options[:rule], :width => width, :color => color, :bold => bold) if options[:rule]
157
- vertical_spacing(lines)
152
+ aligned(title, :align => align, :width => width, :color => color, :bold => bold)
153
+ datetime(:align => align, :width => width, :color => color, :bold => bold) if options[:timestamp]
154
+
155
+ if type == :header
156
+ horizontal_rule(:char => options[:rule], :width => width, :color => color, :bold => bold) if options[:rule]
157
+ vertical_spacing(lines)
158
+ end
158
159
  end
159
- end
160
160
 
161
- def assign_section_properties options
162
- validate_options(options, :title, :width, :align, :spacing, :timestamp, :rule, :color, :bold)
161
+ def assign_section_properties options
162
+ validate_options(options, :title, :width, :align, :spacing, :timestamp, :rule, :color, :bold)
163
163
 
164
- title = options[:title] || 'Report'
165
- width = options[:width] || DEFAULTS[:width]
166
- align = options[:align] || DEFAULTS[:align]
167
- lines = options[:spacing] || 1
168
- color = options[:color]
169
- bold = options[:bold] || false
164
+ title = options[:title] || 'Report'
165
+ width = options[:width] || DEFAULTS[:width]
166
+ align = options[:align] || DEFAULTS[:align]
167
+ lines = options[:spacing] || 1
168
+ color = options[:color]
169
+ bold = options[:bold] || false
170
170
 
171
- return [title, width, align, lines, color, bold]
172
- end
171
+ return [title, width, align, lines, color, bold]
172
+ end
173
173
  end