lib, doc: extended "skip" in "if" body to "skip N"

This commit is contained in:
Dmitry Astapov 2019-10-14 21:40:52 +01:00
parent f877a7789f
commit f1ab107400
3 changed files with 21 additions and 8 deletions

View File

@ -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

View File

@ -92,7 +92,7 @@ You'll need this whenever your CSV data contains header lines. Eg:
<!-- XXX -->
<!-- hledger tries to skip initial CSV header lines automatically. -->
<!-- If it guesses wrong, use this directive to skip exactly N lines. -->
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`*\
&nbsp;&nbsp;&nbsp;&nbsp;*`FIELDASSIGNMENTS or skip`*...
&nbsp;&nbsp;&nbsp;&nbsp;*`FIELDASSIGNMENTS or skip N`*...
`if`\
*`PATTERN`*\
*`PATTERN`*...\
&nbsp;&nbsp;&nbsp;&nbsp;*`FIELDASSIGNMENTS or skip`*...
&nbsp;&nbsp;&nbsp;&nbsp;*`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

View File

@ -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