summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Krewinkel <albert@zeitkraut.de>2017-08-22 23:12:39 +0200
committerAlbert Krewinkel <albert@zeitkraut.de>2017-08-22 23:30:48 +0200
commit41baaff32737e57dd9ec0a1153416ca24a12dca1 (patch)
treeca88cf3b4f2bbc08e2f0704d0a5b9c6bb6c07ff6
parent56fb854ad85dafff2016892bd6d2c5d24423bff0 (diff)
Text.Pandoc.Lua: support Inline and Block catch-alls
Try function `Inline`/`Block` if no other filter function of the respective type matches an element. Closes: #3859
-rw-r--r--data/pandoc.lua3
-rw-r--r--src/Text/Pandoc/Lua.hs14
-rw-r--r--test/Tests/Lua.hs6
-rw-r--r--test/lua/block-count.lua11
4 files changed, 27 insertions, 7 deletions
diff --git a/data/pandoc.lua b/data/pandoc.lua
index f0d773b2d..16387d27b 100644
--- a/data/pandoc.lua
+++ b/data/pandoc.lua
@@ -808,7 +808,8 @@ function M.global_filter()
function is_filter_function(k)
return M.Inline.constructor[k] or
M.Block.constructor[k] or
- k == "Meta" or k == "Doc" or k == "Pandoc"
+ k == "Meta" or k == "Doc" or k == "Pandoc" or
+ k == "Block" or k == "Inline"
end
for k, v in pairs(_G) do
if is_filter_function(k) then
diff --git a/src/Text/Pandoc/Lua.hs b/src/Text/Pandoc/Lua.hs
index db028d325..6c6676e4f 100644
--- a/src/Text/Pandoc/Lua.hs
+++ b/src/Text/Pandoc/Lua.hs
@@ -35,7 +35,7 @@ module Text.Pandoc.Lua (LuaException (..), pushPandocModule, runLuaFilter) where
import Control.Monad (mplus, unless, when, (>=>))
import Control.Monad.Trans (MonadIO (..))
import Data.Data (DataType, Data, toConstr, showConstr, dataTypeOf,
- dataTypeConstrs)
+ dataTypeConstrs, dataTypeName)
import Data.Foldable (foldrM)
import Data.Map (Map)
import Data.Maybe (isJust)
@@ -108,10 +108,10 @@ constructorsFor :: DataType -> [String]
constructorsFor x = map show (dataTypeConstrs x)
inlineFilterNames :: [String]
-inlineFilterNames = constructorsFor (dataTypeOf (Str []))
+inlineFilterNames = "Inline" : constructorsFor (dataTypeOf (Str []))
blockFilterNames :: [String]
-blockFilterNames = constructorsFor (dataTypeOf (Para []))
+blockFilterNames = "Block" : constructorsFor (dataTypeOf (Para []))
metaFilterName :: String
metaFilterName = "Meta"
@@ -126,10 +126,12 @@ newtype LuaFilterFunction = LuaFilterFunction { functionIndex :: Int }
-- | Try running a filter for the given element
tryFilter :: (Data a, FromLuaStack a, ToLuaStack a) => FunctionMap -> a -> Lua a
tryFilter fnMap x =
- let filterFnName = showConstr (toConstr x) in
- case Map.lookup filterFnName fnMap of
- Nothing -> return x
+ let filterFnName = showConstr (toConstr x)
+ catchAllName = dataTypeName (dataTypeOf x)
+ in
+ case Map.lookup filterFnName fnMap `mplus` Map.lookup catchAllName fnMap of
Just fn -> runFilterFunction fn x
+ Nothing -> return x
instance FromLuaStack LuaFilter where
peek idx =
diff --git a/test/Tests/Lua.hs b/test/Tests/Lua.hs
index 06f100048..fea813890 100644
--- a/test/Tests/Lua.hs
+++ b/test/Tests/Lua.hs
@@ -70,6 +70,12 @@ tests = map (localOption (QuickCheckTests 20))
"metatable-catch-all.lua"
(doc . para $ "four words, three spaces")
(doc . para $ str "7")
+
+ , testCase "Count blocks via Block-specific catch-all" $
+ assertFilterConversion "filtering with Block catch-all failed"
+ "block-count.lua"
+ (doc $ para "one" <> para "two")
+ (doc $ para "2")
]
assertFilterConversion :: String -> FilePath -> Pandoc -> Pandoc -> Assertion
diff --git a/test/lua/block-count.lua b/test/lua/block-count.lua
new file mode 100644
index 000000000..508b05ea8
--- /dev/null
+++ b/test/lua/block-count.lua
@@ -0,0 +1,11 @@
+local num_blocks = 0
+
+function Block(el)
+ num_blocks = num_blocks + 1
+end
+
+function Pandoc(blocks, meta)
+ return pandoc.Pandoc {
+ pandoc.Para{pandoc.Str(num_blocks)}
+ }
+end