{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Text.Pandoc.Filter.Plot.Configuration (
configuration
, configurationPathMeta
, defaultConfiguration
) where
import Data.Maybe (fromMaybe)
import Data.Text (Text, pack, unpack)
import qualified Data.Text.IO as TIO
import Data.Yaml
import Data.Yaml.Config (ignoreEnv, loadYamlSettings)
import Text.Pandoc.Definition (Format(..), Pandoc(..), MetaValue(..), lookupMeta)
import Text.Pandoc.Filter.Plot.Monad
configuration :: FilePath -> IO Configuration
configuration fp = (loadYamlSettings [fp] [] ignoreEnv) >>= renderConfig
defaultConfiguration :: Configuration
defaultConfiguration =
Configuration
{ defaultDirectory = "plots/"
, defaultWithSource = False
, defaultDPI = 80
, defaultSaveFormat = PNG
, defaultDependencies = mempty
, captionFormat = Format "markdown+tex_math_dollars"
, logVerbosity = Warning
, logSink = StdErr
, matplotlibPreamble = mempty
, plotlyPythonPreamble= mempty
, plotlyRPreamble = mempty
, matlabPreamble = mempty
, mathematicaPreamble = mempty
, octavePreamble = mempty
, ggplot2Preamble = mempty
, gnuplotPreamble = mempty
, graphvizPreamble = mempty
, bokehPreamble = mempty
, plotsjlPreamble = mempty
, matplotlibExe = python
, matlabExe = "matlab"
, plotlyPythonExe = python
, plotlyRExe = "Rscript"
, mathematicaExe = "math"
, octaveExe = "octave"
, ggplot2Exe = "Rscript"
, gnuplotExe = "gnuplot"
, graphvizExe = "dot"
, bokehExe = python
, plotsjlExe = "julia"
, matplotlibTightBBox = False
, matplotlibTransparent = False
}
where
python = if isWindows then "python" else "python3"
configurationPathMeta :: Pandoc -> Maybe FilePath
configurationPathMeta (Pandoc meta _) =
lookupMeta "plot-configuration" meta >>= getPath
where
getPath (MetaString s) = Just (unpack s)
getPath _ = Nothing
data ConfigPrecursor = ConfigPrecursor
{ _defaultDirectory :: !FilePath
, _defaultWithSource :: !Bool
, _defaultDPI :: !Int
, _defaultSaveFormat :: !SaveFormat
, _defaultDependencies :: ![FilePath]
, _captionFormat :: !Format
, _logPrec :: !LoggingPrecursor
, _matplotlibPrec :: !MatplotlibPrecursor
, _matlabPrec :: !MatlabPrecursor
, _plotlyPythonPrec :: !PlotlyPythonPrecursor
, _plotlyRPrec :: !PlotlyRPrecursor
, _mathematicaPrec :: !MathematicaPrecursor
, _octavePrec :: !OctavePrecursor
, _ggplot2Prec :: !GGPlot2Precursor
, _gnuplotPrec :: !GNUPlotPrecursor
, _graphvizPrec :: !GraphvizPrecursor
, _bokehPrec :: !BokehPrecursor
, _plotsjlPrec :: !PlotsjlPrecursor
}
defaultConfigPrecursor :: ConfigPrecursor
defaultConfigPrecursor =
ConfigPrecursor
{ _defaultDirectory = defaultDirectory defaultConfiguration
, _defaultWithSource = defaultWithSource defaultConfiguration
, _defaultDPI = defaultDPI defaultConfiguration
, _defaultSaveFormat = defaultSaveFormat defaultConfiguration
, _defaultDependencies = defaultDependencies defaultConfiguration
, _captionFormat = captionFormat defaultConfiguration
, _logPrec = LoggingPrecursor (logVerbosity defaultConfiguration) Nothing
, _matplotlibPrec = MatplotlibPrecursor Nothing (matplotlibTightBBox defaultConfiguration) (matplotlibTransparent defaultConfiguration) (matplotlibExe defaultConfiguration)
, _matlabPrec = MatlabPrecursor Nothing (matlabExe defaultConfiguration)
, _plotlyPythonPrec = PlotlyPythonPrecursor Nothing (plotlyPythonExe defaultConfiguration)
, _plotlyRPrec = PlotlyRPrecursor Nothing (plotlyRExe defaultConfiguration)
, _mathematicaPrec = MathematicaPrecursor Nothing (mathematicaExe defaultConfiguration)
, _octavePrec = OctavePrecursor Nothing (octaveExe defaultConfiguration)
, _ggplot2Prec = GGPlot2Precursor Nothing (ggplot2Exe defaultConfiguration)
, _gnuplotPrec = GNUPlotPrecursor Nothing (gnuplotExe defaultConfiguration)
, _graphvizPrec = GraphvizPrecursor Nothing (graphvizExe defaultConfiguration)
, _bokehPrec = BokehPrecursor Nothing (bokehExe defaultConfiguration)
, _plotsjlPrec = PlotsjlPrecursor Nothing (plotsjlExe defaultConfiguration)
}
data LoggingPrecursor = LoggingPrecursor { _logVerbosity :: !Verbosity
, _logFilePath :: !(Maybe FilePath)
}
data MatplotlibPrecursor = MatplotlibPrecursor
{ _matplotlibPreamble :: !(Maybe FilePath)
, _matplotlibTightBBox :: !Bool
, _matplotlibTransparent :: !Bool
, _matplotlibExe :: !FilePath
}
data MatlabPrecursor = MatlabPrecursor {_matlabPreamble :: !(Maybe FilePath), _matlabExe :: !FilePath}
data PlotlyPythonPrecursor = PlotlyPythonPrecursor {_plotlyPythonPreamble :: !(Maybe FilePath), _plotlyPythonExe :: !FilePath}
data PlotlyRPrecursor = PlotlyRPrecursor {_plotlyRPreamble :: !(Maybe FilePath), _plotlyRExe :: !FilePath}
data MathematicaPrecursor = MathematicaPrecursor {_mathematicaPreamble :: !(Maybe FilePath), _mathematicaExe :: !FilePath}
data OctavePrecursor = OctavePrecursor {_octavePreamble :: !(Maybe FilePath), _octaveExe :: !FilePath}
data GGPlot2Precursor = GGPlot2Precursor {_ggplot2Preamble :: !(Maybe FilePath), _ggplot2Exe :: !FilePath}
data GNUPlotPrecursor = GNUPlotPrecursor {_gnuplotPreamble :: !(Maybe FilePath), _gnuplotExe :: !FilePath}
data GraphvizPrecursor = GraphvizPrecursor {_graphvizPreamble :: !(Maybe FilePath), _graphvizExe :: !FilePath}
data BokehPrecursor = BokehPrecursor {_bokehPreamble :: !(Maybe FilePath), _bokehExe :: !FilePath}
data PlotsjlPrecursor = PlotsjlPrecursor {_plotsjlPreamble :: !(Maybe FilePath), _plotsjlExe :: !FilePath}
instance FromJSON LoggingPrecursor where
parseJSON (Object v) =
LoggingPrecursor <$> v .:? "verbosity" .!= (logVerbosity defaultConfiguration)
<*> v .:? "filepath"
parseJSON _ = fail $ mconcat ["Could not parse logging configuration. "]
instance FromJSON MatplotlibPrecursor where
parseJSON (Object v) =
MatplotlibPrecursor
<$> v .:? (tshow PreambleK)
<*> v .:? (tshow MatplotlibTightBBoxK) .!= (matplotlibTightBBox defaultConfiguration)
<*> v .:? (tshow MatplotlibTransparentK) .!= (matplotlibTransparent defaultConfiguration)
<*> v .:? (tshow ExecutableK) .!= (matplotlibExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Matplotlib, " configuration."]
instance FromJSON MatlabPrecursor where
parseJSON (Object v) = MatlabPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (matlabExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Matlab, " configuration."]
instance FromJSON PlotlyPythonPrecursor where
parseJSON (Object v) = PlotlyPythonPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (plotlyPythonExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show PlotlyPython, " configuration."]
instance FromJSON PlotlyRPrecursor where
parseJSON (Object v) = PlotlyRPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (plotlyRExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show PlotlyR, " configuration."]
instance FromJSON MathematicaPrecursor where
parseJSON (Object v) = MathematicaPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (mathematicaExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Mathematica, " configuration."]
instance FromJSON OctavePrecursor where
parseJSON (Object v) = OctavePrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (octaveExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Octave, " configuration."]
instance FromJSON GGPlot2Precursor where
parseJSON (Object v) = GGPlot2Precursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (ggplot2Exe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show GGPlot2, " configuration."]
instance FromJSON GNUPlotPrecursor where
parseJSON (Object v) = GNUPlotPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (gnuplotExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show GNUPlot, " configuration."]
instance FromJSON GraphvizPrecursor where
parseJSON (Object v) = GraphvizPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (graphvizExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Graphviz, " configuration."]
instance FromJSON BokehPrecursor where
parseJSON (Object v) = BokehPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (bokehExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Bokeh, " configuration."]
instance FromJSON PlotsjlPrecursor where
parseJSON (Object v) = PlotsjlPrecursor <$> v .:? (tshow PreambleK) <*> v .:? (tshow ExecutableK) .!= (plotsjlExe defaultConfiguration)
parseJSON _ = fail $ mconcat ["Could not parse ", show Plotsjl, " configuration."]
instance FromJSON ConfigPrecursor where
parseJSON (Null) = return defaultConfigPrecursor
parseJSON (Object v) = do
_defaultDirectory <- v .:? (tshow DirectoryK) .!= (_defaultDirectory defaultConfigPrecursor)
_defaultWithSource <- v .:? (tshow WithSourceK) .!= (_defaultWithSource defaultConfigPrecursor)
_defaultDPI <- v .:? (tshow DpiK) .!= (_defaultDPI defaultConfigPrecursor)
_defaultSaveFormat <- v .:? (tshow SaveFormatK) .!= (_defaultSaveFormat defaultConfigPrecursor)
_defaultDependencies <- v .:? (tshow DependenciesK) .!= (_defaultDependencies defaultConfigPrecursor)
_captionFormat <- v .:? (tshow CaptionFormatK) .!= (_captionFormat defaultConfigPrecursor)
_logPrec <- v .:? "logging" .!= _logPrec defaultConfigPrecursor
_matplotlibPrec <- v .:? (cls Matplotlib) .!= _matplotlibPrec defaultConfigPrecursor
_matlabPrec <- v .:? (cls Matlab) .!= _matlabPrec defaultConfigPrecursor
_plotlyPythonPrec <- v .:? (cls PlotlyPython) .!= _plotlyPythonPrec defaultConfigPrecursor
_plotlyRPrec <- v .:? (cls PlotlyR) .!= _plotlyRPrec defaultConfigPrecursor
_mathematicaPrec <- v .:? (cls Mathematica) .!= _mathematicaPrec defaultConfigPrecursor
_octavePrec <- v .:? (cls Octave) .!= _octavePrec defaultConfigPrecursor
_ggplot2Prec <- v .:? (cls GGPlot2) .!= _ggplot2Prec defaultConfigPrecursor
_gnuplotPrec <- v .:? (cls GNUPlot) .!= _gnuplotPrec defaultConfigPrecursor
_graphvizPrec <- v .:? (cls Graphviz) .!= _graphvizPrec defaultConfigPrecursor
_bokehPrec <- v .:? (cls Bokeh) .!= _bokehPrec defaultConfigPrecursor
_plotsjlPrec <- v .:? (cls Plotsjl) .!= _plotsjlPrec defaultConfigPrecursor
return $ ConfigPrecursor{..}
parseJSON _ = fail "Could not parse configuration."
renderConfig :: ConfigPrecursor -> IO Configuration
renderConfig ConfigPrecursor{..} = do
let defaultDirectory = _defaultDirectory
defaultWithSource = _defaultWithSource
defaultDPI = _defaultDPI
defaultSaveFormat = _defaultSaveFormat
defaultDependencies = _defaultDependencies
captionFormat = _captionFormat
logVerbosity = _logVerbosity _logPrec
logSink = maybe StdErr LogFile (_logFilePath _logPrec)
matplotlibTightBBox = _matplotlibTightBBox _matplotlibPrec
matplotlibTransparent = _matplotlibTransparent _matplotlibPrec
matplotlibExe = _matplotlibExe _matplotlibPrec
matlabExe = _matlabExe _matlabPrec
plotlyPythonExe = _plotlyPythonExe _plotlyPythonPrec
plotlyRExe = _plotlyRExe _plotlyRPrec
mathematicaExe = _mathematicaExe _mathematicaPrec
octaveExe = _octaveExe _octavePrec
ggplot2Exe = _ggplot2Exe _ggplot2Prec
gnuplotExe = _gnuplotExe _gnuplotPrec
graphvizExe = _graphvizExe _graphvizPrec
bokehExe = _bokehExe _bokehPrec
plotsjlExe = _plotsjlExe _plotsjlPrec
matplotlibPreamble <- readPreamble (_matplotlibPreamble _matplotlibPrec)
matlabPreamble <- readPreamble (_matlabPreamble _matlabPrec)
plotlyPythonPreamble <- readPreamble (_plotlyPythonPreamble _plotlyPythonPrec)
plotlyRPreamble <- readPreamble (_plotlyRPreamble _plotlyRPrec)
mathematicaPreamble <- readPreamble (_mathematicaPreamble _mathematicaPrec)
octavePreamble <- readPreamble (_octavePreamble _octavePrec)
ggplot2Preamble <- readPreamble (_ggplot2Preamble _ggplot2Prec)
gnuplotPreamble <- readPreamble (_gnuplotPreamble _gnuplotPrec)
graphvizPreamble <- readPreamble (_graphvizPreamble _graphvizPrec)
bokehPreamble <- readPreamble (_bokehPreamble _bokehPrec)
plotsjlPreamble <- readPreamble (_plotsjlPreamble _plotsjlPrec)
return Configuration{..}
where
readPreamble fp = fromMaybe mempty $ TIO.readFile <$> fp
tshow :: Show a => a -> Text
tshow = pack . show