tb 0.7 → 0.8

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: 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