csv 3.1.4 → 3.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS.md +97 -0
  3. data/README.md +5 -0
  4. data/doc/csv/arguments/io.rdoc +5 -0
  5. data/doc/csv/options/common/col_sep.rdoc +57 -0
  6. data/doc/csv/options/common/quote_char.rdoc +42 -0
  7. data/doc/csv/options/common/row_sep.rdoc +91 -0
  8. data/doc/csv/options/generating/force_quotes.rdoc +17 -0
  9. data/doc/csv/options/generating/quote_empty.rdoc +12 -0
  10. data/doc/csv/options/generating/write_converters.rdoc +25 -0
  11. data/doc/csv/options/generating/write_empty_value.rdoc +15 -0
  12. data/doc/csv/options/generating/write_headers.rdoc +29 -0
  13. data/doc/csv/options/generating/write_nil_value.rdoc +14 -0
  14. data/doc/csv/options/parsing/converters.rdoc +46 -0
  15. data/doc/csv/options/parsing/empty_value.rdoc +13 -0
  16. data/doc/csv/options/parsing/field_size_limit.rdoc +39 -0
  17. data/doc/csv/options/parsing/header_converters.rdoc +43 -0
  18. data/doc/csv/options/parsing/headers.rdoc +63 -0
  19. data/doc/csv/options/parsing/liberal_parsing.rdoc +19 -0
  20. data/doc/csv/options/parsing/nil_value.rdoc +12 -0
  21. data/doc/csv/options/parsing/return_headers.rdoc +22 -0
  22. data/doc/csv/options/parsing/skip_blanks.rdoc +31 -0
  23. data/doc/csv/options/parsing/skip_lines.rdoc +37 -0
  24. data/doc/csv/options/parsing/strip.rdoc +15 -0
  25. data/doc/csv/options/parsing/unconverted_fields.rdoc +27 -0
  26. data/doc/csv/recipes/filtering.rdoc +158 -0
  27. data/doc/csv/recipes/generating.rdoc +298 -0
  28. data/doc/csv/recipes/parsing.rdoc +545 -0
  29. data/doc/csv/recipes/recipes.rdoc +6 -0
  30. data/lib/csv.rb +1570 -520
  31. data/lib/csv/parser.rb +1 -0
  32. data/lib/csv/row.rb +478 -133
  33. data/lib/csv/table.rb +750 -108
  34. data/lib/csv/version.rb +1 -1
  35. data/lib/csv/writer.rb +45 -4
  36. metadata +42 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dad2154faebc0d08b471d1f5624752997374f8472dc2408756d7a78efb87d9c9
4
- data.tar.gz: 9c6e071bcf07ab25aa0ff068030b42dbb47968d9f9e7aa5b04a1ff33ed12c2ea
3
+ metadata.gz: 44985560f2528c6909f94ce869ec8ddb014ee66d89fe940fe6f4c872f8773e97
4
+ data.tar.gz: 60297accbe6a82852d251f5e4990dfacc241d6ec1084a39eb7ce39ac04c059d6
5
5
  SHA512:
6
- metadata.gz: 4da5b31e15b5c215d1f346c330a3d86ebea640cc4af4c33bd0aa238ac4b9b5cde2c72fc7edcd045de60f4cacb49a5ed8cbbf8a963a1a0750d16f5472faa95c1c
7
- data.tar.gz: 83ee56fae5acb6afdb8d722e0c0182f17112a157a2ab6ad0b30a60d524fd146850a1afe360217c2e2b5af36335668716289612ae1817d98c77b2ea2c5d610240
6
+ metadata.gz: 7d51eae6f0e4eaccf382ffc52306ff9b9235259353c8514aafc3fd0116449ae342d9b5972e6ab236ddad542a9a286580f060080503fb18a2f81dfc97299cb8e8
7
+ data.tar.gz: ef7d5e134f0ed59e4e0e466c5a6c4a6e45d51ff90a8e3bc22be1014041d29cb3a70c6ae7b482865426d5957962007875b734364b43742b2b7074548d3263bc76
data/NEWS.md CHANGED
@@ -1,5 +1,102 @@
1
1
  # News
2
2
 
