{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RecordWildCards #-}
-- <-- Only for RecursiveTree a b c ; remove if changed 
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}

module Scrappy.Elem.Types where

import Scrappy.Links

import Data.Aeson
import Text.URI (URI)
import Data.Text (Text, unpack)
import Data.Map (Map, toList)
import qualified Data.Map as Map

import Data.Graph (Tree (Node), Forest)
--import Text.Megaparsec as MParsec (some)
import Control.Applicative (some)
import Text.Parsec (ParsecT, Stream, parserZero, string, (<|>), anyChar, char, optional, try, manyTill, alphaNum
                   , parserFail)
import Data.Maybe (fromMaybe)
-- Goals: eliminate need for sub tree and inner datatypes ; so Element --> foldr [HTMLMatcher] empty :: Element 


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

-- MAYBE:
class HtmlMatcher a where
  --defines relation between Element -> ITR 

-- practically just show but we dont wanna restrict the entirety
-- of the show class for any sub-datatype in the context of html
-- laws:
  -- in the expression:
       -- x <- parser input
  -- showH x == input
-- This is useful for extracting values while retaining structure for successive parsing 
class ShowHTML a where
  showH :: a -> String

instance ShowHTML Char where
  showH :: Char -> String
showH = Char -> String
forall a. Show a => a -> String
show

instance Show a => ShowHTML [a] where
  showH :: [a] -> String
showH [a]
x = [a] -> String
forall a. Show a => a -> String
show [a]
x

instance ShowHTML Text where
  showH :: Text -> String
showH = Text -> String
unpack 

-- a b c are the three main types
-- class RecursiveTree a b c where
--   type (Element c)
--   type (InnerForest c)--   type (HMatcher c) -- may not need this tho
                 
--   toHtmlGen :: Element c -> HMatcher c
--   elToITR :: Element c -> InnerForest c
--   htmlGenToITR :: HMatcher c -> InnerForest c 
--   concatForest :: InnerForest c -> InnerForest c -> InnerForest c
--    -- must be instance of monoid -- dont need to declare each time 
--   label :: ElemHead -> InnerForest c -> Element c

-- need system too for 
-- Just shared accessors of html datatypes 
class ElementRep (a :: * -> *) where
--type InnerHTMLRep a = something 
  elTag :: a b -> Elem
  attrs :: a b -> Attrs
  innerText' :: a b -> String 
  matches' :: a b -> [b]
--

-- Elem should determine InnerText
-- Summarizes finds as a result of parsing then folding 
-- Recursive fold of multi-constructor structure 
class (ShowHTML c, ElementRep a) => InnerHTMLRep (a :: * -> *)  (b :: * -> *) c | a c -> b c where
  -- type HMatcher a b c :: * -> *
  foldHtmlMatcher :: [HTMLMatcher a c] -> b c
  -- emptyInner :: a d
  innerText :: b c -> String 
  matches :: b c -> [c]



noPat :: Maybe (ParsecT s u m String)
noPat :: forall s u (m :: * -> *). Maybe (ParsecT s u m String)
noPat = Maybe (ParsecT s u m String)
forall a. Maybe a
Nothing

