module Hledger.Read.TimelogReader (
reader,
tests_Hledger_Read_TimelogReader
)
where
import Control.Monad
import Control.Monad.Except
import Data.List (isPrefixOf, foldl')
import Test.HUnit
import Text.Parsec hiding (parse)
import System.FilePath
import Hledger.Data
import Hledger.Read.JournalReader (
directive, historicalpricedirective, defaultyeardirective, emptyorcommentlinep, datetimep,
parseJournalWith, getParentAccount
)
import Hledger.Utils
reader :: Reader
reader = Reader format detect parse
format :: String
format = "timelog"
detect :: FilePath -> String -> Bool
detect f s
| f /= "-" = takeExtension f == '.':format
| otherwise = "i " `isPrefixOf` s || "o " `isPrefixOf` s
parse :: Maybe FilePath -> Bool -> FilePath -> String -> ExceptT String IO Journal
parse _ = parseJournalWith timelogFile
timelogFile :: ParsecT [Char] JournalContext (ExceptT String IO) (JournalUpdate, JournalContext)
timelogFile = do items <- many timelogItem
eof
ctx <- getState
return (liftM (foldl' (\acc new x -> new (acc x)) id) $ sequence items, ctx)
where
timelogItem = choice [ directive
, liftM (return . addHistoricalPrice) historicalpricedirective
, defaultyeardirective
, emptyorcommentlinep >> return (return id)
, liftM (return . addTimeLogEntry) timelogentry
] <?> "timelog entry, or default year or historical price directive"
timelogentry :: ParsecT [Char] JournalContext (ExceptT String IO) TimeLogEntry
timelogentry = do
sourcepos <- getPosition
code <- oneOf "bhioO"
many1 spacenonewline
datetime <- datetimep
comment <- optionMaybe (many1 spacenonewline >> liftM2 (++) getParentAccount restofline)
return $ TimeLogEntry sourcepos (read [code]) datetime (maybe "" rstrip comment)
tests_Hledger_Read_TimelogReader = TestList [
]