tabulate 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.
- data/History.txt +4 -0
- data/README.md +53 -0
- data/Rakefile +17 -0
- data/bin/tabulate +7 -0
- data/lib/tabulate.rb +157 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/tabulate_spec.rb +6 -0
- data/test/test_tabulate.rb +0 -0
- data/version.txt +1 -0
- metadata +90 -0
data/History.txt
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
tabulate
|
2
|
+
===========
|
3
|
+
|
4
|
+
Create fancy command line tables with ease.
|
5
|
+
|
6
|
+
Builtin styles:
|
7
|
+
|
8
|
+
"simple", "plain", "fancy", "sqlite", "plain2", "plain\_alt", "legacy".
|
9
|
+
|
10
|
+
PLEASE BE AWARE this is my first gem :) .
|
11
|
+
|
12
|
+
Features
|
13
|
+
--------
|
14
|
+
|
15
|
+
* Builtin styles
|
16
|
+
* Colored data input support
|
17
|
+
* Double width east Asian character support with ruby 1.9
|
18
|
+
|
19
|
+
Examples
|
20
|
+
--------
|
21
|
+
|
22
|
+
source = [["\e[31maht\e[m",3],[4,"\e[33msomething\e[m"],['s',['abc','de']]]
|
23
|
+
labels = ["a",'b']
|
24
|
+
puts tabulate(labels, source, :indent => 4, :style => 'legacy')
|
25
|
+
|
26
|
+
will produce a table like the following, with "aht" colored in red and
|
27
|
+
"something" in yellow.
|
28
|
+
|
29
|
+
+-----+-----------+
|
30
|
+
| a | b |
|
31
|
+
+=====+===========+
|
32
|
+
| aht | 3 |
|
33
|
+
| 4 | something |
|
34
|
+
| s | abc |
|
35
|
+
| | de |
|
36
|
+
+-----+-----------+
|
37
|
+
|
38
|
+
Requirements
|
39
|
+
------------
|
40
|
+
|
41
|
+
Nil.
|
42
|
+
East Asian character support requires ruby 1.9 and above.
|
43
|
+
|
44
|
+
Install
|
45
|
+
-------
|
46
|
+
|
47
|
+
gem install tabulate
|
48
|
+
|
49
|
+
License
|
50
|
+
-------
|
51
|
+
|
52
|
+
MIT
|
53
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones'
|
4
|
+
rescue LoadError
|
5
|
+
abort '### Please install the "bones" gem ###'
|
6
|
+
end
|
7
|
+
|
8
|
+
task :default => 'test:run'
|
9
|
+
task 'gem:release' => 'test:run'
|
10
|
+
|
11
|
+
Bones {
|
12
|
+
name 'tabulate'
|
13
|
+
authors 'Roy Zuo (aka roylez)'
|
14
|
+
email 'roylzuo AT gmail DOT com'
|
15
|
+
url 'http://tabulate.rubygems.org'
|
16
|
+
}
|
17
|
+
|
data/bin/tabulate
ADDED
data/lib/tabulate.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
# author: Roy Zuo ( roylzuo AT gmail DOT com )
|
4
|
+
|
5
|
+
$template = {
|
6
|
+
"simple" => {
|
7
|
+
:rs => '', :fs => ' | ', :cross => '+',
|
8
|
+
:lframe => '', :rframe => '' ,
|
9
|
+
:hlframe => "\e[1;2m", :hrframe => "\e[m" ,
|
10
|
+
:padding => 0,
|
11
|
+
},
|
12
|
+
"legacy" => {
|
13
|
+
:rs => '', :fs => '|', :cross => '+',
|
14
|
+
:lframe => '|', :rframe => '|',
|
15
|
+
:hlframe => "|", :hrframe => "|",
|
16
|
+
:tframe => "-", :bframe => "-",
|
17
|
+
:hs => "=", :padding => 1,
|
18
|
+
},
|
19
|
+
'plain' => {
|
20
|
+
:rs => '', :fs => ' ', :cross => '+',
|
21
|
+
:lframe => '', :rframe => '',
|
22
|
+
:hlframe => "", :hrframe => "",
|
23
|
+
:padding => 0,
|
24
|
+
},
|
25
|
+
'sqlite' => {
|
26
|
+
:rs => '', :fs => ' ', :cross => ' ',
|
27
|
+
:lframe => '', :rframe => '',
|
28
|
+
:hlframe => "", :hrframe => "",
|
29
|
+
:padding => 0, :hs => '-'
|
30
|
+
},
|
31
|
+
'plain2' => {
|
32
|
+
:rs => '', :fs => ':', :cross => '+',
|
33
|
+
:lframe => '', :rframe => '',
|
34
|
+
:hlframe => "", :hrframe => "",
|
35
|
+
:hs => "-", :padding => 1,
|
36
|
+
},
|
37
|
+
'plain_alt' => {
|
38
|
+
:rs => '', :fs => ' ', :cross => '+',
|
39
|
+
:lframe => '', :rframe => '',
|
40
|
+
:hlframe => "", :hrframe => "",
|
41
|
+
:hs => "-", :padding => 1,
|
42
|
+
},
|
43
|
+
'fancy' => {
|
44
|
+
:rs => '', :fs => '|', :cross => '+',
|
45
|
+
:lframe => '', :rframe => '',
|
46
|
+
:hlframe => "\e[1;7m", :hrframe => "\e[m",
|
47
|
+
:padding => 1,
|
48
|
+
},
|
49
|
+
}
|
50
|
+
|
51
|
+
# tabulate arrays, styles can be simple/legacy
|
52
|
+
# data may come in in a format like
|
53
|
+
# +labels+ table heading, an array
|
54
|
+
# +data+ an array of data to be tabulated, one element for one row
|
55
|
+
# +opts+ optional arguments, :indent => 0, :style => 'fancy'
|
56
|
+
#
|
57
|
+
# return a String
|
58
|
+
#
|
59
|
+
# [ [a, b, c], [d, e, [f, g]] .... ]
|
60
|
+
# [ a, b, c] will be used as a single row
|
61
|
+
# and [d, e,[f,g]] will be used as two rows
|
62
|
+
def tabulate(labels, data, opts = { } )
|
63
|
+
raise 'Label and data do not have equal columns!' unless labels.size == data.transpose.size
|
64
|
+
|
65
|
+
opts = { :indent => 0, :style => 'fancy'}.merge opts
|
66
|
+
indent = opts[:indent]
|
67
|
+
style = opts[:style]
|
68
|
+
raise "Invalid table style!" unless $template.keys.include? style
|
69
|
+
|
70
|
+
data = data.inject([]){|rs, r| rs += r.to_rows }
|
71
|
+
data = data.unshift(labels).transpose
|
72
|
+
padding = $template[style][:padding]
|
73
|
+
data = data.collect {|c|
|
74
|
+
c.collect {|e| ' ' * padding + e.to_s + ' ' * padding }
|
75
|
+
}
|
76
|
+
widths = data.collect {|c| c.collect {|a| a.width}.max }
|
77
|
+
newdata = []
|
78
|
+
data.each_with_index {|c,i|
|
79
|
+
newdata << c.collect { |e| e + ' '*(widths[i] - e.width) }
|
80
|
+
}
|
81
|
+
data = newdata
|
82
|
+
data = data.transpose
|
83
|
+
data = [ $template[style][:hlframe] + data[0].join($template[style][:fs]) + $template[style][:hrframe] ] + \
|
84
|
+
data[1..-1].collect {|l| $template[style][:lframe] + l.join($template[style][:fs]) + $template[style][:rframe] }
|
85
|
+
lines = []
|
86
|
+
|
87
|
+
#add top frame
|
88
|
+
if !$template[style][:tframe].to_s.empty?
|
89
|
+
lines << $template[style][:cross] + widths.collect{|n| $template[style][:tframe] *n }.join($template[style][:cross]) + $template[style][:cross]
|
90
|
+
end
|
91
|
+
|
92
|
+
#add title
|
93
|
+
lines << data[0]
|
94
|
+
|
95
|
+
#add title ruler
|
96
|
+
if !$template[style][:hs].to_s.empty? and !$template[style][:lframe].to_s.empty?
|
97
|
+
lines << $template[style][:cross] + widths.collect{|n| $template[style][:hs] *n }.join($template[style][:cross]) + $template[style][:cross]
|
98
|
+
elsif !$template[style][:hs].to_s.empty?
|
99
|
+
lines << widths.collect{|n| $template[style][:hs] *n }.join($template[style][:cross])
|
100
|
+
end
|
101
|
+
|
102
|
+
#add data
|
103
|
+
data[1..-2].each{ |line|
|
104
|
+
lines << line
|
105
|
+
if !$template[style][:rs].to_s.empty?
|
106
|
+
lines << $template[style][:cross] + widths.collect{|n| $template[style][:rs] *n }.join($template[style][:cross]) + $template[style][:cross]
|
107
|
+
end
|
108
|
+
}
|
109
|
+
|
110
|
+
#add last record and bottom frame
|
111
|
+
lines << data[-1]
|
112
|
+
if !$template[style][:bframe].to_s.empty?
|
113
|
+
lines << $template[style][:cross] + widths.collect{|n| $template[style][:bframe] *n }.join($template[style][:cross]) + $template[style][:cross]
|
114
|
+
end
|
115
|
+
|
116
|
+
#add indent
|
117
|
+
lines.collect {|l| ' '*indent + l}.join("\n")
|
118
|
+
end
|
119
|
+
|
120
|
+
class Array
|
121
|
+
def to_rows
|
122
|
+
a = collect{|i| i.is_a?(Array) ? i : [ i ]}
|
123
|
+
nr = a.collect{|i| i.size}.max
|
124
|
+
rows = []
|
125
|
+
0.upto( nr-1 ) {|j| rows << a.collect{|i| i[j] ? i[j] : ''} }
|
126
|
+
rows
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class String
|
131
|
+
if RUBY_VERSION >= '1.9'
|
132
|
+
def contains_cjk? # Oniguruma regex !!!
|
133
|
+
(self =~ /\p{Han}|\p{Katakana}|\p{Hiragana}\p{Hangul}/)
|
134
|
+
end
|
135
|
+
def width
|
136
|
+
gsub(/(\e|\033|\33)\[[;0-9]*\D/,'').split(//).inject( 0 ) do |s, i|
|
137
|
+
s += i.contains_cjk? ? 2 : 1
|
138
|
+
s
|
139
|
+
end
|
140
|
+
end
|
141
|
+
else
|
142
|
+
def width
|
143
|
+
gsub(/(\e|\033|\33)\[[;0-9]*\D/,'').size
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
if __FILE__ == $0
|
149
|
+
source = [["\e[31maht\e[m",3],[4,"\e[33msomething\e[m"],['s',['abc','de']]]
|
150
|
+
labels = ["a",'b']
|
151
|
+
puts "Available themes: #{$template.keys.inspect}"
|
152
|
+
$template.keys.each do |k|
|
153
|
+
puts "#{k} :"
|
154
|
+
puts tabulate(labels, source, :indent => 4, :style => k)
|
155
|
+
puts
|
156
|
+
end
|
157
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
|
2
|
+
require File.expand_path(
|
3
|
+
File.join(File.dirname(__FILE__), %w[.. lib tabulate]))
|
4
|
+
|
5
|
+
Spec::Runner.configure do |config|
|
6
|
+
# == Mock Framework
|
7
|
+
#
|
8
|
+
# RSpec uses it's own mocking framework by default. If you prefer to
|
9
|
+
# use mocha, flexmock or RR, uncomment the appropriate line:
|
10
|
+
#
|
11
|
+
# config.mock_with :mocha
|
12
|
+
# config.mock_with :flexmock
|
13
|
+
# config.mock_with :rr
|
14
|
+
end
|
15
|
+
|
File without changes
|
data/version.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tabulate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Roy Zuo (aka roylez)
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-25 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bones
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 21
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 6
|
32
|
+
- 5
|
33
|
+
version: 3.6.5
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
description: Create fancy command line tables with ease.
|
37
|
+
email: roylzuo AT gmail DOT com
|
38
|
+
executables:
|
39
|
+
- tabulate
|
40
|
+
extensions: []
|
41
|
+
|
42
|
+
extra_rdoc_files:
|
43
|
+
- History.txt
|
44
|
+
- bin/tabulate
|
45
|
+
files:
|
46
|
+
- History.txt
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- bin/tabulate
|
50
|
+
- lib/tabulate.rb
|
51
|
+
- spec/spec_helper.rb
|
52
|
+
- spec/tabulate_spec.rb
|
53
|
+
- test/test_tabulate.rb
|
54
|
+
- version.txt
|
55
|
+
homepage: http://tabulate.rubygems.org
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options:
|
60
|
+
- --main
|
61
|
+
- README.md
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: tabulate
|
85
|
+
rubygems_version: 1.7.2
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Create fancy command line tables with ease.
|
89
|
+
test_files:
|
90
|
+
- test/test_tabulate.rb
|