From 20a9131270c3bbb2216fedc6d5e4467b75cf560b Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Thu, 22 Oct 2020 20:51:44 -0500 Subject: [ruby/csv] RDoc recipes for RFC-compliant generation (#187) https://github.com/ruby/csv/commit/5adeaff91f --- doc/csv/recipes/generating.rdoc | 95 +++++++++++++++++++++++++++++++++++++++++ doc/csv/recipes/parsing.rdoc | 20 ++++----- 2 files changed, 105 insertions(+), 10 deletions(-) (limited to 'doc') diff --git a/doc/csv/recipes/generating.rdoc b/doc/csv/recipes/generating.rdoc index f0458a3684..3ef6df99b4 100644 --- a/doc/csv/recipes/generating.rdoc +++ b/doc/csv/recipes/generating.rdoc @@ -20,6 +20,16 @@ All code snippets on this page assume that the following has been executed: - {Converting Fields}[#label-Converting+Fields] - {Recipe: Filter Generated Field Strings}[#label-Recipe-3A+Filter+Generated+Field+Strings] - {Recipe: Specify Multiple Write Converters}[#label-Recipe-3A+Specify+Multiple+Write+Converters] +- {RFC 4180 Compliance}[#label-RFC+4180+Compliance] + - {Row Separator}[#label-Row+Separator] + - {Recipe: Generate Compliant Row Separator}[#label-Recipe-3A+Generate+Compliant+Row+Separator] + - {Recipe: Generate Non-Compliant Row Separator}[#label-Recipe-3A+Generate+Non-Compliant+Row+Separator] + - {Column Separator}[#label-Column+Separator] + - {Recipe: Generate Compliant Column Separator}[#label-Recipe-3A+Generate+Compliant+Column+Separator] + - {Recipe: Generate Non-Compliant Column Separator}[#label-Recipe-3A+Generate+Non-Compliant+Column+Separator] + - {Quote Character}[#label-Quote+Character] + - {Recipe: Generate Compliant Quote Character}[#label-Recipe-3A+Generate+Compliant+Quote+Character] + - {Recipe: Generate Non-Compliant Quote Character}[#label-Recipe-3A+Generate+Non-Compliant+Quote+Character] === Output Formats @@ -147,3 +157,88 @@ This example defines and uses two custom write converters to strip and upcase ge csv << [' baz ', 2] end output_string # => "FOO,0\nBAR,1\nBAZ,2\n" + +=== RFC 4180 Compliance + +By default, \CSV generates data that is compliant with +{RFC 4180}[https://tools.ietf.org/html/rfc4180] +with respect to: +- Column separator. +- Quote character. + +==== Row Separator + +RFC 4180 specifies the row separator CRLF (Ruby "\r\n"). + +===== Recipe: Generate Compliant Row Separator + +For strict compliance, use option +:row_sep+ to specify row separator "\r\n": + output_string = CSV.generate('', row_sep: "\r\n") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0\r\nBar,1\r\nBaz,2\r\n" + +===== Recipe: Generate Non-Compliant Row Separator + +For data with non-compliant row separators, use option +:row_sep+ with a different value: +This example source uses semicolon (";') as its row separator: + output_string = CSV.generate('', row_sep: ";") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0;Bar,1;Baz,2;" + +==== Column Separator + +RFC 4180 specifies column separator COMMA (Ruby ","). + +===== Recipe: Generate Compliant Column Separator + +Because the \CSV default comma separator is ",", +you need not specify option +:col_sep+ for compliant data: + output_string = CSV.generate('') do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo,0\nBar,1\nBaz,2\n" + +===== Recipe: Generate Non-Compliant Column Separator + +For data with non-compliant column separators, use option +:col_sep+. +This example source uses TAB ("\t") as its column separator: + output_string = CSV.generate('', col_sep: "\t") do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "Foo\t0\nBar\t1\nBaz\t2\n" + +==== Quote Character + +RFC 4180 specifies quote character DQUOTE (Ruby "\""). + +===== Recipe: Generate Compliant Quote Character + +Because the \CSV default quote character is "\"", +you need not specify option +:quote_char+ for compliant data: + output_string = CSV.generate('', force_quotes: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "\"Foo\",\"0\"\n\"Bar\",\"1\"\n\"Baz\",\"2\"\n" + +===== Recipe: Generate Non-Compliant Quote Character + +For data with non-compliant quote characters, use option +:quote_char+. +This example source uses SQUOTE ("'") as its quote character: + output_string = CSV.generate('', quote_char: "'", force_quotes: true) do |csv| + csv << ['Foo', 0] + csv << ['Bar', 1] + csv << ['Baz', 2] + end + output_string # => "'Foo','0'\n'Bar','1'\n'Baz','2'\n" diff --git a/doc/csv/recipes/parsing.rdoc b/doc/csv/recipes/parsing.rdoc index cdb58e4612..9640c5522f 100644 --- a/doc/csv/recipes/parsing.rdoc +++ b/doc/csv/recipes/parsing.rdoc @@ -197,14 +197,14 @@ with respect to: ==== Row Separator -RFC 4180 specifies the row separator CRLF (Ruby "\r\n"). +RFC 4180 specifies the row separator CRLF (Ruby "\r\n"). -Although the \CSV default row separator is "\n", -the parser also by default handles row seperator "\r" and the RFC-compliant "\r\n". +Although the \CSV default row separator is "\n", +the parser also by default handles row separator "\r" and the RFC-compliant "\r\n". ===== Recipe: Handle Compliant Row Separator -For strict compliance, use option +:row_sep+ to specify row separator "\r\n", +For strict compliance, use option +:row_sep+ to specify row separator "\r\n", which allows the compliant row separator: source = "foo,1\r\nbar,1\r\nbaz,2\r\n" CSV.parse(source, row_sep: "\r\n") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] @@ -219,13 +219,13 @@ But rejects other row separators: ===== Recipe: Handle Non-Compliant Row Separator For data with non-compliant row separators, use option +:row_sep+. -This example source uses semicolon (';') as its row separator: +This example source uses semicolon (";") as its row separator: source = "foo,1;bar,1;baz,2;" CSV.parse(source, row_sep: ';') # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] ==== Column Separator -RFC 4180 specifies column separator COMMA (Ruby ','). +RFC 4180 specifies column separator COMMA (Ruby ","). ===== Recipe: Handle Compliant Column Separator @@ -237,17 +237,17 @@ you need not specify option +:col_sep+ for compliant data: ===== Recipe: Handle Non-Compliant Column Separator For data with non-compliant column separators, use option +:col_sep+. -This example source uses TAB ("\t") as its column separator: +This example source uses TAB ("\t") as its column separator: source = "foo,1\tbar,1\tbaz,2" CSV.parse(source, col_sep: "\t") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] ==== Quote Character -RFC 4180 specifies quote character DQUOTE (Ruby '"'). +RFC 4180 specifies quote character DQUOTE (Ruby "\""). ===== Recipe: Handle Compliant Quote Character -Because the \CSV default quote character is '"', +Because the \CSV default quote character is "\"", you need not specify option +:quote_char+ for compliant data: source = "\"foo\",\"1\"\n\"bar\",\"1\"\n\"baz\",\"2\"\n" CSV.parse(source) # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] @@ -255,7 +255,7 @@ you need not specify option +:quote_char+ for compliant data: ===== Recipe: Handle Non-Compliant Quote Character For data with non-compliant quote characters, use option +:quote_char+. -This example source uses SQUOTE ("'") as its quote character: +This example source uses SQUOTE ("'") as its quote character: source = "'foo','1'\n'bar','1'\n'baz','2'\n" CSV.parse(source, quote_char: "'") # => [["foo", "1"], ["bar", "1"], ["baz", "2"]] -- cgit v1.2.3