import Data.Text.Encoding.Error (UnicodeException (..)) import Language.Preprocessor.Unlit (unlit, UnlitError (..)) import System.Environment (getArgs, getProgName) import System.Exit (exitFailure) import System.IO (hPutStrLn, stderr) import qualified Data.ByteString as B import qualified Data.Text as T import qualified Data.Text.Encoding as TE usageError :: [String] -> IO x usageError _args = do programName <- getProgName hPutStrLn stderr $ "Usage: " ++ programName ++ " [FILENAME]" exitFailure decodingError :: UnicodeException -> IO x decodingError x = do hPutStrLn stderr $ show x exitFailure unlitError :: [UnlitError] -> IO x unlitError [] = exitFailure unlitError (NotPrecededByBlank ln : xs) = do hPutStrLn stderr $ "Line " ++ show ln ++ ": not preceded by a blank line." unlitError xs unlitError (NotFollowedByBlank ln : xs) = do hPutStrLn stderr $ "Line " ++ show ln ++ ": not followed by a blank line." unlitError xs main :: IO () main = do args <- getArgs (readIn, writeOut) <- case args of [] -> return (B.getContents, B.putStr) [x] -> return (B.readFile x, B.putStr) -- [x, y] -> return (B.readFile x, B.writeFile x) _ -> usageError args contents <- readIn (errs, result) <- case TE.decodeUtf8' contents of Left x -> decodingError x Right x -> return . unlit $ x case errs of [] -> writeOut (TE.encodeUtf8 result) _ -> unlitError errs