mirror of
https://github.com/jgm/pandoc.git
synced 2026-08-23 00:36:29 +00:00
Lua: add function pandoc.utils.run_lua_filter (#9803)
This commit is contained in:
@@ -3910,6 +3910,28 @@ Returns:
|
||||
|
||||
*Since: 2.17*
|
||||
|
||||
### run_filter_filter {#pandoc.utils.run_filter_filter}
|
||||
|
||||
`run_filter_filter (doc, filter)`
|
||||
|
||||
Filter the given doc by passing it through a Lua filter.
|
||||
|
||||
The filter will be run in the current Lua process.
|
||||
|
||||
Parameters:
|
||||
|
||||
`doc`
|
||||
: the Pandoc document to filter ([Pandoc])
|
||||
|
||||
`filter`
|
||||
: filepath of the filter to run (string)
|
||||
|
||||
Returns:
|
||||
|
||||
- filtered document ([Pandoc])
|
||||
|
||||
*Since: 3.2.1*
|
||||
|
||||
### run_json_filter {#pandoc.utils.run_json_filter}
|
||||
|
||||
`run_json_filter (doc, filter[, args])`
|
||||
|
||||
@@ -67,6 +67,7 @@ library
|
||||
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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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+pandoc@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.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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user