legitable 0.1.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/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +167 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/legitable.gemspec +29 -0
- data/lib/legitable.rb +2 -0
- data/lib/legitable/table.rb +96 -0
- data/lib/legitable/version.rb +3 -0
- metadata +128 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d6086efaf0670225d0febbaad3691f73445ff490
|
4
|
+
data.tar.gz: 2728c004d3cec600a73ef0f94158271630a1f5b1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ff2a9c168c2da2d4f6caaaf979308b41ae44d0f76764ad68a4e630affb537b33144eb58ea16e6c7afc62b7d166a34e1ae83f3484b526366bf8f8eee510a36fe6
|
7
|
+
data.tar.gz: 8978a1b77ffe9b5ee7b9664c8d4cc26e645c4d7151a9cca47037a49126bd19a40ea8b9985e7a75d92a0d678db42c7539f5721e6aad4b727e01e083fc4304e35e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2017 Joel Helbling
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
# Legitable
|
2
|
+
|
3
|
+
Tables are easier to read. Legitable makes it easy to display plain text output in tabular form.
|
4
|
+
|
5
|
+
Given a normal series of hash objects as rows _(where "normal" means that all hashes have the same
|
6
|
+
keys)_, the first row's keys will be taken as the table's column headers; deviations in subsequent
|
7
|
+
hashes will be ignored.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'legitable'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install legitable
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
First, require it:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
require 'legitable'
|
31
|
+
```
|
32
|
+
|
33
|
+
Then, create a table object:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
table = Legitable::Table.new
|
37
|
+
```
|
38
|
+
|
39
|
+
Now add some rows:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
table << { name: 'joss whedon', phone: '444-555-1212' }
|
43
|
+
table << { name: 'jj abrams', phone: '333-555-1212' }
|
44
|
+
```
|
45
|
+
|
46
|
+
And then you can display it:
|
47
|
+
```ruby
|
48
|
+
puts table.to_s
|
49
|
+
```
|
50
|
+
|
51
|
+
NAME | PHONE
|
52
|
+
--------------------------
|
53
|
+
joss whedon | 444-555-1212
|
54
|
+
jj abrams | 333-555-1212
|
55
|
+
|
56
|
+
### Right-aligned columns
|
57
|
+
|
58
|
+
Some data, such as numbers, look better aligned to the right instead
|
59
|
+
of to the left:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
table = Legitable::Table.new(alignment: { bytes: :right })
|
63
|
+
|
64
|
+
table << { bytes: 12, file: 'foo.zip' }
|
65
|
+
table << { bytes: 1200, file: 'bar.zip' }
|
66
|
+
table << { bytes: 12000000, file: 'baz.zip' }
|
67
|
+
```
|
68
|
+
|
69
|
+
Which makes the numbers much easier to read:
|
70
|
+
|
71
|
+
BYTES | FILE
|
72
|
+
------------------
|
73
|
+
12 | foo.zip
|
74
|
+
1200 | bar.zip
|
75
|
+
12000000 | baz.zip
|
76
|
+
|
77
|
+
### Changing up the look
|
78
|
+
|
79
|
+
Some aspects of the table are configurable, such as the column
|
80
|
+
delimiter (which defaults to `" | "`) and the character used as
|
81
|
+
a header row separator (which defaults to `"-"`).
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
table = Legitable::Table.new(delimiter: ' ', separator: '=')
|
85
|
+
```
|
86
|
+
|
87
|
+
Which would give us this:
|
88
|
+
|
89
|
+
|
90
|
+
NAME PHONE
|
91
|
+
=========================
|
92
|
+
joss whedon 444-555-1212
|
93
|
+
jj abrams 333-555-1212
|
94
|
+
|
95
|
+
### Formatting columns
|
96
|
+
|
97
|
+
Sometimes the raw data as it comes in isn't exactly what you want
|
98
|
+
to display. So you can define formatters:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
title = Legitable::Table.new do
|
102
|
+
formatting :name do |value|
|
103
|
+
"_#{value.titleize}_"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
Which, of course, improves the display of the names column:
|
109
|
+
|
110
|
+
|
111
|
+
NAME | PHONE
|
112
|
+
----------------------------
|
113
|
+
_Joss Whedon_ | 444-555-1212
|
114
|
+
_JJ Abrams_ | 333-555-1212
|
115
|
+
|
116
|
+
And, of course, you can do something similar for the column headings:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
title = Legitable::Table.new do
|
120
|
+
formatting_headers do |header|
|
121
|
+
header.capitalize
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
126
|
+
Which makes the headers a little nicer:
|
127
|
+
|
128
|
+
Name | Phone
|
129
|
+
--------------------------
|
130
|
+
joss whedon | 444-555-1212
|
131
|
+
jj abrams | 333-555-1212
|
132
|
+
|
133
|
+
|
134
|
+
## Caveats
|
135
|
+
|
136
|
+
It should be obvious that this utility pulls in all rows, and then
|
137
|
+
displays them taking into account the widest values when determining
|
138
|
+
the appropriate column width. Accordingly, all rows to be processed
|
139
|
+
will be in memory as long as the table object exists. So this isn't
|
140
|
+
a good tool for formatting a terrabyte of tabular data.
|
141
|
+
|
142
|
+
The focus is on _display_ of data. Think of a `Legitable::Table` as
|
143
|
+
a _page_ of data. If you have multiple pages of data, you'd probably
|
144
|
+
want to repeat the headers anyway at some point, so it makes sense to
|
145
|
+
just create a new table after every *n* rows.
|
146
|
+
|
147
|
+
This puts me in mind of some ideas for the future:
|
148
|
+
|
149
|
+
- ability to "flush" all rows so that the table's formatting can be
|
150
|
+
re-used and re-loaded.
|
151
|
+
- ability to fix the width of a column and to word wrap within that
|
152
|
+
width in order to control the overall width of the table.
|
153
|
+
- ANSI color support
|
154
|
+
|
155
|
+
## Development
|
156
|
+
|
157
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
158
|
+
|
159
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
160
|
+
|
161
|
+
## Contributing
|
162
|
+
|
163
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/joelhelbling/legitable.
|
164
|
+
|
165
|
+
## License
|
166
|
+
|
167
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "legitable"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/legitable.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "legitable/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "legitable"
|
8
|
+
spec.version = Legitable::VERSION
|
9
|
+
spec.authors = ["Joel Helbling"]
|
10
|
+
spec.email = ["joel@joelhelbling.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Easy plain text tables}
|
13
|
+
spec.description = %q{Tables are easier to read. Legitable makes it easy to display plain text output in tabular form.}
|
14
|
+
spec.homepage = "https://github.com/joelhelbling/legitable"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.16.a"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.7"
|
27
|
+
spec.add_development_dependency "rspec-given", "~> 3.8"
|
28
|
+
spec.add_development_dependency "pry", "~> 0.11"
|
29
|
+
end
|
data/lib/legitable.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module Legitable
|
4
|
+
class Table
|
5
|
+
attr_reader :rows, :headers, :delimiter, :separator, :format
|
6
|
+
|
7
|
+
def initialize(alignment: {}, delimiter: ' | ', separator: '-', &block)
|
8
|
+
@rows = []
|
9
|
+
@headers = []
|
10
|
+
@format = {}
|
11
|
+
@formatters = {}
|
12
|
+
@alignment = alignment
|
13
|
+
@delimiter = delimiter
|
14
|
+
@separator = separator
|
15
|
+
|
16
|
+
self.instance_eval(&block) unless block.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def <<(row)
|
20
|
+
initialize_headers(row) if headers.empty?
|
21
|
+
add_row row
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
render_headers +
|
27
|
+
rows.map do |row|
|
28
|
+
headers.map do |header|
|
29
|
+
render_cell(header, row[header])
|
30
|
+
end.join(delimiter)
|
31
|
+
end.join("\n") + "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def initialize_headers(row)
|
37
|
+
@headers = row.keys
|
38
|
+
headers.each do |header|
|
39
|
+
format[header] = OpenStruct.new(
|
40
|
+
width: header.to_s.length,
|
41
|
+
formatter: @formatters[header] || default_formatter,
|
42
|
+
align: @alignment[header] || :left
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_row(row)
|
48
|
+
rows << headers.inject({}) do |memo, header|
|
49
|
+
formatter = format[header].formatter
|
50
|
+
value = formatter.call(row[header].to_s).to_s
|
51
|
+
if format[header].width < value.length
|
52
|
+
format[header].width = value.length
|
53
|
+
end
|
54
|
+
memo[header] = value
|
55
|
+
memo
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def render_headers
|
60
|
+
headers.map do |header|
|
61
|
+
render_cell(header, header_formatter.call(header))
|
62
|
+
end.join(delimiter) + "\n" + (separator * row_width) + "\n"
|
63
|
+
end
|
64
|
+
|
65
|
+
def row_width
|
66
|
+
width = (headers.size - 1) * delimiter.length
|
67
|
+
headers.sum(width) do |header|
|
68
|
+
format[header].width
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def render_cell(header, value)
|
73
|
+
cell_width = format[header].width
|
74
|
+
|
75
|
+
(format[header].align == :right) ?
|
76
|
+
value.rjust(cell_width, ' ') :
|
77
|
+
value.to_s + (' ' * (cell_width - value.to_s.length))
|
78
|
+
end
|
79
|
+
|
80
|
+
def formatting(header, &block)
|
81
|
+
@formatters[header] = block ? block : default_formatter
|
82
|
+
end
|
83
|
+
|
84
|
+
def default_formatter
|
85
|
+
@default_formatter ||= Proc.new {|value| value.to_s }
|
86
|
+
end
|
87
|
+
|
88
|
+
def formatting_headers(&block)
|
89
|
+
@header_formatter = block
|
90
|
+
end
|
91
|
+
|
92
|
+
def header_formatter
|
93
|
+
@header_formatter ||= Proc.new {|header| header.to_s.upcase }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: legitable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel Helbling
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-12-12 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.16.a
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.16.a
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-given
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0.11'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0.11'
|
83
|
+
description: Tables are easier to read. Legitable makes it easy to display plain
|
84
|
+
text output in tabular form.
|
85
|
+
email:
|
86
|
+
- joel@joelhelbling.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- ".gitignore"
|
92
|
+
- ".rspec"
|
93
|
+
- ".travis.yml"
|
94
|
+
- Gemfile
|
95
|
+
- LICENSE.txt
|
96
|
+
- README.md
|
97
|
+
- Rakefile
|
98
|
+
- bin/console
|
99
|
+
- bin/setup
|
100
|
+
- legitable.gemspec
|
101
|
+
- lib/legitable.rb
|
102
|
+
- lib/legitable/table.rb
|
103
|
+
- lib/legitable/version.rb
|
104
|
+
homepage: https://github.com/joelhelbling/legitable
|
105
|
+
licenses:
|
106
|
+
- MIT
|
107
|
+
metadata: {}
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options: []
|
110
|
+
require_paths:
|
111
|
+
- lib
|
112
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 2.6.13
|
125
|
+
signing_key:
|
126
|
+
specification_version: 4
|
127
|
+
summary: Easy plain text tables
|
128
|
+
test_files: []
|