module Text.Parser.Substring ( replaceFileOnceWithParser , replaceOnceWithParser , onceReplacify ) where import Control.Applicative ((<|>)) import Data.Attoparsec.Text import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text.Lazy as Text import qualified Data.Text.Lazy.Builder as TextBuilder import Data.Text.Lazy.Builder (Builder) import qualified Data.Text.IO as Text import Debug.NoTrace (trace) replaceFileOnceWithParser :: Parser Text -> FilePath -> IO () replaceFileOnceWithParser p filePath = Text.writeFile filePath =<< replaceOnceWithParser p <$> Text.readFile filePath replaceOnceWithParser :: Parser Text -> Text -> Text replaceOnceWithParser p t = maybe t (Text.toStrict . TextBuilder.toLazyText) $ maybeResult $ traceId "fed" $ flip feed "" $ traceId "parsed" $ parse (onceReplacify p) t onceReplacify :: Parser Text -> Parser Builder onceReplacify p = let firstToMatched = (TextBuilder.fromText <$> p) <|> ((<>) <$> (TextBuilder.singleton <$> anyChar) <*> firstToMatched) in (<>) <$> firstToMatched <*> (TextBuilder.fromText <$> takeText) traceIdVia :: Show b => (a -> b) -> String -> a -> a traceIdVia via prefix x = trace (prefix ++ ": " ++ show (via x)) x traceId :: Show a => String -> a -> a traceId = traceIdVia id