From acdbdd7da575f94e6fd326879fd8632edc9dd9cd Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Mon, 6 Feb 2012 12:12:23 -0800 Subject: Text.Pandoc.PDF: Simplified tex2pdf. We no longer try to parse the log file to determine whether latex needs to be rerun. Instead, we run latex twice -- which should be enough for table of contents and hyperrefs. Closes #402. --- src/Text/Pandoc/PDF.hs | 42 ++++++++++++++++-------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'src/Text/Pandoc') diff --git a/src/Text/Pandoc/PDF.hs b/src/Text/Pandoc/PDF.hs index 85689fa9b..4b0dd9207 100644 --- a/src/Text/Pandoc/PDF.hs +++ b/src/Text/Pandoc/PDF.hs @@ -42,6 +42,7 @@ import Control.Exception (evaluate) import System.IO (hClose) import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO) import Text.Pandoc.UTF8 as UTF8 +import Control.Monad (unless) tex2pdf :: String -- ^ tex program (pdflatex, lualatex, xelatex) -> String -- ^ latex source @@ -54,7 +55,8 @@ tex2pdf' :: FilePath -- ^ temp directory for output -> String -- ^ tex source -> IO (Either ByteString ByteString) tex2pdf' tmpDir program source = do - (exit, log', mbPdf) <- runTeXProgram program 3 tmpDir source + let numruns = 2 -- should suffice for toc and hyperrefs + (exit, log', mbPdf) <- runTeXProgram program numruns tmpDir source let msg = "Error producing PDF from TeX source." case (exit, mbPdf) of (ExitFailure _, _) -> return $ Left $ @@ -76,41 +78,29 @@ extractMsg log' = do then log' else BC.unlines (msg'' ++ lineno) -parseLine :: ByteString -> Bool -parseLine ln = - if "LaTeX Warning:" `BC.isPrefixOf` ln - then if "Rerun" `elem` ws - then True - else False - else False - where ws = BC.words ln - -hasUndefinedRefs :: ByteString -> Bool -hasUndefinedRefs = or . map parseLine . BC.lines - -- running tex programs -- Run a TeX program on an input bytestring and return (exit code, -- contents of stdout, contents of produced PDF if any). Rerun --- latex as needed to resolve references, but don't run bibtex/biber. +-- a fixed number of times to resolve references. runTeXProgram :: String -> Int -> FilePath -> String -> IO (ExitCode, ByteString, Maybe ByteString) runTeXProgram program runsLeft tmpDir source = do - withTempFile tmpDir "tex2pdf" $ \file h -> do - UTF8.hPutStr h source - hClose h + let file = tmpDir "input.tex" + exists <- doesFileExist file + unless exists $ UTF8.writeFile file source let programArgs = ["-halt-on-error", "-interaction", "nonstopmode", "-output-directory", tmpDir, file] (exit, out, err) <- readCommand program programArgs - removeFile file - let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir - pdfExists <- doesFileExist pdfFile - pdf <- if pdfExists - then Just `fmap` B.readFile pdfFile - else return Nothing - if hasUndefinedRefs out && runsLeft > 0 + if runsLeft > 1 then runTeXProgram program (runsLeft - 1) tmpDir source - else return (exit, out <> err, pdf) + else do + let pdfFile = replaceDirectory (replaceExtension file ".pdf") tmpDir + pdfExists <- doesFileExist pdfFile + pdf <- if pdfExists + then Just `fmap` B.readFile pdfFile + else return Nothing + return (exit, out <> err, pdf) -- utility functions @@ -140,4 +130,4 @@ readCommand cmd args = do hClose outh -- wait on the process ex <- waitForProcess pid - return (ex, out, err) \ No newline at end of file + return (ex, out, err) -- cgit v1.2.3