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.
@@ -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
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.4.2
5
+ before_install: gem install bundler -v 1.16.0.pre.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in legitable.gemspec
6
+ gemspec
@@ -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.
@@ -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).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -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
@@ -0,0 +1,2 @@
1
+ require "legitable/version"
2
+ require "legitable/table"
@@ -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
@@ -0,0 +1,3 @@
1
+ module Legitable
2
+ VERSION = "0.1.0"
3
+ 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: []