@@ -14,10 +14,11 @@ module Text.Pandoc.Lua.Init
1414 ( runLua
1515 ) where
1616
17- import Control.Monad (forM_ , when )
17+ import Control.Monad (forM , forM_ , when )
1818import Control.Monad.Catch (throwM , try )
1919import Control.Monad.Trans (MonadIO (.. ))
2020import Data.Data (Data , dataTypeConstrs , dataTypeOf , showConstr )
21+ import Data.Maybe (catMaybes )
2122import HsLua as Lua hiding (status , try )
2223import GHC.IO.Encoding (getForeignEncoding , setForeignEncoding , utf8 )
2324import Text.Pandoc.Class.PandocMonad (PandocMonad , readDataFile )
@@ -78,23 +79,42 @@ initLuaState = do
7879 _ -> T. pack $ show err
7980
8081 setGlobalModules :: PandocLua ()
81- setGlobalModules = liftPandocLua $
82- forM_ [ (" lpeg" , LPeg. luaopen_lpeg_ptr)
83- , (" re" , LPeg. luaopen_re_ptr)
84- ] $
82+ setGlobalModules = liftPandocLua $ do
83+ let globalModules =
84+ [ (" lpeg" , LPeg. luaopen_lpeg_ptr) -- must be loaded first
85+ , (" re" , LPeg. luaopen_re_ptr) -- re depends on lpeg
86+ ]
87+ loadedBuiltInModules <- fmap catMaybes . forM globalModules $
8588 \ (pkgname, luaopen) -> do
8689 Lua. pushcfunction luaopen
87- Lua. pcall 0 1 Nothing >>= \ case
88- OK -> pure () -- all good, loading succeeded
90+ usedBuiltIn <- Lua. pcall 0 1 Nothing >>= \ case
91+ OK -> do -- all good, loading succeeded
92+ -- register as loaded module so later modules can rely on this
93+ Lua. getfield Lua. registryindex Lua. loaded
94+ Lua. pushvalue (Lua. nth 2 )
95+ Lua. setfield (Lua. nth 2 ) pkgname
96+ Lua. pop 1 -- pop _LOADED
97+ return True
8998 _ -> do -- built-in library failed, load system lib
9099 Lua. pop 1 -- ignore error message
91100 -- Try loading via the normal package loading mechanism.
92101 Lua. getglobal " require"
93102 Lua. pushName pkgname
94103 Lua. call 1 1 -- Throws an exception if loading failed again!
104+ return False
95105
96106 -- Module on top of stack. Register as global
97107 Lua. setglobal pkgname
108+ return $ if usedBuiltIn then Just pkgname else Nothing
109+
110+ -- Remove module entry from _LOADED table in registry if we used a
111+ -- built-in library. This ensures that later calls to @require@ will
112+ -- prefer the shared library, if any.
113+ forM_ loadedBuiltInModules $ \ pkgname -> do
114+ Lua. getfield Lua. registryindex Lua. loaded
115+ Lua. pushnil
116+ Lua. setfield (Lua. nth 2 ) pkgname
117+ Lua. pop 1 -- registry
98118
99119 installLpegSearcher :: PandocLua ()
100120 installLpegSearcher = liftPandocLua $ do
0 commit comments