csv reader: add the include directive, useful for factoring out common rules used with multiple CSV files
This commit is contained in:
parent
308916185c
commit
eff1d3f1a5
@ -549,8 +549,12 @@ The following kinds of rule can appear in any order:
|
||||
%-m/%-d/%Y
|
||||
%Y-%h-%d
|
||||
|
||||
**include** *RULESFILE*
|
||||
: Include another rules file at this point. Useful for common rules shared across multiple CSV files.
|
||||
|
||||
Typically you'll keep one rules file for each account which you
|
||||
download as CSV. For an example, see [How to read CSV files](CSV.html).
|
||||
download as CSV. For an example, see [How to read CSV
|
||||
files](CSV.html).
|
||||
|
||||
Other notes:
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ import Control.Exception hiding (try)
|
||||
import Control.Monad
|
||||
import Control.Monad.Error
|
||||
-- import Test.HUnit
|
||||
import Data.Char (toLower, isDigit)
|
||||
import Data.Char (toLower, isDigit, isSpace)
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Data.Ord
|
||||
@ -319,7 +319,7 @@ getDirective directivename = lookup directivename . rdirectives
|
||||
|
||||
parseRulesFile :: FilePath -> IO (Either ParseError CsvRules)
|
||||
parseRulesFile f = do
|
||||
s <- readFile' f
|
||||
s <- readFile' f >>= expandIncludes
|
||||
let rules = parseCsvRules f s
|
||||
return $ case rules of
|
||||
Left e -> Left e
|
||||
@ -329,6 +329,19 @@ parseRulesFile f = do
|
||||
where
|
||||
toParseError s = newErrorMessage (Message s) (initialPos "")
|
||||
|
||||
-- | Pre-parse csv rules to interpolate included files, recursively.
|
||||
-- This is a cheap hack to avoid rewriting the existing parser.
|
||||
expandIncludes :: String -> IO String
|
||||
expandIncludes s = do
|
||||
let (ls,rest) = break (isPrefixOf "include") $ lines s
|
||||
case rest of
|
||||
[] -> return $ unlines ls
|
||||
(('i':'n':'c':'l':'u':'d':'e':f):ls') -> do
|
||||
let f' = dropWhile isSpace f
|
||||
included <- readFile f' >>= expandIncludes
|
||||
return $ unlines [unlines ls, included, unlines ls']
|
||||
ls' -> return $ unlines $ ls ++ ls' -- should never get here
|
||||
|
||||
parseCsvRules :: FilePath -> String -> Either ParseError CsvRules
|
||||
-- parseCsvRules rulesfile s = runParser csvrulesfile nullrules{baseAccount=takeBaseName rulesfile} rulesfile s
|
||||
parseCsvRules rulesfile s =
|
||||
|
||||
Loading…
Reference in New Issue
Block a user