diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
 
 pandoc-plot uses [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
 
+Release 0.9.2.0
+---------------
+
+* Fixed an issue where executables located on paths with spaces would not be invoked correctly (#12)
+* Fixed an issue where R-paths were not normalized correctly.
+* Fixed an issue where executables specified in configuration that did not exist would crash `pandoc-plot`.
+* Fixed an issue where some R-based toolkits appeared to be available, but were not.
+
 Release 0.9.1.0
 ---------------
 
diff --git a/MANUAL.md b/MANUAL.md
--- a/MANUAL.md
+++ b/MANUAL.md
@@ -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.1.0 - generate figures directly in documents
+pandoc-plot 0.9.2.0 - generate figures directly in documents
 
 Usage: pandoc-plot.EXE [(-v|--version) | --full-version | (-m|--manual)] 
                        [COMMAND] [AST]
diff --git a/docs/MANUAL.html b/docs/MANUAL.html
--- a/docs/MANUAL.html
+++ b/docs/MANUAL.html
@@ -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.1.0 manual</title>
+  <title>pandoc-plot 0.9.2.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.1.0 manual</h1>
+<h1 class="title">pandoc-plot 0.9.2.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.1.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.2.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>
diff --git a/executable/Main.hs b/executable/Main.hs
--- a/executable/Main.hs
+++ b/executable/Main.hs
@@ -10,6 +10,7 @@
 import           Control.Monad                    (join, when, msum)
 
 import           Data.List                        (intersperse, (\\))
+import           Data.Maybe                       (fromJust)
 import           Data.Text                        (unpack)
 import qualified Data.Text.IO                     as TIO
 import           Data.Version                     (parseVersion, showVersion)
@@ -34,7 +35,7 @@
                                                    toolkits, readDoc, 
                                                    cleanOutputDirs, 
                                                    configurationPathMeta,
-                                                   executable, runPlotM)
+                                                   executable, runPlotM, Executable(..))
 
 import           Text.Pandoc                      (pandocVersion)
 import           Text.Pandoc.Definition           (pandocTypesVersion)
@@ -233,9 +234,10 @@
     return unavailable >>= mapM_ (unavailToolkitInfo c)
     where
         toolkitInfo avail conf tk = do
-            exe <- runPlotM conf $ executable tk
             putStrLn $ "Toolkit: " <> show tk
-            when avail $ putStrLn $ "    Executable: " <> exe
+            when avail $ do
+                Executable dir exe <- fmap fromJust $ runPlotM conf $ executable tk
+                putStrLn $ "    Executable: " <> (dir </> unpack exe)
             putStrLn $ "    Code block trigger: " <> (unpack . cls $ tk)
             putStrLn $ "    Supported save formats: " <> (mconcat . intersperse ", " . fmap show $ supportedSaveFormats tk)
             putStrLn mempty
diff --git a/pandoc-plot.cabal b/pandoc-plot.cabal
--- a/pandoc-plot.cabal
+++ b/pandoc-plot.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           pandoc-plot
-version:        0.9.1.0
+version:        0.9.2.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
diff --git a/src/Text/Pandoc/Filter/Plot.hs b/src/Text/Pandoc/Filter/Plot.hs
--- a/src/Text/Pandoc/Filter/Plot.hs
+++ b/src/Text/Pandoc/Filter/Plot.hs
@@ -116,6 +116,7 @@
     , cls
     , configurationPathMeta
     , executable
+    , Executable(..)
     -- ** Embedding HTML content
     , extractPlot
     ) where
diff --git a/src/Text/Pandoc/Filter/Plot/Clean.hs b/src/Text/Pandoc/Filter/Plot/Clean.hs
--- a/src/Text/Pandoc/Filter/Plot/Clean.hs
+++ b/src/Text/Pandoc/Filter/Plot/Clean.hs
@@ -52,7 +52,14 @@
 -- The cleaned directories are returned.
 cleanOutputDirs :: Walkable Block b 
                 => Configuration -> b -> IO [FilePath]
