module Task ( Task(..) , Status(..) , dumpTasks , showTasks , loadTasks ) where import Ansi ( Palette(ternary) , makeCrossed , makeFaint , makeInverse , makeItalic , paint , reset ) import Style (preen) data Status = Todo | Doing | Done data Task = Task { line :: Int , status :: Status , text :: String , comment :: Maybe String } -- Dump dumpTasks :: [Task] -> String dumpTasks tasks = unlines $ map dumpTask tasks dumpTask :: Task -> String dumpTask (Task _ status' text' comment') = (mconcat [" - ", dumpStatus status', text', dumpComment comment']) dumpStatus :: Status -> String dumpStatus Todo = "[ ] " dumpStatus Doing = "[ ] … " dumpStatus Done = "[x] " dumpComment :: Maybe String -> String dumpComment (Just comment') = " — " ++ comment' dumpComment Nothing = "" -- Load loadTasks :: Int -> [Task] -> [String] -> [Task] loadTasks l tasks (x:xs) = loadTasks (l + 1) ((buildTask x l) : tasks) xs loadTasks _ tasks [] = reverse tasks buildTask :: String -> Int -> Task buildTask (' ':'-':' ':'[':' ':']':' ':'…':' ':r) line' = buildTask' (Task line' Doing) r buildTask (' ':'-':' ':'[':' ':']':' ':r) line' = buildTask' (Task line' Todo) r buildTask (' ':'-':' ':'[':'x':']':' ':r) line' = buildTask' (Task line' Done) r buildTask text' _ = error $ "Error: \"" ++ text' ++ "\" is not a valid task." buildTask' :: (String -> Maybe String -> Task) -> String -> Task buildTask' partialTask text' = uncurry partialTask $ splitComment text' ("", Nothing) splitComment :: String -> (String, Maybe String) -> (String, Maybe String) splitComment [] (t, c) = (reverse t, c) splitComment (' ':'—':' ':xs) (t, Nothing) = (reverse t, Just xs) splitComment (x:xs) (t, _) = splitComment xs (x : t, Nothing) -- Show showTasks :: [Task] -> [String] showTasks tasks = map (showTask $ length tasks) tasks showTask :: Int -> Task -> String showTask total (Task line' Todo text' comment') = (showLine total line' id) ++ " " ++ (showText text' comment' id) ++ reset showTask total (Task line' Doing text' comment') = (showLine total line' makeInverse) ++ " " ++ (showText text' comment' id) ++ reset showTask total (Task line' Done text' comment') = (showLine total line' makeCrossed) ++ " " ++ (showText text' comment' makeFaint) ++ reset showLine :: Int -> Int -> (String -> String) -> String showLine total line' style = (alignRight total line') ++ (style $ paint ternary $ show line') where alignRight x n = replicate (length (show $ x - 1) - length (show n)) ' ' showText :: String -> Maybe String -> (String -> String) -> String showText text' (Just comment') style = style $ preen text' ++ (makeItalic $ " — " ++ comment') showText text' Nothing style = style $ preen text'