summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Gesang <phg@phi-gamma.net>2018-06-23 14:53:06 +0200
committerPhilipp Gesang <phg@phi-gamma.net>2018-06-26 13:57:25 +0200
commit2ab4257bf85adcc055e783df5735601cec9cbfff (patch)
treed17a182475700e2ef2f67128cfdb95089148e4f4
parent0b9144c3ca46c1138f37db3de4b1698818178085 (diff)
downloadcaldr-2ab4257bf85adcc055e783df5735601cec9cbfff.tar.gz
cal: handle folding
-rwxr-xr-xcal.lua52
1 files changed, 46 insertions, 6 deletions
diff --git a/cal.lua b/cal.lua
index 7fcbbed..6dd2c6b 100755
--- a/cal.lua
+++ b/cal.lua
@@ -1,4 +1,9 @@
#!/usr/bin/env lua
+--[[--
+
+ RFC2445 parser.
+
+--]]--
local io = require "io"
local ioopen = io.open
@@ -11,16 +16,37 @@ local println = function (...) print (stringformat (...)) end
local parse_calendar do
local lpeg = require "lpeg"
local lpegmatch = lpeg.match
- local P = lpeg.P
local C = lpeg.C
local Cp = lpeg.Cp
+ local Cs = lpeg.Cs
+ local P = lpeg.P
+ local S = lpeg.S
+ local p_space = P" "
local p_cr = P"\r"
local p_lf = P"\n"
+
+ local p_white_fold = S" \t"
+ local p_white = S" \n\r\t\v"
local p_eol = p_cr * p_lf + p_lf
local p_noeol = P(1) - p_eol
- local p_content_line = C (p_noeol^1) * p_eol * Cp ()
+ --[[--
+
+ RFC2445: Long content lines SHOULD be split into a multiple line
+ representations using a line "folding" technique. That is, a long line can
+ be split between any two characters by inserting a CRLF immediately
+ followed by a single linear white space character (i.e., SPACE, US-ASCII
+ decimal 32 or HTAB, US-ASCII decimal 9).
+
+ --]]--
+
+ local p_folded_line_1 = p_noeol^1 * (p_eol / "")
+ local p_folded_line_c = p_white_fold/"" * p_folded_line_1
+
+ local p_content_line = Cs(p_folded_line_1 * p_folded_line_c^0) * Cp()
+
+ local p_skip_line = p_noeol^0 * p_eol * Cp()
local parse_content_line = function (raw, pos0)
local res, pos1 = lpegmatch (p_content_line, raw, pos0)
@@ -28,12 +54,26 @@ local parse_calendar do
return res, pos1
end
- parse_calendar = function (raw, pos0, consumed)
- if pos0 == nil then return parse_calendar (raw, 1, 0) end
+ local skip_line = function (raw, pos0)
+ return lpegmatch (p_skip_line, raw, pos0)
+ end
+
+ local errline = function (pos)
+ end
+
+ parse_calendar = function (raw, pos0, consumed, nline, nskipped)
+ if pos0 == nil then return parse_calendar (raw, 1, 0, 1) end
local cline, pos1 = parse_content_line (raw, pos0)
- println ("»»» [%d–%d] [%s]", pos0, pos1, cline)
- return parse_calendar (raw, pos1, consumed + pos1 - pos0)
+ if cline == nil then
+ pos1 = skip_line (raw, pos0)
+ println ("[%d–%d] %d bad content line; skipping", pos0, pos1, nline)
+ nskipped = nskipped + 1
+ else
+ println ("[%d–%d] %d [%s]", pos0, pos1, nline, cline)
+ end
+ return parse_calendar (raw, pos1, consumed + pos1 - pos0, nline + 1,
+ nskipped)
end
end