module Text.Pandoc.Lua.Init
( LuaException (..)
, LuaPackageParams (..)
, runLua
, luaPackageParams
) where
import Control.Monad.Trans (MonadIO (..))
import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
import Foreign.Lua (Lua)
import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
import Text.Pandoc.Class.PandocIO (PandocIO)
import Text.Pandoc.Class.PandocMonad (getCommonState, getUserDataDir,
putCommonState)
import Text.Pandoc.Lua.Global (Global (..), setGlobals)
import Text.Pandoc.Lua.Packages (LuaPackageParams (..),
installPandocPackageSearcher)
import Text.Pandoc.Lua.Util (loadScriptFromDataDir)
import qualified Data.Text as Text
import qualified Foreign.Lua as Lua
import qualified Foreign.Lua.Module.Text as Lua
import qualified Text.Pandoc.Definition as Pandoc
import qualified Text.Pandoc.Lua.Module.Pandoc as ModulePandoc
newtype LuaException = LuaException Text.Text deriving (Int -> LuaException -> ShowS
[LuaException] -> ShowS
LuaException -> String
(Int -> LuaException -> ShowS)
-> (LuaException -> String)
-> ([LuaException] -> ShowS)
-> Show LuaException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LuaException] -> ShowS
$cshowList :: [LuaException] -> ShowS
show :: LuaException -> String
$cshow :: LuaException -> String
showsPrec :: Int -> LuaException -> ShowS
$cshowsPrec :: Int -> LuaException -> ShowS
Show)
runLua :: Lua a -> PandocIO (Either LuaException a)
runLua :: Lua a -> PandocIO (Either LuaException a)
runLua luaOp :: Lua a
luaOp = do
LuaPackageParams
luaPkgParams <- PandocIO LuaPackageParams
luaPackageParams
[Global]
globals <- PandocIO [Global]
defaultGlobals
TextEncoding
enc <- IO TextEncoding -> PandocIO TextEncoding
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TextEncoding -> PandocIO TextEncoding)
-> IO TextEncoding -> PandocIO TextEncoding
forall a b. (a -> b) -> a -> b
$ IO TextEncoding
getForeignEncoding IO TextEncoding -> IO () -> IO TextEncoding
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* TextEncoding -> IO ()
setForeignEncoding TextEncoding
utf8
Either Exception (a, CommonState)
res <- IO (Either Exception (a, CommonState))
-> PandocIO (Either Exception (a, CommonState))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either Exception (a, CommonState))
-> PandocIO (Either Exception (a, CommonState)))
-> (Lua (a, CommonState) -> IO (Either Exception (a, CommonState)))
-> Lua (a, CommonState)
-> PandocIO (Either Exception (a, CommonState))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lua (a, CommonState) -> IO (Either Exception (a, CommonState))
forall a. Lua a -> IO (Either Exception a)
Lua.runEither (Lua (a, CommonState)
-> PandocIO (Either Exception (a, CommonState)))
-> Lua (a, CommonState)
-> PandocIO (Either Exception (a, CommonState))
forall a b. (a -> b) -> a -> b
$ do
[Global] -> Lua ()
setGlobals [Global]
globals
LuaPackageParams -> Lua ()
initLuaState LuaPackageParams
luaPkgParams
a
opResult <- Lua a
luaOp
String -> Lua ()
Lua.getglobal "PANDOC_STATE"
CommonState
st <- StackIndex -> Lua CommonState
forall a. Peekable a => StackIndex -> Lua a
Lua.peek StackIndex
Lua.stackTop
StackIndex -> Lua ()
Lua.pop 1
(a, CommonState) -> Lua (a, CommonState)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
opResult, CommonState
st)
IO () -> PandocIO ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> PandocIO ()) -> IO () -> PandocIO ()
forall a b. (a -> b) -> a -> b
$ TextEncoding -> IO ()
setForeignEncoding TextEncoding
enc
case Either Exception (a, CommonState)
res of
Left (Lua.Exception msg :: String
msg) -> Either LuaException a -> PandocIO (Either LuaException a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either LuaException a -> PandocIO (Either LuaException a))
-> Either LuaException a -> PandocIO (Either LuaException a)
forall a b. (a -> b) -> a -> b
$ LuaException -> Either LuaException a
forall a b. a -> Either a b
Left (Text -> LuaException
LuaException (Text -> LuaException) -> Text -> LuaException
forall a b. (a -> b) -> a -> b
$ String -> Text
Text.pack String
msg)
Right (x :: a
x, newState :: CommonState
newState) -> do
CommonState -> PandocIO ()
forall (m :: * -> *). PandocMonad m => CommonState -> m ()
putCommonState CommonState
newState
Either LuaException a -> PandocIO (Either LuaException a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either LuaException a -> PandocIO (Either LuaException a))
-> Either LuaException a -> PandocIO (Either LuaException a)
forall a b. (a -> b) -> a -> b
$ a -> Either LuaException a
forall a b. b -> Either a b
Right a
x
defaultGlobals :: PandocIO [Global]
defaultGlobals :: PandocIO [Global]
defaultGlobals = do
CommonState
commonState <- PandocIO CommonState
forall (m :: * -> *). PandocMonad m => m CommonState
getCommonState
[Global] -> PandocIO [Global]
forall (m :: * -> *) a. Monad m => a -> m a
return
[ Global
PANDOC_API_VERSION
, CommonState -> Global
PANDOC_STATE CommonState
commonState
, Global
PANDOC_VERSION
]
luaPackageParams :: PandocIO LuaPackageParams
luaPackageParams :: PandocIO LuaPackageParams
luaPackageParams = do
Maybe String
datadir <- PandocIO (Maybe String)
forall (m :: * -> *). PandocMonad m => m (Maybe String)
getUserDataDir
LuaPackageParams -> PandocIO LuaPackageParams
forall (m :: * -> *) a. Monad m => a -> m a
return LuaPackageParams :: Maybe String -> LuaPackageParams
LuaPackageParams { luaPkgDataDir :: Maybe String
luaPkgDataDir = Maybe String
datadir }
initLuaState :: LuaPackageParams -> Lua ()
initLuaState :: LuaPackageParams -> Lua ()
initLuaState pkgParams :: LuaPackageParams
pkgParams = do
Lua ()
Lua.openlibs
String -> Lua ()
Lua.preloadTextModule "text"
LuaPackageParams -> Lua ()
installPandocPackageSearcher LuaPackageParams
pkgParams
Lua ()
initPandocModule
Maybe String -> String -> Lua ()
loadScriptFromDataDir (LuaPackageParams -> Maybe String
luaPkgDataDir LuaPackageParams
pkgParams) "init.lua"
where
initPandocModule :: Lua ()
initPandocModule :: Lua ()
initPandocModule = do
Maybe String -> Lua NumResults
ModulePandoc.pushModule (LuaPackageParams -> Maybe String
luaPkgDataDir LuaPackageParams
pkgParams)
StackIndex -> Lua ()
Lua.pushvalue StackIndex
Lua.stackTop
StackIndex -> String -> Lua ()
Lua.getfield StackIndex
Lua.registryindex String
Lua.loadedTableRegistryField
StackIndex -> String -> Lua ()
Lua.setfield (CInt -> StackIndex
Lua.nthFromTop 2) "pandoc"
StackIndex -> Lua ()
Lua.pop 1
Lua ()
putConstructorsInRegistry
String -> Lua ()
Lua.setglobal "pandoc"
putConstructorsInRegistry :: Lua ()
putConstructorsInRegistry :: Lua ()
putConstructorsInRegistry = do
Pandoc -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (Pandoc -> Lua ()) -> Pandoc -> Lua ()
forall a b. (a -> b) -> a -> b
$ Meta -> [Block] -> Pandoc
Pandoc.Pandoc Meta
forall a. Monoid a => a
mempty [Block]
forall a. Monoid a => a
mempty
Inline -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (Inline -> Lua ()) -> Inline -> Lua ()
forall a b. (a -> b) -> a -> b
$ Text -> Inline
Pandoc.Str Text
forall a. Monoid a => a
mempty
Block -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (Block -> Lua ()) -> Block -> Lua ()
forall a b. (a -> b) -> a -> b
$ [Inline] -> Block
Pandoc.Para [Inline]
forall a. Monoid a => a
mempty
Meta -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (Meta -> Lua ()) -> Meta -> Lua ()
forall a b. (a -> b) -> a -> b
$ Map Text MetaValue -> Meta
Pandoc.Meta Map Text MetaValue
forall a. Monoid a => a
mempty
MetaValue -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (MetaValue -> Lua ()) -> MetaValue -> Lua ()
forall a b. (a -> b) -> a -> b
$ [MetaValue] -> MetaValue
Pandoc.MetaList [MetaValue]
forall a. Monoid a => a
mempty
Citation -> Lua ()
forall a. Data a => a -> Lua ()
constrsToReg (Citation -> Lua ()) -> Citation -> Lua ()
forall a b. (a -> b) -> a -> b
$ Text
-> [Inline] -> [Inline] -> CitationMode -> Int -> Int -> Citation
Pandoc.Citation Text
forall a. Monoid a => a
mempty [Inline]
forall a. Monoid a => a
mempty [Inline]
forall a. Monoid a => a
mempty CitationMode
Pandoc.AuthorInText 0 0
String -> Lua ()
putInReg "Attr"
String -> Lua ()
putInReg "ListAttributes"
String -> Lua ()
putInReg "List"
where
constrsToReg :: Data a => a -> Lua ()
constrsToReg :: a -> Lua ()
constrsToReg = (Constr -> Lua ()) -> [Constr] -> Lua ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (String -> Lua ()
putInReg (String -> Lua ()) -> (Constr -> String) -> Constr -> Lua ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constr -> String
showConstr) ([Constr] -> Lua ()) -> (a -> [Constr]) -> a -> Lua ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataType -> [Constr]
dataTypeConstrs (DataType -> [Constr]) -> (a -> DataType) -> a -> [Constr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> DataType
forall a. Data a => a -> DataType
dataTypeOf
putInReg :: String -> Lua ()
putInReg :: String -> Lua ()
putInReg name :: String
name = do
String -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push ("pandoc." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
name)
String -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push String
name
StackIndex -> Lua ()
Lua.rawget (CInt -> StackIndex
Lua.nthFromTop 3)
StackIndex -> Lua ()
Lua.rawset StackIndex
Lua.registryindex