refactor ledgerDirective

This commit is contained in:
Simon Michael 2011-08-04 07:49:10 +00:00
parent 8e7d20e4d5
commit 345c2343b6
2 changed files with 76 additions and 71 deletions

View File

@ -168,21 +168,12 @@ journalFile = do
-- character, excepting transactions versus empty (blank or -- character, excepting transactions versus empty (blank or
-- comment-only) lines, can use choice w/o try -- comment-only) lines, can use choice w/o try
journalItem = choice [ ledgerDirective journalItem = choice [ ledgerDirective
, liftM (return . addTransaction) ledgerTransaction , liftM (return . addTransaction) ledgerTransaction
, liftM (return . addModifierTransaction) ledgerModifierTransaction , liftM (return . addModifierTransaction) ledgerModifierTransaction
, liftM (return . addPeriodicTransaction) ledgerPeriodicTransaction , liftM (return . addPeriodicTransaction) ledgerPeriodicTransaction
, liftM (return . addHistoricalPrice) ledgerHistoricalPrice , liftM (return . addHistoricalPrice) ledgerHistoricalPrice
, ledgerDefaultYear , emptyLine >> return (return id)
, ledgerDefaultCommodity ] <?> "journal transaction or directive"
, ledgerCommodityConversion
, ledgerIgnoredPriceCommodity
, ledgerTagDirective
, ledgerEndTagDirective
, emptyLine >> return (return id)
] <?> "journal transaction or directive"
journalAddFile :: (FilePath,String) -> Journal -> Journal
journalAddFile f j@Journal{files=fs} = j{files=fs++[f]}
emptyLine :: GenParser Char JournalContext () emptyLine :: GenParser Char JournalContext ()
emptyLine = do many spacenonewline emptyLine = do many spacenonewline
@ -210,14 +201,21 @@ ledgerDirective :: GenParser Char JournalContext JournalUpdate
ledgerDirective = do ledgerDirective = do
optional $ char '!' optional $ char '!'
choice' [ choice' [
string "include" >> ledgerInclude ledgerInclude
,string "account" >> ledgerAccountBegin ,ledgerAccountBegin
,string "end" >> ledgerAccountEnd ,ledgerAccountEnd
,ledgerTagDirective
,ledgerEndTagDirective
,ledgerDefaultYear
,ledgerDefaultCommodity
,ledgerCommodityConversion
,ledgerIgnoredPriceCommodity
] ]
<?> "directive" <?> "directive"
ledgerInclude :: GenParser Char JournalContext JournalUpdate ledgerInclude :: GenParser Char JournalContext JournalUpdate
ledgerInclude = do ledgerInclude = do
string "include"
many1 spacenonewline many1 spacenonewline
filename <- restofline filename <- restofline
outerState <- getState outerState <- getState
@ -232,31 +230,58 @@ ledgerInclude = do
ErrorT $ liftM Right (readFile fp) `catch` ErrorT $ liftM Right (readFile fp) `catch`
\err -> return $ Left $ printf "%s reading %s:\n%s" (show pos) fp (show err) \err -> return $ Left $ printf "%s reading %s:\n%s" (show pos) fp (show err)
journalAddFile :: (FilePath,String) -> Journal -> Journal
journalAddFile f j@Journal{files=fs} = j{files=fs++[f]}
ledgerAccountBegin :: GenParser Char JournalContext JournalUpdate ledgerAccountBegin :: GenParser Char JournalContext JournalUpdate
ledgerAccountBegin = do many1 spacenonewline ledgerAccountBegin = do
parent <- ledgeraccountname string "account"
newline many1 spacenonewline
pushParentAccount parent parent <- ledgeraccountname
return $ return id newline
pushParentAccount parent
return $ return id
ledgerAccountEnd :: GenParser Char JournalContext JournalUpdate ledgerAccountEnd :: GenParser Char JournalContext JournalUpdate
ledgerAccountEnd = popParentAccount >> return (return id) ledgerAccountEnd = do
string "end"
popParentAccount
return (return id)
ledgerModifierTransaction :: GenParser Char JournalContext ModifierTransaction ledgerTagDirective :: GenParser Char JournalContext JournalUpdate
ledgerModifierTransaction = do ledgerTagDirective = do
char '=' <?> "modifier transaction" string "tag" <?> "tag directive"
many spacenonewline many1 spacenonewline
valueexpr <- restofline _ <- many1 nonspace
postings <- ledgerpostings restofline
return $ ModifierTransaction valueexpr postings return $ return id
ledgerPeriodicTransaction :: GenParser Char JournalContext PeriodicTransaction ledgerEndTagDirective :: GenParser Char JournalContext JournalUpdate
ledgerPeriodicTransaction = do ledgerEndTagDirective = do
char '~' <?> "periodic transaction" (string "end tag" <|> string "pop") <?> "end tag or pop directive"
restofline
return $ return id
ledgerDefaultYear :: GenParser Char JournalContext JournalUpdate
ledgerDefaultYear = do
char 'Y' <?> "default year"
many spacenonewline many spacenonewline
periodexpr <- restofline y <- many1 digit
postings <- ledgerpostings let y' = read y
return $ PeriodicTransaction periodexpr postings failIfInvalidYear y
setYear y'
return $ return id
ledgerDefaultCommodity :: GenParser Char JournalContext JournalUpdate
ledgerDefaultCommodity = do
char 'D' <?> "default commodity"
many1 spacenonewline
a <- someamount
-- someamount always returns a MixedAmount containing one Amount, but let's be safe
let as = amounts a
when (not $ null as) $ setCommodity $ commodity $ head as
restofline
return $ return id
ledgerHistoricalPrice :: GenParser Char JournalContext HistoricalPrice ledgerHistoricalPrice :: GenParser Char JournalContext HistoricalPrice
ledgerHistoricalPrice = do ledgerHistoricalPrice = do
@ -290,41 +315,21 @@ ledgerCommodityConversion = do
restofline restofline
return $ return id return $ return id
ledgerTagDirective :: GenParser Char JournalContext JournalUpdate ledgerModifierTransaction :: GenParser Char JournalContext ModifierTransaction
ledgerTagDirective = do ledgerModifierTransaction = do
string "tag" <?> "tag directive" char '=' <?> "modifier transaction"
many1 spacenonewline
_ <- many1 nonspace
restofline
return $ return id
ledgerEndTagDirective :: GenParser Char JournalContext JournalUpdate
ledgerEndTagDirective = do
(string "end tag" <|> string "pop") <?> "end tag or pop directive"
restofline
return $ return id
-- like ledgerAccountBegin, updates the JournalContext
ledgerDefaultYear :: GenParser Char JournalContext JournalUpdate
ledgerDefaultYear = do
char 'Y' <?> "default year"
many spacenonewline many spacenonewline
y <- many1 digit valueexpr <- restofline
let y' = read y postings <- ledgerpostings
failIfInvalidYear y return $ ModifierTransaction valueexpr postings
setYear y'
return $ return id
ledgerDefaultCommodity :: GenParser Char JournalContext JournalUpdate ledgerPeriodicTransaction :: GenParser Char JournalContext PeriodicTransaction
ledgerDefaultCommodity = do ledgerPeriodicTransaction = do
char 'D' <?> "default commodity" char '~' <?> "periodic transaction"
many1 spacenonewline many spacenonewline
a <- someamount periodexpr <- restofline
-- someamount always returns a MixedAmount containing one Amount, but let's be safe postings <- ledgerpostings
let as = amounts a return $ PeriodicTransaction periodexpr postings
when (not $ null as) $ setCommodity $ commodity $ head as
restofline
return $ return id
-- | Parse a (possibly unbalanced) ledger transaction. -- | Parse a (possibly unbalanced) ledger transaction.
ledgerTransaction :: GenParser Char JournalContext Transaction ledgerTransaction :: GenParser Char JournalContext Transaction

View File

@ -12,7 +12,7 @@ import System.FilePath(takeDirectory,combine)
import System.Time (getClockTime) import System.Time (getClockTime)
import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec
import Hledger.Data.Types (Journal, JournalContext(..), Commodity, JournalUpdate) import Hledger.Data.Types
import Hledger.Utils import Hledger.Utils
import Hledger.Data.Dates (getCurrentYear) import Hledger.Data.Dates (getCurrentYear)
import Hledger.Data.Journal (nullctx, nulljournal, journalFinalise) import Hledger.Data.Journal (nullctx, nulljournal, journalFinalise)