From bd5652c1c2594f6d0478904f2f4f57ba54dde3d2 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Mon, 26 Feb 2024 22:02:56 +0000 Subject: [PATCH 01/10] ;cln:import: remove superfluous comment lines Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 1540 +---------------------- 1 file changed, 3 insertions(+), 1537 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index 1f4babc92..ee5cd0a8e 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -1236,518 +1236,7 @@ getAmount rules record currency p1IsVirtual n = in case discardExcessZeros $ discardUnnumbered assignments of [] -> Nothing [(f,a)] -> Just $ negateIfOut f a - fs -> error' . T.unpack . textChomp . T.unlines $ -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: + fs -> error' . T.unpack . textChomp . T.unlines $ ["in CSV rules:" ,"While processing " <> showRecord record ,"while calculating amount for posting " <> T.pack (show n) @@ -1785,518 +1274,7 @@ getBalance rules record currency n = do -- The whole CSV record is provided for the error message. parseAmount :: CsvRules -> CsvRecord -> Text -> Text -> MixedAmount parseAmount rules record currency s = - either mkerror mixedAmount $ -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: - -- PARTIAL: + either mkerror mixedAmount $ runParser (evalStateT (amountp <* eof) journalparsestate) "" $ currency <> simplifySign s where @@ -2492,521 +1470,9 @@ tests_RulesReader = testGroup "RulesReader" [ (Right (mkrules $ defrules{rassignments = [("account1","")], rconditionalblocks = [CB{cbMatchers=[RecordMatcher None (toRegex' "foo")],cbAssignments=[("account2","foo")]}]})) ] ,testGroup "conditionalblockp" [ - testCase "space after conditional" $ -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 - -- #1120 + testCase "space after conditional" $ parseWithState' defrules conditionalblockp "if a\n account2 b\n \n" @?= (Right $ CB{cbMatchers=[RecordMatcher None $ toRegexCI' "a"],cbAssignments=[("account2","b")]}) - ], testGroup "csvfieldreferencep" [ From 7e06e0caeb17c17c2791a6b96ebae9b38454b52f Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Thu, 29 Feb 2024 20:06:46 +0000 Subject: [PATCH 02/10] ;dev:ghc-tags: ignore hledger/test/addons Signed-off-by: Jonathan Dowland --- ghc-tags.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ghc-tags.yaml b/ghc-tags.yaml index 04d126a07..07cd66c0b 100644 --- a/ghc-tags.yaml +++ b/ghc-tags.yaml @@ -6,3 +6,5 @@ source_paths: cpp_options: - -DMIN_VERSION_megaparsec(x,y,z)=1 - -DMIN_VERSION_aeson(x,y,z)=1 +exclude_paths: +- hledger/test/addons From 8f514ac16d45dd400bf34dc9df6888813f5ee298 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Tue, 27 Feb 2024 18:45:43 +0000 Subject: [PATCH 03/10] ;test:import: test case for match groups (#2158) Add a test which captures the issue of overlapping scope described in GitHub issue #2158. Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index ee5cd0a8e..b8681aca8 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -1531,4 +1531,20 @@ tests_RulesReader = testGroup "RulesReader" [ ] + -- testing match groups (#2158) + ,testGroup "hledgerFieldValue" $ + let rules = mkrules $ defrules + { rcsvfieldindexes=[ ("date",1), ("description",2) ] + , rassignments=[ ("account2","equity"), ("amount1","1") ] + -- ConditionalBlocks here are in reverse order: mkrules reverses the list + , rconditionalblocks=[ CB { cbMatchers=[FieldMatcher None "%description" (toRegex' "PREFIX (.*) - (.*)")] + , cbAssignments=[("account1","account:\\1:\\2")] } + , CB { cbMatchers=[FieldMatcher None "%description" (toRegex' "PREFIX (.*)")] + , cbAssignments=[("account1","account:\\1"), ("comment1","\\1")] } + ] + } + record = ["2019-02-01","PREFIX Text 1 - Text 2"] + in [ testCase "scoped match groups forwards" $ hledgerFieldValue rules record "account1" @?= (Just "account:Text 1:Text 2") + , testCase "scoped match groups backwards" $ hledgerFieldValue rules record "comment1" @?= (Just "Text 1 - Text 2") + ] ] From 8b14022d9709e49f295bc3900d1764d8a3b431dc Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Wed, 28 Feb 2024 18:35:50 +0000 Subject: [PATCH 04/10] ;test:import: update matchgroup functest for #2158 Also re-format the comments. Some of the comments within the conditional blocks were actually being parsed as case-insensitive regexes to match against each record. Luckily this didn't impact the results. Signed-off-by: Jonathan Dowland --- hledger/test/import/match.rules | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/hledger/test/import/match.rules b/hledger/test/import/match.rules index db087e2f6..8596e21c5 100644 --- a/hledger/test/import/match.rules +++ b/hledger/test/import/match.rules @@ -1,16 +1,23 @@ fields _, date, _, description, account1, amount, _ -# checking brackets in a field matcher are captured... + +# checking brackets in a field matcher are captured and interpolated into field +# assignments (real-life use-case #2) if %account1 liabilities:jon:(.*) -# ...and interpolated into field assignments (real-life use-case #2) account1 \1 -# checking brackets in a record matcher are captured, including -# nesting... + +# This should match, as should the next block. Both blocks assign to comment1, +# so this block should be a no-op. It's here to test the match group numbering +# between blocks are not conflated (#2158). +if (Zettle) + comment1 ignore + +# checking brackets in a record matcher are captured, including nesting and the +# interpolation token numerical offset is local to this match group; and the +# token is interpolated into surrounding text if Zettle.*(Robert W. (Bell)).*£ -# ... and the interpolation token numerical offset is local to -# this match group; and the token is interpolated into surrounding -# text comment1 Bell=\2. -# Match the YYY-MM of a date field and warp the posting date, useful -# for credit cards (real-life use-case #1)) + +# Match the YYYY-MM of a date field and warp the posting date, useful for +# credit cards (real-life use-case #1)) if %date (....-..)-.. comment2 date:\1-01 From ac7f7262824604c488237c3180b65d74b906f5f6 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Thu, 29 Feb 2024 20:03:18 +0000 Subject: [PATCH 05/10] ;ref:import: consistently use hledgerField hledgerField is an alias to the function getEffectiveAssignment: both names are used in various parts of RulesReader. Treat hledgerField as the canonical name, and getEffectiveAssignment as an implementation detail of hledgerField. Replace all uses of getEffectiveAssignment with hledgerField (except the one in hledgerField.) Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index b8681aca8..cf4162c85 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -235,7 +235,7 @@ validateCsvRules rules = do unless (isAssigned "date") $ Left "Please specify (at top level) the date field. Eg: date %1" Right rules where - isAssigned f = isJust $ getEffectiveAssignment rules [] f + isAssigned f = isJust $ hledgerField rules [] f --- *** rules types _RULES_TYPES__________________________________________ = undefined @@ -1002,7 +1002,7 @@ applyConditionalSkips rules (r:rest) = Just cnt -> applyConditionalSkips rules $ drop (cnt-1) rest where skipnum r1 = - case (getEffectiveAssignment rules r1 "end", getEffectiveAssignment rules r1 "skip") of + case (hledgerField rules r1 "end", hledgerField rules r1 "skip") of (Nothing, Nothing) -> Nothing (Just _, _) -> Just maxBound (Nothing, Just "") -> Just 1 @@ -1293,7 +1293,7 @@ parseAmount rules record currency s = -- | Show the values assigned to each journal field. showRules rules record = T.unlines $ catMaybes [ (("the "<>fld<>" rule is: ")<>) <$> - getEffectiveAssignment rules record fld | fld <- journalfieldnames ] + hledgerField rules record fld | fld <- journalfieldnames ] -- | Show a (approximate) recreation of the original CSV record. showRecord :: CsvRecord -> Text @@ -1503,31 +1503,31 @@ tests_RulesReader = testGroup "RulesReader" [ ] - ,testGroup "getEffectiveAssignment" [ + ,testGroup "hledgerField" [ let rules = mkrules $ defrules {rcsvfieldindexes=[("csvdate",1)],rassignments=[("date","%csvdate")]} - in testCase "toplevel" $ getEffectiveAssignment rules ["a","b"] "date" @?= (Just "%csvdate") + in testCase "toplevel" $ hledgerField rules ["a","b"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1)], rconditionalblocks=[CB [FieldMatcher None "%csvdate" $ toRegex' "a"] [("date","%csvdate")]]} - in testCase "conditional" $ getEffectiveAssignment rules ["a","b"] "date" @?= (Just "%csvdate") + in testCase "conditional" $ hledgerField rules ["a","b"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1)], rconditionalblocks=[CB [FieldMatcher Not "%csvdate" $ toRegex' "a"] [("date","%csvdate")]]} - in testCase "negated-conditional-false" $ getEffectiveAssignment rules ["a","b"] "date" @?= (Nothing) + in testCase "negated-conditional-false" $ hledgerField rules ["a","b"] "date" @?= (Nothing) ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1)], rconditionalblocks=[CB [FieldMatcher Not "%csvdate" $ toRegex' "b"] [("date","%csvdate")]]} - in testCase "negated-conditional-true" $ getEffectiveAssignment rules ["a","b"] "date" @?= (Just "%csvdate") + in testCase "negated-conditional-true" $ hledgerField rules ["a","b"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1),("description",2)], rconditionalblocks=[CB [FieldMatcher None "%csvdate" $ toRegex' "a", FieldMatcher None "%description" $ toRegex' "b"] [("date","%csvdate")]]} - in testCase "conditional-with-or-a" $ getEffectiveAssignment rules ["a"] "date" @?= (Just "%csvdate") + in testCase "conditional-with-or-a" $ hledgerField rules ["a"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1),("description",2)], rconditionalblocks=[CB [FieldMatcher None "%csvdate" $ toRegex' "a", FieldMatcher None "%description" $ toRegex' "b"] [("date","%csvdate")]]} - in testCase "conditional-with-or-b" $ getEffectiveAssignment rules ["_", "b"] "date" @?= (Just "%csvdate") + in testCase "conditional-with-or-b" $ hledgerField rules ["_", "b"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1),("description",2)], rconditionalblocks=[CB [FieldMatcher None "%csvdate" $ toRegex' "a", FieldMatcher And "%description" $ toRegex' "b"] [("date","%csvdate")]]} - in testCase "conditional.with-and" $ getEffectiveAssignment rules ["a", "b"] "date" @?= (Just "%csvdate") + in testCase "conditional.with-and" $ hledgerField rules ["a", "b"] "date" @?= (Just "%csvdate") ,let rules = mkrules $ defrules{rcsvfieldindexes=[("csvdate",1),("description",2)], rconditionalblocks=[CB [FieldMatcher None "%csvdate" $ toRegex' "a", FieldMatcher And "%description" $ toRegex' "b", FieldMatcher None "%description" $ toRegex' "c"] [("date","%csvdate")]]} - in testCase "conditional.with-and-or" $ getEffectiveAssignment rules ["_", "c"] "date" @?= (Just "%csvdate") + in testCase "conditional.with-and-or" $ hledgerField rules ["_", "c"] "date" @?= (Just "%csvdate") ] From b7027c8bbbfdf3fa13a43dbf0d069ac3deaf9855 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Thu, 29 Feb 2024 20:56:18 +0000 Subject: [PATCH 06/10] feat:import: resolve matchgroup references in ConditionalBlock scope (#2158) Adjust getEffectiveAssignment to compute an intermediary form of the active assignments (with an additional Either wrapper to distinguish top-level and conditional assignments) and move the remaining work to its only caller, hledgerField. Rework hledgerFieldValue. Instead of calling hledgerField, call getEffectiveAssignment and--in the conditional block case--construct a CsvRules scoped just to the active ConditionalBlock before calling renderTemplate. Adjust regexMatchValue to use rconditionalblocks to access conditional blocks from the CsvRules, rather than rblocksassigning, since we haven't narrowed the scope of that field. The result is match group references are only expanded for match groups that occur within the in-scope ConditionalBlock. Fixes: #2158. Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 35 ++++++++++++++++++------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index cf4162c85..7d7c89a94 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -710,12 +710,21 @@ csvRule rules = (`getDirective` rules) -- list/field assignment rules, taking into account the current record and -- conditional rules. hledgerField :: CsvRules -> CsvRecord -> HledgerFieldName -> Maybe FieldTemplate -hledgerField = getEffectiveAssignment +hledgerField rules record f = fmap + (either id (lastCBAssignmentTemplate f)) + (getEffectiveAssignment rules record f) -- | Look up the final value assigned to a hledger field, with csv field -- references interpolated. -hledgerFieldValue :: CsvRules -> CsvRecord -> HledgerFieldName -> Maybe Text -hledgerFieldValue rules record f = (fmap (renderTemplate rules record f) . hledgerField rules record) f +hledgerFieldValue rules record f = (flip fmap) (getEffectiveAssignment rules record f) + $ either (renderTemplate rules record) + $ \cb -> let + t = lastCBAssignmentTemplate f cb + r = rules { rconditionalblocks = [cb] } -- XXX handle rblocksassigning + in renderTemplate r record t + +lastCBAssignmentTemplate :: HledgerFieldName -> ConditionalBlock -> FieldTemplate +lastCBAssignmentTemplate f = snd . last . filter ((==f).fst) . cbAssignments maybeNegate :: MatcherPrefix -> Bool -> Bool maybeNegate Not origbool = not origbool @@ -728,15 +737,22 @@ maybeNegate _ origbool = origbool -- Note conditional blocks' patterns are matched against an approximation of the -- CSV record: all the field values, without enclosing quotes, comma-separated. -- -getEffectiveAssignment :: CsvRules -> CsvRecord -> HledgerFieldName -> Maybe FieldTemplate -getEffectiveAssignment rules record f = lastMay $ map snd $ assignments +getEffectiveAssignment + :: CsvRules + -> CsvRecord + -> HledgerFieldName + -> Maybe (Either FieldTemplate ConditionalBlock) +getEffectiveAssignment rules record f = lastMay assignments where -- all active assignments to field f, in order - assignments = dbg9 "csv assignments" $ filter ((==f).fst) $ toplevelassignments ++ conditionalassignments + assignments = dbg9 "csv assignments" $ toplevelassignments ++ conditionalassignments -- all top level field assignments - toplevelassignments = rassignments rules + toplevelassignments = map (Left . snd) $ filter ((==f).fst) $ rassignments rules -- all field assignments in conditional blocks assigning to field f and active for the current csv record - conditionalassignments = concatMap cbAssignments $ filter (isBlockActive rules record) $ (rblocksassigning rules) f + conditionalassignments = map Right + $ filter (any (==f) . map fst . cbAssignments) + $ filter (isBlockActive rules record) + $ (rblocksassigning rules) f -- does this conditional block match the current csv record ? isBlockActive :: CsvRules -> CsvRecord -> ConditionalBlock -> Bool @@ -812,7 +828,8 @@ regexMatchValue rules record f sgroup = let matchgroups = concatMap (getMatchGroups rules record) $ concatMap cbMatchers $ filter (isBlockActive rules record) - $ rblocksassigning rules f + $ rconditionalblocks rules + -- ^ XXX adjusted to not use memoized field as caller might be sending a subset of rules with just one CB (hacky) group = (read (T.unpack sgroup) :: Int) - 1 -- adjust to 0-indexing in atMay matchgroups group From 71684f5611b1e0b376b8611754712a00f66cac6c Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Thu, 29 Feb 2024 21:27:05 +0000 Subject: [PATCH 07/10] ref:import: simplify renderTemplate and friends renderTemplate and its ancillary functions did not need the HledgerFieldName argument, so remove it. Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index 7d7c89a94..dd6bdecc6 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -795,12 +795,12 @@ isBlockActive rules record CB{..} = any (all matcherMatches) $ groupedMatchers c -- | Render a field assignment's template, possibly interpolating referenced -- CSV field values or match groups. Outer whitespace is removed from interpolated values. -renderTemplate :: CsvRules -> CsvRecord -> HledgerFieldName -> FieldTemplate -> Text -renderTemplate rules record f t = +renderTemplate :: CsvRules -> CsvRecord -> FieldTemplate -> Text +renderTemplate rules record t = maybe t mconcat $ parseMaybe (many ( literaltextp - <|> (matchrefp <&> replaceRegexGroupReference rules record f) + <|> (matchrefp <&> replaceRegexGroupReference rules record) <|> (fieldrefp <&> replaceCsvFieldReference rules record) ) ) @@ -818,13 +818,13 @@ renderTemplate rules record f t = -- | Replace something that looks like a Regex match group reference with the -- resulting match group value after applying the Regex. -replaceRegexGroupReference :: CsvRules -> CsvRecord -> HledgerFieldName -> MatchGroupReference -> Text -replaceRegexGroupReference rules record f s = case T.uncons s of - Just ('\\', group) -> fromMaybe "" $ regexMatchValue rules record f group +replaceRegexGroupReference :: CsvRules -> CsvRecord -> MatchGroupReference -> Text +replaceRegexGroupReference rules record s = case T.uncons s of + Just ('\\', group) -> fromMaybe "" $ regexMatchValue rules record group _ -> s -regexMatchValue :: CsvRules -> CsvRecord -> HledgerFieldName -> Text -> Maybe Text -regexMatchValue rules record f sgroup = let +regexMatchValue :: CsvRules -> CsvRecord -> Text -> Maybe Text +regexMatchValue rules record sgroup = let matchgroups = concatMap (getMatchGroups rules record) $ concatMap cbMatchers $ filter (isBlockActive rules record) @@ -1228,7 +1228,7 @@ getAmount rules record currency p1IsVirtual n = -- assignments to any of these field names with non-empty values assignments = [(f,a') | f <- fieldnames - , Just v <- [T.strip . renderTemplate rules record f <$> hledgerField rules record f] + , Just v <- [T.strip . renderTemplate rules record <$> hledgerField rules record f] , not $ T.null v -- XXX maybe ignore rule-generated values like "", "-", "$", "-$", "$-" ? cf CSV FORMAT -> "amount", "Setting amounts", , let a = parseAmount rules record currency v From 1424a1f2f16b28df85afe4f2bc52fe75e0d7b096 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Fri, 1 Mar 2024 17:58:28 +0000 Subject: [PATCH 08/10] ;cln:import: update some Haddock strings to reflect #2158 Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index dd6bdecc6..1995a2978 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -715,7 +715,7 @@ hledgerField rules record f = fmap (getEffectiveAssignment rules record f) -- | Look up the final value assigned to a hledger field, with csv field --- references interpolated. +-- references and regular expression match group references interpolated. hledgerFieldValue rules record f = (flip fmap) (getEffectiveAssignment rules record f) $ either (renderTemplate rules record) $ \cb -> let @@ -730,9 +730,10 @@ maybeNegate :: MatcherPrefix -> Bool -> Bool maybeNegate Not origbool = not origbool maybeNegate _ origbool = origbool --- | Given the conversion rules, a CSV record and a hledger field name, find --- the value template ultimately assigned to this field, if any, by a field --- assignment at top level or in a conditional block matching this record. +-- | Given the conversion rules, a CSV record and a hledger field name, collect +-- the value templates (and their parent Conditional Blocks where applicable) +-- assigned to this field, if any, by top-level field assignments and +-- conditional blocks matching this record. -- -- Note conditional blocks' patterns are matched against an approximation of the -- CSV record: all the field values, without enclosing quotes, comma-separated. @@ -748,7 +749,7 @@ getEffectiveAssignment rules record f = lastMay assignments assignments = dbg9 "csv assignments" $ toplevelassignments ++ conditionalassignments -- all top level field assignments toplevelassignments = map (Left . snd) $ filter ((==f).fst) $ rassignments rules - -- all field assignments in conditional blocks assigning to field f and active for the current csv record + -- all conditional blocks assigning to field f and active for the current csv record conditionalassignments = map Right $ filter (any (==f) . map fst . cbAssignments) $ filter (isBlockActive rules record) From c5079d4f1e02a2a3ceb1a06a15531c8a714c9993 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Fri, 1 Mar 2024 18:02:29 +0000 Subject: [PATCH 09/10] dev:import: call hledgerFieldValue rather than re-implementing it Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index 1995a2978..d75962e50 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -716,6 +716,7 @@ hledgerField rules record f = fmap -- | Look up the final value assigned to a hledger field, with csv field -- references and regular expression match group references interpolated. +hledgerFieldValue :: CsvRules -> CsvRecord -> HledgerFieldName -> Maybe Text hledgerFieldValue rules record f = (flip fmap) (getEffectiveAssignment rules record f) $ either (renderTemplate rules record) $ \cb -> let @@ -1229,7 +1230,7 @@ getAmount rules record currency p1IsVirtual n = -- assignments to any of these field names with non-empty values assignments = [(f,a') | f <- fieldnames - , Just v <- [T.strip . renderTemplate rules record <$> hledgerField rules record f] + , Just v <- [T.strip <$> hledgerFieldValue rules record f] , not $ T.null v -- XXX maybe ignore rule-generated values like "", "-", "$", "-$", "$-" ? cf CSV FORMAT -> "amount", "Setting amounts", , let a = parseAmount rules record currency v From 3b416a76ef0d332baf0ffb9af94c6deab6f37495 Mon Sep 17 00:00:00 2001 From: Jonathan Dowland Date: Sat, 2 Mar 2024 20:56:35 +0000 Subject: [PATCH 10/10] ;cln:import: clarify haddock for getEffectiveAssignment Signed-off-by: Jonathan Dowland --- hledger-lib/Hledger/Read/RulesReader.hs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index d75962e50..4e88d5444 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -731,10 +731,9 @@ maybeNegate :: MatcherPrefix -> Bool -> Bool maybeNegate Not origbool = not origbool maybeNegate _ origbool = origbool --- | Given the conversion rules, a CSV record and a hledger field name, collect --- the value templates (and their parent Conditional Blocks where applicable) --- assigned to this field, if any, by top-level field assignments and --- conditional blocks matching this record. +-- | Given the conversion rules, a CSV record and a hledger field name, find +-- either the last applicable `ConditionalBlock`, or the final value template +-- assigned to this field by a top-level field assignment, if any exist. -- -- Note conditional blocks' patterns are matched against an approximation of the -- CSV record: all the field values, without enclosing quotes, comma-separated.