{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Text.Pandoc.Filter.Plot.Renderers
( renderer,
preambleSelector,
parseExtraAttrs,
executable,
availableToolkits,
availableToolkitsM,
unavailableToolkits,
unavailableToolkitsM,
supportedSaveFormats,
OutputSpec (..),
Executable (..),
Renderer (..),
)
where
import Control.Concurrent.Async.Lifted (forConcurrently)
import Control.Monad.Reader (local)
import Data.Functor ((<&>))
import Data.List ((\\))
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Data.Maybe (catMaybes, isJust)
import Data.Text (Text, pack)
import System.Exit (ExitCode (..))
import Text.Pandoc.Filter.Plot.Monad
import Text.Pandoc.Filter.Plot.Monad.Logging
( Logger (lVerbosity),
)
import Text.Pandoc.Filter.Plot.Renderers.Bokeh
( bokeh, bokehSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.GGPlot2
( ggplot2, ggplot2SupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.GNUPlot
( gnuplot, gnuplotSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Graphviz
( graphviz, graphvizSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Mathematica
( mathematica, mathematicaSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Matlab
( matlab, matlabSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Matplotlib
( matplotlib, matplotlibSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Octave
( octave, octaveSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.PlantUML
( plantuml, plantumlSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.PlotlyPython
( plotlyPython, plotlyPythonSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.PlotlyR
( plotlyR, plotlyRSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.Plotsjl
( plotsjl, plotsjlSupportedSaveFormats )
import Text.Pandoc.Filter.Plot.Renderers.SageMath
( sagemath, sagemathSupportedSaveFormats )
import System.Directory (findExecutable)
renderer :: Toolkit -> PlotM Renderer
renderer :: Toolkit -> PlotM Renderer
renderer Toolkit
Matplotlib = PlotM Renderer
matplotlib
renderer Toolkit
PlotlyPython = PlotM Renderer
plotlyPython
renderer Toolkit
PlotlyR = PlotM Renderer
plotlyR
renderer Toolkit
Matlab = PlotM Renderer
matlab
renderer Toolkit
Mathematica = PlotM Renderer
mathematica
renderer Toolkit
Octave = PlotM Renderer
octave
renderer Toolkit
GGPlot2 = PlotM Renderer
ggplot2
renderer Toolkit
GNUPlot = PlotM Renderer
gnuplot
renderer Toolkit
Graphviz = PlotM Renderer
graphviz
renderer Toolkit
Bokeh = PlotM Renderer
bokeh
renderer Toolkit
Plotsjl = PlotM Renderer
plotsjl
renderer Toolkit
PlantUML = PlotM Renderer
plantuml
renderer Toolkit
SageMath = PlotM Renderer
sagemath
supportedSaveFormats :: Toolkit -> [SaveFormat]
supportedSaveFormats :: Toolkit -> [SaveFormat]
supportedSaveFormats Toolkit
Matplotlib = [SaveFormat]
matplotlibSupportedSaveFormats
supportedSaveFormats Toolkit
PlotlyPython = [SaveFormat]
plotlyPythonSupportedSaveFormats
supportedSaveFormats Toolkit
PlotlyR = [SaveFormat]
plotlyRSupportedSaveFormats
supportedSaveFormats Toolkit
Matlab = [SaveFormat]
matlabSupportedSaveFormats
supportedSaveFormats Toolkit
Mathematica = [SaveFormat]
mathematicaSupportedSaveFormats
supportedSaveFormats Toolkit
Octave = [SaveFormat]
octaveSupportedSaveFormats
supportedSaveFormats Toolkit
GGPlot2 = [SaveFormat]
ggplot2SupportedSaveFormats
supportedSaveFormats Toolkit
GNUPlot = [SaveFormat]
gnuplotSupportedSaveFormats
supportedSaveFormats Toolkit
Graphviz = [SaveFormat]
graphvizSupportedSaveFormats
supportedSaveFormats Toolkit
Bokeh = [SaveFormat]
bokehSupportedSaveFormats
supportedSaveFormats Toolkit
Plotsjl = [SaveFormat]
plotsjlSupportedSaveFormats
supportedSaveFormats Toolkit
PlantUML = [SaveFormat]
plantumlSupportedSaveFormats
supportedSaveFormats Toolkit
SageMath = [SaveFormat]
sagemathSupportedSaveFormats
preambleSelector :: Toolkit -> (Configuration -> Script)
preambleSelector :: Toolkit -> Configuration -> Script
preambleSelector Toolkit
Matplotlib = Configuration -> Script
matplotlibPreamble
preambleSelector Toolkit
PlotlyPython = Configuration -> Script
plotlyPythonPreamble
preambleSelector Toolkit
PlotlyR = Configuration -> Script
plotlyRPreamble
preambleSelector Toolkit
Matlab = Configuration -> Script
matlabPreamble
preambleSelector Toolkit
Mathematica = Configuration -> Script
mathematicaPreamble
preambleSelector Toolkit
Octave = Configuration -> Script
octavePreamble
preambleSelector Toolkit
GGPlot2 = Configuration -> Script
ggplot2Preamble
preambleSelector Toolkit
GNUPlot = Configuration -> Script
gnuplotPreamble
preambleSelector Toolkit
Graphviz = Configuration -> Script
graphvizPreamble
preambleSelector Toolkit
Bokeh = Configuration -> Script
bokehPreamble
preambleSelector Toolkit
Plotsjl = Configuration -> Script
plotsjlPreamble
preambleSelector Toolkit
PlantUML = Configuration -> Script
plantumlPreamble
preambleSelector Toolkit
SageMath = Configuration -> Script
sagemathPreamble
parseExtraAttrs :: Toolkit -> Map Text Text -> Map Text Text
Toolkit
Matplotlib = (Script -> Script -> Bool)
-> Map Script Script -> Map Script Script
forall k a. (k -> a -> Bool) -> Map k a -> Map k a
M.filterWithKey (\Script
k Script
_ -> Script
k Script -> [Script] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Script
"tight_bbox", Script
"transparent"])
parseExtraAttrs Toolkit
_ = Map Script Script -> Map Script Script -> Map Script Script
forall (m :: * -> *) a. Monad m => a -> m a
return Map Script Script
forall a. Monoid a => a
mempty
availableToolkits :: Configuration -> IO [Toolkit]
availableToolkits :: Configuration -> IO [Toolkit]
availableToolkits Configuration
conf = Maybe Format -> Configuration -> PlotM [Toolkit] -> IO [Toolkit]
forall a. Maybe Format -> Configuration -> PlotM a -> IO a
runPlotM Maybe Format
forall a. Maybe a
Nothing Configuration
conf PlotM [Toolkit]
availableToolkitsM
unavailableToolkits :: Configuration -> IO [Toolkit]
unavailableToolkits :: Configuration -> IO [Toolkit]
unavailableToolkits Configuration
conf = Maybe Format -> Configuration -> PlotM [Toolkit] -> IO [Toolkit]
forall a. Maybe Format -> Configuration -> PlotM a -> IO a
runPlotM Maybe Format
forall a. Maybe a
Nothing Configuration
conf PlotM [Toolkit]
unavailableToolkitsM
availableToolkitsM :: PlotM [Toolkit]
availableToolkitsM :: PlotM [Toolkit]
availableToolkitsM = PlotM [Toolkit] -> PlotM [Toolkit]
forall a.
StateT PlotState (ReaderT RuntimeEnv IO) a
-> StateT PlotState (ReaderT RuntimeEnv IO) a
asNonStrictAndSilent (PlotM [Toolkit] -> PlotM [Toolkit])
-> PlotM [Toolkit] -> PlotM [Toolkit]
forall a b. (a -> b) -> a -> b
$ do
[Maybe Toolkit]
mtks <- [Toolkit]
-> (Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit))
-> StateT PlotState (ReaderT RuntimeEnv IO) [Maybe Toolkit]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, MonadBaseControl IO m) =>
t a -> (a -> m b) -> m (t b)
forConcurrently [Toolkit]
toolkits ((Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit))
-> StateT PlotState (ReaderT RuntimeEnv IO) [Maybe Toolkit])
-> (Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit))
-> StateT PlotState (ReaderT RuntimeEnv IO) [Maybe Toolkit]
forall a b. (a -> b) -> a -> b
$ \Toolkit
tk -> do
Renderer
r <- Toolkit -> PlotM Renderer
renderer Toolkit
tk
Executable
exe <- Toolkit -> PlotM Executable
executable Toolkit
tk
Bool
a <- Executable -> AvailabilityCheck -> PlotM Bool
isAvailable Executable
exe (Renderer -> AvailabilityCheck
rendererAvailability Renderer
r)
if Bool
a
then Maybe Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit))
-> Maybe Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit)
forall a b. (a -> b) -> a -> b
$ Toolkit -> Maybe Toolkit
forall a. a -> Maybe a
Just Toolkit
tk
else Maybe Toolkit
-> StateT PlotState (ReaderT RuntimeEnv IO) (Maybe Toolkit)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Toolkit
forall a. Maybe a
Nothing
[Toolkit] -> PlotM [Toolkit]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Toolkit] -> PlotM [Toolkit]) -> [Toolkit] -> PlotM [Toolkit]
forall a b. (a -> b) -> a -> b
$ [Maybe Toolkit] -> [Toolkit]
forall a. [Maybe a] -> [a]
catMaybes [Maybe Toolkit]
mtks
where
asNonStrictAndSilent :: StateT PlotState (ReaderT RuntimeEnv IO) a
-> StateT PlotState (ReaderT RuntimeEnv IO) a
asNonStrictAndSilent = (RuntimeEnv -> RuntimeEnv)
-> StateT PlotState (ReaderT RuntimeEnv IO) a
-> StateT PlotState (ReaderT RuntimeEnv IO) a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local (\(RuntimeEnv Maybe Format
f Configuration
c Logger
l FilePath
d) -> Maybe Format -> Configuration -> Logger -> FilePath -> RuntimeEnv
RuntimeEnv Maybe Format
f (Configuration
c{strictMode :: Bool
strictMode = Bool
False}) (Logger
l{lVerbosity :: Verbosity
lVerbosity = Verbosity
Silent}) FilePath
d)
commandSuccess :: Text -> PlotM Bool
commandSuccess :: Script -> PlotM Bool
commandSuccess Script
s = do
FilePath
cwd <- (RuntimeEnv -> FilePath)
-> StateT PlotState (ReaderT RuntimeEnv IO) FilePath
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks RuntimeEnv -> FilePath
envCWD
(ExitCode
ec, Script
_) <- FilePath -> Script -> PlotM (ExitCode, Script)
runCommand FilePath
cwd Script
s
Script -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall (m :: * -> *). (MonadLogger m, MonadIO m) => Script -> m ()
debug (Script -> StateT PlotState (ReaderT RuntimeEnv IO) ())
-> Script -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall a b. (a -> b) -> a -> b
$ [Script] -> Script
forall a. Monoid a => [a] -> a
mconcat [Script
"Command ", Script
s, Script
" resulted in ", FilePath -> Script
pack (FilePath -> Script) -> FilePath -> Script
forall a b. (a -> b) -> a -> b
$ ExitCode -> FilePath
forall a. Show a => a -> FilePath
show ExitCode
ec]
Bool -> PlotM Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> PlotM Bool) -> Bool -> PlotM Bool
forall a b. (a -> b) -> a -> b
$ ExitCode
ec ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
== ExitCode
ExitSuccess
isAvailable :: Executable -> AvailabilityCheck -> PlotM Bool
isAvailable :: Executable -> AvailabilityCheck -> PlotM Bool
isAvailable Executable
exe (CommandSuccess Executable -> Script
f) = Script -> PlotM Bool
commandSuccess (Executable -> Script
f Executable
exe)
isAvailable Executable
exe (AvailabilityCheck
ExecutableExists) = IO Bool -> PlotM Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> PlotM Bool) -> IO Bool -> PlotM Bool
forall a b. (a -> b) -> a -> b
$ FilePath -> IO (Maybe FilePath)
findExecutable (Executable -> FilePath
pathToExe Executable
exe) IO (Maybe FilePath) -> (Maybe FilePath -> Bool) -> IO Bool
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Maybe FilePath -> Bool
forall a. Maybe a -> Bool
isJust
unavailableToolkitsM :: PlotM [Toolkit]
unavailableToolkitsM :: PlotM [Toolkit]
unavailableToolkitsM = [Toolkit] -> [Toolkit] -> [Toolkit]
forall a. Eq a => [a] -> [a] -> [a]
(\\) [Toolkit]
toolkits ([Toolkit] -> [Toolkit]) -> PlotM [Toolkit] -> PlotM [Toolkit]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PlotM [Toolkit]
availableToolkitsM