{-# LANGUAGE FlexibleContexts    #-}

{-# LANGUAGE ScopedTypeVariables #-}
{- |
   Module      : Text.Pandoc.Readers.RST
   Copyright   : Copyright (C) 2006-2020 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable

Conversion from CSV to a 'Pandoc' table.
-}
module Text.Pandoc.Readers.CSV ( readCSV ) where
import Data.Text (Text)
import qualified Data.Text as T
import Text.Pandoc.CSV (parseCSV, defaultCSVOptions)
import Text.Pandoc.Definition
import qualified Text.Pandoc.Builder as B
import Text.Pandoc.Class (PandocMonad)
import Text.Pandoc.Shared (crFilter)
import Text.Pandoc.Error
import Text.Pandoc.Options (ReaderOptions)
import Control.Monad.Except (throwError)

readCSV :: PandocMonad m
        => ReaderOptions -- ^ Reader options
        -> Text          -- ^ Text to parse (assuming @'\n'@ line endings)
        -> m Pandoc
readCSV :: ReaderOptions -> Text -> m Pandoc
readCSV _opts :: ReaderOptions
_opts s :: Text
s =
  case CSVOptions -> Text -> Either ParseError [[Text]]
parseCSV CSVOptions
defaultCSVOptions (Text -> Text
crFilter Text
s) of
    Right (r :: [Text]
r:rs :: [[Text]]
rs) -> Pandoc -> m Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> m Pandoc) -> Pandoc -> m Pandoc
forall a b. (a -> b) -> a -> b
$ Blocks -> Pandoc
B.doc (Blocks -> Pandoc) -> Blocks -> Pandoc
forall a b. (a -> b) -> a -> b
$ Inlines
-> [(Alignment, Double)] -> [Blocks] -> [[Blocks]] -> Blocks
B.table Inlines
capt ([Alignment] -> [Double] -> [(Alignment, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Alignment]
aligns [Double]
widths) [Blocks]
hdrs [[Blocks]]
rows
       where capt :: Inlines
capt = Inlines
forall a. Monoid a => a
mempty
             numcols :: Int
numcols = [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
r
             toplain :: Text -> Blocks
toplain = Inlines -> Blocks
B.plain (Inlines -> Blocks) -> (Text -> Inlines) -> Text -> Blocks
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Inlines
B.text (Text -> Inlines) -> (Text -> Text) -> Text -> Inlines
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
T.strip
             hdrs :: [Blocks]
hdrs = (Text -> Blocks) -> [Text] -> [Blocks]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Blocks
toplain [Text]
r
             rows :: [[Blocks]]
rows = ([Text] -> [Blocks]) -> [[Text]] -> [[Blocks]]
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> Blocks) -> [Text] -> [Blocks]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Blocks
toplain) [[Text]]
rs
             aligns :: [Alignment]
aligns = Int -> Alignment -> [Alignment]
forall a. Int -> a -> [a]
replicate Int
numcols Alignment
AlignDefault
             widths :: [Double]
widths = Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate Int
numcols 0
    Right []     -> Pandoc -> m Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> m Pandoc) -> Pandoc -> m Pandoc
forall a b. (a -> b) -> a -> b
$ Blocks -> Pandoc
B.doc Blocks
forall a. Monoid a => a
mempty
    Left e :: ParseError
e       -> PandocError -> m Pandoc
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (PandocError -> m Pandoc) -> PandocError -> m Pandoc
forall a b. (a -> b) -> a -> b
$ Text -> ParseError -> PandocError
PandocParsecError Text
s ParseError
e