@@ -45,26 +45,23 @@ import qualified Data.ByteString.Lazy.Char8 as BC
45import Data.Maybe (fromMaybe)
45import Data.Maybe (fromMaybe)
46import Data.Text (Text)
46import Data.Text (Text)
47import qualified Data.Text as T
47import qualified Data.Text as T
48−import qualified Data.Text.IO as TextIO
49import System.Directory
48import System.Directory
50import System.Environment
49import System.Environment
51import System.Exit (ExitCode (..))
50import System.Exit (ExitCode (..))
52import System.FilePath
51import System.FilePath
53import System.IO (stdout)
52import System.IO (stdout)
54−import System.IO.Temp (withTempDirectory)
53+import System.IO.Temp (withTempDirectory, withTempFile)
55#if MIN_VERSION_base(4,8,3)
54#if MIN_VERSION_base(4,8,3)
56import System.IO.Error (IOError, isDoesNotExistError)
55import System.IO.Error (IOError, isDoesNotExistError)
58import System.IO.Error (isDoesNotExistError)
57import System.IO.Error (isDoesNotExistError)
60−import Text.HTML.TagSoup
61−import Text.HTML.TagSoup.Match
62import Text.Pandoc.Definition
59import Text.Pandoc.Definition
63import Text.Pandoc.Error (PandocError (PandocPDFProgramNotFoundError))
60import Text.Pandoc.Error (PandocError (PandocPDFProgramNotFoundError))
64import Text.Pandoc.MIME (getMimeType)
61import Text.Pandoc.MIME (getMimeType)
65import Text.Pandoc.Options (HTMLMathMethod (..), WriterOptions (..))
62import Text.Pandoc.Options (HTMLMathMethod (..), WriterOptions (..))
66import Text.Pandoc.Process (pipeProcess)
63import Text.Pandoc.Process (pipeProcess)
67−import Text.Pandoc.Shared (inDirectory, stringify, withTempDir)
64+import Text.Pandoc.Shared (inDirectory, stringify)
68import qualified Text.Pandoc.UTF8 as UTF8
65import qualified Text.Pandoc.UTF8 as UTF8
69import Text.Pandoc.Walk (walkM)
66import Text.Pandoc.Walk (walkM)
70import Text.Pandoc.Writers.Shared (getField, metaToJSON)
67import Text.Pandoc.Writers.Shared (getField, metaToJSON)
@@ -365,51 +362,50 @@ html2pdf :: Verbosity -- ^ Verbosity level
365 -> [String] -- ^ Args to program
362 -> [String] -- ^ Args to program
366 -> Text -- ^ HTML5 source
363 -> Text -- ^ HTML5 source
367 -> IO (Either ByteString ByteString)
364 -> IO (Either ByteString ByteString)
368−html2pdf verbosity program args htmlSource = do
365+html2pdf verbosity program args source = do
369− cwd <- getCurrentDirectory
366+ -- write HTML to temp file so we don't have to rewrite
370− let tags = parseTags htmlSource
367+ -- all links in `a`, `img`, `style`, `script`, etc. tags,
371− (hd, tl) = break (tagClose (== "head")) tags
368+ -- and piping to weasyprint didn't work on Windows either.
372− baseTag = TagOpen "base"
369+ file <- withTempFile "." "html2pdf.html" $ \fp _ -> return fp
373− [("href", T.pack cwd <> T.singleton pathSeparator)] : [TagText "\n"]
370+ pdfFile <- withTempFile "." "html2pdf.pdf" $ \fp _ -> return fp
374− source = renderTags $ hd ++ baseTag ++ tl
371+ BS.writeFile file $ UTF8.fromText source
375− withTempDir "html2pdf.pdf" $ \tmpdir -> do
376− let pdfFile = tmpdir </> "out.pdf"
377− let pdfFileArgName = ["-o" | program == "prince"]
372+ let pdfFileArgName = ["-o" | program == "prince"]
378− let programArgs = args ++ ["-"] ++ pdfFileArgName ++ [pdfFile]
373+ let programArgs = args ++ [file] ++ pdfFileArgName ++ [pdfFile]
379− env' <- getEnvironment
374+ env' <- getEnvironment
380− when (verbosity >= INFO) $ do
375+ when (verbosity >= INFO) $ do
381− putStrLn "[makePDF] Command line:"
376+ putStrLn "[makePDF] Command line:"
382− putStrLn $ program ++ " " ++ unwords (map show programArgs)
377+ putStrLn $ program ++ " " ++ unwords (map show programArgs)
383− putStr "\n"
378+ putStr "\n"
384− putStrLn "[makePDF] Environment:"
379+ putStrLn "[makePDF] Environment:"
385− mapM_ print env'
380+ mapM_ print env'
386− putStr "\n"
381+ putStr "\n"
387− putStrLn "[makePDF] Contents of intermediate HTML:"
382+ putStrLn $ "[makePDF] Contents of " ++ file ++ ":"
388− TextIO.putStr source
383+ BL.readFile file >>= BL.putStr
389− putStr "\n"
384+ putStr "\n"
390− (exit, out) <- E.catch
385+ (exit, out) <- E.catch
391− (pipeProcess (Just env') program programArgs $ BL.fromStrict $ UTF8.fromText source)
386+ (pipeProcess (Just env') program programArgs BL.empty)
392− (\(e :: IOError) -> if isDoesNotExistError e
387+ (\(e :: IOError) -> if isDoesNotExistError e
393− then E.throwIO $
388+ then E.throwIO $
394− PandocPDFProgramNotFoundError program
389+ PandocPDFProgramNotFoundError program
395− else E.throwIO e)
390+ else E.throwIO e)
396− when (verbosity >= INFO) $ do
392+ when (verbosity >= INFO) $ do
397− BL.hPutStr stdout out
393+ BL.hPutStr stdout out
398− putStr "\n"
394+ putStr "\n"
399− pdfExists <- doesFileExist pdfFile
395+ pdfExists <- doesFileExist pdfFile
400− mbPdf <- if pdfExists
396+ mbPdf <- if pdfExists
401− -- We read PDF as a strict bytestring to make sure that the
397+ -- We read PDF as a strict bytestring to make sure that the
402− -- temp directory is removed on Windows.
398+ -- temp directory is removed on Windows.
403− -- See https://github.com/jgm/pandoc/issues/1192.
399+ -- See https://github.com/jgm/pandoc/issues/1192.
405− res <- (Just . BL.fromChunks . (:[])) `fmap` BS.readFile pdfFile
401+ res <- (Just . BL.fromChunks . (:[])) `fmap` BS.readFile pdfFile
406− removeFile pdfFile
402+ removeFile pdfFile
407− return res
403+ return res
408− else return Nothing
404+ else return Nothing
409− return $ case (exit, mbPdf) of
405+ return $ case (exit, mbPdf) of
410− (ExitFailure _, _) -> Left out
406+ (ExitFailure _, _) -> Left out
411− (ExitSuccess, Nothing) -> Left ""
407+ (ExitSuccess, Nothing) -> Left ""
412− (ExitSuccess, Just pdf) -> Right pdf
408+ (ExitSuccess, Just pdf) -> Right pdf
414context2pdf :: Verbosity -- ^ Verbosity level
410context2pdf :: Verbosity -- ^ Verbosity level
415 -> FilePath -- ^ temp directory for output
411 -> FilePath -- ^ temp directory for output