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 +5/−0
- README.md +1/−0
- example-config.yml +4/−0
- executable/Main.hs +10/−13
- pandoc-plot.cabal +11/−8
- src/Text/Pandoc/Filter/Plot.hs +14/−14
- src/Text/Pandoc/Filter/Plot/Clean.hs +4/−4
- src/Text/Pandoc/Filter/Plot/Configuration.hs +23/−8
- src/Text/Pandoc/Filter/Plot/Embed.hs +10/−8
- src/Text/Pandoc/Filter/Plot/Monad.hs +8/−1
- src/Text/Pandoc/Filter/Plot/Monad/Logging.hs +1/−1
- src/Text/Pandoc/Filter/Plot/Monad/Types.hs +20/−16
- src/Text/Pandoc/Filter/Plot/Parse.hs +18/−18
- src/Text/Pandoc/Filter/Plot/Renderers.hs +66/−28
- src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/D2.hs +48/−0
- src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs +14/−13
- src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs +20/−20
- src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/PlantUML.hs +17/−17
- src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs +14/−14
- src/Text/Pandoc/Filter/Plot/Renderers/SageMath.hs +13/−13
- src/Text/Pandoc/Filter/Plot/Scripting.hs +6/−6
- tests/Common.hs +36/−22
- tests/includes/d2-dd.d2 +0/−0
- tests/includes/sagemath.sage +0/−0
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