diff --git a/hledger-lib/Hledger/Read/RulesReader.hs b/hledger-lib/Hledger/Read/RulesReader.hs index 4e88d5444..3ba82bbb9 100644 --- a/hledger-lib/Hledger/Read/RulesReader.hs +++ b/hledger-lib/Hledger/Read/RulesReader.hs @@ -600,8 +600,9 @@ conditionalblockp = do "conditional block" -- A conditional table: "if" followed by separator, followed by some field names, --- followed by many lines, each of which has: --- one matchers, followed by field assignments (as many as there were fields) +-- followed by many lines, each of which is either: +-- a comment line, or ... +-- one matcher, followed by field assignments (as many as there were fields in the header) conditionaltablep :: CsvRulesParser [ConditionalBlock] conditionaltablep = do lift $ dbgparse 8 "trying conditionaltablep" @@ -610,18 +611,25 @@ conditionaltablep = do sep <- lift $ satisfy (\c -> not (isAlphaNum c || isSpace c)) fields <- journalfieldnamep `sepBy1` (char sep) newline - body <- flip manyTill (lift eolof) $ do - off <- getOffset - m <- matcherp' $ void $ char sep - vs <- T.split (==sep) . T.pack <$> lift restofline - if (length vs /= length fields) - then customFailure $ parseErrorAt off $ ((printf "line of conditional table should have %d values, but this one has only %d" (length fields) (length vs)) :: String) - else return (m,vs) + body <- catMaybes <$> (flip manyTill (lift eolof) $ + choice [ commentlinep >> return Nothing + , fmap Just $ bodylinep sep fields + ]) when (null body) $ customFailure $ parseErrorAt start $ "start of conditional table found, but no assignment rules afterward" return $ flip map body $ \(m,vs) -> CB{cbMatchers=[m], cbAssignments=zip fields vs} "conditional table" + where + bodylinep :: Char -> [Text] -> CsvRulesParser (Matcher,[FieldTemplate]) + bodylinep sep fields = do + off <- getOffset + m <- matcherp' $ void $ char sep + vs <- T.split (==sep) . T.pack <$> lift restofline + if (length vs /= length fields) + then customFailure $ parseErrorAt off $ ((printf "line of conditional table should have %d values, but this one has only %d" (length fields) (length vs)) :: String) + else return (m,vs) + -- A single matcher, on one line. matcherp' :: CsvRulesParser () -> CsvRulesParser Matcher diff --git a/hledger/test/csv.test b/hledger/test/csv.test index 905fcfe44..efe369eba 100644 --- a/hledger/test/csv.test +++ b/hledger/test/csv.test @@ -1144,6 +1144,33 @@ $ ./ssvtest.sh >= +# ** 60. tabular rules with comments +< +10/2009/09,Flubber Co,50 +10/2009/09,Blubber Co,150 + +RULES +fields date, description, amount +date-format %d/%Y/%m +currency $ +account1 assets:myacct +if|account2|comment +; This rule is for Flubber +%description Flubber|acct| +; This rule is not for Flubber +%amount 150|acct2|cmt2 +; commented out: %description Flubber|acct3| +$ ./csvtest.sh +2009-09-10 Flubber Co + assets:myacct $50 + acct $-50 + +2009-09-10 Blubber Co ; cmt2 + assets:myacct $150 + acct2 $-150 + +>=0 + # ** . #< #$ ./csvtest.sh