censive 1.0.5 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/censive.rb +34 -31
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f5885eeeeab9f57546128e03407fbb1546137c3dfe19edc1a8dc8e08c95ad50
|
4
|
+
data.tar.gz: ed4b2f1ac55b826534c5bf9d854feca86cd2b4ef3cca9a2fab9e1993f3b2d6a4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf304f19bcabdbff428cfbc021807228291eded005c30bb3578bf2530f97dfb73b7fd08f684f39cb2eb5bd159c24ecedc8d6d8a768dd3dba50c3462ff87dc597
|
7
|
+
data.tar.gz: 02fddd62e35fd145ed34d34524c038b3397508eb8bfc81ce66dad2cfd4b4ea4bea931f1685f1f8ae81cdaac027740c5ef73f422c80c566974121ceaa3ed4bb87
|
data/lib/censive.rb
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# censive - A quick and lightweight CSV handling library for Ruby
|
5
5
|
#
|
6
6
|
# Author: Steve Shreeve (steve.shreeve@gmail.com)
|
7
|
-
# Date: June
|
7
|
+
# Date: June 28, 2023
|
8
8
|
#
|
9
9
|
# https://crystal-lang.org/api/1.7.2/CSV.html (Crystal's CSV library)
|
10
10
|
# https://github.com/ruby/strscan/blob/master/ext/strscan/strscan.c
|
11
11
|
#
|
12
|
-
# Thanks to Sutou Kouhei (kou) for his excellent advice on using scan
|
12
|
+
# Thanks to Sutou Kouhei (kou) for his excellent advice on using scan better
|
13
13
|
# ============================================================================
|
14
|
-
#
|
14
|
+
# HIGHLIGHTS:
|
15
15
|
# 1. Faster than Ruby's default CSV library
|
16
16
|
# 2. Lightweight code with streamlined and optimized logic
|
17
17
|
# 3. Support most non-compliant CSV variations (@excel, @relax, etc)
|
@@ -29,15 +29,15 @@ require "stringio"
|
|
29
29
|
require "strscan"
|
30
30
|
|
31
31
|
class Censive < StringScanner
|
32
|
-
VERSION="1.0
|
32
|
+
VERSION="1.1.0"
|
33
33
|
|
34
34
|
attr :encoding, :out, :rows
|
35
35
|
|
36
|
-
def self.
|
37
|
-
new(...).
|
36
|
+
def self.read(...)
|
37
|
+
new(...).read
|
38
38
|
end
|
39
39
|
|
40
|
-
def self.
|
40
|
+
def self.write(obj=nil, **opts, &code)
|
41
41
|
case obj
|
42
42
|
when String
|
43
43
|
if block_given?
|
@@ -48,7 +48,7 @@ class Censive < StringScanner
|
|
48
48
|
when StringIO, IO, nil
|
49
49
|
new(out: obj, **opts, &code)
|
50
50
|
else
|
51
|
-
abort "#{File.basename($0)}:
|
51
|
+
abort "#{File.basename($0)}: #{self}.write can't use #{obj.class} objects"
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -124,9 +124,9 @@ class Censive < StringScanner
|
|
124
124
|
super()
|
125
125
|
end
|
126
126
|
|
127
|
-
# ==[
|
127
|
+
# ==[ Reader ]==
|
128
128
|
|
129
|
-
def
|
129
|
+
def read
|
130
130
|
@rows = []
|
131
131
|
while row = next_row
|
132
132
|
@rows << row
|
@@ -189,28 +189,19 @@ class Censive < StringScanner
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def each
|
192
|
-
@rows or
|
192
|
+
@rows or read
|
193
193
|
@rows.each {|row| yield row }
|
194
194
|
end
|
195
195
|
|
196
|
-
|
196
|
+
# ==[ Writer ]==
|
197
|
+
|
198
|
+
def write(*args, **opts, &code)
|
197
199
|
if args.empty? && opts.empty?
|
198
200
|
block_given? ? each(&code) : each {|row| @out << row }
|
199
201
|
elsif block_given?
|
200
|
-
Censive.
|
201
|
-
else
|
202
|
-
Censive.writer(*args, **opts) {|csv| each {|row| csv << row }}
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
# ==[ Helpers ]==
|
207
|
-
|
208
|
-
# returns 2 (must be quoted and escaped), 1 (must be quoted), 0 (neither)
|
209
|
-
def grok(str)
|
210
|
-
if idx = str&.index(@escapes)
|
211
|
-
$1 ? 2 : str.index(@quote, idx) ? 2 : 1
|
202
|
+
Censive.write(*args, **opts, &code)
|
212
203
|
else
|
213
|
-
|
204
|
+
Censive.write(*args, **opts) {|csv| each {|row| csv << row }}
|
214
205
|
end
|
215
206
|
end
|
216
207
|
|
@@ -223,7 +214,7 @@ class Censive < StringScanner
|
|
223
214
|
s,q = @sep, @quote
|
224
215
|
out = case @mode
|
225
216
|
when :compact
|
226
|
-
case @excel ? 2 :
|
217
|
+
case @excel ? 2 : quote_type(row.join)
|
227
218
|
when 0
|
228
219
|
row
|
229
220
|
when 1
|
@@ -233,7 +224,7 @@ class Censive < StringScanner
|
|
233
224
|
else
|
234
225
|
row.map do |col|
|
235
226
|
@excel && col =~ @leadzero ? "=#{q}#{col}#{q}" :
|
236
|
-
case
|
227
|
+
case quote_type(col)
|
237
228
|
when 0 then col
|
238
229
|
when 1 then "#{q}#{col}#{q}"
|
239
230
|
else "#{q}#{col.gsub(q, @esc)}#{q}"
|
@@ -253,6 +244,21 @@ class Censive < StringScanner
|
|
253
244
|
@out << out + @rowsep
|
254
245
|
end
|
255
246
|
|
247
|
+
# ==[ Helpers ]==
|
248
|
+
|
249
|
+
def bomb(msg)
|
250
|
+
abort "\n#{File.basename($0)}: #{msg} at character #{pos} near '#{string[pos-4,7]}'"
|
251
|
+
end
|
252
|
+
|
253
|
+
# returns 2 (must be quoted and escaped), 1 (must be quoted), 0 (neither)
|
254
|
+
def quote_type(str)
|
255
|
+
if idx = str&.index(@escapes)
|
256
|
+
$1 ? 2 : str.index(@quote, idx) ? 2 : 1
|
257
|
+
else
|
258
|
+
0
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
256
262
|
def stats
|
257
263
|
wide = string.size.to_s.size
|
258
264
|
puts "%#{wide}d rows" % @rows.size
|
@@ -261,9 +267,6 @@ class Censive < StringScanner
|
|
261
267
|
puts "%#{wide}d bytes" % string.size
|
262
268
|
end
|
263
269
|
|
264
|
-
def bomb(msg)
|
265
|
-
abort "\n#{File.basename($0)}: #{msg} at character #{pos} near '#{string[pos-4,7]}'"
|
266
|
-
end
|
267
270
|
end
|
268
271
|
|
269
272
|
if __FILE__ == $0
|
@@ -281,7 +284,7 @@ if __FILE__ == $0
|
|
281
284
|
# out = csv.export
|
282
285
|
# puts out.out
|
283
286
|
|
284
|
-
puts Censive.
|
287
|
+
puts Censive.read(str, excel: true, relax: true).write
|
285
288
|
end
|
286
289
|
|
287
290
|
__END__
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: censive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Shreeve
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-06-
|
11
|
+
date: 2023-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A quick and lightweight CSV handling library for Ruby
|
14
14
|
email: steve.shreeve@gmail.com
|