{-# LANGUAGE FlexibleContexts #-}

module Scrappy.Find where

--import Scrappy.Elem.Types (ElementRep, GroupHtml(GroupHtml), Elem, mkGH, Elem', TreeHTML, ShowHTML)
-- import Elem.TreeElemParser (findSameTreeH)
--import Scrappy.Types (ScrapeFail(..))

import Control.Monad.IO.Class
import Text.Parsec (ParsecT, ParseError, Parsec, Stream, parse, eof, anyChar, (<|>), try, parserZero, anyChar
                   , many) 
import Data.Text (Text)
import Data.Functor.Identity (Identity)
import Data.Either (fromRight)
import Scrappy.Types (ScrapeFail(..))

--data ScrapeFail = Eof | NonMatch

-- | This module provides an interface for getting patterns seperated by whatever in a given source
-- | that you plan to parse

-- | findSequential(_x) is for information rich elements such as products that should have multiple fields
-- | that the user would like to return 




-- | Converts a parsing/scraping pattern to one which either returns Nothing
-- | or Just a list of at least 1 element. Maybe type is used so that there is a clearer
-- | distinction between a failed search and a successful one
findNaive :: Stream s m Char => ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaive :: forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaive ParsecT s u m a
p = ([a] -> Maybe [a]
forall {t :: * -> *} {a}. Foldable t => t a -> Maybe (t a)
justify ([a] -> Maybe [a])
-> ([Either ScrapeFail a] -> [a])
-> [Either ScrapeFail a]
-> Maybe [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  ([a] -> Either ScrapeFail [a] -> [a]
forall b a. b -> Either a b -> b
fromRight [a]
forall a. Monoid a => a
mempty) (Either ScrapeFail [a] -> [a])
-> ([Either ScrapeFail a] -> Either ScrapeFail [a])
-> [Either ScrapeFail a]
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either ScrapeFail a] -> Either ScrapeFail [a]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => [f a] -> f [a]
sequenceA) ([Either ScrapeFail a] -> Maybe [a])
-> ParsecT s u m [Either ScrapeFail a] -> ParsecT s u m (Maybe [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
p)
  where
    justify :: t a -> Maybe (t a)
justify t a
x = if t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (t a)
forall a. Maybe a
Nothing else t a -> Maybe (t a)
forall a. a -> Maybe a
Just t a
x 


findNaiveIO :: (MonadIO m, Stream s m Char, Show a) => ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaiveIO :: forall (m :: * -> *) s a u.
(MonadIO m, Stream s m Char, Show a) =>
ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaiveIO ParsecT s u m a
p = ([a] -> Maybe [a]
forall {t :: * -> *} {a}. Foldable t => t a -> Maybe (t a)
justify ([a] -> Maybe [a])
-> ([Either ScrapeFail a] -> [a])
-> [Either ScrapeFail a]
-> Maybe [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
.  ([a] -> Either ScrapeFail [a] -> [a]
forall b a. b -> Either a b -> b
fromRight [a]
forall a. Monoid a => a
mempty) (Either ScrapeFail [a] -> [a])
-> ([Either ScrapeFail a] -> Either ScrapeFail [a])
-> [Either ScrapeFail a]
-> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Either ScrapeFail a] -> Either ScrapeFail [a]
forall (t :: * -> *) (f :: * -> *) a.
(Traversable t, Applicative f) =>
t (f a) -> f (t a)
forall (f :: * -> *) a. Applicative f => [f a] -> f [a]
sequenceA) ([Either ScrapeFail a] -> Maybe [a])
-> ParsecT s u m [Either ScrapeFail a] -> ParsecT s u m (Maybe [a])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall (m :: * -> *) s a u.
(MonadIO m, Stream s m Char, Show a) =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
findIO ParsecT s u m a
p)
  where
    justify :: t a -> Maybe (t a)
justify t a
x = if t a -> Int
forall a. t a -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length t a
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 then Maybe (t a)
forall a. Maybe a
Nothing else t a -> Maybe (t a)
forall a. a -> Maybe a
Just t a
x 


-- | Great for debugging
findIO :: (MonadIO m, Stream s m Char, Show a) => ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
findIO :: forall (m :: * -> *) s a u.
(MonadIO m, Stream s m Char, Show a) =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
findIO ParsecT s u m a
parser = do
  Either ScrapeFail a
x <- (ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
baseParser ParsecT s u m a
parser)) ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail 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 (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m (Either ScrapeFail a)
givesNothing ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail 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 (Either ScrapeFail a)
forall s (m :: * -> *) t u a.
(Stream s m t, Show t) =>
ParsecT s u m (Either ScrapeFail a)
endStream
  IO () -> ParsecT s u m ()
forall a. IO a -> ParsecT s u m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> ParsecT s u m ()) -> IO () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ Either ScrapeFail a -> IO ()
forall a. Show a => a -> IO ()
print Either ScrapeFail a
x
  case Either ScrapeFail a
x of
    Right a
a -> ([Either ScrapeFail a] -> [Either ScrapeFail a])
-> ParsecT s u m [Either ScrapeFail a]
-> ParsecT s u m [Either ScrapeFail a]
forall a b. (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either ScrapeFail a
x Either ScrapeFail a
-> [Either ScrapeFail a] -> [Either ScrapeFail a]
forall a. a -> [a] -> [a]
:) (ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
parser)
    Left ScrapeFail
Eof -> [Either ScrapeFail a] -> ParsecT s u m [Either ScrapeFail a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
    Left ScrapeFail
NonMatch -> ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
parser


-- givesNothing :: ParsecT e s m (Either ScrapeFail a) 
-- givesNothing = Left NonMatch <$ anyChar

findSequential :: Stream s m Char => [ParsecT s u m a] -> ParsecT s u m [Either ScrapeFail a] 
findSequential :: forall s (m :: * -> *) u a.
Stream s m Char =>
[ParsecT s u m a] -> ParsecT s u m [Either ScrapeFail a]
findSequential [ParsecT s u m a]
parsers = ParsecT s u m [Either ScrapeFail a]
forall a. HasCallStack => a
undefined -- builds off findUntilMatch

findSequential2 :: Stream s m Char => (ParsecT s u m a, ParsecT s u m b) -> ParsecT s u m (a,b)
findSequential2 :: forall s (m :: * -> *) u a b.
Stream s m Char =>
(ParsecT s u m a, ParsecT s u m b) -> ParsecT s u m (a, b)
findSequential2 (ParsecT s u m a
a,ParsecT s u m b
b) = do
  a
a' <- ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m a
a
  b
b' <- ParsecT s u m b -> ParsecT s u m b
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m b
b
  (a, b) -> ParsecT s u m (a, b)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a', b
b')

findSequential3 :: Stream s m Char => (ParsecT s u m a, ParsecT s u m b, ParsecT s u m c) -> ParsecT s u m (a,b,c)
findSequential3 :: forall s (m :: * -> *) u a b c.
Stream s m Char =>
(ParsecT s u m a, ParsecT s u m b, ParsecT s u m c)
-> ParsecT s u m (a, b, c)
findSequential3 (ParsecT s u m a
a,ParsecT s u m b
b,ParsecT s u m c
c) = do
  a
a' <- ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m a
a
  
  b
b' <- ParsecT s u m b -> ParsecT s u m b
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m b
b
  c
c' <- ParsecT s u m c -> ParsecT s u m c
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m c
c
  (a, b, c) -> ParsecT s u m (a, b, c)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a', b
b', c
c')

-- | Like find naive except that finishes parsing on the first match it finds in the document
findUntilMatch :: Stream s m Char => ParsecT s u m a -> ParsecT s u m a
findUntilMatch :: forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m a
parser = do
  Either ScrapeFail a
x <- (ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
baseParser ParsecT s u m a
parser)) ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail 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 (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m (Either ScrapeFail a)
givesNothing
  case Either ScrapeFail a
x of
    Right a
a -> a -> ParsecT s u m a
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
    Left ScrapeFail
NonMatch -> ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m a
findUntilMatch ParsecT s u m a
parser 
    Left ScrapeFail
Eof -> ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a
parserZero


-- -- this is for sequencing matches amongst noise
-- findUntilMatch2 :: ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
-- findUntilMatch2 parser = do
--   x <- (try (baseParser parser)) <|> givesNothing
--   case x of
--     Right a -> return $ Right a
--     Left NonMatch -> findUntilMatch parser 
--     Left Eof -> parserZero 
  


      
-- -- Note: List will be backwards as is 
find :: Stream s m Char => ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find :: forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
parser = do
  Either ScrapeFail a
x <- (ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
baseParser ParsecT s u m a
parser)) ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail 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 (Either ScrapeFail a)
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m (Either ScrapeFail a)
givesNothing ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail 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 (Either ScrapeFail a)
forall s (m :: * -> *) t u a.
(Stream s m t, Show t) =>
ParsecT s u m (Either ScrapeFail a)
endStream
  case Either ScrapeFail a
x of
    Right a
a -> ([Either ScrapeFail a] -> [Either ScrapeFail a])
-> ParsecT s u m [Either ScrapeFail a]
-> ParsecT s u m [Either ScrapeFail a]
forall a b. (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Either ScrapeFail a
x Either ScrapeFail a
-> [Either ScrapeFail a] -> [Either ScrapeFail a]
forall a. a -> [a] -> [a]
:) (ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
parser)
    Left ScrapeFail
Eof -> [Either ScrapeFail a] -> ParsecT s u m [Either ScrapeFail a]
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return []
    Left ScrapeFail
NonMatch -> ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m [Either ScrapeFail a]
find ParsecT s u m a
parser
-- return (x:xs)

-- | Should never throw Left or I did it wrong
streamEdit :: ParsecT String () Identity a -> (a -> String) -> String -> String
streamEdit :: forall a.
ParsecT String () Identity a -> (a -> String) -> String -> String
streamEdit ParsecT String () Identity a
p a -> String
f String
src = String -> Either ParseError String -> String
forall b a. b -> Either a b -> b
fromRight String
forall a. HasCallStack => a
undefined (Either ParseError String -> String)
-> Either ParseError String -> String
forall a b. (a -> b) -> a -> b
$ Parsec String () String
-> String -> String -> Either ParseError String
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse (Parsec String () String -> Parsec String () String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (Parsec String () String -> Parsec String () String)
-> Parsec String () String -> Parsec String () String
forall a b. (a -> b) -> a -> b
$ (a -> String)
-> ParsecT String () Identity a -> Parsec String () String
forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
findEdit a -> String
f ParsecT String () Identity a
p) String
"" String
src


-- -- Note: List will be backwards as is 
findEdit :: Stream String m Char => (a -> String) -> ParsecT String u m a -> ParsecT String u m String 
findEdit :: forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
findEdit a -> String
f ParsecT String u m a
parser = do
  let endStream :: ParsecT String u m StreamEditCase
endStream = ParsecT String u m () -> ParsecT String u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof ParsecT String u m ()
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall a b.
ParsecT String u m a
-> ParsecT String u m b -> ParsecT String u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (StreamEditCase -> ParsecT String u m StreamEditCase
forall a. a -> ParsecT String u m a
forall (m :: * -> *) a. Monad m => a -> m a
return StreamEditCase
EOF)
  StreamEditCase
x <- ((String -> StreamEditCase
Edit (String -> StreamEditCase) -> (a -> String) -> a -> StreamEditCase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
f) (a -> StreamEditCase)
-> ParsecT String u m a -> ParsecT String u m StreamEditCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u m a -> ParsecT String u m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String u m a
parser)) ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> StreamEditCase
Carry (Char -> StreamEditCase)
-> ParsecT String u m Char -> ParsecT String u m StreamEditCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String u m StreamEditCase
forall {u}. ParsecT String u m StreamEditCase
endStream
  case StreamEditCase
