@@ -69,6 +69,7 @@ import Text.Pandoc.Writers.Shared (getField, metaToJSON)
6969#ifdef _WINDOWS
7070import Data.List (intercalate)
7171#endif
72+import Data.List (isPrefixOf)
7273import Text.Pandoc.Class (PandocIO, extractMedia, fillMediaBag, getCommonState,
7374 getVerbosity, putCommonState, report, runIO,
7475 runIOorExplode, setVerbosity)
@@ -99,7 +100,7 @@ makePDF program pdfargs writer opts doc = do
99100 let args = ["-ms", "-mpdfmark", "-e", "-t", "-k", "-KUTF-8", "-i",
100101 "--no-toc-relocation"] ++ pdfargs
101102 verbosity <- getVerbosity
102− liftIO $ ms2pdf verbosity program args source
103+ liftIO $ generic2pdf verbosity program args source
103104 baseProg -> do
104105 commonState <- getCommonState
105106 verbosity <- getVerbosity
@@ -111,14 +112,20 @@ makePDF program pdfargs writer opts doc = do
111112 if '~' `elem` tmp
112113 then withTempDirectory "." templ action
113114 else withSystemTempDirectory templ action
114− liftIO $ withTempDir "tex2pdf." $ \tmpdir -> do
115+ liftIO $ withTempDir "tex2pdf." $ \tmpdir' -> do
116+#ifdef _WINDOWS
117+ -- note: we want / even on Windows, for TexLive
118+ let tmpdir = changePathSeparators tmpdir'
119+#else
120+ let tmpdir = tmpdir'
121+#endif
115122 source <- runIOorExplode $ do
116123 putCommonState commonState
117124 doc' <- handleImages tmpdir doc
118125 writer opts doc'
119126 case baseProg of
120− "context" -> context2pdf verbosity program tmpdir source
121− prog | prog `elem` ["pdflatex", "lualatex", "xelatex"]
127+ "context" -> context2pdf verbosity program pdfargs tmpdir source
128+ prog | prog `elem` ["pdflatex", "lualatex", "xelatex", "latexmk"]
122129 -> tex2pdf verbosity program pdfargs tmpdir source
123130 _ -> return $ Left $ UTF8.fromStringLazy $ "Unknown program " ++ program
124131
@@ -213,7 +220,10 @@ tex2pdf :: Verbosity -- ^ Verbosity level
213220 -> Text -- ^ tex source
214221 -> IO (Either ByteString ByteString)
215222tex2pdf verbosity program args tmpDir source = do
216− let numruns = if "\\tableofcontents" `T.isInfixOf` source
223+ let numruns =
224+ if takeBaseName program == "latexmk"
225+ then 1
226+ else if "\\tableofcontents" `T.isInfixOf` source
217227 then 3 -- to get page numbers
218228 else 2 -- 1 run won't give you PDF bookmarks
219229 (exit, log', mbPdf) <- E.catch
@@ -276,40 +286,32 @@ extractConTeXtMsg log' = do
276286-- a fixed number of times to resolve references.
277287runTeXProgram :: Verbosity -> String -> [String] -> Int -> Int -> FilePath
278288 -> Text -> IO (ExitCode, ByteString, Maybe ByteString)
279−runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
289+runTeXProgram verbosity program args runNumber numRuns tmpDir' source = do
290+ let tmpDir =
291+ case [x | x <- args, "-outdir=" `isPrefixOf` x] of
292+ [x] -> drop 8 x
293+ _ -> tmpDir'
294+ createDirectoryIfMissing True tmpDir
280295 let file = tmpDir </> "input.tex"
281296 exists <- doesFileExist file
282297 unless exists $ BS.writeFile file $ UTF8.fromText source
283−#ifdef _WINDOWS
284− -- note: we want / even on Windows, for TexLive
285− let tmpDir' = changePathSeparators tmpDir
286− let file' = changePathSeparators file
287−#else
288− let tmpDir' = tmpDir
289− let file' = file
290−#endif
291− let programArgs = ["-halt-on-error", "-interaction", "nonstopmode",
292− "-output-directory", tmpDir'] ++ args ++ [file']
298+ let programArgs =
299+ if takeBaseName program == "latexmk"
300+ then ["-interaction=batchmode", "-halt-on-error", "-pdf",
301+ "-quiet", "-outdir=" ++ tmpDir] ++ args ++ [file]
302+ else ["-halt-on-error", "-interaction", "nonstopmode",
303+ "-output-directory", tmpDir] ++ args ++ [file]
293304 env' <- getEnvironment
294305 let sep = [searchPathSeparator]
295− let texinputs = maybe (tmpDir' ++ sep) ((tmpDir' ++ sep) ++)
306+ let texinputs = maybe (tmpDir ++ sep) ((tmpDir ++ sep) ++)
296307 $ lookup "TEXINPUTS" env'
297308 let env'' = ("TEXINPUTS", texinputs) :
298− ("TEXMFOUTPUT", tmpDir') :
309+ ("TEXMFOUTPUT", tmpDir) :
299310 [(k,v) | (k,v) <- env'
300311 , k /= "TEXINPUTS" && k /= "TEXMFOUTPUT"]
301− when (verbosity >= INFO && runNumber == 1) $ do
302− putStrLn "[makePDF] temp dir:"
303− putStrLn tmpDir'
304− putStrLn "[makePDF] Command line:"
305− putStrLn $ program ++ " " ++ unwords (map show programArgs)
306− putStr "\n"
307− putStrLn "[makePDF] Environment:"
308− mapM_ print env''
309− putStr "\n"
310− putStrLn $ "[makePDF] Contents of " ++ file' ++ ":"
311− BL.readFile file' >>= BL.putStr
312− putStr "\n"
312+ when (runNumber == 1 && verbosity >= INFO) $
313+ UTF8.readFile file >>=
314+ showVerboseInfo (Just tmpDir) program programArgs env''
313315 (exit, out) <- pipeProcess (Just env'') program programArgs BL.empty
314316 when (verbosity >= INFO) $ do
315317 putStrLn $ "[makePDF] Run #" ++ show runNumber
@@ -335,23 +337,15 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
335337 else return out
336338 return (exit, log', pdf)
337339
338−ms2pdf :: Verbosity
339− -> String
340− -> [String]
341− -> Text
342− -> IO (Either ByteString ByteString)
343−ms2pdf verbosity program args source = do
340+generic2pdf :: Verbosity
341+ -> String
342+ -> [String]
343+ -> Text
344+ -> IO (Either ByteString ByteString)
345+generic2pdf verbosity program args source = do
344346 env' <- getEnvironment
345− when (verbosity >= INFO) $ do
346− putStrLn "[makePDF] Command line:"
347− putStrLn $ program ++ " " ++ unwords (map show args)
348− putStr "\n"
349− putStrLn "[makePDF] Environment:"
350− mapM_ print env'
351− putStr "\n"
352− putStrLn "[makePDF] Contents:\n"
353− putStr $ T.unpack source
354− putStr "\n"
347+ when (verbosity >= INFO) $
348+ showVerboseInfo Nothing program args env' (T.unpack source)
355349 (exit, out) <- E.catch
356350 (pipeProcess (Just env') program args
357351 (BL.fromStrict $ UTF8.fromText source))
@@ -359,13 +353,11 @@ ms2pdf verbosity program args source = do
359353 then E.throwIO $
360354 PandocPDFProgramNotFoundError program
361355 else E.throwIO e)
362− when (verbosity >= INFO) $ do
363− BL.hPutStr stdout out
364− putStr "\n"
365356 return $ case exit of
366357 ExitFailure _ -> Left out
367358 ExitSuccess -> Right out
368359
360+
369361html2pdf :: Verbosity -- ^ Verbosity level
370362 -> String -- ^ Program (wkhtmltopdf, weasyprint, prince, or path)
371363 -> [String] -- ^ Args to program
@@ -381,16 +373,9 @@ html2pdf verbosity program args source = do
381373 let pdfFileArgName = ["-o" | takeBaseName program == "prince"]
382374 let programArgs = args ++ [file] ++ pdfFileArgName ++ [pdfFile]
383375 env' <- getEnvironment
384− when (verbosity >= INFO) $ do
385− putStrLn "[makePDF] Command line:"
386− putStrLn $ program ++ " " ++ unwords (map show programArgs)
387− putStr "\n"
388− putStrLn "[makePDF] Environment:"
389− mapM_ print env'
390− putStr "\n"
391− putStrLn $ "[makePDF] Contents of " ++ file ++ ":"
392− BL.readFile file >>= BL.putStr
393− putStr "\n"
376+ when (verbosity >= INFO) $
377+ UTF8.readFile file >>=
378+ showVerboseInfo Nothing program programArgs env'
394379 (exit, out) <- E.catch
395380 (pipeProcess (Just env') program programArgs BL.empty)
396381 (\(e :: IOError) -> if isDoesNotExistError e
@@ -418,32 +403,18 @@ html2pdf verbosity program args source = do
418403
419404context2pdf :: Verbosity -- ^ Verbosity level
420405 -> String -- ^ "context" or path to it
406+ -> [String] -- ^ extra arguments
421407 -> FilePath -- ^ temp directory for output
422408 -> Text -- ^ ConTeXt source
423409 -> IO (Either ByteString ByteString)
424−context2pdf verbosity program tmpDir source = inDirectory tmpDir $ do
410+context2pdf verbosity program pdfargs tmpDir source = inDirectory tmpDir $ do
425411 let file = "input.tex"
426412 BS.writeFile file $ UTF8.fromText source
427−#ifdef _WINDOWS
428− -- note: we want / even on Windows, for TexLive
429− let tmpDir' = changePathSeparators tmpDir
430−#else
431− let tmpDir' = tmpDir
432−#endif
433− let programArgs = "--batchmode" : [file]
413+ let programArgs = "--batchmode" : pdfargs ++ [file]
434414 env' <- getEnvironment
435− when (verbosity >= INFO) $ do
436− putStrLn "[makePDF] temp dir:"
437− putStrLn tmpDir'
438− putStrLn "[makePDF] Command line:"
439− putStrLn $ program ++ " " ++ unwords (map show programArgs)
440− putStr "\n"
441− putStrLn "[makePDF] Environment:"
442− mapM_ print env'
443− putStr "\n"
444− putStrLn $ "[makePDF] Contents of " ++ file ++ ":"
445− BL.readFile file >>= BL.putStr
446− putStr "\n"
415+ when (verbosity >= INFO) $
416+ UTF8.readFile file >>=
417+ showVerboseInfo (Just tmpDir) program programArgs env'
447418 (exit, out) <- E.catch
448419 (pipeProcess (Just env') program programArgs BL.empty)
449420 (\(e :: IOError) -> if isDoesNotExistError e
@@ -467,3 +438,25 @@ context2pdf verbosity program tmpDir source = inDirectory tmpDir $ do
467438 return $ Left logmsg
468439 (ExitSuccess, Nothing) -> return $ Left ""
469440 (ExitSuccess, Just pdf) -> return $ Right pdf
441+
442+
443+showVerboseInfo :: Maybe FilePath
444+ -> String
445+ -> [String]
446+ -> [(String, String)]
447+ -> String
448+ -> IO ()
449+showVerboseInfo mbTmpDir program programArgs env source = do
450+ case mbTmpDir of
451+ Just tmpDir -> do
452+ putStrLn "[makePDF] temp dir:"
453+ putStrLn tmpDir
454+ Nothing -> return ()
455+ putStrLn "[makePDF] Command line:"
456+ putStrLn $ program ++ " " ++ unwords (map show programArgs)
457+ putStr "\n"
458+ putStrLn "[makePDF] Environment:"
459+ mapM_ print env
460+ putStr "\n"
461+ putStrLn $ "[makePDF] Source:"
462+ putStrLn source