{-# LANGUAGE OverloadedStrings, ViewPatterns #-} module Text.HTML.TagStream.Stream where import Data.ByteString (ByteString) import qualified Data.ByteString.Char8 as S import Data.Attoparsec.ByteString (parseOnly) import Data.Conduit import Text.HTML.TagStream.Parser import Text.HTML.TagStream.Types -- | html parser conduit. tokenStream :: Monad m => Conduit ByteString m Token tokenStream = conduitState S.empty push close where push accum input = case parseOnly html (accum `S.append` input) of Right (splitAccum -> (accum', tokens)) -> return $ StateProducing accum' tokens Left err -> fail err close s = return $ if S.null s then [] else [Text s] splitAccum :: [Token] -> (ByteString, [Token]) splitAccum [] = (S.empty, []) splitAccum (reverse -> (Incomplete s : xs)) = (s, reverse xs) splitAccum tokens = (S.empty, tokens)