{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} {-| Module : $header$ Copyright : (c) Laurent P René de Cotret, 2020 License : GNU GPL, version 2 or above Maintainer : laurent.decotret@outlook.com Stability : internal Portability : portable This module defines base types in use in pandoc-plot -} module Text.Pandoc.Filter.Plot.Monad.Types ( Toolkit(..) , Script , CheckResult(..) , InclusionKey(..) , FigureSpec(..) , SaveFormat(..) , cls , extension , toolkits , inclusionKeys , Executable(..) , exeFromPath -- Utilities , isWindows ) where import Data.Char (toLower) import Data.List (intersperse) import Data.String (IsString (..)) import Data.Text (Text, pack) import Data.Yaml (FromJSON, ToJSON(toJSON)) import GHC.Generics (Generic) import System.FilePath (splitFileName) import System.Info (os) import Text.Pandoc.Definition (Attr) -- | List of supported toolkits. toolkits :: [Toolkit] toolkits = enumFromTo minBound maxBound -- | Enumeration of supported toolkits data Toolkit = Matplotlib | Matlab | PlotlyPython | PlotlyR | Mathematica | Octave | GGPlot2 | GNUPlot | Graphviz | Bokeh | Plotsjl deriving (Bounded, Eq, Enum, Generic, Ord) -- | This instance should only be used to display toolkit names instance Show Toolkit where show Matplotlib = "Python/Matplotlib" show Matlab = "MATLAB" show PlotlyPython = "Python/Plotly" show PlotlyR = "R/Plotly" show Mathematica = "Mathematica" show Octave = "GNU Octave" show GGPlot2 = "ggplot2" show GNUPlot = "gnuplot" show Graphviz = "graphviz" show Bokeh = "Python/Bokeh" show Plotsjl = "Julia/Plots.jl" -- | Class name which will trigger the filter cls :: Toolkit -> Text cls Matplotlib = "matplotlib" cls Matlab = "matlabplot" cls PlotlyPython = "plotly_python" cls PlotlyR = "plotly_r" cls Mathematica = "mathplot" cls Octave = "octaveplot" cls GGPlot2 = "ggplot2" cls GNUPlot = "gnuplot" cls Graphviz = "graphviz" cls Bokeh = "bokeh" cls Plotsjl = "plotsjl" -- | Executable program and directory where it can be found. data Executable = Executable FilePath Text exeFromPath :: FilePath -> Executable exeFromPath fp = let (dir, name) = splitFileName fp in Executable dir (pack name) -- | Source context for plotting scripts type Script = Text -- | Result of checking scripts for problems data CheckResult = CheckPassed | CheckFailed Text deriving (Eq) instance Semigroup CheckResult where (<>) CheckPassed a = a (<>) a CheckPassed = a (<>) (CheckFailed msg1) (CheckFailed msg2) = CheckFailed (msg1 <> msg2) instance Monoid CheckResult where mempty = CheckPassed -- | Description of any possible inclusion key, both in documents -- and in configuration files. data InclusionKey = DirectoryK | CaptionK | SaveFormatK | WithSourceK | CaptionFormatK | PreambleK | DpiK | ExecutableK | DependenciesK | FileK | MatplotlibTightBBoxK | MatplotlibTransparentK deriving (Bounded, Eq, Enum) -- | Keys that pandoc-plot will look for in code blocks. -- These are only exported for testing purposes. instance Show InclusionKey where show DirectoryK = "directory" show CaptionK = "caption" show SaveFormatK = "format" show WithSourceK = "source" show CaptionFormatK = "caption_format" show PreambleK = "preamble" show DpiK = "dpi" show ExecutableK = "executable" show DependenciesK = "dependencies" show FileK = "file" show MatplotlibTightBBoxK = "tight_bbox" show MatplotlibTransparentK = "transparent" -- | List of all keys related to pandoc-plot that -- can be specified in source material. inclusionKeys :: [InclusionKey] inclusionKeys = enumFromTo (minBound::InclusionKey) maxBound -- | Datatype containing all parameters required to run pandoc-plot. -- -- It is assumed that once a @FigureSpec@ has been created, no configuration -- can overload it; hence, a @FigureSpec@ completely encodes a particular figure. data FigureSpec = FigureSpec { toolkit :: !Toolkit -- ^ Plotting toolkit to use for this figure. , caption :: !Text -- ^ Figure caption. , withSource :: !Bool -- ^ Append link to source code in caption. , script :: !Script -- ^ Source code for the figure. , saveFormat :: !SaveFormat -- ^ Save format of the figure. , directory :: !FilePath -- ^ Directory where to save the file. , dpi :: !Int -- ^ Dots-per-inch of figure. , dependencies :: ![FilePath] -- ^ Files/directories on which this figure depends, e.g. data files. , extraAttrs :: ![(Text, Text)] -- ^ Renderer-specific extra attributes. , blockAttrs :: !Attr -- ^ Attributes not related to @pandoc-plot@ will be propagated. } -- | Generated figure file format supported by pandoc-plot. -- Note that not all formats are supported by all toolkits. data SaveFormat = PNG -- ^ Portable network graphics | PDF -- ^ Portable document format | SVG -- ^ Scalable vector graphics | JPG -- ^ JPEG/JPG compressed image | EPS -- ^ Encapsulated postscript | GIF -- ^ GIF format | TIF -- ^ Tagged image format | WEBP -- ^ WebP image format | HTML -- ^ HTML for interactive plots. deriving (Bounded, Enum, Eq, Show, Generic) instance IsString SaveFormat where -- | An error is thrown if the save format cannot be parsed. That's OK -- since pandoc-plot is a command-line tool and isn't expected to run -- long. fromString s | s `elem` ["png", "PNG", ".png"] = PNG | s `elem` ["pdf", "PDF", ".pdf"] = PDF | s `elem` ["svg", "SVG", ".svg"] = SVG | s `elem` ["eps", "EPS", ".eps"] = EPS | s `elem` ["gif", "GIF", ".gif"] = GIF | s `elem` ["jpg", "jpeg", "JPG", "JPEG", ".jpg", ".jpeg"] = JPG | s `elem` ["tif", "tiff", "TIF", "TIFF", ".tif", ".tiff"] = TIF | s `elem` ["webp", "WEBP", ".webp"] = WEBP | s `elem` ["html", "HTML", ".html"] = HTML | otherwise = errorWithoutStackTrace $ mconcat [ s , " is not one of valid save format : " , mconcat $ intersperse ", " $ show <$> saveFormats ] where saveFormats = (enumFromTo minBound maxBound) :: [SaveFormat] instance FromJSON SaveFormat -- TODO: test this parsing instance ToJSON SaveFormat where toJSON = toJSON . extension -- | Save format file extension extension :: SaveFormat -> String extension fmt = mconcat [".", fmap toLower . show $ fmt] isWindows :: Bool isWindows = os `elem` ["mingw32", "win32", "cygwin32"] -- Aliases taken from cabal's Distribution.System module