csv 3.0.1 → 3.0.2
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 +4 -4
- data/{news.md → NEWS.md} +29 -0
- data/lib/csv.rb +222 -614
- data/lib/csv/fields_converter.rb +78 -0
- data/lib/csv/match_p.rb +20 -0
- data/lib/csv/parser.rb +713 -0
- data/lib/csv/version.rb +1 -1
- data/lib/csv/writer.rb +144 -0
- metadata +8 -4
data/lib/csv/version.rb
CHANGED
data/lib/csv/writer.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "match_p"
|
4
|
+
require_relative "row"
|
5
|
+
|
6
|
+
using CSV::MatchP if CSV.const_defined?(:MatchP)
|
7
|
+
|
8
|
+
class CSV
|
9
|
+
class Writer
|
10
|
+
attr_reader :lineno
|
11
|
+
attr_reader :headers
|
12
|
+
|
13
|
+
def initialize(output, options)
|
14
|
+
@output = output
|
15
|
+
@options = options
|
16
|
+
@lineno = 0
|
17
|
+
prepare
|
18
|
+
if @options[:write_headers] and @headers
|
19
|
+
self << @headers
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def <<(row)
|
24
|
+
case row
|
25
|
+
when Row
|
26
|
+
row = row.fields
|
27
|
+
when Hash
|
28
|
+
row = @headers.collect {|header| row[header]}
|
29
|
+
end
|
30
|
+
|
31
|
+
@headers ||= row if @use_headers
|
32
|
+
@lineno += 1
|
33
|
+
|
34
|
+
line = row.collect(&@quote).join(@column_separator) + @row_separator
|
35
|
+
if @output_encoding
|
36
|
+
line = line.encode(@output_encoding)
|
37
|
+
end
|
38
|
+
@output << line
|
39
|
+
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def rewind
|
44
|
+
@lineno = 0
|
45
|
+
@headers = nil if @options[:headers].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
def prepare
|
50
|
+
@encoding = @options[:encoding]
|
51
|
+
|
52
|
+
prepare_header
|
53
|
+
prepare_format
|
54
|
+
prepare_output
|
55
|
+
end
|
56
|
+
|
57
|
+
def prepare_header
|
58
|
+
headers = @options[:headers]
|
59
|
+
case headers
|
60
|
+
when Array
|
61
|
+
@headers = headers
|
62
|
+
@use_headers = true
|
63
|
+
when String
|
64
|
+
@headers = CSV.parse_line(headers,
|
65
|
+
col_sep: @options[:column_separator],
|
66
|
+
row_sep: @options[:row_separator],
|
67
|
+
quote_char: @options[:quote_character])
|
68
|
+
@use_headers = true
|
69
|
+
when true
|
70
|
+
@headers = nil
|
71
|
+
@use_headers = true
|
72
|
+
else
|
73
|
+
@headers = nil
|
74
|
+
@use_headers = false
|
75
|
+
end
|
76
|
+
return unless @headers
|
77
|
+
|
78
|
+
converter = @options[:header_fields_converter]
|
79
|
+
@headers = converter.convert(@headers, nil, 0)
|
80
|
+
@headers.each do |header|
|
81
|
+
header.freeze if header.is_a?(String)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def prepare_format
|
86
|
+
@column_separator = @options[:column_separator].to_s.encode(@encoding)
|
87
|
+
row_separator = @options[:row_separator]
|
88
|
+
if row_separator == :auto
|
89
|
+
@row_separator = $INPUT_RECORD_SEPARATOR.encode(@encoding)
|
90
|
+
else
|
91
|
+
@row_separator = row_separator.to_s.encode(@encoding)
|
92
|
+
end
|
93
|
+
quote_character = @options[:quote_character]
|
94
|
+
quote = lambda do |field|
|
95
|
+
field = String(field)
|
96
|
+
encoded_quote_character = quote_character.encode(field.encoding)
|
97
|
+
encoded_quote_character +
|
98
|
+
field.gsub(encoded_quote_character,
|
99
|
+
encoded_quote_character * 2) +
|
100
|
+
encoded_quote_character
|
101
|
+
end
|
102
|
+
if @options[:force_quotes]
|
103
|
+
@quote = quote
|
104
|
+
else
|
105
|
+
quotable_pattern =
|
106
|
+
Regexp.new("[\r\n".encode(@encoding) +
|
107
|
+
Regexp.escape(@column_separator) +
|
108
|
+
Regexp.escape(quote_character.encode(@encoding)) +
|
109
|
+
"]".encode(@encoding))
|
110
|
+
@quote = lambda do |field|
|
111
|
+
if field.nil? # represent +nil+ fields as empty unquoted fields
|
112
|
+
""
|
113
|
+
else
|
114
|
+
field = String(field) # Stringify fields
|
115
|
+
# represent empty fields as empty quoted fields
|
116
|
+
if field.empty? or quotable_pattern.match?(field)
|
117
|
+
quote.call(field)
|
118
|
+
else
|
119
|
+
field # unquoted field
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def prepare_output
|
127
|
+
@output_encoding = nil
|
128
|
+
return unless @output.is_a?(StringIO)
|
129
|
+
|
130
|
+
output_encoding = @output.internal_encoding || @output.external_encoding
|
131
|
+
if @encoding != output_encoding
|
132
|
+
if @options[:force_encoding]
|
133
|
+
@output_encoding = output_encoding
|
134
|
+
else
|
135
|
+
compatible_encoding = Encoding.compatible?(@encoding, output_encoding)
|
136
|
+
if compatible_encoding
|
137
|
+
@output.set_encoding(compatible_encoding)
|
138
|
+
@output.seek(0, IO::SEEK_END)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Edward Gray II
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-12-
|
12
|
+
date: 2018-12-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -78,14 +78,18 @@ extensions: []
|
|
78
78
|
extra_rdoc_files: []
|
79
79
|
files:
|
80
80
|
- LICENSE.txt
|
81
|
+
- NEWS.md
|
81
82
|
- README.md
|
82
83
|
- lib/csv.rb
|
83
84
|
- lib/csv/core_ext/array.rb
|
84
85
|
- lib/csv/core_ext/string.rb
|
86
|
+
- lib/csv/fields_converter.rb
|
87
|
+
- lib/csv/match_p.rb
|
88
|
+
- lib/csv/parser.rb
|
85
89
|
- lib/csv/row.rb
|
86
90
|
- lib/csv/table.rb
|
87
91
|
- lib/csv/version.rb
|
88
|
-
-
|
92
|
+
- lib/csv/writer.rb
|
89
93
|
homepage: https://github.com/ruby/csv
|
90
94
|
licenses:
|
91
95
|
- BSD-2-Clause
|
@@ -106,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
110
|
version: '0'
|
107
111
|
requirements: []
|
108
112
|
rubyforge_project:
|
109
|
-
rubygems_version: 3.0.0.
|
113
|
+
rubygems_version: 3.0.0.beta2
|
110
114
|
signing_key:
|
111
115
|
specification_version: 4
|
112
116
|
summary: CSV Reading and Writing
|