import Control.Monad import Data.List import System.Directory import System.Environment import System.Exit import System.IO import System.IO.Temp import System.Process import Text.PDF.Info import Text.Printf texBegin = "\ \\\documentclass{article}\ \\\usepackage[paperwidth=4.25in,paperheight=11in]{geometry}\ \\\usepackage{pdfpages}\ \\\begin{document}\ \" includeTemplate = "\ \\\includepdf[pages=%d,noautoscale,offset=2.125in 0]{%s}\ \\\includepdf[pages=%d,noautoscale,offset=-2.125in 0]{%s}\ \" texEnd = "\\end{document}" usageTemplate = "\ \USAGE: %s infile.pdf [infile.pdf ...]\n\ \\n\ \Each filename given on the command line is treated as a standard US-letter\n\ \(8.25\" x 11\") sized, two-column PDF, and a new PDF file is produced. If the\n\ \input file name has the form .pdf, then the new file will be named\n\ \-split.pdf. Otherwise, the output file name will be identical to the\n\ \input file name, but with -split.pdf appended. Input filenames must not\n\ \contain whitespace (not even properly-escaped whitespace!).\n\ \\n\ \Also, don't name your input files -h or --help. Come on.\n\ \" fixTheHighlighting = "--" splitPages name n = withTempFile "." "pdfsplit.tex" $ \tmp h -> do hPutStr h texBegin forM_ [1..n] $ \i -> hPrintf h includeTemplate i name i name hPutStr h texEnd hFlush h readProcess "pdflatex" [tmp] "" renameFile (base "tex" tmp ++ ".pdf") (base "pdf" name ++ "-split.pdf") forM_ [".aux", ".log"] (removeFile . (base "tex" tmp ++)) base ext s | ('.':ext) `isSuffixOf` s = zipWith const s (drop (1 + length ext) s) | otherwise = s problem s = printf (printf "Error processing file <%%s>: %s\n" s) process name = do info <- pdfInfo name case (info, words name) of (Left error, _) -> problem "%s" name (show error) >> return 1 (_, _:_:_) -> problem "filenames must not contain whitespace" name >> return 1 (Right PDFInfo { pdfInfoPages = Nothing }, _) -> problem "can't divine the page count" name >> return 1 (Right PDFInfo { pdfInfoPages = Just n }, _) -> splitPages name n >> return 0 usage = getProgName >>= printf usageTemplate >> exitWith ExitSuccess main = do names <- getArgs when (names `elem` [[], ["--help"], ["-h"]]) usage successes <- mapM process names case sum successes of 0 -> exitWith ExitSuccess n -> exitWith (ExitFailure n)