{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Text.Pandoc.Readers.CSV ( readCSV ) where
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.Error
import Text.Pandoc.Sources (ToSources(..), sourcesToText)
import Text.Pandoc.Options (ReaderOptions)
import Control.Monad.Except (throwError)
readCSV :: (PandocMonad m, ToSources a)
=> ReaderOptions
-> a
-> m Pandoc
readCSV :: ReaderOptions -> a -> m Pandoc
readCSV ReaderOptions
_opts a
s = do
let txt :: Text
txt = Sources -> Text
sourcesToText (Sources -> Text) -> Sources -> Text
forall a b. (a -> b) -> a -> b
$ a -> Sources
forall a. ToSources a => a -> Sources
toSources a
s
case CSVOptions -> Text -> Either ParseError [[Text]]
parseCSV CSVOptions
defaultCSVOptions Text
txt of
Right ([Text]
r:[[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
$ Caption
-> [ColSpec] -> TableHead -> [TableBody] -> TableFoot -> Blocks
B.table Caption
capt
([Alignment] -> [ColWidth] -> [ColSpec]
forall a b. [a] -> [b] -> [(a, b)]
zip [Alignment]
aligns [ColWidth]
widths)
(Attr -> [Row] -> TableHead
TableHead Attr
nullAttr [Row]
hdrs)
[Attr -> RowHeadColumns -> [Row] -> [Row] -> TableBody
TableBody Attr
nullAttr RowHeadColumns
0 [] [Row]
rows]
(Attr -> [Row] -> TableFoot
TableFoot Attr
nullAttr [])
where capt :: Caption
capt = Caption
B.emptyCaption
numcols :: Int
numcols = [Text] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Text]
r
toplain :: Text -> Cell
toplain = Blocks -> Cell
B.simpleCell (Blocks -> Cell) -> (Text -> Blocks) -> Text -> Cell
forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
toRow :: [Text] -> Row
toRow = Attr -> [Cell] -> Row
Row Attr
nullAttr ([Cell] -> Row) -> ([Text] -> [Cell]) -> [Text] -> Row
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Cell) -> [Text] -> [Cell]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Cell
toplain
toHeaderRow :: [Text] -> [Row]
toHeaderRow [Text]
l = [[Text] -> Row
toRow [Text]
l | Bool -> Bool
not ([Text] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Text]
l)]
hdrs :: [Row]
hdrs = [Text] -> [Row]
toHeaderRow [Text]
r
rows :: [Row]
rows = ([Text] -> Row) -> [[Text]] -> [Row]
forall a b. (a -> b) -> [a] -> [b]
map [Text] -> Row
toRow [[Text]]
rs
aligns :: [Alignment]
aligns = Int -> Alignment -> [Alignment]
forall a. Int -> a -> [a]
replicate Int
numcols Alignment
AlignDefault
widths :: [ColWidth]
widths = Int -> ColWidth -> [ColWidth]
forall a. Int -> a -> [a]
replicate Int
numcols ColWidth
ColWidthDefault
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 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
$ Sources -> ParseError -> PandocError
PandocParsecError ([([Char], Text)] -> Sources
forall a. ToSources a => a -> Sources
toSources [([Char]
"",Text
txt)]) ParseError
e