packages feed

pandoc-plot 1.6.2 → 1.7.0

raw patch · 32 files changed

+467/−328 lines, 32 filesdep ~basedep ~optparse-applicativedep ~pandoc-typesPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base, optparse-applicative, pandoc-types

API changes (from Hackage documentation)

+ Text.Pandoc.Filter.Plot: D2 :: Toolkit
+ Text.Pandoc.Filter.Plot: [d2CmdArgs] :: Configuration -> !Text
+ Text.Pandoc.Filter.Plot: [d2Exe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot: [d2Preamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: D2 :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: [d2CmdArgs] :: Configuration -> !Text
+ Text.Pandoc.Filter.Plot.Internal: [d2Exe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [d2Preamble] :: Configuration -> !Script
- Text.Pandoc.Filter.Plot: Configuration :: !FilePath -> !Bool -> !Int -> !SaveFormat -> ![FilePath] -> !Format -> !Text -> !Bool -> !Verbosity -> !LogSink -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Bool -> !Bool -> Configuration
+ Text.Pandoc.Filter.Plot: Configuration :: !FilePath -> !Bool -> !Int -> !SaveFormat -> ![FilePath] -> !Format -> !Text -> !Bool -> !Verbosity -> !LogSink -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Bool -> !Bool -> Configuration
- Text.Pandoc.Filter.Plot.Internal: Configuration :: !FilePath -> !Bool -> !Int -> !SaveFormat -> ![FilePath] -> !Format -> !Text -> !Bool -> !Verbosity -> !LogSink -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Bool -> !Bool -> Configuration
+ Text.Pandoc.Filter.Plot.Internal: Configuration :: !FilePath -> !Bool -> !Int -> !SaveFormat -> ![FilePath] -> !Format -> !Text -> !Bool -> !Verbosity -> !LogSink -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Text -> !Bool -> !Bool -> Configuration

Files

CHANGELOG.md view
@@ -2,6 +2,11 @@  pandoc-plot uses [Semantic Versioning](http://semver.org/spec/v2.0.0.html) +## Release 1.7.0++* Added support for the declarative diagram language [D2](https://d2lang.com/), thanks to a contribution by Sanchayan Maity (#60).+* Added support for `optparse-applicative` v0.18.+ ## Release 1.6.2  * Fixed some imports which were removed in `mtl-2.3`.
README.md view
@@ -71,6 +71,7 @@   - `plotsjl`: plots using the [Julia `Plots.jl`](https://docs.juliaplots.org/latest/) package;   - `plantuml`: diagrams using the [PlantUML](https://plantuml.com/) software suite;   - `sageplot`: plots using the [Sage](https://www.sagemath.org/) software system.+  - `d2`: plots using [D2](https://d2lang.com/).   To know which toolkits are useable on *your machine* (and which ones are not available), you can check with the `toolkits` command:
example-config.yml view
@@ -142,3 +142,7 @@   # preamble: sageplot.sage   executable: sage   command_line_arguments:++d2:+  executable: d2+  command_line_arguments:
executable/Main.hs view
@@ -61,11 +61,11 @@     cls,     configurationPathMeta,     executable,+    pathToExe,     readDoc,     runPlotM,     supportedSaveFormats,-    toolkits, -    pathToExe+    toolkits,   ) import Text.Pandoc.JSON (toJSONFilter) import Text.ParserCombinators.ReadP (readP_to_S)@@ -105,7 +105,13 @@                   ]               )             <> header (mconcat ["pandoc-plot ", V.showVersion pandocPlotVersion, " - generate figures directly in documents"])-            <> footerDoc (Just footer')+            <> footerDoc+              ( Just $+                  P.vsep+                    [ "More information can be found via the manual (pandoc-plot --manual) or the",+                      "repository README, located at https://github.com/LaurentRDC/pandoc-plot"+                    ]+              )         )      optparse = do@@ -286,7 +292,7 @@       putStrLn $ "Toolkit: " <> show tk       when avail $ do         exe <- runPlotM Nothing conf $ executable tk-        putStrLn $ "    Executable: " <> (pathToExe exe)+        putStrLn $ "    Executable: " <> pathToExe exe       putStrLn $ "    Code block trigger: " <> (unpack . cls $ tk)       putStrLn $ "    Supported save formats: " <> (mconcat . intersperse ", " . fmap show $ supportedSaveFormats tk)       putStrLn mempty@@ -318,12 +324,3 @@   manualPath <- (</> "pandoc-plot-manual.html") <$> getTemporaryDirectory   TIO.writeFile manualPath $(embedManualHtml)   openFile ("file:///" <> manualPath)---- | Use Doc type directly because of newline formatting-footer' :: P.Doc-footer' =-  mconcat-    [ P.text "More information can be found via the manual (pandoc-plot --manual) or the",-      P.line,-      P.text "repository README, located at https://github.com/LaurentRDC/pandoc-plot"-    ]
pandoc-plot.cabal view
@@ -1,6 +1,6 @@ cabal-version:  2.2 name:           pandoc-plot-version:        1.6.2+version:        1.7.0 synopsis:       A Pandoc filter to include figures generated from code blocks using your plotting toolkit of choice. description:    A Pandoc filter to include figures generated from code blocks.                  Keep the document and code in the same location. Output is @@ -48,6 +48,8 @@     tests/includes/plotly-r.r     tests/includes/plotsjl.jl     tests/includes/plantuml.txt+    tests/includes/sagemath.sage+    tests/includes/d2-dd.d2  source-repository head     type: git@@ -79,6 +81,7 @@         Text.Pandoc.Filter.Plot.Renderers.Plotsjl         Text.Pandoc.Filter.Plot.Renderers.PlantUML         Text.Pandoc.Filter.Plot.Renderers.SageMath+        Text.Pandoc.Filter.Plot.Renderers.D2         Text.Pandoc.Filter.Plot.Monad         Text.Pandoc.Filter.Plot.Monad.Logging         Text.Pandoc.Filter.Plot.Monad.Types@@ -98,8 +101,8 @@         -Wmissing-export-lists         -Wpartial-fields     build-depends:-          aeson              >= 2     && <3-        , base               >= 4.11  && <5+          aeson              >= 2     && < 3+        , base               >= 4.11  && < 5         , bytestring         , containers         , data-default  @@ -137,11 +140,11 @@         , directory         , filepath         , gitrev                >= 1    && < 2-        , optparse-applicative  >= 0.14 && < 1+        , optparse-applicative  >= 0.14 && < 0.19         , pandoc         , pandoc-plot-        , pandoc-types          >= 1.21 && <2-        , template-haskell      >  2.7 && < 3+        , pandoc-types          >= 1.21 && < 2+        , template-haskell      >  2.7  && < 3         , typed-process         , text     default-language: Haskell2010@@ -151,12 +154,12 @@     hs-source-dirs:  tests     main-is:         Main.hs     other-modules:   Common-    build-depends:   base                 >= 4.11 && < 5+    build-depends:   base                    , containers                    , directory                    , filepath                    , hspec-expectations-                   , pandoc-types         >= 1.20 && <= 2+                   , pandoc-types                    , pandoc-plot                    , tasty                    , tasty-hunit
src/Text/Pandoc/Filter/Plot.hs view
@@ -22,7 +22,7 @@ -- -- @ -- This is a paragraph.--- +-- -- ```{.matlabplot} -- figure() -- plot([1,2,3,4,5], [1,2,3,4,5], '-k')@@ -34,7 +34,7 @@ -- @ -- ```{.gnuplot format=png caption="Sinusoidal function" source=true} -- sin(x)--- +-- -- set xlabel "x" -- set ylabel "y" -- ```@@ -63,8 +63,7 @@ --       code block will be ignored. This path should be specified with respect to the current working --       directory, and not with respect to the document. ----- All attributes are described in the online documentation, linked on the home page. -+-- All attributes are described in the online documentation, linked on the home page. module Text.Pandoc.Filter.Plot   ( -- * Operating on whole Pandoc documents     plotFilter,@@ -106,7 +105,7 @@ import Data.Text (Text, pack, unpack) import Data.Version (Version) import Paths_pandoc_plot (version)-import Text.Pandoc.Definition (Block, Meta (..), Format, MetaValue (..), Pandoc (..))+import Text.Pandoc.Definition (Block, Format, Meta (..), MetaValue (..), Pandoc (..)) import Text.Pandoc.Filter.Plot.Internal   ( Configuration (..),     FigureSpec,@@ -175,7 +174,7 @@ -- on documents without having all necessary toolkits installed. In this case, error -- messages are printed to stderr, and blocks are left unchanged. ----- __Note that this function is DEPRECATED in favour of @plotFilter@. It will be +-- __Note that this function is DEPRECATED in favour of @plotFilter@. It will be -- removed in the next major update (v2+).__ plotTransform ::   -- | Configuration for default values@@ -183,11 +182,12 @@   -- | Input document   Pandoc ->   IO Pandoc-{-# DEPRECATED plotTransform-  [ "plotTransform has been deprecated in favour of plotFilter, which is aware of conversion format."-  , "plotTransform will be removed in an upcoming major update."-  ] -#-}+{-# DEPRECATED+  plotTransform+  [ "plotTransform has been deprecated in favour of plotFilter, which is aware of conversion format.",+    "plotTransform will be removed in an upcoming major update."+  ]+  #-} plotTransform conf = plotFilter conf Nothing  -- | The version of the pandoc-plot package.@@ -197,7 +197,7 @@ pandocPlotVersion = version  -- | Try to process the block with `pandoc-plot`. If a failure happens (or the block)--- was not meant to become a figure, return the block as-is unless running in strict mode. +-- was not meant to become a figure, return the block as-is unless running in strict mode. -- In strict mode, any failure (for example, due to a missing plotting toolkit) will halt execution. -- -- New in version 1.2.0: this function will detect nested code blocks, for example in @Div@ blocks.@@ -208,7 +208,7 @@     onError b e = do       whenStrict $ throwStrictError (pack . show $ e)       return b-    +     whenStrict f = asksConfig strictMode >>= \s -> when s f  -- | Try to process the block with `pandoc-plot`, documenting the error.@@ -239,4 +239,4 @@   show (ScriptRuntimeError _ exitcode) = "ERROR (pandoc-plot) The script failed with exit code " <> show exitcode <> "."   show (ScriptChecksFailedError msg) = "ERROR (pandoc-plot) A script check failed with message: " <> unpack msg <> "."   show (ToolkitNotInstalledError tk) = "ERROR (pandoc-plot) The " <> show tk <> " toolkit is required but not installed."-  show (IncompatibleSaveFormatError tk sv) = "ERROR (pandoc-plot) Save format " <> show sv <> " not supported by the " <> show tk <> " toolkit." +  show (IncompatibleSaveFormatError tk sv) = "ERROR (pandoc-plot) Save format " <> show sv <> " not supported by the " <> show tk <> " toolkit."
src/Text/Pandoc/Filter/Plot/Clean.hs view
@@ -31,9 +31,9 @@ import Text.Pandoc.Class (runIO) import Text.Pandoc.Definition (Block, Pandoc) import Text.Pandoc.Error (handleError)-import Text.Pandoc.Format (FlavoredFormat(..)) import Text.Pandoc.Filter.Plot.Monad import Text.Pandoc.Filter.Plot.Parse+import Text.Pandoc.Format (FlavoredFormat (..)) import qualified Text.Pandoc.Options as P import qualified Text.Pandoc.Readers as P import Text.Pandoc.Walk (Walkable, query)@@ -44,7 +44,7 @@ -- -- The cleaned directories are returned. cleanOutputDirs ::-  Walkable Block b =>+  (Walkable Block b) =>   Configuration ->   b ->   IO [FilePath]@@ -59,7 +59,7 @@  -- | Analyze a document to determine where would the pandoc-plot output directories be. outputDirs ::-  Walkable Block b =>+  (Walkable Block b) =>   b ->   PlotM [FilePath] outputDirs = fmap (nub . catMaybes) . sequence . query (\b -> [hasDirectory <$> parseFigureSpec b])@@ -70,7 +70,7 @@  -- | PlotM version of @cleanOutputDirs@ cleanOutputDirsM ::-  Walkable Block b =>+  (Walkable Block b) =>   b ->   PlotM [FilePath] cleanOutputDirsM doc = do
src/Text/Pandoc/Filter/Plot/Configuration.hs view
@@ -17,8 +17,8 @@   ) where -import Data.Aeson ( (.:?), (.!=), Key, Value(Object, Null), FromJSON(parseJSON) )-import Data.String (IsString(..))+import Data.Aeson (FromJSON (parseJSON), Key, Value (Null, Object), (.!=), (.:?))+import Data.String (IsString (..)) import Data.Text (Text, unpack) import qualified Data.Text.IO as TIO import Data.Yaml.Config (ignoreEnv, loadYamlSettings)@@ -64,6 +64,7 @@       plotsjlPreamble = mempty,       plantumlPreamble = mempty,       sagemathPreamble = mempty,+      d2Preamble = mempty,       -- Executables       matplotlibExe = python,       matlabExe = "matlab",@@ -78,6 +79,7 @@       plotsjlExe = "julia",       plantumlExe = "java",       sagemathExe = "sage",+      d2Exe = "d2",       -- Command line arguments       matplotlibCmdArgs = mempty,       matlabCmdArgs = mempty,@@ -92,6 +94,7 @@       plotsjlCmdArgs = mempty,       plantumlCmdArgs = "-jar plantuml.jar",       sagemathCmdArgs = mempty,+      d2CmdArgs = mempty,       -- Extras       matplotlibTightBBox = False,       matplotlibTransparent = False@@ -151,7 +154,8 @@     _bokehPrec :: !BokehPrecursor,     _plotsjlPrec :: !PlotsjlPrecursor,     _plantumlPrec :: !PlantUMLPrecursor,-    _sagemathPrec :: !SageMathPrecursor+    _sagemathPrec :: !SageMathPrecursor,+    _d2Prec :: !D2Precursor   }  defaultConfigPrecursor :: ConfigPrecursor@@ -178,7 +182,8 @@       _bokehPrec = BokehPrecursor Nothing (bokehExe defaultConfiguration) (bokehCmdArgs defaultConfiguration),       _plotsjlPrec = PlotsjlPrecursor Nothing (plotsjlExe defaultConfiguration) (plotsjlCmdArgs defaultConfiguration),       _plantumlPrec = PlantUMLPrecursor Nothing (plantumlExe defaultConfiguration) (plantumlCmdArgs defaultConfiguration),-      _sagemathPrec = SageMathPrecursor Nothing (sagemathExe defaultConfiguration) (sagemathCmdArgs defaultConfiguration)+      _sagemathPrec = SageMathPrecursor Nothing (sagemathExe defaultConfiguration) (sagemathCmdArgs defaultConfiguration),+      _d2Prec = D2Precursor Nothing (d2Exe defaultConfiguration) (d2CmdArgs defaultConfiguration)     }  data LoggingPrecursor = LoggingPrecursor@@ -219,13 +224,16 @@  data SageMathPrecursor = SageMathPrecursor {_sagemathPreamble :: !(Maybe FilePath), _sagemathExe :: !FilePath, _sagemathCmdArgs :: !Text} +data D2Precursor = D2Precursor {_d2Preamble :: !(Maybe FilePath), _d2Exe :: !FilePath, _d2CmdArgs :: !Text}+ instance FromJSON LoggingPrecursor where   parseJSON (Object v) =-    LoggingPrecursor <$> v .:? "verbosity" .!= logVerbosity defaultConfiguration+    LoggingPrecursor+      <$> v .:? "verbosity" .!= logVerbosity defaultConfiguration       <*> v .:? "filepath"   parseJSON _ = fail $ mconcat ["Could not parse logging configuration. "] -asKey :: InclusionKey -> Key +asKey :: InclusionKey -> Key asKey = fromString . show  instance FromJSON MatplotlibPrecursor where@@ -286,7 +294,11 @@   parseJSON (Object v) = SageMathPrecursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= sagemathExe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= sagemathCmdArgs defaultConfiguration   parseJSON _ = fail $ mconcat ["Could not parse ", show SageMath, " configuration."] -toolkitAsKey :: Toolkit -> Key +instance FromJSON D2Precursor where+  parseJSON (Object v) = D2Precursor <$> v .:? asKey PreambleK <*> v .:? asKey ExecutableK .!= d2Exe defaultConfiguration <*> v .:? asKey CommandLineArgsK .!= d2CmdArgs defaultConfiguration+  parseJSON _ = fail $ mconcat ["Could not parse ", show SageMath, " configuration."]++toolkitAsKey :: Toolkit -> Key toolkitAsKey = fromString . unpack . cls  instance FromJSON ConfigPrecursor where@@ -315,6 +327,7 @@     _plotsjlPrec <- v .:? toolkitAsKey Plotsjl .!= _plotsjlPrec defaultConfigPrecursor     _plantumlPrec <- v .:? toolkitAsKey PlantUML .!= _plantumlPrec defaultConfigPrecursor     _sagemathPrec <- v .:? toolkitAsKey SageMath .!= _sagemathPrec defaultConfigPrecursor+    _d2Prec <- v .:? toolkitAsKey D2 .!= _d2Prec defaultConfigPrecursor      return $ ConfigPrecursor {..}   parseJSON _ = fail "Could not parse configuration."@@ -349,6 +362,7 @@       plotsjlExe = _plotsjlExe _plotsjlPrec       plantumlExe = _plantumlExe _plantumlPrec       sagemathExe = _sagemathExe _sagemathPrec+      d2Exe = _d2Exe _d2Prec        matplotlibCmdArgs = _matplotlibCmdArgs _matplotlibPrec       matlabCmdArgs = _matlabCmdArgs _matlabPrec@@ -363,6 +377,7 @@       plotsjlCmdArgs = _plotsjlCmdArgs _plotsjlPrec       plantumlCmdArgs = _plantumlCmdArgs _plantumlPrec       sagemathCmdArgs = _sagemathCmdArgs _sagemathPrec+      d2CmdArgs = _d2CmdArgs _d2Prec    matplotlibPreamble <- readPreamble (_matplotlibPreamble _matplotlibPrec)   matlabPreamble <- readPreamble (_matlabPreamble _matlabPrec)@@ -377,8 +392,8 @@   plotsjlPreamble <- readPreamble (_plotsjlPreamble _plotsjlPrec)   plantumlPreamble <- readPreamble (_plantumlPreamble _plantumlPrec)   sagemathPreamble <- readPreamble (_sagemathPreamble _sagemathPrec)+  d2Preamble <- readPreamble (_d2Preamble _d2Prec)    return Configuration {..}   where     readPreamble = maybe mempty TIO.readFile-
src/Text/Pandoc/Filter/Plot/Embed.hs view
@@ -32,15 +32,15 @@   ) import Text.Pandoc.Builder as Builder   ( Inlines,-    fromList,     figureWith,+    fromList,     imageWith,-    plain,     link,-    str,+    plain,     simpleCaption,+    str,     toList,-  ) +  ) import Text.Pandoc.Class (runPure) import Text.Pandoc.Definition (Attr, Block (..), Format, Pandoc (..)) import Text.Pandoc.Error (handleError)@@ -84,7 +84,9 @@   return . head . toList $     -- We want the attributes both on the Figure element and the contained Image element     -- so that pandoc-plot plays nice with pandoc-crossref and other filters-    figureWith as (simpleCaption (plain caption')) $ plain $ imageWith mempty (pack fp) mempty caption'+    figureWith as (simpleCaption (plain caption')) $+      plain $+        imageWith mempty (pack fp) mempty caption'  -- TODO: also add the case where SVG plots can be --       embedded in HTML output@@ -172,11 +174,11 @@ extractPlot t =   let tags = canonicalizeTags $ parseTagsOptions parseOptionsFast t       extracted = headScripts tags <> [inside "body" tags]-      -- In the past (e.g. commit 8417b011ccb20263427822c7447840ab4a30a41e), we used to-      -- make all JS scripts 'deferred'. This turned out to be problematic for plotly +   in -- In the past (e.g. commit 8417b011ccb20263427822c7447840ab4a30a41e), we used to+      -- make all JS scripts 'deferred'. This turned out to be problematic for plotly       -- specifically (see issue #39). In the future, we may want to defer scripts for       -- certain toolkits, but that's a testing nightmare...-   in mconcat $ renderTags <$> extracted+      mconcat $ renderTags <$> extracted   where     headScripts = partitions (~== ("<script>" :: String)) . inside "head" 
src/Text/Pandoc/Filter/Plot/Monad.hs view
@@ -149,7 +149,7 @@     \logger -> runReaderT (evalStateT v st) (RuntimeEnv fmt conf logger cwd sem)  -- | maps a function, performing at most @N@ actions concurrently.-mapConcurrentlyN :: Traversable t => Int -> (a -> PlotM b) -> t a -> PlotM (t b)+mapConcurrentlyN :: (Traversable t) => Int -> (a -> PlotM b) -> t a -> PlotM (t b) mapConcurrentlyN n f xs = do   -- Emulating a pool of processes with locked access   sem <- liftIO $ newQSemN n@@ -282,6 +282,7 @@     exeSelector Plotsjl = asksConfig plotsjlExe     exeSelector PlantUML = asksConfig plantumlExe     exeSelector SageMath = asksConfig sagemathExe+    exeSelector D2 = asksConfig d2Exe  -- | The @Configuration@ type holds the default values to use -- when running pandoc-plot. These values can be overridden in code blocks.@@ -350,6 +351,8 @@     plantumlPreamble :: !Script,     -- | The default preamble script for the SageMath toolkit.     sagemathPreamble :: !Script,+    -- | The default preamble script for the d2 toolkit.+    d2Preamble :: !Script,     -- | The executable to use to generate figures using the matplotlib toolkit.     matplotlibExe :: !FilePath,     -- | The executable to use to generate figures using the MATLAB toolkit.@@ -376,6 +379,8 @@     plantumlExe :: !FilePath,     -- | The executable to use to generate figures using SageMath.     sagemathExe :: !FilePath,+    -- | The executable to use to generate figures using d2.+    d2Exe :: !FilePath,     -- | Command-line arguments to pass to the Python interpreter for the Matplotlib toolkit     matplotlibCmdArgs :: !Text,     -- | Command-line arguments to pass to the interpreter for the MATLAB toolkit.@@ -402,6 +407,8 @@     plantumlCmdArgs :: !Text,     -- | Command-line arguments to pass to the interpreter for the SageMath toolkit.     sagemathCmdArgs :: !Text,+    -- | Command-line arguments to pass to the interpreter for the d2 toolkit.+    d2CmdArgs :: !Text,     -- | Whether or not to make Matplotlib figures tight by default.     matplotlibTightBBox :: !Bool,     -- | Whether or not to make Matplotlib figures transparent by default.
src/Text/Pandoc/Filter/Plot/Monad/Logging.hs view
@@ -76,7 +76,7 @@   = LogMessage Text   | EndLogging -class Monad m => MonadLogger m where+class (Monad m) => MonadLogger m where   askLogger :: m Logger  -- | Ensure that all log messages are flushed, and stop logging
src/Text/Pandoc/Filter/Plot/Monad/Types.hs view
@@ -13,7 +13,7 @@ module Text.Pandoc.Filter.Plot.Monad.Types   ( Toolkit (..),     Renderer (..),-    AvailabilityCheck(..),+    AvailabilityCheck (..),     Script,     CheckResult (..),     InclusionKey (..),@@ -36,9 +36,9 @@ import Data.List (intersperse) import Data.String (IsString (..)) import Data.Text (Text, pack, unpack)-import Data.Yaml (FromJSON(..), ToJSON (toJSON), withText)+import Data.Yaml (FromJSON (..), ToJSON (toJSON), withText) import GHC.Generics (Generic)-import System.FilePath (splitFileName, (</>), isAbsolute)+import System.FilePath (isAbsolute, splitFileName, (</>)) import System.Info (os) import Text.Pandoc.Definition (Attr) @@ -61,6 +61,7 @@   | Plotsjl   | PlantUML   | SageMath+  | D2   deriving (Bounded, Eq, Enum, Generic, Ord)  -- | This instance should only be used to display toolkit names@@ -78,6 +79,7 @@   show Plotsjl = "Julia/Plots.jl"   show PlantUML = "PlantUML"   show SageMath = "SageMath"+  show D2 = "D2"  -- | Class name which will trigger the filter cls :: Toolkit -> Text@@ -94,21 +96,23 @@ cls Plotsjl = "plotsjl" cls PlantUML = "plantuml" cls SageMath = "sageplot"+cls D2 = "d2"  -- | Executable program, and sometimes the directory where it can be found.-data Executable +data Executable   = AbsExe FilePath Text   | RelExe Text  exeFromPath :: FilePath -> Executable exeFromPath fp-  | isAbsolute fp = let (dir, name) = splitFileName fp-                     in AbsExe dir (pack name)-  | otherwise     = RelExe (pack fp) +  | isAbsolute fp =+      let (dir, name) = splitFileName fp+       in AbsExe dir (pack name)+  | otherwise = RelExe (pack fp)  pathToExe :: Executable -> FilePath-pathToExe (AbsExe dir name) = dir </> unpack name -pathToExe (RelExe name)            = unpack name+pathToExe (AbsExe dir name) = dir </> unpack name+pathToExe (RelExe name) = unpack name  -- | Source context for plotting scripts type Script = Text@@ -238,13 +242,13 @@     | s `elem` ["html", "HTML", ".html"] = HTML     | s `elem` ["latex", "LaTeX", ".tex"] = LaTeX     | otherwise =-      errorWithoutStackTrace $-        mconcat-          [ s,-            " is not one of the valid save formats : ",-            mconcat $ intersperse ", " $ show <$> saveFormats,-            " (and lowercase variations). "-          ]+        errorWithoutStackTrace $+          mconcat+            [ s,+              " is not one of the valid save formats : ",+              mconcat $ intersperse ", " $ show <$> saveFormats,+              " (and lowercase variations). "+            ]     where       saveFormats = enumFromTo minBound maxBound :: [SaveFormat] 
src/Text/Pandoc/Filter/Plot/Parse.hs view
@@ -39,25 +39,25 @@     Inline,     Pandoc (..),   )-import Text.Pandoc.Format (parseFlavoredFormat) import Text.Pandoc.Filter.Plot.Monad import Text.Pandoc.Filter.Plot.Renderers+import Text.Pandoc.Format (parseFlavoredFormat) import Text.Pandoc.Options (ReaderOptions (..)) import Text.Pandoc.Readers (Reader (..), getReader) -tshow :: Show a => a -> Text+tshow :: (Show a) => a -> Text tshow = pack . show  data ParseFigureResult-  -- | The block is not meant to become a figure-  = NotAFigure-  -- | The block is meant to become a figure-  | PFigure FigureSpec-  -- | The block is meant to become a figure, but the plotting toolkit is missing-  | MissingToolkit Toolkit-  -- | The block is meant to become a figure, but the figure format is incompatible -  --   with the plotting toolkit-  | UnsupportedSaveFormat Toolkit SaveFormat+  = -- | The block is not meant to become a figure+    NotAFigure+  | -- | The block is meant to become a figure+    PFigure FigureSpec+  | -- | The block is meant to become a figure, but the plotting toolkit is missing+    MissingToolkit Toolkit+  | -- | The block is meant to become a figure, but the figure format is incompatible+    --   with the plotting toolkit+    UnsupportedSaveFormat Toolkit SaveFormat  -- | Determine inclusion specifications from @Block@ attributes. -- If an environment is detected, but the save format is incompatible,@@ -105,7 +105,7 @@            -- Decide between reading from file or using document content           content <- parseContent block-          +           defaultExe <- executable rendererToolkit            let caption = Map.findWithDefault mempty (tshow CaptionK) attrs'@@ -124,8 +124,8 @@           _' <-             unless (saveFormat `elem` rendererSupportedSaveFormats) $               let msg = pack $ mconcat ["Save format ", show saveFormat, " not supported by ", show toolkit]-              in err msg-          +               in err msg+           -- Ensure that the save format makes sense given the final conversion format, if known           return $ PFigure (FigureSpec {..}) -- Base case: block is not a CodeBlock@@ -190,7 +190,7 @@ parseFileDependencies t   | t == mempty = mempty   | otherwise =-    fmap (normalise . unpack . T.dropAround isSpace)-      . T.splitOn ","-      . T.dropAround (\c -> c `elem` ['[', ']'])-      $ t+      fmap (normalise . unpack . T.dropAround isSpace)+        . T.splitOn ","+        . T.dropAround (\c -> c `elem` ['[', ']'])+        $ t
src/Text/Pandoc/Filter/Plot/Renderers.hs view
@@ -33,38 +33,68 @@ import qualified Data.Map.Strict as M import Data.Maybe (catMaybes, isJust) import Data.Text (Text, pack)+import System.Directory (findExecutable) 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 )+  ( bokeh,+    bokehSupportedSaveFormats,+  )+import Text.Pandoc.Filter.Plot.Renderers.D2+  ( d2,+    d2SupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.GGPlot2-    ( ggplot2, ggplot2SupportedSaveFormats )+  ( ggplot2,+    ggplot2SupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.GNUPlot-    ( gnuplot, gnuplotSupportedSaveFormats )+  ( gnuplot,+    gnuplotSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Graphviz-    ( graphviz, graphvizSupportedSaveFormats )+  ( graphviz,+    graphvizSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Mathematica-    ( mathematica, mathematicaSupportedSaveFormats )+  ( mathematica,+    mathematicaSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Matlab-    ( matlab, matlabSupportedSaveFormats )+  ( matlab,+    matlabSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Matplotlib-    ( matplotlib, matplotlibSupportedSaveFormats )+  ( matplotlib,+    matplotlibSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Octave-    ( octave, octaveSupportedSaveFormats )+  ( octave,+    octaveSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.PlantUML-    ( plantuml, plantumlSupportedSaveFormats )+  ( plantuml,+    plantumlSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.PlotlyPython-    ( plotlyPython, plotlyPythonSupportedSaveFormats )+  ( plotlyPython,+    plotlyPythonSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.PlotlyR-    ( plotlyR, plotlyRSupportedSaveFormats )+  ( plotlyR,+    plotlyRSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.Plotsjl-    ( plotsjl, plotsjlSupportedSaveFormats )+  ( plotsjl,+    plotsjlSupportedSaveFormats,+  ) import Text.Pandoc.Filter.Plot.Renderers.SageMath-    ( sagemath, sagemathSupportedSaveFormats )-import System.Directory (findExecutable)+  ( sagemath,+    sagemathSupportedSaveFormats,+  )  -- | Get the renderer associated with a toolkit. -- If the renderer has not been used before,@@ -83,6 +113,7 @@ renderer Plotsjl = plotsjl renderer PlantUML = plantuml renderer SageMath = sagemath+renderer D2 = d2  -- | Save formats supported by this renderer. supportedSaveFormats :: Toolkit -> [SaveFormat]@@ -99,6 +130,7 @@ supportedSaveFormats Plotsjl = plotsjlSupportedSaveFormats supportedSaveFormats PlantUML = plantumlSupportedSaveFormats supportedSaveFormats SageMath = sagemathSupportedSaveFormats+supportedSaveFormats D2 = d2SupportedSaveFormats  -- | The function that maps from configuration to the preamble. preambleSelector :: Toolkit -> (Configuration -> Script)@@ -115,13 +147,19 @@ preambleSelector Plotsjl = plotsjlPreamble preambleSelector PlantUML = plantumlPreamble preambleSelector SageMath = sagemathPreamble+preambleSelector D2 = d2Preamble  -- | 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` [ pack $ show MatplotlibTightBBoxK-                                                               , pack $ show MatplotlibTransparentK-                                                               ])+parseExtraAttrs Matplotlib =+  M.filterWithKey+    ( \k _ ->+        k+          `elem` [ pack $ show MatplotlibTightBBoxK,+                   pack $ show MatplotlibTransparentK+                 ]+    ) parseExtraAttrs _ = return mempty  -- | List of toolkits available on this machine.@@ -139,22 +177,22 @@ -- 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+  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 s) -> RuntimeEnv f (c{strictMode = False}) (l{lVerbosity = Silent}) d s)+    asNonStrictAndSilent = local (\(RuntimeEnv f c l d s) -> RuntimeEnv f (c {strictMode = False}) (l {lVerbosity = Silent}) d s) -    -- | Check that the supplied command results in+    -- \| 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 +      cwd <- asks envCWD       (ec, _) <- runCommand cwd s       debug $ mconcat ["Command ", s, " resulted in ", pack $ show ec]       return $ ec == ExitSuccess
src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs view
@@ -24,19 +24,19 @@  bokeh :: PlotM Renderer bokeh = do-      cmdargs <- asksConfig bokehCmdArgs-      return $-        Renderer-          { rendererToolkit = Bokeh,-            rendererCapture = appendCapture bokehCaptureFragment,-            rendererCommand = bokehCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import bokeh; import selenium"|],-            rendererSupportedSaveFormats = bokehSupportedSaveFormats,-            rendererChecks = [bokehCheckIfShow],-            rendererLanguage = "python",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".py"-          }+  cmdargs <- asksConfig bokehCmdArgs+  return+    $ Renderer+      { rendererToolkit = Bokeh,+        rendererCapture = appendCapture bokehCaptureFragment,+        rendererCommand = bokehCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import bokeh; import selenium"|],+        rendererSupportedSaveFormats = bokehSupportedSaveFormats,+        rendererChecks = [bokehCheckIfShow],+        rendererLanguage = "python",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".py"+      }  bokehSupportedSaveFormats :: [SaveFormat] bokehSupportedSaveFormats = [PNG, SVG, HTML]
+ src/Text/Pandoc/Filter/Plot/Renderers/D2.hs view
@@ -0,0 +1,48 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE NoImplicitPrelude #-}++-- |+-- Module      : $header$+-- Copyright   : (c) Sanchayan Maity, 2023 - present+-- License     : GNU GPL, version 2 or above+-- Maintainer  : sanchayan@sanchayanmaity.net+-- Stability   : internal+-- Portability : portable+--+-- Rendering D2 plots code blocks+module Text.Pandoc.Filter.Plot.Renderers.D2+  ( d2,+    d2SupportedSaveFormats,+  )+where++import Text.Pandoc.Filter.Plot.Renderers.Prelude++d2 :: PlotM Renderer+d2 = do+  cmdargs <- asksConfig d2CmdArgs+  return+    $ Renderer+      { rendererToolkit = D2,+        rendererCapture = d2Capture,+        rendererCommand = d2Command cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -v|],+        rendererSupportedSaveFormats = d2SupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "d2",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".d2"+      }++d2SupportedSaveFormats :: [SaveFormat]+d2SupportedSaveFormats = [PNG, PDF, SVG]++d2Command :: Text -> OutputSpec -> Text+d2Command cmdargs OutputSpec {..} = [st|#{pathToExe oExecutable} #{cmdargs} "#{oScriptPath}" "#{oFigurePath}"|]++-- d2 export is entirely based on command-line arguments+-- so there is no need to modify the script itself.+d2Capture :: FigureSpec -> FilePath -> Script+d2Capture FigureSpec {..} _ = script
src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs view
@@ -23,19 +23,19 @@  ggplot2 :: PlotM Renderer ggplot2 = do-      cmdargs <- asksConfig ggplot2CmdArgs-      return $-        Renderer-          { rendererToolkit = GGPlot2,-            rendererCapture = ggplot2Capture,-            rendererCommand = ggplot2Command cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "if(!require('ggplot2')) {quit(status=1)}"|],-            rendererSupportedSaveFormats = ggplot2SupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "r",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".r"-          }+  cmdargs <- asksConfig ggplot2CmdArgs+  return+    $ Renderer+      { rendererToolkit = GGPlot2,+        rendererCapture = ggplot2Capture,+        rendererCommand = ggplot2Command cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "if(!require('ggplot2')) {quit(status=1)}"|],+        rendererSupportedSaveFormats = ggplot2SupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "r",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".r"+      }  ggplot2SupportedSaveFormats :: [SaveFormat] ggplot2SupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, TIF]
src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs view
@@ -22,19 +22,19 @@  gnuplot :: PlotM Renderer gnuplot = do-      cmdargs <- asksConfig gnuplotCmdArgs-      return $-        Renderer-          { rendererToolkit = GNUPlot,-            rendererCapture = gnuplotCapture,-            rendererCommand = gnuplotCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|],-            rendererSupportedSaveFormats = gnuplotSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "gnuplot",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".gp"-          }+  cmdargs <- asksConfig gnuplotCmdArgs+  return+    $ Renderer+      { rendererToolkit = GNUPlot,+        rendererCapture = gnuplotCapture,+        rendererCommand = gnuplotCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|],+        rendererSupportedSaveFormats = gnuplotSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "gnuplot",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".gp"+      }  gnuplotSupportedSaveFormats :: [SaveFormat] gnuplotSupportedSaveFormats = [LaTeX, PNG, SVG, EPS, GIF, JPG, PDF]
src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs view
@@ -23,19 +23,19 @@  graphviz :: PlotM Renderer graphviz = do-      cmdargs <- asksConfig graphvizCmdArgs-      return $-        Renderer-          { rendererToolkit = Graphviz,-            rendererCapture = graphvizCapture,-            rendererCommand = graphvizCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -?|],-            rendererSupportedSaveFormats = graphvizSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "dot",-            rendererComment = mappend "// ",-            rendererScriptExtension = ".dot"-          }+  cmdargs <- asksConfig graphvizCmdArgs+  return+    $ Renderer+      { rendererToolkit = Graphviz,+        rendererCapture = graphvizCapture,+        rendererCommand = graphvizCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -?|],+        rendererSupportedSaveFormats = graphvizSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "dot",+        rendererComment = mappend "// ",+        rendererScriptExtension = ".dot"+      }  graphvizSupportedSaveFormats :: [SaveFormat] graphvizSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, WEBP, GIF]
src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs view
@@ -22,19 +22,20 @@  mathematica :: PlotM Renderer mathematica = do-      cmdargs <- asksConfig mathematicaCmdArgs-      return $-        Renderer-          { rendererToolkit = Mathematica,-            rendererCapture = mathematicaCapture,-            rendererCommand = mathematicaCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|], -- TODO: test this-            rendererSupportedSaveFormats = mathematicaSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "mathematica",-            rendererComment = \t -> mconcat ["(*", t, "*)"],-            rendererScriptExtension = ".m"-          }+  cmdargs <- asksConfig mathematicaCmdArgs+  return+    $ Renderer+      { rendererToolkit = Mathematica,+        rendererCapture = mathematicaCapture,+        rendererCommand = mathematicaCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|],+        -- TODO: test this+        rendererSupportedSaveFormats = mathematicaSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "mathematica",+        rendererComment = \t -> mconcat ["(*", t, "*)"],+        rendererScriptExtension = ".m"+      }  mathematicaSupportedSaveFormats :: [SaveFormat] mathematicaSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs view
@@ -22,32 +22,32 @@  matlab :: PlotM Renderer matlab = do-      cmdargs <- asksConfig matlabCmdArgs-      return $-        Renderer-          { rendererToolkit = Matlab,-            rendererCapture = matlabCapture,-            rendererCommand = matlabCommand cmdargs,-            -- On Windows at least, "matlab -help"  actually returns -1, even though the-            -- help text is shown successfully!-            -- Therefore, we cannot rely on this behavior to know if matlab is present,-            -- like other toolkits.-            rendererAvailability = ExecutableExists,-            rendererSupportedSaveFormats = matlabSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "matlab",-            rendererComment = mappend "% ",-            rendererScriptExtension = ".m"-          }+  cmdargs <- asksConfig matlabCmdArgs+  return+    $ Renderer+      { rendererToolkit = Matlab,+        rendererCapture = matlabCapture,+        rendererCommand = matlabCommand cmdargs,+        -- On Windows at least, "matlab -help"  actually returns -1, even though the+        -- help text is shown successfully!+        -- Therefore, we cannot rely on this behavior to know if matlab is present,+        -- like other toolkits.+        rendererAvailability = ExecutableExists,+        rendererSupportedSaveFormats = matlabSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "matlab",+        rendererComment = mappend "% ",+        rendererScriptExtension = ".m"+      }  matlabSupportedSaveFormats :: [SaveFormat] matlabSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF] -matlabCommand :: Text  -> OutputSpec -> Text-matlabCommand cmdargs OutputSpec {..} = +matlabCommand :: Text -> OutputSpec -> Text+matlabCommand cmdargs OutputSpec {..} =   -- The MATLAB 'run' function will switch to the directory where the script   -- is located before executing the script. Therefore, we first save the current-  -- working directory in the variable 'pandoc_plot_cwd' so that we can use it +  -- working directory in the variable 'pandoc_plot_cwd' so that we can use it   -- when exporting the figure   [st|#{pathToExe oExecutable} #{cmdargs} -sd '#{oCWD}' -noFigureWindows -batch "pandoc_plot_cwd=pwd; run('#{oScriptPath}')"|] 
src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs view
@@ -29,19 +29,19 @@  matplotlib :: PlotM Renderer matplotlib = do-      cmdargs <- asksConfig matplotlibCmdArgs-      return $-        Renderer-          { rendererToolkit = Matplotlib,-            rendererCapture = matplotlibCapture,-            rendererCommand = matplotlibCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import matplotlib"|],-            rendererSupportedSaveFormats = matplotlibSupportedSaveFormats,-            rendererChecks = [matplotlibCheckIfShow],-            rendererLanguage = "python",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".py"-          }+  cmdargs <- asksConfig matplotlibCmdArgs+  return+    $ Renderer+      { rendererToolkit = Matplotlib,+        rendererCapture = matplotlibCapture,+        rendererCommand = matplotlibCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import matplotlib"|],+        rendererSupportedSaveFormats = matplotlibSupportedSaveFormats,+        rendererChecks = [matplotlibCheckIfShow],+        rendererLanguage = "python",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".py"+      }  matplotlibSupportedSaveFormats :: [SaveFormat] matplotlibSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs view
@@ -22,19 +22,19 @@  octave :: PlotM Renderer octave = do-      cmdargs <- asksConfig octaveCmdArgs-      return $-        Renderer-          { rendererToolkit = Octave,-            rendererCapture = octaveCapture,-            rendererCommand = octaveCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|],-            rendererSupportedSaveFormats = octaveSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "matlab",-            rendererComment = mappend "% ",-            rendererScriptExtension = ".m"-          }+  cmdargs <- asksConfig octaveCmdArgs+  return+    $ Renderer+      { rendererToolkit = Octave,+        rendererCapture = octaveCapture,+        rendererCommand = octaveCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -h|],+        rendererSupportedSaveFormats = octaveSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "matlab",+        rendererComment = mappend "% ",+        rendererScriptExtension = ".m"+      }  octaveSupportedSaveFormats :: [SaveFormat] octaveSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
src/Text/Pandoc/Filter/Plot/Renderers/PlantUML.hs view
@@ -24,19 +24,19 @@  plantuml :: PlotM Renderer plantuml = do-      cmdargs <- asksConfig plantumlCmdArgs-      return $-        Renderer-          { rendererToolkit = PlantUML,-            rendererCapture = plantumlCapture,-            rendererCommand = plantumlCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} #{cmdargs} -h|],-            rendererSupportedSaveFormats = plantumlSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "plantuml",-            rendererComment = mappend "' ",-            rendererScriptExtension = ".txt"-          }+  cmdargs <- asksConfig plantumlCmdArgs+  return+    $ Renderer+      { rendererToolkit = PlantUML,+        rendererCapture = plantumlCapture,+        rendererCommand = plantumlCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} #{cmdargs} -h|],+        rendererSupportedSaveFormats = plantumlSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "plantuml",+        rendererComment = mappend "' ",+        rendererScriptExtension = ".txt"+      }  plantumlSupportedSaveFormats :: [SaveFormat] plantumlSupportedSaveFormats = [PNG, PDF, SVG]@@ -45,10 +45,10 @@ plantumlCommand cmdargs OutputSpec {..} =   let fmt = fmap toLower . show . saveFormat $ oFigureSpec       dir = takeDirectory oFigurePath-    -- the command below works as long as the script name is the same basename-    -- as the target figure path. E.g.: script basename of pandocplot123456789.txt-    -- will result in pandocplot123456789.(extension)-   in [st|#{pathToExe oExecutable} #{cmdargs} -t#{fmt} -output "#{oCWD </> dir}" "#{normalizePath oScriptPath}"|]+   in -- the command below works as long as the script name is the same basename+      -- as the target figure path. E.g.: script basename of pandocplot123456789.txt+      -- will result in pandocplot123456789.(extension)+      [st|#{pathToExe oExecutable} #{cmdargs} -t#{fmt} -output "#{oCWD </> dir}" "#{normalizePath oScriptPath}"|]  normalizePath :: String -> String normalizePath = map f
src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs view
@@ -22,19 +22,19 @@  plotlyPython :: PlotM Renderer plotlyPython = do-      cmdargs <- asksConfig plotlyPythonCmdArgs-      return $-            Renderer-              { rendererToolkit = PlotlyPython,-                rendererCapture = plotlyPythonCapture,-                rendererCommand = plotlyPythonCommand cmdargs,-                rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import plotly.graph_objects"|],-                rendererSupportedSaveFormats = plotlyPythonSupportedSaveFormats,-                rendererChecks = mempty,-                rendererLanguage = "python",-                rendererComment = mappend "# ",-                rendererScriptExtension = ".py"-              }+  cmdargs <- asksConfig plotlyPythonCmdArgs+  return+    $ Renderer+      { rendererToolkit = PlotlyPython,+        rendererCapture = plotlyPythonCapture,+        rendererCommand = plotlyPythonCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -c "import plotly.graph_objects"|],+        rendererSupportedSaveFormats = plotlyPythonSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "python",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".py"+      }  plotlyPythonSupportedSaveFormats :: [SaveFormat] plotlyPythonSupportedSaveFormats = [PNG, JPG, WEBP, PDF, SVG, EPS, HTML]
src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs view
@@ -23,19 +23,19 @@  plotlyR :: PlotM Renderer plotlyR = do-      cmdargs <- asksConfig plotlyRCmdArgs-      return $-        Renderer-          { rendererToolkit = PlotlyR,-            rendererCapture = plotlyRCapture,-            rendererCommand = plotlyRCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "if(!require('plotly')) {quit(status=1)}"|],-            rendererSupportedSaveFormats = plotlyRSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "r",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".r"-          }+  cmdargs <- asksConfig plotlyRCmdArgs+  return+    $ Renderer+      { rendererToolkit = PlotlyR,+        rendererCapture = plotlyRCapture,+        rendererCommand = plotlyRCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "if(!require('plotly')) {quit(status=1)}"|],+        rendererSupportedSaveFormats = plotlyRSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "r",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".r"+      }  plotlyRSupportedSaveFormats :: [SaveFormat] plotlyRSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, HTML]
src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs view
@@ -22,26 +22,26 @@  plotsjl :: PlotM Renderer plotsjl = do-      cmdargs <- asksConfig plotsjlCmdArgs-      return $-        Renderer-          { rendererToolkit = Plotsjl,-            rendererCapture = plotsjlCapture,-            rendererCommand = plotsjlCommand cmdargs,-            rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "using Plots"|],-            rendererSupportedSaveFormats = plotsjlSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "julia",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".jl"-          }+  cmdargs <- asksConfig plotsjlCmdArgs+  return+    $ Renderer+      { rendererToolkit = Plotsjl,+        rendererCapture = plotsjlCapture,+        rendererCommand = plotsjlCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -e "using Plots"|],+        rendererSupportedSaveFormats = plotsjlSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "julia",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".jl"+      }  -- Save formats support by most backends -- https://docs.plotsjl.org/latest/output/#Supported-output-file-formats-1 plotsjlSupportedSaveFormats :: [SaveFormat] plotsjlSupportedSaveFormats = [PNG, SVG, PDF] -plotsjlCommand :: Text ->  OutputSpec -> Text+plotsjlCommand :: Text -> OutputSpec -> Text plotsjlCommand cmdargs OutputSpec {..} = [st|#{pathToExe oExecutable} #{cmdargs} -- "#{oScriptPath}"|]  plotsjlCapture :: FigureSpec -> FilePath -> Script
src/Text/Pandoc/Filter/Plot/Renderers/SageMath.hs view
@@ -22,19 +22,19 @@  sagemath :: PlotM Renderer sagemath = do-      cmdargs <- asksConfig sagemathCmdArgs-      return $-        Renderer-          { rendererToolkit = SageMath,-            rendererCapture = sagemathCapture,-            rendererCommand = sagemathCommand cmdargs,-            rendererAvailability = CommandSuccess  $ \exe -> [st|#{pathToExe exe} -v|],-            rendererSupportedSaveFormats = sagemathSupportedSaveFormats,-            rendererChecks = mempty,-            rendererLanguage = "sagemath",-            rendererComment = mappend "# ",-            rendererScriptExtension = ".sage"-          }+  cmdargs <- asksConfig sagemathCmdArgs+  return+    $ Renderer+      { rendererToolkit = SageMath,+        rendererCapture = sagemathCapture,+        rendererCommand = sagemathCommand cmdargs,+        rendererAvailability = CommandSuccess $ \exe -> [st|#{pathToExe exe} -v|],+        rendererSupportedSaveFormats = sagemathSupportedSaveFormats,+        rendererChecks = mempty,+        rendererLanguage = "sagemath",+        rendererComment = mappend "# ",+        rendererScriptExtension = ".sage"+      }  -- See here: -- https://doc.sagemath.org/html/en/reference/plotting/sage/plot/graphics.html#sage.plot.graphics.Graphics.save
src/Text/Pandoc/Filter/Plot/Scripting.hs view
@@ -38,9 +38,9 @@   ( addExtension,     normalise,     replaceExtension,-    takeDirectory,-    (</>),      takeBaseName,+    takeDirectory,+    (</>),   ) import Text.Pandoc.Class (runPure) import Text.Pandoc.Definition (Block (CodeBlock), Pandoc (Pandoc))@@ -116,7 +116,7 @@       let scriptWithCapture = rendererCapture renderer_ spec target        -- Note the use of a lock. This is a crude solution for issue #53, where-      -- multiple identical figures can cause a race condition to write to the +      -- multiple identical figures can cause a race condition to write to the       -- same output file.       sem <- asks envIOLock       liftIO $ withMVar sem $ \_ -> T.writeFile scriptPath scriptWithCapture@@ -188,7 +188,7 @@   fh <- figureContentHash spec   let ext = extension . saveFormat $ spec       -- MATLAB will refuse to process files that don't start with-      -- a letter so it is simplest to use filenames that start +      -- a letter so it is simplest to use filenames that start       -- with "pandocplot" throughout       stem = flip addExtension ext . mappend "pandocplot" . show $ fh   return $ normalise $ directory spec </> stem@@ -205,9 +205,9 @@             -- Note that making the document self-contained is absolutely required so that the CSS for             -- syntax highlighting is included directly in the document.             t = either (const mempty) id $ runPure (writeHtml5String opts doc >>= makeSelfContained)-        +         -- Note the use of a lock. This is a crude solution for issue #53, where-        -- multiple identical figures can cause a race condition to write to the +        -- multiple identical figures can cause a race condition to write to the         -- same output file.         sem <- asks envIOLock         liftIO $ withMVar sem $ \_ -> T.writeFile scp t
tests/Common.hs view
@@ -98,7 +98,8 @@      let cb =           ( addPreamble (include tk) $-              addDirectory tempDir $ codeBlock tk (trivialContent tk)+              addDirectory tempDir $+                codeBlock tk (trivialContent tk)           )     _ <- runPlotM Nothing defaultTestConfig $ make cb     inclusion <- readFile (include tk)@@ -119,6 +120,7 @@     include Plotsjl = "tests/includes/plotsjl.jl"     include PlantUML = "tests/includes/plantuml.txt"     include SageMath = "tests/includes/sagemath.sage"+    include D2 = "tests/includes/d2-dd.d2"  ------------------------------------------------------------------------------- -- Test that the files are saved in the appropriate format@@ -131,11 +133,13 @@     let fmt = head (supportedSaveFormats tk)         cb =           ( addSaveFormat fmt $-              addDirectory tempDir $ codeBlock tk (trivialContent tk)+              addDirectory tempDir $+                codeBlock tk (trivialContent tk)           )     _ <- runPlotM Nothing defaultTestConfig $ make cb     numberjpgFiles <--      length <$> filter (isExtensionOf (extension fmt))+      length+        <$> filter (isExtensionOf (extension fmt))         <$> listDirectory tempDir     assertEqual "" numberjpgFiles 1 @@ -143,7 +147,7 @@ -- Test that the appropriate error is raised when trying to save figures -- in an incompatible format testSaveFormatIncompatibility :: Toolkit -> TestTree-testSaveFormatIncompatibility tk = +testSaveFormatIncompatibility tk =   testCase "raises the appropriate error on save format incompatibility" $ do     let allSaveFormats = enumFromTo minBound maxBound :: [SaveFormat]         incompatibleFormats = S.toList $ S.difference (S.fromList allSaveFormats) (S.fromList $ supportedSaveFormats tk)@@ -179,16 +183,16 @@             addDirectory tempDir $               addCaption expected $                 codeBlock tk (trivialContent tk)-    blockNoSource   <- runPlotM Nothing defaultTestConfig $ make noSource+    blockNoSource <- runPlotM Nothing defaultTestConfig $ make noSource     blockWithSource <- runPlotM Nothing defaultTestConfig $ make withSource      -- In the case where source=false, the caption is used verbatim.     -- Otherwise, links will be appended to the caption; hence, the caption     -- is no longer equal to the initial value-    assertEqual    "" [B.Plain $ B.toList (fromString expected)] (extractCaption blockNoSource)+    assertEqual "" [B.Plain $ B.toList (fromString expected)] (extractCaption blockNoSource)     assertNotEqual "" [B.Plain $ B.toList (fromString expected)] (extractCaption blockWithSource)   where-    extractCaption (B.Figure _ (Caption _ caption) _) = caption +    extractCaption (B.Figure _ (Caption _ caption) _) = caption  ------------------------------------------------------------------------------- -- Test that it is possible to change the source code label in captions@@ -211,7 +215,7 @@     let [Plain [Space, _, B.Link _ ils _, _]] = extractCaption blockWithSource     assertEqual "" (B.toList $ B.str "Test label") ils   where-    extractCaption (B.Figure _ (Caption _ caption) _) = caption +    extractCaption (B.Figure _ (Caption _ caption) _) = caption      linkLabel (B.Plain [B.Link _ ils _]) = B.fromList ils     linkLabel _ = mempty@@ -248,10 +252,12 @@         _ <- runPlotM Nothing config $ make cb          numberPngFiles <--          length <$> filter (isExtensionOf (extension PNG))+          length+            <$> filter (isExtensionOf (extension PNG))             <$> listDirectory (defaultDirectory config)         numberJpgFiles <--          length <$> filter (isExtensionOf (extension JPG))+          length+            <$> filter (isExtensionOf (extension JPG))             <$> listDirectory (defaultDirectory config)         assertEqual "" numberPngFiles 1         assertEqual "" numberJpgFiles 0@@ -276,7 +282,7 @@     result <- runPlotM Nothing (defaultTestConfig {captionFormat = fmt}) $ make cb     assertIsInfix expected (extractCaption result)   where-    extractCaption (B.Figure _ (Caption _ caption) _) = caption +    extractCaption (B.Figure _ (Caption _ caption) _) = caption  ------------------------------------------------------------------------------- -- Test that Markdown bold formatting in captions is correctly rendered@@ -298,7 +304,7 @@     result <- runPlotM Nothing (defaultTestConfig {captionFormat = fmt}) $ make cb     assertIsInfix expected (extractCaption result)   where-    extractCaption (B.Figure _ (Caption _ caption) _) = caption +    extractCaption (B.Figure _ (Caption _ caption) _) = caption  ------------------------------------------------------------------------------- -- Test that cleanOutpuDirs correctly cleans the output directory specified in a block.@@ -353,19 +359,26 @@     -- Note that this test is fragile, in the sense that the expected result must be carefully     -- constructed     let expectedAttrs = ("hello", [cls tk], [("key1", "val1"), ("key2", "val2")])-        cb = setAttrs expectedAttrs $-              addDirectory tempDir $-                addCaption "[title](https://google.com)" $-                  codeBlock tk (trivialContent tk)+        cb =+          setAttrs expectedAttrs $+            addDirectory tempDir $+              addCaption "[title](https://google.com)" $+                codeBlock tk (trivialContent tk)         fmt = B.Format "markdown"-    Figure (id', _, keyvals) _ _ <- runPlotM Nothing (defaultTestConfig { captionFormat = fmt-                                                                        , defaultDirectory = tempDir-                                                                        }) $ make cb+    Figure (id', _, keyvals) _ _ <-+      runPlotM+        Nothing+        ( defaultTestConfig+            { captionFormat = fmt,+              defaultDirectory = tempDir+            }+        )+        $ make cb     let (expectedId, _, expectedKeyVals) = expectedAttrs     assertEqual "identifier" expectedId id'     assertEqual "key-value pairs" expectedKeyVals keyvals   where-    extractCaption (B.Figure _ (Caption _ caption) _) = caption +    extractCaption (B.Figure _ (Caption _ caption) _) = caption  codeBlock :: Toolkit -> Script -> Block codeBlock tk script = CodeBlock (mempty, [cls tk], mempty) script@@ -389,6 +402,7 @@ trivialContent Plotsjl = "using Plots; x = 1:10; y = rand(10); plot(x, y);" trivialContent PlantUML = "@startuml\nAlice -> Bob: test\n@enduml" trivialContent SageMath = "G = plot(sin, 1, 10)"+trivialContent D2 = "x -> y -> z"  addCaption :: String -> Block -> Block addCaption caption (CodeBlock (id', cls, attrs) script) =@@ -418,7 +432,7 @@ setAttrs attrs (CodeBlock _ script) = CodeBlock attrs script  -- | Assert that a file exists-assertFileExists :: HasCallStack => FilePath -> Assertion+assertFileExists :: (HasCallStack) => FilePath -> Assertion assertFileExists filepath = do   fileExists <- doesFileExist filepath   unless fileExists (assertFailure msg)@@ -455,5 +469,5 @@     else return ()   createDirectory dir -tshow :: Show a => a -> Text+tshow :: (Show a) => a -> Text tshow = pack . show
+ tests/includes/d2-dd.d2 view
+ tests/includes/sagemath.sage view