So, I worked on an interesting problem today - parsing iCal feeds. My desire to parse iCal feeds stems from the fact that I want to translate an iCal feed to an RSS feed. This would let me turn a calendar into an RSS feed that can be added to my.yahoo.com for example. (Obviously you would only publish events in the future.)
So, working on this I ran into an interesting issue. I needed to parse a string that looked a bit like this:
foo=goo:zoo
Everything after the colon was data. Everything before the data is considered params. There are two ways we can make this crazy. First off - the params side can have colons too - if they are in quotes, and not just ":", but...
foo="http://www.cnn.com":CNN
Let's make things interesting again - you can have multiple params if you separate them by commas - but again, commas can be inside quotes:
kidnames="jacon,lynn,noah",foo="http://www.cn.com":CNN
Now - as we all know - ColdFusion has some nifty string parsing functions. The list functions are especially useful for cutting up strings, but in this case, are useless. What I ended up doing then was writing a UDF called: findNotInQuotes. Here it is:
var inQuotes = false;
var x = 1;
var c = "";
if(arraylen(arguments) gte 3) x = arguments[3];
for(; x lte len(data); x=x+1) {
c = mid(data,x,1);
if(c is """") {
if(inQuotes) inQuotes=false;
else inQuotes = true;
}
if(c is target and not inQuotes) return x;
}
return 0;
}
This worked for me, and I was able to write a conditional loop. However - I think it could be done better. My first thought was - why not rewrite all the list functions so they will ignore delimiters in quotes. This seems a bit crazy. Instead - why not simply write a function that will "split" a string into an array, using your delimiters (and why not allow for delimiters of multi-chars, something CF doesn't let you do). Then you can simply loop over the array.
Any thoughts on this?
For those interested in the iCal code - I've got it working, but I want to convert it to a nice CFC first. There are a set of helper functions also included with it so you can parse their time formats. I'm also going to add a function so you can pass in an iCal start date and an iCal duration value and get an end date.