git.iko.soy/typeable/pandoc
on master help sign in
T.P.Lua: get CommonState from Lua global

This allows more control over the common state from within Lua scripts.

commit85470c49fe52b9fec5b5d35255f94c7833670131 authorAlbert Krewinkel <albert@zeitkraut.de> dateSat 16 Feb 2019, 12:08 (8 years ago) parentbc2aca3
3 files changed+64−54
src/Text/Pandoc/Lua/Init.hs+15−15 src/Text/Pandoc/Lua/Module/MediaBag.hs+41−25 src/Text/Pandoc/Lua/Packages.hs+8−14
src/Text/Pandoc/Lua/Init.hs+15−15
@@ -36,11 +36,10 @@ module Text.Pandoc.Lua.Init
3636import Prelude
3737import Control.Monad.Trans (MonadIO (..))
3838import Data.Data (Data, dataTypeConstrs, dataTypeOf, showConstr)
39−import Data.IORef (newIORef, readIORef)
4039import Foreign.Lua (Lua)
4140import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
4241import Text.Pandoc.Class (PandocIO, getCommonState, getUserDataDir,
43− getMediaBag, setMediaBag)
42+ putCommonState)
4443import Text.Pandoc.Lua.Global (Global (..), setGlobals)
4544import Text.Pandoc.Lua.Packages (LuaPackageParams (..),
4645 installPandocPackageSearcher)
@@ -64,13 +63,20 @@ runLua luaOp = do
6463 res <- liftIO . Lua.runEither $ do
6564 setGlobals globals
6665 initLuaState luaPkgParams
67− luaOp
66+ -- run the given Lua operation
67+ opResult <- luaOp
68+ -- get the (possibly modified) state back
69+ Lua.getglobal "PANDOC_STATE"
70+ st <- Lua.peek Lua.stackTop
71+ Lua.pop 1
72+ -- done
73+ return (opResult, st)
6874 liftIO $ setForeignEncoding enc
69− newMediaBag <- liftIO (readIORef (luaPkgMediaBag luaPkgParams))
70− setMediaBag newMediaBag
71− return $ case res of
72− Left (Lua.Exception msg) -> Left (LuaException msg)
73− Right x -> Right x
75+ case res of
76+ Left (Lua.Exception msg) -> return $ Left (LuaException msg)
77+ Right (x, newState) -> do
78+ putCommonState newState
79+ return $ Right x
7480
7581-- | Global variables which should always be set.
7682defaultGlobals :: PandocIO [Global]
@@ -85,14 +91,8 @@ defaultGlobals = do
8591-- | Generate parameters required to setup pandoc's lua environment.
8692luaPackageParams :: PandocIO LuaPackageParams
8793luaPackageParams = do
88− commonState <- getCommonState
8994 datadir <- getUserDataDir
90− mbRef <- liftIO . newIORef =<< getMediaBag
91− return LuaPackageParams
92− { luaPkgCommonState = commonState
93− , luaPkgDataDir = datadir
94− , luaPkgMediaBag = mbRef
95− }
95+ return LuaPackageParams { luaPkgDataDir = datadir }
9696
9797-- | Initialize the lua state with all required values
9898initLuaState :: LuaPackageParams -> Lua ()
src/Text/Pandoc/Lua/Module/MediaBag.hs+41−25
@@ -32,7 +32,6 @@ module Text.Pandoc.Lua.Module.MediaBag
3232
3333import Prelude
3434import Control.Monad (zipWithM_)
35−import Data.IORef (IORef, modifyIORef', readIORef)
3635import Data.Maybe (fromMaybe)
3736import Foreign.Lua (Lua, NumResults, Optional, liftIO)
3837import Text.Pandoc.Class (CommonState (..), fetchItem, putCommonState,
@@ -48,30 +47,49 @@ import qualified Text.Pandoc.MediaBag as MB
4847--
4948-- MediaBag submodule
5049--
51−pushModule :: CommonState -> IORef MB.MediaBag -> Lua NumResults
52−pushModule commonState mediaBagRef = do
50+pushModule :: Lua NumResults
51+pushModule = do
5352 Lua.newtable
54− addFunction "insert" (insertMediaFn mediaBagRef)
55− addFunction "lookup" (lookupMediaFn mediaBagRef)
56− addFunction "list" (mediaDirectoryFn mediaBagRef)
57− addFunction "fetch" (fetch commonState mediaBagRef)
53+ addFunction "insert" insertMediaFn
54+ addFunction "lookup" lookupMediaFn
55+ addFunction "list" mediaDirectoryFn
56+ addFunction "fetch" fetch
5857 return 1
5958
60−insertMediaFn :: IORef MB.MediaBag
61− -> FilePath
59+--
60+-- Port functions from Text.Pandoc.Class to the Lua monad.
61+-- TODO: reuse existing functions.
62+
63+-- Get the current CommonState.
64+getCommonState :: Lua CommonState
65+getCommonState = do
66+ Lua.getglobal "PANDOC_STATE"
67+ Lua.peek Lua.stackTop
68+
69+-- Replace MediaBag in CommonState.
70+setCommonState :: CommonState -> Lua ()
71+setCommonState st = do
72+ Lua.push st
73+ Lua.setglobal "PANDOC_STATE"
74+
75+modifyCommonState :: (CommonState -> CommonState) -> Lua ()
76+modifyCommonState f = getCommonState >>= setCommonState . f
77+
78+insertMediaFn :: FilePath
6279 -> Optional MimeType
6380 -> BL.ByteString
6481 -> Lua NumResults
65−insertMediaFn mbRef fp optionalMime contents = do
66− liftIO . modifyIORef' mbRef $
67− MB.insertMedia fp (Lua.fromOptional optionalMime) contents
82+insertMediaFn fp optionalMime contents = do
83+ modifyCommonState $ \st ->
84+ let mb = MB.insertMedia fp (Lua.fromOptional optionalMime) contents
85+ (stMediaBag st)
86+ in st { stMediaBag = mb}
6887 return 0
6988
70−lookupMediaFn :: IORef MB.MediaBag
71− -> FilePath
89+lookupMediaFn :: FilePath
7290 -> Lua NumResults
73−lookupMediaFn mbRef fp = do
74− res <- MB.lookupMedia fp <$> liftIO (readIORef mbRef)
91+lookupMediaFn fp = do
92+ res <- MB.lookupMedia fp . stMediaBag <$> getCommonState
7593 case res of
7694 Nothing -> Lua.pushnil *> return 1
7795 Just (mimeType, contents) -> do
@@ -79,10 +97,9 @@ lookupMediaFn mbRef fp = do
7997 Lua.push contents
8098 return 2
8199
82−mediaDirectoryFn :: IORef MB.MediaBag
83− -> Lua NumResults
84−mediaDirectoryFn mbRef = do
85− dirContents <- MB.mediaDirectory <$> liftIO (readIORef mbRef)
100+mediaDirectoryFn :: Lua NumResults
101+mediaDirectoryFn = do
102+ dirContents <- MB.mediaDirectory . stMediaBag <$> getCommonState
86103 Lua.newtable
87104 zipWithM_ addEntry [1..] dirContents
88105 return 1
@@ -95,12 +112,11 @@ mediaDirectoryFn mbRef = do
95112 Lua.push "length" *> Lua.push contentLength *> Lua.rawset (-3)
96113 Lua.rawseti (-2) idx
97114
98−fetch :: CommonState
99− -> IORef MB.MediaBag
100− -> String
115+fetch :: String
101116 -> Lua NumResults
102−fetch commonState mbRef src = do
103− mediaBag <- liftIO $ readIORef mbRef
117+fetch src = do
118+ commonState <- getCommonState
119+ let mediaBag = stMediaBag commonState
104120 (bs, mimeType) <- liftIO . runIOorExplode $ do
105121 putCommonState commonState
106122 setMediaBag mediaBag
src/Text/Pandoc/Lua/Packages.hs+8−14
@@ -36,10 +36,8 @@ module Text.Pandoc.Lua.Packages
3636import Prelude
3737import Control.Monad (forM_)
3838import Data.ByteString (ByteString)
39−import Data.IORef (IORef)
4039import Foreign.Lua (Lua, NumResults, liftIO)
41−import Text.Pandoc.Class (CommonState, readDataFile, runIO, setUserDataDir)
42−import Text.Pandoc.MediaBag (MediaBag)
40+import Text.Pandoc.Class (readDataFile, runIO, setUserDataDir)
4341
4442import qualified Foreign.Lua as Lua
4543import Text.Pandoc.Lua.Module.Pandoc as Pandoc
@@ -48,9 +46,7 @@ import Text.Pandoc.Lua.Module.Utils as Utils
4846
4947-- | Parameters used to create lua packages/modules.
5048data LuaPackageParams = LuaPackageParams
51− { luaPkgCommonState :: CommonState
52− , luaPkgDataDir :: Maybe FilePath
53− , luaPkgMediaBag :: IORef MediaBag
49+ { luaPkgDataDir :: Maybe FilePath
5450 }
5551
5652-- | Insert pandoc's package loader as the first loader, making it the default.
@@ -68,15 +64,13 @@ installPandocPackageSearcher luaPkgParams = do
6864
6965-- | Load a pandoc module.
7066pandocPackageSearcher :: LuaPackageParams -> String -> Lua NumResults
71−pandocPackageSearcher luaPkgParams pkgName =
67+pandocPackageSearcher pkgParams pkgName =
7268 case pkgName of
73− "pandoc" -> let datadir = luaPkgDataDir luaPkgParams
69+ "pandoc" -> let datadir = luaPkgDataDir pkgParams
7470 in pushWrappedHsFun (Pandoc.pushModule datadir)
75− "pandoc.mediabag" -> let st = luaPkgCommonState luaPkgParams
76− mbRef = luaPkgMediaBag luaPkgParams
77− in pushWrappedHsFun (MediaBag.pushModule st mbRef)
78− "pandoc.utils" -> let datadirMb = luaPkgDataDir luaPkgParams
79− in pushWrappedHsFun (Utils.pushModule datadirMb)
71+ "pandoc.mediabag" -> pushWrappedHsFun MediaBag.pushModule
72+ "pandoc.utils" -> let datadir = luaPkgDataDir pkgParams
73+ in pushWrappedHsFun (Utils.pushModule datadir)
8074 _ -> searchPureLuaLoader
8175 where
8276 pushWrappedHsFun f = do
@@ -84,7 +78,7 @@ pandocPackageSearcher luaPkgParams pkgName =
8478 return 1
8579 searchPureLuaLoader = do
8680 let filename = pkgName ++ ".lua"
87− modScript <- liftIO (dataDirScript (luaPkgDataDir luaPkgParams) filename)
81+ modScript <- liftIO (dataDirScript (luaPkgDataDir pkgParams) filename)
8882 case modScript of
8983 Just script -> pushWrappedHsFun (loadStringAsPackage pkgName script)
9084 Nothing -> do