Added write-csv word
parent
2291c2d18a
commit
cbf5fccb69
|
@ -2,20 +2,27 @@ USING: help.syntax help.markup kernel prettyprint sequences ;
|
||||||
IN: csv
|
IN: csv
|
||||||
|
|
||||||
HELP: csv
|
HELP: csv
|
||||||
{ $values { "stream" "a stream" }
|
{ $values { "stream" "an input stream" }
|
||||||
{ "rows" "an array of arrays of fields" } }
|
{ "rows" "an array of arrays of fields" } }
|
||||||
{ $description "parses a csv stream into an array of row arrays"
|
{ $description "parses a csv stream into an array of row arrays"
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
HELP: csv-row
|
HELP: csv-row
|
||||||
{ $values { "stream" "a stream" }
|
{ $values { "stream" "an input stream" }
|
||||||
{ "row" "an array of fields" } }
|
{ "row" "an array of fields" } }
|
||||||
{ $description "parses a row from a csv stream"
|
{ $description "parses a row from a csv stream"
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
HELP: write-csv
|
||||||
|
{ $values { "rows" "an sequence of sequences of strings" }
|
||||||
|
{ "stream" "an output stream" } }
|
||||||
|
{ $description "writes csv to the output stream, escaping where necessary"
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
HELP: with-delimiter
|
HELP: with-delimiter
|
||||||
{ $values { "char" "field delimiter (e.g. CHAR: \t)" }
|
{ $values { "char" "field delimiter (e.g. CHAR: \t)" }
|
||||||
{ "quot" "a quotation" } }
|
{ "quot" "a quotation" } }
|
||||||
{ $description "Sets the field delimiter for csv or csv-row words "
|
{ $description "Sets the field delimiter for csv or csv-row words "
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: io.streams.string csv tools.test shuffle ;
|
|
||||||
IN: csv.tests
|
IN: csv.tests
|
||||||
|
USING: io.streams.string csv tools.test shuffle kernel strings ;
|
||||||
|
|
||||||
! I like to name my unit tests
|
! I like to name my unit tests
|
||||||
: named-unit-test ( name output input -- )
|
: named-unit-test ( name output input -- )
|
||||||
|
@ -68,3 +68,11 @@ IN: csv.tests
|
||||||
[ { { "foo" "bar" }
|
[ { { "foo" "bar" }
|
||||||
{ "1" "2" } } ]
|
{ "1" "2" } } ]
|
||||||
[ "foo,\"bar\"\n1,2" <string-reader> csv ] named-unit-test
|
[ "foo,\"bar\"\n1,2" <string-reader> csv ] named-unit-test
|
||||||
|
|
||||||
|
"can write csv too!"
|
||||||
|
[ "foo1,bar1\nfoo2,bar2\n" ]
|
||||||
|
[ { { "foo1" "bar1" } { "foo2" "bar2" } } <string-writer> tuck write-csv >string ] named-unit-test
|
||||||
|
|
||||||
|
"escapes quotes commas and newlines when writing"
|
||||||
|
[ "\"fo\"\"o1\",bar1\n\"fo\no2\",\"b,ar2\"\n" ]
|
||||||
|
[ { { "fo\"o1" "bar1" } { "fo\no2" "b,ar2" } } <string-writer> tuck write-csv >string ] named-unit-test ! "
|
||||||
|
|
|
@ -10,7 +10,7 @@ IN: csv
|
||||||
DEFER: quoted-field
|
DEFER: quoted-field
|
||||||
|
|
||||||
VAR: delimiter
|
VAR: delimiter
|
||||||
|
|
||||||
! trims whitespace from either end of string
|
! trims whitespace from either end of string
|
||||||
: trim-whitespace ( str -- str )
|
: trim-whitespace ( str -- str )
|
||||||
[ blank? ] trim ; inline
|
[ blank? ] trim ; inline
|
||||||
|
@ -57,7 +57,7 @@ VAR: delimiter
|
||||||
[ (csv) ] when ;
|
[ (csv) ] when ;
|
||||||
|
|
||||||
: init-vars ( -- )
|
: init-vars ( -- )
|
||||||
delimiter> [ CHAR: , >delimiter ] unless ; inline
|
delimiter> [ CHAR: , >delimiter ] unless ; inline
|
||||||
|
|
||||||
: csv-row ( stream -- row )
|
: csv-row ( stream -- row )
|
||||||
init-vars
|
init-vars
|
||||||
|
@ -69,3 +69,24 @@ VAR: delimiter
|
||||||
|
|
||||||
: with-delimiter ( char quot -- )
|
: with-delimiter ( char quot -- )
|
||||||
delimiter swap with-variable ; inline
|
delimiter swap with-variable ; inline
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
: needs-escaping? ( cell -- ? )
|
||||||
|
[ "\n\"" delimiter> suffix member? ] contains? ; inline ! "
|
||||||
|
|
||||||
|
: escape-quotes ( cell -- cell' )
|
||||||
|
[ [ dup , CHAR: " = [ CHAR: " , ] when ] each ] "" make ; inline
|
||||||
|
|
||||||
|
: enclose-in-quotes ( cell -- cell' )
|
||||||
|
CHAR: " [ prefix ] [ suffix ] bi ; inline ! "
|
||||||
|
|
||||||
|
: escape-if-required ( cell -- cell' )
|
||||||
|
dup needs-escaping? [ escape-quotes enclose-in-quotes ] when ; inline
|
||||||
|
|
||||||
|
: write-row ( row -- )
|
||||||
|
[ delimiter> write1 ] [ escape-if-required write ] interleave nl ; inline
|
||||||
|
|
||||||
|
: write-csv ( rows outstream -- )
|
||||||
|
init-vars
|
||||||
|
[ [ write-row ] each ] with-output-stream ;
|
||||||
|
|
Loading…
Reference in New Issue