From 2ab4257bf85adcc055e783df5735601cec9cbfff Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sat, 23 Jun 2018 14:53:06 +0200 Subject: cal: handle folding --- cal.lua | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file 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 -- cgit v1.2.3