-- | Parser is configured via the return type but gives the input type 
coerceAttrs :: Attrs -> [(String, Maybe String)]
coerceAttrs :: Attrs -> [(String, Maybe String)]
coerceAttrs Attrs
as = (((String, String) -> (String, Maybe String))
-> [(String, String)] -> [(String, Maybe String)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap(((String, String) -> (String, Maybe String))
 -> [(String, String)] -> [(String, Maybe String)])
-> ((String -> Maybe String)
    -> (String, String) -> (String, Maybe String))
-> (String -> Maybe String)
-> [(String, String)]
-> [(String, Maybe String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(String -> Maybe String)
-> (String, String) -> (String, Maybe String)
forall a b. (a -> b) -> (String, a) -> (String, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap) String -> Maybe String
f ([(String, String)] -> [(String, Maybe String)])
-> [(String, String)] -> [(String, Maybe String)]
forall a b. (a -> b) -> a -> b
$ Attrs -> [(String, String)]
forall k a. Map k a -> [(k, a)]
toList Attrs
as 

f :: String -> Maybe String
f :: String -> Maybe String
f String
"" = Maybe String
forall a. Maybe a
Nothing
f String
s = String -> Maybe String
forall a. a -> Maybe a
Just String
s 

-- f :: ([a], [b], [c]) -> Elem' a
-- f (x,y,z) = f' x y z

-- f' el attrs = Elem' el attrs

-------------------------------------------------------------------------------------------------------------------

instance Semigroup (InnerTextHTMLTree a) where
  InnerTextHTMLTree [a]
a String
b Forest ElemHead
c <> :: InnerTextHTMLTree a -> InnerTextHTMLTree a -> InnerTextHTMLTree a
<> InnerTextHTMLTree [a]
d String
e Forest ElemHead
f = [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
forall a. [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
InnerTextHTMLTree ([a]
a [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a]
d) (String
b String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
e) (Forest ElemHead
c Forest ElemHead -> Forest ElemHead -> Forest ElemHead
forall a. Semigroup a => a -> a -> a
<> Forest ElemHead
f)

instance Monoid (InnerTextHTMLTree a) where
  mempty :: InnerTextHTMLTree a
mempty = InnerTextHTMLTree { _matches :: [a]
_matches = [], _innerText :: String
_innerText = String
"", innerTree :: Forest ElemHead
innerTree = [] }

instance Semigroup (InnerTextResult a) where
  InnerTextResult [a]
a String
b <> :: InnerTextResult a -> InnerTextResult a -> InnerTextResult a
<> InnerTextResult [a]
a' String
b' = [a] -> String -> InnerTextResult a
forall a. [a] -> String -> InnerTextResult a
InnerTextResult ([a]
a [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a]
a') (String
b String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
b')

instance Monoid (InnerTextResult a) where
  mempty :: InnerTextResult a
mempty = InnerTextResult { _matchesITR :: [a]
_matchesITR = [], _fullInner :: String
_fullInner = String
"" }

-- instance Num GroupHtml e a where
--   GroupHtml


--Note that the fullInner would be useful for stepping in cases as well needing some pieces of the
-- whole, in the case, that theres a match (like a form: want a form if it has search in it, then
-- we'd want to use certain html elements within the form such as <input> or <select>
--so result would be : InnerTextResult { match = "Search", fullInner = """<input> ... <select> """ } 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


-- foldFuncToITR' :: [Elem' a] -> InnerTextResult a -> InnerTextResult a
-- foldFuncToITR' InnerTextResult{..} (Elem'{..}:xs) =
--   func (InnerTextResult (matchesITR <> matchesEl) (fullInner <> innerHtmlFull)) xs 

-- case x of
  -- Elem' x -> [Element (Elem' x)]



-- foldElements' :: [Elem' a] -> InnerTextResult a
-- foldElements' elems = foldr func (mempty :: InnerTextResult a) (fmap Element elems) 




-- | Tree
-- func :: Show a => [HTMLMatcher a] -> InnerTextHTMLTree a -> InnerTextHTMLTree a
--     func [] state = state
--     func (htmlM:htmlMatchers) (InnerTextHTMLTree{..}) = case htmlM of
--       IText str -> 
--         func htmlMatchers (InnerTextHTMLTree matches (innerText <> str) innerTree)
--       -- | May need to enforce a Show Instance on 'mat'
--       Match mat -> 
--         func htmlMatchers (InnerTextHTMLTree (mat : matches) (innerText <> (show mat)) innerTree)
--       --concat to fullInnerText
--       Element htmlTree -> --interEl :: ElemHead [HtmlMatcher]
--         func htmlMatchers (InnerTextHTMLTree (matches <> matches' htmlTree) (innerText <> treeElemToStr htmlTree) ((makeBranch htmlTree) : innerTree))


-- | SimpleElem
--     func :: (ShowHTML a, ElementRep e) => [HTMLMatcher e a] -> InnerTextResult a
--     func state [] = state
--     func InnerTextResult{..} (next:inners) = case next of
--       IText str -> 
--         func (InnerTextResult matches (innerText <> str)) inners 
--       -- | May need to enforce a Show Instance on 'mat'
--       Match mat -> 
--         func (InnerTextResult (mat : matches) (innerText <> (showH mat))) inners 
--       --concat to fullInnerText
--       Element elem  -> --interEl :: ElemHead [HtmlMatcher]
--         func (InnerTextResult (matches' elem <> matches) (innerText <> (innerText' elem))) inners



-- instance InnerHTMLRep Elem' InnerTextHTMLTree c --> deletion of tree; we no longer care for this info
  
instance ShowHTML c => InnerHTMLRep TreeHTML InnerTextHTMLTree c where
  -- type HMatcher TreeHTML InnerTextHTMLTree c = HMatcher' c 
  -- emptyInner = InnerTextHTMLTree { matches = []
  --                                , innerText = ""
  --                                , innerTree = [] }
  foldHtmlMatcher :: [HTMLMatcher TreeHTML c] -> InnerTextHTMLTree c
foldHtmlMatcher = (HTMLMatcher TreeHTML c
 -> InnerTextHTMLTree c -> InnerTextHTMLTree c)
-> InnerTextHTMLTree c
-> [HTMLMatcher TreeHTML c]
-> InnerTextHTMLTree c
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr HTMLMatcher TreeHTML c
-> InnerTextHTMLTree c -> InnerTextHTMLTree c
forall a.
(InnerHTMLRep TreeHTML InnerTextHTMLTree a, ShowHTML a) =>
HTMLMatcher TreeHTML a
-> InnerTextHTMLTree a -> InnerTextHTMLTree a
fHM_c InnerTextHTMLTree c
forall a. Monoid a => a
mempty -- original one
  matches :: InnerTextHTMLTree c -> [c]
matches = InnerTextHTMLTree c -> [c]
forall a. InnerTextHTMLTree a -> [a]
_matches
  innerText :: InnerTextHTMLTree c -> String
innerText = InnerTextHTMLTree c -> String
forall a. InnerTextHTMLTree a -> String
_innerText 
  
instance ShowHTML c => InnerHTMLRep Elem' InnerTextResult c where
  foldHtmlMatcher :: [HTMLMatcher Elem' c] -> InnerTextResult c
foldHtmlMatcher = (HTMLMatcher Elem' c -> InnerTextResult c -> InnerTextResult c)
-> InnerTextResult c -> [HTMLMatcher Elem' c] -> InnerTextResult c
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr HTMLMatcher Elem' c -> InnerTextResult c -> InnerTextResult c
forall a (e :: * -> *).
(ShowHTML a, ElementRep e) =>
HTMLMatcher e a -> InnerTextResult a -> InnerTextResult a
foldFuncITR InnerTextResult c
forall a. Monoid a => a
mempty -- partially applied, expecting some a 
  matches :: InnerTextResult c -> [c]
matches = InnerTextResult c -> [c]
forall a. InnerTextResult a -> [a]
_matchesITR
  innerText :: InnerTextResult c -> String
innerText = InnerTextResult c -> String
forall a. InnerTextResult a -> String
_fullInner 

-- instance InnerHTMLRep InnerTextResult where
--   type HtmlMatcherM a = HTMLMatcher Elem' a
--   foldHtmlMatcher = foldInners



instance ElementRep (Elem') where
  elTag :: forall b. Elem' b -> String
elTag = Elem' b -> String
forall b. Elem' b -> String
_el
  attrs :: forall b. Elem' b -> Attrs
attrs = Elem' b -> Attrs
forall b. Elem' b -> Attrs
_attrs
  innerText' :: forall b. Elem' b -> String
innerText' = Elem' b -> String
forall b. Elem' b -> String
innerHtmlFull
  matches' :: forall b. Elem' b -> [b]
matches' = Elem' b -> [b]
forall b. Elem' b -> [b]
innerMatches

instance ElementRep (TreeHTML) where
  elTag :: forall b. TreeHTML b -> String
elTag = TreeHTML b -> String
forall b. TreeHTML b -> String
_topEl
  attrs :: forall b. TreeHTML b -> Attrs
attrs = TreeHTML b -> Attrs
forall b. TreeHTML b -> Attrs
_topAttrs
  innerText' :: forall b. TreeHTML b -> String
innerText' = TreeHTML b -> String
forall b. TreeHTML b -> String
_innerText'
  matches' :: forall b. TreeHTML b -> [b]
matches' = TreeHTML b -> [b]
forall b. TreeHTML b -> [b]
_matches'





instance ShowHTML a => ShowHTML (Elem' a) where
  showH :: Elem' a -> String
showH = Elem' a -> String
forall b. Elem' b -> String
elemToStr 



instance ShowHTML a => ShowHTML (TreeHTML a) where
  showH :: TreeHTML a -> String
showH = TreeHTML a -> String
forall a. ShowHTML a => TreeHTML a -> String
treeElemToStr

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
   



    
-------------------------------------------------------------------------------------------------------------------


-- | Note, this is the representation i'll be using
data TreeHTML a = TreeHTML { forall b. TreeHTML b -> String
_topEl :: Elem
                           , forall b. TreeHTML b -> Attrs
_topAttrs :: Map String String
                           --
                           , forall b. TreeHTML b -> [b]
_matches' :: [a]
                           , forall b. TreeHTML b -> String
_innerText' :: String
                           , forall a. TreeHTML a -> Forest ElemHead
_innerTree' :: Forest ElemHead 
                           } deriving Int -> TreeHTML a -> String -> String
[TreeHTML a] -> String -> String
TreeHTML a -> String
(Int -> TreeHTML a -> String -> String)
-> (TreeHTML a -> String)
-> ([TreeHTML a] -> String -> String)
-> Show (TreeHTML a)
forall a. Show a => Int -> TreeHTML a -> String -> String
forall a. Show a => [TreeHTML a] -> String -> String
forall a. Show a => TreeHTML a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> TreeHTML a -> String -> String
showsPrec :: Int -> TreeHTML a -> String -> String
$cshow :: forall a. Show a => TreeHTML a -> String
show :: TreeHTML a -> String
$cshowList :: forall a. Show a => [TreeHTML a] -> String -> String
showList :: [TreeHTML a] -> String -> String
Show 


---Future: Make both below into semigroups
data InnerTextHTMLTree a = InnerTextHTMLTree { forall a. InnerTextHTMLTree a -> [a]
_matches :: [a]
                                             , forall a. InnerTextHTMLTree a -> String
_innerText :: String
                                             , forall a. InnerTextHTMLTree a -> Forest ElemHead
innerTree :: Forest ElemHead
                                             } 
-------------------------------------------------------------------------------------------------------------------
-- | node-like
data Elem' a = Elem' { forall b. Elem' b -> String
_el :: Elem -- change to Elem?
                     , forall b. Elem' b -> Attrs
_attrs :: Map String String --Attrs needs to become map
                     , forall b. Elem' b -> [b]
innerMatches :: [a] --will be "" if not specified
                     , forall b. Elem' b -> String
innerHtmlFull :: String
                     } deriving Int -> Elem' a -> String -> String
[Elem' a] -> String -> String
Elem' a -> String
(Int -> Elem' a -> String -> String)
-> (Elem' a -> String)
-> ([Elem' a] -> String -> String)
-> Show (Elem' a)
forall a. Show a => Int -> Elem' a -> String -> String
forall a. Show a => [Elem' a] -> String -> String
forall a. Show a => Elem' a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Elem' a -> String -> String
showsPrec :: Int -> Elem' a -> String -> String
$cshow :: forall a. Show a => Elem' a -> String
show :: Elem' a -> String
$cshowList :: forall a. Show a => [Elem' a] -> String -> String
showList :: [Elem' a] -> String -> String
Show

-- instance ToJSON (Elem' a) where
--   toJSON = writeTheHtmlEquivalent 


data InnerTextResult a = InnerTextResult { forall a. InnerTextResult a -> [a]
_matchesITR :: [a]
                                         , forall a. InnerTextResult a -> String
_fullInner :: String -- set to Nothing if TextOnly
                                         } deriving Int -> InnerTextResult a -> String -> String
[InnerTextResult a] -> String -> String
InnerTextResult a -> String
(Int -> InnerTextResult a -> String -> String)
-> (InnerTextResult a -> String)
-> ([InnerTextResult a] -> String -> String)
-> Show (InnerTextResult a)
forall a. Show a => Int -> InnerTextResult a -> String -> String
forall a. Show a => [InnerTextResult a] -> String -> String
forall a. Show a => InnerTextResult a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> InnerTextResult a -> String -> String
showsPrec :: Int -> InnerTextResult a -> String -> String
$cshow :: forall a. Show a => InnerTextResult a -> String
show :: InnerTextResult a -> String
$cshowList :: forall a. Show a => [InnerTextResult a] -> String -> String
showList :: [InnerTextResult a] -> String -> String
Show
-------------------------------------------------------------------------------------------------------------------

type HMatcher' a b c = [HTMLMatcher b c] -> a c





data HTMLMatcher (a :: * -> *) b = IText String | Element (a b) | Match b deriving Int -> HTMLMatcher a b -> String -> String
[HTMLMatcher a b] -> String -> String
HTMLMatcher a b -> String
(Int -> HTMLMatcher a b -> String -> String)
-> (HTMLMatcher a b -> String)
-> ([HTMLMatcher a b] -> String -> String)
-> Show (HTMLMatcher a b)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall (a :: * -> *) b.
(Show b, Show (a b)) =>
Int -> HTMLMatcher a b -> String -> String
forall (a :: * -> *) b.
(Show b, Show (a b)) =>
[HTMLMatcher a b] -> String -> String
forall (a :: * -> *) b.
(Show b, Show (a b)) =>
HTMLMatcher a b -> String
$cshowsPrec :: forall (a :: * -> *) b.
(Show b, Show (a b)) =>
Int -> HTMLMatcher a b -> String -> String
showsPrec :: Int -> HTMLMatcher a b -> String -> String
$cshow :: forall (a :: * -> *) b.
(Show b, Show (a b)) =>
HTMLMatcher a b -> String
show :: HTMLMatcher a b -> String
$cshowList :: forall (a :: * -> *) b.
(Show b, Show (a b)) =>
[HTMLMatcher a b] -> String -> String
showList :: [HTMLMatcher a b] -> String -> String
Show







type HTMLMatcherM a = HTMLMatcher TreeHTML a
-- data HTMLMatcher a = IText String | Match a | Element (TreeHTML a)
type Inner a = HTMLMatcher Elem' a


type HTMLMatcherList a = HTMLMatcher [] a
-- IText String | Match a | Element [] a 



-- mainly for testing
-- allows for minimal steps and ensuring that low level parsing is working
data HTMLBare e a = HTMLBare { forall (e :: * -> *) a. HTMLBare e a -> String
tag :: Elem
                             , forall (e :: * -> *) a. HTMLBare e a -> Attrs
attrsss :: Attrs
                             , forall (e :: * -> *) a. HTMLBare e a -> [HTMLMatcher e a]
htmlM :: [HTMLMatcher e a]
                             }



type ElemHead = (Elem, Attrs) 
type Attrs = Map String String
type Elem = String


data AttrsError = IncorrectAttrs deriving Int -> AttrsError -> String -> String
[AttrsError] -> String -> String
AttrsError -> String
(Int -> AttrsError -> String -> String)
-> (AttrsError -> String)
-> ([AttrsError] -> String -> String)
-> Show AttrsError
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> AttrsError -> String -> String
showsPrec :: Int -> AttrsError -> String -> String
$cshow :: AttrsError -> String
show :: AttrsError -> String
$cshowList :: [AttrsError] -> String -> String
showList :: [AttrsError] -> String -> String
Show


instance Eq (GroupHtml e a) where
  GroupHtml [e a]
_ Int
gl1 Int
ml1 == :: GroupHtml e a -> GroupHtml e a -> Bool
== GroupHtml [e a]
_ Int
gl2 Int
ml2 = (Int
gl1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ml1) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
gl2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ml2)

-- allows for max
instance Ord (GroupHtml e a) where
  --  compare multiples of Glength * MaxLength
  (GroupHtml [e a]
_ Int
gl1 Int
ml1) <= :: GroupHtml e a -> GroupHtml e a -> Bool
<= (GroupHtml [e a]
_ Int
gl2 Int
ml2) = (Int
gl1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ml1)  Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= (Int
gl2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ml2)

--Note, maybe there's a way to extend this to being capable of gathering all text-distinct pieces of
--the page

-- | At end will be able to do Eq2 of trees where tree params are (tag,attrs)
-- | Need some "Flexible Equality" match







-- | Would treeElemParser fail on cases like <input> with no end tag? 



-------------------------------------------------------------------------------------------------------------------
-------------------------------------Experimental---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

data MessyTree a b = Noise b | Nodee a [MessyTree a b]
-- where the data at each node, describes the branch .. eg ElemHead
data MessyTreeMatch a b c = Noise' a | Match' b | Node' c [MessyTreeMatch a b c] 


type TreeIndex = [Int]
-- What if we made trees a lense? accessible through treeindex 

-------------------------------------------------------------------------------------------------------------------
-------------------------------------Experimental---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


-- data GroupHtml a = GroupHtml [a] Glength MaxLength deriving Eq -- ... | Nil
data GroupHtml element a = GroupHtml [element a] Glength MaxLength

instance (ElementRep e, Show (e a), Show a, ShowHTML a) => Show (GroupHtml (e :: * -> *) a) where
  show :: GroupHtml e a -> String
show (GroupHtml (e a
e:[e a]
_) Int
count Int
maxELen) =
    String
"GroupHtml { count =" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Int -> String
forall a. Show a => a -> String
show Int
count) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
", longestElem= " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
maxELen String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
", elemStructure=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (e a -> String
forall a. Show a => a -> String
show e a
e)

type Glength = Int -- number of items in group
type MaxLength = Int -- could also just be length of head 



-- a ~ TreeHTML match
ungroup :: ElementRep e => GroupHtml e a -> [e a]
ungroup :: forall (e :: * -> *) a. ElementRep e => GroupHtml e a -> [e a]
ungroup (GroupHtml [e a]
xs Int
_ Int
_) = [e a]
xs 



mkGH :: ElementRep e => [e a] -> GroupHtml e a
mkGH :: forall (e :: * -> *) a. ElementRep e => [e a] -> GroupHtml e a
mkGH [e a]
result = [e a] -> Int -> Int -> GroupHtml e a
forall (element :: * -> *) a.
[element a] -> Int -> Int -> GroupHtml element a
GroupHtml [e a]
result ([e a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [e a]
result) ((String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (e a -> String
forall b. e b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
innerText' ([e a] -> e a
forall a. HasCallStack => [a] -> a
head [e a]
result))))


-- so then id go from

  -- Just GroupHtml { count =20, longestElem= 6047, elemStructure=TreeHTML .. 

-- to:

  -- (e,a) ; in this case -> ("li", [("class", "resultItem ltr")])

              ---- > put to state
              ---- > In order to be safe: findNaive (elemParser "li"..) 
              ---- > with innerText's ; do findNaive linkScraper
                 ---- > 
  

longestElem :: [Elem' a] -> Maybe (Elem' a)
longestElem :: forall a. [Elem' a] -> Maybe (Elem' a)
longestElem [] = Maybe (Elem' a)
forall a. Maybe a
Nothing
longestElem (Elem' a
a:[]) = Elem' a -> Maybe (Elem' a)
forall a. a -> Maybe a
Just Elem' a
a
longestElem (Elem' a
x:[Elem' a]
xs) = if String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Elem' a -> String
forall b. Elem' b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
innerText' Elem' a
x) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length (Elem' a -> String
forall b. Elem' b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
innerText' (Elem' a -> String) -> Elem' a -> String
forall a b. (a -> b) -> a -> b
$ [Elem' a] -> Elem' a
forall a. HasCallStack => [a] -> a
head [Elem' a]
xs)
                     then [Elem' a] -> Maybe (Elem' a)
forall a. [Elem' a] -> Maybe (Elem' a)
longestElem (Elem' a
xElem' a -> [Elem' a] -> [Elem' a]
forall a. a -> [a] -> [a]
: ([Elem' a] -> [Elem' a]
forall a. HasCallStack => [a] -> [a]
tail [Elem' a]
xs))
                     else [Elem' a] -> Maybe (Elem' a)
forall a. [Elem' a] -> Maybe (Elem' a)
longestElem [Elem' a]
xs



maxLength :: [[a]] -> [a]
maxLength :: forall a. [[a]] -> [a]
maxLength ([a]
a:[]) = [a]
a
maxLength ([a]
x:[[a]]
xs) = if [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> [a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([[a]] -> [a]
forall a. HasCallStack => [a] -> a
head [[a]]
xs) then [[a]] -> [a]
forall a. [[a]] -> [a]
maxLength ([a]
x[a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: ([[a]] -> [[a]]
forall a. HasCallStack => [a] -> [a]
tail [[a]]
xs)) else [[a]] -> [a]
forall a. [[a]] -> [a]
maxLength [[a]]
xs



biggestHtmlGroup :: [GroupHtml e a] -> GroupHtml e a 
biggestHtmlGroup :: forall (e :: * -> *) a. [GroupHtml e a] -> GroupHtml e a
biggestHtmlGroup [GroupHtml e a]
ghs = (GroupHtml e a -> GroupHtml e a -> GroupHtml e a)
-> GroupHtml e a -> [GroupHtml e a] -> GroupHtml e a
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr GroupHtml e a -> GroupHtml e a -> GroupHtml e a
forall (e :: * -> *) a.
GroupHtml e a -> GroupHtml e a -> GroupHtml e a
maxE ([e a] -> Int -> Int -> GroupHtml e a
forall (element :: * -> *) a.
[element a] -> Int -> Int -> GroupHtml element a
GroupHtml [] Int
0 Int
0) [GroupHtml e a]
ghs
  where
    maxE :: GroupHtml e a -> GroupHtml e a -> GroupHtml e a -- like max elem
    maxE :: forall (e :: * -> *) a.
GroupHtml e a -> GroupHtml e a -> GroupHtml e a
maxE (GroupHtml [e a]
xs Int
cnt Int
lng) (GroupHtml [e a]
ys Int
cnt' Int
lng') =
      if (Int
cnt Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
lng) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> (Int
cnt' Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
lng')
      then ([e a] -> Int -> Int -> GroupHtml e a
forall (element :: * -> *) a.
[element a] -> Int -> Int -> GroupHtml element a
GroupHtml [e a]
xs Int
cnt Int
lng)
      else ([e a] -> Int -> Int -> GroupHtml e a
forall (element :: * -> *) a.
[element a] -> Int -> Int -> GroupHtml element a
GroupHtml [e a]
ys Int
cnt' Int
lng')
           

-- Note: findAllMutExGroups 
biggestGroup :: ElementRep e => [GroupHtml e a] -> GroupHtml e a
biggestGroup :: forall (e :: * -> *) a.
ElementRep e =>
[GroupHtml e a] -> GroupHtml e a
biggestGroup (GroupHtml e a
gh:[]) = GroupHtml e a
gh 
biggestGroup (n0 :: GroupHtml e a
n0@(GroupHtml [e a]
a Int
x1 Int
y1) :n1 :: GroupHtml e a
n1@(GroupHtml [e a]
b Int
x2 Int
y2):[GroupHtml e a]
ghs) = case (Int
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y1) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> (Int
x2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
y2) of
  Bool
True -> [GroupHtml e a] -> GroupHtml e a
forall (e :: * -> *) a.
ElementRep e =>
[GroupHtml e a] -> GroupHtml e a
biggestGroup (GroupHtml e a
n0GroupHtml e a -> [GroupHtml e a] -> [GroupHtml e a]
forall a. a -> [a] -> [a]
:[GroupHtml e a]
ghs)
  Bool
False -> [GroupHtml e a] -> GroupHtml e a
forall (e :: * -> *) a.
ElementRep e =>
[GroupHtml e a] -> GroupHtml e a
biggestGroup (GroupHtml e a
n1GroupHtml e a -> [GroupHtml e a] -> [GroupHtml e a]
forall a. a -> [a] -> [a]
:[GroupHtml e a]
ghs)
  




getHrefEl :: ElementRep e => Bool -> LastUrl -> e a -> Maybe Link
getHrefEl :: forall (e :: * -> *) a.
ElementRep e =>
Bool -> LastUrl -> e a -> Maybe LastUrl
getHrefEl Bool
b LastUrl
cUrl e a
e = Bool -> LastUrl -> Attrs -> Maybe LastUrl
getHrefAttrs Bool
b LastUrl
cUrl (Attrs -> Maybe LastUrl) -> Attrs -> Maybe LastUrl
forall a b. (a -> b) -> a -> b
$ e a -> Attrs
forall b. e b -> Attrs
forall (a :: * -> *) b. ElementRep a => a b -> Attrs
attrs e a
e 

getHrefAttrs :: Bool -> LastUrl -> Map String String -> Maybe Link 
getHrefAttrs :: Bool -> LastUrl -> Attrs -> Maybe LastUrl
getHrefAttrs Bool
b LastUrl
cUrl Attrs
atribs = Bool -> LastUrl -> String -> Maybe LastUrl
parseLink Bool
b LastUrl
cUrl (String -> Maybe LastUrl) -> Maybe String -> Maybe LastUrl
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< String -> Attrs -> Maybe String
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup String
"href" Attrs
atribs   

  

-- getHref :: ElementRep e => e a -> Maybe String
-- getHref e = ((Map.lookup "href") . attrs) e



-- f
elemToStr :: Elem' a -> String
elemToStr :: forall b. Elem' b -> String
elemToStr Elem' a
elem = String
"<" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Elem' a -> String
forall b. Elem' b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
elTag Elem' a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [(String, String)] -> String
buildAttrs (Attrs -> [(String, String)]
forall k a. Map k a -> [(k, a)]
toList (Elem' a -> Attrs
forall b. Elem' b -> Attrs
forall (a :: * -> *) b. ElementRep a => a b -> Attrs
attrs Elem' a
elem)) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Elem' a -> String
forall b. Elem' b -> String
innerHtmlFull Elem' a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"</" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Elem' a -> String
forall b. Elem' b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
elTag Elem' a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">"
  where
    buildAttrs :: [(String, String)] -> String
buildAttrs [] = String
""
    buildAttrs ((String, String)
attr:[(String, String)]
attrss) = String
" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, String) -> String
forall a b. (a, b) -> a
fst (String, String)
attr String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\"" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, String) -> String
forall a b. (a, b) -> b
snd (String, String)
attr String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\"" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [(String, String)] -> String
buildAttrs [(String, String)]
attrss


-- | List of HTML self-closing (void) elements
selfClosingElems :: [String]
selfClosingElems :: [String]
selfClosingElems = [String
"area", String
"base", String
"br", String
"col", String
"embed", String
"hr", String
"img", String
"input", String
"link", String
"meta", String
"param", String
"source", String
"track", String
"wbr"]

treeElemToStr :: (ShowHTML a) => TreeHTML a -> String
treeElemToStr :: forall a. ShowHTML a => TreeHTML a -> String
treeElemToStr (TreeHTML{[a]
String
Forest ElemHead
Attrs
_topEl :: forall b. TreeHTML b -> String
_topAttrs :: forall b. TreeHTML b -> Attrs
_innerText' :: forall b. TreeHTML b -> String
_matches' :: forall b. TreeHTML b -> [b]
_innerTree' :: forall a. TreeHTML a -> Forest ElemHead
_topEl :: String
_topAttrs :: Attrs
_matches' :: [a]
_innerText' :: String
_innerTree' :: Forest ElemHead
..}) =
  if String
_topEl String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String]
selfClosingElems
  then String
"<" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
_topEl String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Attrs -> String
mdToStringPairs Attrs
_topAttrs String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">"
  else String
"<" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
_topEl String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Attrs -> String
mdToStringPairs Attrs
_topAttrs String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
_innerText'  String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"</" String -> String -> String
forall a. Semigroup a => a -> a -> a
<>  String
_topEl String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">"
  where mdToStringPairs :: Attrs -> String
mdToStringPairs Attrs
attrsSet = case Attrs -> [(String, String)]
forall k a. Map k a -> [(k, a)]
toList Attrs
attrsSet of
          [] -> String
""
          [(String, String)]
attrs -> String
" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [(String, String)] -> String
go [(String, String)]
attrs
        go :: [(String, String)] -> String
go [] = String
""
        go ((String, String)
atr:[])        = ((String, String) -> String
forall a b. (a, b) -> a
fst (String, String)
atr) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Char
'"' Char -> String -> String
forall a. a -> [a] -> [a]
: (String, String) -> String
forall a b. (a, b) -> b
snd (String, String)
atr) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Char
'"' Char -> String -> String
forall a. a -> [a] -> [a]
: [])
        go ((String, String)
atr: [(String, String)]
attrsSet) = ((String, String) -> String
forall a b. (a, b) -> a
fst (String, String)
atr) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Char
'"' Char -> String -> String
forall a. a -> [a] -> [a]
: (String, String) -> String
forall a b. (a, b) -> b
snd (String, String)
atr) String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\" " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> [(String, String)] -> String
go [(String, String)]
attrsSet


-- Future concern:
  -- elem with tree as [Elem a] --> due to lazy evaluation, we dont actually need to summarize these, can just
  -- leave as is, then the user can execute a command
        --- especially easily with accompanying
        -- type TreeIndex = [Int] ; eg [1,4,7] 1st el then 4th el then 7th el

-- Future concern: just discards non matching tokensx
foldFuncMatchlist :: (ShowHTML a, ElementRep e) => HTMLMatcher e a -> InnerTextResult a -> InnerTextResult a
foldFuncMatchlist :: forall a (e :: * -> *).
(ShowHTML a, ElementRep e) =>
HTMLMatcher e a -> InnerTextResult a -> InnerTextResult a
foldFuncMatchlist HTMLMatcher e a
hMatcher InnerTextResult a
itr = InnerTextResult a
forall a. HasCallStack => a
undefined --case hMatcher of
--   IText str -> 
--     InnerTextResult (_matchesITR itr) (_fullInner itr <> str)
--   -- | May need to enforce a Show Instance on 'mat'
--   Match mat -> 
--     InnerTextResult (mat : _matchesITR itr) (_fullInner itr <> (showH mat))
--   --concat to fullInnerText
--   Element elem  -> --interEl :: ElemHead [HtmlMatcher]
--     InnerTextResult (matches' elem <> _matchesITR itr) (_fullInner itr <> (innerText' elem))

--------------------------------------------------------------------------------------------------------------------Testing-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


-- | Bug found: matches start right way then get reversed 

foldFuncTup :: (ShowHTML (e a), ShowHTML a, ElementRep e) => HTMLMatcher e a -> (String, [a]) -> (String, [a])
foldFuncTup :: forall (e :: * -> *) a.
(ShowHTML (e a), ShowHTML a, ElementRep e) =>
HTMLMatcher e a -> (String, [a]) -> (String, [a])
foldFuncTup HTMLMatcher e a
hMatcher (String, [a])
itr = case HTMLMatcher e a
hMatcher of
   IText String
str ->
    (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a]) -> String
forall a b. (a, b) -> a
fst (String, [a])
itr, (String, [a]) -> [a]
forall a b. (a, b) -> b
snd (String, [a])
itr)
    --  May need to enforce a Show Instance on 'mat'
   Match a
mat ->
    (a -> String
forall a. ShowHTML a => a -> String
showH a
mat String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a]) -> String
forall a b. (a, b) -> a
fst (String, [a])
itr, (String, [a]) -> [a]
forall a b. (a, b) -> b
snd (String, [a])
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a
mat])
  --concat to fullInnerText
   Element e a
elem  -> --interEl :: ElemHead [HtmlMatcher]
    (e a -> String
forall a. ShowHTML a => a -> String
showH e a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a]) -> String
forall a b. (a, b) -> a
fst (String, [a])
itr, (String, [a]) -> [a]
forall a b. (a, b) -> b
snd (String, [a])
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> e a -> [a]
forall b. e b -> [b]
forall (a :: * -> *) b. ElementRep a => a b -> [b]
matches' e a
elem)

foldFuncTrup :: (ShowHTML a) => HTMLMatcher TreeHTML a -> (String, [a], Forest ElemHead) -> (String, [a], Forest ElemHead)
foldFuncTrup :: forall a.
ShowHTML a =>
HTMLMatcher TreeHTML a
-> (String, [a], Forest ElemHead) -> (String, [a], Forest ElemHead)
foldFuncTrup HTMLMatcher TreeHTML a
hMatcher (String, [a], Forest ElemHead)
itr = case HTMLMatcher TreeHTML a
hMatcher of
  IText String
str ->
    (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a], Forest ElemHead) -> String
forall a b c. (a, b, c) -> a
fst' (String, [a], Forest ElemHead)
itr, (String, [a], Forest ElemHead) -> [a]
forall a b c. (a, b, c) -> b
snd' (String, [a], Forest ElemHead)
itr, (String, [a], Forest ElemHead) -> Forest ElemHead
forall a b c. (a, b, c) -> c
thd' (String, [a], Forest ElemHead)
itr)
    --  May need to enforce a Show Instance on 'mat'
  Match a
mat ->
    (a -> String
forall a. ShowHTML a => a -> String
showH a
mat String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a], Forest ElemHead) -> String
forall a b c. (a, b, c) -> a
fst' (String, [a], Forest ElemHead)
itr, (String, [a], Forest ElemHead) -> [a]
forall a b c. (a, b, c) -> b
snd' (String, [a], Forest ElemHead)
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a
mat], (String, [a], Forest ElemHead) -> Forest ElemHead
forall a b c. (a, b, c) -> c
thd' (String, [a], Forest ElemHead)
itr)
  --concat to fullInnerText
  Element TreeHTML a
elem  -> --interEl :: ElemHead [HtmlMatcher]
    (TreeHTML a -> String
forall a. ShowHTML a => a -> String
showH TreeHTML a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (String, [a], Forest ElemHead) -> String
forall a b c. (a, b, c) -> a
fst' (String, [a], Forest ElemHead)
itr, (String, [a], Forest ElemHead) -> [a]
forall a b c. (a, b, c) -> b
snd' (String, [a], Forest ElemHead)
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> TreeHTML a -> [a]
forall b. TreeHTML b -> [b]
forall (a :: * -> *) b. ElementRep a => a b -> [b]
matches' TreeHTML a
elem, (String, [a], Forest ElemHead) -> Forest ElemHead
forall a b c. (a, b, c) -> c
thd' (String, [a], Forest ElemHead)
itr Forest ElemHead -> Forest ElemHead -> Forest ElemHead
forall a. Semigroup a => a -> a -> a
<> [TreeHTML a -> Tree ElemHead
forall a. TreeHTML a -> Tree ElemHead
makeBranch TreeHTML a
elem])

-- | In our failed test case with the command : parse f "" "<a></div></a>"
  -- where f :: (Stream s m Char) => ParsecT s u m (TreeHTML String); f = treeElemParser (Just ["a"]) Nothing []
  --
  -- we can tell that foldFuncTrup has been called twice (we believe)
  --
  -- we will test how an element named "div" inside of "a" element would behave

-- | TODO(galen): As we advance scrappy we need to be more realistic in what a clickable is
-- | since here we really have a LinkEl rather than a button (which is clickable but doesn't fit here)
-- | and can emit a side effect such as that of a LinkEl or some other event like we can handle with lazy-js
data Clickable = Clickable ElemHead Link deriving (Clickable -> Clickable -> Bool
(Clickable -> Clickable -> Bool)
-> (Clickable -> Clickable -> Bool) -> Eq Clickable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Clickable -> Clickable -> Bool
== :: Clickable -> Clickable -> Bool
$c/= :: Clickable -> Clickable -> Bool
/= :: Clickable -> Clickable -> Bool
Eq, Int -> Clickable -> String -> String
[Clickable] -> String -> String
Clickable -> String
(Int -> Clickable -> String -> String)
-> (Clickable -> String)
-> ([Clickable] -> String -> String)
-> Show Clickable
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Clickable -> String -> String
showsPrec :: Int -> Clickable -> String -> String
$cshow :: Clickable -> String
show :: Clickable -> String
$cshowList :: [Clickable] -> String -> String
showList :: [Clickable] -> String -> String
Show)


-- | In the future this definitely could be expanded upon for our JS interface
-- | right now this only works for links but wouldn't literally click a button 
--mkClickable :: ElemHead -> Elem' a -> Maybe Clickable
--mkClickable eHead emnt = do
  -- href <- getHref emnt
 -- pure $ Clickable eHead href



  
-- scrapeClickable :: Stream s m Char => LastUrl -> ParsecT s u m Clickable
-- scrapeClickable lastUrl = do
--   e <- elemParser Nothing (Just $ string "download") [("href", Nothing)]
--   href <- mapMaybe getHref $ pure e 
--   let
--     mkURI' :: Text -> Maybe URI
--     mkURI' = mkURI
--   uri <- mapMaybe mkURI' . pure . pack $ fixUrl lastUrl href 
--   return $ Clickable (elTag e, attrs e) (unpack . render $ uri)


mkClickableEH :: Bool -> LastUrl -> ElemHead -> Maybe Clickable
mkClickableEH :: Bool -> LastUrl -> ElemHead -> Maybe Clickable
mkClickableEH Bool
booly LastUrl
cUrl (String
e, Attrs
ats) = do
  LastUrl
h <- Bool -> LastUrl -> Attrs -> Maybe LastUrl
getHrefAttrs Bool
booly LastUrl
cUrl Attrs
ats
  Clickable -> Maybe Clickable
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Clickable -> Maybe Clickable) -> Clickable -> Maybe Clickable
forall a b. (a -> b) -> a -> b
$ ElemHead -> LastUrl -> Clickable
Clickable (String
e, Attrs
ats) LastUrl
h


mkClickable :: ElementRep e => Bool -> LastUrl -> e a -> Maybe Clickable
mkClickable :: forall (e :: * -> *) a.
ElementRep e =>
Bool -> LastUrl -> e a -> Maybe Clickable
mkClickable Bool
booly LastUrl
cUrl e a
e = do
  let ats :: Attrs
ats = e a -> Attrs
forall b. e b -> Attrs
forall (a :: * -> *) b. ElementRep a => a b -> Attrs
attrs e a
e
  LastUrl
h <- Bool -> LastUrl -> Attrs -> Maybe LastUrl
getHrefAttrs Bool
booly LastUrl
cUrl Attrs
ats
  Clickable -> Maybe Clickable
forall a. a -> Maybe a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Clickable -> Maybe Clickable) -> Clickable -> Maybe Clickable
forall a b. (a -> b) -> a -> b
$ ElemHead -> LastUrl -> Clickable
Clickable (e a -> String
forall b. e b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
elTag e a
e,Attrs
ats) LastUrl
h


getLink :: Clickable -> Link
getLink :: Clickable -> LastUrl
getLink (Clickable ElemHead
_ LastUrl
link) = LastUrl
link

getSrc :: a
getSrc = a
forall a. HasCallStack => a
undefined -- just like getHref xo

-- -- |data ElemHead = (Elem/Text, Attrs)
-- -- | Note: Attrs will be changed to being a Map String String
-- makeBranch :: ShowHTML a => TreeHTML a -> Tree ElemHead
-- makeBranch treeH = Node (elTag treeH, attrs treeH) (_innerTree' treeH)




----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

fst' :: (a, b, c) -> a
fst' :: forall a b c. (a, b, c) -> a
fst' (a
a,b
_,c
_) = a
a

snd' :: (a,b,c) -> b
snd' :: forall a b c. (a, b, c) -> b
snd' (a
_,b
b,c
_) = b
b

thd' :: (a,b,c) -> c
thd' :: forall a b c. (a, b, c) -> c
thd' (a
_,b
_,c
c) = c
c

foldFuncITR :: (ShowHTML a, ElementRep e) => HTMLMatcher e a -> InnerTextResult a -> InnerTextResult a
foldFuncITR :: forall a (e :: * -> *).
(ShowHTML a, ElementRep e) =>
HTMLMatcher e a -> InnerTextResult a -> InnerTextResult a
foldFuncITR HTMLMatcher e a
hMatcher InnerTextResult a
itr = case HTMLMatcher e a
hMatcher of
  IText String
str ->
    [a] -> String -> InnerTextResult a
forall a. [a] -> String -> InnerTextResult a
InnerTextResult (InnerTextResult a -> [a]
forall a. InnerTextResult a -> [a]
_matchesITR InnerTextResult a
itr) (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextResult a -> String
forall a. InnerTextResult a -> String
_fullInner InnerTextResult a
itr)
    --  May need to enforce a Show Instance on 'mat'
  Match a
mat ->
    [a] -> String -> InnerTextResult a
forall a. [a] -> String -> InnerTextResult a
InnerTextResult (InnerTextResult a -> [a]
forall a. InnerTextResult a -> [a]
_matchesITR InnerTextResult a
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a
mat]) (a -> String
forall a. ShowHTML a => a -> String
showH a
mat String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextResult a -> String
forall a. InnerTextResult a -> String
_fullInner InnerTextResult a
itr)
  --concat to fullInnerText
  Element e a
elem  -> --interEl :: ElemHead [HtmlMatcher]
    [a] -> String -> InnerTextResult a
forall a. [a] -> String -> InnerTextResult a
InnerTextResult (InnerTextResult a -> [a]
forall a. InnerTextResult a -> [a]
_matchesITR InnerTextResult a
itr [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> e a -> [a]
forall b. e b -> [b]
forall (a :: * -> *) b. ElementRep a => a b -> [b]
matches' e a
elem) (e a -> String
forall b. e b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
innerText' e a
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextResult a -> String
forall a. InnerTextResult a -> String
_fullInner InnerTextResult a
itr)


-- foldFuncITHT :: (ShowHTML a, ElementRep e) => HTMLMatcher TreeHTML a -> InnerTextResult a -> InnerTextResult a
-- We could also implement (with a proper class system, a way to fold to InnerTextResult not just tree
  -- has performance benefits
  
fHM_c :: (InnerHTMLRep TreeHTML InnerTextHTMLTree a, ShowHTML a) =>
         HTMLMatcher TreeHTML a
      -> InnerTextHTMLTree a
      -> InnerTextHTMLTree a
fHM_c :: forall a.
(InnerHTMLRep TreeHTML InnerTextHTMLTree a, ShowHTML a) =>
HTMLMatcher TreeHTML a
-> InnerTextHTMLTree a -> InnerTextHTMLTree a
fHM_c HTMLMatcher TreeHTML a
hMatcher InnerTextHTMLTree a
ithT = case HTMLMatcher TreeHTML a
hMatcher of
  IText String
str ->
    [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
forall a. [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
InnerTextHTMLTree (InnerTextHTMLTree a -> [a]
forall a. InnerTextHTMLTree a -> [a]
_matches InnerTextHTMLTree a
ithT) (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextHTMLTree a -> String
forall a. InnerTextHTMLTree a -> String
_innerText InnerTextHTMLTree a
ithT) (InnerTextHTMLTree a -> Forest ElemHead
forall a. InnerTextHTMLTree a -> Forest ElemHead
innerTree InnerTextHTMLTree a
ithT)
      --  May need to enforce a Show Instance on 'mat'
  Match a
mat ->
    [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
forall a. [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
InnerTextHTMLTree (InnerTextHTMLTree a -> [a]
forall a. InnerTextHTMLTree a -> [a]
_matches InnerTextHTMLTree a
ithT [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> [a
mat]) (a -> String
forall a. ShowHTML a => a -> String
showH a
mat String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextHTMLTree a -> String
forall a. InnerTextHTMLTree a -> String
_innerText InnerTextHTMLTree a
ithT) (InnerTextHTMLTree a -> Forest ElemHead
forall a. InnerTextHTMLTree a -> Forest ElemHead
innerTree InnerTextHTMLTree a
ithT)
      --concat to fullInnerText
  Element TreeHTML a
htmlTree -> --interEl :: ElemHead [HtmlMatcher]
    [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
forall a. [a] -> String -> Forest ElemHead -> InnerTextHTMLTree a
InnerTextHTMLTree (InnerTextHTMLTree a -> [a]
forall a. InnerTextHTMLTree a -> [a]
_matches InnerTextHTMLTree a
ithT [a] -> [a] -> [a]
forall a. Semigroup a => a -> a -> a
<> TreeHTML a -> [a]
forall b. TreeHTML b -> [b]
forall (a :: * -> *) b. ElementRep a => a b -> [b]
matches' TreeHTML a
htmlTree) (TreeHTML a -> String
forall a. ShowHTML a => a -> String
showH TreeHTML a
htmlTree String -> String -> String
forall a. Semigroup a => a -> a -> a
<> InnerTextHTMLTree a -> String
forall a. InnerTextHTMLTree a -> String
_innerText InnerTextHTMLTree a
ithT) (InnerTextHTMLTree a -> Forest ElemHead
forall a. InnerTextHTMLTree a -> Forest ElemHead
innerTree InnerTextHTMLTree a
ithT Forest ElemHead -> Forest ElemHead -> Forest ElemHead
forall a. Semigroup a => a -> a -> a
<> [TreeHTML a -> Tree ElemHead
forall a. TreeHTML a -> Tree ElemHead
makeBranch TreeHTML a
htmlTree])


makeBranch :: TreeHTML a -> Tree ElemHead
makeBranch :: forall a. TreeHTML a -> Tree ElemHead
makeBranch TreeHTML a
treeH = ElemHead -> Forest ElemHead -> Tree ElemHead
forall a. a -> [Tree a] -> Tree a
Node (TreeHTML a -> String
forall b. TreeHTML b -> String
forall (a :: * -> *) b. ElementRep a => a b -> String
elTag TreeHTML a
treeH, TreeHTML a -> Attrs
forall b. TreeHTML b -> Attrs
forall (a :: * -> *) b. ElementRep a => a b -> Attrs
attrs TreeHTML a
treeH) (TreeHTML a -> Forest ElemHead
forall a. TreeHTML a -> Forest ElemHead
_innerTree' TreeHTML a
treeH) -- 2 cases: 
                   



endTag :: Stream s m Char => String -> ParsecT s u m String 
endTag :: forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
endTag String
elem = ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (String
"</" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
elem String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
">"))


enoughMatches :: Int -> String -> Map String String -> (String, [a]) -> ParsecT s u m (Elem' a)
enoughMatches :: forall a s u (m :: * -> *).
Int -> String -> Attrs -> (String, [a]) -> ParsecT s u m (Elem' a)
enoughMatches Int
required String
e Attrs
a (String
asString, [a]
matches) =
  if Int
required Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
matches)
  then Elem' a -> ParsecT s u m (Elem' a)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Elem' a -> ParsecT s u m (Elem' a))
-> Elem' a -> ParsecT s u m (Elem' a)
forall a b. (a -> b) -> a -> b
$ String -> Attrs -> [a] -> String -> Elem' a
forall a. String -> Attrs -> [a] -> String -> Elem' a
Elem' String
e Attrs
a [a]
matches String
asString
  else String -> ParsecT s u m (Elem' a)
forall s u (m :: * -> *) a. String -> ParsecT s u m a
parserFail String
"not enough matches" -- should throw real error

enoughMatchesTree :: Int -> String -> Map String String -> (String, [a], Forest ElemHead) -> ParsecT s u m (TreeHTML a)
enoughMatchesTree :: forall a s u (m :: * -> *).
Int
-> String
-> Attrs
-> (String, [a], Forest ElemHead)
-> ParsecT s u m (TreeHTML a)
enoughMatchesTree Int
required String
e Attrs
a (String
asString, [a]
matches, Forest ElemHead
forest) =
  if Int
required Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
matches)
  then TreeHTML a -> ParsecT s u m (TreeHTML a)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (TreeHTML a -> ParsecT s u m (TreeHTML a))
-> TreeHTML a -> ParsecT s u m (TreeHTML a)
forall a b. (a -> b) -> a -> b
$ String -> Attrs -> [a] -> String -> Forest ElemHead -> TreeHTML a
forall a.
String -> Attrs -> [a] -> String -> Forest ElemHead -> TreeHTML a
TreeHTML String
e Attrs
a [a]
matches String
asString Forest ElemHead
forest
  else String -> ParsecT s u m (TreeHTML a)
forall s u (m :: * -> *) a. String -> ParsecT s u m a
parserFail String
"not enough matches" -- should throw real error 



-- | Explanation: This is for the edge case of <p> tags that are allowed to "contain" text without actually having
-- | an end tag
-- | If i recall correctly, self-closing tags dont allow embedded elements, only plaintext.
-- | this means that the text belonging to the tag read, is that up until the next HTML control section
selfClosingTextful :: (ShowHTML a, Stream s m Char) =>
                      Maybe (ParsecT s u m a)
                   -> ParsecT s u m [HTMLMatcher e a]
selfClosingTextful :: forall a s (m :: * -> *) u (e :: * -> *).
(ShowHTML a, Stream s m Char) =>
Maybe (ParsecT s u m a) -> ParsecT s u m [HTMLMatcher e a]
selfClosingTextful Maybe (ParsecT s u m a)
innerP = do
  -- Fix: all is prefixed with 
  
  Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'>'
  ParsecT s u m (HTMLMatcher e a)
-> ParsecT s u m String -> ParsecT s u m [HTMLMatcher e a]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill
    (
      (ParsecT s u m (HTMLMatcher e a) -> ParsecT s u m (HTMLMatcher e a)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (a -> HTMLMatcher e a
forall (a :: * -> *) b. b -> HTMLMatcher a b
Match (a -> HTMLMatcher e a)
-> ParsecT s u m a -> ParsecT s u m (HTMLMatcher e a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m a
innerP'))
      ParsecT s u m (HTMLMatcher e a)
-> ParsecT s u m (HTMLMatcher e a)
-> ParsecT s u m (HTMLMatcher e a)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (ParsecT s u m (HTMLMatcher e a) -> ParsecT s u m (HTMLMatcher e a)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ((String -> HTMLMatcher e a
forall (a :: * -> *) b. String -> HTMLMatcher a b
IText (String -> HTMLMatcher e a)
-> (Char -> String) -> Char -> HTMLMatcher e a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> String -> String
forall a. a -> [a] -> [a]
:[])) (Char -> HTMLMatcher e a)
-> ParsecT s u m Char -> ParsecT s u m (HTMLMatcher e a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar))
    )
    (
      (ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT s u m String
forall {u}. ParsecT s u m String
anyEndTag) ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'<' ParsecT s u m Char -> ParsecT s u m String -> ParsecT s u m String
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m Char -> ParsecT s u m String
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
alphaNum)
    )
  where anyEndTag :: ParsecT s u m String
anyEndTag = (ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'<'
                       ParsecT s u m Char -> ParsecT s u m () -> ParsecT s u m ()
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (ParsecT s u m Char -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
optional (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'/'))
                       ParsecT s u m () -> ParsecT s u m String -> ParsecT s u m String
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT s u m Char -> ParsecT s u m String
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
some ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
                       ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
" " ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
">")))
        innerP' :: ParsecT s u m a
innerP' = ParsecT s u m a -> Maybe (ParsecT s u m a) -> ParsecT s u m a
forall a. a -> Maybe a -> a
fromMaybe ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a
parserZero Maybe (ParsecT s u m a)
innerP

-- is (selfClosingTextful Nothing) if no match desired 




---- # DEPRECATED UrlPagination "use CurrentQuery" #
data UrlPagination = UrlPagination String String deriving (UrlPagination -> UrlPagination -> Bool
(UrlPagination -> UrlPagination -> Bool)
-> (UrlPagination -> UrlPagination -> Bool) -> Eq UrlPagination
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: UrlPagination -> UrlPagination -> Bool
== :: UrlPagination -> UrlPagination -> Bool
$c/= :: UrlPagination -> UrlPagination -> Bool
/= :: UrlPagination -> UrlPagination -> Bool
Eq, Int -> UrlPagination -> String -> String
[UrlPagination] -> String -> String
UrlPagination -> String
(Int -> UrlPagination -> String -> String)
-> (UrlPagination -> String)
-> ([UrlPagination] -> String -> String)
-> Show UrlPagination
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> UrlPagination -> String -> String
showsPrec :: Int -> UrlPagination -> String -> String
$cshow :: UrlPagination -> String
show :: UrlPagination -> String
$cshowList :: [UrlPagination] -> String -> String
showList :: [UrlPagination] -> String -> String
Show)



--   where
--     func :: Show a => [HTMLMatcher a] -> InnerTextHTMLTree a -> InnerTextHTMLTree a
--     func [] state = state
--     func (htmlM:htmlMatchers) (InnerTextHTMLTree{..}) = case htmlM of
--       IText str -> 
--         func htmlMatchers (InnerTextHTMLTree matches (innerText <> str) innerTree)
--       -- | May need to enforce a Show Instance on 'mat'
--       Match mat -> 
--         func htmlMatchers (InnerTextHTMLTree (mat : matches) (innerText <> (show mat)) innerTree)
--       --concat to fullInnerText
--       Element htmlTree -> --interEl :: ElemHead [HtmlMatcher]
--         func htmlMatchers (InnerTextHTMLTree (matches <> matches' htmlTree) (innerText <> treeElemToStr htmlTree) ((makeBranch htmlTree) : innerTree))



  
-- -- In future, I may generalize this along with HtmlMatcher to be something * -> * -> *

-- instance ToHTMLString a => ToHTMLString (Inner a) where
--   showH NonMatch str = str
--   showH IsMatch x = showH x

-- instance ToHTMLString a => ToHTMLString (HTMLMatcher a) where
--   showH IText str = str
--   showH Match x = showH x
--   showH Element treeH = treeElemToStr

-- Behaves just like two are right beside each other 


  

-- Note: I could fold Elem' by labeling as Element then folding to ITR

-- (Element $ elem) : [] --> ITR





-- foldr :: (Elem' -> ITR -> ITR) -> ITR -> [] Element -> ITR 

-- for InnerTextResult, should preserve as string
-- for InnerTextHTMLTree , elem and attrs should build new single branch where branch = (,) elem attrs

-- my recursive functions can build off of this mutual foldability and work for anything that can provide
-- mutual foldability for any two relations 

-- foldFuncToITR :: [Elem' a] -> InnerTextResult a -> InnerTextResult a
-- foldFuncToITR InnerTextResult{..} (Elem'{..}:xs) =
--   func (InnerTextResult (matchesITR <> matchesEl) (fullInner <> innerHtmlFull)) xs 

-- case x of
  -- Elem' x -> [Element (Elem' x)]



-- foldElements :: [Elem' a] -> InnerTextResult a
-- foldElements elems = foldr func (mempty :: InnerTextResult a) (fmap Element elems) 

-- foldr func mempty htmlMatchers 

-- foldrForHTMLGen :: func@(HMatcher a -> ITR -> ITR) -> mempty -> 




-- this builds off the type classification of IsHTMLRep



-- -- Note: Inner a = HtmlMatcher (String, a) a
-- foldInners :: [Inner a] ->  InnerTextResult a
-- foldInners htmlMatchers = func emptyInner htmlMatchers
--   where
--     func :: (ShowHTML a, ElementRep e) => [HTMLMatcher e a] -> InnerTextResult a -> InnerTextResult a
--     func state [] = state
--     func itr (next:inners) = case next of
--       IText str -> 
--         func (InnerTextResult matches (innerText <> str)) inners 
--       -- | May need to enforce a Show Instance on 'mat'
--       Match mat -> 
--         func (InnerTextResult (mat : matches) (innerText <> (showH mat))) inners 
--       --concat to fullInnerText
--       Element elem  -> --interEl :: ElemHead [HtmlMatcher]
--         func (InnerTextResult (matches' elem <> matches itr) (innerText itr <> (innerText' elem))) inners





















-- instance Eq ((->) a b) where
  -- eq fx fx' = f (x:xs) = fx x == fx' x && f xs


--- > A prerequisite would need to be Universe instance 
type Tag = String