diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,3 +1,4 @@
+Copyright (c)2024, Daniel Vianna
 Copyright (c)2013, Ozgun Ataman
 Copyright (c)2012, Johan Tibell
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,7 @@
-# README [![Build Status](https://travis-ci.org/ozataman/csv-conduit.svg?branch=master)](https://travis-ci.org/ozataman/csv-conduit)
+# README
+[![cabal
+build](https://github.com/ozataman/csv-conduit/actions/workflows/cabal.yml/badge.svg)](https://github.com/ozataman/csv-conduit/actions)
+[![stack build](https://github.com/ozataman/csv-conduit/actions/workflows/stack.yml/badge.svg)](https://github.com/ozataman/csv-conduit/actions)
 
 ## CSV Files and Haskell
 
@@ -50,7 +53,7 @@
 - Dmitry Dzhus (@dzhus)
 - Niklas Hambüchen (@nh2)
 - Facundo Domínguez (@facundominguez)
-
+- Daniel Vianna (@dmvianna)
 
 ### Introduction
 
@@ -90,9 +93,9 @@
 myProcessor = CL.map reverse
 
 test :: IO ()
-test = runResourceT $ 
-  transformCSV defCSVSettings 
-               (sourceFile "input.csv") 
+test = runResourceT $
+  transformCSV defCSVSettings
+               (sourceFile "input.csv")
                myProcessor
                (sinkFile "output.csv")
 ```
@@ -113,11 +116,10 @@
 -- Let's simply stream from a file, parse the CSV, reserialize it
 -- and push back into another file.
 test :: IO ()
-test = runResourceT $ 
-  sourceFile "test/BigFile.csv" $= 
+test = runResourceT $
+  sourceFile "test/BigFile.csv" $=
   intoCSV defCSVSettings $=
   myProcessor $=
   fromCSV defCSVSettings $$
   sinkFile "test/BigFileOut.csv"
 ```
-
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,27 @@
+1.0.1.1
+* Fix test suite to build with text 2.1.2 and ghc 9.12.2, resolving [#62](https://github.com/ozataman/csv-conduit/issues/62)
+
+1.0.1.0
+* Use ConduitT instead of ConduitM (prettier type inference with newer conduit imports)
+
+1.0.0.2
+* Fixed [#17](https://github.com/ozataman/csv-conduit/issues/17),
+  where CSV created with Excel in Mac OS failed to parse due to its
+  newline characters.
+
+1.0.0.1
+* Removed dependencies: mmorph, monad-control, mtl,
+  unordered-containers, primitive
+
+1.0.0.0
+* Removed `return` from the `Monad` instance for `Parser`, and
+  transfered its definition to `pure` in the `Applicative` instance of
+  `Parser`. This was necessary to support GHC 9.6.4.
+* Create new API to choose whether to handle empty CSV cells as empty
+  strings or NULLs.
+* Added imports that were removed from `Prelude` in GHC 9.6.4.
+* Bumped the default Stack resolver to LTS-22.20.
+
 0.7.3.0
 * Add ordered versions of named records for consistent, controllable header column ordering. [PR 44](https://github.com/ozataman/csv-conduit/pull/44)
 * Add support for GHC 9.0.1
diff --git a/csv-conduit.cabal b/csv-conduit.cabal
--- a/csv-conduit.cabal
+++ b/csv-conduit.cabal
@@ -1,27 +1,34 @@
-Name:                csv-conduit
-Version:             0.7.3.0
-Synopsis:            A flexible, fast, conduit-based CSV parser library for Haskell.
-Homepage:            http://github.com/ozataman/csv-conduit
-License:             BSD3
-License-file:        LICENSE
-Author:              Ozgun Ataman
-Maintainer:          Ozgun Ataman <ozataman@gmail.com>
-Category:            Data, Conduit, CSV, Text
-Build-type:          Simple
-Cabal-version:       >= 1.10
-Tested-with:         GHC == 9.0.1, GHC == 8.10.4, GHC == 8.8.4, GHC == 8.8.3, GHC == 8.6.5, GHC == 8.4.4, GHC == 8.2.2
-Description:
+name:               csv-conduit
+version:            1.0.1.1
+synopsis:
+  A flexible, fast, conduit-based CSV parser library for Haskell.
+
+homepage:           http://github.com/ozataman/csv-conduit
+license:            BSD3
+license-file:       LICENSE
+author:             Ozgun Ataman
+maintainer:         Daniel Vianna <dmvianna@gmail.com>
+category:           Data, Conduit, CSV, Text
+build-type:         Simple
+cabal-version:      >=1.10
+tested-with:
+  GHC ==8.2.2
+   || ==8.4.4
+   || ==8.6.5
+   || ==8.8.3
+   || ==8.8.4
+   || ==8.10.4
+   || ==9.0.1
+   || ==9.6.4
+
+description:
   CSV files are the de-facto standard in many situations involving data transfer,
   particularly when dealing with enterprise application or disparate database
   systems.
-
   .
-
   While there are a number of CSV libraries in Haskell, at the time of this
   project's start in 2010, there wasn't one that provided all of the following:
-
   .
-
   * Full flexibility in quote characters, separators, input/output
   .
   * Constant space operation
@@ -32,106 +39,94 @@
   .
   * Fast operation
   .
-
   This library is an attempt to close these gaps. Please note that
   this library started its life based on the enumerator package and
   has recently been ported to work with conduits instead. In the
   process, it has been greatly simplified thanks to the modular nature
   of the conduits library.
-
   .
-
   Following the port to conduits, the library has also gained the
   ability to parameterize on the stream type and work both with
   ByteString and Text.
-
   .
-
   For more documentation and examples, check out the README at:
   .
-
   <http://github.com/ozataman/csv-conduit>
   .
 
-
 extra-source-files:
-  README.md
   changelog.md
+  README.md
+  test/test-mac-excel.csv
+  test/test-windows-excel.csv
   test/test.csv
   test/Test.hs
+  test/test.xls
 
 flag lib-Werror
   default: False
-  manual: True
+  manual:  True
 
 library
   default-language: Haskell2010
   exposed-modules:
-      Data.CSV.Conduit
-      Data.CSV.Conduit.Types
-      Data.CSV.Conduit.Conversion
-      Data.CSV.Conduit.Parser.ByteString
-      Data.CSV.Conduit.Parser.Text
+    Data.CSV.Conduit
+    Data.CSV.Conduit.Conversion
+    Data.CSV.Conduit.Parser.ByteString
+    Data.CSV.Conduit.Parser.Text
+    Data.CSV.Conduit.Types
+
   other-modules:
-      Data.CSV.Conduit.Conversion.Internal
-      Data.CSV.Conduit.Monoid
-  ghc-options: -Wall -funbox-strict-fields
-  if flag(lib-Werror)
+    Data.CSV.Conduit.Conversion.Internal
+    Data.CSV.Conduit.Monoid
+
+  ghc-options:      -Wall -funbox-strict-fields
+
+  if flag(lib-werror)
     ghc-options: -Werror
-  hs-source-dirs: src
+
+  hs-source-dirs:   src
   build-depends:
-      attoparsec             >= 0.10
-    , base                   >= 4 && < 5
+      array
+    , attoparsec          >=0.10
+    , base                >=4       && <5
+    , blaze-builder
     , bytestring
-    , conduit                >= 1.2.8
+    , conduit             >=1.3.0   && <2.0
     , conduit-extra
-    , containers             >= 0.3
-    , exceptions             >= 0.3
-    , monad-control
-    , text
+    , containers          >=0.3
     , data-default
-    , vector
-    , array
-    , blaze-builder
-    , unordered-containers
+    , exceptions          >=0.3
     , ordered-containers
-    , transformers
-    , mtl
-    , mmorph
     , primitive
-    , resourcet              >= 1.1.2.1
-    , semigroups
-
-  if impl(ghc >= 7.2.1)
-    cpp-options: -DGENERICS
-    build-depends: ghc-prim >= 0.2
-
+    , resourcet           >=1.1.2.1
+    , text
+    , transformers
+    , vector
 
 test-suite test
   default-language: Haskell2010
-  type: exitcode-stdio-1.0
-  main-is: Test.hs
-  ghc-options: -Wall
-  if flag(lib-Werror)
+  type:             exitcode-stdio-1.0
+  main-is:          Test.hs
+  ghc-options:      -Wall -Wunused-packages
+
+  if flag(lib-werror)
     ghc-options: -Werror
-  hs-source-dirs: test
+
+  hs-source-dirs:   test
   build-depends:
-      base >= 4 && < 5
+      base                  >=4     && <5
     , bytestring
-    , conduit >= 1.3.0
-    , containers >= 0.3
+    , conduit               >=1.3.0
+    , containers            >=0.3
     , csv-conduit
     , directory
-    , vector
-    , HUnit >= 1.2
+    , HUnit                 >=1.2
+    , ordered-containers
     , test-framework
     , test-framework-hunit
     , text
-    , ordered-containers
-    , transformers
-    , mtl
-    , primitive
-
+    , vector
 
 source-repository head
   type:     git
diff --git a/src/Data/CSV/Conduit.hs b/src/Data/CSV/Conduit.hs
--- a/src/Data/CSV/Conduit.hs
+++ b/src/Data/CSV/Conduit.hs
@@ -6,7 +6,6 @@
 {-# LANGUAGE OverloadedStrings     #-}
 {-# LANGUAGE RankNTypes            #-}
 {-# LANGUAGE ScopedTypeVariables   #-}
-{-# LANGUAGE TypeSynonymInstances  #-}
 {-# LANGUAGE UndecidableInstances  #-}
 
 module Data.CSV.Conduit
@@ -36,11 +35,12 @@
 
 -------------------------------------------------------------------------------
 import           Control.Exception
-import           Control.Monad.Catch.Pure           (CatchT)
-import           Control.Monad.Catch.Pure           (runCatchT)
-import           Control.Monad.Except
+import           Control.Monad.Catch.Pure           (runCatchT, CatchT)
+import           Control.Monad.IO.Class             (MonadIO (liftIO))
 import           Control.Monad.Primitive
 import           Control.Monad.ST
+import           Control.Monad.Trans.Class          (MonadTrans(lift))
+import           Control.Monad.Trans.Except         (ExceptT(..), runExceptT)
 import           Control.Monad.Trans.Resource       (MonadResource, MonadThrow,
                                                      runResourceT)
 import           Data.Attoparsec.Types              (Parser)
@@ -135,13 +135,13 @@
   -----------------------------------------------------------------------------
   -- | Turn a stream of 's' into a stream of CSV row type. An example
   -- would be parsing a ByteString stream as rows of 'MapRow' 'Text'.
-  intoCSV :: (MonadThrow m) => CSVSettings -> ConduitM s r m ()
+  intoCSV :: (MonadThrow m) => CSVSettings -> ConduitT s r m ()
 
   -----------------------------------------------------------------------------
   -- | Turn a stream of CSV row type back into a stream of 's'. An
   -- example would be rendering a stream of 'Row' 'ByteString' rows as
   -- 'Text'.
-  fromCSV :: Monad m => CSVSettings -> ConduitM r s m ()
+  fromCSV :: Monad m => CSVSettings -> ConduitT r s m ()
 
 
 
@@ -153,9 +153,12 @@
   rowToStr s !r =
     let
       sep = B.pack [c2w (csvSep s)]
-      wrapField !f = case csvQuoteChar s of
-        Just !x-> (x `B8.cons` escape x f) `B8.snoc` x
-        _      -> f
+      wrapField !f = case csvQuoteCharAndStyle s of
+        Just (x, quoteEmpty) ->
+          case quoteEmpty == DoQuoteEmpty || B8.length f /= 0 of
+            True -> (x `B8.cons` escape x f) `B8.snoc` x
+            False -> f
+        Nothing   -> f
       escape c str = B8.intercalate (B8.pack [c,c]) $ B8.split c str
     in B.intercalate sep . map wrapField $ r
 
@@ -169,9 +172,11 @@
   rowToStr s !r =
     let
       sep = T.pack [csvSep s]
-      wrapField !f = case csvQuoteChar s of
-        Just !x-> x `T.cons` escape x f `T.snoc` x
-        _      -> f
+      wrapField !f = case csvQuoteCharAndStyle s of
+        Just (x, quoteEmpty) -> case quoteEmpty == DoQuoteEmpty || not (T.null f) of
+          True -> x `T.cons` escape x f `T.snoc` x
+          False -> f
+        Nothing -> f
       escape c str = T.intercalate (T.pack [c,c]) $ T.split (== c) str
     in T.intercalate sep . map wrapField $ r
 
@@ -208,13 +213,13 @@
 
 -------------------------------------------------------------------------------
 fromCSVRow :: (Monad m, IsString s, CSV s r)
-           => CSVSettings -> ConduitM r s m ()
+           => CSVSettings -> ConduitT r s m ()
 fromCSVRow set = awaitForever $ \row -> mapM_ yield [rowToStr set row, "\n"]
 
 
 
 -------------------------------------------------------------------------------
-intoCSVRow :: (MonadThrow m, AttoparsecInput i) => Parser i (Maybe o) -> ConduitM i o m ()
+intoCSVRow :: (MonadThrow m, AttoparsecInput i) => Parser i (Maybe o) -> ConduitT i o m ()
 intoCSVRow p = parse .| puller
   where
     parse = {-# SCC "conduitParser_p" #-} conduitParser p
@@ -238,7 +243,7 @@
 
 -------------------------------------------------------------------------------
 intoCSVMap :: (Ord a, MonadThrow m, CSV s [a])
-           => CSVSettings -> ConduitM s (MapRow a) m ()
+           => CSVSettings -> ConduitT s (MapRow a) m ()
 intoCSVMap set = intoCSV set .| (headers >>= converter)
   where
     headers = do
@@ -293,7 +298,7 @@
 
 -------------------------------------------------------------------------------
 fromCSVMap :: (Monad m, IsString s, CSV s [a])
-           => CSVSettings -> ConduitM (M.Map k a) s m ()
+           => CSVSettings -> ConduitT (M.Map k a) s m ()
 fromCSVMap set = awaitForever push
   where
     push r = mapM_ yield [rowToStr set (M.elems r), "\n"]
@@ -316,7 +321,7 @@
 writeHeaders
     :: (Monad m, CSV s (Row r), IsString s)
     => CSVSettings
-    -> ConduitM (MapRow r) s m ()
+    -> ConduitT (MapRow r) s m ()
 writeHeaders set = do
   mrow <- await
   case mrow of
@@ -375,14 +380,14 @@
     -> Either SomeException (v a)
 decodeCSV set bs = runST $ runExceptT pipeline
   where
-    src :: ConduitM () s (ExceptT SomeException (ST s1)) ()
+    src :: ConduitT () s (ExceptT SomeException (ST s1)) ()
     src = C.sourceList [bs]
-    csvConvert :: ConduitM s a (ExceptT SomeException (ST s1)) ()
+    csvConvert :: ConduitT s a (ExceptT SomeException (ST s1)) ()
     csvConvert = transPipe (ExceptT . runCatchT) csvConvert'
-    csvConvert' :: ConduitM s a (CatchT (ST s1)) ()
+    csvConvert' :: ConduitT s a (CatchT (ST s1)) ()
     csvConvert' = intoCSV set
     growthFactor = 10
-    sink :: ConduitM a Void.Void (ExceptT SomeException (ST s1)) (v a)
+    sink :: ConduitT a Void.Void (ExceptT SomeException (ST s1)) (v a)
     sink = sinkVector growthFactor
     pipeline :: ExceptT SomeException (ST s1) (v a)
     pipeline = runConduit (src .| csvConvert .| sink)
@@ -442,11 +447,11 @@
     :: (MonadThrow m, CSV s a, CSV s' b)
     => CSVSettings
     -- ^ Settings to be used for both input and output
-    -> ConduitM () s m ()
+    -> ConduitT () s m ()
     -- ^ A raw stream data source. Ex: 'sourceFile inFile'
-    -> ConduitM a b m ()
+    -> ConduitT a b m ()
     -- ^ A transforming conduit
-    -> ConduitM s' Void.Void m ()
+    -> ConduitT s' Void.Void m ()
     -- ^ A raw stream data sink. Ex: 'sinkFile outFile'
     -> m ()
 transformCSV set = transformCSV' set set
@@ -470,11 +475,11 @@
     -- ^ Settings to be used for input
     -> CSVSettings
     -- ^ Settings to be used for output
-    -> ConduitM () s m ()
+    -> ConduitT () s m ()
     -- ^ A raw stream data source. Ex: 'sourceFile inFile'
-    -> ConduitM a b m ()
+    -> ConduitT a b m ()
     -- ^ A transforming conduit
-    -> ConduitM s' Void.Void m ()
+    -> ConduitT s' Void.Void m ()
     -- ^ A raw stream data sink. Ex: 'sinkFile outFile'
     -> m ()
 transformCSV' setIn setOut source c sink = runConduit $
@@ -495,7 +500,7 @@
 
 -------------------------------------------------------------------------------
 -- | An efficient sink that incrementally grows a vector from the input stream
-sinkVector :: (PrimMonad m, GV.Vector v a) => Int -> ConduitM a o m (v a)
+sinkVector :: (PrimMonad m, GV.Vector v a) => Int -> ConduitT a o m (v a)
 sinkVector by = do
     v <- lift $ GMV.new by
     go 0 v
diff --git a/src/Data/CSV/Conduit/Conversion.hs b/src/Data/CSV/Conduit/Conversion.hs
--- a/src/Data/CSV/Conduit/Conversion.hs
+++ b/src/Data/CSV/Conduit/Conversion.hs
@@ -68,7 +68,6 @@
 import qualified Data.ByteString.Char8 as B8
 import qualified Data.ByteString.Lazy as L
 import Data.Int (Int8, Int16, Int32, Int64)
-import Data.Kind (Type)
 import qualified Data.Map as M
 import qualified Data.Map.Ordered as MO
 import Data.Semigroup as Semigroup
@@ -160,7 +159,7 @@
 -- >         | otherwise     = mzero
 class FromRecord a where
     parseRecord :: Record -> Parser a
-  
+
 #ifdef GENERICS
     default parseRecord :: (Generic a, GFromRecord (Rep a)) => Record -> Parser a
     parseRecord r = to A.<$> gparseRecord r
@@ -778,8 +777,6 @@
     m >>= g = Parser $ \kf ks -> let ks' a = unParser (g a) kf ks
                                  in unParser m kf ks'
     {-# INLINE (>>=) #-}
-    return a = Parser $ \_kf ks -> ks a
-    {-# INLINE return #-}
 
 #if MIN_VERSION_base(4,13,0)
 instance MonadFail Parser where
@@ -794,10 +791,11 @@
     {-# INLINE fmap #-}
 
 instance Applicative Parser where
-    pure  = return
-    {-# INLINE pure #-}
+
     (<*>) = apP
     {-# INLINE (<*>) #-}
+    pure a = Parser $ \_kf ks -> ks a
+    {-# INLINE pure #-}
 
 instance Alternative Parser where
     empty = fail "empty"
@@ -842,9 +840,9 @@
     gparseRecord :: Record -> Parser (f p)
 
 instance GFromRecordSum f Record => GFromRecord (M1 i n f) where
-    gparseRecord v = 
+    gparseRecord v =
         case (IM.lookup n gparseRecordSum) of
-            Nothing -> lengthMismatch n v 
+            Nothing -> lengthMismatch n v
             Just p -> M1 <$> p v
       where
         n = V.length v
@@ -853,15 +851,15 @@
     gparseNamedRecord :: NamedRecord -> Parser (f p)
 
 instance GFromRecordSum f NamedRecord => GFromNamedRecord (M1 i n f) where
-    gparseNamedRecord v = 
+    gparseNamedRecord v =
         foldr (\f p -> p <|> M1 <$> f v) empty (IM.elems gparseRecordSum)
 
 class GFromRecordSum f r where
     gparseRecordSum :: IM.IntMap (r -> Parser (f p))
 
 instance (GFromRecordSum a r, GFromRecordSum b r) => GFromRecordSum (a :+: b) r where
-    gparseRecordSum = 
-        IM.unionWith (\a b r -> a r <|> b r) 
+    gparseRecordSum =
+        IM.unionWith (\a b r -> a r <|> b r)
             (fmap (L1 <$>) <$> gparseRecordSum)
             (fmap (R1 <$>) <$> gparseRecordSum)
 
diff --git a/src/Data/CSV/Conduit/Parser/ByteString.hs b/src/Data/CSV/Conduit/Parser/ByteString.hs
--- a/src/Data/CSV/Conduit/Parser/ByteString.hs
+++ b/src/Data/CSV/Conduit/Parser/ByteString.hs
@@ -58,15 +58,17 @@
 row :: CSVSettings -> Parser (Maybe (Row ByteString))
 row csvs = csvrow csvs <|> badrow
 
+csvEndOfLine :: Parser ()
+csvEndOfLine = (word8 10 >> return ()) <|> ((word8 13 *> word8 10) >> return ()) <|> (word8 13 >> return ())
 
 badrow :: Parser (Maybe (Row ByteString))
 badrow = P.takeWhile (not . C8.isEndOfLine) *>
-         (C8.endOfLine <|> C8.endOfInput) *> return Nothing
+         (csvEndOfLine <|> C8.endOfInput) *> return Nothing
 
 csvrow :: CSVSettings -> Parser (Maybe (Row ByteString))
 csvrow c =
   let rowbody = (quotedField' <|> field c) `sepBy` C8.char (csvSep c)
-      properrow = rowbody <* (C8.endOfLine <|> P.endOfInput)
+      properrow = rowbody <* (csvEndOfLine <|> P.endOfInput)
       quotedField' = case csvQuoteChar c of
           Nothing -> mzero
           Just q' -> try (quotedField q')
@@ -93,5 +95,3 @@
   f <- many (C8.notChar c <|> quoted)
   _ <- C8.char c
   return $ B8.pack f
-
-
diff --git a/src/Data/CSV/Conduit/Parser/Text.hs b/src/Data/CSV/Conduit/Parser/Text.hs
--- a/src/Data/CSV/Conduit/Parser/Text.hs
+++ b/src/Data/CSV/Conduit/Parser/Text.hs
@@ -58,15 +58,17 @@
 row :: CSVSettings -> Parser (Maybe (Row Text))
 row csvs = csvrow csvs <|> badrow
 
+csvEndOfLine :: Parser ()
+csvEndOfLine = (char '\n' >> return ()) <|> (string (T.pack "\r\n") >> return ()) <|> (char '\r' >> return ())
 
 badrow :: Parser (Maybe (Row Text))
 badrow = P.takeWhile (not . T.isEndOfLine) *>
-         (T.endOfLine <|> T.endOfInput) *> return Nothing
+         (csvEndOfLine <|> T.endOfInput) *> return Nothing
 
 csvrow :: CSVSettings -> Parser (Maybe (Row Text))
 csvrow c =
   let rowbody = (quotedField' <|> field c) `sepBy` T.char (csvSep c)
-      properrow = rowbody <* (T.endOfLine <|> P.endOfInput)
+      properrow = rowbody <* (csvEndOfLine <|> P.endOfInput)
       quotedField' = case csvQuoteChar c of
           Nothing -> mzero
           Just q' -> try (quotedField q')
diff --git a/src/Data/CSV/Conduit/Types.hs b/src/Data/CSV/Conduit/Types.hs
--- a/src/Data/CSV/Conduit/Types.hs
+++ b/src/Data/CSV/Conduit/Types.hs
@@ -9,6 +9,7 @@
 import qualified Data.Map.Ordered as MO
 -------------------------------------------------------------------------------
 
+data QuoteEmpty = DoQuoteEmpty | DontQuoteEmpty deriving (Show, Eq)
 
 -------------------------------------------------------------------------------
 -- | Settings for a CSV file. This library is intended to be flexible
@@ -22,10 +23,12 @@
     -- | Quote character that may sometimes be present around fields.
     -- If 'Nothing' is given, the library will never expect quotation
     -- even if it is present.
-  , csvQuoteChar :: !(Maybe Char)
-  } deriving (Read, Show, Eq)
+  , csvQuoteCharAndStyle :: !(Maybe (Char, QuoteEmpty))
+  } deriving (Show, Eq)
 
 
+csvQuoteChar :: CSVSettings -> Maybe Char
+csvQuoteChar = (fst <$>) . csvQuoteCharAndStyle
 
 -------------------------------------------------------------------------------
 -- | Default settings for a CSV file.
@@ -36,9 +39,14 @@
 defCSVSettings :: CSVSettings
 defCSVSettings = CSVSettings
   { csvSep = ','
-  , csvQuoteChar = Just '"'
+  , csvQuoteCharAndStyle = Just ('"', DoQuoteEmpty)
   }
 
+defDontQuoteEmptyCSVSettings :: CSVSettings
+defDontQuoteEmptyCSVSettings = CSVSettings
+  { csvSep = ','
+  , csvQuoteCharAndStyle = Just ('"', DontQuoteEmpty)
+  }
 
 instance Default CSVSettings where
     def = defCSVSettings
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -9,10 +9,11 @@
 import qualified Data.ByteString.Char8 as B
 import Data.CSV.Conduit
 import Data.CSV.Conduit.Conversion
+import Data.CSV.Conduit.Types
 import qualified Data.Map as Map
 import qualified Data.Map.Ordered as OMap
 import Data.Monoid as M
-import Data.Text
+import Data.Text (Text)
 import qualified Data.Vector as V
 import System.Directory
 import Test.Framework (Test, defaultMain, testGroup)
@@ -31,7 +32,10 @@
 baseTests :: [Test]
 baseTests =
   [ testCase "mapping with id works" test_identityMap,
-    testCase "simple parsing works" test_simpleParse,
+    testCase "simple parsing works" (test_simpleParse testFile1),
+    testCase "simple parsing works for Mac-Excel" (test_simpleParse testFile3),
+    testCase "simple parsing works for Windows-Excel" (test_simpleParse testFile4),
+    testCase "fails parsing gracefully" test_parseFail,
     testCase "OrderedMap" test_orderedMap
   ]
 
@@ -73,9 +77,9 @@
     f :: Row Text -> [Row Text]
     f = return
 
-test_simpleParse :: IO ()
-test_simpleParse = do
-  (d :: V.Vector (MapRow B.ByteString)) <- readCSVFile csvSettings testFile1
+test_simpleParse :: FilePath -> IO ()
+test_simpleParse fp = do
+  (d :: V.Vector (MapRow B.ByteString)) <- readCSVFile csvSettings fp
   V.mapM_ assertRow d
   where
     assertRow r = v3 @=? (v1 + v2)
@@ -84,6 +88,20 @@
         v2 = readBS $ r Map.! "Col3"
         v3 = readBS $ r Map.! "Sum"
 
+test_parseFail :: IO ()
+test_parseFail = do
+  (d :: V.Vector (MapRow B.ByteString)) <- readCSVFile csvSettings testXLS
+  errored <- catch (V.mapM_ assertRow d >> pure False) handler
+  if errored then pure () else assertFailure "readCSVFile shouldn't read XLS"
+  where
+    handler :: ErrorCall -> IO Bool
+    handler _ = pure True
+    assertRow r = v3 @=? (v1 + v2)
+      where
+        v1 = readBS $ r Map.! "Col2"
+        v2 = readBS $ r Map.! "Col3"
+        v3 = readBS $ r Map.! "Sum"
+
 test_orderedMap :: IO ()
 test_orderedMap = do
   unorderedRes <-
@@ -106,11 +124,16 @@
     pairs = [("b", "bval"), ("a", "aval")]
 
 csvSettings :: CSVSettings
-csvSettings = defCSVSettings {csvQuoteChar = Just '`'}
+csvSettings = defCSVSettings {csvQuoteCharAndStyle = Just ('`', DontQuoteEmpty)}
 
-testFile1, testFile2 :: FilePath
+testFile1, testFile2, testFile3, testFile4 :: FilePath
 testFile1 = "test/test.csv"
 testFile2 = "test/test.csv"
+testFile3 = "test/test-mac-excel.csv"
+testFile4 = "test/test-windows-excel.csv"
+
+testXLS :: FilePath
+testXLS = "test/test.xls"
 
 readBS :: B.ByteString -> Int
 readBS = read . B.unpack
diff --git a/test/test-mac-excel.csv b/test/test-mac-excel.csv
new file mode 100644
--- /dev/null
+++ b/test/test-mac-excel.csv
@@ -0,0 +1,1 @@
+`Col1`,`Col2`,`Col3`,`Sum``A`,`2`,`3`,`5``B`,`3`,`4`,`7``Field using the quote char ``this is the in-quoted value```,`4`,`5`,`9`
diff --git a/test/test-windows-excel.csv b/test/test-windows-excel.csv
new file mode 100644
--- /dev/null
+++ b/test/test-windows-excel.csv
@@ -0,0 +1,4 @@
+Col1,Col2,Col3,Sum
+A,2,3,5
+B,3,4,7
+"Field using the quote char ""this is the in-quoted value""",4,5,9
diff --git a/test/test.xls b/test/test.xls
new file mode 100644
Binary files /dev/null and b/test/test.xls differ
