Skip to content

Instantly share code, notes, and snippets.

@PanJarda
Last active November 4, 2019 18:14
Show Gist options
  • Save PanJarda/c6e4e0879e8c421013ce8205902b5c34 to your computer and use it in GitHub Desktop.
Save PanJarda/c6e4e0879e8c421013ce8205902b5c34 to your computer and use it in GitHub Desktop.
/*
* parsecsv.js
*
* by: JP 2019
*
* example:
* res = [];
* if (err = parsecsv('1,2,3\n4,5,6', res))
* console.error(err);
* // res <-- [["1","2","3"],["4","5","6"]]
*
* License MIT
*/
var parsecsv = (function() {
var ERR_MISSING_QUOTE = 1,
parstbl = {
ROW: {
'"': ['QOT', startqot],
',': ['ROW', pushcol],
'\r': ['CR', pushrow],
default: ['COL', startcol]
},
COL: {
',': ['ROW', pushcol],
'\n': ['ROW', pushrow],
'\r': ['CR', pushrow],
default: ['COL', skipchar]
},
QOT: {
'"': ['ESC', pushesc],
default: ['QOT', skipchar]
},
ESC: {
'"': ['QOT', startqot],
'\n': ['ROW', pushrow],
'\r': ['CR', pushrow],
',': ['ROW', pushcol],
default: ['COL', startcol]
},
CR: {
'\n': ['ROW', skipchar],
'\r': ['CR', pushrow],
',': ['ROW', pushcol],
'"': ['QOT', startqot],
default: ['COL', startcol]
},
END: {
default: ['', pushrow]
}
};
function pushesc() {
this.col += this.str.slice(this.j, this.i++);
}
function pushcol() {
this.row.push(this.col || this.str.slice(this.j, this.i));
this.j = ++this.i;
this.col = '';
}
function pushrow() {
pushcol.call(this);
this.res.push(this.row);
this.row = [];
}
function skipchar() {
this.i++;
}
function startcol() {
this.j = this.i++;
}
function startqot() {
this.j = ++this.i;
this.i = this.str.indexOf('"', this.i);
if (this.i < 0) {
this.err = ERR_MISSING_QUOTE;
this.i = this.str.length;
}
}
return function main(str, res) {
var action,
c,
o = {
col: '',
err: 0,
i: 0,
j: 0,
str: str,
res: res,
row: []
},
state = "ROW",
tmp;
while(c = str.charAt(o.i)) {
tmp = parstbl[state][c] || parstbl[state].default;
state = tmp[0];
action = tmp[1];
action.call(o);
}
parstbl.END.default[1].call(o);
return o.err;
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment