From ae21a8bb2a9d892491424f257ed0146c1b2affa2 Mon Sep 17 00:00:00 2001 From: Albert Krewinkel Date: Sun, 30 Apr 2017 16:14:33 +0200 Subject: Lua filter: fall-back to global filters when none is returned The implicitly defined global filter (i.e. all element filtering functions defined in the global lua environment) is used if no filter is returned from a lua script. This allows to just write top-level functions in order to define a lua filter. E.g function Emph(elem) return pandoc.Strong(elem.content) end --- data/pandoc.lua | 2 +- src/Text/Pandoc/Lua.hs | 13 ++++++++++++- test/Tests/Lua.hs | 6 ++++++ test/lua/implicit-doc-filter.lua | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/lua/implicit-doc-filter.lua diff --git a/data/pandoc.lua b/data/pandoc.lua index 31e46637c..2a5a945b5 100644 --- a/data/pandoc.lua +++ b/data/pandoc.lua @@ -803,7 +803,7 @@ end function M.global_filter() local res = {} for k, v in pairs(_G) do - if M.Inline.constructor[k] or M.Block.constructor[k] or M.Block.constructors[k] or k == "Doc" then + if M.Inline.constructor[k] or M.Block.constructor[k] or k == "Doc" then res[k] = v end end diff --git a/src/Text/Pandoc/Lua.hs b/src/Text/Pandoc/Lua.hs index ffc57c9c2..f4a22b92a 100644 --- a/src/Text/Pandoc/Lua.hs +++ b/src/Text/Pandoc/Lua.hs @@ -54,13 +54,17 @@ runLuaFilter filterPath args pd = liftIO $ do -- store module in global "pandoc" pushPandocModule lua Lua.setglobal lua "pandoc" + top <- Lua.gettop lua status <- Lua.loadfile lua filterPath if (status /= 0) then do Just luaErrMsg <- Lua.peek lua 1 error luaErrMsg else do - Lua.call lua 0 1 + Lua.call lua 0 Lua.multret + newtop <- Lua.gettop lua + -- Use the implicitly defined global filter if nothing was returned + when (newtop - top < 1) $ pushGlobalFilter lua Just luaFilters <- Lua.peek lua (-1) Lua.push lua args Lua.setglobal lua "PandocParameters" @@ -68,6 +72,13 @@ runLuaFilter filterPath args pd = liftIO $ do Lua.close lua return doc +pushGlobalFilter :: LuaState -> IO () +pushGlobalFilter lua = + Lua.newtable lua + *> Lua.getglobal2 lua "pandoc.global_filter" + *> Lua.call lua 0 1 + *> Lua.rawseti lua (-2) 1 + runAll :: [LuaFilter] -> Pandoc -> IO Pandoc runAll [] = return runAll (x:xs) = walkMWithLuaFilter x >=> runAll xs diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs index 80c733751..50f9634a2 100644 --- a/test/Tests/Lua.hs +++ b/test/Tests/Lua.hs @@ -47,6 +47,12 @@ tests = (doc . para $ str "Hey!" <> linebreak <> str "What's up?") (doc . para $ str "Hello," <> space <> str "World!") + , testCase "implicit doc filter" $ + assertFilterConversion "Document contains 'Hello, World!'" + "implicit-doc-filter.lua" + (doc . plain $ linebreak) + (doc . para $ str "Hello," <> space <> str "World!") + , testCase "parse raw markdown blocks" $ assertFilterConversion "raw markdown block is converted" "markdown-reader.lua" diff --git a/test/lua/implicit-doc-filter.lua b/test/lua/implicit-doc-filter.lua new file mode 100644 index 000000000..320d22105 --- /dev/null +++ b/test/lua/implicit-doc-filter.lua @@ -0,0 +1,6 @@ +function Doc (doc) + local meta = {} + local hello = { pandoc.Str "Hello,", pandoc.Space(), pandoc.Str "World!" } + local blocks = { pandoc.Para(hello) } + return pandoc.Doc(blocks, meta) +end -- cgit v1.2.3