79: convert: add a skip-lines directive (Magnus Henoch)

This commit is contained in:
Simon Michael 2012-11-18 18:21:52 +00:00
parent 34baea6302
commit 8b4a99c4d5
3 changed files with 22 additions and 4 deletions

View File

@ -517,11 +517,13 @@ file with `--rules-file` (useful when reading from standard input).
An example - sample.csv: An example - sample.csv:
sample.csv: sample.csv:
"Date","Note","Amount"
"2012/3/22","TRANSFER TO SAVINGS","-10.00" "2012/3/22","TRANSFER TO SAVINGS","-10.00"
"2012/3/23","SOMETHING ELSE","5.50" "2012/3/23","SOMETHING ELSE","5.50"
sample.rules: sample.rules:
skip-lines 1
date-field 0 date-field 0
description-field 1 description-field 1
amount-field 2 amount-field 2
@ -632,6 +634,11 @@ results.)
> Which field contains the transaction cleared status (`*`). > Which field contains the transaction cleared status (`*`).
`skip-lines`
> How many lines to skip in the beginning of the file, e.g. to skip a
> line of column headings.
Account-assigning rules select an account to transfer to based on the Account-assigning rules select an account to transfer to based on the
description field (unless `account2-field` is used.) Each description field (unless `account2-field` is used.) Each
account-assigning rule is a paragraph consisting of one or more account-assigning rule is a paragraph consisting of one or more

View File

@ -203,7 +203,8 @@ data CsvRules = CsvRules {
account2Field :: Maybe FieldPosition, account2Field :: Maybe FieldPosition,
effectiveDateField :: Maybe FieldPosition, effectiveDateField :: Maybe FieldPosition,
baseAccount :: AccountName, baseAccount :: AccountName,
accountRules :: [AccountRule] accountRules :: [AccountRule],
skipLines :: Int
} deriving (Show, Eq) } deriving (Show, Eq)
type FieldPosition = Int type FieldPosition = Int

View File

@ -98,7 +98,8 @@ nullrules = CsvRules {
account2Field=Nothing, account2Field=Nothing,
effectiveDateField=Nothing, effectiveDateField=Nothing,
baseAccount="unknown", baseAccount="unknown",
accountRules=[] accountRules=[],
skipLines=0
} }
type CsvRecord = [String] type CsvRecord = [String]
@ -137,9 +138,10 @@ readJournalFromCsv mrulesfile csvfile csvdata =
rules <- liftM (either (throw.userError.show) id) $ parseCsvRulesFile rulesfile rules <- liftM (either (throw.userError.show) id) $ parseCsvRulesFile rulesfile
let requiredfields = (maxFieldIndex rules + 1) let requiredfields = (maxFieldIndex rules + 1)
badrecords = take 1 $ filter ((< requiredfields).length) records realrecords = drop (skipLines rules) records
badrecords = take 1 $ filter ((< requiredfields).length) realrecords
return $ case badrecords of return $ case badrecords of
[] -> Right nulljournal{jtxns=sortBy (comparing tdate) $ map (transactionFromCsvRecord rules) records} [] -> Right nulljournal{jtxns=sortBy (comparing tdate) $ map (transactionFromCsvRecord rules) realrecords}
(_:_) -> Left $ "Parse error: at least one CSV record does not contain a field referenced by the conversion rules file:\n"++(show $ head badrecords) (_:_) -> Left $ "Parse error: at least one CSV record does not contain a field referenced by the conversion rules file:\n"++(show $ head badrecords)
-- | Ensure there is a conversion rules file at the given path, creating a -- | Ensure there is a conversion rules file at the given path, creating a
@ -189,6 +191,7 @@ newRulesFileContent = let prognameandversion = "hledger" in
"# Add rules to this file for more accurate conversion, see\n"++ "# Add rules to this file for more accurate conversion, see\n"++
"# http://hledger.org/MANUAL.html#convert\n" ++ "# http://hledger.org/MANUAL.html#convert\n" ++
"\n" ++ "\n" ++
"skip-lines 0\n" ++
"base-account assets:bank:checking\n" ++ "base-account assets:bank:checking\n" ++
"date-field 0\n" ++ "date-field 0\n" ++
"description-field 4\n" ++ "description-field 4\n" ++
@ -251,6 +254,7 @@ definitions = do
,effectivedatefield ,effectivedatefield
,basecurrency ,basecurrency
,baseaccount ,baseaccount
,skiplines
,commentline ,commentline
] <?> "definition" ] <?> "definition"
return () return ()
@ -350,6 +354,12 @@ baseaccount = do
optional newline optional newline
updateState (\r -> r{baseAccount=v}) updateState (\r -> r{baseAccount=v})
skiplines = do
string "skip-lines"
many1 spacenonewline
v <- restofline
updateState (\r -> r{skipLines=read v})
accountrule :: GenParser Char CsvRules AccountRule accountrule :: GenParser Char CsvRules AccountRule
accountrule = do accountrule = do
many blankorcommentline many blankorcommentline