|
1 module("ical", package.seeall) |
|
2 |
|
3 local handler = {}; |
|
4 |
|
5 function handler.VEVENT(ical, line) |
|
6 local k,v = line:match("^(%w+):(.*)$"); |
|
7 local curr_event = ical[#ical]; |
|
8 if k and v then |
|
9 curr_event[k] = v; |
|
10 end |
|
11 |
|
12 if k == "DTSTAMP" then |
|
13 local t = {}; |
|
14 t.year, t.month, t.day, t.hour, t.min, t.sec = v:match("^(%d%d%d%d)(%d%d)(%d%d)T(%d%d)(%d%d)(%d%d)Z$"); |
|
15 for k,v in pairs(t) do t[k] = tonumber(v); end |
|
16 curr_event.when = os.time(t); |
|
17 end |
|
18 end |
|
19 |
|
20 function load(data) |
|
21 local ical, stack = {}, {}; |
|
22 local line_num = 0; |
|
23 |
|
24 -- Parse |
|
25 for line in data:gmatch("(.-)[\r\n]+") do |
|
26 line_num = line_num + 1; |
|
27 if line:match("^BEGIN:") then |
|
28 local type = line:match("^BEGIN:(%S+)"); |
|
29 table.insert(stack, type); |
|
30 table.insert(ical, { type = type }); |
|
31 elseif line:match("^END:") then |
|
32 if stack[#stack] ~= line:match("^END:(%S+)") then |
|
33 return nil, "Parsing error, expected END:"..stack[#stack].." before line "..line_num; |
|
34 end |
|
35 table.remove(stack); |
|
36 elseif handler[stack[#stack]] then |
|
37 handler[stack[#stack]](ical, line); |
|
38 end |
|
39 end |
|
40 |
|
41 -- Return calendar |
|
42 return ical; |
|
43 end |
|
44 |
|
45 |
|
46 return _M; |