Images and Compilation Units

Shake allows you to use external files as compilation units. This is usually a 3-step process. We walk through adding R support in this document.

We first need to define a build action for taking an output path and running the corresponding source file to produce an output image.

fromHaskell :: (MonadThrow m, MonadAction m) => [String] -> Within Rel (Path Rel File) -> m ()
fromHaskell opts out = do
  src <- blinkAndMapM sourceFolder withHsExtension out
  command_ [] "runhaskell" $ (toFilePath . fromWithin $ src) : opts

buildRPlot :: (MonadThrow m, MonadAction m) => Within Rel (Path Rel File) -> m ()
buildRPlot out = fromHaskell ["-o", toFilePath . fromWithin $ out] out

We then have to add a Shake pattern rule in the main shake body, to match on any output image and call buildRPlot on it.

("plots//*.png" `within` outputFolder) %^> buildRPlot

Finally, we add a phony rule to allow us to run shake plots and build all plots simultaneously.

phony "plots" $
  getDirectoryFiles sourceFolder ["posts/*.md"] >>= mapM withPngExtension >>= needIn outputFolder

Shake will take all the .hs files in /site/plots/ and compile them to images. You can add your own rules to run external commands and copy them to the output directory. To include an image in the output, just reference it using normal markdown syntax. In this case the file will end up in /plots/, include it like so:

![Cluster Example](/plots/cluster.png)