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 +8/−0
- MANUAL.md +1/−1
- README.md +1/−3
- docs/MANUAL.html +3/−3
- executable/Main.hs +2/−1
- pandoc-plot.cabal +17/−2
- src/Text/Pandoc/Filter/Plot.hs +2/−39
- src/Text/Pandoc/Filter/Plot/Monad.hs +50/−10
- src/Text/Pandoc/Filter/Plot/Monad/Types.hs +14/−2
- src/Text/Pandoc/Filter/Plot/Renderers.hs +1/−1
- src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs +2/−31
- src/Text/Pandoc/Filter/Plot/Scripting.hs +3/−0
- tests/Common.hs +19/−1
- tests/Main.hs +2/−0
- tests/fixtures/.config-meta.yml +3/−0
- tests/fixtures/.empty-config.yml +0/−0
- tests/fixtures/.verbose-config.yml +3/−0
- tests/fixtures/plotfile.py +3/−0
- tests/includes/bokeh.py +0/−0
- tests/includes/ggplot2.r +0/−0
- tests/includes/gnuplot.gp +0/−0
- tests/includes/graphviz.dot +1/−0
- tests/includes/mathplot.m +0/−0
- tests/includes/matlabplot.m +1/−0
- tests/includes/matplotlib.py +1/−0
- tests/includes/octave.m +0/−0
- tests/includes/plotly-python.py +1/−0
- tests/includes/plotly-r.r +0/−0
- tests/includes/plotsjl.jl +0/−0
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 -[](http://hackage.haskell.org/package/pandoc-plot) [](http://stackage.org/lts/package/pandoc-plot) [](http://stackage.org/nightly/package/pandoc-plot) [](https://anaconda.org/conda-forge/pandoc-plot) [](https://www.gnu.org/licenses/gpl.html) +[](http://hackage.haskell.org/package/pandoc-plot) [](http://stackage.org/lts/package/pandoc-plot) [](https://anaconda.org/conda-forge/pandoc-plot) [](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