{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE CPP #-}
#if MIN_VERSION_base(4,9,0)
{-# OPTIONS_GHC -fno-warn-redundant-constraints -O2 #-}
#endif
#define OVERLAPS {-# OVERLAPPING #-}
module Text.Pandoc.Walk
( Walkable(..)
, queryBlock
, queryCaption
, queryRow
, queryTableHead
, queryTableBody
, queryTableFoot
, queryCell
, queryCitation
, queryInline
, queryMetaValue
, queryPandoc
, walkBlockM
, walkCaptionM
, walkRowM
, walkTableHeadM
, walkTableBodyM
, walkTableFootM
, walkCellM
, walkCitationM
, walkInlineM
, walkMetaValueM
, walkPandocM
)
where
import Control.Applicative (Applicative ((<*>), pure), (<$>))
import Control.Monad ((>=>))
import Data.Functor.Identity (Identity (runIdentity))
import Text.Pandoc.Definition
import qualified Data.Traversable as T
import Data.Traversable (Traversable)
import qualified Data.Foldable as F
import Data.Foldable (Foldable)
import Data.Monoid ((<>))
class Walkable a b where
walk :: (a -> a) -> b -> b
walk f = runIdentity . walkM (return . f)
walkM :: (Monad m, Applicative m, Functor m) => (a -> m a) -> b -> m b
query :: Monoid c => (a -> c) -> b -> c
{-# MINIMAL walkM, query #-}
instance (Foldable t, Traversable t, Walkable a b) => Walkable a (t b) where
walk f = T.fmapDefault (walk f)
walkM f = T.mapM (walkM f)
query f = F.foldMap (query f)
instance OVERLAPS
(Walkable a b, Walkable a c) => Walkable a (b,c) where
walk f (x,y) = (walk f x, walk f y)
walkM f (x,y) = do x' <- walkM f x
y' <- walkM f y
return (x',y')
query f (x,y) = mappend (query f x) (query f y)
instance Walkable Inline Inline where
walkM f x = walkInlineM f x >>= f
query f x = f x <> queryInline f x
instance OVERLAPS
Walkable [Inline] [Inline] where
walkM f = T.traverse (walkInlineM f) >=> f
query f inlns = f inlns <> mconcat (map (queryInline f) inlns)
instance Walkable [Inline] Inline where
walkM = walkInlineM
query = queryInline
instance Walkable Inline Block where
walkM = walkBlockM
query = queryBlock
instance Walkable [Inline] Block where
walkM = walkBlockM
query = queryBlock
instance Walkable Block Block where
walkM f x = walkBlockM f x >>= f
query f x = f x <> queryBlock f x
instance Walkable [Block] Block where
walkM = walkBlockM
query = queryBlock
instance OVERLAPS
Walkable [Block] [Block] where
walkM f = T.traverse (walkBlockM f) >=> f
query f blks = f blks <> mconcat (map (queryBlock f) blks)
instance Walkable Block Inline where
walkM = walkInlineM
query = queryInline
instance Walkable [Block] Inline where
walkM = walkInlineM
query = queryInline
instance Walkable Block Pandoc where
walkM = walkPandocM
query = queryPandoc
instance Walkable [Block] Pandoc where
walkM = walkPandocM
query = queryPandoc
instance Walkable Inline Pandoc where
walkM = walkPandocM
query = queryPandoc
instance Walkable [Inline] Pandoc where
walkM = walkPandocM
query = queryPandoc
instance Walkable Pandoc Pandoc where
walkM f = f
query f = f
instance Walkable Meta Meta where
walkM f = f
query f = f
instance Walkable Inline Meta where
walkM f (Meta metamap) = Meta <$> walkM f metamap
query f (Meta metamap) = query f metamap
instance Walkable [Inline] Meta where
walkM f (Meta metamap) = Meta <$> walkM f metamap
query f (Meta metamap) = query f metamap
instance Walkable Block Meta where
walkM f (Meta metamap) = Meta <$> walkM f metamap
query f (Meta metamap) = query f metamap
instance Walkable [Block] Meta where
walkM f (Meta metamap) = Meta <$> walkM f metamap
query f (Meta metamap) = query f metamap
instance Walkable Inline MetaValue where
walkM = walkMetaValueM
query = queryMetaValue
instance Walkable [Inline] MetaValue where
walkM = walkMetaValueM
query = queryMetaValue
instance Walkable Block MetaValue where
walkM = walkMetaValueM
query = queryMetaValue
instance Walkable [Block] MetaValue where
walkM = walkMetaValueM
query = queryMetaValue
instance Walkable Inline Row where
walkM = walkRowM
query = queryRow
instance Walkable [Inline] Row where
walkM = walkRowM
query = queryRow
instance Walkable Block Row where
walkM = walkRowM
query = queryRow
instance Walkable [Block] Row where
walkM = walkRowM
query = queryRow
instance Walkable Inline TableHead where
walkM = walkTableHeadM
query = queryTableHead
instance Walkable [Inline] TableHead where
walkM = walkTableHeadM
query = queryTableHead
instance Walkable Block TableHead where
walkM = walkTableHeadM
query = queryTableHead
instance Walkable [Block] TableHead where
walkM = walkTableHeadM
query = queryTableHead
instance Walkable Inline TableBody where
walkM = walkTableBodyM
query = queryTableBody
instance Walkable [Inline] TableBody where
walkM = walkTableBodyM
query = queryTableBody
instance Walkable Block TableBody where
walkM = walkTableBodyM
query = queryTableBody
instance Walkable [Block] TableBody where
walkM = walkTableBodyM
query = queryTableBody
instance Walkable Inline TableFoot where
walkM = walkTableFootM
query = queryTableFoot
instance Walkable [Inline] TableFoot where
walkM = walkTableFootM
query = queryTableFoot
instance Walkable Block TableFoot where
walkM = walkTableFootM
query = queryTableFoot
instance Walkable [Block] TableFoot where
walkM = walkTableFootM
query = queryTableFoot
instance Walkable Inline Caption where
walkM = walkCaptionM
query = queryCaption
instance Walkable [Inline] Caption where
walkM = walkCaptionM
query = queryCaption
instance Walkable Block Caption where
walkM = walkCaptionM
query = queryCaption
instance Walkable [Block] Caption where
walkM = walkCaptionM
query = queryCaption
instance Walkable Inline Cell where
walkM = walkCellM
query = queryCell
instance Walkable [Inline] Cell where
walkM = walkCellM
query = queryCell
instance Walkable Block Cell where
walkM = walkCellM
query = queryCell
instance Walkable [Block] Cell where
walkM = walkCellM
query = queryCell
instance Walkable Inline Citation where
walkM = walkCitationM
query = queryCitation
instance Walkable [Inline] Citation where
walkM = walkCitationM
query = queryCitation
instance Walkable Block Citation where
walkM = walkCitationM
query = queryCitation
instance Walkable [Block] Citation where
walkM = walkCitationM
query = queryCitation
walkInlineM :: (Walkable a Citation, Walkable a [Block],
Walkable a [Inline], Monad m, Applicative m, Functor m)
=> (a -> m a) -> Inline -> m Inline
walkInlineM _ (Str xs) = return (Str xs)
walkInlineM f (Emph xs) = Emph <$> walkM f xs
walkInlineM f (Underline xs) = Underline <$> walkM f xs
walkInlineM f (Strong xs) = Strong <$> walkM f xs
walkInlineM f (Strikeout xs) = Strikeout <$> walkM f xs
walkInlineM f (Subscript xs) = Subscript <$> walkM f xs
walkInlineM f (Superscript xs) = Superscript <$> walkM f xs
walkInlineM f (SmallCaps xs) = SmallCaps <$> walkM f xs
walkInlineM f (Quoted qt xs) = Quoted qt <$> walkM f xs
walkInlineM f (Link atr xs t) = Link atr <$> walkM f xs <*> pure t
walkInlineM f (Image atr xs t) = Image atr <$> walkM f xs <*> pure t
walkInlineM f (Note bs) = Note <$> walkM f bs
walkInlineM f (Span attr xs) = Span attr <$> walkM f xs
walkInlineM f (Cite cs xs) = Cite <$> walkM f cs <*> walkM f xs
walkInlineM _ LineBreak = return LineBreak
walkInlineM _ SoftBreak = return SoftBreak
walkInlineM _ Space = return Space
walkInlineM _ x@Code {} = return x
walkInlineM _ x@Math {} = return x
walkInlineM _ x@RawInline {} = return x
queryInline :: (Walkable a Citation, Walkable a [Block],
Walkable a [Inline], Monoid c)
=> (a -> c) -> Inline -> c
queryInline _ (Str _) = mempty
queryInline f (Emph xs) = query f xs
queryInline f (Underline xs) = query f xs
queryInline f (Strong xs) = query f xs
queryInline f (Strikeout xs) = query f xs
queryInline f (Subscript xs) = query f xs
queryInline f (Superscript xs)= query f xs
queryInline f (SmallCaps xs) = query f xs
queryInline f (Quoted _ xs) = query f xs
queryInline f (Cite cs xs) = query f cs <> query f xs
queryInline _ (Code _ _) = mempty
queryInline _ Space = mempty
queryInline _ SoftBreak = mempty
queryInline _ LineBreak = mempty
queryInline _ (Math _ _) = mempty
queryInline _ (RawInline _ _) = mempty
queryInline f (Link _ xs _) = query f xs
queryInline f (Image _ xs _) = query f xs
queryInline f (Note bs) = query f bs
queryInline f (Span _ xs) = query f xs
walkBlockM :: (Walkable a [Block], Walkable a [Inline], Walkable a Row,
Walkable a Caption, Walkable a TableHead, Walkable a TableBody,
Walkable a TableFoot, Monad m, Applicative m, Functor m)
=> (a -> m a) -> Block -> m Block
walkBlockM f (Para xs) = Para <$> walkM f xs
walkBlockM f (Plain xs) = Plain <$> walkM f xs
walkBlockM f (LineBlock xs) = LineBlock <$> walkM f xs
walkBlockM f (BlockQuote xs) = BlockQuote <$> walkM f xs
walkBlockM f (OrderedList a cs) = OrderedList a <$> walkM f cs
walkBlockM f (BulletList cs) = BulletList <$> walkM f cs
walkBlockM f (DefinitionList xs) = DefinitionList <$> walkM f xs
walkBlockM f (Header lev attr xs) = Header lev attr <$> walkM f xs
walkBlockM f (Div attr bs') = Div attr <$> walkM f bs'
walkBlockM _ x@CodeBlock {} = return x
walkBlockM _ x@RawBlock {} = return x
walkBlockM _ HorizontalRule = return HorizontalRule
walkBlockM _ Null = return Null
walkBlockM f (Table attr capt as hs bs fs)
= do capt' <- walkM f capt
hs' <- walkM f hs
bs' <- walkM f bs
fs' <- walkM f fs
return $ Table attr capt' as hs' bs' fs'
queryBlock :: (Walkable a Citation, Walkable a [Block], Walkable a Row,
Walkable a Caption, Walkable a TableHead, Walkable a TableBody,
Walkable a TableFoot, Walkable a [Inline], Monoid c)
=> (a -> c) -> Block -> c
queryBlock f (Para xs) = query f xs
queryBlock f (Plain xs) = query f xs
queryBlock f (LineBlock xs) = query f xs
queryBlock _ (CodeBlock _ _) = mempty
queryBlock _ (RawBlock _ _) = mempty
queryBlock f (BlockQuote bs) = query f bs
queryBlock f (OrderedList _ cs) = query f cs
queryBlock f (BulletList cs) = query f cs
queryBlock f (DefinitionList xs) = query f xs
queryBlock f (Header _ _ xs) = query f xs
queryBlock _ HorizontalRule = mempty
queryBlock f (Table _ capt _ hs bs fs)
= query f capt <>
query f hs <>
query f bs <>
query f fs
queryBlock f (Div _ bs) = query f bs
queryBlock _ Null = mempty
walkMetaValueM :: (Walkable a MetaValue, Walkable a [Block],
Walkable a [Inline], Monad f, Applicative f, Functor f)
=> (a -> f a) -> MetaValue -> f MetaValue
walkMetaValueM f (MetaList xs) = MetaList <$> walkM f xs
walkMetaValueM _ (MetaBool b) = return $ MetaBool b
walkMetaValueM _ (MetaString s) = return $ MetaString s
walkMetaValueM f (MetaInlines xs) = MetaInlines <$> walkM f xs
walkMetaValueM f (MetaBlocks bs) = MetaBlocks <$> walkM f bs
walkMetaValueM f (MetaMap m) = MetaMap <$> walkM f m
queryMetaValue :: (Walkable a MetaValue, Walkable a [Block],
Walkable a [Inline], Monoid c)
=> (a -> c) -> MetaValue -> c
queryMetaValue f (MetaList xs) = query f xs
queryMetaValue _ (MetaBool _) = mempty
queryMetaValue _ (MetaString _) = mempty
queryMetaValue f (MetaInlines xs) = query f xs
queryMetaValue f (MetaBlocks bs) = query f bs
queryMetaValue f (MetaMap m) = query f m
walkCitationM :: (Walkable a [Inline], Monad m, Applicative m, Functor m)
=> (a -> m a) -> Citation -> m Citation
walkCitationM f (Citation id' pref suff mode notenum hash) =
do pref' <- walkM f pref
suff' <- walkM f suff
return $ Citation id' pref' suff' mode notenum hash
queryCitation :: (Walkable a [Inline], Monoid c)
=> (a -> c) -> Citation -> c
queryCitation f (Citation _ pref suff _ _ _) = query f pref <> query f suff
walkRowM :: (Walkable a Cell, Monad m)
=> (a -> m a) -> Row -> m Row
walkRowM f (Row attr bd) = Row attr <$> walkM f bd
queryRow :: (Walkable a Cell, Monoid c)
=> (a -> c) -> Row -> c
queryRow f (Row _ bd) = query f bd
walkTableHeadM :: (Walkable a Row, Monad m)
=> (a -> m a) -> TableHead -> m TableHead
walkTableHeadM f (TableHead attr body) = TableHead attr <$> walkM f body
queryTableHead :: (Walkable a Row, Monoid c)
=> (a -> c) -> TableHead -> c
queryTableHead f (TableHead _ body) = query f body
walkTableBodyM :: (Walkable a Row, Monad m)
=> (a -> m a) -> TableBody -> m TableBody
walkTableBodyM f (TableBody attr rhc hd bd) = TableBody attr rhc <$> walkM f hd <*> walkM f bd
queryTableBody :: (Walkable a Row, Monoid c)
=> (a -> c) -> TableBody -> c
queryTableBody f (TableBody _ _ hd bd) = query f hd <> query f bd
walkTableFootM :: (Walkable a Row, Monad m)
=> (a -> m a) -> TableFoot -> m TableFoot
walkTableFootM f (TableFoot attr body) = TableFoot attr <$> walkM f body
queryTableFoot :: (Walkable a Row, Monoid c)
=> (a -> c) -> TableFoot -> c
queryTableFoot f (TableFoot _ body) = query f body
walkCellM :: (Walkable a [Block], Monad m)
=> (a -> m a) -> Cell -> m Cell
walkCellM f (Cell attr ma rs cs content) = Cell attr ma rs cs <$> walkM f content
queryCell :: (Walkable a [Block], Monoid c)
=> (a -> c) -> Cell -> c
queryCell f (Cell _ _ _ _ content) = query f content
walkCaptionM :: (Walkable a [Block], Walkable a [Inline], Monad m, Walkable a ShortCaption)
=> (a -> m a) -> Caption -> m Caption
walkCaptionM f (Caption mshort body) = Caption <$> walkM f mshort <*> walkM f body
queryCaption :: (Walkable a [Block], Walkable a [Inline], Walkable a ShortCaption, Monoid c)
=> (a -> c) -> Caption -> c
queryCaption f (Caption mshort body) = query f mshort <> query f body
walkPandocM :: (Walkable a Meta, Walkable a [Block], Monad m,
Applicative m, Functor m)
=> (a -> m a) -> Pandoc -> m Pandoc
walkPandocM f (Pandoc m bs) = do m' <- walkM f m
bs' <- walkM f bs
return $ Pandoc m' bs'
queryPandoc :: (Walkable a Meta, Walkable a [Block], Monoid c)
=> (a -> c) -> Pandoc -> c
queryPandoc f (Pandoc m bs) = query f m <> query f bs