@@ -2,6 +2,7 @@
22{-# LANGUAGE FlexibleInstances #-}
33{-# LANGUAGE MultiParamTypeClasses #-}
44{-# LANGUAGE DeriveDataTypeable #-}
5+{-# LANGUAGE ScopedTypeVariables #-}
56{-
67Copyright © 2017 Albert Krewinkel <tarleb+pandoc@moltkeplatz.de>
78
@@ -34,10 +35,11 @@ module Text.Pandoc.Lua ( LuaException(..),
3435 pushPandocModule ) where
3536
3637import Control.Exception
37−import Control.Monad (unless, when, (>=>))
38+import Control.Monad (unless, when, (>=>), mplus)
3839import Control.Monad.Trans (MonadIO (..))
39−import Data.Data (toConstr)
40+import Data.Data (toConstr, showConstr, dataTypeOf, dataTypeConstrs, Data)
4041import Data.Map (Map)
42+import Data.Maybe (isJust)
4143import Data.Typeable (Typeable)
4244import Scripting.Lua (LuaState, StackValue (..))
4345import Text.Pandoc.Definition
@@ -91,44 +93,38 @@ runAll = foldr ((>=>) . walkMWithLuaFilter) return
9193
9294walkMWithLuaFilter :: LuaFilter -> Pandoc -> IO Pandoc
9395walkMWithLuaFilter (LuaFilter lua fnMap) =
94− walkM (execInlineLuaFilter lua fnMap) >=>
95− walkM (execBlockLuaFilter lua fnMap) >=>
96− walkM (execMetaLuaFilter lua fnMap) >=>
97− walkM (execDocLuaFilter lua fnMap)
96+ (if hasOneOf (constructorsFor (dataTypeOf (Str [])))
97+ then walkM (tryFilter lua fnMap :: Inline -> IO Inline)
98+ else return)
99+ >=>
100+ (if hasOneOf (constructorsFor (dataTypeOf (Para [])))
101+ then walkM (tryFilter lua fnMap :: Block -> IO Block)
102+ else return)
103+ >=>
104+ (case Map.lookup "Meta" fnMap of
105+ Just fn -> walkM (\(Pandoc meta blocks) -> do
106+ meta' <- runFilterFunction lua fn meta
107+ return $ Pandoc meta' blocks)
108+ Nothing -> return)
109+ >=>
110+ (case Map.lookup "Pandoc" fnMap `mplus` Map.lookup "Doc" fnMap of
111+ Just fn -> (runFilterFunction lua fn) :: Pandoc -> IO Pandoc
112+ Nothing -> return)
113+ where hasOneOf = any (\k -> isJust (Map.lookup k fnMap))
114+ constructorsFor x = map show (dataTypeConstrs x)
98115
99116type FunctionMap = Map String LuaFilterFunction
100117data LuaFilter = LuaFilter LuaState FunctionMap
101118
102119newtype LuaFilterFunction = LuaFilterFunction { functionIndex :: Int }
103120
104−tryFilter :: StackValue a => LuaState -> FunctionMap -> String -> a -> IO a
105−tryFilter lua fnMap filterFnName x =
121+tryFilter :: (Data a, StackValue a) => LuaState -> FunctionMap -> a -> IO a
122+tryFilter lua fnMap x =
123+ let filterFnName = showConstr (toConstr x) in
106124 case Map.lookup filterFnName fnMap of
107125 Nothing -> return x
108126 Just fn -> runFilterFunction lua fn x
109127
110−execDocLuaFilter :: LuaState
111− -> FunctionMap
112− -> Pandoc -> IO Pandoc
113−execDocLuaFilter lua fnMap = tryFilter lua fnMap "Doc"
114−
115−execMetaLuaFilter :: LuaState
116− -> FunctionMap
117− -> Pandoc -> IO Pandoc
118−execMetaLuaFilter lua fnMap (Pandoc meta blks) = do
119− meta' <- tryFilter lua fnMap "Meta" meta
120− return $ Pandoc meta' blks
121−
122−execBlockLuaFilter :: LuaState
123− -> FunctionMap
124− -> Block -> IO Block
125−execBlockLuaFilter lua fnMap x = tryFilter lua fnMap (show (toConstr x)) x
126−
127−execInlineLuaFilter :: LuaState
128− -> FunctionMap
129− -> Inline -> IO Inline
130−execInlineLuaFilter lua fnMap x = tryFilter lua fnMap (show (toConstr x)) x
131−
132128instance StackValue LuaFilter where
133129 valuetype _ = Lua.TTABLE
134130 push = undefined