csv.um
A CSV parser, which also works for similar formats. It doesn't support quotes, but you can escape characters using a backslash.
fn parse
Parses input into a 2d string array.
fn parse*(inp: str, sep: char = ','): [][]str {
fn encode
Converts 2d array to csv string.
fn encode*(inp: [][]str, sep: char = ','): str {
//~~
// A CSV parser, which also works for similar formats. It doesn't support
// quotes, but you can escape characters using a backslash.
//~~
//~~fn parse
// Parses input into a 2d string array.
fn parse*(inp: str, sep: char = ','): [][]str {
//~~
out := [][]str{}
row := []str{}
start := 0
acc := ""
l := len(inp)
skipnext := false
for i,c in inp {
if skipnext { skipnext = false; continue }
if c == '\\' {
acc += slice(inp, start, i)
start = i + 1
skipnext = true
} else if c == '\r' {
acc += slice(inp, start, i)
start = i + 1
} else if c == '\n' {
acc += slice(inp, start, i)
start = i + 1
row = append(row, acc)
out = append(out, row)
acc = ""
row = []str{}
} else if c == sep {
acc += slice(inp, start, i)
start = i + 1
row = append(row, acc)
acc = ""
}
}
if start < l {
row = append(row, acc + slice(inp, start, l))
}
if len(row) > 0 {
out = append(out, row)
}
return out
}
fn escapeStr(s: str, sep: char): str {
o := ""
for i,c in s {
if c == sep || c == '\n' || c == '\\' {
o += "\\"
}
o += str(c)
}
return o
}
//~~fn encode
// Converts 2d array to csv string.
fn encode*(inp: [][]str, sep: char = ','): str {
//~~
o := ""
for i in inp {
for j in inp[i] {
o += escapeStr(inp[i][j], sep)
if j < len(inp[i]) - 1 { o += sep }
}
o += "\n"
}
return o
}
fn main() {
testval := "val1,val2\nanother row\\,still another row,third value,fourth value\n"
res := parse(testval)
printf("%v\n", res)
printf("%s\n", encode(res))
}