From 0eceeb5542b6894d6124182572baf136234689c8 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sat, 28 Jun 2008 04:44:33 +0000 Subject: [PATCH] basic support for a comments-preserving print command. Preserves most inter-entry comment lines and whitespace (but not yet a comment immediately after an entry, or whitespace/comments after the last entry.) Whitespace and comment lines are stored as part of the following entry. Lines after the last entry are stored as an extra ledger file field. Inspired by Nafai on #ledger. --- Ledger.hs | 10 +++++----- LedgerEntry.hs | 9 +++++---- Parse.hs | 15 ++++++--------- Tests.hs | 21 ++++++++++++++------- TimeLog.hs | 5 +++-- Transaction.hs | 4 ++-- Types.hs | 6 ++++-- 7 files changed, 39 insertions(+), 31 deletions(-) diff --git a/Ledger.hs b/Ledger.hs index b98326c37..2310612be 100644 --- a/Ledger.hs +++ b/Ledger.hs @@ -64,8 +64,8 @@ cacheLedger pats l = -- filter entries by description and whether any transactions match account patterns filterLedgerEntries :: FilterPatterns -> LedgerFile -> LedgerFile -filterLedgerEntries (acctpat,descpat) (LedgerFile ms ps es) = - LedgerFile ms ps (filter matchdesc $ filter (any matchtxn . etransactions) es) +filterLedgerEntries (acctpat,descpat) (LedgerFile ms ps es f) = + LedgerFile ms ps (filter matchdesc $ filter (any matchtxn . etransactions) es) f where matchtxn t = case matchRegex (wilddefault acctpat) (taccount t) of Nothing -> False @@ -77,10 +77,10 @@ filterLedgerEntries (acctpat,descpat) (LedgerFile ms ps es) = -- filter transactions in each ledger entry by account patterns -- this may unbalance entries filterLedgerTransactions :: FilterPatterns -> LedgerFile -> LedgerFile -filterLedgerTransactions (acctpat,descpat) (LedgerFile ms ps es) = - LedgerFile ms ps (map filterentrytxns es) +filterLedgerTransactions (acctpat,descpat) (LedgerFile ms ps es f) = + LedgerFile ms ps (map filterentrytxns es) f where - filterentrytxns l@(LedgerEntry _ _ _ _ _ ts) = l{etransactions=filter matchtxn ts} + filterentrytxns l@(LedgerEntry _ _ _ _ _ ts _) = l{etransactions=filter matchtxn ts} matchtxn t = case matchRegex (wilddefault acctpat) (taccount t) of Nothing -> False otherwise -> True diff --git a/LedgerEntry.hs b/LedgerEntry.hs index 51a05b0ff..82bb6becd 100644 --- a/LedgerEntry.hs +++ b/LedgerEntry.hs @@ -30,7 +30,7 @@ isEntryBalanced :: LedgerEntry -> Bool isEntryBalanced = ((0::Double)==) . read . printf "%0.8f" . quantity . sumLedgerTransactions . etransactions autofillEntry :: LedgerEntry -> LedgerEntry -autofillEntry e@(LedgerEntry _ _ _ _ _ ts) = +autofillEntry e@(LedgerEntry _ _ _ _ _ ts _) = let e' = e{etransactions=autofillTransactions ts} in case (isEntryBalanced e') of True -> e' @@ -50,8 +50,9 @@ autofillEntry e@(LedgerEntry _ _ _ _ _ ts) = showEntry :: LedgerEntry -> String showEntry e = - unlines $ ["", description] ++ (showtxns $ etransactions e) + "\n" ++ precedingcomment ++ description ++ unlines (showtxns $ etransactions e) where + precedingcomment = epreceding_comment_lines e description = concat [date, status, code, desc] -- , comment] date = showDate $ edate e status = if estatus e then " *" else "" @@ -71,8 +72,8 @@ showEntries :: [LedgerEntry] -> String showEntries = concatMap showEntry entrySetPrecision :: Int -> LedgerEntry -> LedgerEntry -entrySetPrecision p (LedgerEntry d s c desc comm ts) = - LedgerEntry d s c desc comm $ map (ledgerTransactionSetPrecision p) ts +entrySetPrecision p (LedgerEntry d s c desc comm ts prec) = + LedgerEntry d s c desc comm (map (ledgerTransactionSetPrecision p) ts) prec -- modifier & periodic entries diff --git a/Parse.hs b/Parse.hs index ef9dacfda..e6afac437 100644 --- a/Parse.hs +++ b/Parse.hs @@ -142,14 +142,14 @@ ledgerfile = ledger <|> ledgerfromtimelog ledger :: Parser LedgerFile ledger = do - ledgernondatalines -- for now these must come first, unlike ledger modifier_entries <- many ledgermodifierentry periodic_entries <- many ledgerperiodicentry -- entries <- (many ledgerentry) "entry" + final_comment_lines <- ledgernondatalines eof - return $ LedgerFile modifier_entries periodic_entries entries + return $ LedgerFile modifier_entries periodic_entries entries (unlines final_comment_lines) ledgernondatalines :: Parser [String] ledgernondatalines = many (ledgerdirective <|> ledgercommentline <|> do {whiteSpace1; return []}) @@ -157,8 +157,8 @@ ledgernondatalines = many (ledgerdirective <|> ledgercommentline <|> do {whiteSp ledgercommentline :: Parser String ledgercommentline = do char ';' - many spacenonewline - restofline "comment line" + l <- restofline "comment line" + return $ ";" ++ l ledgercomment :: Parser String ledgercomment = @@ -178,7 +178,6 @@ ledgermodifierentry = do many spacenonewline valueexpr <- restofline transactions <- ledgertransactions - ledgernondatalines return (ModifierEntry valueexpr transactions) ledgerperiodicentry :: Parser PeriodicEntry @@ -187,11 +186,11 @@ ledgerperiodicentry = do many spacenonewline periodexpr <- restofline transactions <- ledgertransactions - ledgernondatalines return (PeriodicEntry periodexpr transactions) ledgerentry :: Parser LedgerEntry ledgerentry = do + preceding <- ledgernondatalines date <- ledgerdate status <- ledgerstatus code <- ledgercode @@ -202,8 +201,7 @@ ledgerentry = do comment <- ledgercomment restofline transactions <- ledgertransactions - ledgernondatalines - return $ autofillEntry $ LedgerEntry date status code description comment transactions + return $ autofillEntry $ LedgerEntry date status code description comment transactions (unlines preceding) ledgerdate :: Parser String ledgerdate = do @@ -232,7 +230,6 @@ ledgertransaction = do many spacenonewline comment <- ledgercomment restofline - many ledgercommentline return (LedgerTransaction account amount comment) -- account names may have single spaces in them, and are terminated by two or more spaces diff --git a/Tests.hs b/Tests.hs index 3e17ce349..3cccc4b6e 100644 --- a/Tests.hs +++ b/Tests.hs @@ -70,7 +70,7 @@ entry1_str = "\ entry1 = (LedgerEntry "2007/01/28" False "" "coopportunity" "" [LedgerTransaction "expenses:food:groceries" (Amount (getcurrency "$") 47.18 2) "", - LedgerTransaction "assets:checking" (Amount (getcurrency "$") (-47.18) 2) ""]) + LedgerTransaction "assets:checking" (Amount (getcurrency "$") (-47.18) 2) ""] "") entry2_str = "\ \2007/01/27 * joes diner\n\ @@ -213,7 +213,8 @@ ledger7 = LedgerFile LedgerTransaction {taccount="equity:opening balances", tamount=Amount {currency=(getcurrency "$"), quantity=(-4.82), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } , LedgerEntry { @@ -225,7 +226,8 @@ ledger7 = LedgerFile LedgerTransaction {taccount="assets:checking", tamount=Amount {currency=(getcurrency "$"), quantity=(-179.92), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } , LedgerEntry { @@ -237,7 +239,8 @@ ledger7 = LedgerFile LedgerTransaction {taccount="assets:checking", tamount=Amount {currency=(getcurrency "$"), quantity=(-200), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } , LedgerEntry { @@ -249,7 +252,8 @@ ledger7 = LedgerFile LedgerTransaction {taccount="assets:cash", tamount=Amount {currency=(getcurrency "$"), quantity=(-4.82), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } , LedgerEntry { @@ -261,7 +265,8 @@ ledger7 = LedgerFile LedgerTransaction {taccount="assets:checking", tamount=Amount {currency=(getcurrency "$"), quantity=(-95.11), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } , LedgerEntry { @@ -273,9 +278,11 @@ ledger7 = LedgerFile LedgerTransaction {taccount="assets:checking", tamount=Amount {currency=(getcurrency "$"), quantity=(-80), precision=2}, tcomment=""} - ] + ], + epreceding_comment_lines="" } ] + "" l7 = cacheLedger (argpats [] []) ledger7 diff --git a/TimeLog.hs b/TimeLog.hs index 9224e6393..014c0e879 100644 --- a/TimeLog.hs +++ b/TimeLog.hs @@ -16,7 +16,7 @@ instance Show TimeLog where ledgerFromTimeLog :: TimeLog -> LedgerFile ledgerFromTimeLog tl = - LedgerFile [] [] (entriesFromTimeLogEntries $ timelog_entries tl) + LedgerFile [] [] (entriesFromTimeLogEntries $ timelog_entries tl) "" entriesFromTimeLogEntries :: [TimeLogEntry] -> [LedgerEntry] @@ -34,7 +34,8 @@ entriesFromTimeLogEntries [clockin,clockout] = etransactions = [ LedgerTransaction accountname amount "", LedgerTransaction "TIME" (-amount) "" - ]} + ], + epreceding_comment_lines=""} ] where accountname = tlcomment clockin diff --git a/Transaction.hs b/Transaction.hs index 17a356b56..0a3040632 100644 --- a/Transaction.hs +++ b/Transaction.hs @@ -15,7 +15,7 @@ instance Show Transaction where -- we use the entry number e to remember the grouping of txns flattenEntry :: (LedgerEntry, Int) -> [Transaction] -flattenEntry (LedgerEntry d _ _ desc _ ts, e) = +flattenEntry (LedgerEntry d _ _ desc _ ts _, e) = [Transaction e d desc (taccount t) (tamount t) | t <- ts] transactionSetPrecision :: Int -> Transaction -> Transaction @@ -47,7 +47,7 @@ showTransactionsWithBalances ts b = showTransactionDescriptionAndBalance :: Transaction -> Amount -> String showTransactionDescriptionAndBalance t b = - (showEntryDescription $ LedgerEntry (date t) False "" (description t) "" []) + (showEntryDescription $ LedgerEntry (date t) False "" (description t) "" [] "") ++ (showLedgerTransaction $ LedgerTransaction (account t) (amount t) "") ++ (showBalance b) showTransactionAndBalance :: Transaction -> Amount -> String diff --git a/Types.hs b/Types.hs index 3bccb68db..3413f008a 100644 --- a/Types.hs +++ b/Types.hs @@ -67,7 +67,8 @@ data LedgerEntry = LedgerEntry { ecode :: String, edescription :: String, ecomment :: String, - etransactions :: [LedgerTransaction] + etransactions :: [LedgerTransaction], + epreceding_comment_lines :: String } deriving (Eq) -- an automated ledger entry @@ -97,7 +98,8 @@ data TimeLog = TimeLog { data LedgerFile = LedgerFile { modifier_entries :: [ModifierEntry], periodic_entries :: [PeriodicEntry], - entries :: [LedgerEntry] + entries :: [LedgerEntry], + final_comment_lines :: String } deriving (Eq) -- we flatten LedgerEntries and LedgerTransactions into Transactions,