Created
April 10, 2018 21:03
-
-
Save bartoszbobin/533a9ef36166eb3c4ad389bfd3602204 to your computer and use it in GitHub Desktop.
Simple ICalendar Parser to JS Objects
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
/** | |
* @copyright bartosz.bobin | |
*/ | |
export class ICalendarParser { | |
skipNotStandardKeys = true; | |
parse(text: string) { | |
const lines = text.replace(/\n /g, '').split(/\n/); | |
let obj = {vcalendar: undefined}; | |
this.analyseCalendar(lines, obj); | |
return obj.vcalendar; | |
} | |
private analyseCalendar(lines, obj) { | |
const path = [obj]; | |
for (let line of lines) { | |
line = line.trim(); | |
let currentPathItem = path[path.length - 1]; | |
if (line.indexOf('BEGIN:') === 0) { | |
this.createNewPathItem(line, currentPathItem, path); | |
continue; | |
} | |
if (line.indexOf(`END:`) === 0) { | |
path.pop(); | |
continue; | |
} | |
if (line.indexOf(`X-`) === 0 && this.skipNotStandardKeys) { | |
continue; | |
} | |
this.analyseProperty(line, currentPathItem); | |
} | |
} | |
private analyseProperty(line, current) { | |
const keyValueSeparatorIndex = line.indexOf(':'); | |
let key = line.substr(0, keyValueSeparatorIndex); | |
const keyPropertySeparatorIndex = key.indexOf(';'); | |
let value = { | |
data: line.substr(keyValueSeparatorIndex + 1) | |
}; | |
if (keyPropertySeparatorIndex > -1) { | |
const properties = key.split(/;/g); | |
key = properties.shift(); | |
for (const prop of properties) { | |
const t = prop.split('='); | |
value[ICalendarParser.toCamelCase(t.shift())] = t.join('='); | |
} | |
} | |
current[ICalendarParser.toCamelCase(key)] = value; | |
} | |
private createNewPathItem(line, currentPathItem, path) { | |
const keyName = ICalendarParser.toCamelCase(line.substr(6)); | |
const item = this.keyToObjectMapper(keyName); | |
if (typeof currentPathItem[keyName] === 'object') { | |
if (!Array.isArray(currentPathItem[keyName])) { | |
currentPathItem[keyName] = [currentPathItem[keyName]]; | |
} | |
currentPathItem[keyName].push(item); | |
} else { | |
currentPathItem[keyName] = item; | |
} | |
path.push(item); | |
} | |
private keyToObjectMapper(key) { | |
switch (key.toLowerCase()) { | |
case "vcalendar": return new VCalendar(); | |
case "vevent": return new VEvent(); | |
case "vtodo": return new VTodo(); | |
case "vjournal": return new VJournal(); | |
case "vfreebusy": return new VFreeBusy(); | |
case "vtimezone": return new VTimezone(); | |
default:return {}; | |
} | |
} | |
static toCamelCase(str) { | |
return str.toLowerCase(); | |
} | |
} | |
export class VCalendar {} | |
export class VEvent {} | |
export class VTodo {} | |
export class VJournal {} | |
export class VFreeBusy {} | |
export class VTimezone {} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment