Newer
Older
{-# LANGUAGE FlexibleInstances, NamedFieldPuns, OverloadedStrings #-}
Alice Brenon
committed
module Text.Editor (
Editable(..)
, (<>.)
, apply
, fileFilter
, xargs
Alice Brenon
committed
) where
import Control.Monad.IO.Class (MonadIO(..))
import Data.ByteString.Lazy as BS (ByteString, pack, unpack)
Alice Brenon
committed
import Data.Text as Text (Text, intercalate, lines, pack, unpack)
import Data.Text.IO as Text (readFile, writeFile)
import System.FilePath (replaceDirectory, replaceExtension)
Alice Brenon
committed
class Editable a where
enter :: Text -> a
leave :: a -> Text
instance Editable [Text] where
enter = Text.lines
leave = Text.intercalate "\n"
instance Editable String where
enter = Text.unpack
leave = Text.pack
type Editor m = FilePath -> FilePath -> m ()
fileFilter :: (Editable a, Editable b, MonadIO m) =>
(FilePath -> FilePath) -> (a -> m b) -> Editor m
fileFilter fixFormat transform target input =
Alice Brenon
committed
liftIO (Text.readFile input)
Alice Brenon
committed
>>= liftIO . Text.writeFile output . leave
where
output = fixFormat $ replaceDirectory input target
Alice Brenon
committed
(<>.) :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> String -> Editor m
(<>.) transform extension = fileFilter (`replaceExtension` extension) transform
Alice Brenon
committed
apply :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> Editor m
apply = fileFilter id
Alice Brenon
committed
xargs :: (Editable a, Editable b, MonadIO m) => (a -> m b) -> FilePath -> m ()
xargs transform target =
Prelude.lines <$> liftIO getContents >>= mapM_ (apply transform target)