x of
    Edit String
str -> (String -> String)
-> ParsecT String u m String -> ParsecT String u m String
forall a b.
(a -> b) -> ParsecT String u m a -> ParsecT String u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) ((a -> String) -> ParsecT String u m a -> ParsecT String u m String
forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
findEdit a -> String
f ParsecT String u m a
parser) 
    Carry Char
chr -> (String -> String)
-> ParsecT String u m String -> ParsecT String u m String
forall a b.
(a -> b) -> ParsecT String u m a -> ParsecT String u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char
chr] String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) ((a -> String) -> ParsecT String u m a -> ParsecT String u m String
forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
findEdit a -> String
f ParsecT String u m a
parser) 
    StreamEditCase
EOF -> String -> ParsecT String u m String
forall a. a -> ParsecT String u m a
forall (m :: * -> *) a. Monad m => a -> m a
return [] 


-- -- Note: List will be backwards as is 
editFirst :: Stream String m Char => (a -> String) -> ParsecT String u m a -> ParsecT String u m String 
editFirst :: forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
editFirst a -> String
f ParsecT String u m a
parser = do
  let endStream :: ParsecT String u m StreamEditCase
endStream = ParsecT String u m () -> ParsecT String u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof ParsecT String u m ()
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall a b.
ParsecT String u m a
-> ParsecT String u m b -> ParsecT String u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (StreamEditCase -> ParsecT String u m StreamEditCase
forall a. a -> ParsecT String u m a
forall (m :: * -> *) a. Monad m => a -> m a
return StreamEditCase
EOF)
  StreamEditCase
