Skip to content

Commit fc2ed1f

Browse files
committed
refactor(createPngFallbacks): introduce PandocMonad.runConversion
This will be needed to run the conversion inside the PandocMonad, where we know the desired image size. [API change] Signed-off-by: Edwin Török <[email protected]>
1 parent 610f6b1 commit fc2ed1f

File tree

7 files changed

+34
-19
lines changed

7 files changed

+34
-19
lines changed

pandoc-lua-engine/src/Text/Pandoc/Lua/PandocLua.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ instance PandocMonad PandocLua where
7070
readFileLazy = IO.readFileLazy
7171
readFileStrict = IO.readFileStrict
7272
readStdinStrict = IO.readStdinStrict
73+
runConversion = IO.runConversion
7374

7475
glob = IO.glob
7576
fileExists = IO.fileExists

src/Text/Pandoc/App.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ readAbbreviations mbfilepath =
372372
>>= fmap (Set.fromList . filter (not . T.null) . T.lines) .
373373
toTextM (fromMaybe mempty mbfilepath)
374374

375-
createPngFallbacks :: (PandocMonad m, MonadIO m) => Int -> m ()
375+
createPngFallbacks :: (PandocMonad m) => Int -> m ()
376376
createPngFallbacks dpi = do
377377
-- create fallback pngs for svgs
378378
items <- mediaItems <$> getMediaBag

src/Text/Pandoc/Class/IO.hs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE CPP #-}
22
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE ScopedTypeVariables #-}
34
{- |
45
Module : Text.Pandoc.Class.IO
56
Copyright : Copyright (C) 2016-2020 Jesse Rosenthal, John MacFarlane
@@ -31,6 +32,7 @@ module Text.Pandoc.Class.IO
3132
, readFileLazy
3233
, readFileStrict
3334
, readStdinStrict
35+
, runConversion
3436
, extractMedia
3537
, writeMedia
3638
) where
@@ -60,7 +62,7 @@ import System.IO.Error
6062
import System.Random (StdGen)
6163
import Text.Pandoc.Class.CommonState (CommonState (..))
6264
import Text.Pandoc.Class.PandocMonad
63-
(PandocMonad, getsCommonState, getMediaBag, report)
65+
(PandocMonad (trace), getsCommonState, getMediaBag, report)
6466
import Text.Pandoc.Definition (Pandoc, Inline (Image))
6567
import Text.Pandoc.Error (PandocError (..))
6668
import Text.Pandoc.Logging (LogMessage (..), messageVerbosity, showLogMessage)
@@ -80,6 +82,9 @@ import qualified System.Environment as Env
8082
import qualified System.FilePath.Glob
8183
import qualified System.Random
8284
import qualified Text.Pandoc.UTF8 as UTF8
85+
import Text.Pandoc.Process (pipeProcess)
86+
import System.Exit (ExitCode(ExitSuccess))
87+
import Text.Pandoc.Shared (tshow)
8388
#ifndef EMBED_DATA_FILES
8489
import qualified Paths_pandoc as Paths
8590
#endif
@@ -170,6 +175,21 @@ readFileStrict s = liftIOError B.readFile s
170175
readStdinStrict :: (PandocMonad m, MonadIO m) => m B.ByteString
171176
readStdinStrict = liftIOError (const B.getContents) "stdin"
172177

178+
-- | Runs an image conversion step, returning an error on failure.
179+
-- Not available when sandboxed.
180+
runConversion :: (PandocMonad m, MonadIO m) => (String, [String], BL.ByteString) -> m (Either T.Text BL.ByteString)
181+
runConversion (cmd, args, bs) = do
182+
trace (T.intercalate " " $ map T.pack $ cmd : args)
183+
liftIO $ E.catch
184+
(do (exit, out) <- pipeProcess Nothing cmd
185+
args
186+
bs
187+
return $ if exit == ExitSuccess
188+
then Right out
189+
else Left "conversion from SVG failed")
190+
(\(e :: E.SomeException) -> return $ Left $
191+
"check that " <> T.pack cmd <> " is in path.\n" <> tshow e)
192+
173193
-- | Return a list of paths that match a glob, relative to the working
174194
-- directory. See 'System.FilePath.Glob' for the glob syntax.
175195
glob :: (PandocMonad m, MonadIO m) => String -> m [FilePath]

src/Text/Pandoc/Class/PandocIO.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ instance PandocMonad PandocIO where
6363
readFileLazy = IO.readFileLazy
6464
readFileStrict = IO.readFileStrict
6565
readStdinStrict = IO.readStdinStrict
66+
runConversion = IO.runConversion
6667

6768
glob = IO.glob
6869
fileExists = IO.fileExists

src/Text/Pandoc/Class/PandocMonad.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
{-# LANGUAGE ScopedTypeVariables #-}
99
{-# LANGUAGE UndecidableInstances #-}
1010
{-# LANGUAGE ViewPatterns #-}
11+
1112
{- |
1213
Module : Text.Pandoc.Class.PandocMonad
1314
Copyright : Copyright (C) 2016-2020 Jesse Rosenthal, John MacFarlane
@@ -116,6 +117,9 @@ class (Functor m, Applicative m, Monad m, MonadError PandocError m)
116117
-- | Read the contents of stdin as a strict ByteString, raising
117118
-- an error on failure.
118119
readStdinStrict :: m B.ByteString
120+
-- | Runs an image conversion step, returning an error on failure.
121+
-- Not called when sandboxed.
122+
runConversion :: (String, [String], BL.ByteString) -> m (Either T.Text BL.ByteString)
119123
-- | Return a list of paths that match a glob, relative to
120124
-- the working directory. See 'System.FilePath.Glob' for
121125
-- the glob syntax.
@@ -505,6 +509,7 @@ instance (MonadTrans t, PandocMonad m, Functor (t m),
505509
readFileLazy = lift . readFileLazy
506510
readFileStrict = lift . readFileStrict
507511
readStdinStrict = lift readStdinStrict
512+
runConversion = lift . runConversion
508513
glob = lift . glob
509514
fileExists = lift . fileExists
510515
getDataFileName = lift . getDataFileName
@@ -523,6 +528,7 @@ instance {-# OVERLAPS #-} PandocMonad m => PandocMonad (ParsecT s st m) where
523528
readFileLazy = lift . readFileLazy
524529
readFileStrict = lift . readFileStrict
525530
readStdinStrict = lift readStdinStrict
531+
runConversion = lift . runConversion
526532
glob = lift . glob
527533
fileExists = lift . fileExists
528534
getDataFileName = lift . getDataFileName

src/Text/Pandoc/Class/PandocPure.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ instance PandocMonad PandocPure where
205205
Nothing -> throwError $ PandocResourceNotFound $ T.pack fp
206206

207207
readStdinStrict = getsPureState stStdin
208+
209+
runConversion _ = return $ Left "Conversion not available in PandocPure"
208210

209211
glob s = do
210212
FileTree ftmap <- getsPureState stFiles

src/Text/Pandoc/Image.hs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,17 @@ Portability : portable
1111
Functions for converting images.
1212
-}
1313
module Text.Pandoc.Image ( svgToPng ) where
14-
import Text.Pandoc.Process (pipeProcess)
1514
import qualified Data.ByteString.Lazy as L
16-
import System.Exit
1715
import Data.Text (Text)
18-
import Text.Pandoc.Shared (tshow)
19-
import qualified Control.Exception as E
20-
import Control.Monad.IO.Class (MonadIO(liftIO))
2116
import Text.Pandoc.Class.PandocMonad
22-
import qualified Data.Text as T
2317

2418
-- | Convert svg image to png. rsvg-convert
2519
-- is used and must be available on the path.
26-
svgToPng :: (PandocMonad m, MonadIO m)
20+
svgToPng :: (PandocMonad m)
2721
=> Int -- ^ DPI
2822
-> L.ByteString -- ^ Input image as bytestring
2923
-> m (Either Text L.ByteString)
3024
svgToPng dpi bs = do
3125
let dpi' = show dpi
3226
let args = ["-f","png","-a","--dpi-x",dpi',"--dpi-y",dpi']
33-
trace (T.intercalate " " $ map T.pack $ "rsvg-convert" : args)
34-
liftIO $ E.catch
35-
(do (exit, out) <- pipeProcess Nothing "rsvg-convert"
36-
args
37-
bs
38-
return $ if exit == ExitSuccess
39-
then Right out
40-
else Left "conversion from SVG failed")
41-
(\(e :: E.SomeException) -> return $ Left $
42-
"check that rsvg-convert is in path.\n" <> tshow e)
27+
runConversion ("rsvg-convert", args, bs)

0 commit comments

Comments
 (0)