module Checkmate.Parser.CheckFile ( parseCheckFile , parseCheckFileText , parser ) where import Control.Monad import Data.Set import qualified Data.Text as T import Data.Text.IO import System.FilePath import Text.Megaparsec import Text.Megaparsec.Text import Checkmate.Check parseCheckFile :: FilePath -> IO (Either (ParseError (Token T.Text) Dec) Checklist) parseCheckFile filePath = do input <- Data.Text.IO.readFile filePath return $ parseCheckFileText filePath input parseCheckFileText :: FilePath -> T.Text -> Either (ParseError (Token T.Text) Dec) Checklist parseCheckFileText filePath = parse (parser $ takeDirectory filePath) filePath parser :: FilePath -> Parser Checklist parser dirPath = do space checkTexts <- many checkP eof return $ Data.Set.fromList [Check (Directory dirPath) i ct | (i, ct) <- zip [1..] checkTexts] where bulletP :: Parser () bulletP = do skipMany (spaceChar <|> tab) bullet <- choice [ string "*" , string "+" , string "-" , string "CHECK:" , string "CHECK" , some digitChar >> (string "." <|> string ")") ] skipSome (spaceChar <|> tab) unless (bullet == "CHECK") $ void . optional $ do void $ string "CHECK" skipSome (spaceChar <|> tab) checkP :: Parser T.Text checkP = do bulletP texts <- (`sepBy1` try (eol >> notFollowedBy bulletP)) $ do chars <- many $ noneOf "\n" return $ T.pack chars let texts' = texts :: [T.Text] return $ T.strip $ T.intercalate (T.singleton '\n') texts'