diff options
Diffstat (limited to 'src/Text/Pandoc/Filter')
-rw-r--r-- | src/Text/Pandoc/Filter/Lua.hs | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/src/Text/Pandoc/Filter/Lua.hs b/src/Text/Pandoc/Filter/Lua.hs index d559fb912..6c78bef06 100644 --- a/src/Text/Pandoc/Filter/Lua.hs +++ b/src/Text/Pandoc/Filter/Lua.hs @@ -32,24 +32,55 @@ module Text.Pandoc.Filter.Lua (apply) where import Prelude import Control.Exception (throw) +import Control.Monad ((>=>)) +import Foreign.Lua (Lua) import Text.Pandoc.Class (PandocIO) import Text.Pandoc.Definition (Pandoc) import Text.Pandoc.Error (PandocError (PandocFilterError)) import Text.Pandoc.Filter.Path (expandFilterPath) -import Text.Pandoc.Lua (LuaException (..), runLuaFilter) +import Text.Pandoc.Lua (LuaException (..), runPandocLua) +import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter) +import Text.Pandoc.Lua.Global (Global (..), setGlobals) +import Text.Pandoc.Lua.Util (dofileWithTraceback) import Text.Pandoc.Options (ReaderOptions) +import qualified Foreign.Lua as Lua + +-- | 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. apply :: ReaderOptions -> [String] -> FilePath -> Pandoc -> PandocIO Pandoc -apply ropts args f d = do - f' <- expandFilterPath f +apply ropts args f doc = do + filterPath <- expandFilterPath f let format = case args of (x:_) -> x - _ -> error "Format not supplied for lua filter" - res <- runLuaFilter ropts f' format d - case res of - Right x -> return x - Left (LuaException s) -> throw (PandocFilterError f s) + _ -> error "Format not supplied for Lua filter" + runPandocLua >=> forceResult filterPath $ do + setGlobals [ FORMAT format + , PANDOC_READER_OPTIONS ropts + , PANDOC_SCRIPT_FILE filterPath + ] + top <- Lua.gettop + stat <- dofileWithTraceback filterPath + if stat /= Lua.OK + then Lua.throwTopMessage + else do + newtop <- Lua.gettop + -- Use the returned filters, or the implicitly defined global + -- filter if nothing was returned. + luaFilters <- if newtop - top >= 1 + then Lua.peek Lua.stackTop + else Lua.pushglobaltable *> fmap (:[]) Lua.popValue + runAll luaFilters doc + +forceResult :: FilePath -> Either LuaException Pandoc -> PandocIO Pandoc +forceResult fp eitherResult = case eitherResult of + Right x -> return x + Left (LuaException s) -> throw (PandocFilterError fp s) + +runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc +runAll = foldr ((>=>) . walkMWithLuaFilter) return |