module Text.Pandoc.Lua.Init
( runLua
) where
import Control.Monad (when)
import Control.Monad.Catch (try)
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.PandocMonad (readDataFile)
import Text.Pandoc.Class.PandocIO (PandocIO)
import Text.Pandoc.Error (PandocError)
import Text.Pandoc.Lua.Packages (installPandocPackageSearcher)
import Text.Pandoc.Lua.PandocLua (PandocLua, liftPandocLua, runPandocLua)
import Text.Pandoc.Lua.Util (throwTopMessageAsError')
import qualified Foreign.Lua as Lua
import qualified Text.Pandoc.Definition as Pandoc
import qualified Text.Pandoc.Lua.Module.Pandoc as ModulePandoc
runLua :: Lua a -> PandocIO (Either PandocError a)
runLua :: Lua a -> PandocIO (Either PandocError a)
runLua Lua a
luaOp = do
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 PandocError a
res <- PandocLua (Either PandocError a) -> PandocIO (Either PandocError a)
forall a. PandocLua a -> PandocIO a
runPandocLua (PandocLua (Either PandocError a)
-> PandocIO (Either PandocError a))
-> (PandocLua a -> PandocLua (Either PandocError a))
-> PandocLua a
-> PandocIO (Either PandocError a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PandocLua a -> PandocLua (Either PandocError a)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (PandocLua a -> PandocIO (Either PandocError a))
-> PandocLua a -> PandocIO (Either PandocError a)
forall a b. (a -> b) -> a -> b
$ do
PandocLua ()
initLuaState
Lua a -> PandocLua a
forall a. Lua a -> PandocLua a
liftPandocLua Lua a
luaOp
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
Either PandocError a -> PandocIO (Either PandocError a)
forall (m :: * -> *) a. Monad m => a -> m a
return Either PandocError a
res
initLuaState :: PandocLua ()
initLuaState :: PandocLua ()
initLuaState = do
Lua () -> PandocLua ()
forall a. Lua a -> PandocLua a
liftPandocLua Lua ()
Lua.openlibs
PandocLua ()
installPandocPackageSearcher
PandocLua ()
initPandocModule
FilePath -> PandocLua ()
loadInitScript FilePath
"init.lua"
where
initPandocModule :: PandocLua ()
initPandocModule :: PandocLua ()
initPandocModule = do
PandocLua NumResults
ModulePandoc.pushModule
Lua () -> PandocLua ()
forall a. Lua a -> PandocLua a
liftPandocLua (Lua () -> PandocLua ()) -> Lua () -> PandocLua ()
forall a b. (a -> b) -> a -> b
$ do
StackIndex -> Lua ()
Lua.pushvalue StackIndex
Lua.stackTop
StackIndex -> FilePath -> Lua ()
Lua.getfield StackIndex
Lua.registryindex FilePath
Lua.loadedTableRegistryField
StackIndex -> FilePath -> Lua ()
Lua.setfield (CInt -> StackIndex
Lua.nthFromTop CInt
2) FilePath
"pandoc"
StackIndex -> Lua ()
Lua.pop StackIndex
1
PandocLua ()
putConstructorsInRegistry
Lua () -> PandocLua ()
forall a. Lua a -> PandocLua a
liftPandocLua (Lua () -> PandocLua ()) -> Lua () -> PandocLua ()
forall a b. (a -> b) -> a -> b
$ FilePath -> Lua ()
Lua.setglobal FilePath
"pandoc"
loadInitScript :: FilePath -> PandocLua ()
loadInitScript :: FilePath -> PandocLua ()
loadInitScript FilePath
scriptFile = do
ByteString
script <- FilePath -> PandocLua ByteString
forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
readDataFile FilePath
scriptFile
Status
status <- Lua Status -> PandocLua Status
forall a. Lua a -> PandocLua a
liftPandocLua (Lua Status -> PandocLua Status) -> Lua Status -> PandocLua Status
forall a b. (a -> b) -> a -> b
$ ByteString -> Lua Status
Lua.dostring ByteString
script
Bool -> PandocLua () -> PandocLua ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Status
status Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
/= Status
Lua.OK) (PandocLua () -> PandocLua ())
-> (Lua () -> PandocLua ()) -> Lua () -> PandocLua ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Lua () -> PandocLua ()
forall a. Lua a -> PandocLua a
liftPandocLua (Lua () -> PandocLua ()) -> Lua () -> PandocLua ()
forall a b. (a -> b) -> a -> b
$
(FilePath -> FilePath) -> Lua ()
forall a. (FilePath -> FilePath) -> Lua a
throwTopMessageAsError'
((FilePath
"Couldn't load '" FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
scriptFile FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
"'.\n") FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++)
putConstructorsInRegistry :: PandocLua ()
putConstructorsInRegistry :: PandocLua ()
putConstructorsInRegistry = Lua () -> PandocLua ()
forall a. Lua a -> PandocLua a
liftPandocLua (Lua () -> PandocLua ()) -> Lua () -> PandocLua ()
forall a b. (a -> b) -> a -> b
$ 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 Int
0 Int
0
FilePath -> Lua ()
putInReg FilePath
"Attr"
FilePath -> Lua ()
putInReg FilePath
"ListAttributes"
FilePath -> Lua ()
putInReg FilePath
"List"
FilePath -> Lua ()
putInReg FilePath
"SimpleTable"
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_ (FilePath -> Lua ()
putInReg (FilePath -> Lua ()) -> (Constr -> FilePath) -> Constr -> Lua ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constr -> FilePath
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 :: FilePath -> Lua ()
putInReg FilePath
name = do
FilePath -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push (FilePath
"pandoc." FilePath -> FilePath -> FilePath
forall a. [a] -> [a] -> [a]
++ FilePath
name)
FilePath -> Lua ()
forall a. Pushable a => a -> Lua ()
Lua.push FilePath
name
StackIndex -> Lua ()
Lua.rawget (CInt -> StackIndex
Lua.nthFromTop CInt
3)
StackIndex -> Lua ()
Lua.rawset StackIndex
Lua.registryindex