module Parser (schedule) where
-- MITSFS iPhone schedule pretty-printer
-- Copyright (C) 2008 Brian Sniffen
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU General Public License along
-- with this program; if not, write to the Free Software Foundation, Inc.,
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
import Text.ParserCombinators.ReadP
import Model
slot :: ReadP Slot
slot = do
separator
sixChars <- count 6 get
return $ case filter (/=' ') sixChars of
"" -> Nothing
keyholder -> Just keyholder
separator :: ReadP ()
separator = string " " >> return ()
line :: ReadP Line
line = dateLine <++ timeLine <++ junk
junk = return mkJunk
dateLine = do
dates <- count 7 (skipSpaces >> date)
return $ head dates
where
date = do
month <- integer
char '/'
day <- integer
return $ mkDates month day
timeLine = do
header <- time
hours <- count 7 slot
return $ mkTime header hours
time :: ReadP Int
time = do
skipSpaces
start <- timeSpec
string " - "
end <- timeSpec
return start
timeSpec :: ReadP Int
timeSpec = noon +++ midnight +++ withAMPM +++ integer
where
noon = string "Noon" >> return 12
midnight = string "Mid" >> return 0
withAMPM = do
n <- integer
string " AM" <++ string " PM"
return n
integer :: ReadP Int
integer = do
chars <- munch1 (\c -> c `elem` "0123456789")
return $ read chars
parseLine = fst . head . readP_to_S line . extendWithSpace
where
extendWithSpace x = take 80 $ x ++ repeat ' '
schedule r =
tail . reverse . snd . foldl collect ([],[]) . map parseLine $ lines r
where
collect (accum,result) j | isJunk j = (accum,result)
collect (accum,result) d | isDate d = ([d], (reverse accum):result)
collect (accum,result) t | isTime t = (t:accum, result)