x <- ((String -> StreamEditCase
Edit (String -> StreamEditCase) -> (a -> String) -> a -> StreamEditCase
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
f) (a -> StreamEditCase)
-> ParsecT String u m a -> ParsecT String u m StreamEditCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ParsecT String u m a -> ParsecT String u m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String u m a
parser)) ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> StreamEditCase
Carry (Char -> StreamEditCase)
-> ParsecT String u m Char -> ParsecT String u m StreamEditCase
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar) ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
-> ParsecT String u m StreamEditCase
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String u m StreamEditCase
forall {u}. ParsecT String u m StreamEditCase
endStream
  case StreamEditCase
x of
    Edit String
str -> (String -> String)
-> ParsecT String u m String -> ParsecT String u m String
forall a b.
(a -> b) -> ParsecT String u m a -> ParsecT String u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String
str String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) (ParsecT String u m String -> ParsecT String u m String)
-> ParsecT String u m String -> ParsecT String u m String
forall a b. (a -> b) -> a -> b
$ ParsecT String u m Char -> ParsecT String u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT String u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar -- consume rest automatically  --  (findEdit f parser) 
    Carry Char
chr -> (String -> String)
-> ParsecT String u m String -> ParsecT String u m String
forall a b.
(a -> b) -> ParsecT String u m a -> ParsecT String u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Char
chr] String -> String -> String
forall a. Semigroup a => a -> a -> a
<>) ((a -> String) -> ParsecT String u m a -> ParsecT String u m String
forall (m :: * -> *) a u.
Stream String m Char =>
(a -> String) -> ParsecT String u m a -> ParsecT String u m String
findEdit a -> String
f ParsecT String u m a
parser) 
    StreamEditCase
EOF -> String -> ParsecT String u m String
forall a. a -> ParsecT String u m a
forall (m :: * -> *) a. Monad m => a -> m a
return [] 



-- endStream :: (Stream s m t, Show t) => ParsecT s u m (Either ScrapeFail a)
-- endStream = try (eof) >> (return $ Left Eof)

    
-- return (x:xs)

-- | We can define Edit to be a string because we know it will turn back into one
data StreamEditCase = EOF
                    | Carry Char
                    | Edit String


-- findSome = undefined
-- findSomeSame = findSomeSameEl



baseParser :: Stream s m Char => ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
baseParser :: forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
baseParser ParsecT s u m a
parser = (a -> Either ScrapeFail a)
-> ParsecT s u m a -> ParsecT s u m (Either ScrapeFail a)
forall a b. (a -> b) -> ParsecT s u m a -> ParsecT s u m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Either ScrapeFail a
forall a b. b -> Either a b
Right ParsecT s u m a
parser

givesNothing :: Stream s m Char => ParsecT s u m (Either ScrapeFail a) 
givesNothing :: forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m (Either ScrapeFail a)
givesNothing = ScrapeFail -> Either ScrapeFail a
forall a b. a -> Either a b
Left ScrapeFail
NonMatch Either ScrapeFail a
-> ParsecT s u m Char -> ParsecT s u m (Either ScrapeFail a)
forall a b. a -> ParsecT s u m b -> ParsecT s u m a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar

