git.iko.soy/typeable/pandoc
on master help sign in
PDF generation improvements.

* `Text.Pandoc.PDF` exports `makePDF` instead of `tex2pdf`. (API change.) * `makePDF` walks the pandoc AST and checks for the existence of images in the local directory. If they are not found, it attempts to find them, either in the directory containing the first source file, or at an absolute URL, or at a URL relative to the base URL of the first command line argument. * Closes #917.

commit7102254e244b37c91d6b35b4940511a8656edc49 authorJohn MacFarlane <fiddlosopher@gmail.com> dateSat 20 Jul 2013, 12:14 (13 years ago) parent93877e5
3 files changed+56−9
pandoc.hs+2−2 src/Text/Pandoc/MIME.hs+9−2 src/Text/Pandoc/PDF.hs+45−5
pandoc.hs+2−2
@@ -31,7 +31,7 @@ writers.
3131-}
3232module Main where
3333import Text.Pandoc
34−import Text.Pandoc.PDF (tex2pdf)
34+import Text.Pandoc.PDF (makePDF)
3535import Text.Pandoc.Readers.LaTeX (handleIncludes)
3636import Text.Pandoc.Shared ( tabFilter, readDataFileUTF8, safeRead,
3737 headerShift, normalize, err, warn )
@@ -1113,7 +1113,7 @@ main = do
11131113 Right (IOByteStringWriter f) -> f writerOptions doc0 >>= writeBinary
11141114 Right (PureStringWriter f)
11151115 | pdfOutput -> do
1116− res <- tex2pdf latexEngine $ f writerOptions doc0
1116+ res <- makePDF latexEngine f writerOptions doc0
11171117 case res of
11181118 Right pdf -> writeBinary pdf
11191119 Left err' -> err 43 $ UTF8.toStringLazy err'
src/Text/Pandoc/MIME.hs+9−2
@@ -27,7 +27,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2727
2828Mime type lookup for ODT writer.
2929-}
30−module Text.Pandoc.MIME ( getMimeType )
30+module Text.Pandoc.MIME ( getMimeType, extensionFromMimeType )
3131where
3232import System.FilePath
3333import Data.Char ( toLower )
@@ -37,7 +37,14 @@ import qualified Data.Map as M
3737getMimeType :: FilePath -> Maybe String
3838getMimeType "layout-cache" = Just "application/binary" -- in ODT
3939getMimeType f = M.lookup (map toLower $ drop 1 $ takeExtension f) mimeTypes
40− where mimeTypes = M.fromList -- List borrowed from happstack-server.
40+ where mimeTypes = M.fromList mimeTypesList
41+
42+extensionFromMimeType :: String -> Maybe String
43+extensionFromMimeType mimetype = M.lookup mimetype reverseMimeTypes
44+ where reverseMimeTypes = M.fromList $ map (\(k,v) -> (v,k)) mimeTypesList
45+
46+mimeTypesList :: [(String, String)]
47+mimeTypesList = -- List borrowed from happstack-server.
4148 [("gz","application/x-gzip")
4249 ,("cabal","application/x-cabal")
4350 ,("%","application/x-trash")
src/Text/Pandoc/PDF.hs+45−5
@@ -28,12 +28,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2828
2929Conversion of LaTeX documents to PDF.
3030-}
31−module Text.Pandoc.PDF ( tex2pdf ) where
31+module Text.Pandoc.PDF ( makePDF ) where
3232
3333import System.IO.Temp
3434import Data.ByteString.Lazy (ByteString)
3535import qualified Data.ByteString.Lazy as B
3636import qualified Data.ByteString.Lazy.Char8 as BC
37+import qualified Data.ByteString as BS
3738import System.Exit (ExitCode (..))
3839import System.FilePath
3940import System.Directory
@@ -42,9 +43,15 @@ import System.Environment
4243import Control.Exception (evaluate)
4344import System.IO (hClose)
4445import Control.Concurrent (putMVar, takeMVar, newEmptyMVar, forkIO)
45−import Text.Pandoc.UTF8 as UTF8
4646import Control.Monad (unless)
4747import Data.List (isInfixOf)
48+import qualified Data.ByteString.Base64 as B64
49+import qualified Text.Pandoc.UTF8 as UTF8
50+import Text.Pandoc.Definition
51+import Text.Pandoc.Generic (bottomUpM)
52+import Text.Pandoc.Shared (fetchItem, warn)
53+import Text.Pandoc.Options (WriterOptions(..))
54+import Text.Pandoc.MIME (extensionFromMimeType)
4855
4956withTempDir :: String -> (FilePath -> IO a) -> IO a
5057withTempDir =
@@ -54,12 +61,45 @@ withTempDir =
5461 withSystemTempDirectory
5562#endif
5663
57−tex2pdf :: String -- ^ tex program (pdflatex, lualatex, xelatex)
58− -> String -- ^ latex source
64+makePDF :: String -- ^ pdf creator (pdflatex, lualatex, xelatex)
65+ -> (WriterOptions -> Pandoc -> String) -- ^ writer
66+ -> WriterOptions -- ^ options
67+ -> Pandoc -- ^ document
5968 -> IO (Either ByteString ByteString)
60−tex2pdf program source = withTempDir "tex2pdf." $ \tmpdir ->
69+makePDF program writer opts doc = withTempDir "tex2pdf." $ \tmpdir -> do
70+ doc' <- handleImages (writerSourceDirectory opts) tmpdir doc
71+ let source = writer opts doc'
6172 tex2pdf' tmpdir program source
6273
74+handleImages :: String -- ^ source directory/base URL
75+ -> FilePath -- ^ temp dir to store images
76+ -> Pandoc -- ^ document
77+ -> IO Pandoc
78+handleImages baseURL tmpdir = bottomUpM (handleImage' baseURL tmpdir)
79+
80+handleImage' :: String
81+ -> FilePath
82+ -> Inline
83+ -> IO Inline
84+handleImage' baseURL tmpdir (Image ils (src,tit)) = do
85+ exists <- doesFileExist src
86+ if exists
87+ then return $ Image ils (src,tit)
88+ else do
89+ res <- fetchItem baseURL src
90+ case res of
91+ Right (contents, Just mime) -> do
92+ let ext = maybe (takeExtension src) id $
93+ extensionFromMimeType mime
94+ let basename = UTF8.toString $ B64.encode $ UTF8.fromString src
95+ let fname = tmpdir </> basename <.> ext
96+ BS.writeFile fname contents
97+ return $ Image ils (fname,tit)
98+ _ -> do
99+ warn $ "Could not find image `" ++ src ++ "', skipping..."
100+ return $ Image ils (src,tit)
101+handleImage' _ _ x = return x
102+
63103tex2pdf' :: FilePath -- ^ temp directory for output
64104 -> String -- ^ tex program
65105 -> String -- ^ tex source