aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2019-02-16 12:08:22 +0100
committerAlbert Krewinkel <albert@zeitkraut.de>2019-02-16 12:08:22 +0100
commit85470c49fe52b9fec5b5d35255f94c7833670131 (patch)
tree321fa7c211486b407a3e40bdcd6e837c24c87c4f /src
parentbc2aca3d6d4f3d59ba0b6a4b2f1e17ed4716e31a (diff)
downloadpandoc-85470c49fe52b9fec5b5d35255f94c7833670131.tar.gz
T.P.Lua: get CommonState from Lua global
This allows more control over the common state from within Lua scripts.
Diffstat (limited to 'src')
-rw-r--r--src/Text/Pandoc/Lua/Init.hs30
-rw-r--r--src/Text/Pandoc/Lua/Module/MediaBag.hs66
-rw-r--r--src/Text/Pandoc/Lua/Packages.hs22
3 files changed, 64 insertions, 54 deletions
diff --git a/src/Text/Pandoc/Lua/Init.hs b/src/Text/Pandoc/Lua/Init.hs
index f05076b20..b0b506add 100644
--- a/src/Text/Pandoc/Lua/Init.hs
+++ b/src/Text/Pandoc/Lua/Init.hs
@@ -36,11 +36,10 @@ module Text.Pandoc.Lua.Init
import Prelude
import Control.Monad.Trans (MonadIO (..))
import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
-import Data.IORef (newIORef, readIORef)
import Foreign.Lua (Lua)
import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
import Text.Pandoc.Class (PandocIO, getCommonState, getUserDataDir,
- getMediaBag, setMediaBag)
+ putCommonState)
import Text.Pandoc.Lua.Global (Global (..), setGlobals)
import Text.Pandoc.Lua.Packages (LuaPackageParams (..),
installPandocPackageSearcher)
@@ -64,13 +63,20 @@ runLua luaOp = do
res <- liftIO . Lua.runEither $ do
setGlobals globals
initLuaState luaPkgParams
- luaOp
+ -- run the given Lua operation
+ opResult <- luaOp
+ -- get the (possibly modified) state back
+ Lua.getglobal "PANDOC_STATE"
+ st <- Lua.peek Lua.stackTop
+ Lua.pop 1
+ -- done
+ return (opResult, st)
liftIO $ setForeignEncoding enc
- newMediaBag <- liftIO (readIORef (luaPkgMediaBag luaPkgParams))
- setMediaBag newMediaBag
- return $ case res of
- Left (Lua.Exception msg) -> Left (LuaException msg)
- Right x -> Right x
+ case res of
+ Left (Lua.Exception msg) -> return $ Left (LuaException msg)
+ Right (x, newState) -> do
+ putCommonState newState
+ return $ Right x
-- | Global variables which should always be set.
defaultGlobals :: PandocIO [Global]
@@ -85,14 +91,8 @@ defaultGlobals = do
-- | Generate parameters required to setup pandoc's lua environment.
luaPackageParams :: PandocIO LuaPackageParams
luaPackageParams = do
- commonState <- getCommonState
datadir <- getUserDataDir
- mbRef <- liftIO . newIORef =<< getMediaBag
- return LuaPackageParams
- { luaPkgCommonState = commonState
- , luaPkgDataDir = datadir
- , luaPkgMediaBag = mbRef
- }
+ return LuaPackageParams { luaPkgDataDir = datadir }
-- | Initialize the lua state with all required values
initLuaState :: LuaPackageParams -> Lua ()
diff --git a/src/Text/Pandoc/Lua/Module/MediaBag.hs b/src/Text/Pandoc/Lua/Module/MediaBag.hs
index 3c3f59907..eabab11ed 100644
--- a/src/Text/Pandoc/Lua/Module/MediaBag.hs
+++ b/src/Text/Pandoc/Lua/Module/MediaBag.hs
@@ -32,7 +32,6 @@ module Text.Pandoc.Lua.Module.MediaBag
import Prelude
import Control.Monad (zipWithM_)
-import Data.IORef (IORef, modifyIORef', readIORef)
import Data.Maybe (fromMaybe)
import Foreign.Lua (Lua, NumResults, Optional, liftIO)
import Text.Pandoc.Class (CommonState (..), fetchItem, putCommonState,
@@ -48,30 +47,49 @@ import qualified Text.Pandoc.MediaBag as MB
--
-- MediaBag submodule
--
-pushModule :: CommonState -> IORef MB.MediaBag -> Lua NumResults
-pushModule commonState mediaBagRef = do
+pushModule :: Lua NumResults
+pushModule = do
Lua.newtable
- addFunction "insert" (insertMediaFn mediaBagRef)
- addFunction "lookup" (lookupMediaFn mediaBagRef)
- addFunction "list" (mediaDirectoryFn mediaBagRef)
- addFunction "fetch" (fetch commonState mediaBagRef)
+ addFunction "insert" insertMediaFn
+ addFunction "lookup" lookupMediaFn
+ addFunction "list" mediaDirectoryFn
+ addFunction "fetch" fetch
return 1
-insertMediaFn :: IORef MB.MediaBag
- -> FilePath
+--
+-- Port functions from Text.Pandoc.Class to the Lua monad.
+-- TODO: reuse existing functions.
+
+-- Get the current CommonState.
+getCommonState :: Lua CommonState
+getCommonState = do
+ Lua.getglobal "PANDOC_STATE"
+ Lua.peek Lua.stackTop
+
+-- Replace MediaBag in CommonState.
+setCommonState :: CommonState -> Lua ()
+setCommonState st = do
+ Lua.push st
+ Lua.setglobal "PANDOC_STATE"
+
+modifyCommonState :: (CommonState -> CommonState) -> Lua ()
+modifyCommonState f = getCommonState >>= setCommonState . f
+
+insertMediaFn :: FilePath
-> Optional MimeType
-> BL.ByteString
-> Lua NumResults
-insertMediaFn mbRef fp optionalMime contents = do
- liftIO . modifyIORef' mbRef $
- MB.insertMedia fp (Lua.fromOptional optionalMime) contents
+insertMediaFn fp optionalMime contents = do
+ modifyCommonState $ \st ->
+ let mb = MB.insertMedia fp (Lua.fromOptional optionalMime) contents
+ (stMediaBag st)
+ in st { stMediaBag = mb}
return 0
-lookupMediaFn :: IORef MB.MediaBag
- -> FilePath
+lookupMediaFn :: FilePath
-> Lua NumResults
-lookupMediaFn mbRef fp = do
- res <- MB.lookupMedia fp <$> liftIO (readIORef mbRef)
+lookupMediaFn fp = do
+ res <- MB.lookupMedia fp . stMediaBag <$> getCommonState
case res of
Nothing -> Lua.pushnil *> return 1
Just (mimeType, contents) -> do
@@ -79,10 +97,9 @@ lookupMediaFn mbRef fp = do
Lua.push contents
return 2
-mediaDirectoryFn :: IORef MB.MediaBag
- -> Lua NumResults
-mediaDirectoryFn mbRef = do
- dirContents <- MB.mediaDirectory <$> liftIO (readIORef mbRef)
+mediaDirectoryFn :: Lua NumResults
+mediaDirectoryFn = do
+ dirContents <- MB.mediaDirectory . stMediaBag <$> getCommonState
Lua.newtable
zipWithM_ addEntry [1..] dirContents
return 1
@@ -95,12 +112,11 @@ mediaDirectoryFn mbRef = do
Lua.push "length" *> Lua.push contentLength *> Lua.rawset (-3)
Lua.rawseti (-2) idx
-fetch :: CommonState
- -> IORef MB.MediaBag
- -> String
+fetch :: String
-> Lua NumResults
-fetch commonState mbRef src = do
- mediaBag <- liftIO $ readIORef mbRef
+fetch src = do
+ commonState <- getCommonState
+ let mediaBag = stMediaBag commonState
(bs, mimeType) <- liftIO . runIOorExplode $ do
putCommonState commonState
setMediaBag mediaBag
diff --git a/src/Text/Pandoc/Lua/Packages.hs b/src/Text/Pandoc/Lua/Packages.hs
index d1b679962..8a6f939da 100644
--- a/src/Text/Pandoc/Lua/Packages.hs
+++ b/src/Text/Pandoc/Lua/Packages.hs
@@ -36,10 +36,8 @@ module Text.Pandoc.Lua.Packages
import Prelude
import Control.Monad (forM_)
import Data.ByteString (ByteString)
-import Data.IORef (IORef)
import Foreign.Lua (Lua, NumResults, liftIO)
-import Text.Pandoc.Class (CommonState, readDataFile, runIO, setUserDataDir)
-import Text.Pandoc.MediaBag (MediaBag)
+import Text.Pandoc.Class (readDataFile, runIO, setUserDataDir)
import qualified Foreign.Lua as Lua
import Text.Pandoc.Lua.Module.Pandoc as Pandoc
@@ -48,9 +46,7 @@ import Text.Pandoc.Lua.Module.Utils as Utils
-- | Parameters used to create lua packages/modules.
data LuaPackageParams = LuaPackageParams
- { luaPkgCommonState :: CommonState
- , luaPkgDataDir :: Maybe FilePath
- , luaPkgMediaBag :: IORef MediaBag
+ { luaPkgDataDir :: Maybe FilePath
}
-- | Insert pandoc's package loader as the first loader, making it the default.
@@ -68,15 +64,13 @@ installPandocPackageSearcher luaPkgParams = do
-- | Load a pandoc module.
pandocPackageSearcher :: LuaPackageParams -> String -> Lua NumResults
-pandocPackageSearcher luaPkgParams pkgName =
+pandocPackageSearcher pkgParams pkgName =
case pkgName of
- "pandoc" -> let datadir = luaPkgDataDir luaPkgParams
+ "pandoc" -> let datadir = luaPkgDataDir pkgParams
in pushWrappedHsFun (Pandoc.pushModule datadir)
- "pandoc.mediabag" -> let st = luaPkgCommonState luaPkgParams
- mbRef = luaPkgMediaBag luaPkgParams
- in pushWrappedHsFun (MediaBag.pushModule st mbRef)
- "pandoc.utils" -> let datadirMb = luaPkgDataDir luaPkgParams
- in pushWrappedHsFun (Utils.pushModule datadirMb)
+ "pandoc.mediabag" -> pushWrappedHsFun MediaBag.pushModule
+ "pandoc.utils" -> let datadir = luaPkgDataDir pkgParams
+ in pushWrappedHsFun (Utils.pushModule datadir)
_ -> searchPureLuaLoader
where
pushWrappedHsFun f = do
@@ -84,7 +78,7 @@ pandocPackageSearcher luaPkgParams pkgName =
return 1
searchPureLuaLoader = do
let filename = pkgName ++ ".lua"
- modScript <- liftIO (dataDirScript (luaPkgDataDir luaPkgParams) filename)
+ modScript <- liftIO (dataDirScript (luaPkgDataDir pkgParams) filename)
case modScript of
Just script -> pushWrappedHsFun (loadStringAsPackage pkgName script)
Nothing -> do