madlang-1.1.2.0: src/Text/Madlibs/Exec/Main.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
-- | Provides `madlang` runMadlangutable
module Text.Madlibs.Exec.Main where
import Control.Monad
import Text.Madlibs.Cata.Run
import Text.Madlibs.Ana.Parse
import Text.Madlibs.Internal.Types
import Text.Madlibs.Internal.Utils
import qualified Data.Text as T
import qualified Data.Text.IO as TIO
import Text.Megaparsec
import Options.Generic
import Development.GitRev
-- | datatype for the program
data Program = Program { input :: FilePath <?> "filepath to template"
, debug :: Bool <?> "whether to display parsed RandTok"
, rep :: Maybe Int <?> "How many times to repeat"
, v :: [String] <?> "Extra input to the template" --fix soon?
, version :: Bool <?> "Display version information for debugging"
} deriving (Generic)
data Subcommand = Debug { file :: FilePath }
| Run { file :: FilePath , rep' :: Maybe Int , input' :: [String] }
-- | Generated automatically by optparse-generic.
instance ParseRecord Program where
-- | Main program action
runMadlang :: IO ()
runMadlang = do
x <- getRecord "Text.Madlibs templating DSL"
if unHelpful . version $ x then putStrLn build else pure ()
case unHelpful . rep $ x of
(Just n) -> replicateM_ n $ template x
Nothing -> template x
-- | given a parsed record perform the appropriate IO action
template :: Program -> IO ()
template rec = do
let filepath = unHelpful . input $ rec
let ins = map T.pack $ (unHelpful . v $ rec)
parsed <- parseFile ins filepath
runFile ins filepath >>= TIO.putStrLn
if unHelpful . debug $ rec then
print parsed
else
pure ()
-- | Generate randomized text from a template
templateGen :: [T.Text] -> T.Text -> Either (ParseError Char Dec) (IO T.Text)
templateGen ins txt = run <$> parseTok ins txt
-- | Generate randomized text from a file conatining a template
runFile :: [T.Text] -> FilePath -> IO T.Text
runFile ins filepath = do
txt <- readFile' filepath
either (pure . parseErrorPretty') (>>= (pure . show')) (templateGen ins txt)
-- | Parse a template file into the `RandTok` data type
parseFile :: [T.Text] -> FilePath -> IO (Either (ParseError Char Dec) RandTok)
parseFile ins filepath = do
txt <- readFile' filepath
let val = parseTok ins txt
pure val
-- | String with git commit string
build :: String
build = concat [ "[version: ", $(gitBranch), "@", $(gitHash)
, " (", $(gitCommitDate), ")"
, " (", $(gitCommitCount), " commits in HEAD)"
, dirty, "] "]
where
dirty | $(gitDirty) = " (uncommitted files present)"
| otherwise = ""