array-formatter 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 74c5fcc251fdd3259eb03c4c60aab0cbd067a4a8
4
+ data.tar.gz: b3101c02d554d3b2971752e4154aa7ad06e1b74c
5
+ SHA512:
6
+ metadata.gz: c4e0b8880b25896db9867d8a7439d83b28127fa04dd84895ab083c5cccc9223305291af7b021d78d0023a4d9868fe202a813b655c5e93d64c432267f25dc4b3f
7
+ data.tar.gz: 4698454dc011619bfbd8f75d6bbf1b05b3025c0fd88f5621cf830799c55479bac8e1d97d625eab1244962cc439f3dfce83637e485ea52a01b5300fa8ce33ef0b
@@ -0,0 +1,25 @@
1
+ # Because this is a gem, ignore Gemfile.lock:
2
+
3
+ Gemfile.lock
4
+
5
+ # And because this is Ruby, ignore the following
6
+ # (source: https://github.com/github/gitignore/blob/master/Ruby.gitignore):
7
+
8
+ *.gem
9
+ *.rbc
10
+ .bundle
11
+ .config
12
+ coverage
13
+ InstalledFiles
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
21
+
22
+ # YARD artifacts
23
+ .yardoc
24
+ _yardoc
25
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alan K. Stebbens <aks@stebbens.org>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,50 @@
1
+ # Array::Formatter
2
+
3
+ A simple gem to reformat an array of arrays into one of several formats:
4
+
5
+ - HTML table (as a string)
6
+ - CSV string
7
+ - table (using fixed-width ASCII text or Unicode drawing characters)
8
+ - YAML string
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'array-formatter'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install array-formatter
23
+
24
+ ## Usage
25
+
26
+ require 'array/formatter'
27
+
28
+ array.to_table :ascii
29
+ array.to_table :unicode
30
+ array.to_table :unicode_double
31
+ array.to_table :unicode_single
32
+ array.to_table :unicode_mixed
33
+
34
+ array.to_csv
35
+
36
+ array.to_html
37
+
38
+ array.to_yaml
39
+
40
+ ## Author:
41
+
42
+ Alan K. Stebbens <aks@stebbens.org>
43
+
44
+ ## Contributing
45
+
46
+ 1. Fork it
47
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
48
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
49
+ 4. Push to the branch (`git push origin my-new-feature`)
50
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ #require 'rake'
2
+
3
+ require "bundler/gem_tasks"
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.pattern = 'test/**/test[-_]*.rb'
9
+ t.verbose = false
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'array/formatter/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "array-formatter"
8
+ spec.version = Array::Formatter::VERSION
9
+ spec.authors = ["Alan Stebbens"]
10
+ spec.email = ["aks@stebbens.org"]
11
+ spec.summary = "Format an array of arrays in one of serveral string formats"
12
+ spec.description = <<-EOF
13
+ A simple gem to reformat an array of arrays into one of several string
14
+ formats: HTML table; CSV; ASCII table; YAML
15
+ EOF
16
+ spec.homepage = "https://gitlab.com/as/array-formatter"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files`.split($/)
20
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ end
@@ -0,0 +1,247 @@
1
+ # array-formatter.rb
2
+ #
3
+ # Author: Alan K. Stebbens <aks@stebbens.org>
4
+ #
5
+ # ARRAY.to_html -- format an array of arrays into an HTML table string
6
+ # ARRAY.to_csv -- format an array of arrays into a CSV string
7
+ # ARRAY.to_table -- format an array of arrays into an ASCII table string
8
+ #
9
+
10
+ class Array
11
+
12
+ # string = ARRAY.to_html indent=0
13
+ #
14
+ # Return an HTML representation of an array of arrays as an
15
+ # HTML table. If indent given, indent the <table> by that
16
+ # many spaces.
17
+
18
+ def to_html indent=0
19
+ require 'cgi'
20
+ s = self.wrap_map_html_data("table", indent + 0) do |row, rx|
21
+ row.wrap_map_html_data("tr", indent + 1) do |field, fx|
22
+ tag = rx == 0 ? 'th' : 'td'
23
+ (' ' * (indent + 2)) + # indention
24
+ "<#{tag}>" + # open tag
25
+ (field && CGI.escapeHTML(field) || '') + # cell text
26
+ "</#{tag}>\n" # close tag
27
+ end
28
+ end
29
+ s
30
+ end
31
+
32
+ # string = ARRAY.wrap_map_html_data TAG, INDENT {|DATA, INDEX| block}
33
+ #
34
+ # Return a string HTML representation of an array of data, starting with
35
+ # <TAG> and ending with </TAG>, and invoking the block on each array item,
36
+ # passing the DATA item with its INDEX.
37
+
38
+ def wrap_map_html_data tag, indent=0
39
+ s = ''
40
+ prefix = ' ' * indent
41
+ s << prefix + "<#{tag}>\n"
42
+ self.each_with_index {|data, x| s << ((yield data, x) || '') }
43
+ s << prefix + "</#{tag}>\n"
44
+ s
45
+ end
46
+
47
+ # string = ARRAY.to_csv
48
+ #
49
+ # Convert an array of arrays to CSV representation Basically, each
50
+ # top-level array row becomes a line of CSV data The 2nd level
51
+ # arrays become individual rows of data, separated by commas. Each
52
+ # 2nd level array item gets quoted if it contains any punctuation
53
+ # characters.
54
+
55
+ def to_csv
56
+ self.map {|row| row.map {|f| f =~ /[[:punct:]]/ ? '"' + f.gsub(/"/, '""') + '"' : f }.join(",")}.join("\n")
57
+ end
58
+
59
+ # string = ARRAY.to_table type
60
+ #
61
+ # Convert an array of arrays to ASCII table representation
62
+ #
63
+ # to create a box, we need to describe the parts of it:
64
+ # (be sure to used fixed-width font)
65
+ #
66
+ # +-------+-------+ <== top border
67
+ # | cell1 | cell2 | <== data row
68
+ # +-------+-------+ <== inner border
69
+ # | r2c1 | r2c2 | <== data row
70
+ # +-------+-------+ <== bottom border
71
+ # ^ ^ ^
72
+ # | | +--<== right
73
+ # | +----------<== middle
74
+ # +------------------<== left
75
+ #
76
+ # Given these, there are 15 specific characters for line drawing:
77
+ #
78
+ # Location Symbol Location Symbol
79
+ # ================ ====== ================ ======
80
+ # top-left-border tlb left-inner-border lib
81
+ # top-border tb inner-border ib
82
+ # top-inner-border tib middle-inner-border mib
83
+ # top-right-border trb right-inner-border rib
84
+ #
85
+ # left-data-border ldb bottom-left-border blb
86
+ # inner-data-border idb bottom-border bb
87
+ # right-data-border rdb bottom-inner-border bib
88
+ # bottom-right-border brb
89
+ #
90
+ # In the specs below, the characters are given in the same order as above.
91
+ # The characters are index by the given symbols.
92
+
93
+ class TableChars < Hash
94
+
95
+ @@table_chars = {}
96
+ @@table_char_names = %w( tlb tb tib trb ldb idb rdb lib ib mib rib blb bb bib brb ).map{|n|n.intern}
97
+
98
+ def initialize name, fmt_chars, start=nil, stop=nil
99
+ @chars = self
100
+ @@table_chars[name] = @chars
101
+ if fmt_chars.class == Symbol
102
+ @@table_chars[name] = @chars = @@table_chars[fmt_chars].dup
103
+ elsif fmt_chars.class == Array
104
+ chars = fmt_chars.dup
105
+ @@table_char_names.each{|n| @chars[n] = chars.shift || raise(ArgumentError, "Missing characters from table drawing charset!")}
106
+ end
107
+ @start = start
108
+ @stop = stop
109
+ @chars
110
+ end
111
+
112
+ @@table_char_names.each do |name|
113
+ define_method(name) { @chars[name] }
114
+ end
115
+
116
+ # TableChars.get NAME
117
+ #
118
+ # Return the TableChars object for NAME, or nil
119
+
120
+ def self.get name
121
+ @chars = @@table_chars[name]
122
+ end
123
+
124
+ attr_reader :start, :stop
125
+
126
+ def wrap text
127
+ (@start || '') + text + (@stop || '')
128
+ end
129
+
130
+ end
131
+
132
+ # :ascii -- an ASCII table
133
+
134
+ TableChars.new :ascii, %w( + - + + | | | + - + + + - + + )
135
+
136
+ # :unicode_single - a table with thick outer border, and thin inner lines.
137
+ TableChars.new :unicode_single, [ "\u250F", "\u2501", "\u252F", "\u2513", # tlb, tb, tib, trb
138
+ "\u2503", "\u2502", "\u2503", # ldb, idb, rdb
139
+ "\u2520", "\u2500", "\u253C", "\u2528", # lib, ib, mib, rib
140
+ "\u2517", "\u2501", "\u2537", "\u251B" ] # blb, bb, bib, brb
141
+
142
+ # :unicode_bold - a table with thick borders everywhere
143
+ TableChars.new :unicode_bold, [ "\u250F", "\u2501", "\u2533", "\u2513", # tlb, tb, tib, trb
144
+ "\u2503", "\u2503", "\u2503", # ldb, idb, rdb
145
+ "\u2523", "\u2501", "\u254B", "\u252B", # lib, ib, mib, rib
146
+ "\u2517", "\u2501", "\u253B", "\u251B" ] # blb, bb, bib, brb
147
+
148
+ # :unicode_double - a table with double lines everywhere
149
+ TableChars.new :unicode_double, [ "\u2554", "\u2550", "\u2566", "\u2557", # tlb, tb, tib, trb
150
+ "\u2551", "\u2551", "\u2551", # ldb, idb, rdb
151
+ "\u2560", "\u2550", "\u256C", "\u2563", # lib, ib, mib, rib
152
+ "\u255A", "\u2550", "\u2569", "\u255D" ] # blb, bb, bib, brb
153
+
154
+ # :unicode_mixed - a table with double outer lines, and single inner lines
155
+ TableChars.new :unicode_mixed, [ "\u2554", "\u2550", "\u2564", "\u2557", # tlb, tb, tib, trb
156
+ "\u2551", "\u2502", "\u2551", # ldb, idb, rdb
157
+ "\u2557", "\u2550", "\u253C", "\u2562", # lib, ib, mib, rib
158
+ "\u255A", "\u2550", "\u2567", "\u255D" ] # blb, bb, bib, brb
159
+
160
+ TableChars.new :dos_single, [ "\xDA", "\xC4", "\xC2", "\xBF", # tlb, tb, tib, trb
161
+ "\xB3", "\xB3", "\xB3", # ldb, idb, rdb
162
+ "\xC3", "\xC4", "\xC5", "\xB4", # lib, ib, mib, rib
163
+ "\xC0", "\xC4", "\xC1", "\xD9" ] # blb, bb, bib, brb
164
+
165
+ TableChars.new :dos_double, [ "\xC9", "\xCD", "\xCB", "\xBB", # tlb, tb, tib, trb
166
+ "\xBA", "\xBA", "\xBA", # ldb, idb, rdb
167
+ "\xCC", "\xCD", "\xCE", "\xB9", # lib, ib, mib, rib
168
+ "\xC8", "\xCD", "\xCA", "\xBC" ] # blb, bb, bib, brb
169
+
170
+ TableChars.new :vt100, [ "\x6C", "\x71", "\x77", "\x6B", # tlb, tb, tib, trb
171
+ "\x78", "\x78", "\x78", # ldb, idb, rdb,
172
+ "\x74", "\x71", "\x6E", "\x75", # lib, ib, mib, rib
173
+ "\xCD", "\x71", "\x76", "\x6A" ], # blb, bb, bib, brb
174
+ "\e(0", "\e(B"
175
+
176
+ TableChars.new :unicode, :unicode_single
177
+ TableChars.new :dos, :dos_single
178
+
179
+
180
+ def to_table name=:ascii
181
+ @chars = TableChars.get name
182
+
183
+ # compute the maximum widths and the alignment of each column
184
+ @widths = []
185
+ @align = []
186
+ self.each_with_index do |row,rx|
187
+ row.each_with_index do |col,cx|
188
+ @widths[cx] ||= 0
189
+ l = col.to_s.length
190
+ @widths[cx] = l if l > @widths[cx]
191
+ if rx == 0
192
+ type = nil
193
+ else
194
+ type = case (col || '')
195
+ when /^\$?\s*\d[,\d]*\.\d*$/ then :rjust # real number and/or currency
196
+ when /^\$?\s*\d[,\d]*$/ then :rjust # integer
197
+ when /^$/, /^\s*-\s*$/, nil then nil # empty values have no alignment
198
+ else :ljust
199
+ end
200
+ end
201
+ @align[cx] ||= (col ? type : nil)
202
+ @align[cx] = :ljust if type && @align[cx] != type && rx > 0
203
+ end
204
+ end
205
+
206
+ # now format each row
207
+ s = ''
208
+ self.each_with_index do |row, rx|
209
+ s << table_line(rx == 0 ? :top : :middle)
210
+ s << table_data(row)
211
+ end
212
+ s << table_line(:bottom)
213
+ s
214
+ end
215
+
216
+ ##
217
+ # table_line position
218
+ #
219
+ # generate a table line for position (:top, :middle, :bottom)
220
+ #
221
+ def table_line position
222
+ c = @chars
223
+ left, line, mid, right = case position
224
+ when :top then [c[:tlb], c[:tb], c[:tib], c[:trb]]
225
+ when :middle then [c[:lib], c[:ib], c[:mib], c[:rib]]
226
+ when :bottom then [c[:blb], c[:bb], c[:bib], c[:brb]]
227
+ end
228
+ s = @chars.wrap(left + @widths.map{|w| line * (w + 2)}.join(mid) + right) + "\n"
229
+ s
230
+ end
231
+
232
+ ##
233
+ # table_data data
234
+ #
235
+ # generate a data row as part of a table
236
+
237
+ def table_data data
238
+ left, middle, right = [@chars[:ldb], @chars[:idb], @chars[:rdb]]
239
+ a = []
240
+ data.each_with_index do |item, x|
241
+ a << (' ' + item.to_s.send(@align[x] || :ljust, @widths[x]) + ' ')
242
+ end
243
+ s = @chars.wrap(left) + a.join(@chars.wrap(middle)) + @chars.wrap(right) + "\n"
244
+ s
245
+ end
246
+
247
+ end
@@ -0,0 +1,3 @@
1
+ class Array::Formatter
2
+ VERSION = "1.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift '.', './test', './lib'
4
+
5
+ require 'array/formatter'
6
+ require 'test-helper'
7
+
8
+ class Test_Array_Formatter < MiniTest::Unit::TestCase
9
+
10
+ @@a = [ %w( Company Name Address Phone Email ),
11
+ [ 'New Company', 'First Last', 'Somewhere, US', '123-45-6789', 'user@sample.com' ],
12
+ [ 'Old Company', 'First2 Last2', 'Somewhere else, US', '987-65-4321', 'user2@sample.com' ],
13
+ [ 'No Company', 'First3 Last3', 'Elsewhere ZZ', '763-34-1234', 'user3@sample.com' ]
14
+ ]
15
+
16
+ @@a2 = [ %w( Region State Sales ),
17
+ %w( Northwest WA $2,100,500 ),
18
+ %w( Northwest OR $900,800 ),
19
+ %w( Northeast NY $8,120,000 ),
20
+ %w( Northeast MN $489,500 ),
21
+ %w( Southeast GA $2,111,200 ),
22
+ %w( Southeast FL $9,388,000 ),
23
+ %w( Southwest AZ $7,377,000 ) ]
24
+
25
+
26
+ def test_to_table_default
27
+ s = @@a.to_table
28
+ puts s
29
+ end
30
+
31
+ def test_to_table_unicode
32
+ s = @@a.to_table(:unicode)
33
+ puts s
34
+ end
35
+
36
+ def test_to_table_alignments
37
+ s = @@a2.to_table
38
+ puts s
39
+ puts ''
40
+ s = @@a2.to_table(:unicode)
41
+ puts s
42
+ end
43
+
44
+ end
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'minitest/autorun'
4
+ require 'array/formatter'
metadata ADDED
@@ -0,0 +1,86 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: array-formatter
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Alan Stebbens
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: |2
42
+ A simple gem to reformat an array of arrays into one of several string
43
+ formats: HTML table; CSV; ASCII table; YAML
44
+ email:
45
+ - aks@stebbens.org
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - .gitignore
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - array-formatter.gemspec
56
+ - lib/array/formatter.rb
57
+ - lib/array/formatter/version.rb
58
+ - test/test-array-formatter.rb
59
+ - test/test-helper.rb
60
+ homepage: https://gitlab.com/as/array-formatter
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.0.7
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Format an array of arrays in one of serveral string formats
84
+ test_files:
85
+ - test/test-array-formatter.rb
86
+ - test/test-helper.rb