module Text.Parser.Substring ( replaceFileOnceWithParser , replaceOnceWithParser , onceReplacify ) where import Control.Applicative ((<|>)) import Data.Attoparsec.Text import Data.Maybe (fromMaybe) import Data.Monoid ((<>), mempty) 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 -- TODO: 失敗した場合に元のテキストを返す replaceOnceWithParser :: Parser Text -> Text -> Text replaceOnceWithParser p = Text.toStrict . TextBuilder.toLazyText . fromMaybe mempty . maybeResult . traceId "fed" . flip feed "" . traceId "parsed" . parse (onceReplacify p) 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