-cleanOutputDirs conf = runPlotM conf . cleanOutputDirsM
+cleanOutputDirs conf doc = do
+    dirs <- runPlotM conf . cleanOutputDirsM $ doc
+    -- Deletion of the log file must be done outside of PlotM
+    -- to ensure the log file has been closed.
+    case logSink conf of 
+        LogFile path -> removePathForcibly path
+        _            -> return ()
+    return dirs
 
 
 -- | Analyze a document to determine where would the pandoc-plot output directories be.
@@ -67,15 +74,7 @@
 cleanOutputDirsM :: Walkable Block b 
                  => b -> PlotM [FilePath]
 cleanOutputDirsM doc = do
-    conf <- asksConfig id
-    case logSink conf of 
-        LogFile path -> do
-            info $ "Removing log file " <> pack path
-            liftIO $ removePathForcibly path
-        _            -> return ()
-    
     directories <- outputDirs doc
-
     forM directories $ \fp -> do
         info $ "Removing directory " <> pack fp
         -- It is important to use `removePathForcibly` here, because it does 
diff --git a/src/Text/Pandoc/Filter/Plot/Monad.hs b/src/Text/Pandoc/Filter/Plot/Monad.hs
--- a/src/Text/Pandoc/Filter/Plot/Monad.hs
+++ b/src/Text/Pandoc/Filter/Plot/Monad.hs
@@ -57,6 +57,7 @@
 import           System.Exit                 (ExitCode (..))
 import           System.Process.Typed        ( readProcessStderr, shell, nullStream
                                              , setStdout, setStderr, byteStringOutput
+                                             , setWorkingDir
                                              )
 import           Text.Pandoc.Definition      (Format(..))
 
@@ -119,13 +120,16 @@
 -- | Run a command within the @PlotM@ monad. Stderr stream
 -- is read and decoded, while Stdout is ignored. 
 -- Logging happens at the debug level if the command succeeds, or at
--- the error level if it does not succeed..
-runCommand :: Text -> PlotM (ExitCode, Text)
-runCommand command = do
+-- the error level if it does not succeed.
+runCommand :: FilePath  -- Directory from which to run the command
+           -> Text      -- Command to run, including executable
+           -> PlotM (ExitCode, Text)
+runCommand wordir command = do
     (ec, processOutput') <- liftIO 
                         $ readProcessStderr 
                         $ setStdout nullStream
                         $ setStderr byteStringOutput 
+                        $ setWorkingDir wordir
                         $ shell (unpack command)
     let processOutput = decodeUtf8With lenientDecode $ toStrict processOutput'
         logFunc = if ec == ExitSuccess
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers.hs b/src/Text/Pandoc/Filter/Plot/Renderers.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers.hs
@@ -27,6 +27,7 @@
     , unavailableToolkits
     , unavailableToolkitsM
     , OutputSpec(..)
+    , Executable(..)
 ) where
 
 import Control.Concurrent.Async.Lifted               (forConcurrently)
@@ -47,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, OutputSpec(..))
+import Text.Pandoc.Filter.Plot.Renderers.Prelude     (executable, Executable(..), OutputSpec(..))
 
 import Text.Pandoc.Filter.Plot.Monad
 
@@ -132,7 +133,8 @@
 -- The executable will need to be found first, hence the IO monad.
 command :: Toolkit 
         -> OutputSpec
-        -> PlotM Text
+        -> Text                -- Executable name (e.g. "python3")
+        -> Text
 command Matplotlib   = matplotlibCommand
 command PlotlyPython = plotlyPythonCommand
 command PlotlyR      = plotlyRCommand
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Bokeh.hs
@@ -30,16 +30,16 @@
 bokehSupportedSaveFormats = [PNG, SVG, HTML]
 
 
