diff --git a/hledger-lib/Hledger/Read/CsvReader.hs b/hledger-lib/Hledger/Read/CsvReader.hs index 2cf03517d..fccfbd8f7 100644 --- a/hledger-lib/Hledger/Read/CsvReader.hs +++ b/hledger-lib/Hledger/Read/CsvReader.hs @@ -218,10 +218,19 @@ printCSV records = unlined (printRecord `map` records) -- | Return the cleaned up and validated CSV data (can be empty), or an error. validateCsv :: CsvRules -> Int -> Either String CSV -> Either String [CsvRecord] validateCsv _ _ (Left err) = Left err -validateCsv rules numhdrlines (Right rs) = validate $ filter (not.shouldSkip) $ drop numhdrlines $ filternulls rs +validateCsv rules numhdrlines (Right rs) = validate $ applyConditionalSkips $ drop numhdrlines $ filternulls rs where filternulls = filter (/=[""]) - shouldSkip r = isJust $ getEffectiveAssignment rules r "skip" + skipCount r = + case getEffectiveAssignment rules r "skip" of + Nothing -> Nothing + Just "" -> Just 1 + Just x -> Just (read x) + applyConditionalSkips [] = [] + applyConditionalSkips (r:rest) = + case skipCount r of + Nothing -> r:(applyConditionalSkips rest) + Just cnt -> applyConditionalSkips (drop (cnt-1) rest) validate [] = Right [] validate rs@(_first:_) | isJust lessthan2 = let r = fromJust lessthan2 in diff --git a/hledger-lib/hledger_csv.m4.md b/hledger-lib/hledger_csv.m4.md index a3b131cc3..dee69ce7b 100644 --- a/hledger-lib/hledger_csv.m4.md +++ b/hledger-lib/hledger_csv.m4.md @@ -92,7 +92,7 @@ You'll need this whenever your CSV data contains header lines. Eg: -This can also be used in a conditional block (without numeric argument) to ignore certain CSV records. +This can also be used in a conditional block to ignore certain CSV records. ```rules # ignore the first CSV line skip 1 @@ -178,12 +178,12 @@ Note, interpolation strips any outer whitespace, so a CSV value like ## conditional block `if` *`PATTERN`*\ -    *`FIELDASSIGNMENTS or skip`*... +    *`FIELDASSIGNMENTS or skip N`*... `if`\ *`PATTERN`*\ *`PATTERN`*...\ -    *`FIELDASSIGNMENTS or skip`*... +    *`FIELDASSIGNMENTS or skip N`*... This applies one or more field assignments, only to those CSV records matched by one of the PATTERNs. The patterns are case-insensitive regular expressions which match anywhere @@ -192,7 +192,7 @@ specific field). When there are multiple patterns they can be written on separate lines, unindented. The field assignments are on separate lines indented by at least one space. -Instead of field assignments you can specify `skip` to skip the matching record. +Instead of field assignments you can specify `skip N` to skip the next N records (including the one that matchied). Examples: ```rules diff --git a/tests/csv.test b/tests/csv.test index a84f3a38f..b26df9f38 100644 --- a/tests/csv.test +++ b/tests/csv.test @@ -354,7 +354,9 @@ $ ./hledger-csv | hledger balance -f - --no-total < HEADER 10/2009/09,Flubber Co,50 -MIDDLE +MIDDLE SKIP THIS LINE +AND THIS +AND THIS ONE 10/2009/09,Flubber Co,50 *** END OF FILE *** RULES @@ -364,10 +366,12 @@ currency $ account1 assets:myacct if HEADER -MIDDLE END OF FILE skip +if MIDDLE + skip 3 + $ ./hledger-csv 2009/09/10 Flubber Co assets:myacct $50