@@ -32,24 +32,55 @@ module Text.Pandoc.Filter.Lua (apply) where
3232
3333import Prelude
3434import Control.Exception (throw)
35+import Control.Monad ((>=>))
36+import Foreign.Lua (Lua)
3537import Text.Pandoc.Class (PandocIO)
3638import Text.Pandoc.Definition (Pandoc)
3739import Text.Pandoc.Error (PandocError (PandocFilterError))
3840import Text.Pandoc.Filter.Path (expandFilterPath)
39−import Text.Pandoc.Lua (LuaException (..), runLuaFilter)
41+import Text.Pandoc.Lua (LuaException (..), runPandocLua)
42+import Text.Pandoc.Lua.Filter (LuaFilter, walkMWithLuaFilter)
43+import Text.Pandoc.Lua.Global (Global (..), setGlobals)
44+import Text.Pandoc.Lua.Util (dofileWithTraceback)
4045import Text.Pandoc.Options (ReaderOptions)
4146
47+import qualified Foreign.Lua as Lua
48+
49+-- | Run the Lua filter in @filterPath@ for a transformation to the
50+-- target format (first element in args). Pandoc uses Lua init files to
51+-- setup the Lua interpreter.
4252apply :: ReaderOptions
4353 -> [String]
4454 -> FilePath
4555 -> Pandoc
4656 -> PandocIO Pandoc
47−apply ropts args f d = do
48− f' <- expandFilterPath f
57+apply ropts args f doc = do
58+ filterPath <- expandFilterPath f
4959 let format = case args of
5060 (x:_) -> x
51− _ -> error "Format not supplied for lua filter"
52− res <- runLuaFilter ropts f' format d
53− case res of
54− Right x -> return x
55− Left (LuaException s) -> throw (PandocFilterError f s)
61+ _ -> error "Format not supplied for Lua filter"
62+ runPandocLua >=> forceResult filterPath $ do
63+ setGlobals [ FORMAT format
64+ , PANDOC_READER_OPTIONS ropts
65+ , PANDOC_SCRIPT_FILE filterPath
66+ ]
67+ top <- Lua.gettop
68+ stat <- dofileWithTraceback filterPath
69+ if stat /= Lua.OK
70+ then Lua.throwTopMessage
71+ else do
72+ newtop <- Lua.gettop
73+ -- Use the returned filters, or the implicitly defined global
74+ -- filter if nothing was returned.
75+ luaFilters <- if newtop - top >= 1
76+ then Lua.peek Lua.stackTop
77+ else Lua.pushglobaltable *> fmap (:[]) Lua.popValue
78+ runAll luaFilters doc
79+
80+forceResult :: FilePath -> Either LuaException Pandoc -> PandocIO Pandoc
81+forceResult fp eitherResult = case eitherResult of
82+ Right x -> return x
83+ Left (LuaException s) -> throw (PandocFilterError fp s)
84+
85+runAll :: [LuaFilter] -> Pandoc -> Lua Pandoc
86+runAll = foldr ((>=>) . walkMWithLuaFilter) return