-bokehCommand :: OutputSpec -> PlotM Text
-bokehCommand OutputSpec{..} = do
-    exe <- executable Bokeh
-    return [st|#{exe} "#{oScriptPath}"|]
+bokehCommand :: OutputSpec -> Text -> Text
+bokehCommand OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 bokehAvailable :: PlotM Bool
 bokehAvailable = do
-    exe <- executable Bokeh
-    commandSuccess [st|#{exe} -c "import bokeh; import selenium"|]
+    mexe <- executable Bokeh
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> commandSuccess dir [st|#{exe} -c "import bokeh; import selenium"|]
 
 
 -- | Check if `matplotlib.pyplot.show()` calls are present in the script,
@@ -57,7 +57,11 @@
 
 
 bokehCapture :: FigureSpec -> FilePath -> Script
-bokehCapture FigureSpec{..} fname = [st|
+bokehCapture = appendCapture bokehCaptureFragment
+
+
+bokehCaptureFragment :: FigureSpec -> FilePath -> Script
+bokehCaptureFragment FigureSpec{..} fname = [st|
 from bokeh.io import export_png, export_svgs, save
 from bokeh.models import Model
 from bokeh.resources import CDN
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs b/src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/GGPlot2.hs
@@ -20,6 +20,7 @@
     , ggplot2Available
 ) where
 
+import qualified Data.Text as T
 import           Text.Pandoc.Filter.Plot.Renderers.Prelude
 
 
@@ -27,20 +28,29 @@
 ggplot2SupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, TIF]
 
 
-ggplot2Command :: OutputSpec -> PlotM Text
-ggplot2Command OutputSpec{..} = do
-    exe <- executable GGPlot2
-    return [st|#{exe} "#{oScriptPath}"|]
+ggplot2Command :: OutputSpec -> Text -> Text
+ggplot2Command OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 ggplot2Available :: PlotM Bool
 ggplot2Available = do
-    exe <- executable GGPlot2
-    commandSuccess [st|#{exe} -e 'library("ggplot2")'|]
+    mexe <- executable GGPlot2
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -e 'if(!require("ggplot2")) {quit(status=1)}'|]
 
 
 ggplot2Capture :: FigureSpec -> FilePath -> Script
-ggplot2Capture FigureSpec{..} fname = [st|
+ggplot2Capture fs fp = 
+    T.unlines [ "pdf(NULL)" -- Prevent the creation of empty Rplots.pdf
+              , script fs
+              , ggplot2CaptureFragment fs fp
+              ]
+
+
+ggplot2CaptureFragment :: FigureSpec -> FilePath -> Script
+ggplot2CaptureFragment FigureSpec{..} fname = [st|
 library(ggplot2) # just in case
-ggsave("#{fname}", plot = last_plot(), dpi = #{dpi})
+ggsave("#{toRPath fname}", plot = last_plot(), dpi = #{dpi})
 |]
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs b/src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/GNUPlot.hs
@@ -26,23 +26,31 @@
 gnuplotSupportedSaveFormats = [PNG, SVG, EPS, GIF, JPG, PDF]
 
 
-gnuplotCommand :: OutputSpec -> PlotM Text
-gnuplotCommand OutputSpec{..} = do
-    exe <- executable GNUPlot
-    return [st|#{exe} -c "#{oScriptPath}"|]
+gnuplotCommand :: OutputSpec -> Text -> Text
+gnuplotCommand OutputSpec{..} exe = [st|#{exe} -c "#{oScriptPath}"|]
 
 
 gnuplotAvailable :: PlotM Bool
 gnuplotAvailable = do
-    exe <- executable GNUPlot 
-    commandSuccess [st|#{exe} -h|]
+    mexe <- executable GNUPlot
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|"#{exe}" -h|]
 
 
 gnuplotCapture :: FigureSpec -> FilePath -> Script
-gnuplotCapture FigureSpec{..} fname = [st|
+gnuplotCapture = prependCapture gnuplotCaptureFragment
+    where
+        prependCapture f s fp = mconcat [f s fp, "\n", script s]
+
+
+gnuplotCaptureFragment :: FigureSpec -> FilePath -> Script
+gnuplotCaptureFragment FigureSpec{..} fname = [st|
 set terminal #{terminalString saveFormat}
 set output '#{fname}'
 |]
+
 
 -- | Terminal name for supported save formats
 terminalString :: SaveFormat -> Text
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Graphviz.hs
@@ -28,21 +28,23 @@
 graphvizSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, WEBP, GIF]
 
 
-graphvizCommand :: OutputSpec -> PlotM Text
-graphvizCommand OutputSpec{..} = do
-    exe <- executable Graphviz
+graphvizCommand :: OutputSpec -> Text -> Text
+graphvizCommand OutputSpec{..} exe = 
     let fmt = fmap toLower . show . saveFormat $ oFigureSpec
         dpi' = dpi oFigureSpec
-    return [st|#{exe} -T#{fmt} -Gdpi=#{dpi'} -o "#{oFigurePath}" "#{oScriptPath}"|]
+    in [st|#{exe} -T#{fmt} -Gdpi=#{dpi'} -o "#{oFigurePath}" "#{oScriptPath}"|]
 
 
 graphvizAvailable :: PlotM Bool
 graphvizAvailable = do
-    exe <- executable Graphviz
-    commandSuccess [st|#{exe} -?|]
+    mexe <- executable Graphviz
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -?|]
 
 
 -- Graphviz export is entirely based on command-line arguments
 -- so there is no need to modify the script itself.
 graphvizCapture :: FigureSpec -> FilePath -> Script
-graphvizCapture _ _ = mempty
+graphvizCapture FigureSpec{..} _ = script
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Mathematica.hs
@@ -26,19 +26,24 @@
 mathematicaSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
 
 
-mathematicaCommand :: OutputSpec -> PlotM Text
-mathematicaCommand OutputSpec{..} = do
-    exe <- executable Mathematica
-    return [st|#{exe} -script "#{oScriptPath}"|]
+mathematicaCommand :: OutputSpec -> Text -> Text
+mathematicaCommand OutputSpec{..} exe = [st|#{exe} -script "#{oScriptPath}"|]
 
 
 mathematicaAvailable :: PlotM Bool
 mathematicaAvailable = do
-    exe <- executable Mathematica
-    commandSuccess [st|#{exe} -h|] -- TODO: test this
+    mexe <- executable Mathematica
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -h|] -- TODO: test this
 
 
 mathematicaCapture :: FigureSpec -> FilePath -> Script
-mathematicaCapture FigureSpec{..} fname = [st|
+mathematicaCapture = appendCapture mathematicaCaptureFragment
+
+
+mathematicaCaptureFragment :: FigureSpec -> FilePath -> Script
+mathematicaCaptureFragment FigureSpec{..} fname = [st|
 Export["#{fname}", %, #{show saveFormat}, ImageResolution -> #{dpi}]
 |]
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Matlab.hs
@@ -29,10 +29,8 @@
 matlabSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
 
 
-matlabCommand :: OutputSpec -> PlotM Text
-matlabCommand OutputSpec{..} = do
-    exe <- executable Matlab
-    return [st|#{exe} -batch "run('#{oScriptPath}')"|]
+matlabCommand :: OutputSpec -> Text -> Text
+matlabCommand OutputSpec{..} exe = [st|#{exe} -batch "run('#{oScriptPath}')"|]
 
 
 -- On Windows at least, "matlab -help"  actually returns -1, even though the
@@ -44,7 +42,11 @@
 
 
 matlabCapture :: FigureSpec -> FilePath -> Script
-matlabCapture FigureSpec{..} fname = [st|
+matlabCapture = appendCapture matlabCaptureFragment
+
+
+matlabCaptureFragment :: FigureSpec -> FilePath -> Script
+matlabCaptureFragment FigureSpec{..} fname = [st|
 if exist("exportgraphics")>0
     exportgraphics(gcf, '#{fname}', 'Resolution', #{dpi});
 else
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Matplotlib.hs
@@ -36,14 +36,16 @@
 matplotlibSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
 
 
-matplotlibCommand :: OutputSpec -> PlotM Text
-matplotlibCommand OutputSpec{..} = do
-    exe <- executable Matplotlib
-    return [st|#{exe} "#{oScriptPath}"|]
+matplotlibCommand :: OutputSpec -> Text -> Text
+matplotlibCommand OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 matplotlibCapture :: FigureSpec -> FilePath -> Script
-matplotlibCapture FigureSpec{..} fname = [st|
+matplotlibCapture = appendCapture matplotlibCaptureFragment
+
+
+matplotlibCaptureFragment :: FigureSpec -> FilePath -> Script
+matplotlibCaptureFragment FigureSpec{..} fname = [st|
 import matplotlib.pyplot as plt
 plt.savefig(r"#{fname}", dpi=#{dpi}, transparent=#{transparent}, bbox_inches=#{tightBox})
 |]
@@ -60,8 +62,11 @@
 
 matplotlibAvailable :: PlotM Bool
 matplotlibAvailable = do
-    exe <- executable Matplotlib
-    commandSuccess [st|#{exe} -c "import matplotlib"|]
+    mexe <- executable Matplotlib
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -c "import matplotlib"|]
 
 
 -- | Check if `matplotlib.pyplot.show()` calls are present in the script,
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Octave.hs
@@ -27,19 +27,24 @@
 octaveSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, GIF, TIF]
 
 
-octaveCommand :: OutputSpec -> PlotM Text
-octaveCommand OutputSpec{..} = do
-    exe <- executable Octave
-    return [st|#{exe} --no-gui --no-window-system "#{oScriptPath}"|]
+octaveCommand :: OutputSpec -> Text -> Text
+octaveCommand OutputSpec{..} exe = [st|#{exe} --no-gui --no-window-system "#{oScriptPath}"|]
 
 
 octaveAvailable :: PlotM Bool
 octaveAvailable = do
-    exe <- executable Octave
-    commandSuccess [st|#{exe} -h|]
+    mexe <- executable Octave
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -h|]
 
 
 octaveCapture :: FigureSpec -> FilePath -> Script
-octaveCapture _ fname = [st|
+octaveCapture = appendCapture octaveCaptureFragment
+
+
+octaveCaptureFragment :: FigureSpec -> FilePath -> Script
+octaveCaptureFragment _ fname = [st|
 saveas(gcf, '#{fname}')
 |]
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs b/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyPython.hs
@@ -27,19 +27,25 @@
 plotlyPythonSupportedSaveFormats = [PNG, JPG, WEBP, PDF, SVG, EPS, HTML]
 
 
-plotlyPythonCommand :: OutputSpec -> PlotM Text
-plotlyPythonCommand OutputSpec{..} = do
-    exe <- executable PlotlyPython
-    return [st|#{exe} "#{oScriptPath}"|]
+plotlyPythonCommand :: OutputSpec -> Text -> Text
+plotlyPythonCommand OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 plotlyPythonAvailable :: PlotM Bool
 plotlyPythonAvailable = do
-    exe <- executable PlotlyPython
-    commandSuccess [st|#{exe} -c "import plotly.graph_objects"|]
+    mexe <- executable Matplotlib
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -c "import plotly.graph_objects"|]
 
+
 plotlyPythonCapture :: FigureSpec -> FilePath -> Script
-plotlyPythonCapture FigureSpec{..} fname = [st|
+plotlyPythonCapture = appendCapture plotlyPythonCaptureFragment
+
+
+plotlyPythonCaptureFragment :: FigureSpec -> FilePath -> Script
+plotlyPythonCaptureFragment FigureSpec{..} fname = [st|
 import plotly.graph_objects as go
 __current_plotly_figure = next(obj for obj in globals().values() if type(obj) == go.Figure)
 __current_plotly_figure.#{write_method}(r"#{fname}"#{extra_args})
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs b/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/PlotlyR.hs
@@ -20,6 +20,7 @@
     , plotlyRAvailable
 ) where
 
+import qualified Data.Text as T
 import           Text.Pandoc.Filter.Plot.Renderers.Prelude
 
 
@@ -27,20 +28,29 @@
 plotlyRSupportedSaveFormats = [PNG, PDF, SVG, JPG, EPS, HTML]
 
 
-plotlyRCommand :: OutputSpec -> PlotM Text
-plotlyRCommand OutputSpec{..} = do
-    exe <- executable PlotlyR
-    return [st|#{exe} "#{oScriptPath}"|]
+plotlyRCommand :: OutputSpec -> Text -> Text
+plotlyRCommand OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 plotlyRAvailable :: PlotM Bool
 plotlyRAvailable = do
-    exe <- executable GGPlot2
-    commandSuccess [st|#{exe} -e 'library("plotly")'|]
+    mexe <- executable PlotlyR
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -e 'if(!require("plotly")) {quit(status=1)}'|]
 
 
 plotlyRCapture :: FigureSpec -> FilePath -> Script
-plotlyRCapture spec@FigureSpec{..} fname = case saveFormat of
+plotlyRCapture fs fp = 
+    T.unlines [ "pdf(NULL)" -- Prevent the creation of empty Rplots.pdf
+              , script fs
+              , plotlyRCaptureFragment fs fp
+              ]
+
+
+plotlyRCaptureFragment :: FigureSpec -> FilePath -> Script
+plotlyRCaptureFragment spec@FigureSpec{..} fname = case saveFormat of
     HTML -> plotlyRCaptureHtml spec fname
     _    -> plotlyRCaptureStatic spec fname
 
@@ -52,7 +62,7 @@
 library(plotly) # just in case
 library(htmlwidgets)
 p <- last_plot()
-htmlwidgets::saveWidget(as_widget(p), "#{fname}")
+htmlwidgets::saveWidget(as_widget(p), "#{toRPath fname}")
 |]
 
 
@@ -62,5 +72,6 @@
 plotlyRCaptureStatic _ fname = [st|
 library(plotly) # just in case
 if (!require("processx")) install.packages("processx")
-orca(last_plot(), file = "#{fname}")
+pdf(NULL)
+orca(last_plot(), file = "#{toRPath fname}")
 |]
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Plotsjl.hs
@@ -29,19 +29,24 @@
 plotsjlSupportedSaveFormats = [PNG, SVG, PDF]
 
 
-plotsjlCommand :: OutputSpec -> PlotM Text
-plotsjlCommand OutputSpec{..} = do
-    exe <- executable Plotsjl
-    return [st|#{exe} "#{oScriptPath}"|]
+plotsjlCommand :: OutputSpec -> Text -> Text
+plotsjlCommand OutputSpec{..} exe = [st|#{exe} "#{oScriptPath}"|]
 
 
 plotsjlAvailable :: PlotM Bool
 plotsjlAvailable = do
-    exe <- executable Plotsjl
-    commandSuccess [st|#{exe} -e "using Plots"|]
+    mexe <- executable Plotsjl
+    case mexe of 
+        Nothing -> return False
+        Just (Executable dir exe) -> 
+            commandSuccess dir [st|#{exe} -e "using Plots"|]
 
 
 plotsjlCapture :: FigureSpec -> FilePath -> Script
-plotsjlCapture _ fname = [st|
+plotsjlCapture = appendCapture plotsjlCaptureFragment
+
+
+plotsjlCaptureFragment :: FigureSpec -> FilePath -> Script
+plotsjlCaptureFragment _ fname = [st|
 savefig(raw"#{fname}")
 |]
diff --git a/src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs b/src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs
--- a/src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs
+++ b/src/Text/Pandoc/Filter/Plot/Renderers/Prelude.hs
@@ -1,4 +1,4 @@
-
+{-# LANGUAGE OverloadedStrings #-}
 {-|
 Module      : $header$
 Copyright   : (c) Laurent P René de Cotret, 2020
@@ -20,24 +20,36 @@
     , existsOnPath
     , executable
     , OutputSpec(..)
+    , Executable(..)
+    , appendCapture
+    , toRPath
 ) where
 
 import           Data.Maybe                    (isJust)
-import           Data.Text                     (Text, unpack)
+import           Data.Text                     (Text, unpack, pack)
 
 import           System.Directory              (findExecutable)
+import           System.FilePath               (splitFileName, 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 :: Text -> PlotM Bool
-commandSuccess s = do
-    (ec, _) <- runCommand s
+commandSuccess :: FilePath -- Directory from which to run the command
+               -> Text     -- Command to run, including the executable
+               -> PlotM Bool
+commandSuccess fp s = do
+    (ec, _) <- runCommand fp s
     return $ ec == ExitSuccess
 
 
@@ -48,26 +60,31 @@
 
 -- | Try to find the executable and normalise its path.
 -- If it cannot be found, it is left unchanged - just in case.
-tryToFindExe :: String -> IO FilePath
-tryToFindExe fp = findExecutable fp >>= maybe (return fp) return
+tryToFindExe :: String -> IO (Maybe Executable)
+tryToFindExe fp = findExecutable fp >>= return . fmap exeFromPath
 
 
--- | Path to the executable of a toolkit. If the executable can
--- be found, then it will be the full path to it.
-executable :: Toolkit -> PlotM FilePath
-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
+-- | 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
+appendCapture :: (FigureSpec -> FilePath -> Script) 
+              ->  FigureSpec -> FilePath -> Script
+appendCapture f s fp = mconcat [script s, "\n", f s fp]
+
+
 -- | Internal description of all information 
 -- needed to output a figure.
 data OutputSpec = OutputSpec 
@@ -75,3 +92,8 @@
     , oScriptPath    :: FilePath      -- ^ Path to the script to render
     , oFigurePath    :: FilePath      -- ^ Figure output path
     } 
+
+
+-- | R paths use the '/' path separator
+toRPath :: FilePath -> FilePath
+toRPath = fmap (\c -> if isPathSeparator c then '/' else c)
diff --git a/src/Text/Pandoc/Filter/Plot/Scripting.hs b/src/Text/Pandoc/Filter/Plot/Scripting.hs
--- a/src/Text/Pandoc/Filter/Plot/Scripting.hs
+++ b/src/Text/Pandoc/Filter/Plot/Scripting.hs
@@ -27,7 +27,8 @@
 import           Paths_pandoc_plot                 (version)
 
 import           System.Directory                  (createDirectoryIfMissing,
-                                                    doesFileExist, getTemporaryDirectory)
+                                                    doesFileExist, getTemporaryDirectory, 
+                                                    getCurrentDirectory)
 import           System.Exit                       (ExitCode (..))
 import           System.FilePath                   (addExtension,
                                                     normalise, replaceExtension,
@@ -88,40 +89,46 @@
         CheckPassed -> do
             scriptPath <- tempScriptPath spec
             target <- figurePath spec
-            let captureFragment = (capture toolkit) spec target
-                -- Note: for gnuplot, the capture string must be placed
-                --       BEFORE plotting happens. Since this is only really an
-                --       issue for gnuplot, we have a special case.
-                scriptWithCapture = if (toolkit == GNUPlot)
-                                        then mconcat [captureFragment, "\n", script]
-                                        else mconcat [script, "\n", captureFragment]
-            liftIO $ T.writeFile scriptPath scriptWithCapture
-            let outputSpec = OutputSpec { oFigureSpec = spec
-                                        , oScriptPath = scriptPath
-                                        , oFigurePath = target
-                                        }
-            command_ <- command toolkit outputSpec
-            (ec, _) <- runCommand command_
-            case ec of
-                ExitSuccess      -> return   ScriptSuccess
-                ExitFailure code -> do
-                    -- Two possible types of failures: either the script
-                    -- failed because the toolkit was not available, or
-                    -- because of a genuine error
-                    toolkitInstalled <- toolkitAvailable toolkit 
-                    if toolkitInstalled
-                        then return $ ScriptFailure command_ code
-                        else return $ ToolkitNotInstalled toolkit
 
+            -- Check if executable is present
+            exe <- executable toolkit
+            case exe of
+                Nothing -> error $ "Toolkit " <> show toolkit <> " is not installed."
+                Just (Executable exedir exename) -> do
+                    -- Commands are run from the executable directory,
+                    -- so we need to tell the full absolute path where to save the
+                    -- figure
+                    curdir <- liftIO $ getCurrentDirectory
+                    let scriptWithCapture = (capture toolkit) spec (curdir </> target)
 
+                    liftIO $ T.writeFile scriptPath scriptWithCapture
+                    let outputSpec = OutputSpec { oFigureSpec = spec
+                                                , oScriptPath = scriptPath
+                                                , oFigurePath = target
+                                                }
+
+                    let command_ = command toolkit outputSpec exename
+                    (ec, _) <- runCommand exedir command_
+                    case ec of
+                        ExitSuccess      -> return   ScriptSuccess
+                        ExitFailure code -> do
+                            -- Two possible types of failures: either the script
+                            -- failed because the toolkit was not available, or
+                            -- because of a genuine error
+                            toolkitInstalled <- toolkitAvailable toolkit 
+                            if toolkitInstalled
+                                then return $ ScriptFailure command_ code
+                                else return $ ToolkitNotInstalled toolkit
+
+
 -- | Determine the temp script path from Figure specifications
 -- Note that for certain renderers, the appropriate file extension
 -- is important.
 tempScriptPath :: FigureSpec -> PlotM FilePath
 tempScriptPath FigureSpec{..} = do
     let ext = scriptExtension toolkit
-    -- Note that matlab will refuse to process files that don't start with
-    -- a letter... so we append the renderer name
+    -- MATLAB will refuse to process files that don't start with
+    -- a letter
     -- Note that this hash is only so that we are running scripts from unique
     -- file names; it does NOT determine whether this figure should
     -- be rendered or not.
diff --git a/tests/Common.hs b/tests/Common.hs
--- a/tests/Common.hs
+++ b/tests/Common.hs
@@ -31,7 +31,9 @@
 
 
 defaultTestConfig :: Configuration
-defaultTestConfig = defaultConfiguration {logVerbosity=Silent, logSink=StdErr}
+defaultTestConfig = defaultConfiguration { logVerbosity = Silent
+                                         , logSink = StdErr --LogFile "test_log.txt"
+                                         }
 
 -------------------------------------------------------------------------------
 -- Test that plot files and source files are created when the filter is run
@@ -66,6 +68,7 @@
     where
         include Matplotlib   = "tests/includes/matplotlib.py"
         include PlotlyPython = "tests/includes/plotly-python.py"
+        include PlotlyR      = "tests/includes/plotly-r.r"
         include Matlab       = "tests/includes/matlabplot.m"
         include Mathematica  = "tests/includes/mathplot.m"
         include Octave       = "tests/includes/octave.m"
@@ -73,7 +76,7 @@
         include GNUPlot      = "tests/includes/gnuplot.gp"
         include Graphviz     = "tests/includes/graphviz.dot"
         include Bokeh        = "tests/includes/bokeh.py"
-        include Plotsjl   = "tests/includes/plotsjl.jl"
+        include Plotsjl      = "tests/includes/plotsjl.jl"
 
 -------------------------------------------------------------------------------
 -- Test that the files are saved in the appropriate format
@@ -262,6 +265,7 @@
 trivialContent :: Toolkit -> Script
 trivialContent Matplotlib   = "import matplotlib.pyplot as plt\n"
 trivialContent PlotlyPython = "import plotly.graph_objects as go; fit = go.Figure()\n"
+trivialContent PlotlyR      = "library(plotly)\nfig <- plot_ly(midwest, x = ~percollege, color = ~state, type = \"box\")"
 trivialContent Matlab       = "figure('visible', 'off')\n"
 trivialContent Mathematica  = "\n"
 trivialContent Octave       = "figure('visible', 'off')\nplot (-10:0.1:10);"
