{-# LANGUAGE DeriveDataTypeable #-} module CommandLine (Args(..), apply_args, show_help) where -- Get the version from Cabal. import Paths_lwn_epub (version) import Data.Version (showVersion) import Data.String.Utils (startswith) import System.Console.CmdArgs ( CmdArgs, Data, Mode, Typeable, (&=), argPos, cmdArgsApply, cmdArgsMode, def, details, help, program, typ, typFile, summary ) import System.Console.CmdArgs.Explicit (process) import System.Environment (getArgs, withArgs) import System.Exit (ExitCode(..), exitWith) import System.IO (hPutStrLn, stderr) import ExitCodes data Args = Args { output :: FilePath, article :: String } deriving (Show, Data, Typeable) description :: String description = "Convert LWN articles to EPUB format." program_name :: String program_name = "lwn_epub" lwn_epub_summary :: String lwn_epub_summary = program_name ++ "-" ++ (showVersion version) output_help :: String output_help = "Output file, defaults to stdout" arg_spec :: Mode (CmdArgs Args) arg_spec = cmdArgsMode $ Args { output = def &= typFile &= help output_help, article = def &= argPos 0 &= typ "ARTICLE" } &= program program_name &= summary lwn_epub_summary &= details [description] -- Infix notation won't work, the arguments are backwards! is_missing_arg_error :: String -> Bool is_missing_arg_error s = startswith "Requires at least" s show_help :: IO (CmdArgs Args) show_help = withArgs ["--help"] parse_args parse_args :: IO (CmdArgs Args) parse_args = do x <- getArgs let y = process arg_spec x case y of Right result -> return result Left err -> if (is_missing_arg_error err) then -- Disregard the error message, show help instead. show_help else do hPutStrLn stderr err exitWith (ExitFailure exit_args_parse_failed) -- | Really get the command-line arguments. This calls 'parse_args' -- first to replace the default "wrong number of arguments" error, -- and then runs 'cmdArgsApply' on the result to do what the -- 'cmdArgs' function usually does. apply_args :: IO Args apply_args = parse_args >>= cmdArgsApply