ical.lua

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