vcal
Version:
An vCal ics parser designed to specifically handle Google's ICS private export feed, but could handle more too.
99 lines (81 loc) • 2.34 kB
JavaScript
exports.build_ics_string = function(ics_object) {
var ics_data = "";
for(var key in ics_object) {
if(ics_object.hasOwnProperty(key)) {
var node = ics_object[key];
if(node.constructor == [].constructor) {
node.forEach(function(item) {
ics_data += "BEGIN:" + key + "\r\n";
ics_data += exports.build_ics_string(item);
ics_data += "END:" + key + "\r\n";
});
} else {
node = node.replace(/\n/g, "\\n").replace(/,/g, "\\,");
if(key.length + node.length + 1 > 75) {
var string = node;
var output = [];
var line = key + ":";
output.push(line + string.substr(0, 75 - line.length));
string = string.substr(75 - line.length);
while(string.length) {
output.push(" " + string.substr(0, 75));
string = string.substr(75);
}
ics_data += output.join("\r\n") + "\r\n";
} else {
ics_data += key + ":" + node + "\r\n";
}
}
}
}
return ics_data;
}
exports.parse_ics_string = function(ics_string) {
var lines = ics_string.replace(/\r/g, '').split('\n');
var current_line = "";
var tree = {};
var stack = [];
for(var i = 0; i < lines.length; i++) {
current_line = lines[i];
while(i+1 < lines.length && /\s/.test(lines[i+1][0])) {
current_line += lines[i+1].substr(1);
i++;
}
var pieces = current_line.split(":");
var key = pieces[0];
var value = pieces.slice(1, pieces.length).join(":").replace(/\\n/g, "\n").replace(/\\,/g, ",");
if(!key) {
continue;
}
// Start our state machine
if(key == "BEGIN") {
// If we encounter a BEGIN:<SECTION>, create a new leaf,
// append it to the tree, push the existing tree on the stack
// then set out leaf to be the root of the tree
if(!tree[value]) {
tree[value] = [];
}
var leaf = {};
if(tree[value] && tree[value].constructor == [].constructor) {
tree[value].push(leaf);
} else {
if(tree[value]) {
tree[value] = [tree[value]];
tree[value].push(leaf);
} else {
tree[value] = leaf;
}
}
stack.push(tree);
tree = leaf;
} else if(key == "END") {
// If we encounter a END:<SECTION>, pop the old root
// from the stack and set it to be our root of the tree
tree = stack.pop();
} else {
// Just set the key/value
tree[key] = value;
}
}
return tree;
}