{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
module Text.Pandoc.Filter.Plot
(
plotTransform,
cleanOutputDirs,
configuration,
defaultConfiguration,
Configuration (..),
Verbosity (..),
LogSink (..),
SaveFormat (..),
Script,
Toolkit (..),
availableToolkits,
unavailableToolkits,
toolkits,
supportedSaveFormats,
pandocPlotVersion,
make,
makeEither,
PandocPlotError (..),
)
where
import Control.Concurrent.Async.Lifted (mapConcurrently)
import Data.Text (Text, unpack)
import Data.Version (Version)
import Paths_pandoc_plot (version)
import Text.Pandoc.Definition (Block, Pandoc (..))
import Text.Pandoc.Filter.Plot.Internal
( Configuration (..),
FigureSpec,
LogSink (..),
PlotM,
RuntimeEnv (envConfig),
SaveFormat (..),
Script,
ScriptResult (..),
Toolkit (..),
Verbosity (..),
asks,
availableToolkits,
cleanOutputDirs,
configuration,
defaultConfiguration,
parseFigureSpec,
runPlotM,
runScriptIfNecessary,
supportedSaveFormats,
toFigure,
toolkits,
unavailableToolkits,
)
plotTransform ::
Configuration ->
Pandoc ->
IO Pandoc
plotTransform :: Configuration -> Pandoc -> IO Pandoc
plotTransform Configuration
conf (Pandoc Meta
meta [Block]
blocks) =
Configuration -> PlotM Pandoc -> IO Pandoc
forall a. Configuration -> PlotM a -> IO a
runPlotM Configuration
conf (PlotM Pandoc -> IO Pandoc) -> PlotM Pandoc -> IO Pandoc
forall a b. (a -> b) -> a -> b
$ (Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block)
-> [Block] -> StateT PlotState (ReaderT RuntimeEnv IO) [Block]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, MonadBaseControl IO m) =>
(a -> m b) -> t a -> m (t b)
mapConcurrently Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block
make [Block]
blocks StateT PlotState (ReaderT RuntimeEnv IO) [Block]
-> ([Block] -> PlotM Pandoc) -> PlotM Pandoc
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pandoc -> PlotM Pandoc
forall (m :: * -> *) a. Monad m => a -> m a
return (Pandoc -> PlotM Pandoc)
-> ([Block] -> Pandoc) -> [Block] -> PlotM Pandoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Meta -> [Block] -> Pandoc
Pandoc Meta
meta
pandocPlotVersion :: Version
pandocPlotVersion :: Version
pandocPlotVersion = Version
version
make :: Block -> PlotM Block
make :: Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block
make Block
blk = (PandocPlotError -> StateT PlotState (ReaderT RuntimeEnv IO) Block)
-> (Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block)
-> Either PandocPlotError Block
-> StateT PlotState (ReaderT RuntimeEnv IO) Block
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (StateT PlotState (ReaderT RuntimeEnv IO) Block
-> PandocPlotError
-> StateT PlotState (ReaderT RuntimeEnv IO) Block
forall a b. a -> b -> a
const (Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block
forall (m :: * -> *) a. Monad m => a -> m a
return Block
blk)) Block -> StateT PlotState (ReaderT RuntimeEnv IO) Block
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PandocPlotError Block
-> StateT PlotState (ReaderT RuntimeEnv IO) Block)
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
-> StateT PlotState (ReaderT RuntimeEnv IO) Block
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
makeEither Block
blk
makeEither :: Block -> PlotM (Either PandocPlotError Block)
makeEither :: Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
makeEither Block
block =
Block -> PlotM (Maybe FigureSpec)
parseFigureSpec Block
block
PlotM (Maybe FigureSpec)
-> (Maybe FigureSpec
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
-> (FigureSpec
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> Maybe FigureSpec
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
(Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall a b. (a -> b) -> a -> b
$ Block -> Either PandocPlotError Block
forall a b. b -> Either a b
Right Block
block)
(\FigureSpec
s -> FigureSpec -> PlotM ScriptResult
runScriptIfNecessary FigureSpec
s PlotM ScriptResult
-> (ScriptResult
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= FigureSpec
-> ScriptResult
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
handleResult FigureSpec
s)
where
handleResult :: FigureSpec -> ScriptResult -> PlotM (Either PandocPlotError Block)
handleResult :: FigureSpec
-> ScriptResult
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
handleResult FigureSpec
_ (ScriptFailure Text
msg Int
code) = Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall a b. (a -> b) -> a -> b
$ PandocPlotError -> Either PandocPlotError Block
forall a b. a -> Either a b
Left (Text -> Int -> PandocPlotError
ScriptRuntimeError Text
msg Int
code)
handleResult FigureSpec
_ (ScriptChecksFailed Text
msg) = Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall a b. (a -> b) -> a -> b
$ PandocPlotError -> Either PandocPlotError Block
forall a b. a -> Either a b
Left (Text -> PandocPlotError
ScriptChecksFailedError Text
msg)
handleResult FigureSpec
_ (ToolkitNotInstalled Toolkit
tk') = Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> Either PandocPlotError Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall a b. (a -> b) -> a -> b
$ PandocPlotError -> Either PandocPlotError Block
forall a b. a -> Either a b
Left (Toolkit -> PandocPlotError
ToolkitNotInstalledError Toolkit
tk')
handleResult FigureSpec
spec ScriptResult
ScriptSuccess = (RuntimeEnv -> Configuration)
-> StateT PlotState (ReaderT RuntimeEnv IO) Configuration
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks RuntimeEnv -> Configuration
envConfig StateT PlotState (ReaderT RuntimeEnv IO) Configuration
-> (Configuration
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block))
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Configuration
c -> Block -> Either PandocPlotError Block
forall a b. b -> Either a b
Right (Block -> Either PandocPlotError Block)
-> StateT PlotState (ReaderT RuntimeEnv IO) Block
-> StateT
PlotState (ReaderT RuntimeEnv IO) (Either PandocPlotError Block)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Format
-> FigureSpec -> StateT PlotState (ReaderT RuntimeEnv IO) Block
toFigure (Configuration -> Format
captionFormat Configuration
c) FigureSpec
spec
data PandocPlotError
= ScriptRuntimeError Text Int
| ScriptChecksFailedError Text
| ToolkitNotInstalledError Toolkit
instance Show PandocPlotError where
show :: PandocPlotError -> String
show (ScriptRuntimeError Text
_ Int
exitcode) = String
"ERROR (pandoc-plot) The script failed with exit code " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
exitcode String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"."
show (ScriptChecksFailedError Text
msg) = String
"ERROR (pandoc-plot) A script check failed with message: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Text -> String
unpack Text
msg String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"."
show (ToolkitNotInstalledError Toolkit
tk) = String
"ERROR (pandoc-plot) The " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Toolkit -> String
forall a. Show a => a -> String
show Toolkit
tk String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" toolkit is required but not installed."