3
+ ## 3.1.9 - 2020-11-23
4
+
5
+ ### Fixes
6
+
7
+ * Fixed a compatibility bug that the line to be processed by
8
+ `skip_lines:` has a row separator.
9
+ [GitHub#194][Reported by Josef Šimánek]
10
+
11
+ ### Thanks
12
+
13
+ * Josef Šimánek
14
+
15
+ ## 3.1.8 - 2020-11-18
16
+
17
+ ### Improvements
18
+
19
+ * Improved documentation.
20
+ [Patch by Burdette Lamar]
21
+
22
+ ### Thanks
23
+
24
+ * Burdette Lamar
25
+
26
+ ## 3.1.7 - 2020-08-04
27
+
28
+ ### Improvements
29
+
30
+ * Improved document.
31
+ [GitHub#158][GitHub#160][GitHub#161]
32
+ [Patch by Burdette Lamar]
33
+
34
+ * Updated required Ruby version to 2.5.0 or later.
35
+ [GitHub#159]
36
+ [Patch by Gabriel Nagy]
37
+
38
+ * Removed stringio 0.1.3 or later dependency.
39
+
40
+ ### Thanks
41
+
42
+ * Burdette Lamar
43
+
44
+ * Gabriel Nagy
45
+
46
+ ## 3.1.6 - 2020-07-20
47
+
48
+ ### Improvements
49
+
50
+ * Improved document.
51
+ [GitHub#127][GitHub#135][GitHub#136][GitHub#137][GitHub#139][GitHub#140]
52
+ [GitHub#141][GitHub#142][GitHub#143][GitHub#145][GitHub#146][GitHub#148]
53
+ [GitHub#148][GitHub#151][GitHub#152][GitHub#154][GitHub#155][GitHub#157]
54
+ [Patch by Burdette Lamar]
55
+
56
+ * `CSV.open`: Added support for `undef: :replace`.
57
+ [GitHub#129][Patch by Koichi ITO]
58
+
59
+ * `CSV.open`: Added support for `invalid: :replace`.
60
+ [GitHub#129][Patch by Koichi ITO]
61
+
62
+ * Don't run quotable check for invalid encoding field values.
63
+ [GitHub#131][Patch by Koichi ITO]
64
+
65
+ * Added support for specifying the target indexes and names to
66
+ `force_quotes:`.
67
+ [GitHub#153][Reported by Aleksandr]
68
+
69
+ * `CSV.generate`: Changed to use the encoding of the first non-ASCII
70
+ field rather than the encoding of ASCII only field.
71
+
72
+ * Changed to require the stringio gem 0.1.3 or later.
73
+
74
+ ### Thanks
75
+
76
+ * Burdette Lamar
77
+
78
+ * Koichi ITO
79
+
80
+ * Aleksandr
81
+
82
+ ## 3.1.5 - 2020-05-18
83
+
84
+ ### Improvements
85
+
86
+ * Improved document.
87
+ [GitHub#124][Patch by Burdette Lamar]
88
+
89
+ ### Fixes
90
+
91
+ * Added missing document files.
92
+ [GitHub#125][Reported by joast]
93
+
94
+ ### Thanks
95
+
96
+ * Burdette Lamar
97
+
98
+ * joast
99
+
3
100
  ## 3.1.4 - 2020-05-17
4
101
 
5
102
  ### Improvements
data/README.md CHANGED
@@ -31,6 +31,11 @@ CSV.foreach("path/to/file.csv") do |row|
31
31
  end
32
32
  ```
33
33
 
34
+ ## Documentation
35
+
36
+ - {API}[CSV.html]: all classes, methods, and constants.
37
+ - {Recipes}[doc/csv/recipes/recipes_rdoc.html]: specific code for specific tasks.
38
+
34
39
  ## Development
35
40
 
36
41
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -0,0 +1,5 @@
1
+ * Argument +io+ should be an IO object that is:
2
+ * Open for reading; on return, the IO object will be closed.
3
+ * Positioned at the beginning.
4
+ To position at the end, for appending, use method CSV.generate.
5
+ For any other positioning, pass a preset \StringIO object instead.
@@ -0,0 +1,57 @@
1
+ ====== Option +col_sep+
2
+
3
+ Specifies the \String column separator to be used
4
+ for both parsing and generating.
5
+ The \String will be transcoded into the data's \Encoding before use.
6
+
7
+ Default value:
8
+ CSV::DEFAULT_OPTIONS.fetch(:col_sep) # => "," (comma)
9
+
10
+ Using the default (comma):
11
+ str = CSV.generate do |csv|
12
+ csv << [:foo, 0]
13
+ csv << [:bar, 1]
14
+ csv << [:baz, 2]
15
+ end
16
+ str # => "foo,0\nbar,1\nbaz,2\n"
17
+ ary = CSV.parse(str)
18
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
19
+
20
+ Using +:+ (colon):
21
+ col_sep = ':'
22
+ str = CSV.generate(col_sep: col_sep) do |csv|
23
+ csv << [:foo, 0]
24
+ csv << [:bar, 1]
25
+ csv << [:baz, 2]
26
+ end
27
+ str # => "foo:0\nbar:1\nbaz:2\n"
28
+ ary = CSV.parse(str, col_sep: col_sep)
29
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
30
+
31
+ Using +::+ (two colons):
32
+ col_sep = '::'
33
+ str = CSV.generate(col_sep: col_sep) do |csv|
34
+ csv << [:foo, 0]
35
+ csv << [:bar, 1]
36
+ csv << [:baz, 2]
37
+ end
38
+ str # => "foo::0\nbar::1\nbaz::2\n"
39
+ ary = CSV.parse(str, col_sep: col_sep)
40
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
41
+
42
+ Using <tt>''</tt> (empty string):
43
+ col_sep = ''
44
+ str = CSV.generate(col_sep: col_sep) do |csv|
45
+ csv << [:foo, 0]
46
+ csv << [:bar, 1]
47
+ csv << [:baz, 2]
48
+ end
49
+ str # => "foo0\nbar1\nbaz2\n"
50
+
51
+ ---
52
+
53
+ Raises an exception if parsing with the empty \String:
54
+ col_sep = ''
55
+ # Raises ArgumentError (:col_sep must be 1 or more characters: "")
56
+ CSV.parse("foo0\nbar1\nbaz2\n", col_sep: col_sep)
57
+
@@ -0,0 +1,42 @@
1
+ ====== Option +quote_char+
2
+
3
+ Specifies the character (\String of length 1) used used to quote fields
4
+ in both parsing and generating.
5
+ This String will be transcoded into the data's \Encoding before use.
6
+
7
+ Default value:
8
+ CSV::DEFAULT_OPTIONS.fetch(:quote_char) # => "\"" (double quote)
9
+
10
+ This is useful for an application that incorrectly uses <tt>'</tt> (single-quote)
11
+ to quote fields, instead of the correct <tt>"</tt> (double-quote).
12
+
13
+ Using the default (double quote):
14
+ str = CSV.generate do |csv|
15
+ csv << ['foo', 0]
16
+ csv << ["'bar'", 1]
17
+ csv << ['"baz"', 2]
18
+ end
19
+ str # => "foo,0\n'bar',1\n\"\"\"baz\"\"\",2\n"
20
+ ary = CSV.parse(str)
21
+ ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]]
22
+
23
+ Using <tt>'</tt> (single-quote):
24
+ quote_char = "'"
25
+ str = CSV.generate(quote_char: quote_char) do |csv|
26
+ csv << ['foo', 0]
27
+ csv << ["'bar'", 1]
28
+ csv << ['"baz"', 2]
29
+ end
30
+ str # => "foo,0\n'''bar''',1\n\"baz\",2\n"
31
+ ary = CSV.parse(str, quote_char: quote_char)
32
+ ary # => [["foo", "0"], ["'bar'", "1"], ["\"baz\"", "2"]]
33
+
34
+ ---
35
+
36
+ Raises an exception if the \String length is greater than 1:
37
+ # Raises ArgumentError (:quote_char has to be nil or a single character String)
38
+ CSV.new('', quote_char: 'xx')
39
+
40
+ Raises an exception if the value is not a \String:
41
+ # Raises ArgumentError (:quote_char has to be nil or a single character String)
42
+ CSV.new('', quote_char: :foo)
@@ -0,0 +1,91 @@
1
+ ====== Option +row_sep+
2
+
3
+ Specifies the row separator, a \String or the \Symbol <tt>:auto</tt> (see below),
4
+ to be used for both parsing and generating.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:row_sep) # => :auto
8
+
9
+ ---
10
+
11
+ When +row_sep+ is a \String, that \String becomes the row separator.
12
+ The String will be transcoded into the data's Encoding before use.
13
+
14
+ Using <tt>"\n"</tt>:
15
+ row_sep = "\n"
16
+ str = CSV.generate(row_sep: row_sep) do |csv|
17
+ csv << [:foo, 0]
18
+ csv << [:bar, 1]
19
+ csv << [:baz, 2]
20
+ end
21
+ str # => "foo,0\nbar,1\nbaz,2\n"
22
+ ary = CSV.parse(str)
23
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
24
+
25
+ Using <tt>|</tt> (pipe):
26
+ row_sep = '|'
27
+ str = CSV.generate(row_sep: row_sep) do |csv|
28
+ csv << [:foo, 0]
29
+ csv << [:bar, 1]
30
+ csv << [:baz, 2]
31
+ end
32
+ str # => "foo,0|bar,1|baz,2|"
33
+ ary = CSV.parse(str, row_sep: row_sep)
34
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
35
+
36
+ Using <tt>--</tt> (two hyphens):
37
+ row_sep = '--'
38
+ str = CSV.generate(row_sep: row_sep) do |csv|
39
+ csv << [:foo, 0]
40
+ csv << [:bar, 1]
41
+ csv << [:baz, 2]
42
+ end
43
+ str # => "foo,0--bar,1--baz,2--"
44
+ ary = CSV.parse(str, row_sep: row_sep)
45
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
46
+
47
+ Using <tt>''</tt> (empty string):
48
+ row_sep = ''
49
+ str = CSV.generate(row_sep: row_sep) do |csv|
50
+ csv << [:foo, 0]
51
+ csv << [:bar, 1]
52
+ csv << [:baz, 2]
53
+ end
54
+ str # => "foo,0bar,1baz,2"
55
+ ary = CSV.parse(str, row_sep: row_sep)
56
+ ary # => [["foo", "0bar", "1baz", "2"]]
57
+
58
+ ---
59
+
60
+ When +row_sep+ is the \Symbol +:auto+ (the default),
61
+ generating uses <tt>"\n"</tt> as the row separator:
62
+ str = CSV.generate do |csv|
63
+ csv << [:foo, 0]
64
+ csv << [:bar, 1]
65
+ csv << [:baz, 2]
66
+ end
67
+ str # => "foo,0\nbar,1\nbaz,2\n"
68
+
69
+ Parsing, on the other hand, invokes auto-discovery of the row separator.
70
+
71
+ Auto-discovery reads ahead in the data looking for the next <tt>\r\n</tt>, +\n+, or +\r+ sequence.
72
+ The sequence will be selected even if it occurs in a quoted field,
73
+ assuming that you would have the same line endings there.
74
+
75
+ Example:
76
+ str = CSV.generate do |csv|
77
+ csv << [:foo, 0]
78
+ csv << [:bar, 1]
79
+ csv << [:baz, 2]
80
+ end
81
+ str # => "foo,0\nbar,1\nbaz,2\n"
82
+ ary = CSV.parse(str)
83
+ ary # => [["foo", "0"], ["bar", "1"], ["baz", "2"]]
84
+
85
+ The default <tt>$INPUT_RECORD_SEPARATOR</tt> (<tt>$/</tt>) is used
86
+ if any of the following is true:
87
+ * None of those sequences is found.
88
+ * Data is +ARGF+, +STDIN+, +STDOUT+, or +STDERR+.
89
+ * The stream is only available for output.
90
+
91
+ Obviously, discovery takes a little time. Set manually if speed is important. Also note that IO objects should be opened in binary mode on Windows if this feature will be used as the line-ending translation can cause problems with resetting the document position to where it was before the read ahead.
@@ -0,0 +1,17 @@
1
+ ====== Option +force_quotes+
2
+
3
+ Specifies the boolean that determines whether each output field is to be double-quoted.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:force_quotes) # => false
7
+
8
+ For examples in this section:
9
+ ary = ['foo', 0, nil]
10
+
11
+ Using the default, +false+:
12
+ str = CSV.generate_line(ary)
13
+ str # => "foo,0,\n"
14
+
15
+ Using +true+:
16
+ str = CSV.generate_line(ary, force_quotes: true)
17
+ str # => "\"foo\",\"0\",\"\"\n"
@@ -0,0 +1,12 @@
1
+ ====== Option +quote_empty+
2
+
3
+ Specifies the boolean that determines whether an empty value is to be double-quoted.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:quote_empty) # => true
7
+
8
+ With the default +true+:
9
+ CSV.generate_line(['"', ""]) # => "\"\"\"\",\"\"\n"
10
+
11
+ With +false+:
12
+ CSV.generate_line(['"', ""], quote_empty: false) # => "\"\"\"\",\n"
@@ -0,0 +1,25 @@
1
+ ====== Option +write_converters+
2
+
3
+ Specifies converters to be used in generating fields.
4
+ See {Write Converters}[#class-CSV-label-Write+Converters]
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_converters) # => nil
8
+
9
+ With no write converter:
10
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "])
11
+ str # => "\"\na\n\",\tb\t, c \n"
12
+
13
+ With a write converter:
14
+ strip_converter = proc {|field| field.strip }
15
+ str = CSV.generate_line(["\na\n", "\tb\t", " c "], write_converters: strip_converter)
16
+ str # => "a,b,c\n"
17
+
18
+ With two write converters (called in order):
19
+ upcase_converter = proc {|field| field.upcase }
20
+ downcase_converter = proc {|field| field.downcase }
21
+ write_converters = [upcase_converter, downcase_converter]
22
+ str = CSV.generate_line(['a', 'b', 'c'], write_converters: write_converters)
23
+ str # => "a,b,c\n"
24
+
25
+ See also {Write Converters}[#class-CSV-label-Write+Converters]
@@ -0,0 +1,15 @@
1
+ ====== Option +write_empty_value+
2
+
3
+ Specifies the object that is to be substituted for each field
4
+ that has an empty \String.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_empty_value) # => ""
8
+
9
+ Without the option:
10
+ str = CSV.generate_line(['a', '', 'c', ''])
11
+ str # => "a,\"\",c,\"\"\n"
12
+
13
+ With the option:
14
+ str = CSV.generate_line(['a', '', 'c', ''], write_empty_value: "x")
15
+ str # => "a,x,c,x\n"
@@ -0,0 +1,29 @@
1
+ ====== Option +write_headers+
2
+
3
+ Specifies the boolean that determines whether a header row is included in the output;
4
+ ignored if there are no headers.
5
+
6
+ Default value:
7
+ CSV::DEFAULT_OPTIONS.fetch(:write_headers) # => nil
8
+
9
+ Without +write_headers+:
10
+ file_path = 't.csv'
11
+ CSV.open(file_path,'w',
12
+ :headers => ['Name','Value']
13
+ ) do |csv|
14
+ csv << ['foo', '0']
15
+ end
16
+ CSV.open(file_path) do |csv|
17
+ csv.shift
18
+ end # => ["foo", "0"]
19
+
20
+ With +write_headers+":
21
+ CSV.open(file_path,'w',
22
+ :write_headers=> true,
23
+ :headers => ['Name','Value']
24
+ ) do |csv|
25
+ csv << ['foo', '0']
26
+ end
27
+ CSV.open(file_path) do |csv|
28
+ csv.shift
29
+ end # => ["Name", "Value"]
@@ -0,0 +1,14 @@
1
+ ====== Option +write_nil_value+
2
+
3
+ Specifies the object that is to be substituted for each +nil+-valued field.
4
+
5
+ Default value:
6
+ CSV::DEFAULT_OPTIONS.fetch(:write_nil_value) # => nil
7
+
8
+ Without the option:
9
+ str = CSV.generate_line(['a', nil, 'c', nil])
10
+ str # => "a,,c,\n"
11
+
12
+ With the option:
13
+ str = CSV.generate_line(['a', nil, 'c', nil], write_nil_value: "x")
14
+ str # => "a,x,c,x\n"