packages feed

pandoc-plot 0.9.2.0 → 0.9.3.0

raw patch · 29 files changed

+138/−94 lines, 29 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Text.Pandoc.Filter.Plot: CaptionFormatK :: InclusionKey
- Text.Pandoc.Filter.Plot: CaptionK :: InclusionKey
- Text.Pandoc.Filter.Plot: DependenciesK :: InclusionKey
- Text.Pandoc.Filter.Plot: DirectoryK :: InclusionKey
- Text.Pandoc.Filter.Plot: DpiK :: InclusionKey
- Text.Pandoc.Filter.Plot: Executable :: FilePath -> Text -> Executable
- Text.Pandoc.Filter.Plot: ExecutableK :: InclusionKey
- Text.Pandoc.Filter.Plot: FileK :: InclusionKey
- Text.Pandoc.Filter.Plot: MatplotlibTightBBoxK :: InclusionKey
- Text.Pandoc.Filter.Plot: MatplotlibTransparentK :: InclusionKey
- Text.Pandoc.Filter.Plot: PreambleK :: InclusionKey
- Text.Pandoc.Filter.Plot: SaveFormatK :: InclusionKey
- Text.Pandoc.Filter.Plot: WithSourceK :: InclusionKey
- Text.Pandoc.Filter.Plot: captionReader :: Format -> Text -> Maybe [Inline]
- Text.Pandoc.Filter.Plot: cls :: Toolkit -> Text
- Text.Pandoc.Filter.Plot: configurationPathMeta :: Pandoc -> Maybe FilePath
- Text.Pandoc.Filter.Plot: data Executable
- Text.Pandoc.Filter.Plot: data InclusionKey
- Text.Pandoc.Filter.Plot: executable :: Toolkit -> PlotM (Maybe Executable)
- Text.Pandoc.Filter.Plot: extension :: SaveFormat -> String
- Text.Pandoc.Filter.Plot: extractPlot :: Text -> Text
- Text.Pandoc.Filter.Plot: inclusionKeys :: [InclusionKey]
- Text.Pandoc.Filter.Plot: makePlot :: Walkable Block a => Configuration -> a -> IO a
- Text.Pandoc.Filter.Plot: readDoc :: FilePath -> IO Pandoc
- Text.Pandoc.Filter.Plot: runPlotM :: Configuration -> PlotM a -> IO a
- Text.Pandoc.Filter.Plot: type PlotM a = StateT PlotState (ReaderT RuntimeEnv IO) a
+ Text.Pandoc.Filter.Plot.Internal: Bokeh :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: CaptionFormatK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: CaptionK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: CheckFailed :: Text -> CheckResult
+ Text.Pandoc.Filter.Plot.Internal: CheckPassed :: CheckResult
+ Text.Pandoc.Filter.Plot.Internal: Configuration :: !FilePath -> !Bool -> !Int -> !SaveFormat -> ![FilePath] -> !Format -> !Verbosity -> !LogSink -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !Script -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !FilePath -> !Bool -> !Bool -> Configuration
+ Text.Pandoc.Filter.Plot.Internal: Debug :: Verbosity
+ Text.Pandoc.Filter.Plot.Internal: DependenciesK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: DirectoryK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: DpiK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: EPS :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: Error :: Verbosity
+ Text.Pandoc.Filter.Plot.Internal: Executable :: FilePath -> Text -> Executable
+ Text.Pandoc.Filter.Plot.Internal: ExecutableK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: FigureSpec :: !Toolkit -> !Text -> !Bool -> !Script -> !SaveFormat -> !FilePath -> !Int -> ![FilePath] -> ![(Text, Text)] -> !Attr -> FigureSpec
+ Text.Pandoc.Filter.Plot.Internal: FileK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: GGPlot2 :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: GIF :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: GNUPlot :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: Graphviz :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: HTML :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: Info :: Verbosity
+ Text.Pandoc.Filter.Plot.Internal: JPG :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: LogFile :: FilePath -> LogSink
+ Text.Pandoc.Filter.Plot.Internal: Mathematica :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: Matlab :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: Matplotlib :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: MatplotlibTightBBoxK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: MatplotlibTransparentK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: Octave :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: OutputSpec :: FigureSpec -> FilePath -> FilePath -> OutputSpec
+ Text.Pandoc.Filter.Plot.Internal: PDF :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: PNG :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: PlotlyPython :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: PlotlyR :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: Plotsjl :: Toolkit
+ Text.Pandoc.Filter.Plot.Internal: PreambleK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: RuntimeEnv :: Configuration -> Logger -> RuntimeEnv
+ Text.Pandoc.Filter.Plot.Internal: SVG :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: SaveFormatK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: ScriptChecksFailed :: Text -> ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: ScriptFailure :: Text -> Int -> ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: ScriptSuccess :: ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: Silent :: Verbosity
+ Text.Pandoc.Filter.Plot.Internal: StdErr :: LogSink
+ Text.Pandoc.Filter.Plot.Internal: TIF :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: ToolkitNotInstalled :: Toolkit -> ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: WEBP :: SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: Warning :: Verbosity
+ Text.Pandoc.Filter.Plot.Internal: WithSourceK :: InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: [blockAttrs] :: FigureSpec -> !Attr
+ Text.Pandoc.Filter.Plot.Internal: [bokehExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [bokehPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [captionFormat] :: Configuration -> !Format
+ Text.Pandoc.Filter.Plot.Internal: [caption] :: FigureSpec -> !Text
+ Text.Pandoc.Filter.Plot.Internal: [defaultDPI] :: Configuration -> !Int
+ Text.Pandoc.Filter.Plot.Internal: [defaultDependencies] :: Configuration -> ![FilePath]
+ Text.Pandoc.Filter.Plot.Internal: [defaultDirectory] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [defaultSaveFormat] :: Configuration -> !SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: [defaultWithSource] :: Configuration -> !Bool
+ Text.Pandoc.Filter.Plot.Internal: [dependencies] :: FigureSpec -> ![FilePath]
+ Text.Pandoc.Filter.Plot.Internal: [directory] :: FigureSpec -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [dpi] :: FigureSpec -> !Int
+ Text.Pandoc.Filter.Plot.Internal: [envConfig] :: RuntimeEnv -> Configuration
+ Text.Pandoc.Filter.Plot.Internal: [envLogger] :: RuntimeEnv -> Logger
+ Text.Pandoc.Filter.Plot.Internal: [extraAttrs] :: FigureSpec -> ![(Text, Text)]
+ Text.Pandoc.Filter.Plot.Internal: [ggplot2Exe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [ggplot2Preamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [gnuplotExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [gnuplotPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [graphvizExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [graphvizPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [logSink] :: Configuration -> !LogSink
+ Text.Pandoc.Filter.Plot.Internal: [logVerbosity] :: Configuration -> !Verbosity
+ Text.Pandoc.Filter.Plot.Internal: [mathematicaExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [mathematicaPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [matlabExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [matlabPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [matplotlibExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [matplotlibPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [matplotlibTightBBox] :: Configuration -> !Bool
+ Text.Pandoc.Filter.Plot.Internal: [matplotlibTransparent] :: Configuration -> !Bool
+ Text.Pandoc.Filter.Plot.Internal: [oFigurePath] :: OutputSpec -> FilePath
+ Text.Pandoc.Filter.Plot.Internal: [oFigureSpec] :: OutputSpec -> FigureSpec
+ Text.Pandoc.Filter.Plot.Internal: [oScriptPath] :: OutputSpec -> FilePath
+ Text.Pandoc.Filter.Plot.Internal: [octaveExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [octavePreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [plotlyPythonExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [plotlyPythonPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [plotlyRExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [plotlyRPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [plotsjlExe] :: Configuration -> !FilePath
+ Text.Pandoc.Filter.Plot.Internal: [plotsjlPreamble] :: Configuration -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [saveFormat] :: FigureSpec -> !SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: [script] :: FigureSpec -> !Script
+ Text.Pandoc.Filter.Plot.Internal: [toolkit] :: FigureSpec -> !Toolkit
+ Text.Pandoc.Filter.Plot.Internal: [withSource] :: FigureSpec -> !Bool
+ Text.Pandoc.Filter.Plot.Internal: ask :: MonadReader r m => m r
+ Text.Pandoc.Filter.Plot.Internal: asks :: MonadReader r m => (r -> a) -> m a
+ Text.Pandoc.Filter.Plot.Internal: asksConfig :: (Configuration -> a) -> PlotM a
+ Text.Pandoc.Filter.Plot.Internal: availableToolkits :: Configuration -> IO [Toolkit]
+ Text.Pandoc.Filter.Plot.Internal: availableToolkitsM :: PlotM [Toolkit]
+ Text.Pandoc.Filter.Plot.Internal: captionReader :: Format -> Text -> Maybe [Inline]
+ Text.Pandoc.Filter.Plot.Internal: capture :: Toolkit -> FigureSpec -> FilePath -> Script
+ Text.Pandoc.Filter.Plot.Internal: cleanOutputDirs :: Walkable Block b => Configuration -> b -> IO [FilePath]
+ Text.Pandoc.Filter.Plot.Internal: cls :: Toolkit -> Text
+ Text.Pandoc.Filter.Plot.Internal: command :: Toolkit -> OutputSpec -> Text -> Text
+ Text.Pandoc.Filter.Plot.Internal: comment :: Toolkit -> Text -> Text
+ Text.Pandoc.Filter.Plot.Internal: configuration :: FilePath -> IO Configuration
+ Text.Pandoc.Filter.Plot.Internal: configurationPathMeta :: Pandoc -> Maybe FilePath
+ Text.Pandoc.Filter.Plot.Internal: data CheckResult
+ Text.Pandoc.Filter.Plot.Internal: data Configuration
+ Text.Pandoc.Filter.Plot.Internal: data Executable
+ Text.Pandoc.Filter.Plot.Internal: data FigureSpec
+ Text.Pandoc.Filter.Plot.Internal: data InclusionKey
+ Text.Pandoc.Filter.Plot.Internal: data LogSink
+ Text.Pandoc.Filter.Plot.Internal: data OutputSpec
+ Text.Pandoc.Filter.Plot.Internal: data RuntimeEnv
+ Text.Pandoc.Filter.Plot.Internal: data SaveFormat
+ Text.Pandoc.Filter.Plot.Internal: data ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: data Toolkit
+ Text.Pandoc.Filter.Plot.Internal: data Verbosity
+ Text.Pandoc.Filter.Plot.Internal: debug :: Text -> PlotM ()
+ Text.Pandoc.Filter.Plot.Internal: defaultConfiguration :: Configuration
+ Text.Pandoc.Filter.Plot.Internal: err :: Text -> PlotM ()
+ Text.Pandoc.Filter.Plot.Internal: exeFromPath :: FilePath -> Executable
+ Text.Pandoc.Filter.Plot.Internal: executable :: Toolkit -> PlotM (Maybe Executable)
+ Text.Pandoc.Filter.Plot.Internal: extension :: SaveFormat -> String
+ Text.Pandoc.Filter.Plot.Internal: extractPlot :: Text -> Text
+ Text.Pandoc.Filter.Plot.Internal: figurePath :: FigureSpec -> PlotM FilePath
+ Text.Pandoc.Filter.Plot.Internal: fileHash :: FilePath -> PlotM FileHash
+ Text.Pandoc.Filter.Plot.Internal: inclusionKeys :: [InclusionKey]
+ Text.Pandoc.Filter.Plot.Internal: info :: Text -> PlotM ()
+ Text.Pandoc.Filter.Plot.Internal: isWindows :: Bool
+ Text.Pandoc.Filter.Plot.Internal: liftIO :: MonadIO m => IO a -> m a
+ Text.Pandoc.Filter.Plot.Internal: outputDirs :: Walkable Block b => b -> PlotM [FilePath]
+ Text.Pandoc.Filter.Plot.Internal: parseExtraAttrs :: Toolkit -> Map Text Text -> Map Text Text
+ Text.Pandoc.Filter.Plot.Internal: parseFigureSpec :: Block -> PlotM (Maybe FigureSpec)
+ Text.Pandoc.Filter.Plot.Internal: plotToolkit :: Block -> Maybe Toolkit
+ Text.Pandoc.Filter.Plot.Internal: preambleSelector :: Toolkit -> Configuration -> Script
+ Text.Pandoc.Filter.Plot.Internal: readDoc :: FilePath -> IO Pandoc
+ Text.Pandoc.Filter.Plot.Internal: runCommand :: FilePath -> Text -> PlotM (ExitCode, Text)
+ Text.Pandoc.Filter.Plot.Internal: runPlotM :: Configuration -> PlotM a -> IO a
+ Text.Pandoc.Filter.Plot.Internal: runScriptIfNecessary :: FigureSpec -> PlotM ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: runTempScript :: FigureSpec -> PlotM ScriptResult
+ Text.Pandoc.Filter.Plot.Internal: scriptChecks :: Toolkit -> [Script -> CheckResult]
+ Text.Pandoc.Filter.Plot.Internal: scriptExtension :: Toolkit -> String
+ Text.Pandoc.Filter.Plot.Internal: silence :: PlotM a -> PlotM a
+ Text.Pandoc.Filter.Plot.Internal: supportedSaveFormats :: Toolkit -> [SaveFormat]
+ Text.Pandoc.Filter.Plot.Internal: toFigure :: Format -> FigureSpec -> PlotM Block
+ Text.Pandoc.Filter.Plot.Internal: toolkitAvailable :: Toolkit -> PlotM Bool
+ Text.Pandoc.Filter.Plot.Internal: toolkits :: [Toolkit]
+ Text.Pandoc.Filter.Plot.Internal: type PlotM a = StateT PlotState (ReaderT RuntimeEnv IO) a
+ Text.Pandoc.Filter.Plot.Internal: type Script = Text
+ Text.Pandoc.Filter.Plot.Internal: unavailableToolkits :: Configuration -> IO [Toolkit]
+ Text.Pandoc.Filter.Plot.Internal: unavailableToolkitsM :: PlotM [Toolkit]
+ Text.Pandoc.Filter.Plot.Internal: warning :: Text -> PlotM ()

Files

CHANGELOG.md view
@@ -2,6 +2,14 @@ 
 pandoc-plot uses [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
 
+Release 0.9.3.0
+---------------
+
+* Added executable caching: repeated useage of a particular toolkit will be faster because executables are only looked-for once.
+* Reverting the change from 0.8.1.0: internal machinery of `pandoc-plot` has been moved to the `Text.Pandoc.Filter.Plot.Internal` module, where there is no guarantee of backwards-compatibility after 1.0.0.
+* Removed the `makePlot` function, which could not take advantage of multithreading and other key features of `pandoc-plot`.
+* Fixed an issue where files required for tests were missing from source tarballs.
+
 Release 0.9.2.0
 ---------------
 
MANUAL.md view
@@ -159,7 +159,7 @@ `pandoc-plot` is a command line executable with a few functions. You can take a look at the help using the `-h`/`--help` flag:
 
 ``` bash
-pandoc-plot 0.9.2.0 - generate figures directly in documents
+pandoc-plot 0.9.3.0 - generate figures directly in documents
 
 Usage: pandoc-plot.EXE [(-v|--version) | --full-version | (-m|--manual)] 
                        [COMMAND] [AST]
README.md view
@@ -2,7 +2,7 @@ 
 ## A Pandoc filter to generate figures from code blocks in documents
 
-[![Hackage version](https://img.shields.io/hackage/v/pandoc-plot.svg)](http://hackage.haskell.org/package/pandoc-plot) [![Stackage version (latest long-term service)](http://stackage.org/package/pandoc-plot/badge/lts)](http://stackage.org/lts/package/pandoc-plot) [![Stackage version (nightly)](http://stackage.org/package/pandoc-plot/badge/nightly)](http://stackage.org/nightly/package/pandoc-plot) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/pandoc-plot.svg)](https://anaconda.org/conda-forge/pandoc-plot) [![license](https://img.shields.io/badge/license-GPLv2+-lightgray.svg)](https://www.gnu.org/licenses/gpl.html) 
+[![Hackage version](https://img.shields.io/hackage/v/pandoc-plot.svg)](http://hackage.haskell.org/package/pandoc-plot) [![Stackage version (latest long-term service)](http://stackage.org/package/pandoc-plot/badge/lts)](http://stackage.org/lts/package/pandoc-plot) [![Conda Version](https://img.shields.io/conda/vn/conda-forge/pandoc-plot.svg)](https://anaconda.org/conda-forge/pandoc-plot) [![license](https://img.shields.io/badge/license-GPLv2+-lightgray.svg)](https://www.gnu.org/licenses/gpl.html) 
 
 `pandoc-plot` turns code blocks present in your documents (Markdown, LaTeX, etc.) into embedded figures, using your plotting toolkit of choice, including Matplotlib, ggplot2, MATLAB, Mathematica, and more.
 
@@ -67,8 +67,6 @@ ``` bash
 pandoc-plot toolkits
 ```
-
-The `toolkits` command is described in its own section below.
 
 **Wish your plotting toolkit of choice was available? Please [raise an
 issue](https://github.com/LaurentRDC/pandoc-plot/issues)\!**
docs/MANUAL.html view
@@ -4,7 +4,7 @@   <meta charset="utf-8" />
   <meta name="generator" content="pandoc" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
-  <title>pandoc-plot 0.9.2.0 manual</title>
+  <title>pandoc-plot 0.9.3.0 manual</title>
   <style>
     code{white-space: pre-wrap;}
     span.smallcaps{font-variant: small-caps;}
@@ -83,7 +83,7 @@ </head>
 <body>
 <header id="title-block-header">
-<h1 class="title">pandoc-plot 0.9.2.0 manual</h1>
+<h1 class="title">pandoc-plot 0.9.3.0 manual</h1>
 </header>
 <!--
 The file MANUAL.md is automatically generated by the tools/mkmanual.ps1 script. Do not edit manually.
@@ -187,7 +187,7 @@ <div class="sourceCode" id="cb10"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="ex">pandoc</span> --filter pandoc-plot --filter pandoc-crossref -i myfile.md -o myfile.html</span></code></pre></div>
 <h2 id="detailed-usage">Detailed usage</h2>
 <p><code>pandoc-plot</code> is a command line executable with a few functions. You can take a look at the help using the <code>-h</code>/<code>--help</code> flag:</p>
-<div class="sourceCode" id="cb11"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="ex">pandoc-plot</span> 0.9.2.0 - generate figures directly in documents</span>
+<div class="sourceCode" id="cb11"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="ex">pandoc-plot</span> 0.9.3.0 - generate figures directly in documents</span>
 <span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a></span>
 <span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a><span class="ex">Usage</span>: pandoc-plot.EXE [(-v<span class="kw">|</span><span class="ex">--version</span>) <span class="kw">|</span> <span class="ex">--full-version</span> <span class="kw">|</span> <span class="kw">(</span><span class="ex">-m</span><span class="kw">|</span><span class="ex">--manual</span><span class="kw">)</span>] </span>
 <span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a>                       [<span class="ex">COMMAND</span>] [AST]</span>
executable/Main.hs view
@@ -30,7 +30,8 @@                                                    plotTransform,
                                                    defaultConfiguration, 
                                                    configuration, Configuration(..),
-                                                   pandocPlotVersion, cls, 
+                                                   pandocPlotVersion, )
+import           Text.Pandoc.Filter.Plot.Internal (cls, 
                                                    supportedSaveFormats, 
                                                    toolkits, readDoc, 
                                                    cleanOutputDirs, 
pandoc-plot.cabal view
@@ -1,6 +1,6 @@ cabal-version:  2.2
 name:           pandoc-plot
-version:        0.9.2.0
+version:        0.9.3.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 captured and included as a figure.
 category:       Text
@@ -21,6 +21,21 @@     docs/MANUAL.html
     stack.yaml
     example-config.yml
+    tests/fixtures/.config-meta.yml
+    tests/fixtures/.empty-config.yml
+    tests/fixtures/.verbose-config.yml
+    tests/fixtures/plotfile.py
+    tests/includes/bokeh.py
+    tests/includes/ggplot2.r
+    tests/includes/gnuplot.gp
+    tests/includes/graphviz.dot
+    tests/includes/mathplot.m
+    tests/includes/matlabplot.m
+    tests/includes/matplotlib.py
+    tests/includes/octave.m
+    tests/includes/plotly-python.py
+    tests/includes/plotly-r.r
+    tests/includes/plotsjl.jl
 
 source-repository head
     type: git
@@ -35,9 +50,9 @@ library
     exposed-modules:
         Text.Pandoc.Filter.Plot
+        Text.Pandoc.Filter.Plot.Internal
     other-modules:
         Paths_pandoc_plot
-        Text.Pandoc.Filter.Plot.Internal
         Text.Pandoc.Filter.Plot.Clean
         Text.Pandoc.Filter.Plot.Configuration
         Text.Pandoc.Filter.Plot.Parse
src/Text/Pandoc/Filter/Plot.hs view
@@ -77,10 +77,8 @@ @
 -}
 module Text.Pandoc.Filter.Plot (
-    -- * Operating on single Pandoc blocks
-      makePlot
     -- * Operating on whole Pandoc documents
-    , plotTransform
+      plotTransform
     -- * Cleaning output directories
     , cleanOutputDirs
     -- * Runtime configuration
@@ -99,26 +97,10 @@     , supportedSaveFormats
     -- * Version information
     , pandocPlotVersion
-    -- * For testing and internal purposes ONLY
-    -- ** Running the @PlotM@ monad
+    -- * For embedding, testing and internal purposes ONLY. Might change without notice.
     , make
     , makeEither
-    , PlotM
-    , runPlotM
     , PandocPlotError(..)
-    -- ** Code block parameters
-    , InclusionKey(..)
-    , inclusionKeys
-    -- ** Utilities
-    , extension
-    , readDoc
-    , captionReader
-    , cls
-    , configurationPathMeta
-    , executable
-    , Executable(..)
-    -- ** Embedding HTML content
-    , extractPlot
     ) where
 
 import Control.Concurrent.Async.Lifted   (mapConcurrently)
@@ -128,7 +110,6 @@ import Paths_pandoc_plot                 (version)
 
 import Text.Pandoc.Definition            (Pandoc(..), Block)
-import Text.Pandoc.Walk                  (walkM, Walkable)
 
 import Text.Pandoc.Filter.Plot.Internal
 
@@ -143,24 +124,6 @@               -> IO Pandoc
 plotTransform conf (Pandoc meta blocks) = 
     runPlotM conf $ mapConcurrently make blocks >>= return . Pandoc meta
-
-
--- | Highest-level function that can be walked over a Pandoc tree.
--- All code blocks that have the appropriate class names will be considered
--- figures, e.g. @.matplotlib@.
---
--- This function can be made to operation on whole @Pandoc@ documents. However,
--- you should prefer the @plotTransform@ function for whole documents, as it
--- is optimized for parallel operations.
---
--- Failing to render a figure does not stop the filter, so that you may run the filter
--- on documents without having all necessary toolkits installed. In this case, error
--- messages are printed to stderr, and blocks are left unchanged.
-makePlot :: Walkable Block a
-         => Configuration -- ^ Configuration for default values
-         -> a             -- ^ Input block or document
-         -> IO a
-makePlot conf = runPlotM conf . walkM make
 
 
 -- | The version of the pandoc-plot package.
src/Text/Pandoc/Filter/Plot/Monad.hs view
@@ -19,6 +19,8 @@     , runCommand
     -- * Getting file hashes
     , fileHash
+    -- * Getting executables
+    , executable
     -- * Logging
     , Verbosity(..)
     , LogSink(..)
@@ -53,7 +55,7 @@ import           Data.Text.Encoding          (decodeUtf8With)
 import           Data.Text.Encoding.Error    (lenientDecode)
 
-import           System.Directory            (doesFileExist, getModificationTime)
+import           System.Directory            (doesFileExist, getModificationTime, findExecutable)
 import           System.Exit                 (ExitCode (..))
 import           System.Process.Typed        ( readProcessStderr, shell, nullStream
                                              , setStdout, setStderr, byteStringOutput
@@ -90,7 +92,8 @@ -- | Evaluate a @PlotM@ action.
 runPlotM :: Configuration -> PlotM a -> IO a
 runPlotM conf v = do
-    st <- newMVar mempty
+    st <- PlotState <$> newMVar mempty
+                    <*> newMVar mempty
     let verbosity = logVerbosity conf
         sink      = logSink conf 
     withLogger verbosity sink $ 
@@ -113,8 +116,7 @@     logger <- asks envLogger
     when (v >= lVerbosity logger) $ 
         liftIO $ do
-            let lines' = [l' | l' <- T.lines t]
-            forM_ lines' $ \l -> writeChan (lChannel logger) (Just (h <> l <> "\n"))
+            forM_ ( T.lines t) $ \l -> writeChan (lChannel logger) (Just (h <> l <> "\n"))
 
 
 -- | Run a command within the @PlotM@ monad. Stderr stream
@@ -150,22 +152,27 @@     return (ec, processOutput)
 
 
--- Plot state consists of a map of filepaths to hashes
+-- Plot state is used for caching.
+-- One part consists of a map of filepaths to hashes
 -- This allows multiple plots to depend on the same file/directory, and the file hashes
 -- will only be calculated once. This is OK because pandoc-plot will not run for long.
 -- We note that because figures are rendered possibly in parallel, access to 
 -- the state must be synchronized; otherwise, each thread might compute its own
 -- hashes.
+-- The other part is comprised of a map of toolkits to executables (possibly missing)
+-- This means that executable will be search for only once.
 type FileHash  = Word
-type PlotState = MVar (Map FilePath FileHash)
+data PlotState = 
+    PlotState (MVar (Map FilePath FileHash))
+              (MVar (Map Toolkit (Maybe Executable)))
 
 
 -- | Get a filehash. If the file hash has been computed before,
 -- it is reused. Otherwise, the filehash is calculated and stored.
 fileHash :: FilePath -> PlotM FileHash
 fileHash path = do
-    var <- get
-    hashes <- liftIO $ takeMVar var
+    PlotState varHashes varExes <- get
+    hashes <- liftIO $ takeMVar varHashes
     (fh, hashes') <- case M.lookup path hashes of
         Nothing -> do
             debug $ mconcat ["Calculating hash of dependency ", pack path]
@@ -175,8 +182,8 @@         Just h -> do
             debug $ mconcat ["Hash of dependency ", pack path, " already calculated."]
             return (h, hashes)
-    liftIO $ putMVar var hashes'
-    put var
+    liftIO $ putMVar varHashes hashes'
+    put $ PlotState varHashes varExes
     return fh
     where
     -- As a proxy for the state of a file dependency, we use the modification time
@@ -187,6 +194,39 @@         if fileExists
             then liftIO . fmap (fromIntegral . hash . show) . getModificationTime $ fp
             else err (mconcat ["Dependency ", pack fp, " does not exist."]) >> return 0 
+
+
+-- | Get an executable. If the executable has not been used before, 
+-- find it and store where it is. It will be re-used.
+executable :: Toolkit -> PlotM (Maybe Executable)
+executable tk = do
+    name <- exeSelector tk
+    PlotState varHashes varExes <- get
+    exes <- liftIO $ takeMVar varExes
+    (exe', exes') <- case M.lookup tk exes of
+        Nothing -> do
+            debug $ mconcat ["Looking for executable \"", pack name, "\" for ", pack $ show tk]
+            exe' <- liftIO $ findExecutable name >>= return . fmap exeFromPath
+            let exes' = M.insert tk exe' exes
+            return (exe', exes')
+        Just e -> do
+            debug $ mconcat ["Executable \"", pack name, "\" already found."]
+            return (e, exes)
+    liftIO $ putMVar varExes exes'
+    put $ PlotState varHashes varExes
+    return exe'
+    where
+        exeSelector Matplotlib   = asksConfig matplotlibExe  
+        exeSelector PlotlyPython = asksConfig plotlyPythonExe 
+        exeSelector PlotlyR      = asksConfig plotlyRExe      
+        exeSelector Matlab       = asksConfig matlabExe       
+        exeSelector Mathematica  = asksConfig mathematicaExe  
+        exeSelector Octave       = asksConfig octaveExe       
+        exeSelector GGPlot2      = asksConfig ggplot2Exe      
+        exeSelector GNUPlot      = asksConfig gnuplotExe      
+        exeSelector Graphviz     = asksConfig graphvizExe     
+        exeSelector Bokeh        = asksConfig bokehExe         
+        exeSelector Plotsjl      = asksConfig plotsjlExe 
 
 
 -- | The @Configuration@ type holds the default values to use
src/Text/Pandoc/Filter/Plot/Monad/Types.hs view
@@ -25,6 +25,8 @@     , extension
     , toolkits
     , inclusionKeys
+    , Executable(..)
+    , exeFromPath
     -- Utilities
     , isWindows
 ) where
@@ -32,10 +34,11 @@ import           Data.Char              (toLower)
 import           Data.List              (intersperse)
 import           Data.String            (IsString (..))
-import           Data.Text              (Text)
+import           Data.Text              (Text, pack)
 import           Data.Yaml
 
 import           GHC.Generics           (Generic)
+import           System.FilePath        (splitFileName)
 import           System.Info            (os)
 
 import           Text.Pandoc.Definition (Attr)
@@ -58,7 +61,7 @@     | Graphviz
     | Bokeh
     | Plotsjl
-    deriving (Bounded, Eq, Enum, Generic)
+    deriving (Bounded, Eq, Enum, Generic, Ord)
 
 
 -- | This instance should only be used to display toolkit names
@@ -89,6 +92,15 @@ cls Graphviz     = "graphviz"
 cls Bokeh        = "bokeh"
 cls Plotsjl      = "plotsjl"
+
+
+-- | Executable program and directory where it can be found.
+data Executable = Executable FilePath Text
+
+
+exeFromPath :: FilePath -> Executable
+exeFromPath fp = let (dir, name) = splitFileName fp
+                 in Executable dir (pack name)
 
 
 -- | Source context for plotting scripts
src/Text/Pandoc/Filter/Plot/Renderers.hs view
@@ -48,7 +48,7 @@ import Text.Pandoc.Filter.Plot.Renderers.Graphviz
 import Text.Pandoc.Filter.Plot.Renderers.Bokeh
 import Text.Pandoc.Filter.Plot.Renderers.Plotsjl
-import Text.Pandoc.Filter.Plot.Renderers.Prelude     (executable, Executable(..), OutputSpec(..))
+import Text.Pandoc.Filter.Plot.Renderers.Prelude     (OutputSpec(..))
 
 import Text.Pandoc.Filter.Plot.Monad
 
src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs view
@@ -18,31 +18,23 @@     , unpack
     , commandSuccess
     , existsOnPath
-    , executable
     , OutputSpec(..)
-    , Executable(..)
     , appendCapture
     , toRPath
 ) where
 
 import           Data.Maybe                    (isJust)
-import           Data.Text                     (Text, unpack, pack)
+import           Data.Text                     (Text, unpack)
 
 import           System.Directory              (findExecutable)
-import           System.FilePath               (splitFileName, isPathSeparator)
+import           System.FilePath               (isPathSeparator)
 import           System.Exit                   (ExitCode(..))
 
 import           Text.Shakespeare.Text         (st)
 
 import           Text.Pandoc.Filter.Plot.Monad
 
-data Executable = Executable FilePath Text
 
-
-exeFromPath :: FilePath -> Executable
-exeFromPath fp = let (dir, name) = splitFileName fp
-                 in Executable dir (pack name)
-
 -- | Check that the supplied command results in
 -- an exit code of 0 (i.e. no errors)
 commandSuccess :: FilePath -- Directory from which to run the command
@@ -56,27 +48,6 @@ -- | Checks that an executable is available on path, at all.
 existsOnPath :: FilePath -> IO Bool
 existsOnPath fp = findExecutable fp >>= fmap isJust . return
-
-
--- | Try to find the executable and normalise its path.
--- If it cannot be found, it is left unchanged - just in case.
-tryToFindExe :: String -> IO (Maybe Executable)
-tryToFindExe fp = findExecutable fp >>= return . fmap exeFromPath
-
-
--- | Path to (directory, executable) of a toolkit. 
-executable :: Toolkit -> PlotM (Maybe Executable)
-executable Matplotlib   = asksConfig matplotlibExe   >>= liftIO . tryToFindExe 
-executable PlotlyPython = asksConfig plotlyPythonExe >>= liftIO . tryToFindExe 
-executable PlotlyR      = asksConfig plotlyRExe      >>= liftIO . tryToFindExe 
-executable Matlab       = asksConfig matlabExe       >>= liftIO . tryToFindExe 
-executable Mathematica  = asksConfig mathematicaExe  >>= liftIO . tryToFindExe 
-executable Octave       = asksConfig octaveExe       >>= liftIO . tryToFindExe 
-executable GGPlot2      = asksConfig ggplot2Exe      >>= liftIO . tryToFindExe 
-executable GNUPlot      = asksConfig gnuplotExe      >>= liftIO . tryToFindExe 
-executable Graphviz     = asksConfig graphvizExe     >>= liftIO . tryToFindExe 
-executable Bokeh        = asksConfig bokehExe        >>= liftIO . tryToFindExe  
-executable Plotsjl      = asksConfig plotsjlExe      >>= liftIO . tryToFindExe 
 
 
 -- | A shortcut to append capture script fragments to scripts
src/Text/Pandoc/Filter/Plot/Scripting.hs view
@@ -91,6 +91,9 @@             target <- figurePath spec
 
             -- Check if executable is present
+            -- Note that checking if the toolkit if fully configured is much more involved,
+            -- and so we only check if the toolkit is appropriately installed if there is
+            -- an error.
             exe <- executable toolkit
             case exe of
                 Nothing -> error $ "Toolkit " <> show toolkit <> " is not installed."
tests/Common.hs view
@@ -15,6 +15,7 @@ import           Test.Tasty.HUnit
 
 import           Text.Pandoc.Filter.Plot
+import           Text.Pandoc.Filter.Plot.Internal
 
 import qualified Text.Pandoc.Builder              as B
 import qualified Text.Pandoc.Definition           as B
@@ -32,7 +33,7 @@ 
 defaultTestConfig :: Configuration
 defaultTestConfig = defaultConfiguration { logVerbosity = Silent
-                                         , logSink = StdErr --LogFile "test_log.txt"
+                                         , logSink = StdErr
                                          }
 
 -------------------------------------------------------------------------------
@@ -48,6 +49,23 @@         _ <- runPlotM defaultTestConfig $ make cb
         filesCreated <- length <$> listDirectory tempDir
         assertEqual "" 2 filesCreated
+
+
+-------------------------------------------------------------------------------
+-- Test that plot files and source files are created when the filter is run
+-- and the path of the files involves spaces. See Issue #2
+testFileCreationPathWithSpaces :: Toolkit -> TestTree
+testFileCreationPathWithSpaces tk =
+    testCase "writes output files in appropriate directory (with spaces)" $ do
+        let postfix = unpack . cls $ tk
+        tempDir <- (</> "test-file-creation-with-spaces-   -" <> postfix) <$> getTemporaryDirectory
+        ensureDirectoryExistsAndEmpty tempDir
+
+        let cb = (addDirectory tempDir $ codeBlock tk (trivialContent tk))
+        _ <- runPlotM defaultTestConfig $ make cb
+        filesCreated <- length <$> listDirectory tempDir
+        assertEqual "" 2 filesCreated
+
 
 -------------------------------------------------------------------------------
 -- Test that included files are found within the source
tests/Main.hs view
@@ -16,6 +16,7 @@ 
 import           Common
 import           Text.Pandoc.Filter.Plot
+import           Text.Pandoc.Filter.Plot.Internal
 
 main :: IO ()
 main = do
@@ -50,6 +51,7 @@ toolkitSuite tk =
     testGroup (show tk) $
         [ testFileCreation
+        , testFileCreationPathWithSpaces
         , testFileInclusion
         , testSaveFormat
         , testWithSource
+ tests/fixtures/.config-meta.yml view
@@ -0,0 +1,3 @@+# Just not default values
+dpi: 1000
+directory: ".."
+ tests/fixtures/.empty-config.yml view
+ tests/fixtures/.verbose-config.yml view
@@ -0,0 +1,3 @@+logging:
+  verbosity: debug
+  filepath: log.txt
+ tests/fixtures/plotfile.py view
@@ -0,0 +1,3 @@+import matplotlib.pyplot as plt
+
+plt.plot([1,2,3,4,5], [5,6,7,8,9])
+ tests/includes/bokeh.py view
+ tests/includes/ggplot2.r view
+ tests/includes/gnuplot.gp view
+ tests/includes/graphviz.dot view
@@ -0,0 +1,1 @@+// This is a comment in DOT
+ tests/includes/mathplot.m view
+ tests/includes/matlabplot.m view
@@ -0,0 +1,1 @@+% Matlab content
+ tests/includes/matplotlib.py view
@@ -0,0 +1,1 @@+# matplotlib content
+ tests/includes/octave.m view
+ tests/includes/plotly-python.py view
@@ -0,0 +1,1 @@+# plotly content
+ tests/includes/plotly-r.r view
+ tests/includes/plotsjl.jl view