diff --git a/Ledger/Ledger.hs b/Ledger/Ledger.hs index d594c25d6..c3258a1bb 100644 --- a/Ledger/Ledger.hs +++ b/Ledger/Ledger.hs @@ -2,7 +2,8 @@ A 'Ledger' stores, for efficiency, a 'RawLedger' plus its tree of account names, and a map from account names to 'Account's. It may also have had -uninteresting 'Entry's and 'Transaction's filtered out. +uninteresting 'Entry's and 'Transaction's filtered out. It also stores +the complete ledger file text for the ui command. -} @@ -30,7 +31,7 @@ instance Show Ledger where -- | Convert a raw ledger to a more efficient cached type, described above. cacheLedger :: [String] -> RawLedger -> Ledger -cacheLedger apats l = Ledger l ant acctmap +cacheLedger apats l = Ledger{rawledgertext="",rawledger=l,accountnametree=ant,accountmap=acctmap} where ts = filtertxns apats $ rawLedgerTransactions l ant = rawLedgerAccountNameTree l diff --git a/Ledger/Types.hs b/Ledger/Types.hs index cac146f24..4abb099d3 100644 --- a/Ledger/Types.hs +++ b/Ledger/Types.hs @@ -106,6 +106,7 @@ data Account = Account { } data Ledger = Ledger { + rawledgertext :: String, rawledger :: RawLedger, accountnametree :: Tree AccountName, accountmap :: Map.Map AccountName Account diff --git a/Utils.hs b/Utils.hs index 8d71a2eea..75457dec8 100644 --- a/Utils.hs +++ b/Utils.hs @@ -16,10 +16,10 @@ import Ledger -- | Convert a RawLedger to a canonicalised, cached and filtered Ledger -- based on the command-line options/arguments and today's date. -prepareLedger :: [Opt] -> [String] -> Day -> RawLedger -> Ledger -prepareLedger opts args refdate rl = - cacheLedger apats $ filterRawLedger span dpats c r $ canonicaliseAmounts cb rl +prepareLedger :: [Opt] -> [String] -> Day -> String -> RawLedger -> Ledger +prepareLedger opts args refdate rawtext rl = l{rawledgertext=rawtext} where + l = cacheLedger apats $ filterRawLedger span dpats c r $ canonicaliseAmounts cb rl (apats,dpats) = parseAccountDescriptionArgs [] args span = dateSpanFromOpts refdate opts c = Cleared `elem` opts @@ -33,14 +33,15 @@ rawledgerfromstring = liftM (either error id) . runErrorT . parseLedger "(string -- | Get a Ledger from the given string and options, or raise an error. ledgerfromstringwithopts :: [Opt] -> [String] -> Day -> String -> IO Ledger ledgerfromstringwithopts opts args refdate s = - liftM (prepareLedger opts args refdate) $ rawledgerfromstring s + liftM (prepareLedger opts args refdate s) $ rawledgerfromstring s -- | Get a Ledger from the given file path and options, or raise an error. ledgerfromfilewithopts :: [Opt] -> [String] -> FilePath -> IO Ledger ledgerfromfilewithopts opts args f = do - rl <- readFile f >>= rawledgerfromstring - refdate <- today - return $ prepareLedger opts args refdate rl + refdate <- today + s <- readFile f + rl <- rawledgerfromstring s + return $ prepareLedger opts args refdate s rl -- | Get a Ledger from your default ledger file, or raise an error. -- Assumes no options. diff --git a/hledger.hs b/hledger.hs index 258ee108b..df0301272 100644 --- a/hledger.hs +++ b/hledger.hs @@ -76,5 +76,8 @@ main = do parseLedgerAndDo :: [Opt] -> [String] -> ([Opt] -> [String] -> Ledger -> IO ()) -> IO () parseLedgerAndDo opts args cmd = do refdate <- today - let runcmd = cmd opts args . prepareLedger opts args refdate - ledgerFilePathFromOpts opts >>= runErrorT . parseLedgerFile >>= either (hPutStrLn stderr) runcmd + -- ack, we're reading the file twice in order to save the text + f <- ledgerFilePathFromOpts opts + rawtext <- readFile f + let runcmd = cmd opts args . prepareLedger opts args refdate rawtext + return f >>= runErrorT . parseLedgerFile >>= either (hPutStrLn stderr) runcmd