{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Text.Pandoc.Lua.Filter ( LuaFilterFunction
, LuaFilter
, runFilterFile
, walkInlines
, walkInlineLists
, walkBlocks
, walkBlockLists
, module Text.Pandoc.Lua.Walk
) where
import Control.Applicative ((<|>))
import Control.Monad (mplus, (>=>), (<$!>))
import Data.Data (Data, DataType, dataTypeConstrs, dataTypeName, dataTypeOf,
showConstr, toConstr, tyconUQname)
import Data.Foldable (foldrM)
import Data.List (foldl')
import Data.Map (Map)
import Data.String (IsString (fromString))
import HsLua as Lua
import Text.Pandoc.Definition
import Text.Pandoc.Error (PandocError)
import Text.Pandoc.Lua.Marshaling ()
import Text.Pandoc.Lua.Marshaling.AST
import Text.Pandoc.Lua.Marshaling.List (List (..), peekList')
import Text.Pandoc.Lua.Walk (SingletonsList (..))
import Text.Pandoc.Walk (Walkable (walkM))
import qualified Data.Map.Strict as Map
import qualified Text.Pandoc.Lua.Util as LuaUtil
runFilterFile :: FilePath -> Pandoc -> LuaE PandocError Pandoc
runFilterFile :: FilePath -> Pandoc -> LuaE PandocError Pandoc
runFilterFile FilePath
filterPath Pandoc
doc = do
StackIndex
oldtop <- LuaE PandocError StackIndex
forall e. LuaE e StackIndex
Lua.gettop
Status
stat <- FilePath -> LuaE PandocError Status
forall e. LuaError e => FilePath -> LuaE e Status
LuaUtil.dofileWithTraceback FilePath
filterPath
if Status
stat Status -> Status -> Bool
forall a. Eq a => a -> a -> Bool
/= Status
Lua.OK
then LuaE PandocError Pandoc
forall e a. LuaError e => LuaE e a
Lua.throwErrorAsException
else do
StackIndex
newtop <- LuaE PandocError StackIndex
forall e. LuaE e StackIndex
Lua.gettop
[LuaFilter]
luaFilters <- if StackIndex
newtop StackIndex -> StackIndex -> StackIndex
forall a. Num a => a -> a -> a
- StackIndex
oldtop StackIndex -> StackIndex -> Bool
forall a. Ord a => a -> a -> Bool
>= StackIndex
1
then StackIndex -> LuaE PandocError [LuaFilter]
forall a e. (Peekable a, PeekError e) => StackIndex -> LuaE e a
Lua.peek StackIndex
Lua.top
else LuaE PandocError ()
forall e. LuaE e ()
Lua.pushglobaltable LuaE PandocError ()
-> LuaE PandocError [LuaFilter] -> LuaE PandocError [LuaFilter]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (LuaFilter -> [LuaFilter])
-> LuaE PandocError LuaFilter -> LuaE PandocError [LuaFilter]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (LuaFilter -> [LuaFilter] -> [LuaFilter]
forall a. a -> [a] -> [a]
:[]) LuaE PandocError LuaFilter
forall e a. (PeekError e, Peekable a) => LuaE e a
Lua.popValue
[LuaFilter] -> Pandoc -> LuaE PandocError Pandoc
runAll [LuaFilter]
luaFilters Pandoc
doc
runAll :: [LuaFilter] -> Pandoc -> LuaE PandocError Pandoc
runAll :: [LuaFilter] -> Pandoc -> LuaE PandocError Pandoc
runAll = (LuaFilter
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> [LuaFilter]
-> Pandoc
-> LuaE PandocError Pandoc
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
(>=>) ((Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc)
-> (LuaFilter -> Pandoc -> LuaE PandocError Pandoc)
-> LuaFilter
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMWithLuaFilter) Pandoc -> LuaE PandocError Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return
newtype LuaFilterFunction = LuaFilterFunction Lua.Reference
newtype LuaFilter = LuaFilter (Map Name LuaFilterFunction)
instance Peekable LuaFilter where
peek :: StackIndex -> LuaE e LuaFilter
peek StackIndex
idx = do
let constrs :: [Name]
constrs = Name
listOfInlinesFilterName
Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: Name
listOfBlocksFilterName
Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: Name
metaFilterName
Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: [Name]
pandocFilterNames
[Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name]
blockElementNames
[Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name]
inlineElementNames
let go :: Name
-> Map Name LuaFilterFunction
-> LuaE e (Map Name LuaFilterFunction)
go Name
constr Map Name LuaFilterFunction
acc = do
StackIndex -> Name -> LuaE e Type
forall e. LuaError e => StackIndex -> Name -> LuaE e Type
Lua.getfield StackIndex
idx Name
constr
Maybe LuaFilterFunction
filterFn <- LuaE e (Maybe LuaFilterFunction)
forall e. LuaError e => LuaE e (Maybe LuaFilterFunction)
registerFilterFunction
Map Name LuaFilterFunction -> LuaE e (Map Name LuaFilterFunction)
forall (m :: * -> *) a. Monad m => a -> m a
return (Map Name LuaFilterFunction -> LuaE e (Map Name LuaFilterFunction))
-> Map Name LuaFilterFunction
-> LuaE e (Map Name LuaFilterFunction)
forall a b. (a -> b) -> a -> b
$ case Maybe LuaFilterFunction
filterFn of
Maybe LuaFilterFunction
Nothing -> Map Name LuaFilterFunction
acc
Just LuaFilterFunction
fn -> Name
-> LuaFilterFunction
-> Map Name LuaFilterFunction
-> Map Name LuaFilterFunction
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert Name
constr LuaFilterFunction
fn Map Name LuaFilterFunction
acc
Map Name LuaFilterFunction -> LuaFilter
LuaFilter (Map Name LuaFilterFunction -> LuaFilter)
-> LuaE e (Map Name LuaFilterFunction) -> LuaE e LuaFilter
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> (Name
-> Map Name LuaFilterFunction
-> LuaE e (Map Name LuaFilterFunction))
-> Map Name LuaFilterFunction
-> [Name]
-> LuaE e (Map Name LuaFilterFunction)
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM Name
-> Map Name LuaFilterFunction
-> LuaE e (Map Name LuaFilterFunction)
forall e.
LuaError e =>
Name
-> Map Name LuaFilterFunction
-> LuaE e (Map Name LuaFilterFunction)
go Map Name LuaFilterFunction
forall k a. Map k a
Map.empty [Name]
constrs
registerFilterFunction :: LuaError e => LuaE e (Maybe LuaFilterFunction)
registerFilterFunction :: LuaE e (Maybe LuaFilterFunction)
registerFilterFunction = do
Bool
isFn <- StackIndex -> LuaE e Bool
forall e. StackIndex -> LuaE e Bool
Lua.isfunction StackIndex
Lua.top
if Bool
isFn
then LuaFilterFunction -> Maybe LuaFilterFunction
forall a. a -> Maybe a
Just (LuaFilterFunction -> Maybe LuaFilterFunction)
-> (Reference -> LuaFilterFunction)
-> Reference
-> Maybe LuaFilterFunction
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> LuaFilterFunction
LuaFilterFunction (Reference -> Maybe LuaFilterFunction)
-> LuaE e Reference -> LuaE e (Maybe LuaFilterFunction)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StackIndex -> LuaE e Reference
forall e. StackIndex -> LuaE e Reference
Lua.ref StackIndex
Lua.registryindex
else Maybe LuaFilterFunction
forall a. Maybe a
Nothing Maybe LuaFilterFunction
-> LuaE e () -> LuaE e (Maybe LuaFilterFunction)
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop Int
1
pushFilterFunction :: LuaFilterFunction -> LuaE PandocError ()
pushFilterFunction :: LuaFilterFunction -> LuaE PandocError ()
pushFilterFunction (LuaFilterFunction Reference
fnRef) =
StackIndex -> Reference -> LuaE PandocError ()
forall e. LuaError e => StackIndex -> Reference -> LuaE e ()
Lua.getref StackIndex
Lua.registryindex Reference
fnRef
elementOrList :: Peeker PandocError a -> a -> LuaE PandocError [a]
elementOrList :: Peeker PandocError a -> a -> LuaE PandocError [a]
elementOrList Peeker PandocError a
p a
x = do
Bool
elementUnchanged <- StackIndex -> LuaE PandocError Bool
forall e. StackIndex -> LuaE e Bool
Lua.isnil StackIndex
top
if Bool
elementUnchanged
then [a
x] [a] -> LuaE PandocError () -> LuaE PandocError [a]
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Int -> LuaE PandocError ()
forall e. Int -> LuaE e ()
pop Int
1
else Peek PandocError [a] -> LuaE PandocError [a]
forall e a. LuaError e => Peek e a -> LuaE e a
forcePeek (Peek PandocError [a] -> LuaE PandocError [a])
-> (Peek PandocError [a] -> Peek PandocError [a])
-> Peek PandocError [a]
-> LuaE PandocError [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Peek PandocError [a] -> LuaE PandocError () -> Peek PandocError [a]
forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` Int -> LuaE PandocError ()
forall e. Int -> LuaE e ()
pop Int
1) (Peek PandocError [a] -> LuaE PandocError [a])
-> Peek PandocError [a] -> LuaE PandocError [a]
forall a b. (a -> b) -> a -> b
$ (((a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[]) (a -> [a]) -> Peek PandocError a -> Peek PandocError [a]
forall (m :: * -> *) a b. Monad m => (a -> b) -> m a -> m b
<$!> Peeker PandocError a
p StackIndex
top) Peek PandocError [a]
-> Peek PandocError [a] -> Peek PandocError [a]
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Peeker PandocError a -> Peeker PandocError [a]
forall a e. LuaError e => Peeker e a -> Peeker e [a]
peekList Peeker PandocError a
p StackIndex
top)
singleElement :: forall a e. (LuaError e) => Peeker e a -> a -> LuaE e a
singleElement :: Peeker e a -> a -> LuaE e a
singleElement Peeker e a
p a
x = do
Bool
elementUnchanged <- StackIndex -> LuaE e Bool
forall e. StackIndex -> LuaE e Bool
Lua.isnil StackIndex
top
if Bool
elementUnchanged
then a
x a -> LuaE e () -> LuaE e a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Int -> LuaE e ()
forall e. Int -> LuaE e ()
Lua.pop Int
1
else Peek e a -> LuaE e a
forall e a. LuaError e => Peek e a -> LuaE e a
forcePeek (Peek e a -> LuaE e a) -> Peek e a -> LuaE e a
forall a b. (a -> b) -> a -> b
$ Peeker e a
p StackIndex
top Peek e a -> LuaE e () -> Peek e a
forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` Int -> LuaE e ()
forall e. Int -> LuaE e ()
pop Int
1
popOption :: Peeker PandocError a -> a -> LuaE PandocError a
popOption :: Peeker PandocError a -> a -> LuaE PandocError a
popOption Peeker PandocError a
peeker a
fallback = Peek PandocError a -> LuaE PandocError a
forall e a. LuaError e => Peek e a -> LuaE e a
forcePeek (Peek PandocError a -> LuaE PandocError a)
-> (Peek PandocError a -> Peek PandocError a)
-> Peek PandocError a
-> LuaE PandocError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Peek PandocError a -> LuaE PandocError () -> Peek PandocError a
forall e a b. Peek e a -> LuaE e b -> Peek e a
`lastly` Int -> LuaE PandocError ()
forall e. Int -> LuaE e ()
pop Int
1) (Peek PandocError a -> LuaE PandocError a)
-> Peek PandocError a -> LuaE PandocError a
forall a b. (a -> b) -> a -> b
$
(a
fallback a -> Peek PandocError () -> Peek PandocError a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Peeker PandocError ()
forall e. Peeker e ()
peekNil StackIndex
top) Peek PandocError a -> Peek PandocError a -> Peek PandocError a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Peeker PandocError a
peeker StackIndex
top
runOnSequence :: forall a. (Data a, Pushable a)
=> Peeker PandocError a -> LuaFilter -> SingletonsList a
-> LuaE PandocError (SingletonsList a)
runOnSequence :: Peeker PandocError a
-> LuaFilter
-> SingletonsList a
-> LuaE PandocError (SingletonsList a)
runOnSequence Peeker PandocError a
peeker (LuaFilter Map Name LuaFilterFunction
fnMap) (SingletonsList [a]
xs) =
[a] -> SingletonsList a
forall a. [a] -> SingletonsList a
SingletonsList ([a] -> SingletonsList a)
-> LuaE PandocError [a] -> LuaE PandocError (SingletonsList a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (a -> LuaE PandocError [a]) -> [a] -> LuaE PandocError [a]
forall (m :: * -> *) a. Monad m => (a -> m [a]) -> [a] -> m [a]
mconcatMapM a -> LuaE PandocError [a]
tryFilter [a]
xs
where
tryFilter :: a -> LuaE PandocError [a]
tryFilter :: a -> LuaE PandocError [a]
tryFilter a
x =
let filterFnName :: Name
filterFnName = FilePath -> Name
forall a. IsString a => FilePath -> a
fromString (FilePath -> Name) -> FilePath -> Name
forall a b. (a -> b) -> a -> b
$ Constr -> FilePath
showConstr (a -> Constr
forall a. Data a => a -> Constr
toConstr a
x)
catchAllName :: Name
catchAllName = FilePath -> Name
forall a. IsString a => FilePath -> a
fromString (FilePath -> Name) -> (FilePath -> FilePath) -> FilePath -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> FilePath
tyconUQname (FilePath -> Name) -> FilePath -> Name
forall a b. (a -> b) -> a -> b
$ DataType -> FilePath
dataTypeName (a -> DataType
forall a. Data a => a -> DataType
dataTypeOf a
x)
in case Name -> Map Name LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
filterFnName Map Name LuaFilterFunction
fnMap Maybe LuaFilterFunction
-> Maybe LuaFilterFunction -> Maybe LuaFilterFunction
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Name -> Map Name LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
catchAllName Map Name LuaFilterFunction
fnMap of
Just LuaFilterFunction
fn -> LuaFilterFunction -> a -> LuaE PandocError ()
forall a.
Pushable a =>
LuaFilterFunction -> a -> LuaE PandocError ()
runFilterFunction LuaFilterFunction
fn a
x LuaE PandocError () -> LuaE PandocError [a] -> LuaE PandocError [a]
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker PandocError a -> a -> LuaE PandocError [a]
forall a. Peeker PandocError a -> a -> LuaE PandocError [a]
elementOrList Peeker PandocError a
peeker a
x
Maybe LuaFilterFunction
Nothing -> [a] -> LuaE PandocError [a]
forall (m :: * -> *) a. Monad m => a -> m a
return [a
x]
runOnValue :: (Data a, Pushable a)
=> Name -> Peeker PandocError a
-> LuaFilter -> a
-> LuaE PandocError a
runOnValue :: Name
-> Peeker PandocError a -> LuaFilter -> a -> LuaE PandocError a
runOnValue Name
filterFnName Peeker PandocError a
peeker (LuaFilter Map Name LuaFilterFunction
fnMap) a
x =
case Name -> Map Name LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
filterFnName Map Name LuaFilterFunction
fnMap of
Just LuaFilterFunction
fn -> LuaFilterFunction -> a -> LuaE PandocError ()
forall a.
Pushable a =>
LuaFilterFunction -> a -> LuaE PandocError ()
runFilterFunction LuaFilterFunction
fn a
x LuaE PandocError () -> LuaE PandocError a -> LuaE PandocError a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker PandocError a -> a -> LuaE PandocError a
forall a. Peeker PandocError a -> a -> LuaE PandocError a
popOption Peeker PandocError a
peeker a
x
Maybe LuaFilterFunction
Nothing -> a -> LuaE PandocError a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
runFilterFunction :: Pushable a
=> LuaFilterFunction -> a -> LuaE PandocError ()
runFilterFunction :: LuaFilterFunction -> a -> LuaE PandocError ()
runFilterFunction LuaFilterFunction
lf a
x = do
LuaFilterFunction -> LuaE PandocError ()
pushFilterFunction LuaFilterFunction
lf
a -> LuaE PandocError ()
forall a e. (Pushable a, LuaError e) => a -> LuaE e ()
Lua.push a
x
NumArgs -> NumResults -> LuaE PandocError ()
forall e. LuaError e => NumArgs -> NumResults -> LuaE e ()
LuaUtil.callWithTraceback NumArgs
1 NumResults
1
walkMWithLuaFilter :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMWithLuaFilter :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMWithLuaFilter LuaFilter
f =
LuaFilter -> Pandoc -> LuaE PandocError Pandoc
forall a.
Walkable (SingletonsList Inline) a =>
LuaFilter -> a -> LuaE PandocError a
walkInlines LuaFilter
f
(Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> LuaE PandocError Pandoc
forall a.
Walkable (List Inline) a =>
LuaFilter -> a -> LuaE PandocError a
walkInlineLists LuaFilter
f
(Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> LuaE PandocError Pandoc
forall a.
Walkable (SingletonsList Block) a =>
LuaFilter -> a -> LuaE PandocError a
walkBlocks LuaFilter
f
(Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> LuaE PandocError Pandoc
forall a.
Walkable (List Block) a =>
LuaFilter -> a -> LuaE PandocError a
walkBlockLists LuaFilter
f
(Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMeta LuaFilter
f
(Pandoc -> LuaE PandocError Pandoc)
-> (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc
-> LuaE PandocError Pandoc
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkPandoc LuaFilter
f
mconcatMapM :: (Monad m) => (a -> m [a]) -> [a] -> m [a]
mconcatMapM :: (a -> m [a]) -> [a] -> m [a]
mconcatMapM a -> m [a]
f = ([[a]] -> [a]) -> m [[a]] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[a]] -> [a]
forall a. Monoid a => [a] -> a
mconcat (m [[a]] -> m [a]) -> ([a] -> m [[a]]) -> [a] -> m [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m [a]) -> [a] -> m [[a]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM a -> m [a]
f
hasOneOf :: LuaFilter -> [Name] -> Bool
hasOneOf :: LuaFilter -> [Name] -> Bool
hasOneOf (LuaFilter Map Name LuaFilterFunction
fnMap) = (Name -> Bool) -> [Name] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Name -> Map Name LuaFilterFunction -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map Name LuaFilterFunction
fnMap)
contains :: LuaFilter -> Name -> Bool
contains :: LuaFilter -> Name -> Bool
contains (LuaFilter Map Name LuaFilterFunction
fnMap) = (Name -> Map Name LuaFilterFunction -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map Name LuaFilterFunction
fnMap)
walkInlines :: Walkable (SingletonsList Inline) a
=> LuaFilter -> a -> LuaE PandocError a
walkInlines :: LuaFilter -> a -> LuaE PandocError a
walkInlines LuaFilter
lf =
let f :: SingletonsList Inline -> LuaE PandocError (SingletonsList Inline)
f :: SingletonsList Inline -> LuaE PandocError (SingletonsList Inline)
f = Peeker PandocError Inline
-> LuaFilter
-> SingletonsList Inline
-> LuaE PandocError (SingletonsList Inline)
forall a.
(Data a, Pushable a) =>
Peeker PandocError a
-> LuaFilter
-> SingletonsList a
-> LuaE PandocError (SingletonsList a)
runOnSequence Peeker PandocError Inline
forall e. LuaError e => Peeker e Inline
peekInline LuaFilter
lf
in if LuaFilter
lf LuaFilter -> [Name] -> Bool
`hasOneOf` [Name]
inlineElementNames
then (SingletonsList Inline -> LuaE PandocError (SingletonsList Inline))
-> a -> LuaE PandocError a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM SingletonsList Inline -> LuaE PandocError (SingletonsList Inline)
f
else a -> LuaE PandocError a
forall (m :: * -> *) a. Monad m => a -> m a
return
walkInlineLists :: Walkable (List Inline) a
=> LuaFilter -> a -> LuaE PandocError a
walkInlineLists :: LuaFilter -> a -> LuaE PandocError a
walkInlineLists LuaFilter
lf =
let f :: List Inline -> LuaE PandocError (List Inline)
f :: List Inline -> LuaE PandocError (List Inline)
f = Name
-> Peeker PandocError (List Inline)
-> LuaFilter
-> List Inline
-> LuaE PandocError (List Inline)
forall a.
(Data a, Pushable a) =>
Name
-> Peeker PandocError a -> LuaFilter -> a -> LuaE PandocError a
runOnValue Name
listOfInlinesFilterName (Peeker PandocError Inline -> Peeker PandocError (List Inline)
forall e a. LuaError e => Peeker e a -> Peeker e (List a)
peekList' Peeker PandocError Inline
forall e. LuaError e => Peeker e Inline
peekInline) LuaFilter
lf
in if LuaFilter
lf LuaFilter -> Name -> Bool
`contains` Name
listOfInlinesFilterName
then (List Inline -> LuaE PandocError (List Inline))
-> a -> LuaE PandocError a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM List Inline -> LuaE PandocError (List Inline)
f
else a -> LuaE PandocError a
forall (m :: * -> *) a. Monad m => a -> m a
return
walkBlocks :: Walkable (SingletonsList Block) a
=> LuaFilter -> a -> LuaE PandocError a
walkBlocks :: LuaFilter -> a -> LuaE PandocError a
walkBlocks LuaFilter
lf =
let f :: SingletonsList Block -> LuaE PandocError (SingletonsList Block)
f :: SingletonsList Block -> LuaE PandocError (SingletonsList Block)
f = Peeker PandocError Block
-> LuaFilter
-> SingletonsList Block
-> LuaE PandocError (SingletonsList Block)
forall a.
(Data a, Pushable a) =>
Peeker PandocError a
-> LuaFilter
-> SingletonsList a
-> LuaE PandocError (SingletonsList a)
runOnSequence Peeker PandocError Block
forall e. LuaError e => Peeker e Block
peekBlock LuaFilter
lf
in if LuaFilter
lf LuaFilter -> [Name] -> Bool
`hasOneOf` [Name]
blockElementNames
then (SingletonsList Block -> LuaE PandocError (SingletonsList Block))
-> a -> LuaE PandocError a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM SingletonsList Block -> LuaE PandocError (SingletonsList Block)
f
else a -> LuaE PandocError a
forall (m :: * -> *) a. Monad m => a -> m a
return
walkBlockLists :: Walkable (List Block) a
=> LuaFilter -> a -> LuaE PandocError a
walkBlockLists :: LuaFilter -> a -> LuaE PandocError a
walkBlockLists LuaFilter
lf =
let f :: List Block -> LuaE PandocError (List Block)
f :: List Block -> LuaE PandocError (List Block)
f = Name
-> Peeker PandocError (List Block)
-> LuaFilter
-> List Block
-> LuaE PandocError (List Block)
forall a.
(Data a, Pushable a) =>
Name
-> Peeker PandocError a -> LuaFilter -> a -> LuaE PandocError a
runOnValue Name
listOfBlocksFilterName (Peeker PandocError Block -> Peeker PandocError (List Block)
forall e a. LuaError e => Peeker e a -> Peeker e (List a)
peekList' Peeker PandocError Block
forall e. LuaError e => Peeker e Block
peekBlock) LuaFilter
lf
in if LuaFilter
lf LuaFilter -> Name -> Bool
`contains` Name
listOfBlocksFilterName
then (List Block -> LuaE PandocError (List Block))
-> a -> LuaE PandocError a
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM List Block -> LuaE PandocError (List Block)
f
else a -> LuaE PandocError a
forall (m :: * -> *) a. Monad m => a -> m a
return
walkMeta :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMeta :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkMeta LuaFilter
lf (Pandoc Meta
m [Block]
bs) = do
Meta
m' <- Name
-> Peeker PandocError Meta
-> LuaFilter
-> Meta
-> LuaE PandocError Meta
forall a.
(Data a, Pushable a) =>
Name
-> Peeker PandocError a -> LuaFilter -> a -> LuaE PandocError a
runOnValue Name
"Meta" Peeker PandocError Meta
forall e. LuaError e => Peeker e Meta
peekMeta LuaFilter
lf Meta
m
Pandoc -> LuaE PandocError Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> LuaE PandocError Pandoc)
-> Pandoc -> LuaE PandocError Pandoc
forall a b. (a -> b) -> a -> b
$ Meta -> [Block] -> Pandoc
Pandoc Meta
m' [Block]
bs
walkPandoc :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkPandoc :: LuaFilter -> Pandoc -> LuaE PandocError Pandoc
walkPandoc (LuaFilter Map Name LuaFilterFunction
fnMap) =
case (Maybe LuaFilterFunction
-> Maybe LuaFilterFunction -> Maybe LuaFilterFunction)
-> Maybe LuaFilterFunction
-> [Maybe LuaFilterFunction]
-> Maybe LuaFilterFunction
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Maybe LuaFilterFunction
-> Maybe LuaFilterFunction -> Maybe LuaFilterFunction
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
mplus Maybe LuaFilterFunction
forall a. Maybe a
Nothing ((Name -> Maybe LuaFilterFunction)
-> [Name] -> [Maybe LuaFilterFunction]
forall a b. (a -> b) -> [a] -> [b]
map (Name -> Map Name LuaFilterFunction -> Maybe LuaFilterFunction
forall k a. Ord k => k -> Map k a -> Maybe a
`Map.lookup` Map Name LuaFilterFunction
fnMap) [Name]
pandocFilterNames) of
Just LuaFilterFunction
fn -> \Pandoc
x -> LuaFilterFunction -> Pandoc -> LuaE PandocError ()
forall a.
Pushable a =>
LuaFilterFunction -> a -> LuaE PandocError ()
runFilterFunction LuaFilterFunction
fn Pandoc
x LuaE PandocError ()
-> LuaE PandocError Pandoc -> LuaE PandocError Pandoc
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Peeker PandocError Pandoc -> Pandoc -> LuaE PandocError Pandoc
forall a e. LuaError e => Peeker e a -> a -> LuaE e a
singleElement Peeker PandocError Pandoc
forall e. LuaError e => Peeker e Pandoc
peekPandoc Pandoc
x
Maybe LuaFilterFunction
Nothing -> Pandoc -> LuaE PandocError Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return
constructorsFor :: DataType -> [Name]
constructorsFor :: DataType -> [Name]
constructorsFor DataType
x = (Constr -> Name) -> [Constr] -> [Name]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath -> Name
forall a. IsString a => FilePath -> a
fromString (FilePath -> Name) -> (Constr -> FilePath) -> Constr -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Constr -> FilePath
forall a. Show a => a -> FilePath
show) (DataType -> [Constr]
dataTypeConstrs DataType
x)
inlineElementNames :: [Name]
inlineElementNames :: [Name]
inlineElementNames = Name
"Inline" Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: DataType -> [Name]
constructorsFor (Inline -> DataType
forall a. Data a => a -> DataType
dataTypeOf (Text -> Inline
Str Text
forall a. Monoid a => a
mempty))
blockElementNames :: [Name]
blockElementNames :: [Name]
blockElementNames = Name
"Block" Name -> [Name] -> [Name]
forall a. a -> [a] -> [a]
: DataType -> [Name]
constructorsFor (Block -> DataType
forall a. Data a => a -> DataType
dataTypeOf ([Inline] -> Block
Para []))
listOfInlinesFilterName :: Name
listOfInlinesFilterName :: Name
listOfInlinesFilterName = Name
"Inlines"
listOfBlocksFilterName :: Name
listOfBlocksFilterName :: Name
listOfBlocksFilterName = Name
"Blocks"
metaFilterName :: Name
metaFilterName :: Name
metaFilterName = Name
"Meta"
pandocFilterNames :: [Name]
pandocFilterNames :: [Name]
pandocFilterNames = [Name
"Pandoc", Name
"Doc"]