tb 0.7 → 0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d65f3c5949c1861ab81e5719b92b36e316bd3f84
4
+ data.tar.gz: 97b21fa7f980f3f8d8dcb11628c67d2e3b4ec574
5
+ SHA512:
6
+ metadata.gz: d222449efff43a8eee436cbd3b6bcc265ba15e05e783e310058baef59e338b0ada20e64e721e223c7c9eac005f206940ddea882248c1a152104f23b6c92ab9c7
7
+ data.tar.gz: 30ab19ba71070b0127dbfd96e8f48fefea0f5a03832d35b1dfee87b587e76af83208c06b5d8cad3a54265567adccabeb06d60c48bee814e5f8427ff4e5df92ad
data/lib/tb.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # lib/tb.rb - entry file for table library
2
2
  #
3
- # Copyright (C) 2010-2012 Tanaka Akira <akr@fsij.org>
3
+ # Copyright (C) 2010-2013 Tanaka Akira <akr@fsij.org>
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without
6
6
  # modification, are permitted provided that the following conditions
@@ -42,6 +42,7 @@ require 'tb/basic'
42
42
  require 'tb/record'
43
43
  require 'tb/csv'
44
44
  require 'tb/tsv'
45
+ require 'tb/ltsv'
45
46
  require 'tb/pnm'
46
47
  require 'tb/json'
47
48
  require 'tb/reader'
@@ -39,8 +39,8 @@ def (Tb::Cmd).op_grep
39
39
  "Search rows using regexp or ruby expression."
40
40
  define_common_option(op, "hNo", "--no-pager")
41
41
  op.def_option('-f FIELD', 'search field') {|field| Tb::Cmd.opt_grep_f = field }
42
- op.def_option('-e REGEXP', 'predicate written in ruby. A hash is given as _. no usual regexp argument.') {|pattern| Tb::Cmd.opt_grep_e = pattern }
43
- op.def_option('--ruby RUBY-EXP', 'specify a regexp. no usual regexp argument.') {|ruby_exp| Tb::Cmd.opt_grep_ruby = ruby_exp }
42
+ op.def_option('-e REGEXP', 'specify a regexp.') {|pattern| Tb::Cmd.opt_grep_e = pattern }
43
+ op.def_option('--ruby RUBY-EXP', 'predicate written in ruby. A hash is given as _. no usual regexp argument.') {|ruby_exp| Tb::Cmd.opt_grep_ruby = ruby_exp }
44
44
  op.def_option('-v', 'ouput the records which doesn\'t match') { Tb::Cmd.opt_grep_v = true }
45
45
  op
46
46
  end
@@ -39,7 +39,7 @@ def (Tb::Cmd).op_tar
39
39
  define_common_option(op, "hNo", "--no-pager")
40
40
  op.def_option('-l', 'show more attributes.') {|fs| Tb::Cmd.opt_tar_l += 1 }
41
41
  op.def_option('--ustar', 'ustar format (POSIX.1-1988). No GNU and POSIX.1-2001 extension.') {|fs| Tb::Cmd.opt_tar_ustar = true }
42
- op.def_option('--hash=ALGORITHMS', 'hash algorithms such as md5,sha256,sha384,sha512 (default: none)') {|hs| Tb::Cmd.opt_tar_hash.concat split_field_list_argument(hs) }
42
+ op.def_option('--hash=ALGORITHMS', 'show the hash of contents. algorithms can be some of md5,sha256,sha384,sha512 (default: none)') {|hs| Tb::Cmd.opt_tar_hash.concat split_field_list_argument(hs) }
43
43
  op
44
44
  end
45
45
 
