-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
Renderers.hs
167 lines (155 loc) · 6.41 KB
/
Renderers.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
-- |
-- Module : $header$
-- Copyright : (c) Laurent P René de Cotret, 2019 - present
-- License : GNU GPL, version 2 or above
-- Maintainer : laurent.decotret@outlook.com
-- Stability : internal
-- Portability : portable
--
-- Specification of renderers.
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)
-- | Get the renderer associated with a toolkit.
-- If the renderer has not been used before,
-- initialize it and store where it is. It will be re-used.
renderer :: Toolkit -> PlotM Renderer
renderer Matplotlib = matplotlib
renderer PlotlyPython = plotlyPython
renderer PlotlyR = plotlyR
renderer Matlab = matlab
renderer Mathematica = mathematica
renderer Octave = octave
renderer GGPlot2 = ggplot2
renderer GNUPlot = gnuplot
renderer Graphviz = graphviz
renderer Bokeh = bokeh
renderer Plotsjl = plotsjl
renderer PlantUML = plantuml
renderer SageMath = sagemath
-- | Save formats supported by this renderer.
supportedSaveFormats :: Toolkit -> [SaveFormat]
supportedSaveFormats Matplotlib = matplotlibSupportedSaveFormats
supportedSaveFormats PlotlyPython = plotlyPythonSupportedSaveFormats
supportedSaveFormats PlotlyR = plotlyRSupportedSaveFormats
supportedSaveFormats Matlab = matlabSupportedSaveFormats
supportedSaveFormats Mathematica = mathematicaSupportedSaveFormats
supportedSaveFormats Octave = octaveSupportedSaveFormats
supportedSaveFormats GGPlot2 = ggplot2SupportedSaveFormats
supportedSaveFormats GNUPlot = gnuplotSupportedSaveFormats
supportedSaveFormats Graphviz = graphvizSupportedSaveFormats
supportedSaveFormats Bokeh = bokehSupportedSaveFormats
supportedSaveFormats Plotsjl = plotsjlSupportedSaveFormats
supportedSaveFormats PlantUML = plantumlSupportedSaveFormats
supportedSaveFormats SageMath = sagemathSupportedSaveFormats
-- | The function that maps from configuration to the preamble.
preambleSelector :: Toolkit -> (Configuration -> Script)
preambleSelector Matplotlib = matplotlibPreamble
preambleSelector PlotlyPython = plotlyPythonPreamble
preambleSelector PlotlyR = plotlyRPreamble
preambleSelector Matlab = matlabPreamble
preambleSelector Mathematica = mathematicaPreamble
preambleSelector Octave = octavePreamble
preambleSelector GGPlot2 = ggplot2Preamble
preambleSelector GNUPlot = gnuplotPreamble
preambleSelector Graphviz = graphvizPreamble
preambleSelector Bokeh = bokehPreamble
preambleSelector Plotsjl = plotsjlPreamble
preambleSelector PlantUML = plantumlPreamble
preambleSelector SageMath = sagemathPreamble
-- | Parse code block headers for extra attributes that are specific
-- to this renderer. By default, no extra attributes are parsed.
parseExtraAttrs :: Toolkit -> Map Text Text -> Map Text Text
parseExtraAttrs Matplotlib = M.filterWithKey (\k _ -> k `elem` ["tight_bbox", "transparent"])
parseExtraAttrs _ = return mempty
-- | List of toolkits available on this machine.
-- The executables to look for are taken from the configuration.
availableToolkits :: Configuration -> IO [Toolkit]
availableToolkits conf = runPlotM Nothing conf availableToolkitsM
-- | List of toolkits not available on this machine.
-- The executables to look for are taken from the configur
unavailableToolkits :: Configuration -> IO [Toolkit]
unavailableToolkits conf = runPlotM Nothing conf unavailableToolkitsM
-- | Monadic version of @availableToolkits@.
--
-- Note that logging is disabled
availableToolkitsM :: PlotM [Toolkit]
availableToolkitsM = asNonStrictAndSilent $ do
mtks <- forConcurrently toolkits $ \tk -> do
r <- renderer tk
exe <- executable tk
a <- isAvailable exe (rendererAvailability r)
if a
then return $ Just tk
else return Nothing
return $ catMaybes mtks
where
asNonStrictAndSilent = local (\(RuntimeEnv f c l d) -> RuntimeEnv f (c{strictMode = False}) (l{lVerbosity = Silent}) d)
-- | Check that the supplied command results in
-- an exit code of 0 (i.e. no errors)
commandSuccess :: Text -> PlotM Bool
commandSuccess s = do
cwd <- asks envCWD
(ec, _) <- runCommand cwd s
debug $ mconcat ["Command ", s, " resulted in ", pack $ show ec]
return $ ec == ExitSuccess
isAvailable :: Executable -> AvailabilityCheck -> PlotM Bool
isAvailable exe (CommandSuccess f) = commandSuccess (f exe)
isAvailable exe (ExecutableExists) = liftIO $ findExecutable (pathToExe exe) <&> isJust
-- | Monadic version of @unavailableToolkits@
unavailableToolkitsM :: PlotM [Toolkit]
unavailableToolkitsM = (\\) toolkits <$> availableToolkitsM