From 786594b23be4a757e95776f782527c8a98fbaab5 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Sat, 4 May 2019 07:06:30 +0200 Subject: Lua: add `pandoc.system` module (#5468) The `system` Lua module provides utility functions to interact with the operating- and file system. E.g. print(pandoc.system.get_current_directory()) or pandoc.system.with_temporary_directory('tikz', function (dir) -- write and compile a TikZ file with pdflatex end) --- data/pandoc.lua | 1 + doc/lua-filters.md | 108 +++++++++++++++++++++++++++++++++++ pandoc.cabal | 2 + src/Text/Pandoc/Lua/Module/System.hs | 34 +++++++++++ src/Text/Pandoc/Lua/Packages.hs | 2 + stack.yaml | 1 + test/Tests/Lua.hs | 5 ++ 7 files changed, 153 insertions(+) create mode 100644 src/Text/Pandoc/Lua/Module/System.hs diff --git a/data/pandoc.lua b/data/pandoc.lua index b69070e81..8a45a39e9 100644 --- a/data/pandoc.lua +++ b/data/pandoc.lua @@ -27,6 +27,7 @@ local M = {} -- Re-export bundled modules M.List = require 'pandoc.List' M.mediabag = require 'pandoc.mediabag' +M.system = require 'pandoc.system' M.utils = require 'pandoc.utils' M.text = require 'text' diff --git a/doc/lua-filters.md b/doc/lua-filters.md index 433233ea1..3b3bb2f17 100644 --- a/doc/lua-filters.md +++ b/doc/lua-filters.md @@ -2618,3 +2618,111 @@ Parameters: Returns: a new list containing all items for which \`test\` was true. + +# Module pandoc.system + +Access to system information and functionality. + +## Static Fields {#system-fields} + +### arch {#system-arch} + +The machine architecture on which the program is running. + +### os {#system-os} + +The operating system on which the program is running. + +## Functions {#system-functions} + +### environment {#system-environment} + +`environment ()` + +Retrieve the entire environment as a string-indexed table. + +Returns: + +- A table mapping environment variables names to their string value + (table). + +### get\_working\_directory {#system-get_working_directory} + +`get_working_directory ()` + +Obtain the current working directory as an absolute path. + +Returns: + +- The current working directory (string). + +### with\_environment {#system-with_environment} + +`with_environment (environment, callback)` + +Run an action within a custom environment. Only the environment +variables given by `environment` will be set, when `callback` is +called. The original environment is restored after this function +finishes, even if an error occurs while running the callback +action. + +Parameters: + +`environment` +: Environment variables and their values to be set before + running `callback`. (table with string keys and string + values) + +`callback` +: Action to execute in the custom environment (function) + +Returns: + +- The result(s) of the call to `callback` + +### with\_temporary\_directory {#system-with_temporary_directory} + +`with_temporary_directory ([parent_dir,] templ, callback)` + +Create and use a temporary directory inside the given directory. +The directory is deleted after the callback returns. + +Parameters: + +`parent_dir` +: Parent directory to create the directory in (string). If this + parameter is omitted, the system's canonical temporary + directory is used. + +`templ` +: Directory name template (string). + +`callback` +: Function which takes the name of the temporary directory as its + first argument (function). + +Returns: + +- The result of the call to `callback`. + +### with\_working\_directory {#system-with_working_directory} + +`with_working_directory (directory, callback)` + +Run an action within a different directory. This function will +change the working directory to `directory`, execute `callback`, +then switch back to the original working directory, even if an +error occurs while running the callback action. + +Parameters: + +`directory` +: Directory in which the given `callback` should be executed + (string) + +`callback` +: Action to execute in the given directory (function) + +Returns: + +- The result(s) of the call to `callback` diff --git a/pandoc.cabal b/pandoc.cabal index c35869891..7d2ae5c06 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -394,6 +394,7 @@ library blaze-markup >= 0.8 && < 0.9, vector >= 0.10 && < 0.13, hslua >= 1.0.1 && < 1.1, + hslua-module-system >= 0.2 && < 0.3, hslua-module-text >= 0.2 && < 0.3, binary >= 0.5 && < 0.11, SHA >= 1.6 && < 1.7, @@ -591,6 +592,7 @@ library Text.Pandoc.Lua.Marshaling.ReaderOptions, Text.Pandoc.Lua.Module.MediaBag, Text.Pandoc.Lua.Module.Pandoc, + Text.Pandoc.Lua.Module.System, Text.Pandoc.Lua.Module.Utils, Text.Pandoc.Lua.Packages, Text.Pandoc.Lua.Util, diff --git a/src/Text/Pandoc/Lua/Module/System.hs b/src/Text/Pandoc/Lua/Module/System.hs new file mode 100644 index 000000000..5149c2112 --- /dev/null +++ b/src/Text/Pandoc/Lua/Module/System.hs @@ -0,0 +1,34 @@ +{- | + Module : Text.Pandoc.Lua.Module.System + Copyright : © 2019 Albert Krewinkel + License : GNU GPL, version 2 or above + + Maintainer : Albert Krewinkel + Stability : alpha + +Pandoc's system Lua module. +-} +module Text.Pandoc.Lua.Module.System + ( pushModule + ) where + +import Prelude +import Foreign.Lua (Lua, NumResults) +import Foreign.Lua.Module.System (arch, env, getwd, os, + with_env, with_tmpdir, with_wd) +import Text.Pandoc.Lua.Util (addFunction, addField) + +import qualified Foreign.Lua as Lua + +-- | Push the pandoc.system module on the Lua stack. +pushModule :: Lua NumResults +pushModule = do + Lua.newtable + addField "arch" arch + addField "os" os + addFunction "environment" env + addFunction "get_current_directory" getwd + addFunction "with_environment" with_env + addFunction "with_temp_directory" with_tmpdir + addFunction "with_working_directory" with_wd + return 1 diff --git a/src/Text/Pandoc/Lua/Packages.hs b/src/Text/Pandoc/Lua/Packages.hs index fdfa2238a..5f2751f52 100644 --- a/src/Text/Pandoc/Lua/Packages.hs +++ b/src/Text/Pandoc/Lua/Packages.hs @@ -25,6 +25,7 @@ import Text.Pandoc.Class (readDataFile, runIO, setUserDataDir) import qualified Foreign.Lua as Lua import Text.Pandoc.Lua.Module.Pandoc as Pandoc import Text.Pandoc.Lua.Module.MediaBag as MediaBag +import Text.Pandoc.Lua.Module.System as System import Text.Pandoc.Lua.Module.Utils as Utils -- | Parameters used to create lua packages/modules. @@ -52,6 +53,7 @@ pandocPackageSearcher pkgParams pkgName = "pandoc" -> let datadir = luaPkgDataDir pkgParams in pushWrappedHsFun (Pandoc.pushModule datadir) "pandoc.mediabag" -> pushWrappedHsFun MediaBag.pushModule + "pandoc.system" -> pushWrappedHsFun System.pushModule "pandoc.utils" -> let datadir = luaPkgDataDir pkgParams in pushWrappedHsFun (Utils.pushModule datadir) _ -> searchPureLuaLoader diff --git a/stack.yaml b/stack.yaml index dc28bf0db..d07793f28 100644 --- a/stack.yaml +++ b/stack.yaml @@ -14,6 +14,7 @@ extra-deps: - pandoc-citeproc-0.16.2 - ipynb-0.1 - cmark-gfm-0.2.0 +- hslua-module-system-0.2.0 ghc-options: "$locals": -Wall -fno-warn-unused-do-bind -Wincomplete-record-updates -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances -Wincomplete-uni-patterns -Widentities -Wcpp-undef -fhide-source-paths resolver: lts-13.17 diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs index a66952de8..4040c38ac 100644 --- a/test/Tests/Lua.hs +++ b/test/Tests/Lua.hs @@ -185,6 +185,11 @@ tests = map (localOption (QuickCheckTests 20)) Lua.liftIO . assertEqual "no accessor" (("hi", ["moin"], []) :: Attr) =<< Lua.peek Lua.stackTop + , testCase "module `pandoc.system` is present" . runLua' $ do + Lua.getglobal' "pandoc.system" + ty <- Lua.ltype Lua.stackTop + Lua.liftIO $ assertEqual "module should be a table" Lua.TypeTable ty + , testCase "informative error messages" . runLua' $ do Lua.pushboolean True err <- Lua.peekEither Lua.stackTop -- cgit v1.2.3