shellout 0.1

Sign up to get free protection for your applications and to get access to all the features.
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