[REBOL] [Nifty Object of the Week] CSV
From: AJMartin::orcon::net::nz at: 15-Aug-2003 21:56
An object that contains:
Load-CSV
and:
Mold-CSV
which 'load-s and 'mold-s %.CSV files to/from Rebol values.
CSV: make object! [
Data: complement charset {",^/}
To-Rebol-Value: func [Value [string!]] [
parse/all Value [
[Integer^ end (Value: to integer! Value)]
| [Decimal^ end (Value: to decimal! Value)]
| [Pair^ end (Value: to pair! Value)]
| [Money^ end (Value: to money! Value)]
| [Tuple^ end (Value: to tuple! Value)]
| [Tag^ end (Value: to tag! Value)]
| [#"#" to end end (Value: to issue! next Value)]
| [skip end (Value: to char! Value)]
| [end (Value: none)]
| [Time^ end (Value: to time! Value)]
| [Date^ end (Value: to date! Value)]
| [URL^ end (Value: to url! Value)]
| [Email^ end (Value: to email! Value)]
]
Value
]
set 'Load-CSV Load: function [CSV [file! string!]] [Table Row Value
Value^] [
if file? CSV [
CSV: read CSV
]
if newline <> last CSV [
insert tail CSV newline
]
Table: copy []
Row: copy []
Value: none
Value^: [
{"} copy Value any [Data | #"," | newline | {""} | [{"} Data] |
[{", } Data]] {"} (
if string? Value [
trim/lines Value
replace/all Value {""} {"}
Value: To-Rebol-Value Value
]
insert tail Row Value
)
| copy Value any Data (
if string? Value [
trim Value
Value: To-Rebol-Value Value
]
insert tail Row Value
)
]
all [
parse/all CSV [
any [
Value^ any [#"," Value^] newline (
all [
equal? reduce [none] unique Row
Row: copy []
]
insert/only tail Table Row
Row: copy []
)
]
end
]
Table
]
]
Quote: func [String [string!]] [
if found? find String #"," [
String: Rebol/words/mold String
if all [
#"{" = first String
#"}" = last String
] [
String/1: #"^""
change at String length? String #"^""
]
]
String
]
set 'Mold-CSV Mold: function [
"Molds an array of values into a CSV formatted string."
Array [block!] "The array of values."
] [Page Line Column^ Type Heading] [
Page: make block! length? Array
Line: make string! 1000
Column^: [
into [
(Type: none)
some [
'date! (Type: "Date")
| 'logic! (Type: "Boolean")
| 'integer! (Type: "Int")
| ['decimal! | 'money!] (Type: "Float")
| 'string! (Type: "String")
| word! (any [Type Type: "String"])
]
]
]
if parse Array/1 [
some [
[
[set Heading word! Column^ opt [set Heading string!]]
| [set Heading string! Column^]
] (
Heading: Quote any [
all [
word? Heading
replace/all form Heading #"_" #" "
]
Heading
]
insert tail Line reduce [
Heading #":" Type #","
]
)
]
end
] [
Array: next Array
remove back tail Line
insert tail Line newline
insert tail Page copy Line
clear Line
]
foreach Row Array [
foreach Item Row [
insert tail Line switch/default type?/word :Item [
string! [
Quote Item
]
none! [
#" " ; A blank/space works better as a "none"
value.
]
issue! [
Rebol/words/mold Item
]
] [
Item
]
insert tail Line #","
]
remove back tail Line
insert tail Line newline
insert tail Page copy Line
clear Line
]
rejoin Page
]
]
Andrew J Martin
ICQ: 26227169
http://www.rebol.it/Valley/
http://valley.orcon.net.nz/
http://Valley.150m.com/