{-# 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.Concurrent.MVar (putMVar, takeMVar)
import Control.Monad.Reader (local)
import Control.Monad.State.Strict
( MonadState (get, put),
)
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 Text.Pandoc.Filter.Plot.Monad
import Text.Pandoc.Filter.Plot.Renderers.Bokeh
import Text.Pandoc.Filter.Plot.Renderers.GGPlot2
import Text.Pandoc.Filter.Plot.Renderers.GNUPlot
import Text.Pandoc.Filter.Plot.Renderers.Graphviz
import Text.Pandoc.Filter.Plot.Renderers.Mathematica
import Text.Pandoc.Filter.Plot.Renderers.Matlab
import Text.Pandoc.Filter.Plot.Renderers.Matplotlib
import Text.Pandoc.Filter.Plot.Renderers.Octave
import Text.Pandoc.Filter.Plot.Renderers.PlantUML
import Text.Pandoc.Filter.Plot.Renderers.PlotlyPython
import Text.Pandoc.Filter.Plot.Renderers.PlotlyR
import Text.Pandoc.Filter.Plot.Renderers.Plotsjl
renderer :: Toolkit -> PlotM (Maybe Renderer)
renderer :: Toolkit -> PlotM (Maybe Renderer)
renderer Toolkit
tk = do
PlotState MVar (Map FilePath FileHash)
varHashes MVar (Map Toolkit (Maybe Renderer))
varRenderers <- StateT PlotState (ReaderT RuntimeEnv IO) PlotState
forall s (m :: * -> *). MonadState s m => m s
get
Map Toolkit (Maybe Renderer)
renderers <- IO (Map Toolkit (Maybe Renderer))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Map Toolkit (Maybe Renderer))
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Map Toolkit (Maybe Renderer))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Map Toolkit (Maybe Renderer)))
-> IO (Map Toolkit (Maybe Renderer))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Map Toolkit (Maybe Renderer))
forall a b. (a -> b) -> a -> b
$ MVar (Map Toolkit (Maybe Renderer))
-> IO (Map Toolkit (Maybe Renderer))
forall a. MVar a -> IO a
takeMVar MVar (Map Toolkit (Maybe Renderer))
varRenderers
(Maybe Renderer
r', Map Toolkit (Maybe Renderer)
rs') <- case Toolkit -> Map Toolkit (Maybe Renderer) -> Maybe (Maybe Renderer)
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup Toolkit
tk Map Toolkit (Maybe Renderer)
renderers of
Maybe (Maybe Renderer)
Nothing -> do
Text -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall (m :: * -> *). (MonadLogger m, MonadIO m) => Text -> m ()
debug (Text -> StateT PlotState (ReaderT RuntimeEnv IO) ())
-> Text -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"Looking for renderer for ", FilePath -> Text
pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ Toolkit -> FilePath
forall a. Show a => a -> FilePath
show Toolkit
tk]
Maybe Renderer
r' <- Toolkit -> PlotM (Maybe Renderer)
sel Toolkit
tk
let rs' :: Map Toolkit (Maybe Renderer)
rs' = Toolkit
-> Maybe Renderer
-> Map Toolkit (Maybe Renderer)
-> Map Toolkit (Maybe Renderer)
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert Toolkit
tk Maybe Renderer
r' Map Toolkit (Maybe Renderer)
renderers
(Maybe Renderer, Map Toolkit (Maybe Renderer))
-> StateT
PlotState
(ReaderT RuntimeEnv IO)
(Maybe Renderer, Map Toolkit (Maybe Renderer))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Renderer
r', Map Toolkit (Maybe Renderer)
rs')
Just Maybe Renderer
e -> do
Text -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall (m :: * -> *). (MonadLogger m, MonadIO m) => Text -> m ()
debug (Text -> StateT PlotState (ReaderT RuntimeEnv IO) ())
-> Text -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
forall a. Monoid a => [a] -> a
mconcat [Text
"Renderer for \"", FilePath -> Text
pack (FilePath -> Text) -> FilePath -> Text
forall a b. (a -> b) -> a -> b
$ Toolkit -> FilePath
forall a. Show a => a -> FilePath
show Toolkit
tk, Text
"\" already initialized."]
(Maybe Renderer, Map Toolkit (Maybe Renderer))
-> StateT
PlotState
(ReaderT RuntimeEnv IO)
(Maybe Renderer, Map Toolkit (Maybe Renderer))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Renderer
e, Map Toolkit (Maybe Renderer)
renderers)
IO () -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> StateT PlotState (ReaderT RuntimeEnv IO) ())
-> IO () -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall a b. (a -> b) -> a -> b
$ MVar (Map Toolkit (Maybe Renderer))
-> Map Toolkit (Maybe Renderer) -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Map Toolkit (Maybe Renderer))
varRenderers Map Toolkit (Maybe Renderer)
rs'
PlotState -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (PlotState -> StateT PlotState (ReaderT RuntimeEnv IO) ())
-> PlotState -> StateT PlotState (ReaderT RuntimeEnv IO) ()
forall a b. (a -> b) -> a -> b
$ MVar (Map FilePath FileHash)
-> MVar (Map Toolkit (Maybe Renderer)) -> PlotState
PlotState MVar (Map FilePath FileHash)
varHashes MVar (Map Toolkit (Maybe Renderer))
varRenderers
Maybe Renderer -> PlotM (Maybe Renderer)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Renderer
r'
where
sel :: Toolkit -> PlotM (Maybe Renderer)
sel :: Toolkit -> PlotM (Maybe Renderer)
sel Toolkit
Matplotlib = PlotM (Maybe Renderer)
matplotlib
sel Toolkit
PlotlyPython = PlotM (Maybe Renderer)
plotlyPython
sel Toolkit
PlotlyR = PlotM (Maybe Renderer)
plotlyR
sel Toolkit
Matlab = PlotM (Maybe Renderer)
matlab
sel Toolkit
Mathematica = PlotM (Maybe Renderer)
mathematica
sel Toolkit
Octave = PlotM (Maybe Renderer)
octave
sel Toolkit
GGPlot2 = PlotM (Maybe Renderer)
ggplot2
sel Toolkit
GNUPlot = PlotM (Maybe Renderer)
gnuplot
sel Toolkit
Graphviz = PlotM (Maybe Renderer)
graphviz
sel Toolkit
Bokeh = PlotM (Maybe Renderer)
bokeh
sel Toolkit
Plotsjl = PlotM (Maybe Renderer)
plotsjl
sel Toolkit
PlantUML = PlotM (Maybe Renderer)
plantuml
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
preambleSelector :: Toolkit -> (Configuration -> Script)
preambleSelector :: Toolkit -> Configuration -> Text
preambleSelector Toolkit
Matplotlib = Configuration -> Text
matplotlibPreamble
preambleSelector Toolkit
PlotlyPython = Configuration -> Text
plotlyPythonPreamble
preambleSelector Toolkit
PlotlyR = Configuration -> Text
plotlyRPreamble
preambleSelector Toolkit
Matlab = Configuration -> Text
matlabPreamble
preambleSelector Toolkit
Mathematica = Configuration -> Text
mathematicaPreamble
preambleSelector Toolkit
Octave = Configuration -> Text
octavePreamble
preambleSelector Toolkit
GGPlot2 = Configuration -> Text
ggplot2Preamble
preambleSelector Toolkit
GNUPlot = Configuration -> Text
gnuplotPreamble
preambleSelector Toolkit
Graphviz = Configuration -> Text
graphvizPreamble
preambleSelector Toolkit
Bokeh = Configuration -> Text
bokehPreamble
preambleSelector Toolkit
Plotsjl = Configuration -> Text
plotsjlPreamble
preambleSelector Toolkit
PlantUML = Configuration -> Text
plantumlPreamble
parseExtraAttrs :: Toolkit -> Map Text Text -> Map Text Text
Toolkit
Matplotlib = (Text -> Text -> Bool) -> Map Text Text -> Map Text Text
forall k a. (k -> a -> Bool) -> Map k a -> Map k a
M.filterWithKey (\Text
k Text
_ -> Text
k Text -> [Text] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Text
"tight_bbox", Text
"transparent"])
parseExtraAttrs Toolkit
_ = Map Text Text -> Map Text Text -> Map Text Text
forall (m :: * -> *) a. Monad m => a -> m a
return Map Text Text
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. PlotM a -> PlotM a
silence (PlotM [Toolkit] -> PlotM [Toolkit])
-> PlotM [Toolkit] -> PlotM [Toolkit]
forall a b. (a -> b) -> a -> b
$
PlotM [Toolkit] -> PlotM [Toolkit]
forall a. PlotM a -> PlotM a
asNonStrict (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
Bool
available <- Maybe Renderer -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Renderer -> Bool)
-> PlotM (Maybe Renderer)
-> StateT PlotState (ReaderT RuntimeEnv IO) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Toolkit -> PlotM (Maybe Renderer)
renderer Toolkit
tk
if Bool
available
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
asNonStrict :: StateT PlotState (ReaderT RuntimeEnv IO) a
-> StateT PlotState (ReaderT RuntimeEnv IO) a
asNonStrict = (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 FilePath
d)
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