module Text.XML.HaXml.Xtract.Combinators where
import Text.XML.HaXml.Types
import Text.XML.HaXml.Combinators
type DFilter = Content -> Content -> [Content]
local,global :: CFilter -> DFilter
local f = \xml sub-> f sub
global f = \xml sub-> f xml
dfilter :: DFilter -> CFilter
dfilter f = \xml-> f xml xml
oloco, oglobo :: (CFilter->CFilter) -> (DFilter->DFilter)
oloco ff = \df-> \xml sub-> (ff (df xml)) sub
oglobo ff = \df-> \xml sub-> (ff (df xml)) xml
ooo :: DFilter -> DFilter -> DFilter
g `ooo` f = \xml-> concatMap (g xml) . (f xml)
(||>||) :: (a->b->[c]) -> (a->b->[c]) -> (a->b->[c])
f ||>|| g = \xml sub-> let first = f xml sub in
if null first then g xml sub else first
owitho, owithouto :: DFilter -> DFilter -> DFilter
f `owitho` g = \xml-> filter (not.null.g xml) . f xml
f `owithouto` g = \xml-> filter (null.g xml) . f xml
okeepo, ononeo :: DFilter
okeepo = \xml sub-> [sub]
ononeo = \xml sub-> []
ochildreno, oelmo, otxto :: DFilter
ochildreno = local children
oelmo = local elm
otxto = local txt
applypred :: CFilter -> DFilter -> CFilter
applypred f p = \xml-> (const f `owitho` p) xml xml
oiffindo :: String -> (String -> DFilter) -> DFilter -> DFilter
oiffindo key yes no xml c@(CElem (Elem _ as _)) =
case (lookup key as) of
Nothing -> no xml c
(Just (AttValue [Left s])) -> yes s xml c
oiffindo key yes no xml other = no xml other
oifTxto :: (String->DFilter) -> DFilter -> DFilter
oifTxto yes no xml c@(CString _ s) = yes s xml c
oifTxto yes no xml c = no xml c
ocato :: [a->b->[c]] -> (a->b->[c])
ocato fs = \xml sub-> concat [ f xml sub | f <- fs ]
(//>>) :: DFilter -> DFilter -> DFilter
f //>> g = g `ooo` ochildreno `ooo` f
(<<//) :: DFilter -> DFilter -> DFilter
f <<// g = f `owitho` (g `ooo` ochildreno)
odeepo :: DFilter -> DFilter
odeepo f = f ||>|| (odeepo f `ooo` ochildreno)