polysoup-0.6: src/Text/XML/PolySoup/Tag.hs
-- | The module provides tag-level predicates.
module Text.XML.PolySoup.Tag
(
-- * Tag queries
getName
, getText
, getAttr
, getAtts
-- * Extraction predicates
, name
, text
, attr
, atts
-- * Tag predicates
, innerTag
, leafTag
, textTag
, commentTag
, warningTag
, positionTag
, named
, hasAttr
, hasAttrVal
) where
import Prelude hiding (any)
import Control.Monad ((<=<))
import Data.Maybe (isJust)
import Text.HTML.TagSoup
import Text.XML.PolySoup.Predicate
---------------------------------------------------------------------
-- Tag queries
---------------------------------------------------------------------
-- | Get name of the tag.
getName :: Tag s -> Maybe s
getName t = case t of
TagOpen x _ -> Just x
TagClose x -> Just x
TagText x -> Just x
TagComment x -> Just x
TagWarning x -> Just x
TagPosition _ _ -> Nothing
-- | Get contents of the text node.
-- A synonym for `maybeTagText`.
getText :: Tag s -> Maybe s
getText = maybeTagText
-- | Get the list of the attributes.
getAtts :: Tag s -> Maybe [(s, s)]
getAtts (TagOpen _ x) = Just x
getAtts _ = Nothing
-- | Get value of the attribute.
getAttr :: Eq s => s -> Tag s -> Maybe s
getAttr x = lookup x <=< getAtts
---------------------------------------------------------------------
-- Core predicates
---------------------------------------------------------------------
-- | Internal node (i.e., an opening tag).
innerTag :: Q (Tag s) (Tag s)
innerTag = satisfy isTagOpen
-- | Leaf node (everything but an opening tag).
leafTag :: Q (Tag s) (Tag s)
leafTag = satisfy $ not . isTagOpen
-- | A text node.
textTag :: Q (Tag s) (Tag s)
textTag = satisfy isTagText
-- | A comment node.
commentTag :: Q (Tag s) (Tag s)
commentTag = satisfy isTagComment
-- | A warning node.
warningTag :: Q (Tag s) (Tag s)
warningTag = satisfy isTagWarning
-- | A position node.
positionTag :: Q (Tag s) (Tag s)
positionTag = satisfy isTagPosition
-- | Does it have a given name?
named :: Eq s => s -> Q (Tag s) (Tag s)
named x = satisfy $ justSatisfy (==x) . getName
-- | Does it have a given attribute?
hasAttr :: Eq s => s -> Q (Tag s) (Tag s)
hasAttr x = satisfy $ isJust . getAttr x
-- | Does it have a given attribute with a given value?
hasAttrVal :: Eq s => s -> s -> Q (Tag s) (Tag s)
hasAttrVal x y = satisfy $ justSatisfy (==y) . getAttr x
---------------------------------------------------------------------
-- Convenience predicates
---------------------------------------------------------------------
-- | Extract the tag name.
name :: Q (Tag s) s
name = Q getName
-- | Extract textual contents of the text node.
text :: Q (Tag s) s
text = Q getText
-- | Extract the attribute value.
attr :: Eq s => s -> Q (Tag s) s
attr = Q . getAttr
-- | Extract the attribute value.
atts :: Q (Tag s) [(s, s)]
atts = Q getAtts
---------------------------------------------------------------------
-- Misc
---------------------------------------------------------------------
-- | Is it a `Just` value and does it satisfy the given property?
justSatisfy :: (a -> Bool) -> Maybe a -> Bool
justSatisfy = maybe False
-- | Test if a tag is a comment.
isTagComment :: Tag s -> Bool
isTagComment (TagComment _) = True
isTagComment _ = False