    {- |
       Module      : Text.Pandoc.Filter.Lua
       Copyright   : Copyright (C) 2006-2020 John MacFarlane
       License     : GNU GPL, version 2 or above

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

    Apply Lua filters to modify a pandoc documents programmatically.
    -}
    module Text.Pandoc.Filter.Lua (apply) where

    import Control.Exception (throw)
    import Control.Monad ((>=>))
    import qualified Data.Text as T
    import Text.Pandoc.Class.PandocIO (PandocIO)
    import Text.Pandoc.Definition (Pandoc)
    import Text.Pandoc.Error (PandocError (PandocFilterError))
    import Text.Pandoc.Lua (Global (..), LuaException (..),
                            runLua, runFilterFile, setGlobals)
    import Text.Pandoc.Options (ReaderOptions)

    -- | Run the Lua filter in @filterPath@ for a transformation to the
    -- target format (first element in args). Pandoc uses Lua init files to
    -- setup the Lua interpreter.
    apply :: ReaderOptions
          -> [String]
          -> FilePath
          -> Pandoc
          -> PandocIO Pandoc
    apply :: ReaderOptions -> [String] -> String -> Pandoc -> PandocIO Pandoc
    apply ropts :: ReaderOptions
    ropts args :: [String]
    args fp :: String
    fp doc :: Pandoc
    doc = do
      let format :: String
    format = case [String]
    args of
                     (x :: String
    x:_) -> String
    x
                     _     -> String -> String
    forall a. HasCallStack => String -> a
    error "Format not supplied for Lua filter"
      Lua Pandoc -> PandocIO (Either LuaException Pandoc)
    forall a. Lua a -> PandocIO (Either LuaException a)
    runLua (Lua Pandoc -> PandocIO (Either LuaException Pandoc))
    -> (Either LuaException Pandoc -> PandocIO Pandoc)
    -> Lua Pandoc
    -> PandocIO Pandoc
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> String -> Either LuaException Pandoc -> PandocIO Pandoc
    forceResult String
    fp (Lua Pandoc -> PandocIO Pandoc) -> Lua Pandoc -> PandocIO Pandoc
    forall a b. (a -> b) -> a -> b
    $ do
        [Global] -> Lua ()
    setGlobals [ Text -> Global
    FORMAT (Text -> Global) -> Text -> Global
    forall a b. (a -> b) -> a -> b
    $ String -> Text
    T.pack String
    format
                   , ReaderOptions -> Global
    PANDOC_READER_OPTIONS ReaderOptions
    ropts
                   , String -> Global
    PANDOC_SCRIPT_FILE String
    fp
                   ]
        String -> Pandoc -> Lua Pandoc
    runFilterFile String
    fp Pandoc
    doc

    forceResult :: FilePath -> Either LuaException Pandoc -> PandocIO Pandoc
    forceResult :: String -> Either LuaException Pandoc -> PandocIO Pandoc
    forceResult fp :: String
    fp eitherResult :: Either LuaException Pandoc
    eitherResult = case Either LuaException Pandoc
    eitherResult of
      Right x :: Pandoc
    x               -> Pandoc -> PandocIO Pandoc
    forall (m :: * -> *) a. Monad m => a -> m a
    return Pandoc
    x
      Left (LuaException s :: Text
    s) -> PandocError -> PandocIO Pandoc
    forall a e. Exception e => e -> a
    throw (Text -> Text -> PandocError
    PandocFilterError (String -> Text
    T.pack String
    fp) Text
    s)