module ParseFoldoc where import Data.Char import Data.Maybe import System.Locale import System.Time data FoldocEntry = FoldocEntry String String [String] (Maybe CalendarTime) instance Show FoldocEntry where show (FoldocEntry h b s d) = h ++ "\n" ++ unwords s ++ "\n\n" ++ b ++ "\n" ++ maybe "(no date)" showDate d ++ "\n" showDate d = formatCalendarTime defaultTimeLocale fmt d where fmt = iso8601DateFormat Nothing parse :: String -> [FoldocEntry] parse s = map parseEntry (splitEntries (lines s)) parseEntry :: [String] -> FoldocEntry parseEntry (h:"":b) = FoldocEntry h body (subjects body) maybeDate where b' = map dropTab (initIfLastEmpty b) maybeDate = parseDate (last b') b'' = take (length b' - 2) b' body = unlines (if isJust maybeDate then b'' else b') initIfLastEmpty :: [[a]] -> [[a]] initIfLastEmpty [] = [] initIfLastEmpty [[]] = [] initIfLastEmpty (x:xs) = x:initIfLastEmpty xs dropTab :: String -> String dropTab ('\t':xs) = xs dropTab xs = xs subjects :: String -> [String] subjects _ = [] {- -- doesn't work subjects :: String -> [String] subjects [] = [] subjects ('<':xs) = (subj,'>':rs) = break (=='>') xs in subj : subjects rs subjects (_:xs) = subjects xs -} parseDate :: String -> Maybe CalendarTime parseDate ('(':y1:y2:y3:y4:'-':m1:m2:'-':d1:d2:')':[]) = Just $ CalendarTime { ctYear = read [y1,y2,y3,y4], ctMonth = toEnum (read [m1,m2] - 1), ctDay = read [d1,d2], ctHour = 0, ctMin = 0, ctSec = 0 } parseDate _ = Nothing headIs :: Eq a => (a -> Bool) -> [a] -> Bool headIs _ [] = False headIs f (x:_) = f x splitEntries :: [String] -- ^ list of lines -> [[String]] -- ^ list of entries splitEntries [] = [] splitEntries (l:ls) = let (e,r) = break (headIs (/='\t')) ls in (l:e) : splitEntries r