-- | Combinators to match tags. Some people prefer to use @(~==)@ from
-- "Text.HTML.TagSoup", others prefer these more structured combinators.
-- Which you use is personal preference.
module Text.HTML.TagSoup.Match where import Text.HTML.TagSoup.Type (
Tag
(..), Attribute) import Data.List
-- | match an opening tag
tagOpen
:: (
str
->
Bool
) -> ([
Attribute
str
] ->
Bool
) ->
Tag
str
->
Bool
tagOpen
pName
pAttrs
(
TagOpen
name
attrs
) =
pName
name
&&
pAttrs
attrs
tagOpen
_ _ _ =
False
-- | match an closing tag
tagClose
:: (
str
->
Bool
) ->
Tag
str
->
Bool
tagClose
pName
(
TagClose
name
) =
pName
name
tagClose
_ _ =
False
-- | match a text
tagText
:: (
str
->
Bool
) ->
Tag
str
->
Bool
tagText
p
(
TagText
text
) =
p
text
tagText
_ _ =
False
tagComment
:: (
str
->
Bool
) ->
Tag
str
->
Bool
tagComment
p
(
TagComment
text
) =
p
text
tagComment
_ _ =
False
-- | match a opening tag's name literally
tagOpenLit
::
Eq str =>
str
-> ([
Attribute
str
] ->
Bool
) ->
Tag
str
->
Bool
tagOpenLit
name
=
tagOpen
(
name
==
)
-- | match a closing tag's name literally
tagCloseLit
::
Eq str =>
str
->
Tag
str
->
Bool
tagCloseLit
name
=
tagClose
(
name
==
)
tagOpenAttrLit
::
Eq str =>
str
->
Attribute
str
->
Tag
str
->
Bool
tagOpenAttrLit
name
attr
=
tagOpenLit
name
(
anyAttrLit
attr
)
{- | Match a tag with given name, that contains an attribute with given name, that satisfies a predicate. If an attribute occurs multiple times, all occurrences are checked. -}
tagOpenAttrNameLit
::
Eq str =>
str
->
str
-> (
str
->
Bool
) ->
Tag
str
->
Bool
tagOpenAttrNameLit
tagName
attrName
pAttrValue
=
tagOpenLit
tagName
(
anyAttr
(\(
name
,
value
) ->
name
==
attrName
&&
pAttrValue
value
))
-- | Check if the 'Tag str' is 'TagOpen' and matches the given name
tagOpenNameLit
::
Eq str =>
str
->
Tag
str
->
Bool
tagOpenNameLit
name
=
tagOpenLit
name
(
const
True
)
-- | Check if the 'Tag str' is 'TagClose' and matches the given name
tagCloseNameLit
::
Eq str =>
str
->
Tag
str
->
Bool
tagCloseNameLit
name
=
tagCloseLit
name
anyAttr
:: ((
str
,
str
) ->
Bool
) -> [
Attribute
str
] ->
Bool
anyAttr
=
any
anyAttrName
:: (
str
->
Bool
) -> [
Attribute
str
] ->
Bool
anyAttrName
p
=
any
(
p
.
fst
)
anyAttrValue
:: (
str
->
Bool
) -> [
Attribute
str
] ->
Bool
anyAttrValue
p
=
any
(
p
.
snd
)
anyAttrLit
::
Eq str =>
(
str
,
str
) -> [
Attribute
str
] ->
Bool
anyAttrLit
attr
=
anyAttr
(
attr
==
)
anyAttrNameLit
::
Eq str =>
str
-> [
Attribute
str
] ->
Bool
anyAttrNameLit
name
=
anyAttrName
(
name
==
)
anyAttrValueLit
::
Eq str =>
str
-> [
Attribute
str
] ->
Bool
anyAttrValueLit
value
=
anyAttrValue
(
value
==
)
getTagContent
::
Eq str =>
str
-> ([
Attribute
str
] ->
Bool
) -> [
Tag
str
] -> [
Tag
str
]
getTagContent
name
pAttrs
=
takeWhile
(
not
.
tagCloseLit
name
)
.
drop
1
.
head
.
sections
(
tagOpenLit
name
pAttrs
) where
sections
p
=
filter
(
p
.
head
)
.
init
.
tails