html-rules-0.1.0.0: src/Text/HTML/Rules/Apply.hs
{-# OPTIONS_HADDOCK show-extensions #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE Rank2Types #-}
{-|
Module : Text.HTML.Rules.Apply
Description : Functions for applying sets of rules.
Copyright : (c) Kyle Carter, 2014
License : BSD3
Maintainer : kylcarte@gmail.com
Stability : experimental
-}
module Text.HTML.Rules.Apply
( _HTML
, onHTML
, applyHTMLRules
, applyHTMLRules'
, htmlRules
, htmlRules'
, joinRules
, rule
) where
import Text.HTML.Rules.Transform
import Text.HTML.Rules.Types
import Text.HTML.Rules.Util
import Control.Lens
import Control.Applicative hiding (optional)
import Control.Monad.State
import Text.HTML.TagSoup hiding (Tag)
import Text.HTML.TagSoup.Tree
-- | a parsing/rendering Isomorphism.
_HTML :: Iso' String HTML
_HTML = iso (tagTree . parseTags) (renderTags . flattenTree)
-- | a traversal over HTML under parsing
onHTML :: Functor m => (HTML -> m HTML) -> String -> m String
onHTML = traverseOf _HTML
-- | apply all rules, left to right, bottom up.
applyHTMLRules :: (Applicative m, Monad m) => [FragmentRule m] -> String -> m String
applyHTMLRules = traverseOf _HTML . htmlRules
-- | appy all rules, left to right, top down.
applyHTMLRules' :: (Applicative m, Monad m) => [FragmentRule m] -> String -> m String
applyHTMLRules' = traverseOf _HTML . htmlRules'
{-
-- | apply all rules, left to right, bottom up.
applyRules :: (Functor m, Monad m) => Iso s t a b -> [Rule m a b] -> s -> m t
applyRules l = traverseOf l . rules_XXX
-- | appy all rules, left to right, top down.
applyRules' :: (Applicative m, Monad m) => Iso s t a b -> [Rule m a b] -> s -> m t
applyRules' l = traverseOf l . rules_XXX
rules_XXX :: Monad m => [Rule m a b] -> a -> m b
rules_XXX = undefined
-}
-- | form a bottom-up traversal from a list of 'Rule's
htmlRules :: (Applicative m, Monad m) => [FragmentRule m] -> HTML -> m HTML
htmlRules (joinRules -> go) = (concat <$<) $ mapM $ \t ->
case t of
TagBranch _ _ ds -> do
ds' <- go ds
go1 $ t & _Desc .~ ds'
TagLeaf _ -> go1 t
where
go1 = go . one_
-- | form a top-down traversal from a list of 'Rule's
htmlRules' :: (Applicative m, Monad m) => [FragmentRule m] -> HTML -> m HTML
htmlRules' (joinRules -> go) = (concat <$<) $ mapM $ \t ->
case t of
TagBranch {} -> mapM (traverseOf _Desc go) =<< go1 t
TagLeaf {} -> go1 t
where
go1 = go . one_
-- | join a list of 'Rule's into a traversal, left to right.
joinRules :: (Applicative m, Monad m) => [FragmentRule m] -> HTML -> m HTML
joinRules = concatEndo . map rule
-- | make a traversal out of a single 'Rule'.
-- the 'Trans'formation is applied iff the query predicate holds.
rule :: (Applicative m, Monad m) => FragmentRule m -> HTML -> m HTML
rule (q,m) = mapM go >$> concat
where
go x = do
b <- q x
if b then evalStateT m x
else return [x]
{-
| q x = evalStateT m x
| True = return [x]
-}