diff options
author | Albert Krewinkel <albert@zeitkraut.de> | 2021-11-17 08:47:30 +0100 |
---|---|---|
committer | Albert Krewinkel <albert@zeitkraut.de> | 2021-11-17 10:03:04 +0100 |
commit | cd91f72843359c5305842fa8afbec4a2d72629fa (patch) | |
tree | fbce914ef589cd7173d36bd572466bbfd36ab803 /src/Text | |
parent | 3ac7deadce6cf2fbf6aaa3c7bacebaacb5c68214 (diff) | |
download | pandoc-cd91f72843359c5305842fa8afbec4a2d72629fa.tar.gz |
Lua: set `lpeg`, `re` as globals; allow shared lib access via require
The `lpeg` and `re` modules are loaded into globals of the respective
name, but they are not necessarily registered as loaded packages. This
ensures that
- the built-in library versions are preferred when setting the globals,
- a shared library is used if pandoc has been compiled without `lpeg`,
and
- the `require` mechanism can be used to load the shared library if
available, falling back to the internal version if possible and
necessary.
Diffstat (limited to 'src/Text')
-rw-r--r-- | src/Text/Pandoc/Lua/Init.hs | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/src/Text/Pandoc/Lua/Init.hs b/src/Text/Pandoc/Lua/Init.hs index bf87f0a41..72a06f556 100644 --- a/src/Text/Pandoc/Lua/Init.hs +++ b/src/Text/Pandoc/Lua/Init.hs @@ -47,7 +47,8 @@ initLuaState = do liftPandocLua Lua.openlibs installPandocPackageSearcher initPandocModule - requireGlobalModules + installLpegSearcher + setGlobalModules loadInitScript "init.lua" where initPandocModule :: PandocLua () @@ -76,33 +77,32 @@ initLuaState = do PandocLuaError msg -> msg _ -> T.pack $ show err - requireGlobalModules :: PandocLua () - requireGlobalModules = liftPandocLua $ + setGlobalModules :: PandocLua () + setGlobalModules = liftPandocLua $ forM_ [ ("lpeg", LPeg.luaopen_lpeg_ptr) , ("re", LPeg.luaopen_re_ptr) ] $ \(pkgname, luaopen) -> do - -- Try loading via the normal package loading mechanism, and - -- fall back to manual module loading if the normal mechanism - -- fails. This means the system installation of the package, - -- should it be available, is preferred. - Lua.getglobal "require" - Lua.pushName pkgname - Lua.pcall 1 1 Nothing >>= \case + Lua.pushcfunction luaopen + Lua.pcall 0 1 Nothing >>= \case OK -> pure () -- all good, loading succeeded - _ -> do -- default mechanism failed, load included lib + _ -> do -- built-in library failed, load system lib Lua.pop 1 -- ignore error message - Lua.pushcfunction luaopen - Lua.call 0 1 -- Throws an exception if loading failed again! - -- Success. Add module to table @_LOADED@ in the registry - _ <- Lua.getfield Lua.registryindex Lua.loaded - Lua.pushvalue (Lua.nth 2) -- push module to top - Lua.setfield (Lua.nth 2) pkgname - Lua.pop 1 -- pop _LOADED + -- Try loading via the normal package loading mechanism. + Lua.getglobal "require" + Lua.pushName pkgname + Lua.call 1 1 -- Throws an exception if loading failed again! -- Module on top of stack. Register as global Lua.setglobal pkgname + installLpegSearcher :: PandocLua () + installLpegSearcher = liftPandocLua $ do + Lua.getglobal' "package.searchers" + Lua.pushHaskellFunction $ Lua.state >>= liftIO . LPeg.lpeg_searcher + Lua.rawseti (Lua.nth 2) . (+1) . fromIntegral =<< Lua.rawlen (Lua.nth 2) + Lua.pop 1 -- remove 'package.searchers' from stack + -- | AST elements are marshaled via normal constructor functions in the -- @pandoc@ module. However, accessing Lua globals from Haskell is -- expensive (due to error handling). Accessing the Lua registry is much |