diff options
author | Philipp Gesang <phg@phi-gamma.net> | 2018-06-23 14:53:06 +0200 |
---|---|---|
committer | Philipp Gesang <phg@phi-gamma.net> | 2018-06-26 13:57:25 +0200 |
commit | 2ab4257bf85adcc055e783df5735601cec9cbfff (patch) | |
tree | d17a182475700e2ef2f67128cfdb95089148e4f4 | |
parent | 0b9144c3ca46c1138f37db3de4b1698818178085 (diff) | |
download | caldr-2ab4257bf85adcc055e783df5735601cec9cbfff.tar.gz |
cal: handle folding
-rwxr-xr-x | cal.lua | 52 |
1 files changed, 46 insertions, 6 deletions
@@ -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 |