module Text.HTML.TagSoup(
Tag(..), Attribute,
module Text.HTML.TagSoup.Parser,
canonicalizeTags,
isTagOpen, isTagClose, isTagText, isTagWarning,
isTagOpenName, isTagCloseName,
fromTagText, fromAttrib,
maybeTagText, maybeTagWarning,
innerText,
sections, partitions,
TagRep, IsChar, (~==),(~/=)
) where
import Text.HTML.TagSoup.Parser
import Text.HTML.TagSoup.Type
import Data.Char
import Data.List
canonicalizeTags :: [Tag] -> [Tag]
canonicalizeTags = map f
where
f (TagOpen name attrs) | "!" `isPrefixOf` name = TagOpen (map toUpper name) attrs
f (TagOpen name attrs) | otherwise = TagOpen (map toLower name) attrs
f (TagClose name) = TagClose (map toLower name)
f a = a
class TagRep a where
toTagRep :: a -> Tag
instance TagRep Tag where toTagRep = id
class IsChar a where toChar :: a -> Char
instance IsChar Char where toChar = id
instance IsChar c => TagRep [c] where
toTagRep x = case parseTags s of
[a] -> a
_ -> error $ "When using a TagRep it must be exactly one tag, you gave: " ++ s
where s = map toChar x
(~==) :: TagRep t => Tag -> t -> Bool
(~==) a b = f a (toTagRep b)
where
f (TagText y) (TagText x) = null x || x == y
f (TagClose y) (TagClose x) = null x || x == y
f (TagOpen y ys) (TagOpen x xs) = (null x || x == y) && all g xs
where
g (name,val) | null name = val `elem` map snd ys
| null val = name `elem` map fst ys
g nameval = nameval `elem` ys
f _ _ = False
(~/=) :: TagRep t => Tag -> t -> Bool
(~/=) a b = not (a ~== b)
sections :: (a -> Bool) -> [a] -> [[a]]
sections p = filter (p . head) . init . tails
partitions :: (a -> Bool) -> [a] -> [[a]]
partitions p =
let notp = not . p
in groupBy (const notp) . dropWhile notp