summaryrefslogtreecommitdiff
path: root/src/CSV.hs
diff options
context:
space:
mode:
authorJed Barber <jjbarber@y7mail.com>2017-01-06 00:11:00 +1100
committerJed Barber <jjbarber@y7mail.com>2017-01-06 00:11:00 +1100
commited35d03fbdafce4d6d41d8731318304a8eb7ff61 (patch)
tree42a8fa732ae779a71db2561c93f63979cc4a5fe6 /src/CSV.hs
parenta13d9db820d7cb83e9472e2cf387eb22c26d402d (diff)
Ballot counting working, but results differ slightly from AEC counts
Diffstat (limited to 'src/CSV.hs')
-rw-r--r--src/CSV.hs59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/CSV.hs b/src/CSV.hs
new file mode 100644
index 0000000..ae2bbea
--- /dev/null
+++ b/src/CSV.hs
@@ -0,0 +1,59 @@
+{-# LANGUAGE FlexibleContexts #-}
+
+module CSV(
+ Settings(..),
+ specialChars,
+ defaultSettings,
+ parseRecord
+ ) where
+
+
+
+
+import Text.ParserCombinators.Parsec
+import Data.Char
+
+
+
+
+data Settings = Settings { separator :: Char
+ , quote :: Char
+ , escape :: Char }
+
+
+specialChars :: Settings -> String
+specialChars s = (separator s):(quote s):(escape s):[]
+
+
+defaultSettings = Settings { separator = ',', quote = '\"', escape = '\\' }
+
+
+
+
+parseRecord :: Settings -> String -> Either ParseError [String]
+parseRecord settings input =
+ parse (record settings) "error" input
+
+
+
+
+record s = do
+ f <- (field s) `sepBy` (char (separator s))
+ optional eol
+ eof
+ return f
+
+
+field s = many (try (quoted s) <|> many1 (fieldChar s)) >>= return . foldl1 (++)
+quoted s = between (char (quote s)) (char (quote s)) (many (quotedChar s))
+fieldChar s = allExcept s (specialChars s)
+quotedChar s = allExcept s [quote s]
+allExcept s c = try (escapeChar s) <|> satisfy (\x -> (not (isControl x)) && (x `notElem` c))
+escapeChar s = char (escape s) >> oneOf (specialChars s)
+
+
+eol = try (string "\r\n")
+ <|> try (string "\r")
+ <|> try (string "\n")
+ <?> "end of line"
+