{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Text.Pandoc.Filter.Utils (
convertFilter,
convertFilterM,
PartialFilter,
PandocFilter,
PartialFilterM,
PandocFilterM,
ToPartialFilter (..),
mkConcatedFilter,
applyFilter,
applyFilters,
applyFilterM,
applyFiltersM,
getFilter,
getConcatedFilter,
getFilterM,
getConcatedFilterM,
toFilterM,
) where
import Control.Monad ((>=>))
import Data.Foldable (fold)
import Data.Functor.Identity (Identity (..))
import Text.Pandoc.Definition
import Text.Pandoc.Walk
newtype PartialFilterM m p =
PartialFilterM
{
PartialFilterM m p -> p -> m p
applyFilterM :: p -> m p
}
type PartialFilter = PartialFilterM Identity
type PandocFilter = PartialFilter Pandoc
type PandocFilterM m = PartialFilterM m Pandoc
applyFilter
:: PartialFilter p
-> p
-> p
applyFilter :: PartialFilter p -> p -> p
applyFilter = (Identity p -> p
forall a. Identity a -> a
runIdentity (Identity p -> p) -> (p -> Identity p) -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((p -> Identity p) -> p -> p)
-> (PartialFilter p -> p -> Identity p)
-> PartialFilter p
-> p
-> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PartialFilter p -> p -> Identity p
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM
getFilterM
:: (Monad m, Walkable a b)
=> PartialFilterM m a
-> (b -> m b)
getFilterM :: PartialFilterM m a -> b -> m b
getFilterM = PartialFilterM m b -> b -> m b
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM (PartialFilterM m b -> b -> m b)
-> (PartialFilterM m a -> PartialFilterM m b)
-> PartialFilterM m a
-> b
-> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PartialFilterM m a -> PartialFilterM m b
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter
getFilter
:: (Walkable a b)
=> PartialFilter a
-> (b -> b)
getFilter :: PartialFilter a -> b -> b
getFilter = PartialFilter b -> b -> b
forall p. PartialFilter p -> p -> p
applyFilter (PartialFilter b -> b -> b)
-> (PartialFilter a -> PartialFilter b)
-> PartialFilter a
-> b
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PartialFilter a -> PartialFilter b
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter
instance (Monad m) => Semigroup (PartialFilterM m p) where
f1 :: PartialFilterM m p
f1 <> :: PartialFilterM m p -> PartialFilterM m p -> PartialFilterM m p
<> f2 :: PartialFilterM m p
f2 = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM (PartialFilterM m p -> p -> m p
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM PartialFilterM m p
f1 (p -> m p) -> (p -> m p) -> p -> m p
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> PartialFilterM m p -> p -> m p
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM PartialFilterM m p
f2)
instance (Monad m) => Monoid (PartialFilterM m p) where
mempty :: PartialFilterM m p
mempty = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM p -> m p
forall (m :: * -> *) a. Monad m => a -> m a
return
class ToPartialFilter m f p where
mkFilter
:: f
-> PartialFilterM m p
instance (Monad m, Walkable a p) => ToPartialFilter m (a -> a) p where
mkFilter :: (a -> a) -> PartialFilterM m p
mkFilter = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM ((p -> m p) -> PartialFilterM m p)
-> ((a -> a) -> p -> m p) -> (a -> a) -> PartialFilterM m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (p -> m p
forall (m :: * -> *) a. Monad m => a -> m a
return (p -> m p) -> (p -> p) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((p -> p) -> p -> m p)
-> ((a -> a) -> p -> p) -> (a -> a) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> a) -> p -> p
forall a b. Walkable a b => (a -> a) -> b -> b
walk
instance (Monad m, Walkable a p) => ToPartialFilter m (a -> m a) p where
mkFilter :: (a -> m a) -> PartialFilterM m p
mkFilter = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM ((p -> m p) -> PartialFilterM m p)
-> ((a -> m a) -> p -> m p) -> (a -> m a) -> PartialFilterM m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> m a) -> p -> m p
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM
instance (Monad m, Walkable [a] p) => ToPartialFilter m (a -> [a]) p where
mkFilter :: (a -> [a]) -> PartialFilterM m p
mkFilter = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM ((p -> m p) -> PartialFilterM m p)
-> ((a -> [a]) -> p -> m p) -> (a -> [a]) -> PartialFilterM m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (p -> m p
forall (m :: * -> *) a. Monad m => a -> m a
return (p -> m p) -> (p -> p) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((p -> p) -> p -> m p)
-> ((a -> [a]) -> p -> p) -> (a -> [a]) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [a]) -> p -> p
forall a b. Walkable a b => (a -> a) -> b -> b
walk (([a] -> [a]) -> p -> p)
-> ((a -> [a]) -> [a] -> [a]) -> (a -> [a]) -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> [a]) -> [a] -> [a]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
instance (Monad m, Walkable [a] p) => ToPartialFilter m (a -> m [a]) p where
mkFilter :: (a -> m [a]) -> PartialFilterM m p
mkFilter = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM ((p -> m p) -> PartialFilterM m p)
-> ((a -> m [a]) -> p -> m p) -> (a -> m [a]) -> PartialFilterM m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> m [a]) -> p -> m p
forall a b (m :: * -> *).
(Walkable a b, Monad m, Applicative m, Functor m) =>
(a -> m a) -> b -> m b
walkM (([a] -> m [a]) -> p -> m p)
-> ((a -> m [a]) -> [a] -> m [a]) -> (a -> m [a]) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([[a]] -> [a]) -> m [[a]] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [[a]] -> [a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat (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])
-> ((a -> m [a]) -> [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
instance (Monad m, Walkable a b) => ToPartialFilter m (PartialFilterM m a) b where
mkFilter :: PartialFilterM m a -> PartialFilterM m b
mkFilter = (a -> m a) -> PartialFilterM m b
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter ((a -> m a) -> PartialFilterM m b)
-> (PartialFilterM m a -> a -> m a)
-> PartialFilterM m a
-> PartialFilterM m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PartialFilterM m a -> a -> m a
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM
mkConcatedFilter
:: (Monad m, ToPartialFilter m f p, Foldable t)
=> t f
-> PartialFilterM m p
mkConcatedFilter :: t f -> PartialFilterM m p
mkConcatedFilter = (f -> PartialFilterM m p) -> t f -> PartialFilterM m p
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap f -> PartialFilterM m p
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter
toFilterM
:: (Monad m)
=> PartialFilter p
-> PartialFilterM m p
toFilterM :: PartialFilter p -> PartialFilterM m p
toFilterM = (p -> m p) -> PartialFilterM m p
forall (m :: * -> *) p. (p -> m p) -> PartialFilterM m p
PartialFilterM ((p -> m p) -> PartialFilterM m p)
-> (PartialFilter p -> p -> m p)
-> PartialFilter p
-> PartialFilterM m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (p -> m p
forall (m :: * -> *) a. Monad m => a -> m a
return (p -> m p) -> (p -> p) -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
.) ((p -> p) -> p -> m p)
-> (PartialFilter p -> p -> p) -> PartialFilter p -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PartialFilter p -> p -> p
forall p. PartialFilter p -> p -> p
applyFilter
applyFiltersM
:: (Foldable t, Monad m)
=> t (PartialFilterM m p)
-> p
-> m p
applyFiltersM :: t (PartialFilterM m p) -> p -> m p
applyFiltersM = PartialFilterM m p -> p -> m p
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM (PartialFilterM m p -> p -> m p)
-> (t (PartialFilterM m p) -> PartialFilterM m p)
-> t (PartialFilterM m p)
-> p
-> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t (PartialFilterM m p) -> PartialFilterM m p
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
applyFilters
:: (Foldable t)
=> t (PartialFilter p)
-> p
-> p
applyFilters :: t (PartialFilter p) -> p -> p
applyFilters = PartialFilter p -> p -> p
forall p. PartialFilter p -> p -> p
applyFilter (PartialFilter p -> p -> p)
-> (t (PartialFilter p) -> PartialFilter p)
-> t (PartialFilter p)
-> p
-> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t (PartialFilter p) -> PartialFilter p
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold
getConcatedFilterM
:: (Foldable t, Monad m, Walkable a b)
=> t (PartialFilterM m a)
-> (b -> m b)
getConcatedFilterM :: t (PartialFilterM m a) -> b -> m b
getConcatedFilterM = PartialFilterM m b -> b -> m b
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM (PartialFilterM m b -> b -> m b)
-> (t (PartialFilterM m a) -> PartialFilterM m b)
-> t (PartialFilterM m a)
-> b
-> m b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t (PartialFilterM m a) -> PartialFilterM m b
forall (m :: * -> *) f p (t :: * -> *).
(Monad m, ToPartialFilter m f p, Foldable t) =>
t f -> PartialFilterM m p
mkConcatedFilter
getConcatedFilter
:: (Foldable t, Walkable a b)
=> t (PartialFilter a)
-> (b -> b)
getConcatedFilter :: t (PartialFilter a) -> b -> b
getConcatedFilter = PartialFilter b -> b -> b
forall p. PartialFilter p -> p -> p
applyFilter (PartialFilter b -> b -> b)
-> (t (PartialFilter a) -> PartialFilter b)
-> t (PartialFilter a)
-> b
-> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. t (PartialFilter a) -> PartialFilter b
forall (m :: * -> *) f p (t :: * -> *).
(Monad m, ToPartialFilter m f p, Foldable t) =>
t f -> PartialFilterM m p
mkConcatedFilter
convertFilterM
:: (Monad m, ToPartialFilter m f p)
=> f
-> (p -> m p)
convertFilterM :: f -> p -> m p
convertFilterM = PartialFilterM m p -> p -> m p
forall (m :: * -> *) p. PartialFilterM m p -> p -> m p
applyFilterM (PartialFilterM m p -> p -> m p)
-> (f -> PartialFilterM m p) -> f -> p -> m p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> PartialFilterM m p
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter
convertFilter
:: (ToPartialFilter Identity f p)
=> f
-> (p -> p)
convertFilter :: f -> p -> p
convertFilter = PartialFilter p -> p -> p
forall p. PartialFilter p -> p -> p
applyFilter (PartialFilter p -> p -> p)
-> (f -> PartialFilter p) -> f -> p -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f -> PartialFilter p
forall (m :: * -> *) f p.
ToPartialFilter m f p =>
f -> PartialFilterM m p
mkFilter