2 changed files with 289 additions and 0 deletions
@ -0,0 +1,283 @@ |
|||||||
|
/* |
||||||
|
jQuery Parse plugin |
||||||
|
v0.5.0 |
||||||
|
https://github.com/mholt/jquery.parse
|
||||||
|
*/ |
||||||
|
|
||||||
|
(function($) |
||||||
|
{ |
||||||
|
var defaults = { |
||||||
|
delimiter: ",", |
||||||
|
header: true |
||||||
|
}; |
||||||
|
|
||||||
|
$.parse = function(input, options) |
||||||
|
{ |
||||||
|
options = verifyOptions(options); |
||||||
|
var parser = new Parser(input, options); |
||||||
|
return { |
||||||
|
results: parser.parse(), |
||||||
|
errors: parser.getErrors() |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
function verifyOptions(opt) |
||||||
|
{ |
||||||
|
opt.delimeter = opt.delimiter || defaults.delimiter; |
||||||
|
opt.header = typeof opt.header === 'undefined' ? defaults.header : opt.header; |
||||||
|
|
||||||
|
if (opt.delimiter.length > 1) |
||||||
|
opt.delimiter = opt.delimiter[0]; |
||||||
|
|
||||||
|
return opt; |
||||||
|
} |
||||||
|
|
||||||
|
function Parser(input, config) |
||||||
|
{ |
||||||
|
var self = this; |
||||||
|
var _input = input; |
||||||
|
var _config = config; |
||||||
|
var _errors = []; |
||||||
|
var _state = emptyState(); |
||||||
|
|
||||||
|
this.parse = function(arg) |
||||||
|
{ |
||||||
|
if (typeof arg === 'object') |
||||||
|
self.setConfig(arg) |
||||||
|
else if (typeof arg === 'string') |
||||||
|
self.setInput(arg); |
||||||
|
|
||||||
|
_errors = []; |
||||||
|
_state = emptyState(); |
||||||
|
|
||||||
|
for (_state.i = 0; _state.i < _input.length; _state.i++) |
||||||
|
{ |
||||||
|
_state.ch = _input[_state.i]; |
||||||
|
|
||||||
|
if (_state.ch == '"') |
||||||
|
handleQuote(); |
||||||
|
else if (_state.inQuotes) |
||||||
|
inQuotes(); |
||||||
|
else |
||||||
|
notInQuotes(); |
||||||
|
} |
||||||
|
|
||||||
|
// Treat the last line and its last field
|
||||||
|
saveField(); |
||||||
|
trimEmptyLastLine(); |
||||||
|
inspectFieldCount(); |
||||||
|
|
||||||
|
if (_state.inQuotes) |
||||||
|
addError("Unescaped or mismatched quotes"); |
||||||
|
|
||||||
|
return self.getParsed(); |
||||||
|
}; |
||||||
|
|
||||||
|
this.getDelimiter = function() |
||||||
|
{ |
||||||
|
return config.delimiter; |
||||||
|
}; |
||||||
|
|
||||||
|
this.setDelimiter = function(delim) |
||||||
|
{ |
||||||
|
delim = delim || ","; |
||||||
|
_config.delimiter = delim[0]; |
||||||
|
}; |
||||||
|
|
||||||
|
this.setConfig = function(opt) |
||||||
|
{ |
||||||
|
if ((typeof opt.header !== 'undefined' |
||||||
|
&& opt.header != config.header) |
||||||
|
|| (typeof opt.delimiter !== 'undefined' |
||||||
|
&& opt.delimiter != config.delimiter)) |
||||||
|
{ |
||||||
|
_state.parsed = emptyParsed(opt.header); |
||||||
|
} |
||||||
|
|
||||||
|
_config = opt; |
||||||
|
} |
||||||
|
|
||||||
|
this.getInput = function() |
||||||
|
{ |
||||||
|
return _input; |
||||||
|
} |
||||||
|
|
||||||
|
this.setInput = function(input) |
||||||
|
{ |
||||||
|
_input = input; |
||||||
|
} |
||||||
|
|
||||||
|
this.getParsed = function() |
||||||
|
{ |
||||||
|
return _state.parsed; |
||||||
|
} |
||||||
|
|
||||||
|
this.getErrors = function() |
||||||
|
{ |
||||||
|
return _errors; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
function emptyParsed(header) |
||||||
|
{ |
||||||
|
return header ? { fields: [], rows: [] } : [ [] ]; |
||||||
|
} |
||||||
|
|
||||||
|
function emptyState() |
||||||
|
{ |
||||||
|
return { |
||||||
|
i: 0, |
||||||
|
line: 1, |
||||||
|
field: 0, |
||||||
|
fieldVal: "", |
||||||
|
ch: "", |
||||||
|
inQuotes: false, |
||||||
|
parsed: emptyParsed(config.header) |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
function handleQuote() |
||||||
|
{ |
||||||
|
if (_state.i < _input.length - 1) |
||||||
|
{ |
||||||
|
if (_input[_state.i+1] == '"' && _state.inQuotes) |
||||||
|
{ |
||||||
|
_state.fieldVal += '"' |
||||||
|
_state.i++; |
||||||
|
} |
||||||
|
else if (_input[_state.i+1] != _config.delimiter && _state.inQuotes) |
||||||
|
return addError("Unescaped quote in field value"); |
||||||
|
} |
||||||
|
|
||||||
|
_state.inQuotes = !_state.inQuotes; |
||||||
|
} |
||||||
|
|
||||||
|
function inQuotes() |
||||||
|
{ |
||||||
|
appendCharToField(); |
||||||
|
} |
||||||
|
|
||||||
|
function appendCharToField() |
||||||
|
{ |
||||||
|
_state.fieldVal += _state.ch; |
||||||
|
} |
||||||
|
|
||||||
|
function notInQuotes() |
||||||
|
{ |
||||||
|
if (_state.ch == _config.delimiter) |
||||||
|
{ |
||||||
|
saveField(); |
||||||
|
} |
||||||
|
else if (_state.ch == "\n") |
||||||
|
{ |
||||||
|
saveField(); |
||||||
|
newRow(); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
appendCharToField(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function saveField() |
||||||
|
{ |
||||||
|
if (_config.header) |
||||||
|
{ |
||||||
|
if (_state.line == 1) |
||||||
|
{ |
||||||
|
_state.parsed.fields.push(_state.fieldVal) |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
var currentRow = _state.parsed.rows[_state.parsed.rows.length - 1]; |
||||||
|
var fieldName = _state.parsed.fields[_state.field]; |
||||||
|
if (fieldName) |
||||||
|
currentRow[fieldName] = _state.fieldVal; |
||||||
|
else |
||||||
|
addError("Too many fields; expected " + _state.parsed.fields.length + " fields, found extra value: '" + _state.fieldVal + "'"); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
_state.parsed[_state.parsed.length - 1].push(_state.fieldVal); |
||||||
|
|
||||||
|
_state.fieldVal = ""; |
||||||
|
_state.field ++; |
||||||
|
} |
||||||
|
|
||||||
|
function newRow() |
||||||
|
{ |
||||||
|
trimEmptyLastLine(); |
||||||
|
|
||||||
|
if (_config.header) |
||||||
|
{ |
||||||
|
inspectFieldCount(); |
||||||
|
if (_state.line > 0) |
||||||
|
_state.parsed.rows.push({}); |
||||||
|
} |
||||||
|
else |
||||||
|
_state.parsed.push([]); |
||||||
|
|
||||||
|
_state.line ++; |
||||||
|
_state.field = 0; |
||||||
|
} |
||||||
|
|
||||||
|
function trimEmptyLastLine() |
||||||
|
{ |
||||||
|
if (_config.header) |
||||||
|
{ |
||||||
|
if (_state.line == 1) |
||||||
|
{ |
||||||
|
if (_state.parsed.fields.length == 1 |
||||||
|
&& _state.parsed.fields[0].length == 0) |
||||||
|
{ |
||||||
|
_state.parsed.fields = []; |
||||||
|
_state.line --; |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
var lastRow = _state.parsed.rows[_state.parsed.rows.length - 1]; |
||||||
|
if (!lastRow[_state.parsed.fields[0]]) |
||||||
|
_state.parsed.rows.splice(_state.parsed.rows.length - 1, 1); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
var lastRow = _state.parsed[_state.parsed.length - 1]; |
||||||
|
if (lastRow.length == 0 || (lastRow[0].length == 0)) |
||||||
|
_state.parsed.splice(_state.parsed.length - 1, 1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function inspectFieldCount() |
||||||
|
{ |
||||||
|
if (!_config.header) |
||||||
|
return true; |
||||||
|
|
||||||
|
if (_state.parsed.rows.length == 0) |
||||||
|
return true; |
||||||
|
|
||||||
|
var expected = _state.parsed.fields.length; |
||||||
|
var actual = Object.keys(_state.parsed.rows[_state.parsed.rows.length - 1]).length; |
||||||
|
|
||||||
|
if (expected != actual) |
||||||
|
return addError("Too few fields; expected " + expected + " fields, parsed " + actual); |
||||||
|
|
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
function addError(msg) |
||||||
|
{ |
||||||
|
_errors.push({ |
||||||
|
message: msg, |
||||||
|
line: _state.line, |
||||||
|
row: _config.header ? _state.parsed.rows.length - 1 : _state.parsed.length - 1, |
||||||
|
index: _state.i |
||||||
|
}); |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
})(jQuery); |
@ -0,0 +1,6 @@ |
|||||||
|
/* |
||||||
|
jQuery Parse plugin |
||||||
|
v0.5.0 |
||||||
|
https://github.com/mholt/jquery.parse
|
||||||
|
*/ |
||||||
|
;(function(e){function n(e){e.delimeter=e.delimiter||t.delimiter;e.header=typeof e.header==="undefined"?t.header:e.header;if(e.delimiter.length>1)e.delimiter=e.delimiter[0];return e}function r(e,t){function u(e){return e?{fields:[],rows:[]}:[[]]}function a(){return{i:0,line:1,field:0,fieldVal:"",ch:"",inQuotes:false,parsed:u(t.header)}}function f(){if(o.i<r.length-1){if(r[o.i+1]=='"'&&o.inQuotes){o.fieldVal+='"';o.i++}else if(r[o.i+1]!=i.delimiter&&o.inQuotes)return g("Unescaped quote in field value")}o.inQuotes=!o.inQuotes}function l(){c()}function c(){o.fieldVal+=o.ch}function h(){if(o.ch==i.delimiter){p()}else if(o.ch=="\n"){p();d()}else{c()}}function p(){if(i.header){if(o.line==1){o.parsed.fields.push(o.fieldVal)}else{var e=o.parsed.rows[o.parsed.rows.length-1];var t=o.parsed.fields[o.field];if(t)e[t]=o.fieldVal;else g("Too many fields; expected "+o.parsed.fields.length+" fields, found extra value: '"+o.fieldVal+"'")}}else o.parsed[o.parsed.length-1].push(o.fieldVal);o.fieldVal="";o.field++}function d(){v();if(i.header){m();if(o.line>0)o.parsed.rows.push({})}else o.parsed.push([]);o.line++;o.field=0}function v(){if(i.header){if(o.line==1){if(o.parsed.fields.length==1&&o.parsed.fields[0].length==0){o.parsed.fields=[];o.line--}}else{var e=o.parsed.rows[o.parsed.rows.length-1];if(!e[o.parsed.fields[0]])o.parsed.rows.splice(o.parsed.rows.length-1,1)}}else{var e=o.parsed[o.parsed.length-1];if(e.length==0||e[0].length==0)o.parsed.splice(o.parsed.length-1,1)}}function m(){if(!i.header)return true;if(o.parsed.rows.length==0)return true;var e=o.parsed.fields.length;var t=Object.keys(o.parsed.rows[o.parsed.rows.length-1]).length;if(e!=t)return g("Too few fields; expected "+e+" fields, parsed "+t);return true}function g(e){s.push({message:e,line:o.line,row:i.header?o.parsed.rows.length-1:o.parsed.length-1,index:o.i});return false}var n=this;var r=e;var i=t;var s=[];var o=a();this.parse=function(e){if(typeof e==="object")n.setConfig(e);else if(typeof e==="string")n.setInput(e);s=[];o=a();for(o.i=0;o.i<r.length;o.i++){o.ch=r[o.i];if(o.ch=='"')f();else if(o.inQuotes)l();else h()}p();v();m();if(o.inQuotes)g("Unescaped or mismatched quotes");return n.getParsed()};this.getDelimiter=function(){return t.delimiter};this.setDelimiter=function(e){e=e||",";i.delimiter=e[0]};this.setConfig=function(e){if(typeof e.header!=="undefined"&&e.header!=t.header||typeof e.delimiter!=="undefined"&&e.delimiter!=t.delimiter){o.parsed=u(e.header)}i=e};this.getInput=function(){return r};this.setInput=function(e){r=e};this.getParsed=function(){return o.parsed};this.getErrors=function(){return s}}var t={delimiter:",",header:true};e.parse=function(e,t){t=n(t);var i=new r(e,t);return{results:i.parse(),errors:i.getErrors()}}})(jQuery) |
Loading…
Reference in new issue