module Hledger.Read.TimelogReader (
reader,
tests_Hledger_Read_TimelogReader
)
where
import Prelude ()
import Prelude.Compat
import Control.Monad (liftM)
import Control.Monad.Except (ExceptT)
import Data.List (isPrefixOf, foldl')
import Data.Maybe (fromMaybe)
import Test.HUnit
import Text.Parsec hiding (parse)
import System.FilePath
import Hledger.Data
import Hledger.Read.JournalReader (
directivep, marketpricedirectivep, defaultyeardirectivep, emptyorcommentlinep, datetimep,
parseAndFinaliseJournal, modifiedaccountnamep, genericSourcePos
)
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 _ = parseAndFinaliseJournal timelogfilep
timelogfilep :: ParsecT [Char] JournalContext (ExceptT String IO) (JournalUpdate, JournalContext)
timelogfilep = do items <- many timelogitemp
eof
ctx <- getState
return (liftM (foldl' (\acc new x -> new (acc x)) id) $ sequence items, ctx)
where
timelogitemp = choice [ directivep
, liftM (return . addMarketPrice) marketpricedirectivep
, defaultyeardirectivep
, emptyorcommentlinep >> return (return id)
, liftM (return . addTimeLogEntry) timelogentryp
] <?> "timelog entry, or default year or historical price directive"
timelogentryp :: ParsecT [Char] JournalContext (ExceptT String IO) TimeLogEntry
timelogentryp = do
sourcepos <- genericSourcePos <$> getPosition
code <- oneOf "bhioO"
many1 spacenonewline
datetime <- datetimep
account <- fromMaybe "" <$> optionMaybe (many1 spacenonewline >> modifiedaccountnamep)
description <- fromMaybe "" <$> optionMaybe (many1 spacenonewline >> restofline)
return $ TimeLogEntry sourcepos (read [code]) datetime account description
tests_Hledger_Read_TimelogReader = TestList [
]