{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
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
-> Text
-> 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