{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Readers.Xlsx
   Copyright   : © 2025 Anton Antic
   License     : GNU GPL, version 2 or above

   Maintainer  : Anton Antic <anton@everworker.ai>
   Stability   : alpha
   Portability : portable

Conversion of XLSX (Excel spreadsheet) documents to 'Pandoc' document.
-}
module Text.Pandoc.Readers.Xlsx (readXlsx) where

import qualified Data.ByteString.Lazy as B
import qualified Data.Text as T
import Codec.Archive.Zip (toArchiveOrFail)
import Control.Monad.Except (throwError)
import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition (Pandoc(..))
import Text.Pandoc.Error (PandocError(..))
import Text.Pandoc.Options (ReaderOptions)
import Text.Pandoc.Readers.Xlsx.Parse (archiveToXlsx)
import Text.Pandoc.Readers.Xlsx.Sheets (xlsxToOutput)

-- | Read XLSX file into Pandoc AST
readXlsx :: PandocMonad m => ReaderOptions -> B.ByteString -> m Pandoc
readXlsx :: forall (m :: * -> *).
PandocMonad m =>
ReaderOptions -> ByteString -> m Pandoc
readXlsx ReaderOptions
opts ByteString
bytes =
  case ByteString -> Either String Archive
toArchiveOrFail ByteString
bytes of
    Right Archive
archive ->
      case Archive -> Either Text Xlsx
archiveToXlsx Archive
archive of
        Right Xlsx
xlsx -> do
          let (Meta
meta, [Block]
blocks) = ReaderOptions -> Xlsx -> (Meta, [Block])
xlsxToOutput ReaderOptions
opts Xlsx
xlsx
          Pandoc -> m Pandoc
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> m Pandoc) -> Pandoc -> m Pandoc
forall a b. (a -> b) -> a -> b
$ Meta -> [Block] -> Pandoc
Pandoc Meta
meta [Block]
blocks
        Left Text
err ->
          PandocError -> m Pandoc
forall a. PandocError -> m a
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 -> PandocError
PandocParseError (Text -> PandocError) -> Text -> PandocError
forall a b. (a -> b) -> a -> b
$ Text
"Failed to parse XLSX: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
err

    Left String
err ->
      PandocError -> m Pandoc
forall a. PandocError -> m a
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 -> PandocError
PandocParseError (Text -> PandocError) -> Text -> PandocError
forall a b. (a -> b) -> a -> b
$
        Text
"Failed to unpack XLSX archive: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
T.pack String
err