aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Krewinkel <[email protected]>2023-03-17 15:39:51 +0100
committerJohn MacFarlane <[email protected]>2023-03-18 15:00:45 -0700
commit203a652e4318a6bce2685ea02b16c669b36fc16a (patch)
tree706008d1c6101b0f3e58a3f8e8a26c39a1c4123e
parentf9b6777a92ab304149b93f34a40a36e5e9c95bf5 (diff)
Lua: add pandoc.cli.repl function
-rw-r--r--doc/lua-filters.md34
-rw-r--r--pandoc-lua-engine/pandoc-lua-engine.cabal1
-rw-r--r--pandoc-lua-engine/src/Text/Pandoc/Lua/Module/CLI.hs62
3 files changed, 93 insertions, 4 deletions
diff --git a/doc/lua-filters.md b/doc/lua-filters.md
index 53edfd9b1..37bc89d81 100644
--- a/doc/lua-filters.md
+++ b/doc/lua-filters.md
@@ -3747,6 +3747,40 @@ Returns:
- parsed options, using their JSON-like representation. (table)
+### repl {#pandoc.cli.repl}
+
+`repl ([env])`
+
+Starts a read-eval-print loop (REPL). The function returns all
+values of the last evaluated input. Exit the REPL by pressing
+`ctrl-d` or `ctrl-c`; press `F1` to get a list of all key
+bindings.
+
+The REPL is started in the global namespace, unless the `env`
+parameter is specified. In that case, the global namespace is
+merged into the given table and the result is used as `_ENV` value
+for the repl.
+
+Specifically, local variables *cannot* be accessed, unless they
+are explicitly passed via the `env` parameter; e.g.
+
+ function Pandoc (doc)
+ -- start repl, allow to access the `doc` parameter
+ -- in the repl
+ return pandoc.cli.repl{ doc = doc }
+ end
+
+Parameters:
+
+`env`
+: Extra environment; the global environment is merged into this
+ table. (table)
+
+Returns:
+
+The result(s) of the last evaluated input, or nothing if the last
+input resulted in an error.
+
# Module pandoc.utils
diff --git a/pandoc-lua-engine/pandoc-lua-engine.cabal b/pandoc-lua-engine/pandoc-lua-engine.cabal
index 697dd3bda..35cfde763 100644
--- a/pandoc-lua-engine/pandoc-lua-engine.cabal
+++ b/pandoc-lua-engine/pandoc-lua-engine.cabal
@@ -111,6 +111,7 @@ library
, hslua-module-text >= 1.1 && < 1.2
, hslua-module-version >= 1.1 && < 1.2
, hslua-module-zip >= 1.1 && < 1.2
+ , hslua-repl >= 0.1.1 && < 0.2
, lpeg >= 1.0.4 && < 1.1
, mtl >= 2.2 && < 2.4
, pandoc >= 3.1 && < 3.2
diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/CLI.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/CLI.hs
index 533482d6b..89c9741af 100644
--- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/CLI.hs
+++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/CLI.hs
@@ -13,10 +13,8 @@ module Text.Pandoc.Lua.Module.CLI
) where
import Control.Applicative ((<|>))
-import HsLua ( Field (..), Module (..), (###), (<#>), (=#>), (#?)
- , defun, failLua, functionResult, liftIO, parameter, pop
- , pushViaJSON, rawgeti, top)
-import HsLua.Marshalling (lastly, liftLua, peekList, peekString)
+import HsLua
+import HsLua.REPL (defaultConfig, replWithEnv, setup)
import Text.Pandoc.App (defaultOpts, options, parseOptionsFromArgs)
import Text.Pandoc.Error (PandocError)
import Text.Pandoc.Lua.PandocLua ()
@@ -49,6 +47,8 @@ documentedModule = Module
, "Typically this function will be used in stand-alone pandoc Lua"
, "scripts, taking the list of arguments from the global `arg`."
]
+
+ , repl
]
, moduleOperations = []
, moduleTypeInitializers = []
@@ -64,3 +64,57 @@ documentedModule = Module
\case
Left e -> failLua $ "Cannot process info option: " ++ show e
Right opts -> pure opts
+
+-- | Starts a REPL.
+repl :: DocumentedFunction PandocError
+repl = defun "repl"
+ ### (\menvIdx -> do
+ let repl' = case menvIdx of
+ Nothing -> replWithEnv Nothing
+ Just envIdx -> do
+ settop envIdx
+ fillWithGlobals envIdx
+ replWithEnv . Just =<< ref registryindex
+ setup defaultConfig
+ repl')
+ <#> opt (parameter (typeChecked "table" istable pure) "table" "env"
+ ("Extra environment; the global environment is merged into this" <>
+ "table."))
+ =?> T.unlines
+ [ "The result(s) of the last evaluated input, or nothing if the last"
+ , "input resulted in an error."
+ ]
+ #? T.unlines
+ [ "Starts a read-eval-print loop (REPL). The function returns all"
+ , "values of the last evaluated input. Exit the REPL by pressing"
+ , "`ctrl-d` or `ctrl-c`; press `F1` to get a list of all key"
+ , "bindings."
+ , ""
+ , "The REPL is started in the global namespace, unless the `env`"
+ , "parameter is specified. In that case, the global namespace is"
+ , "merged into the given table and the result is used as `_ENV` value"
+ , "for the repl."
+ , ""
+ , "Specifically, local variables *cannot* be accessed, unless they"
+ , "are explicitly passed via the `env` parameter; e.g."
+ , ""
+ , " function Pandoc (doc)"
+ , " -- start repl, allow to access the `doc` parameter"
+ , " -- in the repl"
+ , " return pandoc.cli.repl{ doc = doc }"
+ , " end"
+ ]
+ where
+ fillWithGlobals idx = do
+ -- Copy all global values into the table
+ pushglobaltable
+ pushnil
+ let copyval = next (nth 2) >>= \case
+ False -> return ()
+ True -> do
+ pushvalue (nth 2)
+ insert (nth 2)
+ rawset idx
+ copyval
+ copyval
+ pop 1 -- global table