As a practice for interacting with system commands, I wrote a Haskell program that compiles a .tex file specified by the argument.
When one execute this program:
- If no argument is specified, print
"Specify a file!"then exit
- If the specified file does not exist, print
"File not found."then exit
- If the specified file does not have the extension
.tex, then print
"Not a .tex file!"then exit
- If a
.texfile is specified (
report.tex), execute the following commands
$ uplatex report.tex -o report.dvi
$ dvipdfmx report.dvi
$ rm report.dvi
- The program does not have to handle errors in the execution of tex-related commands.
This is what I wrote:
import qualified Control.Shell as S import Data.Char (toLower) import Data.List (dropWhileEnd) import qualified System.Environment as E main = do args <- E.getArgs case args of  -> putStrLn "Specify a file!" (filename:_) -> handler filename isTeXFile :: S.FilePath -> Bool isTeXFile = ( == ".tex") . map toLower . S.takeExtension handler :: S.FilePath -> IO () handler f = do (Right isfile) <- S.shell $ S.isFile f if not isfile then putStrLn "File not found." else if isTeXFile f then do result <- compile f case result of (Left l) -> putStrLn l (Right _) -> return () else putStrLn "Not a .tex file!" compile :: S.FilePath -> IO (Either String ()) compile f = S.shell $ do S.run_ "uplatex" [f, "-o", dvifile] "" S.run_ "dvipdfmx" [dvifile] "" S.rm dvifile where basename = dropWhileEnd (/= '.') f dvifile = basename ++ "dvi"
I appreciate any kind of feedback. I'm especially concerned about:
- The body of
handlerseems unnecessarily complicated. How can I clean it up?
- Am I using
Control.Shellin the right way? Is there other function I should use instead? Maybe I should consider using
Side note: I don't use pdflatex because it is not as good as uplatex at Japanese typesetting and I haven't been catching up with the latest LaTeX families.