endStream :: (Stream s m t, Show t) => ParsecT s u m (Either ScrapeFail a)
endStream :: forall s (m :: * -> *) t u a.
(Stream s m t, Show t) =>
ParsecT s u m (Either ScrapeFail a)
endStream = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof) ParsecT s u m ()
-> ParsecT s u m (Either ScrapeFail a)
-> ParsecT s u m (Either ScrapeFail a)
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
>> (Either ScrapeFail a -> ParsecT s u m (Either ScrapeFail a)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ScrapeFail a -> ParsecT s u m (Either ScrapeFail a))
-> Either ScrapeFail a -> ParsecT s u m (Either ScrapeFail a)
forall a b. (a -> b) -> a -> b
$ ScrapeFail -> Either ScrapeFail a
forall a b. a -> Either a b
Left ScrapeFail
Eof)




-- | Just since do we really care about non matches?
findSomeHTMLNaive :: Stream s Identity Char => Parsec s () a -> s -> (Maybe [a])
findSomeHTMLNaive :: forall s a.
Stream s Identity Char =>
Parsec s () a -> s -> Maybe [a]
findSomeHTMLNaive Parsec s () a
parser s
text =
  let parser' :: ParsecT s () Identity (Maybe [a])
parser' = Parsec s () a -> ParsecT s () Identity (Maybe [a])
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaive Parsec s () a
parser  
  in 
    case ParsecT s () Identity (Maybe [a])
-> String -> s -> Either ParseError (Maybe [a])
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse ParsecT s () Identity (Maybe [a])
parser' String
"from html:add-in URL soon" s
text of
      Left ParseError
_ -> Maybe [a]
forall a. Maybe a
Nothing 
      Right Maybe [a]
maybe_A -> Maybe [a]
maybe_A

findSomeHTML :: Stream s Identity Char => Parsec s () a -> s -> Either ParseError (Maybe [a])
findSomeHTML :: forall s a.
Stream s Identity Char =>
Parsec s () a -> s -> Either ParseError (Maybe [a])
findSomeHTML Parsec s () a
parser s
text =
  let parser' :: ParsecT s () Identity (Maybe [a])
parser' = Parsec s () a -> ParsecT s () Identity (Maybe [a])
forall s (m :: * -> *) u a.
Stream s m Char =>
ParsecT s u m a -> ParsecT s u m (Maybe [a])
findNaive Parsec s () a
parser  
  in ParsecT s () Identity (Maybe [a])
-> String -> s -> Either ParseError (Maybe [a])
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse ParsecT s () Identity (Maybe [a])
parser' String
"from html at this url: <unimplemented - derp>" s
text

-- findFirst :: ParsecT s u m a -> Text -> Maybe a 
-- findFirst = undefined

