Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ghc-pandoc-lua-engine for openSUSE:Factory checked in at 2024-07-22 17:16:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-pandoc-lua-engine (Old) and /work/SRC/openSUSE:Factory/.ghc-pandoc-lua-engine.new.17339 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-pandoc-lua-engine" Mon Jul 22 17:16:35 2024 rev:8 rq:1188651 version:0.3 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-pandoc-lua-engine/ghc-pandoc-lua-engine.changes 2024-05-22 21:32:14.853475620 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-pandoc-lua-engine.new.17339/ghc-pandoc-lua-engine.changes 2024-07-22 17:17:29.704060565 +0200 @@ -1,0 +2,6 @@ +Mon Jun 24 21:18:37 UTC 2024 - Peter Simons <psim...@suse.com> + +- Update pandoc-lua-engine to version 0.3. + Upstream does not provide a change log file. + +------------------------------------------------------------------- Old: ---- pandoc-lua-engine-0.2.1.5.tar.gz pandoc-lua-engine.cabal New: ---- pandoc-lua-engine-0.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-pandoc-lua-engine.spec ++++++ --- /var/tmp/diff_new_pack.irVyRg/_old 2024-07-22 17:17:31.252122109 +0200 +++ /var/tmp/diff_new_pack.irVyRg/_new 2024-07-22 17:17:31.284123381 +0200 @@ -20,13 +20,12 @@ %global pkgver %{pkg_name}-%{version} %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.2.1.5 +Version: 0.3 Release: 0 Summary: Lua engine to power custom pandoc conversions License: GPL-2.0-or-later URL: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz -Source1: https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal BuildRequires: ghc-Cabal-devel BuildRequires: ghc-SHA-devel BuildRequires: ghc-SHA-prof @@ -127,7 +126,6 @@ %prep %autosetup -n %{pkg_name}-%{version} -cp -p %{SOURCE1} %{pkg_name}.cabal %build %ghc_lib_build ++++++ pandoc-lua-engine-0.2.1.5.tar.gz -> pandoc-lua-engine-0.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/pandoc-lua-engine.cabal new/pandoc-lua-engine-0.3/pandoc-lua-engine.cabal --- old/pandoc-lua-engine-0.2.1.5/pandoc-lua-engine.cabal 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/pandoc-lua-engine.cabal 2001-09-09 03:46:40.000000000 +0200 @@ -1,10 +1,10 @@ cabal-version: 2.4 name: pandoc-lua-engine -version: 0.2.1.5 +version: 0.3 build-type: Simple license: GPL-2.0-or-later license-file: COPYING.md -copyright: © 2006-2022 John MacFarlane, 2017-2022 Albert Krewinkel +copyright: © 2006-2024 John MacFarlane, 2017-2024 Albert Krewinkel author: John MacFarlane, Albert Krewinkel maintainer: Albert Krewinkel <alb...@hslua.org> bug-reports: https://github.com/jgm/pandoc/issues @@ -67,9 +67,11 @@ hs-source-dirs: src exposed-modules: Text.Pandoc.Lua other-modules: Text.Pandoc.Lua.Custom + , Text.Pandoc.Lua.Engine , Text.Pandoc.Lua.Filter , Text.Pandoc.Lua.Global , Text.Pandoc.Lua.Init + , Text.Pandoc.Lua.Module , Text.Pandoc.Lua.Marshal.Chunks , Text.Pandoc.Lua.Marshal.CommonState , Text.Pandoc.Lua.Marshal.Context @@ -98,6 +100,7 @@ , Text.Pandoc.Lua.Module.Utils , Text.Pandoc.Lua.Orphans , Text.Pandoc.Lua.PandocLua + , Text.Pandoc.Lua.Run , Text.Pandoc.Lua.SourcePos , Text.Pandoc.Lua.Writer.Classic , Text.Pandoc.Lua.Writer.Scaffolding @@ -121,7 +124,7 @@ , hslua-repl >= 0.1.1 && < 0.2 , lpeg >= 1.1 && < 1.2 , mtl >= 2.2 && < 2.4 - , pandoc >= 3.1.4 && < 3.3 + , pandoc >= 3.2.1 && < 3.3 , pandoc-lua-marshal >= 0.2.7 && < 0.3 , pandoc-types >= 1.22 && < 1.24 , parsec >= 3.1 && < 3.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Custom.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Custom.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Custom.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Custom.hs 2001-09-09 03:46:40.000000000 +0200 @@ -18,11 +18,11 @@ import Text.Pandoc.Class (PandocMonad, findFileWithDataFallback) import Text.Pandoc.Error (PandocError) import Text.Pandoc.Lua.Global (Global (..), setGlobals) -import Text.Pandoc.Lua.Init (runLuaWith) import Text.Pandoc.Lua.Marshal.Format (peekExtensionsConfig) import Text.Pandoc.Lua.Marshal.Pandoc (peekPandoc) import Text.Pandoc.Lua.Marshal.WriterOptions (pushWriterOptions) import Text.Pandoc.Lua.PandocLua (unPandocLua) +import Text.Pandoc.Lua.Run (runLuaWith) import Text.Pandoc.Readers (Reader (..)) import Text.Pandoc.Sources (ToSources(..)) import Text.Pandoc.Scripting (CustomComponents (..)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Engine.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Engine.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Engine.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Engine.hs 2001-09-09 03:46:40.000000000 +0200 @@ -0,0 +1,73 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeApplications #-} +{- | + Module : Text.Pandoc.Lua.Engine + Copyright : Copyright © 2017-2024 Albert Krewinkel + License : GPL-2.0-or-later + Maintainer : Albert Krewinkel <tarleb+pan...@zeitkraut.de> + +Running pandoc Lua filters. +-} +module Text.Pandoc.Lua.Engine + ( getEngine + , applyFilter + ) where + +import Control.Exception (throw) +import Control.Monad ((>=>)) +import Control.Monad.IO.Class (MonadIO (liftIO)) +import HsLua.Core (getglobal, openlibs, run, top, tostring) +import Text.Pandoc.Class (PandocMonad) +import Text.Pandoc.Definition (Pandoc) +import Text.Pandoc.Filter (Environment (..)) +import Text.Pandoc.Error (PandocError (PandocFilterError, PandocLuaError)) +import Text.Pandoc.Lua.Custom (loadCustom) +import Text.Pandoc.Lua.Filter (runFilterFile) +import Text.Pandoc.Lua.Global (Global (..), setGlobals) +import Text.Pandoc.Lua.Run (runLua) +import Text.Pandoc.Lua.Orphans () +import Text.Pandoc.Scripting (ScriptingEngine (..)) +import qualified Text.Pandoc.UTF8 as UTF8 +import qualified Data.Text as T + +-- | Constructs the Lua scripting engine. +getEngine :: MonadIO m => m ScriptingEngine +getEngine = do + versionName <- liftIO . run @PandocError $ do + openlibs + getglobal "_VERSION" + tostring top + pure $ ScriptingEngine + { engineName = maybe "Lua (unknown version)" UTF8.toText versionName + , engineApplyFilter = applyFilter + , engineLoadCustom = loadCustom + } + +-- | Run the Lua filter in @filterPath@ for a transformation to the +-- target format (first element in args). Pandoc uses Lua init files to +-- setup the Lua interpreter. +applyFilter :: (PandocMonad m, MonadIO m) + => Environment + -> [String] + -> FilePath + -> Pandoc + -> m Pandoc +applyFilter fenv args fp doc = do + let globals = [ FORMAT $ case args of + x:_ -> T.pack x + _ -> "" + , PANDOC_READER_OPTIONS (envReaderOptions fenv) + , PANDOC_WRITER_OPTIONS (envWriterOptions fenv) + , PANDOC_SCRIPT_FILE fp + ] + runLua >=> forceResult fp $ do + setGlobals globals + runFilterFile fp doc + +forceResult :: (PandocMonad m, MonadIO m) + => FilePath -> Either PandocError Pandoc -> m Pandoc +forceResult fp eitherResult = case eitherResult of + Right x -> return x + Left err -> throw . PandocFilterError (T.pack fp) $ case err of + PandocLuaError msg -> msg + _ -> T.pack $ show err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Filter.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Filter.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Filter.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Filter.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,41 +1,41 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE IncoherentInstances #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} {- | Module : Text.Pandoc.Lua.Filter Copyright : © 2012-2024 John MacFarlane, © 2017-2024 Albert Krewinkel -License : GNU GPL, version 2 or above -Maintainer : Albert Krewinkel <tarleb+pan...@moltkeplatz.de> -Stability : alpha +License : GPL-2.0-or-later +Maintainer : Albert Krewinkel <pan...@tarleb.com> Types and functions for running Lua filters. -} module Text.Pandoc.Lua.Filter - ( applyFilter + ( runFilterFile + , runFilterFile' ) where import Control.Monad ((>=>), (<$!>)) import HsLua as Lua -import Text.Pandoc.Definition -import Text.Pandoc.Filter (Environment (..)) +import Text.Pandoc.Definition (Pandoc) +import Text.Pandoc.Error (PandocError) import Text.Pandoc.Lua.Marshal.AST import Text.Pandoc.Lua.Marshal.Filter -import Text.Pandoc.Lua.Global (Global (..), setGlobals) -import Text.Pandoc.Lua.Init (runLua) import Text.Pandoc.Lua.PandocLua () -import Control.Exception (throw) -import qualified Data.Text as T -import Text.Pandoc.Class (PandocMonad) -import Control.Monad.Trans (MonadIO) -import Text.Pandoc.Error (PandocError (PandocFilterError, PandocLuaError)) -- | Transform document using the filter defined in the given file. +-- Runs the filter in the global environment. runFilterFile :: FilePath -> Pandoc -> LuaE PandocError Pandoc runFilterFile filterPath doc = do + Lua.pushglobaltable + runFilterFile' Lua.top filterPath doc <* Lua.pop 1 + +-- | Like 'runFilterFile', but uses the table at the given index as the +-- environment in which the filter is run. +runFilterFile' :: StackIndex -> FilePath -> Pandoc + -> LuaE PandocError Pandoc +runFilterFile' envIdx filterPath doc = do oldtop <- gettop - stat <- dofileTrace (Just filterPath) - if stat /= Lua.OK + stat <- dofileTrace' envIdx (Just filterPath) + if stat /= OK then throwErrorAsException else do newtop <- gettop @@ -43,39 +43,25 @@ -- filter if nothing was returned. luaFilters <- forcePeek $ if newtop - oldtop >= 1 - then peekList peekFilter top - else (:[]) <$!> (liftLua pushglobaltable *> peekFilter top) + then peekList peekFilter top -- get from explicit filter table + else (:[]) <$!> peekFilter envIdx -- get the implicit filter in _ENV settop oldtop runAll luaFilters doc +-- | Apply Lua filters to a document runAll :: [Filter] -> Pandoc -> LuaE PandocError Pandoc runAll = foldr ((>=>) . applyFully) return --- | Run the Lua filter in @filterPath@ for a transformation to the --- target format (first element in args). Pandoc uses Lua init files to --- setup the Lua interpreter. -applyFilter :: (PandocMonad m, MonadIO m) - => Environment - -> [String] - -> FilePath - -> Pandoc - -> m Pandoc -applyFilter fenv args fp doc = do - let globals = [ FORMAT $ case args of - x:_ -> T.pack x - _ -> "" - , PANDOC_READER_OPTIONS (envReaderOptions fenv) - , PANDOC_WRITER_OPTIONS (envWriterOptions fenv) - , PANDOC_SCRIPT_FILE fp - ] - runLua >=> forceResult fp $ do - setGlobals globals - runFilterFile fp doc - -forceResult :: (PandocMonad m, MonadIO m) - => FilePath -> Either PandocError Pandoc -> m Pandoc -forceResult fp eitherResult = case eitherResult of - Right x -> return x - Left err -> throw . PandocFilterError (T.pack fp) $ case err of - PandocLuaError msg -> msg - _ -> T.pack $ show err +-- | Like 'HsLua.Core.Trace.dofileTrace', but uses a local environment. +dofileTrace' :: LuaError e + => StackIndex -- ^ stack index of the environment table + -> Maybe FilePath -- ^ file to load (or @Nothing@ for stdin) + -> LuaE e Status +dofileTrace' envIdx fp = do + absEnv <- Lua.absindex envIdx + loadfile fp >>= \case + OK -> do + Lua.pushvalue absEnv + Just (Name "_ENV") <- Lua.setupvalue (Lua.nth 2) 1 + pcallTrace 0 multret + s -> pure s diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Init.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Init.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Init.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Init.hs 2001-09-09 03:46:40.000000000 +0200 @@ -2,244 +2,59 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} {- | - Module : Text.Pandoc.Lua - Copyright : Copyright © 2017-2024 Albert Krewinkel - License : GNU GPL, version 2 or above - + Module : Text.Pandoc.Lua.Init + Copyright : © 2017-2024 Albert Krewinkel + License : GPL-2.0-or-later Maintainer : Albert Krewinkel <tarleb+pan...@moltkeplatz.de> - Stability : alpha Functions to initialize the Lua interpreter. -} module Text.Pandoc.Lua.Init - ( runLua - , runLuaNoEnv - , runLuaWith + ( initLua + , userInit ) where -import Control.Monad (forM, forM_, when) -import Control.Monad.Catch (throwM, try) -import Control.Monad.Trans (MonadIO (..)) -import Data.Maybe (catMaybes) -import Data.Version (makeVersion) -import HsLua as Lua hiding (status, try) -import Text.Pandoc.Class (PandocMonad (..), report) +import Control.Monad (when) +import Control.Monad.Catch (throwM) +import HsLua as Lua hiding (status) +import Text.Pandoc.Class (report) import Text.Pandoc.Data (readDataFile) import Text.Pandoc.Error (PandocError (PandocLuaError)) import Text.Pandoc.Logging (LogMessage (ScriptingWarning)) -import Text.Pandoc.Lua.Global (Global (..), setGlobals) -import Text.Pandoc.Lua.Marshal.List (newListMetatable, pushListModule) +import Text.Pandoc.Lua.Module (initModules) import Text.Pandoc.Lua.PandocLua (PandocLua (..), liftPandocLua) import Text.Pandoc.Lua.SourcePos (luaSourcePos) -import qualified Data.ByteString.Char8 as Char8 import qualified Data.Text as T -import qualified Lua.LPeg as LPeg -import qualified HsLua.Aeson -import qualified HsLua.Module.DocLayout as Module.Layout -import qualified HsLua.Module.Path as Module.Path -import qualified HsLua.Module.Zip as Module.Zip -import qualified Text.Pandoc.Lua.Module.CLI as Pandoc.CLI -import qualified Text.Pandoc.Lua.Module.Format as Pandoc.Format -import qualified Text.Pandoc.Lua.Module.Image as Pandoc.Image -import qualified Text.Pandoc.Lua.Module.JSON as Pandoc.JSON -import qualified Text.Pandoc.Lua.Module.Log as Pandoc.Log -import qualified Text.Pandoc.Lua.Module.MediaBag as Pandoc.MediaBag -import qualified Text.Pandoc.Lua.Module.Pandoc as Module.Pandoc -import qualified Text.Pandoc.Lua.Module.Scaffolding as Pandoc.Scaffolding -import qualified Text.Pandoc.Lua.Module.Structure as Pandoc.Structure -import qualified Text.Pandoc.Lua.Module.System as Pandoc.System -import qualified Text.Pandoc.Lua.Module.Template as Pandoc.Template -import qualified Text.Pandoc.Lua.Module.Text as Pandoc.Text -import qualified Text.Pandoc.Lua.Module.Types as Pandoc.Types -import qualified Text.Pandoc.Lua.Module.Utils as Pandoc.Utils import qualified Text.Pandoc.UTF8 as UTF8 --- | Run the Lua interpreter, using pandoc's default way of environment --- initialization. -runLua :: (PandocMonad m, MonadIO m) - => LuaE PandocError a -> m (Either PandocError a) -runLua action = do - runPandocLuaWith Lua.run . try $ do - initLuaState - liftPandocLua action - -runLuaWith :: (PandocMonad m, MonadIO m) - => GCManagedState -> LuaE PandocError a -> m (Either PandocError a) -runLuaWith luaState action = do - runPandocLuaWith (withGCManagedState luaState) . try $ do - initLuaState - liftPandocLua action - --- | Like 'runLua', but ignores all environment variables like @LUA_PATH@. -runLuaNoEnv :: (PandocMonad m, MonadIO m) - => LuaE PandocError a -> m (Either PandocError a) -runLuaNoEnv action = do - runPandocLuaWith Lua.run . try $ do - liftPandocLua $ do - -- This is undocumented, but works -- the code is adapted from the - -- `lua.c` sources for the default interpreter. - Lua.pushboolean True - Lua.setfield Lua.registryindex "LUA_NOENV" - initLuaState - liftPandocLua action - --- | Modules that are loaded at startup and assigned to fields in the --- pandoc module. --- --- Note that @pandoc.List@ is not included here for technical reasons; --- it must be handled separately. -loadedModules :: [Module PandocError] -loadedModules = - [ Pandoc.CLI.documentedModule - , Pandoc.Format.documentedModule - , Pandoc.Image.documentedModule - , Pandoc.JSON.documentedModule - , Pandoc.Log.documentedModule - , Pandoc.MediaBag.documentedModule - , Pandoc.Scaffolding.documentedModule - , Pandoc.Structure.documentedModule - , Pandoc.System.documentedModule - , Pandoc.Template.documentedModule - , Pandoc.Text.documentedModule - , Pandoc.Types.documentedModule - , Pandoc.Utils.documentedModule - , Module.Layout.documentedModule { moduleName = "pandoc.layout" } - `allSince` [2,18] - , Module.Path.documentedModule { moduleName = "pandoc.path" } - `allSince` [2,12] - , Module.Zip.documentedModule { moduleName = "pandoc.zip" } - `allSince` [3,0] - ] - where - allSince mdl version = mdl - { moduleFunctions = map (`since` makeVersion version) $ moduleFunctions mdl - } - --- | Initialize the lua state with all required values -initLuaState :: PandocLua () -initLuaState = do +-- | Initialize Lua with all default and pandoc-specific libraries and default +-- globals. +initLua :: PandocLua () +initLua = do liftPandocLua Lua.openlibs setWarnFunction - initJsonMetatable - initPandocModule - installLpegSearcher - setGlobalModules - loadInitScript "init.lua" - where - initPandocModule :: PandocLua () - initPandocModule = liftPandocLua $ do - -- Push module table - registerModule Module.Pandoc.documentedModule - -- load modules and add them to the `pandoc` module table. - forM_ loadedModules $ \mdl -> do - registerModule mdl - -- pandoc.text must be require-able as 'text' for backwards compat. - when (moduleName mdl == "pandoc.text") $ do - getfield registryindex loaded - pushvalue (nth 2) - setfield (nth 2) "text" - pop 1 -- _LOADED - -- Shorten name, drop everything before the first dot (if any). - let fieldname (Name mdlname) = Name . - maybe mdlname snd . Char8.uncons . snd $ - Char8.break (== '.') mdlname - Lua.setfield (nth 2) (fieldname $ moduleName mdl) - -- pandoc.List is low-level and must be opened differently. - requirehs "pandoc.List" (const pushListModule) - setfield (nth 2) "List" - -- assign module to global variable - Lua.setglobal "pandoc" - - loadInitScript :: FilePath -> PandocLua () - loadInitScript scriptFile = do - script <- readDataFile scriptFile - status <- liftPandocLua $ Lua.dostring script - when (status /= Lua.OK) . liftPandocLua $ do - err <- popException - let prefix = "Couldn't load '" <> T.pack scriptFile <> "':\n" - throwM . PandocLuaError . (prefix <>) $ case err of - PandocLuaError msg -> msg - _ -> T.pack $ show err - - setGlobalModules :: PandocLua () - setGlobalModules = liftPandocLua $ do - let globalModules = - [ ("lpeg", LPeg.luaopen_lpeg_ptr) -- must be loaded first - , ("re", LPeg.luaopen_re_ptr) -- re depends on lpeg - ] - loadedBuiltInModules <- fmap catMaybes . forM globalModules $ - \(pkgname, luaopen) -> do - Lua.pushcfunction luaopen - usedBuiltIn <- Lua.pcall 0 1 Nothing >>= \case - OK -> do -- all good, loading succeeded - -- register as loaded module so later modules can rely on this - Lua.getfield Lua.registryindex Lua.loaded - Lua.pushvalue (Lua.nth 2) - Lua.setfield (Lua.nth 2) pkgname - Lua.pop 1 -- pop _LOADED - return True - _ -> do -- built-in library failed, load system lib - Lua.pop 1 -- ignore error message - -- 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! - return False - - -- Module on top of stack. Register as global - Lua.setglobal pkgname - return $ if usedBuiltIn then Just pkgname else Nothing - - -- Remove module entry from _LOADED table in registry if we used a - -- built-in library. This ensures that later calls to @require@ will - -- prefer the shared library, if any. - forM_ loadedBuiltInModules $ \pkgname -> do - Lua.getfield Lua.registryindex Lua.loaded - Lua.pushnil - Lua.setfield (Lua.nth 2) pkgname - Lua.pop 1 -- registry - - 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 - --- | Setup the metatable that's assigned to Lua tables that were created --- from/via JSON arrays. -initJsonMetatable :: PandocLua () -initJsonMetatable = liftPandocLua $ do - newListMetatable HsLua.Aeson.jsonarray (pure ()) - Lua.pop 1 - --- | Evaluate a @'PandocLua'@ computation, running all contained Lua --- operations. -runPandocLuaWith :: (PandocMonad m, MonadIO m) - => (forall b. LuaE PandocError b -> IO b) - -> PandocLua a - -> m a -runPandocLuaWith runner pLua = do - origState <- getCommonState - globals <- defaultGlobals - (result, newState) <- liftIO . runner . unPandocLua $ do - putCommonState origState - liftPandocLua $ setGlobals globals - r <- pLua - c <- getCommonState - return (r, c) - putCommonState newState - return result - --- | Global variables which should always be set. -defaultGlobals :: PandocMonad m => m [Global] -defaultGlobals = do - commonState <- getCommonState - return - [ PANDOC_API_VERSION - , PANDOC_STATE commonState - , PANDOC_VERSION - ] + initModules + liftPandocLua userInit + +-- | User-controlled initialization, e.g., running the user's init script. +userInit :: LuaE PandocError () +userInit = runInitScript + +-- | Run the @init.lua@ data file as a Lua script. +runInitScript :: LuaE PandocError () +runInitScript = runDataFileScript "init.lua" + +-- | Get a data file and run it as a Lua script. +runDataFileScript :: FilePath -> LuaE PandocError () +runDataFileScript scriptFile = do + script <- unPandocLua $ readDataFile scriptFile + status <- Lua.dostring script + when (status /= Lua.OK) $ do + err <- popException + let prefix = "Couldn't load '" <> T.pack scriptFile <> "':\n" + throwM . PandocLuaError . (prefix <>) $ case err of + PandocLuaError msg -> msg + _ -> T.pack $ show err setWarnFunction :: PandocLua () setWarnFunction = liftPandocLua . setwarnf' $ \msg -> do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Marshal/LogMessage.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Marshal/LogMessage.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Marshal/LogMessage.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Marshal/LogMessage.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,7 +1,7 @@ {-# LANGUAGE OverloadedStrings #-} {- | Module : Text.Pandoc.Lua.Marshal.LogMessage - Copyright : © 2017-2023 Albert Krewinkel + Copyright : © 2017-2024 Albert Krewinkel License : GPL-2.0-or-later Maintainer : Albert Krewinkel <tarleb+pan...@moltkeplatz.de> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module/Template.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module/Template.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module/Template.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module/Template.hs 2001-09-09 03:46:40.000000000 +0200 @@ -21,7 +21,7 @@ import Text.Pandoc.Lua.PandocLua (PandocLua (unPandocLua), liftPandocLua) import Text.Pandoc.Writers.Shared (metaToContext') import Text.Pandoc.Templates - ( compileTemplate, getDefaultTemplate, renderTemplate + ( compileTemplate, getDefaultTemplate, getTemplate, renderTemplate , runWithPartials, runWithDefaultPartials ) import qualified Data.Text as T @@ -31,7 +31,7 @@ documentedModule = Module { moduleName = "pandoc.template" , moduleDescription = T.unlines - [ "Lua functions for pandoc templates." + [ "Handle pandoc templates." ] , moduleFields = [] , moduleOperations = [] @@ -50,7 +50,7 @@ #? T.unlines [ "Applies a context with variable assignments to a template," , "returning the rendered template. The `context` parameter must be a" - , "table with variable names as keys and [Doc], string, boolean, or" + , "table with variable names as keys and [[Doc]], string, boolean, or" , "table as values, where the table can be either be a list of the" , "aforementioned types, or a nested context." ] @@ -63,9 +63,22 @@ Nothing -> runWithDefaultPartials (compileTemplate "templates/default" template)) <#> parameter peekText "string" "template" "template string" - <#> opt (stringParam "templ_path" "template path") - =#> functionResult (either failLua pushTemplate) "pandoc Template" + <#> opt (stringParam "templates_path" + ("parameter to determine a default path and extension for " <> + "partials; uses the data files templates path by default.")) + =#> functionResult (either failLua pushTemplate) "Template" "compiled template" + #? T.unlines + [ "Compiles a template string into a [[Template]] object usable by" + , "pandoc." + , "" + , "If the `templates_path` parameter is specified, then it should be the" + , "file path associated with the template. It is used when checking" + , "for partials. Partials will be taken only from the default data" + , "files if this parameter is omitted." + , "" + , "An error is raised if compilation fails." + ] `since` makeVersion [2,17] , defun "default" @@ -76,11 +89,29 @@ format <- maybe getFORMAT pure mformat getDefaultTemplate format) <#> opt (textParam "writer" - "writer for which the template should be returned.") - =#> functionResult pushText "string" - "string representation of the writer's default template" + ("name of the writer for which the template should be " <> + "retrieved; defaults to the global `FORMAT`.")) + =#> functionResult pushText "string" "raw template" + #? T.unlines + [ "Returns the default template for a given writer as a string. An" + , "error is thrown if no such template can be found." + ] `since` makeVersion [2,17] + , defun "get" + ### (unPandocLua . getTemplate) + <#> stringParam "filename" "name of the template" + =#> textResult "content of template file" + #? T.unlines + [ "Retrieve text for a template." + , "" + , "This function first checks the resource paths for a file of this" + , "name; if none is found, the `templates` directory in the user data" + , "directory is checked. Returns the content of the file, or throws" + , "an error if no file is found." + ] + `since` makeVersion [3,2,1] + , defun "meta_to_context" ### (\meta blockWriterIdx inlineWriterIdx -> unPandocLua $ do let blockWriter blks = liftPandocLua $ do @@ -96,14 +127,14 @@ metaToContext' blockWriter inlineWriter meta) <#> parameter peekMeta "Meta" "meta" "document metadata" <#> parameter pure "function" "blocks_writer" - "converter from Blocks to Doc values" + "converter from [[Blocks]] to [[Doc]] values" <#> parameter pure "function" "inlines_writer" - "converter from Inlines to Doc values" + "converter from [[Inlines]] to [[Doc]] values" =#> functionResult pushContext "table" "template context" #? T.unlines - [ "Creates template context from the document's [Meta]{#type-meta}" - , "data, using the given functions to convert [Blocks] and [Inlines]" - , "to [Doc] values." + [ "Creates template context from the document's [[Meta]] data, using the" + , "given functions to convert [[Blocks]] and [[Inlines]] to [[Doc]]" + , "values." ] `since` makeVersion [3,0] ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module/Utils.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module/Utils.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module/Utils.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module/Utils.hs 2001-09-09 03:46:40.000000000 +0200 @@ -29,6 +29,7 @@ import Text.Pandoc.Definition import Text.Pandoc.Error (PandocError) import Text.Pandoc.Filter (applyJSONFilter) +import Text.Pandoc.Lua.Filter (runFilterFile') import Text.Pandoc.Lua.Marshal.AST import Text.Pandoc.Lua.Marshal.Reference import Text.Pandoc.Lua.PandocLua (PandocLua (unPandocLua)) @@ -60,6 +61,7 @@ , from_simple_table `since` v[2,11] , make_sections `since` v[2,8] , references `since` v[2,17] + , run_lua_filter `since` v[3,2,1] , run_json_filter `since` v[2,1,1] , normalize_date `since` v[2,0,6] , sha1 `since` v[2,0,6] @@ -246,6 +248,39 @@ , " end" ] +-- | Run a filter from a file. +run_lua_filter :: DocumentedFunction PandocError +run_lua_filter = defun "run_lua_filter" + ### (\doc fp mbenv -> do + envIdx <- maybe copyOfGlobalTable pure mbenv + runFilterFile' envIdx fp doc) + <#> parameter peekPandoc "Pandoc" "doc" "the Pandoc document to filter" + <#> parameter peekString "string" "filter" "filepath of the filter to run" + <#> opt (parameter (typeChecked "table" istable pure) "table" "env" + "environment to load and run the filter in") + =#> functionResult pushPandoc "Pandoc" "filtered document" + #? ( "Filter the given doc by passing it through a Lua filter." <> + "\n\nThe filter will be run in the current Lua process." <> + "\n" + ) + where + copynext :: LuaError e => StackIndex -> LuaE e StackIndex + copynext to = + Lua.next (nth 2) >>= \case + False -> pure to + True -> do + pushvalue (nth 2) + insert (nth 2) + rawset to + copynext to + copyOfGlobalTable :: LuaError e => LuaE e StackIndex + copyOfGlobalTable = do + newtable + pushglobaltable + pushnil + (copynext =<< absindex (nth 3)) <* pop 1 -- pop source table + +-- | Process the document with a JSON filter. run_json_filter :: DocumentedFunction PandocError run_json_filter = defun "run_json_filter" ### (\doc filterPath margs -> do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Module.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Module.hs 2001-09-09 03:46:40.000000000 +0200 @@ -0,0 +1,160 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{- | + Module : Text.Pandoc.Lua.Module + Copyright : © 2017-2024 Albert Krewinkel + License : GPL-2.0-or-later + Maintainer : Albert Krewinkel <pan...@tarleb.com> + +Setting up and initializing Lua modules. +-} + +module Text.Pandoc.Lua.Module + ( initModules + ) where + +import Control.Monad (forM, forM_, when) +import Data.Maybe (catMaybes) +import Data.Version (makeVersion) +import HsLua as Lua +import Text.Pandoc.Error (PandocError) +import Text.Pandoc.Lua.Marshal.List (pushPandocList, pushListModule) +import Text.Pandoc.Lua.PandocLua (PandocLua (..), liftPandocLua) +import qualified Data.ByteString.Char8 as Char8 +import qualified Lua.LPeg as LPeg +import qualified HsLua.Aeson +import qualified HsLua.Module.DocLayout as Module.Layout +import qualified HsLua.Module.Path as Module.Path +import qualified HsLua.Module.Zip as Module.Zip +import qualified Text.Pandoc.Lua.Module.CLI as Pandoc.CLI +import qualified Text.Pandoc.Lua.Module.Format as Pandoc.Format +import qualified Text.Pandoc.Lua.Module.Image as Pandoc.Image +import qualified Text.Pandoc.Lua.Module.JSON as Pandoc.JSON +import qualified Text.Pandoc.Lua.Module.Log as Pandoc.Log +import qualified Text.Pandoc.Lua.Module.MediaBag as Pandoc.MediaBag +import qualified Text.Pandoc.Lua.Module.Pandoc as Module.Pandoc +import qualified Text.Pandoc.Lua.Module.Scaffolding as Pandoc.Scaffolding +import qualified Text.Pandoc.Lua.Module.Structure as Pandoc.Structure +import qualified Text.Pandoc.Lua.Module.System as Pandoc.System +import qualified Text.Pandoc.Lua.Module.Template as Pandoc.Template +import qualified Text.Pandoc.Lua.Module.Text as Pandoc.Text +import qualified Text.Pandoc.Lua.Module.Types as Pandoc.Types +import qualified Text.Pandoc.Lua.Module.Utils as Pandoc.Utils + +initModules :: PandocLua () +initModules = do + initPandocModule + initJsonMetatable + installLpegSearcher + setGlobalModules + +initPandocModule :: PandocLua () +initPandocModule = liftPandocLua $ do + -- Push module table + registerModule Module.Pandoc.documentedModule + -- load modules and add them to the `pandoc` module table. + forM_ submodules $ \mdl -> do + registerModule mdl + -- pandoc.text must be require-able as 'text' for backwards compat. + when (moduleName mdl == "pandoc.text") $ do + getfield registryindex loaded + pushvalue (nth 2) + setfield (nth 2) "text" + pop 1 -- _LOADED + -- Shorten name, drop everything before the first dot (if any). + let fieldname (Name mdlname) = Name . + maybe mdlname snd . Char8.uncons . snd $ + Char8.break (== '.') mdlname + Lua.setfield (nth 2) (fieldname $ moduleName mdl) + -- pandoc.List is low-level and must be opened differently. + requirehs "pandoc.List" (const pushListModule) + setfield (nth 2) "List" + -- assign module to global variable + Lua.setglobal "pandoc" + +-- | Modules that are loaded at startup and assigned to fields in the +-- pandoc module. +-- +-- Note that @pandoc.List@ is not included here for technical reasons; +-- it must be handled separately. +submodules :: [Module PandocError] +submodules = + [ Pandoc.CLI.documentedModule + , Pandoc.Format.documentedModule + , Pandoc.Image.documentedModule + , Pandoc.JSON.documentedModule + , Pandoc.Log.documentedModule + , Pandoc.MediaBag.documentedModule + , Pandoc.Scaffolding.documentedModule + , Pandoc.Structure.documentedModule + , Pandoc.System.documentedModule + , Pandoc.Template.documentedModule + , Pandoc.Text.documentedModule + , Pandoc.Types.documentedModule + , Pandoc.Utils.documentedModule + , Module.Layout.documentedModule { moduleName = "pandoc.layout" } + `allSince` [2,18] + , Module.Path.documentedModule { moduleName = "pandoc.path" } + `allSince` [2,12] + , Module.Zip.documentedModule { moduleName = "pandoc.zip" } + `allSince` [3,0] + ] + where + allSince mdl version = mdl + { moduleFunctions = map (`since` makeVersion version) $ moduleFunctions mdl + } + +-- | Load all global modules and set them to their global variables. +setGlobalModules :: PandocLua () +setGlobalModules = liftPandocLua $ do + let globalModules = + [ ("lpeg", LPeg.luaopen_lpeg_ptr) -- must be loaded first + , ("re", LPeg.luaopen_re_ptr) -- re depends on lpeg + ] + loadedBuiltInModules <- fmap catMaybes . forM globalModules $ + \(pkgname, luaopen) -> do + Lua.pushcfunction luaopen + usedBuiltIn <- Lua.pcall 0 1 Nothing >>= \case + OK -> do -- all good, loading succeeded + -- register as loaded module so later modules can rely on this + Lua.getfield Lua.registryindex Lua.loaded + Lua.pushvalue (Lua.nth 2) + Lua.setfield (Lua.nth 2) pkgname + Lua.pop 1 -- pop _LOADED + return True + _ -> do -- built-in library failed, load system lib + Lua.pop 1 -- ignore error message + -- 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! + return False + + -- Module on top of stack. Register as global + Lua.setglobal pkgname + return $ if usedBuiltIn then Just pkgname else Nothing + + -- Remove module entry from _LOADED table in registry if we used a + -- built-in library. This ensures that later calls to @require@ will + -- prefer the shared library, if any. + forM_ loadedBuiltInModules $ \pkgname -> do + Lua.getfield Lua.registryindex Lua.loaded + Lua.pushnil + Lua.setfield (Lua.nth 2) pkgname + Lua.pop 1 -- registry + +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 + +-- | Setup the metatable that's assigned to Lua tables that were created +-- from/via JSON arrays. +initJsonMetatable :: PandocLua () +initJsonMetatable = liftPandocLua $ do + pushPandocList (const pushnil) [] + getmetatable top + setfield registryindex HsLua.Aeson.jsonarray + Lua.pop 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/PandocLua.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/PandocLua.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/PandocLua.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/PandocLua.hs 2001-09-09 03:46:40.000000000 +0200 @@ -77,10 +77,12 @@ getModificationTime = IO.getModificationTime getCommonState = PandocLua $ do - Lua.getglobal "PANDOC_STATE" + Lua.getfield registryindex "PANDOC_STATE" forcePeek $ peekCommonState Lua.top `lastly` pop 1 putCommonState cst = PandocLua $ do pushCommonState cst + Lua.pushvalue Lua.top + Lua.setfield registryindex "PANDOC_STATE" Lua.setglobal "PANDOC_STATE" logOutput = IO.logOutput diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Run.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Run.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua/Run.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua/Run.hs 2001-09-09 03:46:40.000000000 +0200 @@ -0,0 +1,82 @@ +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{- | + Module : Text.Pandoc.Lua.Run + Copyright : Copyright © 2017-2024 Albert Krewinkel + License : GPL-2.0-or-later + Maintainer : Albert Krewinkel <tarleb+pan...@moltkeplatz.de> + +Run code in the Lua interpreter. +-} +module Text.Pandoc.Lua.Run + ( runLua + , runLuaNoEnv + , runLuaWith + ) where + +import Control.Monad.Catch (try) +import Control.Monad.Trans (MonadIO (..)) +import HsLua as Lua hiding (try) +import Text.Pandoc.Class (PandocMonad (..)) +import Text.Pandoc.Error (PandocError) +import Text.Pandoc.Lua.Global (Global (..), setGlobals) +import Text.Pandoc.Lua.Init (initLua) +import Text.Pandoc.Lua.PandocLua (PandocLua (..), liftPandocLua) + +-- | Run the Lua interpreter, using pandoc's default way of environment +-- initialization. +runLua :: (PandocMonad m, MonadIO m) + => LuaE PandocError a -> m (Either PandocError a) +runLua action = do + runPandocLuaWith Lua.run . try $ do + initLua + liftPandocLua action + +runLuaWith :: (PandocMonad m, MonadIO m) + => GCManagedState -> LuaE PandocError a -> m (Either PandocError a) +runLuaWith luaState action = do + runPandocLuaWith (withGCManagedState luaState) . try $ do + initLua + liftPandocLua action + +-- | Like 'runLua', but ignores all environment variables like @LUA_PATH@. +runLuaNoEnv :: (PandocMonad m, MonadIO m) + => LuaE PandocError a -> m (Either PandocError a) +runLuaNoEnv action = do + runPandocLuaWith Lua.run . try $ do + liftPandocLua $ do + -- This is undocumented, but works -- the code is adapted from the + -- `lua.c` sources for the default interpreter. + Lua.pushboolean True + Lua.setfield Lua.registryindex "LUA_NOENV" + initLua + liftPandocLua action + +-- | Evaluate a @'PandocLua'@ computation, running all contained Lua +-- operations. +runPandocLuaWith :: (PandocMonad m, MonadIO m) + => (forall b. LuaE PandocError b -> IO b) + -> PandocLua a + -> m a +runPandocLuaWith runner pLua = do + origState <- getCommonState + globals <- defaultGlobals + (result, newState) <- liftIO . runner . unPandocLua $ do + putCommonState origState + liftPandocLua $ setGlobals globals + r <- pLua + c <- getCommonState + return (r, c) + putCommonState newState + return result + +-- | Global variables which should always be set. +defaultGlobals :: PandocMonad m => m [Global] +defaultGlobals = do + commonState <- getCommonState + return + [ PANDOC_API_VERSION + , PANDOC_STATE commonState + , PANDOC_VERSION + ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua.hs new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua.hs --- old/pandoc-lua-engine-0.2.1.5/src/Text/Pandoc/Lua.hs 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/src/Text/Pandoc/Lua.hs 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,3 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeApplications #-} {- | Module : Text.Pandoc.Lua Copyright : Copyright © 2017-2024 Albert Krewinkel @@ -23,26 +21,8 @@ , getEngine ) where -import Control.Monad.IO.Class (MonadIO (liftIO)) -import HsLua.Core (getglobal, openlibs, run, top, tostring) -import Text.Pandoc.Error (PandocError) -import Text.Pandoc.Lua.Filter (applyFilter) -import Text.Pandoc.Lua.Global (Global (..), setGlobals) -import Text.Pandoc.Lua.Init (runLua, runLuaNoEnv) import Text.Pandoc.Lua.Custom (loadCustom) +import Text.Pandoc.Lua.Engine (getEngine, applyFilter) +import Text.Pandoc.Lua.Global (Global (..), setGlobals) +import Text.Pandoc.Lua.Run (runLua, runLuaNoEnv) import Text.Pandoc.Lua.Orphans () -import Text.Pandoc.Scripting (ScriptingEngine (..)) -import qualified Text.Pandoc.UTF8 as UTF8 - --- | Constructs the Lua scripting engine. -getEngine :: MonadIO m => m ScriptingEngine -getEngine = do - versionName <- liftIO . run @PandocError $ do - openlibs - getglobal "_VERSION" - tostring top - pure $ ScriptingEngine - { engineName = maybe "Lua (unknown version)" UTF8.toText versionName - , engineApplyFilter = applyFilter - , engineLoadCustom = loadCustom - } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/test/lua/module/globals.lua new/pandoc-lua-engine-0.3/test/lua/module/globals.lua --- old/pandoc-lua-engine-0.2.1.5/test/lua/module/globals.lua 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/test/lua/module/globals.lua 2001-09-09 03:46:40.000000000 +0200 @@ -107,5 +107,51 @@ test('wrap_text', function () assert.are_equal(type(PANDOC_WRITER_OPTIONS.wrap_text), 'string') end), - } + }, + + group 'PANDOC_STATE' { + test('is a userdata object', function () + assert.are_equal(type(PANDOC_STATE), 'userdata') + end), + test('has property "input_files"', function () + assert.are_equal(type(PANDOC_STATE.input_files), 'table') + end), + test('has optional property "output_file"', function () + -- property may be nil + if PANDOC_STATE.output_file then + assert.are_equal(type(PANDOC_STATE.output_file), 'string') + end + end), + test('has property "log"', function () + assert.are_equal(type(PANDOC_STATE.log), 'table') + end), + test('has property "request_headers"', function () + assert.are_equal(type(PANDOC_STATE.request_headers), 'table') + end), + test('has property "resource_path"', function () + assert.are_equal(type(PANDOC_STATE.resource_path), 'table') + end), + test('has optional property "source_url"', function () + if PANDOC_STATE.source_url then + assert.are_equal(type(PANDOC_STATE.source_url), 'string') + end + end), + test('has property "trace"', function () + assert.are_equal(type(PANDOC_STATE.trace), 'boolean') + end), + test('has optional property "user_data_dir"', function () + if PANDOC_STATE.user_data_dir then + assert.are_equal(type(PANDOC_STATE.user_data_dir), 'string') + end + end), + test('has property "verbosity"', function () + assert.are_equal(type(PANDOC_STATE.verbosity), 'string') + end), + test('can be deleted without breaking PandocLua monad functions', function() + local state = PANDOC_STATE + PANDOC_STATE = nil + assert.is_nil(pandoc.mediabag.lookup('does-not-exist')) + PANDOC_STATE = state + end), + }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-json.lua new/pandoc-lua-engine-0.3/test/lua/module/pandoc-json.lua --- old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-json.lua 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/test/lua/module/pandoc-json.lua 2001-09-09 03:46:40.000000000 +0200 @@ -1,6 +1,7 @@ -- -- Tests for the system module -- +local pandoc = require 'pandoc' local json = require 'pandoc.json' local tasty = require 'tasty' @@ -33,19 +34,26 @@ local obj = setmetatable( {title = 23}, { - __tojson = function (obj) + __tojson = function (_) return '"Nichts ist so wie es scheint"' end } ) assert.are_same(json.encode(obj), [["Nichts ist so wie es scheint"]]) end), - test('Inline (Space)', function () + test('pandoc.List', function () + local list = pandoc.List {'foo', 'bar', 'baz'} assert.are_equal( - json.encode(pandoc.Space()), - '{"t":"Space"}' + json.encode(list), + '["foo","bar","baz"]' ) end), + test('Inline (Space)', function () + assert.are_equal( + json.encode(pandoc.Space()), + '{"t":"Space"}' + ) + end), test('Block (HorizontalRule)', function () assert.are_equal( json.encode(pandoc.HorizontalRule()), @@ -85,6 +93,9 @@ test('object', function () assert.are_same(json.decode '{"a":5}', {a = 5}) end), + test('list of strings', function () + assert.are_equal(json.decode '["foo", "bar"]', pandoc.List{"foo", "bar"}) + end), test('Inline (Space)', function () assert.are_equal(json.decode '{"t":"Space"}', pandoc.Space()) end), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-template.lua new/pandoc-lua-engine-0.3/test/lua/module/pandoc-template.lua --- old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-template.lua 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/test/lua/module/pandoc-template.lua 2001-09-09 03:46:40.000000000 +0200 @@ -1,4 +1,5 @@ local tasty = require 'tasty' +local pandoc = require 'pandoc' local template = require 'pandoc.template' local assert = tasty.assert @@ -24,8 +25,25 @@ ) end), test('fails on unknown format', function () + local success, msg = pcall(function () + return pandoc.utils.type(template.default 'nosuchformat') + end) + assert.is_falsy(success) + end), + }, + group 'get' { + test('is function', function () + assert.are_equal(type(template.get), 'function') + end), + test('searches the template data directory', function () + assert.are_equal( + template.default 'html5', + template.get 'default.html5' + ) + end), + test('fails on non-existent file', function () local success, msg = pcall(function () - return pandoc.utils.type(template.default 'nosuchformat') + return pandoc.utils.type(template.get 'nosuchfile.nope') end) assert.is_falsy(success) end), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-utils.lua new/pandoc-lua-engine-0.3/test/lua/module/pandoc-utils.lua --- old/pandoc-lua-engine-0.2.1.5/test/lua/module/pandoc-utils.lua 2001-09-09 03:46:40.000000000 +0200 +++ new/pandoc-lua-engine-0.3/test/lua/module/pandoc-utils.lua 2001-09-09 03:46:40.000000000 +0200 @@ -1,5 +1,7 @@ local tasty = require 'tasty' +local pandoc = require 'pandoc' local utils = require 'pandoc.utils' +local io = require 'io' local assert = tasty.assert local test = tasty.test_case @@ -127,6 +129,48 @@ end) }, + group 'run_lua_filter' { + test('runs a filter', function () + local doc = pandoc.Pandoc("indivisible words") + pandoc.system.with_temporary_directory('lua-filter', function (dir) + local filter_path = pandoc.path.join{dir, 'test.lua'} + local filter = 'function Space() return " " end' + local fh = io.open(filter_path, 'wb') + fh:write(filter) + fh:close() + assert.are_equal( + utils.run_lua_filter(doc, filter_path), + pandoc.Pandoc( + pandoc.Plain(pandoc.Inlines{"indivisible", " ", "words"}) + ) + ) + end) + end), + test("doesn't change the local environment by default", function () + pandoc.system.with_temporary_directory('lua-filter', function (dir) + local filter_path = pandoc.path.join{dir, 'test.lua'} + local foo + local filter = 'foo = 42' + local fh = io.open(filter_path, 'wb') + fh:write(filter) + fh:close() + utils.run_lua_filter(pandoc.Pandoc{}, filter_path) + assert.is_nil(foo) + end) + end), + test("accepts an environment in which the filter is executed", function () + pandoc.system.with_temporary_directory('lua-filter', function (dir) + local filter_path = pandoc.path.join{dir, 'test.lua'} + local filter = 'foo = 42' + local fh = io.open(filter_path, 'wb') + fh:write(filter) + fh:close() + utils.run_lua_filter(pandoc.Pandoc{}, filter_path, _ENV) + assert.are_equal(_ENV.foo, 42) + end) + end) + }, + group 'sha1' { test('hashing', function () local ref_hash = '0a0a9f2a6772942557ab5355d76af442f8f65e01'