The comma
package implements parsing and producing of the CSV format.
There are two standard ways of obtaining the module:
- by cloning the git repository:
git clone https://github.com/lovasko/comma
- by using the central Hackage server:
cabal install comma
Main part, the library itself, depends on two packages:
attoparsec
text
In addition, the testing component of the project depends on the QuickCheck
package.
The Text.Comma
module exports only two functions: comma
and uncomma
,
parsing and producing CSV respectively. The function prototypes are as follows:
-- | Parse a block of text into a CSV table.
comma :: T.Text -- ^ CSV text
-> Either String [[T.Text]] -- ^ error | table
-- | Render a table of texts into a valid CSV output.
uncomma :: [[T.Text]] -- ^ table
-> T.Text -- ^ CSV text
The following example loads any CSV file and prepends a column that contains row numbers:
{-# LANGUAGE OverloadedStrings #-}
import Text.Comma
import System.Exit
import qualified Data.Text as T
import qualified Data.Text.IO as T
-- | Prepend a number in front of each row.
number :: [[T.Text]] -> [[T.Text]]
number = zipWith (:) (map (T.pack . show) [0..])
main :: IO ()
main = T.readFile "table.csv" >>= (\file -> case comma file of
Left err -> T.putStrLn ("ERROR: " <> T.pack err) >> exitFailure
Right csv -> T.writeFile "table.csv" (uncomma $ number csv) >> exitSuccess)
Example usage:
$ cat table.csv
name,surname,language
Dennis,Ritchie,C
Larry,Wall,Perl
John,McCarthy,Lisp
$ ./number && cat table.csv
0,name,surname,language
1,Dennis,Ritchie,C
2,Larry,Wall,Perl
3,John,McCarthy,Lisp
Both producing and parsing of CSV files closely follows the
RFC4180 document. The comma
implementation has made the following decisions:
- record separator is always only
\n
('\r` is not recognized as a newline symbol) - it is not required for the last record to be trailed with a
\n
. This means thatcomma "hello\nworld" == comma "hello\nworld\n" == Right [["hello"], ["world"]]
The comma
package is licensed under the terms of the 2-clause BSD
license. In case you need any other license, feel free to contact the
author.
Daniel Lovasko [email protected]