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.
- checksums.yaml +7 -0
- data/lib/tb.rb +2 -1
- data/lib/tb/cmd_grep.rb +2 -2
- data/lib/tb/cmd_tar.rb +3 -3
- data/lib/tb/cmd_to_ltsv.rb +48 -0
- data/lib/tb/cmdtop.rb +2 -1
- data/lib/tb/cmdutil.rb +19 -1
- data/lib/tb/enumerable.rb +8 -1
- data/lib/tb/ltsv.rb +187 -0
- data/lib/tb/ropen.rb +12 -1
- data/lib/tb/search.rb +4 -4
- data/test/test_cmd_to_ltsv.rb +65 -0
- data/test/test_ltsv.rb +40 -0
- data/test/test_pnm.rb +2 -0
- metadata +16 -19
checksums.yaml
ADDED
@@ -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-
|
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'
|
data/lib/tb/cmd_grep.rb
CHANGED
@@ -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', '
|
43
|
-
op.def_option('--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
|
data/lib/tb/cmd_tar.rb
CHANGED
@@ -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
|
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
|
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
|
+
|
data/lib/tb/cmdtop.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
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'
|
data/lib/tb/cmdutil.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C) 2011-
|
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
|
data/lib/tb/enumerable.rb
CHANGED
@@ -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 "["
|
data/lib/tb/ltsv.rb
ADDED
@@ -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
|
data/lib/tb/ropen.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# lib/tb/ropen.rb - Tb::Reader.open
|
2
2
|
#
|
3
|
-
# Copyright (C) 2011-
|
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|
|
data/lib/tb/search.rb
CHANGED
@@ -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, :
|
105
|
-
when :nw, :
|
106
|
-
when :se, :
|
107
|
-
when :sw, :
|
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
|
data/test/test_ltsv.rb
ADDED
@@ -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
|
data/test/test_pnm.rb
CHANGED
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.
|
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:
|
11
|
+
date: 2013-03-29 00:00:00.000000000 Z
|
13
12
|
dependencies: []
|
14
|
-
description:
|
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:
|
166
|
+
rubygems_version: 2.0.2
|
172
167
|
signing_key:
|
173
|
-
specification_version:
|
174
|
-
summary:
|
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
|