Skip to content

Instantly share code, notes, and snippets.

@gerardpaapu
Last active December 23, 2015 07:59
Show Gist options
  • Save gerardpaapu/6604141 to your computer and use it in GitHub Desktop.
Save gerardpaapu/6604141 to your computer and use it in GitHub Desktop.
// A Parslet parser for parsing CSV files
//
// ported from http://hackage.haskell.org/packages/archive/csv/0.1.1/doc/html/Text-CSV.html
define(['./parslet'], function (parslet) {
'use strict';
var Parser = parslet.Parser;
function join(arr) { return arr.join(''); }
// csv :: Parser CSV
// csv = do x <- record `sepEndBy` many1 (oneOf "\n\r")
// eof
// return x
var csv = Parser.lazy(function () {
return record.separatedBy(/[\n\r]+/)
.followedBy(/[\n\r]*/)
.followedBy(Parser.EOF);
});
// record :: Parser Record
// record = (quotedField <|> field) `sepBy` char ','
var record = Parser.lazy(function () {
return quotedField.or(field).separatedBy(',');
});
// field :: Parser Field
// field = many (noneOf ",\n\r\"")
var field = Parser.noneOf(',\n\r"').zeroOrMore().map(join);
// quotedField :: Parser Field
// quotedField = between (char '"') (char '"') $
// many (noneOf "\"" <|> try (string "\"\"" >> return '"'))
var quotedField = Parser.noneOf('"').or(Parser.Exactly('""').returns('"'))
.zeroOrMore()
.between('"', '"')
.map(join);
return {
csv: csv,
parseCSV: function (source) {
var result = csv.parse(source);
if (!result.success) {
throw new Error('csv.parseCSV: Invalid CSV input');
} else {
return result.value.value;
}
},
parseCSVFromFile: function (filename, encoding, cb) {
require('fs').readFile(filename, encoding, function (err, data) {
if (err) {
cb(err);
} else {
var result = csv.parse(data);
if (!result.success) {
cb('csv.parseCSVFromFile(filename, encoding, cb): Invalid CSV file "' + filename + '"');
} else {
cb(null, result.value.value);
}
}
});
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment