{-# LANGUAGE DeriveAnyClass #-}
--------------------------------------------------------------------------------
-- |
-- Module      :  Ipe.IpeRender
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- Use 'iperender' to generate png, pdf, or svg files.
--
-- Note that all functions in this module require that 'iperender' is
-- installed (it is bundled with ipe) and available on the path.

--------------------------------------------------------------------------------
module Ipe.IpeRender where

import           System.OsPath
import qualified System.Process.Typed as Process
import           Data.Finitary
import           GHC.Generics (Generic)

--------------------------------------------------------------------------------

-- | Call 'iperender' to produce an image of the specified type.
--
-- note that pdf files produces with iperender cannot be opened with ipe.
ipeRenderWith                          :: Options -- ^ the options to use
                                       -> FileType -- ^ output file type
                                       -> OsPath -- ^ input file path
                                       -> OsPath -- ^ output file path
                                       -> IO ()
ipeRenderWith :: Options -> FileType -> OsPath -> OsPath -> IO ()
ipeRenderWith Options
options FileType
fType OsPath
inFp OsPath
outFp =
    do
      inFp'  <- OsPath -> IO String
decodeFS OsPath
inFp
      outFp' <- decodeFS outFp
      Process.withProcessWait (Process.proc "iperender" $ args inFp' outFp') $ \Process () () ()
_iperenderProc ->
        () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  where
    args :: String -> String -> [String]
args String
inFp' String
outFp' =
           [ String
"-" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> FileType -> String
forall a. Show a => a -> String
show FileType
fType
           , String
"-page", Int -> String
forall a. Show a => a -> String
show (Options -> Int
pageNumber Options
options)
           , String
"-view", Int -> String
forall a. Show a => a -> String
show (Options -> Int
viewNumber Options
options)
           , String
"-resolution", Int -> String
forall a. Show a => a -> String
show (Options -> Int
resolution Options
options)
           ] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<>
           [ String
"-transparent" | Background
TransparentBackground Background -> Background -> Bool
forall a. Eq a => a -> a -> Bool
== Options -> Background
transparent Options
options ] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<>
           [ String
"-nocrop"      | Crop
NoCrop Crop -> Crop -> Bool
forall a. Eq a => a -> a -> Bool
== Options -> Crop
crop Options
options ] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<>
           [ String
inFp'
           , String
outFp'
           ]

-- | Call 'iperender' with the default options.
--
-- note that pdf files produces with iperender cannot be opened with ipe.
ipeRender :: FileType -> OsPath -> OsPath -> IO ()
ipeRender :: FileType -> OsPath -> OsPath -> IO ()
ipeRender = Options -> FileType -> OsPath -> OsPath -> IO ()
ipeRenderWith Options
defaultOptions

--------------------------------------------------------------------------------

-- | Output filetypes supported by iperender
data FileType = PNG | EPS | PDF | SVG
  deriving (FileType -> FileType -> Bool
(FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool) -> Eq FileType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: FileType -> FileType -> Bool
== :: FileType -> FileType -> Bool
$c/= :: FileType -> FileType -> Bool
/= :: FileType -> FileType -> Bool
Eq,Eq FileType
Eq FileType =>
(FileType -> FileType -> Ordering)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> Bool)
-> (FileType -> FileType -> FileType)
-> (FileType -> FileType -> FileType)
-> Ord FileType
FileType -> FileType -> Bool
FileType -> FileType -> Ordering
FileType -> FileType -> FileType
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: FileType -> FileType -> Ordering
compare :: FileType -> FileType -> Ordering
$c< :: FileType -> FileType -> Bool
< :: FileType -> FileType -> Bool
$c<= :: FileType -> FileType -> Bool
<= :: FileType -> FileType -> Bool
$c> :: FileType -> FileType -> Bool
> :: FileType -> FileType -> Bool
$c>= :: FileType -> FileType -> Bool
>= :: FileType -> FileType -> Bool
$cmax :: FileType -> FileType -> FileType
max :: FileType -> FileType -> FileType
$cmin :: FileType -> FileType -> FileType
min :: FileType -> FileType -> FileType
Ord,(forall x. FileType -> Rep FileType x)
-> (forall x. Rep FileType x -> FileType) -> Generic FileType
forall x. Rep FileType x -> FileType
forall x. FileType -> Rep FileType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. FileType -> Rep FileType x
from :: forall x. FileType -> Rep FileType x
$cto :: forall x. Rep FileType x -> FileType
to :: forall x. Rep FileType x -> FileType
Generic)
  deriving anyclass (Eq FileType
KnownNat (Cardinality FileType)
(Eq FileType, KnownNat (Cardinality FileType)) =>
(Finite (Cardinality FileType) -> FileType)
-> (FileType -> Finite (Cardinality FileType))
-> ((1 <= Cardinality FileType) => FileType)
-> ((1 <= Cardinality FileType) => FileType)
-> (FileType -> Maybe FileType)
-> (FileType -> Maybe FileType)
-> Finitary FileType
(1 <= Cardinality FileType) => FileType
Finite (Cardinality FileType) -> FileType
FileType -> Maybe FileType
FileType -> Finite (Cardinality FileType)
forall a.
(Eq a, KnownNat (Cardinality a)) =>
(Finite (Cardinality a) -> a)
-> (a -> Finite (Cardinality a))
-> ((1 <= Cardinality a) => a)
-> ((1 <= Cardinality a) => a)
-> (a -> Maybe a)
-> (a -> Maybe a)
-> Finitary a
$cfromFinite :: Finite (Cardinality FileType) -> FileType
fromFinite :: Finite (Cardinality FileType) -> FileType
$ctoFinite :: FileType -> Finite (Cardinality FileType)
toFinite :: FileType -> Finite (Cardinality FileType)
$cstart :: (1 <= Cardinality FileType) => FileType
start :: (1 <= Cardinality FileType) => FileType
$cend :: (1 <= Cardinality FileType) => FileType
end :: (1 <= Cardinality FileType) => FileType
$cprevious :: FileType -> Maybe FileType
previous :: FileType -> Maybe FileType
$cnext :: FileType -> Maybe FileType
next :: FileType -> Maybe FileType
Finitary)

instance Show FileType where
  show :: FileType -> String
show = \case
    FileType
PNG -> String
"png"
    FileType
EPS -> String
"eps"
    FileType
PDF -> String
"pdf"
    FileType
SVG -> String
"svg"

-- | Options for iperender
data Options = Options { Options -> Int
pageNumber  :: Int
                       , Options -> Int
viewNumber  :: Int
                       , Options -> Int
resolution  :: Int
                       , Options -> Background
transparent :: Background
                       , Options -> Crop
crop        :: Crop
                       } deriving (Int -> Options -> String -> String
[Options] -> String -> String
Options -> String
(Int -> Options -> String -> String)
-> (Options -> String)
-> ([Options] -> String -> String)
-> Show Options
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Options -> String -> String
showsPrec :: Int -> Options -> String -> String
$cshow :: Options -> String
show :: Options -> String
$cshowList :: [Options] -> String -> String
showList :: [Options] -> String -> String
Show,Options -> Options -> Bool
(Options -> Options -> Bool)
-> (Options -> Options -> Bool) -> Eq Options
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Options -> Options -> Bool
== :: Options -> Options -> Bool
$c/= :: Options -> Options -> Bool
/= :: Options -> Options -> Bool
Eq,Eq Options
Eq Options =>
(Options -> Options -> Ordering)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Bool)
-> (Options -> Options -> Options)
-> (Options -> Options -> Options)
-> Ord Options
Options -> Options -> Bool
Options -> Options -> Ordering
Options -> Options -> Options
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Options -> Options -> Ordering
compare :: Options -> Options -> Ordering
$c< :: Options -> Options -> Bool
< :: Options -> Options -> Bool
$c<= :: Options -> Options -> Bool
<= :: Options -> Options -> Bool
$c> :: Options -> Options -> Bool
> :: Options -> Options -> Bool
$c>= :: Options -> Options -> Bool
>= :: Options -> Options -> Bool
$cmax :: Options -> Options -> Options
max :: Options -> Options -> Options
$cmin :: Options -> Options -> Options
min :: Options -> Options -> Options
Ord)

-- | The default options in Ipe
defaultOptions :: Options
defaultOptions :: Options
defaultOptions = Int -> Int -> Int -> Background -> Crop -> Options
Options Int
1 Int
1 Int
72 Background
TransparentBackground Crop
Crop

-- | Whether or not to render a transparent background in output png
-- images.
data Background = OpaqueBackground | TransparentBackground
  deriving (Int -> Background -> String -> String
[Background] -> String -> String
Background -> String
(Int -> Background -> String -> String)
-> (Background -> String)
-> ([Background] -> String -> String)
-> Show Background
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Background -> String -> String
showsPrec :: Int -> Background -> String -> String
$cshow :: Background -> String
show :: Background -> String
$cshowList :: [Background] -> String -> String
showList :: [Background] -> String -> String
Show,ReadPrec [Background]
ReadPrec Background
Int -> ReadS Background
ReadS [Background]
(Int -> ReadS Background)
-> ReadS [Background]
-> ReadPrec Background
-> ReadPrec [Background]
-> Read Background
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Background
readsPrec :: Int -> ReadS Background
$creadList :: ReadS [Background]
readList :: ReadS [Background]
$creadPrec :: ReadPrec Background
readPrec :: ReadPrec Background
$creadListPrec :: ReadPrec [Background]
readListPrec :: ReadPrec [Background]
Read,Background -> Background -> Bool
(Background -> Background -> Bool)
-> (Background -> Background -> Bool) -> Eq Background
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Background -> Background -> Bool
== :: Background -> Background -> Bool
$c/= :: Background -> Background -> Bool
/= :: Background -> Background -> Bool
Eq,Eq Background
Eq Background =>
(Background -> Background -> Ordering)
-> (Background -> Background -> Bool)
-> (Background -> Background -> Bool)
-> (Background -> Background -> Bool)
-> (Background -> Background -> Bool)
-> (Background -> Background -> Background)
-> (Background -> Background -> Background)
-> Ord Background
Background -> Background -> Bool
Background -> Background -> Ordering
Background -> Background -> Background
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Background -> Background -> Ordering
compare :: Background -> Background -> Ordering
$c< :: Background -> Background -> Bool
< :: Background -> Background -> Bool
$c<= :: Background -> Background -> Bool
<= :: Background -> Background -> Bool
$c> :: Background -> Background -> Bool
> :: Background -> Background -> Bool
$c>= :: Background -> Background -> Bool
>= :: Background -> Background -> Bool
$cmax :: Background -> Background -> Background
max :: Background -> Background -> Background
$cmin :: Background -> Background -> Background
min :: Background -> Background -> Background
Ord,(forall x. Background -> Rep Background x)
-> (forall x. Rep Background x -> Background) -> Generic Background
forall x. Rep Background x -> Background
forall x. Background -> Rep Background x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Background -> Rep Background x
from :: forall x. Background -> Rep Background x
$cto :: forall x. Rep Background x -> Background
to :: forall x. Rep Background x -> Background
Generic)
  deriving anyclass (Eq Background
KnownNat (Cardinality Background)
(Eq Background, KnownNat (Cardinality Background)) =>
(Finite (Cardinality Background) -> Background)
-> (Background -> Finite (Cardinality Background))
-> ((1 <= Cardinality Background) => Background)
-> ((1 <= Cardinality Background) => Background)
-> (Background -> Maybe Background)
-> (Background -> Maybe Background)
-> Finitary Background
(1 <= Cardinality Background) => Background
Finite (Cardinality Background) -> Background
Background -> Maybe Background
Background -> Finite (Cardinality Background)
forall a.
(Eq a, KnownNat (Cardinality a)) =>
(Finite (Cardinality a) -> a)
-> (a -> Finite (Cardinality a))
-> ((1 <= Cardinality a) => a)
-> ((1 <= Cardinality a) => a)
-> (a -> Maybe a)
-> (a -> Maybe a)
-> Finitary a
$cfromFinite :: Finite (Cardinality Background) -> Background
fromFinite :: Finite (Cardinality Background) -> Background
$ctoFinite :: Background -> Finite (Cardinality Background)
toFinite :: Background -> Finite (Cardinality Background)
$cstart :: (1 <= Cardinality Background) => Background
start :: (1 <= Cardinality Background) => Background
$cend :: (1 <= Cardinality Background) => Background
end :: (1 <= Cardinality Background) => Background
$cprevious :: Background -> Maybe Background
previous :: Background -> Maybe Background
$cnext :: Background -> Maybe Background
next :: Background -> Maybe Background
Finitary)

-- | Whether or not to crop the output image.
data Crop = NoCrop | Crop
  deriving (Int -> Crop -> String -> String
[Crop] -> String -> String
Crop -> String
(Int -> Crop -> String -> String)
-> (Crop -> String) -> ([Crop] -> String -> String) -> Show Crop
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: Int -> Crop -> String -> String
showsPrec :: Int -> Crop -> String -> String
$cshow :: Crop -> String
show :: Crop -> String
$cshowList :: [Crop] -> String -> String
showList :: [Crop] -> String -> String
Show,ReadPrec [Crop]
ReadPrec Crop
Int -> ReadS Crop
ReadS [Crop]
(Int -> ReadS Crop)
-> ReadS [Crop] -> ReadPrec Crop -> ReadPrec [Crop] -> Read Crop
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS Crop
readsPrec :: Int -> ReadS Crop
$creadList :: ReadS [Crop]
readList :: ReadS [Crop]
$creadPrec :: ReadPrec Crop
readPrec :: ReadPrec Crop
$creadListPrec :: ReadPrec [Crop]
readListPrec :: ReadPrec [Crop]
Read,Crop -> Crop -> Bool
(Crop -> Crop -> Bool) -> (Crop -> Crop -> Bool) -> Eq Crop
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Crop -> Crop -> Bool
== :: Crop -> Crop -> Bool
$c/= :: Crop -> Crop -> Bool
/= :: Crop -> Crop -> Bool
Eq,Eq Crop
Eq Crop =>
(Crop -> Crop -> Ordering)
-> (Crop -> Crop -> Bool)
-> (Crop -> Crop -> Bool)
-> (Crop -> Crop -> Bool)
-> (Crop -> Crop -> Bool)
-> (Crop -> Crop -> Crop)
-> (Crop -> Crop -> Crop)
-> Ord Crop
Crop -> Crop -> Bool
Crop -> Crop -> Ordering
Crop -> Crop -> Crop
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Crop -> Crop -> Ordering
compare :: Crop -> Crop -> Ordering
$c< :: Crop -> Crop -> Bool
< :: Crop -> Crop -> Bool
$c<= :: Crop -> Crop -> Bool
<= :: Crop -> Crop -> Bool
$c> :: Crop -> Crop -> Bool
> :: Crop -> Crop -> Bool
$c>= :: Crop -> Crop -> Bool
>= :: Crop -> Crop -> Bool
$cmax :: Crop -> Crop -> Crop
max :: Crop -> Crop -> Crop
$cmin :: Crop -> Crop -> Crop
min :: Crop -> Crop -> Crop
Ord,(forall x. Crop -> Rep Crop x)
-> (forall x. Rep Crop x -> Crop) -> Generic Crop
forall x. Rep Crop x -> Crop
forall x. Crop -> Rep Crop x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Crop -> Rep Crop x
from :: forall x. Crop -> Rep Crop x
$cto :: forall x. Rep Crop x -> Crop
to :: forall x. Rep Crop x -> Crop
Generic)
  deriving anyclass (Eq Crop
KnownNat (Cardinality Crop)
(Eq Crop, KnownNat (Cardinality Crop)) =>
(Finite (Cardinality Crop) -> Crop)
-> (Crop -> Finite (Cardinality Crop))
-> ((1 <= Cardinality Crop) => Crop)
-> ((1 <= Cardinality Crop) => Crop)
-> (Crop -> Maybe Crop)
-> (Crop -> Maybe Crop)
-> Finitary Crop
(1 <= Cardinality Crop) => Crop
Finite (Cardinality Crop) -> Crop
Crop -> Maybe Crop
Crop -> Finite (Cardinality Crop)
forall a.
(Eq a, KnownNat (Cardinality a)) =>
(Finite (Cardinality a) -> a)
-> (a -> Finite (Cardinality a))
-> ((1 <= Cardinality a) => a)
-> ((1 <= Cardinality a) => a)
-> (a -> Maybe a)
-> (a -> Maybe a)
-> Finitary a
$cfromFinite :: Finite (Cardinality Crop) -> Crop
fromFinite :: Finite (Cardinality Crop) -> Crop
$ctoFinite :: Crop -> Finite (Cardinality Crop)
toFinite :: Crop -> Finite (Cardinality Crop)
$cstart :: (1 <= Cardinality Crop) => Crop
start :: (1 <= Cardinality Crop) => Crop
$cend :: (1 <= Cardinality Crop) => Crop
end :: (1 <= Cardinality Crop) => Crop
$cprevious :: Crop -> Maybe Crop
previous :: Crop -> Maybe Crop
$cnext :: Crop -> Maybe Crop
next :: Crop -> Maybe Crop
Finitary)