diff options
Diffstat (limited to 'pandoc-lua-engine/src/Text')
| -rw-r--r-- | pandoc-lua-engine/src/Text/Pandoc/Lua.hs | 22 | ||||
| -rw-r--r-- | pandoc-lua-engine/src/Text/Pandoc/Lua/Engine.hs | 73 | ||||
| -rw-r--r-- | pandoc-lua-engine/src/Text/Pandoc/Lua/Filter.hs | 50 | ||||
| -rw-r--r-- | pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Utils.hs | 14 |
4 files changed, 93 insertions, 66 deletions
diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua.hs index 0bc28b2a7..0039e1025 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua.hs @@ -1,5 +1,3 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeApplications #-} {- | Module : Text.Pandoc.Lua Copyright : Copyright © 2017-2024 Albert Krewinkel @@ -23,26 +21,8 @@ module Text.Pandoc.Lua , 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.Engine (getEngine, 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.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 --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Engine.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Engine.hs new file mode 100644 index 000000000..243e7f99a --- /dev/null +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Engine.hs @@ -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 <[email protected]> + +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.Filter (runFilterFile) +import Text.Pandoc.Lua.Global (Global (..), setGlobals) +import Text.Pandoc.Lua.Init (runLua) +import Text.Pandoc.Lua.Custom (loadCustom) +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 --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Filter.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Filter.hs index 994339333..549b82768 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Filter.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Filter.hs @@ -1,7 +1,3 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE IncoherentInstances #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} {- | Module : Text.Pandoc.Lua.Filter Copyright : © 2012-2024 John MacFarlane, @@ -13,29 +9,22 @@ Stability : alpha Types and functions for running Lua filters. -} module Text.Pandoc.Lua.Filter - ( applyFilter + ( runFilterFile ) where import Control.Monad ((>=>), (<$!>)) -import HsLua as Lua -import Text.Pandoc.Definition -import Text.Pandoc.Filter (Environment (..)) +import HsLua +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. runFilterFile :: FilePath -> Pandoc -> LuaE PandocError Pandoc runFilterFile filterPath doc = do oldtop <- gettop stat <- dofileTrace (Just filterPath) - if stat /= Lua.OK + if stat /= OK then throwErrorAsException else do newtop <- gettop @@ -50,32 +39,3 @@ runFilterFile filterPath doc = do 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 diff --git a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Utils.hs b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Utils.hs index 5fddf6e8b..fb3484465 100644 --- a/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Utils.hs +++ b/pandoc-lua-engine/src/Text/Pandoc/Lua/Module/Utils.hs @@ -29,6 +29,7 @@ import Text.Pandoc.Citeproc (getReferences, processCitations) 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 @@ documentedModule = Module , 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,18 @@ references = defun "references" , " end" ] +-- | Run a filter from a file. +run_lua_filter :: DocumentedFunction PandocError +run_lua_filter = defun "run_filter_filter" + ### (flip runFilterFile) + <#> parameter peekPandoc "Pandoc" "doc" "the Pandoc document to filter" + <#> parameter peekString "string" "filter" "filepath of the filter to run" + =#> 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." + ) + +-- | Process the document with a JSON filter. run_json_filter :: DocumentedFunction PandocError run_json_filter = defun "run_json_filter" ### (\doc filterPath margs -> do |