-- findAllHtml :: ParsecT s u m a -> Text -> Maybe a 
-- findAllHtml = undefined
-- | My findAll' function design / runParserOnHtml 
  --use Maybe instead of Either to toss failure
  --case [] -> Nothing

-- | so it returns :: Maybe [a] = Just [a] | Nothing
  -- which will be beautiful for modeling at high level from scrape result to scrape result

-- | I also really need to implement non-zero, non-ending predicate inner function
-- | like nonZeroSep https://hackage.haskell.org/package/replace-megaparsec-1.4.4.0/docs/src/Replace.Megaparsec.html#sepCap

-- | NOTE: I can replace manyTill_ with anyTill from Replace.Megaparsec


-- within :: m a -> m a -> m a
-- within ma mb = do
--   x <- do
--     ma 
--     y <- mb
    
--     return mb 





-- -- Mutually exclusive/non-overlapping patterns 
-- findAll' :: ParsecT s u m a -> ParsecT s u m [a]
-- findAll' parser = do
--   x <- skipManyTill anyChar parser <|> return []
--   xs <- findAll' parser
--   return (x : xs)


    
        
findAllBetween :: a
findAllBetween = a
forall a. HasCallStack => a
undefined



-- | Use with constructed for parsing datatype 
buildSequentialElemsParser :: ParsecT s u m [a]
buildSequentialElemsParser :: forall s u (m :: * -> *) a. ParsecT s u m [a]
buildSequentialElemsParser = ParsecT s u m [a]
forall a. HasCallStack => a
undefined
-- | to be applied to inner text of listlike elem


-- findOnChangeInput :: ParsecT s u m (Elem' a)
-- findOnChangeInput = undefined
-- eg : <select id="s-lg-sel-subjects" name="s-lg-sel-subjects" class="form-control" data-placeholder="All Subjects" onchange="springSpace.publicObj.filterAzBySubject(jQuery(this).val(), 3848);">


-- | Rewrite to being any pattern "a"

-- -- | Note: this isnt necessarily deprecated but just useful for when we want to find many of some pattern
-- -- | that doesnt need to exist right after the previous successful match
-- {-# DEPRECATED findSomeSameEl "need manytill out and useful for find, findAll" #-}
-- findSomeSameEl :: (Stream s m Char, ShowHTML a)
--                => Maybe (ParsecT s u m a)
--                -> Maybe [Elem]
--                -> [(String, Maybe String)]
--                -> ParsecT s u m [TreeHTML a]
-- findSomeSameEl matchh elemOpts attrsSubset = do
--   -- (_, treeH) <- manyTill_ (anyChar) (try $ treeElemParser elemOpts matchh attrsSubset)
--   treeH <- treeElemParser elemOpts matchh attrsSubset
--   treeHs <- findMore matchh treeH
--   case treeHs of
--     [] -> parserFail "no matches" -- by definition: this func should return at least 1 copy 
--     _ -> return (treeH : treeHs)
--   where
--     findMore :: (Stream s m Char, ShowHTML a) =>
--                 Maybe (ParsecT s u m a)
--              -> TreeHTML a
--              -> ParsecT s u m [TreeHTML a]    
--     findMore matchh treeH = do
--       treeH' <- --( fmap (:[]) (skipManyTill anyChar (try $ findSameTreeH matchh treeH) )  )
--                 (do
--                     -- note: using skipManyTill VIOLATES expectations of this functions use
--                     -- this is gonna return something like 19 <a></a> tags since it is not
--                     -- in any way required for the congruent elements to be neighbours 
                    
--                   x <- skipManyTill anyChar (try $ findSameTreeH matchh treeH)
--                   return (x:[])
--                 )
--                 <|> return []
--       case treeH' of
--         [] -> return []
--         _ -> fmap ((treeH:[]) <>) $ findMore matchh treeH -- TreeHTML : ParsecT s u m [TreeHTML]