@@ -365,11 +365,11 @@ def (Tb::Cmd).tar_open_with(arg)
365
365
  tar_open_with0(arg) {|f|
366
366
  magic = f.read(8)
367
367
  case magic
368
- when /\A\x1f\x8b/, /\A\037\235/ # \x1f\x8b is gzip format. \037\235 is "compress" format of old Unix.
368
+ when /\A\x1f\x8b/n, /\A\037\235/n # \x1f\x8b is gzip format. \037\235 is "compress" format of old Unix.
369
369
  decompression = ['gzip', '-dc']
370
370
  when /\ABZh/
371
371
  decompression = ['bzip2', '-dc']
372
- when /\A\xFD7zXZ\x00/
372
+ when /\A\xFD7zXZ\x00/n
373
373
  decompression = ['xz', '-dc']
374
374
  end
375
375
  begin
@@ -0,0 +1,48 @@
1
+ # Copyright (C) 2013 Tanaka Akira <akr@fsij.org>
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ #
7
+ # 1. Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # 2. Redistributions in binary form must reproduce the above
10
+ # copyright notice, this list of conditions and the following
11
+ # disclaimer in the documentation and/or other materials provided
12
+ # with the distribution.
13
+ # 3. The name of the author may not be used to endorse or promote
14
+ # products derived from this software without specific prior
15
+ # written permission.
16
+ #
17
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+
29
+ Tb::Cmd.subcommands << 'to-ltsv'
30
+
31
+ def (Tb::Cmd).op_to_ltsv
32
+ op = OptionParser.new
33
+ op.banner = "Usage: tb to-ltsv [OPTS] [TABLE]\n" +
34
+ "Convert a table to LTSV (Tab Separated Value)."
35
+ define_common_option(op, "hNo", "--no-pager")
36
+ op
37
+ end
38
+
39
+ def (Tb::Cmd).main_to_ltsv(argv)
40
+ op_to_ltsv.parse!(argv)
41
+ exit_if_help('to-ltsv')
42
+ argv = ['-'] if argv.empty?
43
+ tbl = Tb::CatReader.open(argv, Tb::Cmd.opt_N).to_tb
44
+ with_output {|out|
45
+ tbl_generate_ltsv(tbl, out)
46
+ }
47
+ end
48
+
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2011-2012 Tanaka Akira <akr@fsij.org>
1
+ # Copyright (C) 2011-2013 Tanaka Akira <akr@fsij.org>
2
2
  #
3
3
  # Redistribution and use in source and binary forms, with or without
4
4
  # modification, are permitted provided that the following conditions
@@ -38,6 +38,7 @@ require 'tb/cmdutil'
38
38
  require 'tb/cmd_help'
39
39
  require 'tb/cmd_to_csv'
40
40
  require 'tb/cmd_to_tsv'
41
+ require 'tb/cmd_to_ltsv'
41
42
  require 'tb/cmd_to_pnm'
42
43
  require 'tb/cmd_to_json'
43
44
  require 'tb/cmd_to_yaml'
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2011-2012 Tanaka Akira <akr@fsij.org>
1
+ # Copyright (C) 2011-2013 Tanaka Akira <akr@fsij.org>
2
2
  #
3
3
  # Redistribution and use in source and binary forms, with or without
4
4
  # modification, are permitted provided that the following conditions
@@ -152,6 +152,20 @@ def tbl_generate_tsv(tbl, out)
152
152
  end
153
153
  end
154
154
 
155
+ def tbl_generate_ltsv(tbl, out)
156
+ if Tb::Cmd.opt_N
157
+ header = tbl.list_fields
158
+ Tb.ltsv_stream_output(out) {|gen|
159
+ tbl.each {|rec|
160
+ assoc = header.map {|f| [f, rec[f]] }
161
+ gen << assoc
162
+ }
163
+ }
164
+ else
165
+ tbl.generate_ltsv(out)
166
+ end
167
+ end
168
+
155
169
  def with_output(filename=Tb::Cmd.opt_output)
156
170
  if filename && filename != '-'
157
171
  tmp = filename + ".part"
@@ -188,6 +202,8 @@ def output_tbenum(te)
188
202
  case filename
189
203
  when /\.csv\z/
190
204
  fmt = 'csv'
205
+ when /\.ltsv\z/
206
+ fmt = 'ltsv'
191
207
  when /\.json\z/
192
208
  fmt = 'json'
193
209
  end
@@ -196,6 +212,8 @@ def output_tbenum(te)
196
212
  case fmt
197
213
  when 'csv'
198
214
  write_proc = lambda {|out| te.write_to_csv(out, !Tb::Cmd.opt_N) }
215
+ when 'ltsv'
216
+ write_proc = lambda {|out| te.write_to_ltsv(out) }
199
217
  when 'json'
200
218
  write_proc = lambda {|out| te.write_to_json(out) }
201
219
  else
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2012 Tanaka Akira <akr@fsij.org>
1
+ # Copyright (C) 2012-2013 Tanaka Akira <akr@fsij.org>
2
2
  #
3
3
  # Redistribution and use in source and binary forms, with or without
4
4
  # modification, are permitted provided that the following conditions
@@ -232,6 +232,13 @@ module Tb::Enumerable
232
232
  end
233
233
  end
234
234
 
235
+ def write_to_ltsv(out)
236
+ self.each {|pairs|
237
+ out.print Tb.ltsv_assoc_join(pairs)
238
+ out.print "\n"
239
+ }
240
+ end
241
+
235
242
  def write_to_json(out)
236
243
  require 'json'
237
244
  out.print "["
@@ -0,0 +1,187 @@
1
+ # lib/tb/ltsv.rb - LTSV related fetures for table library
2
+ #
3
+ # Copyright (C) 2013 Tanaka Akira <akr@fsij.org>
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions
7
+ # are met:
8
+ #
9
+ # 1. Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # 2. Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following
13
+ # disclaimer in the documentation and/or other materials provided
14
+ # with the distribution.
15
+ # 3. The name of the author may not be used to endorse or promote
16
+ # products derived from this software without specific prior
17
+ # written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25
+ # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27
+ # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29
+ # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'stringio'
32
+
33
+ class Tb
34
+ def Tb.load_ltsv(filename, &block)
35
+ Tb.parse_ltsv(File.read(filename), &block)
36
+ end
37
+
38
+ def Tb.parse_ltsv(ltsv)
39
+ assoc_list = []
40
+ ltsv_stream_input(ltsv) {|assoc|
41
+ assoc_list << assoc
42
+ }
43
+ fields_hash = {}
44
+ assoc_list.each {|assoc|
45
+ assoc.each {|key, val|
46
+ fields_hash[key] ||= fields_hash.size
47
+ }
48
+ }
49
+ header = fields_hash.keys
50
+ t = Tb.new(header)
51
+ assoc_list.each {|assoc|
52
+ t.insert Hash[assoc]
53
+ }
54
+ t
55
+ end
56
+
57
+ def Tb.ltsv_stream_input(ltsv)
58
+ ltsvreader = LTSVReader.new(ltsv)
59
+ while assoc = ltsvreader.shift
60
+ yield assoc
61
+ end
62
+ nil
63
+ end
64
+
65
+ def Tb.ltsv_escape_string(str)
66
+ if /[\0-\x1f":\\\x7f]/ =~ str
67
+ '"' +
68
+ str.gsub(/[\0-\x1f":\\\x7f]/) {
69
+ ch = $&
70
+ case ch
71
+ when "\0"; '\0'
72
+ when "\a"; '\a'
73
+ when "\b"; '\b'
74
+ when "\f"; '\f'
75
+ when "\n"; '\n'
76
+ when "\r"; '\r'
77
+ when "\t"; '\t'
78
+ when "\v"; '\v'
79
+ when "\e"; '\e'
80
+ else
81
+ "\\x%02X" % ch.ord
82
+ end
83
+ } +
84
+ '"'
85
+ else
86
+ str
87
+ end
88
+ end
89
+
90
+ def Tb.ltsv_unescape_string(str)
91
+ if /\A\s*"(.*)"\s*\z/ =~ str
92
+ $1.gsub(/\\([0abfnrtve]|x([0-9A-Fa-f][0-9A-Fa-f]))/) {
93
+ if $2
94
+ [$2.to_i].pack("H2")
95
+ else
96
+ case $1
97
+ when "0"; "\0"
98
+ when "a"; "\a"
99
+ when "b"; "\b"
100
+ when "f"; "\f"
101
+ when "n"; "\n"
102
+ when "r"; "\r"
103
+ when "t"; "\t"
104
+ when "v"; "\v"
105
+ when "e"; "\e"
106
+ else
107
+ raise "[bug] unexpected escape"
108
+ end
109
+ end
110
+ }
111
+ else
112
+ str
113
+ end
114
+ end
115
+
116
+ class LTSVReader
117
+ include Tb::Enumerable
118
+
119
+ def initialize(input)
120
+ if input.respond_to? :to_str
121
+ @input = StringIO.new(input)
122
+ else
123
+ @input = input
124
+ end
125
+ end
126
+
127
+ def shift
128
+ line = @input.gets
129
+ return nil if !line
130
+ line = line.chomp("\n")
131
+ line = line.chomp("\r")
132
+ ary = line.split(/\t/, -1)
133
+ assoc = ary.map {|str|
134
+ /:/ =~ str
135
+ key = $`
136
+ val = $'
137
+ key = Tb.ltsv_unescape_string(key)
138
+ val = Tb.ltsv_unescape_string(val)
139
+ [key, val]
140
+ }
141
+ assoc
142
+ end
143
+
144
+ def header_and_each(header_proc)
145
+ header_proc.call(nil) if header_proc
146
+ while assoc = self.shift
147
+ yield Hash[assoc]
148
+ end
149
+ end
150
+
151
+ def each(&block)
152
+ header_and_each(nil, &block)
153
+ end
154
+ end
155
+
156
+ def Tb.ltsv_stream_output(out)
157
+ gen = Object.new
158
+ gen.instance_variable_set(:@out, out)
159
+ def gen.<<(assoc)
160
+ @out << Tb.ltsv_assoc_join(assoc) << "\n"
161
+ end
162
+ yield gen
163
+ end
164
+
165
+ # :call-seq:
166
+ # generate_ltsv(out='') {|recordids| modified_recordids }
167
+ # generate_ltsv(out='')
168
+ #
169
+ def generate_ltsv(out='', fields=nil, &block)
170
+ recordids = list_recordids
171
+ if block_given?
172
+ recordids = yield(recordids)
173
+ end
174
+ Tb.ltsv_stream_output(out) {|gen|
175
+ recordids.each {|recordid|
176
+ gen << get_record(recordid)
177
+ }
178
+ }
179
+ out
180
+ end
181
+
182
+ def Tb.ltsv_assoc_join(assoc)
183
+ assoc.map {|key, val|
184
+ Tb.ltsv_escape_string(key) + ':' + Tb.ltsv_escape_string(val)
185
+ }.join("\t")
186
+ end
187
+ end
@@ -1,6 +1,6 @@
1
1
  # lib/tb/ropen.rb - Tb::Reader.open
2
2
  #
3
- # Copyright (C) 2011-2012 Tanaka Akira <akr@fsij.org>
3
+ # Copyright (C) 2011-2013 Tanaka Akira <akr@fsij.org>
4
4
  #
5
5
  # Redistribution and use in source and binary forms, with or without
6
6
  # modification, are permitted provided that the following conditions
@@ -37,6 +37,9 @@ def Tb.open_reader(filename, opts={})
37
37
  when /\Atsv:/
38
38
  filename = $'
39
39
  rawreader_maker_for_tb_reader = lambda {|io| Tb::TSVReader.new(io) }
40
+ when /\Altsv:/
41
+ filename = $'
42
+ rawreader_maker_for_tb_reader = lambda {|io| Tb::LTSVReader.new(io) }
40
43
  when /\Ap[pgbn]m:/
41
44
  filename = $'
42
45
  rawreader_maker_for_tb_reader = lambda {|io| Tb.pnm_stream_input(io) }
@@ -47,6 +50,8 @@ def Tb.open_reader(filename, opts={})
47
50
  rawreader_maker_for_tb_reader = lambda {|io| Tb::CSVReader.new(io) }
48
51
  when /\.tsv\z/
49
52
  rawreader_maker_for_tb_reader = lambda {|io| Tb::TSVReader.new(io) }
53
+ when /\.ltsv\z/
54
+ reader_maker_for_tb_reader = lambda {|io| Tb::LTSVReader.new(io) }
50
55
  when /\.p[pgbn]m\z/
51
56
  rawreader_maker_for_tb_reader = lambda {|io| Tb.pnm_stream_input(io) }
52
57
  when /\.json\z/
@@ -65,6 +70,12 @@ def Tb.open_reader(filename, opts={})
65
70
  json_reader_maker.call(io)
66
71
  }
67
72
  end
73
+ elsif reader_maker_for_tb_reader
74
+ if filename == '-'
75
+ reader = reader_maker_for_tb_reader.call($stdin)
76
+ else
77
+ reader = reader_maker_for_tb_reader.call(File.open(filename))
78
+ end
68
79
  else
69
80
  # rawreader_maker_for_tb_reader should be available.
70
81
  reader = Tb::Reader.new(opts) {|body|
@@ -101,10 +101,10 @@ module Tb::Search
101
101
  when :s, :south; try_rmove(0, 1, aa, st, &b)
102
102
  when :e, :east; try_rmove(1, 0, aa, st, &b)
103
103
  when :w, :west; try_rmove(-1, 0, aa, st, &b)
104
- when :ne, :north; try_rmove(1, -1, aa, st, &b)
105
- when :nw, :south; try_rmove(-1, -1, aa, st, &b)
106
- when :se, :east; try_rmove(1, 1, aa, st, &b)
107
- when :sw, :west; try_rmove(-1, 1, aa, st, &b)
104
+ when :ne, :northeast; try_rmove(1, -1, aa, st, &b)
105
+ when :nw, :northwest; try_rmove(-1, -1, aa, st, &b)
106
+ when :se, :southeast; try_rmove(1, 1, aa, st, &b)
107
+ when :sw, :southwest; try_rmove(-1, 1, aa, st, &b)
108
108
  when :debug_print_state; p st; yield st
109
109
  when Array
110
110
  case pat[0]
@@ -0,0 +1,65 @@
1
+ require 'test/unit'
2
+ require 'tb/cmdtop'
3
+ require 'tmpdir'
4
+
5
+ class TestTbCmdToLTSV < Test::Unit::TestCase
6
+ def setup
7
+ Tb::Cmd.reset_option
8
+ @curdir = Dir.pwd
9
+ @tmpdir = Dir.mktmpdir
10
+ Dir.chdir @tmpdir
11
+ end
12
+ def teardown
13
+ Tb::Cmd.reset_option
14
+ Dir.chdir @curdir
15
+ FileUtils.rmtree @tmpdir
16
+ end
17
+
18
+ def test_basic
19
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
20
+ a,b,c
21
+ 0,1,2
22
+ 4,5,6
23
+ End
24
+ Tb::Cmd.main_to_ltsv(['-o', o="o.ltsv", i])
25
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
26
+ a:0\tb:1\tc:2
27
+ a:4\tb:5\tc:6
28
+ End
29
+ end
30
+
31
+ def test_numeric
32
+ File.open(i="i.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
33
+ a,b,c
34
+ 0,1,2
35
+ 4,5,6
36
+ End
37
+ Tb::Cmd.main_to_ltsv(['-o', o="o.ltsv", '-N', i])
38
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
39
+ 1:a\t2:b\t3:c
40
+ 1:0\t2:1\t3:2
41
+ 1:4\t2:5\t3:6
42
+ End
43
+ end
44
+
45
+ def test_twofile
46
+ File.open(i1="i1.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
47
+ a,b
48
+ 1,2
49
+ 3,4
50
+ End
51
+ File.open(i2="i2.csv", "w") {|f| f << <<-"End".gsub(/^[ \t]+/, '') }
52
+ b,a
53
+ 5,6
54
+ 7,8
55
+ End
56
+ Tb::Cmd.main_to_ltsv(['-o', o="o.ltsv", i1, i2])
57
+ assert_equal(<<-"End".gsub(/^[ \t]+/, ''), File.read(o))
58
+ a:1\tb:2
59
+ a:3\tb:4
60
+ a:6\tb:5
61
+ a:8\tb:7
62
+ End
63
+ end
64
+
65
+ end
@@ -0,0 +1,40 @@
1
+ require 'tb'
2
+ require 'test/unit'
3
+
4
+ class TestTbLTSV < Test::Unit::TestCase
5
+ def test_parse
6
+ r = Tb::LTSVReader.new("a:1\tb:2\na:3\tb:4\n")
7
+ result = []
8
+ r.with_header {|header|
9
+ result << header
10
+ }.each {|obj|
11
+ result << obj
12
+ }
13
+ assert_equal([nil, {"a"=>"1", "b"=>"2"}, {"a"=>"3", "b"=>"4"}], result)
14
+ end
15
+
16
+ def test_parse2
17
+ ltsv = "a:1\tb:2\n"
18
+ t = Tb.parse_ltsv(ltsv)
19
+ records = []
20
+ t.each_record {|record|
21
+ records << record.to_h_with_reserved
22
+ }
23
+ assert_equal(
24
+ [{"_recordid"=>0, "a"=>"1", "b"=>"2"}],
25
+ records)
26
+ end
27
+
28
+ def test_generate_ltsv
29
+ tbl = Tb.new %w[a b], %w[foo bar]
30
+ tbl.generate_ltsv(out="")
31
+ assert_equal("a:foo\tb:bar\n", out)
32
+ end
33
+
34
+ def test_generate_ltsv_with_block
35
+ tbl = Tb.new %w[a b], %w[foo bar], %w[q w]
36
+ tbl.generate_ltsv(out="") {|recids| recids.reverse }
37
+ assert_equal("a:q\tb:w\na:foo\tb:bar\n", out)
38
+ end
39
+
40
+ end
@@ -1,3 +1,5 @@
1
+ # coding: ASCII-8BIT
2
+
1
3
  require 'tb'
2
4
  require 'tmpdir'
3
5
  require 'test/unit'
metadata CHANGED
@@ -1,32 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tb
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.7'
5
- prerelease:
4
+ version: '0.8'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tanaka Akira
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-05-29 00:00:00.000000000 Z
11
+ date: 2013-03-29 00:00:00.000000000 Z
13
12
  dependencies: []
14
- description: ! 'tb is a manipulation tool for table: CSV, TSV, JSON, etc.
15
-
13
+ description: |
14
+ tb is a manipulation tool for table: CSV, TSV, LTSV, JSON, etc.
16
15
 
17
16
  tb provides a command and a library for manipulating tables:
18
-
19
17
  Unix filter like operations (grep, sort, cat, cut, ls, etc.),
20
-
21
18
  SQL like operations (join, group, etc.),
22
-
23
19
  other table operations (gsub, rename, cross, melt, unmelt, etc.),
24
-
25
20
  information extractions (git, svn, tar),
26
-
27
21
  and more.
28
-
29
- '
30
22
  email: akr@fsij.org
31
23
  executables:
32
24
  - tb
@@ -61,6 +53,7 @@ files:
61
53
  - lib/tb/cmd_tar.rb
62
54
  - lib/tb/cmd_to_csv.rb
63
55
  - lib/tb/cmd_to_json.rb
56
+ - lib/tb/cmd_to_ltsv.rb
64
57
  - lib/tb/cmd_to_pnm.rb
65
58
  - lib/tb/cmd_to_pp.rb
66
59
  - lib/tb/cmd_to_tsv.rb
@@ -81,6 +74,7 @@ files:
81
74
  - lib/tb/fileenumerator.rb
82
75
  - lib/tb/func.rb
83
76
  - lib/tb/json.rb
77
+ - lib/tb/ltsv.rb
84
78
  - lib/tb/pager.rb
85
79
  - lib/tb/pnm.rb
86
80
  - lib/tb/reader.rb
@@ -124,6 +118,7 @@ files:
124
118
  - test/test_cmd_tar_tvf.rb
125
119
  - test/test_cmd_to_csv.rb
126
120
  - test/test_cmd_to_json.rb
121
+ - test/test_cmd_to_ltsv.rb
127
122
  - test/test_cmd_to_pnm.rb
128
123
  - test/test_cmd_to_pp.rb
129
124
  - test/test_cmd_to_tsv.rb
@@ -139,6 +134,7 @@ files:
139
134
  - test/test_fieldset.rb
140
135
  - test/test_fileenumerator.rb
141
136
  - test/test_json.rb
137
+ - test/test_ltsv.rb
142
138
  - test/test_pager.rb
143
139
  - test/test_pnm.rb
144
140
  - test/test_reader.rb
@@ -150,28 +146,27 @@ files:
150
146
  - test/test_zipper.rb
151
147
  homepage: https://github.com/akr/tb
152
148
  licenses: []
149
+ metadata: {}
153
150
  post_install_message:
154
151
  rdoc_options: []
155
152
  require_paths:
156
153
  - lib
157
154
  required_ruby_version: !ruby/object:Gem::Requirement
158
- none: false
159
155
  requirements:
160
- - - ! '>='
156
+ - - '>='
161
157
  - !ruby/object:Gem::Version
162
158
  version: 1.9.2
163
159
  required_rubygems_version: !ruby/object:Gem::Requirement
164
- none: false
165
160
  requirements:
166
- - - ! '>='
161
+ - - '>='
167
162
  - !ruby/object:Gem::Version
168
163
  version: '0'
169
164
  requirements: []
170
165
  rubyforge_project:
171
- rubygems_version: 1.8.11
166
+ rubygems_version: 2.0.2
172
167
  signing_key:
173
- specification_version: 3
174
- summary: ! 'manipulation tool for tables: CSV, TSV, JSON, etc.'
168
+ specification_version: 4
169
+ summary: 'manipulation tool for tables: CSV, TSV, LTSV, JSON, etc.'
175
170
  test_files:
176
171
  - test/test_basic.rb
177
172
  - test/test_catreader.rb
@@ -198,6 +193,7 @@ test_files:
198
193
  - test/test_cmd_tar_tvf.rb
199
194
  - test/test_cmd_to_csv.rb
200
195
  - test/test_cmd_to_json.rb
196
+ - test/test_cmd_to_ltsv.rb
201
197
  - test/test_cmd_to_pnm.rb
202
198
  - test/test_cmd_to_pp.rb
203
199
  - test/test_cmd_to_tsv.rb
@@ -213,6 +209,7 @@ test_files:
213
209
  - test/test_fieldset.rb
214
210
  - test/test_fileenumerator.rb
215
211
  - test/test_json.rb
212
+ - test/test_ltsv.rb
216
213
  - test/test_pager.rb
217
214
  - test/test_pnm.rb
218
215
  - test/test_reader.rb