shellout 0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ pkg/
2
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
data/Guardfile ADDED
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, :cli => "--color" do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ Shellout
2
+ ========
3
+
4
+ Usage
5
+ -----
6
+
7
+ ### Shadowboxes
8
+
9
+
10
+ require 'shellout/shadowbox'
11
+
12
+ Shellout::Shadowbox.new("Hello world").print
13
+
14
+ # ┌──────────────────────────────────────────┐
15
+ # │ Hello world │▒
16
+ # └──────────────────────────────────────────┘▒
17
+ # ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
18
+
19
+
20
+ ### Tables
21
+
22
+ require 'shellout/table'
23
+
24
+ Shellout::Table.new(headers: %w{Team Points},
25
+ rows: [['Man City', 22],
26
+ ['Man Utd', 20],
27
+ ['Chelsea', 19],
28
+ ['Newcastle', 16]]
29
+ ).print
30
+
31
+ # ┌───────────┬────────┐
32
+ # │ Team │ Points │
33
+ # ├───────────┼────────┤
34
+ # │ Man City │ 22 │
35
+ # │ Man Utd │ 20 │
36
+ # │ Chelsea │ 19 │
37
+ # │ Newcastle │ 16 │
38
+ # └───────────┴────────┘
39
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/shellout.rb ADDED
@@ -0,0 +1,21 @@
1
+
2
+ # Unicode box drawing characters and block elements
3
+ #
4
+ # http://en.wikipedia.org/wiki/Box-drawing_characters
5
+ #
6
+ # 0 1 2 3 4 5 6 7 8 9 A B C D E F
7
+ # U+250x ─ ━ │ ┃ ┄ ┅ ┆ ┇ ┈ ┉ ┊ ┋ ┌ ┍ ┎ ┏
8
+ # U+251x ┐ ┑ ┒ ┓ └ ┕ ┖ ┗ ┘ ┙ ┚ ┛ ├ ┝ ┞ ┟
9
+ # U+252x ┠ ┡ ┢ ┣ ┤ ┥ ┦ ┧ ┨ ┩ ┪ ┫ ┬ ┭ ┮ ┯
10
+ # U+253x ┰ ┱ ┲ ┳ ┴ ┵ ┶ ┷ ┸ ┹ ┺ ┻ ┼ ┽ ┾ ┿
11
+ # U+254x ╀ ╁ ╂ ╃ ╄ ╅ ╆ ╇ ╈ ╉ ╊ ╋ ╌ ╍ ╎ ╏
12
+ # U+255x ═ ║ ╒ ╓ ╔ ╕ ╖ ╗ ╘ ╙ ╚ ╛ ╜ ╝ ╞ ╟
13
+ # U+256x ╠ ╡ ╢ ╣ ╤ ╥ ╦ ╧ ╨ ╩ ╪ ╫ ╬ ╭ ╮ ╯
14
+ # U+257x ╰ ╱ ╲ ╳ ╴ ╵ ╶ ╷ ╸ ╹ ╺ ╻ ╼ ╽ ╾ ╿
15
+ #
16
+ # 0 1 2 3 4 5 6 7 8 9 A B C D E F
17
+ # U+258x ▀ ▁ ▂ ▃ ▄ ▅ ▆ ▇ █ ▉ ▊ ▋ ▌ ▍ ▎ ▏
18
+ # U+259x ▐ ░ ▒ ▓ ▔ ▕ ▖ ▗ ▘ ▙ ▚ ▛ ▜ ▝ ▞ ▟
19
+
20
+ module Shellout
21
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module Shellout
4
+ class Shadowbox
5
+
6
+ MIN_WIDTH = 40
7
+
8
+ def initialize(title)
9
+ @title = title
10
+ end
11
+
12
+ def print(out=$stdout)
13
+ length = [@title.length, MIN_WIDTH].max + 2
14
+ out.print "" <<
15
+ '┌' << '─' * length << "┐ \n" <<
16
+ '│ ' << @title.center(MIN_WIDTH) << " │▒\n" <<
17
+ '└' << '─' * length << "┘▒\n" <<
18
+ ' ' << '▒' * length << "▒\n"
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ module Shellout
4
+ class Table
5
+
6
+ def initialize(table={})
7
+ @data = []
8
+ @data << table[:headers] if table.has_key? :headers
9
+ @data += table[:rows] if table.has_key? :rows
10
+ @data << table[:footers] if table.has_key? :footers
11
+
12
+ @has_headers = table.has_key? :headers
13
+ @has_footers = table.has_key? :footers
14
+ end
15
+
16
+ def print(out=$stdout)
17
+ return if @data.empty?
18
+
19
+ separators = widths.map {|w| '─'*(w+2)}
20
+ format = build_format
21
+
22
+ out.print '┌' << separators.join('┬') << "┐\n"
23
+ @data.each_with_index do |r, i|
24
+ if @has_headers and i == 0
25
+ out.print '│ ' << center(r).join(' │ ') << " │\n"
26
+ out.print '├' << separators.join('┼') << "┤\n"
27
+ elsif @has_footers and i == @data.size-1
28
+ out.print '├' << separators.join('┼') << "┤\n"
29
+ out.printf(format, *r)
30
+ else
31
+ out.printf(format, *r)
32
+ end
33
+ end
34
+ out.print '└' << separators.join('┴') << "┘\n"
35
+ end
36
+
37
+ private
38
+
39
+ def center(row)
40
+ row.zip(widths).map {|s,l| s.center(l)}
41
+ end
42
+
43
+ def widths
44
+ @widths ||= @data.transpose.map {|c| c.map(&:to_s).map(&:size).max }
45
+ end
46
+
47
+ def build_format
48
+ data = @data.clone
49
+ data.shift if @has_headers
50
+
51
+ numeric_columns = data.transpose.map do |col|
52
+ col.reduce(true) do |is_numeric, c|
53
+ is_numeric &&= c.is_a?(Numeric) || c.match(/\d+[:.,]?\d*$/)
54
+ end
55
+ end
56
+
57
+ format = widths.reduce('│') do |f, l|
58
+ justify = numeric_columns.shift ? '' : '-'
59
+ f + " %#{justify}#{l}s │"
60
+ end + "\n"
61
+ end
62
+ end
63
+ end
data/shellout.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "shellout"
5
+ s.version = "0.1"
6
+ s.authors = ["Kjell-Magne Øierud"]
7
+ s.email = ["kjellm@acm.org"]
8
+ s.homepage = "https://github.com/kjellm/shellout"
9
+ s.summary = %q{Tools for writing terminal interfaces}
10
+ s.description = %q{Contains classes for printing tables and boxes}
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- spec/*`.split("\n")
14
+ s.require_paths = ["lib"]
15
+
16
+ s.add_development_dependency "rspec"
17
+ s.add_development_dependency "guard"
18
+ s.add_development_dependency "guard-rspec"
19
+
20
+ if RUBY_PLATFORM.downcase.include?("darwin")
21
+ s.add_development_dependency 'rb-fsevent'
22
+ s.add_development_dependency 'growl_notify'
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ require 'stringio'
4
+ require 'shellout/shadowbox'
5
+
6
+ describe Shellout::Shadowbox do
7
+
8
+ before(:each) do
9
+ @out = StringIO.new
10
+ end
11
+
12
+ describe 'when title is empty' do
13
+ it 'should print an empty box' do
14
+ @box = Shellout::Shadowbox.new('')
15
+ x = <<EOB
16
+ ┌──────────────────────────────────────────┐
17
+ │ │▒
18
+ └──────────────────────────────────────────┘▒
19
+ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
20
+ EOB
21
+ @box.print(@out)
22
+ @out.string.should == x
23
+ end
24
+ end
25
+
26
+ describe 'when a short title is given' do
27
+ it 'should print a padded box with centered title' do
28
+ @box = Shellout::Shadowbox.new('short')
29
+ x = <<EOB
30
+ ┌──────────────────────────────────────────┐
31
+ │ short │▒
32
+ └──────────────────────────────────────────┘▒
33
+ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
34
+ EOB
35
+ @box.print(@out)
36
+ @out.string.should == x
37
+ end
38
+ end
39
+
40
+ describe 'when a long title is given' do
41
+ it 'should print a box that is big enough' do
42
+ @box = Shellout::Shadowbox.new('a very extremely humongously large meaningless title')
43
+ x = <<EOB
44
+ ┌──────────────────────────────────────────────────────┐
45
+ │ a very extremely humongously large meaningless title │▒
46
+ └──────────────────────────────────────────────────────┘▒
47
+ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
48
+ EOB
49
+ @box.print(@out)
50
+ @out.string.should == x
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,91 @@
1
+ # encoding: utf-8
2
+
3
+ require 'stringio'
4
+ require 'shellout/table'
5
+
6
+ describe Shellout::Table do
7
+
8
+ before(:each) do
9
+ @out = StringIO.new
10
+ end
11
+
12
+ describe 'when no parameters' do
13
+ it 'should not print anything' do
14
+ Shellout::Table.new.print(@out)
15
+ @out.string.should == ''
16
+ end
17
+ end
18
+
19
+ describe 'table with only a single data row' do
20
+ it 'should print a single row table' do
21
+ Shellout::Table.new(rows: [%w{a b c}]).print(@out)
22
+ @out.string.should == <<'EOT'
23
+ ┌───┬───┬───┐
24
+ │ a │ b │ c │
25
+ └───┴───┴───┘
26
+ EOT
27
+ end
28
+ end
29
+
30
+ describe 'when only given headers' do
31
+ it 'should print headers and one empty row' do
32
+ Shellout::Table.new(headers: %w{a b c}).print(@out)
33
+ @out.string.should == <<'EOT'
34
+ ┌───┬───┬───┐
35
+ │ a │ b │ c │
36
+ ├───┼───┼───┤
37
+ └───┴───┴───┘
38
+ EOT
39
+ end
40
+ end
41
+
42
+ describe 'when all parameters are defined' do
43
+ it 'should print a nice table' do
44
+ Shellout::Table.new(headers: %w{a b c}, rows: [%w{d e f}, %w{g h i}], footers: %w{j k l}).print(@out)
45
+ @out.string.should == <<'EOT'
46
+ ┌───┬───┬───┐
47
+ │ a │ b │ c │
48
+ ├───┼───┼───┤
49
+ │ d │ e │ f │
50
+ │ g │ h │ i │
51
+ ├───┼───┼───┤
52
+ │ j │ k │ l │
53
+ └───┴───┴───┘
54
+ EOT
55
+ end
56
+ end
57
+
58
+ it 'should center headers' do
59
+ Shellout::Table.new(headers: %w{a b c}, rows: [%w{123 456 789}]).print(@out)
60
+ @out.string.each_line.to_a[1].should == "│ a │ b │ c │\n"
61
+ end
62
+
63
+ it 'should_right_justify_numbers' do
64
+ Shellout::Table.new(headers: %w{aaaa bb ccc}, rows: [%w{123 4 56}]).print(@out)
65
+ @out.string.should == <<'EOT'
66
+ ┌──────┬────┬─────┐
67
+ │ aaaa │ bb │ ccc │
68
+ ├──────┼────┼─────┤
69
+ │ 123 │ 4 │ 56 │
70
+ └──────┴────┴─────┘
71
+ EOT
72
+ end
73
+
74
+ it 'should handle an example with some "real" data' do
75
+ Shellout::Table.new(
76
+ headers: %w{project code hours price},
77
+ rows: [%w{nice_project_1 a 7:30 100.00}, %w{nice_project_2 b 7:30 87.50}],
78
+ footers: %w{Sum - 15:00 187.50},
79
+ ).print(@out)
80
+ @out.string.should == <<'EOT'
81
+ ┌────────────────┬──────┬───────┬────────┐
82
+ │ project │ code │ hours │ price │
83
+ ├────────────────┼──────┼───────┼────────┤
84
+ │ nice_project_1 │ a │ 7:30 │ 100.00 │
85
+ │ nice_project_2 │ b │ 7:30 │ 87.50 │
86
+ ├────────────────┼──────┼───────┼────────┤
87
+ │ Sum │ - │ 15:00 │ 187.50 │
88
+ └────────────────┴──────┴───────┴────────┘
89
+ EOT
90
+ end
91
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shellout
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kjell-Magne Øierud
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-21 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70243003183560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70243003183560
25
+ - !ruby/object:Gem::Dependency
26
+ name: guard
27
+ requirement: &70243003182740 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70243003182740
36
+ - !ruby/object:Gem::Dependency
37
+ name: guard-rspec
38
+ requirement: &70243003181780 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70243003181780
47
+ - !ruby/object:Gem::Dependency
48
+ name: rb-fsevent
49
+ requirement: &70243003180360 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70243003180360
58
+ - !ruby/object:Gem::Dependency
59
+ name: growl_notify
60
+ requirement: &70243003179120 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70243003179120
69
+ description: Contains classes for printing tables and boxes
70
+ email:
71
+ - kjellm@acm.org
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - Guardfile
79
+ - README.md
80
+ - Rakefile
81
+ - lib/shellout.rb
82
+ - lib/shellout/shadowbox.rb
83
+ - lib/shellout/table.rb
84
+ - shellout.gemspec
85
+ - spec/shellout/shadowbox_spec.rb
86
+ - spec/shellout/table_spec.rb
87
+ homepage: https://github.com/kjellm/shellout
88
+ licenses: []
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 1.8.10
108
+ signing_key:
109
+ specification_version: 3
110
+ summary: Tools for writing terminal interfaces
111
+ test_files:
112
+ - spec/shellout/shadowbox_spec.rb
113
+ - spec/shellout/table_spec.rb