<div dir="ltr"><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div><div>Hi,<br><br></div> I&#39;m trying to parse ical files but the source material doesn&#39;t matter much. First, I know there is an icalendar library on hackage, but I&#39;m trying to learn as well through this.<br>
<br></div> Now the format is really quite simple and actually I&#39;m parsing it, it works, but I don&#39;t like the code I&#39;m writing, it feels wrong and I&#39;m sure there is a better way. Actually for now I&#39;m parsing it to an array of arrays, but I want to fill a proper &quot;data&quot; structure.<br>
<br></div> For my purpose the file contains a bunch of records like this:<br><br>BEGIN:VEVENT<br>DTSTART:20121218T103000Z<br>DTEND:20121218T120000Z<br>[..]<br>DESCRIPTION:<br>[..]<br>END:VEVENT<br><br></div>There are a bunch of records I don&#39;t care about and also I want to parse no matter what is the order of directives (so, i want to parse also if DTEND appears before DTSTART for instance, and so on).<br>
<br></div>That last part is my one problem. I can&#39;t do:<br><br></div>parseBegin<br></div>start &lt;- parseStart<br></div>end &lt;- parseEnd<br></div>skipRows<br></div>desc &lt;- parseDesc<br></div>skipRows<br></div>end &lt;- parseEnd<br>
return Event { eventStart = start, eventEnd = end ...}<br><br></div>my current working code is:<br><br>parseEvent = do<br>    parseBegin<br>    contents &lt;- many1 $ (try startDate)<br>            &lt;|&gt; (try endDate)<br>
            &lt;|&gt; (try description)<br>            &lt;|&gt; unknownCalendarInfo<br>    parseEnd<br>    return contents<br><br></div>But then contents of course returns an array, while I want to return only one element here.<br>
<br></div>SOMEHOW what I would like is:<br><br>parseEvent = do<br>    parseBegin<br>    contents &lt;- many1 $ (start &lt;- T.try startDate)<br>            &lt;|&gt; (end &lt;- T.try endDate)<br>            &lt;|&gt; (desc &lt;- T.try description)<br>
            &lt;|&gt; unknownCalendarInfo<br>    parseEnd<br>    return Event { eventStart = start, eventEnd = end ...}<br><br></div> But obviously as far as Parsec is concerned startDate could occur several times and also it&#39;s just not valid Haskell syntax.<br>
<br></div> So, any hint about this problem? Parsing multi-line records with Parsec, when I don&#39;t know the order in which the lines will appear? I mean sure I can convert my array to the proper data structure... I find which element in the array contains the start date and then which contains the end date... and build my data structure.. But I&#39;m sure something much nicer can be done... I just can&#39;t find how.<br>
<br></div><div> I see the author of iCalendar fixed the problem but I can&#39;t completely understand his source, it&#39;s too many things at the same time for me, I need to take this one step at a time.<br></div><div><br>
</div> Thank you!<br><br>Emmanuel<br></div>