@@ -53,7 +53,7 @@ import Data.List (intercalate)
5353#endif
5454import Data.List (isPrefixOf)
5555import Text.Pandoc.Class (PandocIO, extractMedia, fillMediaBag, getCommonState,
56− getVerbosity, putCommonState, report, runIO,
56+ getVerbosity, putCommonState, report,
5757 runIOorExplode, setVerbosity)
5858import Text.Pandoc.Logging
5959
@@ -101,19 +101,18 @@ makePDF program pdfargs writer opts doc = do
101101#else
102102 let tmpdir = tmpdir'
103103#endif
104− (source, newCommonState)
105− <- runIOorExplode $ do
106− putCommonState commonState
107− doc' <- handleImages tmpdir doc
108− result <- writer opts doc'
109− cs <- getCommonState
110− return (result, cs)
111− res <- case baseProg of
112− "context" -> context2pdf verbosity program pdfargs tmpdir source
113− prog | prog `elem` ["pdflatex", "lualatex", "xelatex", "latexmk"]
114− -> tex2pdf verbosity program pdfargs tmpdir source
115− _ -> return $ Left $ UTF8.fromStringLazy $ "Unknown program " ++ program
116− return (newCommonState, res)
104+ runIOorExplode $ do
105+ putCommonState commonState
106+ doc' <- handleImages tmpdir doc
107+ source <- writer opts doc'
108+ res <- case baseProg of
109+ "context" -> context2pdf verbosity program pdfargs tmpdir source
110+ prog | prog `elem` ["pdflatex", "lualatex", "xelatex", "latexmk"]
111+ -> tex2pdf verbosity program pdfargs tmpdir source
112+ _ -> return $ Left $ UTF8.fromStringLazy
113+ $ "Unknown program " ++ program
114+ cs <- getCommonState
115+ return (cs, res)
117116 putCommonState newCommonState
118117 return res
119118
@@ -206,7 +205,7 @@ tex2pdf :: Verbosity -- ^ Verbosity level
206205 -> [String] -- ^ Arguments to the latex-engine
207206 -> FilePath -- ^ temp directory for output
208207 -> Text -- ^ tex source
209− -> IO (Either ByteString ByteString)
208+ -> PandocIO (Either ByteString ByteString)
210209tex2pdf verbosity program args tmpDir source = do
211210 let numruns =
212211 if takeBaseName program == "latexmk"
@@ -214,12 +213,8 @@ tex2pdf verbosity program args tmpDir source = do
214213 else if "\\tableofcontents" `T.isInfixOf` source
215214 then 3 -- to get page numbers
216215 else 2 -- 1 run won't give you PDF bookmarks
217− (exit, log', mbPdf) <- E.catch
218− (runTeXProgram verbosity program args 1 numruns tmpDir source)
219− (\(e :: IOError) -> if isDoesNotExistError e
220− then E.throwIO $
221− PandocPDFProgramNotFoundError program
222− else E.throwIO e)
216+ (exit, log', mbPdf) <- runTeXProgram verbosity program args 1 numruns
217+ tmpDir source
223218 case (exit, mbPdf) of
224219 (ExitFailure _, _) -> do
225220 let logmsg = extractMsg log'
@@ -235,7 +230,7 @@ tex2pdf verbosity program args tmpDir source = do
235230 missingCharacterWarnings verbosity log'
236231 return $ Right pdf
237232
238−missingCharacterWarnings :: Verbosity -> ByteString -> IO ()
233+missingCharacterWarnings :: Verbosity -> ByteString -> PandocIO ()
239234missingCharacterWarnings verbosity log' = do
240235 let ls = BC.lines log'
241236 let isMissingCharacterWarning = BC.isPrefixOf "Missing character: "
@@ -243,10 +238,8 @@ missingCharacterWarnings verbosity log' = do
243238 | l <- ls
244239 , isMissingCharacterWarning l
245240 ]
246− runIO $ do
247− setVerbosity verbosity
248− mapM_ (report . MissingCharacter) warnings
249− return ()
241+ setVerbosity verbosity
242+ mapM_ (report . MissingCharacter) warnings
250243
251244-- parsing output
252245
@@ -273,23 +266,23 @@ extractConTeXtMsg log' = do
273266-- contents of stdout, contents of produced PDF if any). Rerun
274267-- a fixed number of times to resolve references.
275268runTeXProgram :: Verbosity -> String -> [String] -> Int -> Int -> FilePath
276− -> Text -> IO (ExitCode, ByteString, Maybe ByteString)
269+ -> Text -> PandocIO (ExitCode, ByteString, Maybe ByteString)
277270runTeXProgram verbosity program args runNumber numRuns tmpDir' source = do
278271 let tmpDir =
279272 case [x | x <- args, "-outdir=" `isPrefixOf` x] of
280273 [x] -> drop 8 x
281274 _ -> tmpDir'
282− createDirectoryIfMissing True tmpDir
275+ liftIO $ createDirectoryIfMissing True tmpDir
283276 let file = tmpDir </> "input.tex"
284− exists <- doesFileExist file
285− unless exists $ BS.writeFile file $ UTF8.fromText source
277+ exists <- liftIO $ doesFileExist file
278+ unless exists $ liftIO $ BS.writeFile file $ UTF8.fromText source
286279 let programArgs =
287280 if takeBaseName program == "latexmk"
288281 then ["-interaction=batchmode", "-halt-on-error", "-pdf",
289282 "-quiet", "-outdir=" ++ tmpDir] ++ args ++ [file]
290283 else ["-halt-on-error", "-interaction", "nonstopmode",
291284 "-output-directory", tmpDir] ++ args ++ [file]
292− env' <- getEnvironment
285+ env' <- liftIO getEnvironment
293286 let sep = [searchPathSeparator]
294287 let texinputs = maybe (tmpDir ++ sep) ((tmpDir ++ sep) ++)
295288 $ lookup "TEXINPUTS" env'
@@ -297,11 +290,16 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir' source = do
297290 ("TEXMFOUTPUT", tmpDir) :
298291 [(k,v) | (k,v) <- env'
299292 , k /= "TEXINPUTS" && k /= "TEXMFOUTPUT"]
300− when (runNumber == 1 && verbosity >= INFO) $
293+ when (runNumber == 1 && verbosity >= INFO) $ liftIO $
301294 UTF8.readFile file >>=
302295 showVerboseInfo (Just tmpDir) program programArgs env''
303− (exit, out) <- pipeProcess (Just env'') program programArgs BL.empty
304− when (verbosity >= INFO) $ do
296+ (exit, out) <- liftIO $ E.catch
297+ (pipeProcess (Just env'') program programArgs BL.empty)
298+ (\(e :: IOError) -> if isDoesNotExistError e
299+ then E.throwIO $ PandocPDFProgramNotFoundError
300+ program
301+ else E.throwIO e)
302+ when (verbosity >= INFO) $ liftIO $ do
305303 putStrLn $ "[makePDF] Run #" ++ show runNumber
306304 BL.hPutStr stdout out
307305 putStr "\n"
@@ -309,19 +307,20 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir' source = do
309307 then runTeXProgram verbosity program args (runNumber + 1) numRuns tmpDir source
310308 else do
311309 let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir
312− pdfExists <- doesFileExist pdfFile
310+ pdfExists <- liftIO $ doesFileExist pdfFile
313311 pdf <- if pdfExists
314312 -- We read PDF as a strict bytestring to make sure that the
315313 -- temp directory is removed on Windows.
316314 -- See https://github.com/jgm/pandoc/issues/1192.
317− then (Just . BL.fromChunks . (:[])) `fmap` BS.readFile pdfFile
315+ then (Just . BL.fromChunks . (:[])) `fmap`
316+ liftIO (BS.readFile pdfFile)
318317 else return Nothing
319318 -- Note that some things like Missing character warnings
320319 -- appear in the log but not on stderr, so we prefer the log:
321320 let logFile = replaceExtension file ".log"
322− logExists <- doesFileExist logFile
321+ logExists <- liftIO $ doesFileExist logFile
323322 log' <- if logExists
324− then BL.readFile logFile
323+ then liftIO $ BL.readFile logFile
325324 else return out
326325 return (exit, log', pdf)
327326
@@ -394,38 +393,39 @@ context2pdf :: Verbosity -- ^ Verbosity level
394393 -> [String] -- ^ extra arguments
395394 -> FilePath -- ^ temp directory for output
396395 -> Text -- ^ ConTeXt source
397− -> IO (Either ByteString ByteString)
398−context2pdf verbosity program pdfargs tmpDir source = inDirectory tmpDir $ do
399− let file = "input.tex"
400− BS.writeFile file $ UTF8.fromText source
401− let programArgs = "--batchmode" : pdfargs ++ [file]
402− env' <- getEnvironment
403− when (verbosity >= INFO) $
404− UTF8.readFile file >>=
405− showVerboseInfo (Just tmpDir) program programArgs env'
406− (exit, out) <- E.catch
407− (pipeProcess (Just env') program programArgs BL.empty)
408− (\(e :: IOError) -> if isDoesNotExistError e
409− then E.throwIO $
410− PandocPDFProgramNotFoundError "context"
411− else E.throwIO e)
412− when (verbosity >= INFO) $ do
413− BL.hPutStr stdout out
414− putStr "\n"
415− let pdfFile = replaceExtension file ".pdf"
416− pdfExists <- doesFileExist pdfFile
417− mbPdf <- if pdfExists
418− -- We read PDF as a strict bytestring to make sure that the
419− -- temp directory is removed on Windows.
420− -- See https://github.com/jgm/pandoc/issues/1192.
421− then (Just . BL.fromChunks . (:[])) `fmap` BS.readFile pdfFile
422− else return Nothing
423− case (exit, mbPdf) of
424− (ExitFailure _, _) -> do
425− let logmsg = extractConTeXtMsg out
426− return $ Left logmsg
427− (ExitSuccess, Nothing) -> return $ Left ""
428− (ExitSuccess, Just pdf) -> return $ Right pdf
396+ -> PandocIO (Either ByteString ByteString)
397+context2pdf verbosity program pdfargs tmpDir source =
398+ liftIO $ inDirectory tmpDir $ do
399+ let file = "input.tex"
400+ BS.writeFile file $ UTF8.fromText source
401+ let programArgs = "--batchmode" : pdfargs ++ [file]
402+ env' <- getEnvironment
403+ when (verbosity >= INFO) $
404+ UTF8.readFile file >>=
405+ showVerboseInfo (Just tmpDir) program programArgs env'
406+ (exit, out) <- E.catch
407+ (pipeProcess (Just env') program programArgs BL.empty)
408+ (\(e :: IOError) -> if isDoesNotExistError e
409+ then E.throwIO $
410+ PandocPDFProgramNotFoundError "context"
411+ else E.throwIO e)
412+ when (verbosity >= INFO) $ do
413+ BL.hPutStr stdout out
414+ putStr "\n"
415+ let pdfFile = replaceExtension file ".pdf"
416+ pdfExists <- doesFileExist pdfFile
417+ mbPdf <- if pdfExists
418+ -- We read PDF as a strict bytestring to make sure that the
419+ -- temp directory is removed on Windows.
420+ -- See https://github.com/jgm/pandoc/issues/1192.
421+ then (Just . BL.fromChunks . (:[])) `fmap` BS.readFile pdfFile
422+ else return Nothing
423+ case (exit, mbPdf) of
424+ (ExitFailure _, _) -> do
425+ let logmsg = extractConTeXtMsg out
426+ return $ Left logmsg
427+ (ExitSuccess, Nothing) -> return $ Left ""
428+ (ExitSuccess, Just pdf) -> return $ Right pdf
429429
430430
431431showVerboseInfo :: Maybe FilePath