Created
October 1, 2010 17:11
-
-
Save think49/606508 to your computer and use it in GitHub Desktop.
rfc4180plus.js : この gist は http://gist.github.com/606500 に統合されました
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function RFC4180Plus () { | |
var | |
CRLF = '(?:\r\n|[\r\n])', | |
escaped = '"(?:""|[^"])*"', | |
non_escaped = '[^\n\r",]*', | |
field = '(?:' + escaped + '|' + non_escaped + ')', | |
record = field + '(?:,' + field + ')*', | |
file = record + '(?:' + CRLF + record + ')*' + CRLF + '?'; | |
this.non_escaped = new RegExp('^' + non_escaped + '$'); | |
this.file = new RegExp('^' + file + '$'); | |
this.convert_strings = new RegExp([ | |
',', | |
CRLF, | |
escaped, | |
non_escaped, | |
'[\\s\\S]' | |
].join('|'), 'g'); | |
} | |
RFC4180Plus.prototype.isCSV = function (csvString) { | |
if ('string' !== typeof csvString) throw new TypeError(csvString + ' is not a string'); | |
return this.file.test(csvString); | |
}; | |
RFC4180Plus.prototype.toArray = function (csvString) { | |
if ('string' !== typeof csvString) throw new TypeError(csvString + ' is not a string'); | |
var non_escaped, callback, result, records, i, separatorAfterFlag; | |
separatorAfterFlag = true; | |
non_escaped = this.non_escaped; | |
records = [[]]; | |
i = 0; | |
callback = function (token) { | |
switch (token.charAt(0)) { | |
case '"': | |
records[i].push(token.slice(1, token.length - 1).replace(/""/g, '"')); | |
separatorAfterFlag = false; | |
break; | |
case ',': | |
if (separatorAfterFlag) records[i].push(''); | |
separatorAfterFlag = true; | |
break; | |
case '\r': | |
case '\n': | |
if (separatorAfterFlag) records[i].push(''); | |
i++; | |
records[i] = []; | |
separatorAfterFlag = true; | |
break; | |
default: | |
if (non_escaped.test(token)) { | |
if (separatorAfterFlag) { | |
records[i].push(token); | |
separatorAfterFlag = false; | |
} | |
} else { | |
throw new Error('not well-formed CSV (RFC 4180+)'); | |
} | |
break; | |
} | |
return ''; | |
}; | |
result = csvString.replace(this.convert_strings, callback); | |
callback = null; | |
if (result.length !== 0 || records.length < 1) throw new Error('not well-formed CSV (RFC 4180+)'); | |
return records; | |
}; | |
RFC4180Plus.prototype.toTable = function (csvString, doc, theadFlag) { | |
if (typeof csvString !== 'string') throw new TypeError(csvString + ' is not a string'); | |
if (typeof doc !== 'object' || typeof Node === 'function' && doc.nodeType !== Node.DOCUMENT_NODE || doc.nodeType !== 9) throw new TypeError(doc + ' is not a document'); | |
var non_escaped, callback, result, table, tbody, rows, tr, cellElement, cells, i, separatorAfterFlag; | |
separatorAfterFlag = true; | |
non_escaped = this.non_escaped; | |
table = doc.createElement('table'); | |
cellElement = theadFlag ? doc.createElement('th') : doc.createElement('td'); | |
tbody = theadFlag ? table.appendChild(doc.createElement('thead')) : table.appendChild(doc.createElement('tbody')); | |
rows = tbody.rows; | |
tr = tbody.insertRow(0); | |
cells = tr.cells; | |
i = 0; | |
callback = function (token) { | |
switch (token.charAt(0)) { | |
case '"': | |
tr.appendChild(cellElement.cloneNode(false)).appendChild(doc.createTextNode(token.slice(1, token.length - 1).replace(/""/g, '"'))); | |
separatorAfterFlag = false; | |
break; | |
case ',': | |
if (separatorAfterFlag) tr.appendChild(cellElement.cloneNode(false)); | |
separatorAfterFlag = true; | |
break; | |
case '\r': | |
case '\n': | |
if (separatorAfterFlag) tr.appendChild(cellElement.cloneNode(false)); | |
if (theadFlag) { | |
tbody = table.appendChild(doc.createElement('tbody')); | |
rows = tbody.rows; | |
cellElement = doc.createElement('td'); | |
theadFlag = false; | |
} | |
tr = tbody.insertRow(rows.length); | |
cells = tr.cells; | |
separatorAfterFlag = true; | |
break; | |
default: | |
if (non_escaped.test(token)) { | |
if (separatorAfterFlag) { | |
tr.appendChild(cellElement.cloneNode(false)).appendChild(doc.createTextNode(token)); | |
separatorAfterFlag = false; | |
} | |
} else { | |
throw new Error('not well-formed CSV (RFC 4180+)'); | |
} | |
break; | |
} | |
return ''; | |
}; | |
result = csvString.replace(this.convert_strings, callback); | |
callback = null; | |
if (result.length !== 0 || cells.length === 0) throw new Error('not well-formed CSV (RFC 4180+)'); | |
return table; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
rfc4180plus.js は rfc4180.js に統合されましたので、rfc4180.js の方を利用してください。(rfc4180plus.js はもう更新しません)
gist: 606500 (rfc4180.js) - GitHub
http://gist.github.com/606500