In my previous post I described a Hakyll site extension that allows a blog author to treat their raw markdown files as Haskell code for the purposes of generating site resources. It’s much more common for Haskell bloggers to make literate Haskell blog posts for the purposes of distributing runnable example code to readers. In this post we’ll make a small tweak so that our final browser-rendered result is literate haskell friendly for readers as well.
Updating the Code Renderer
Only a couple of small tweaks are needed since we were previously rendering our markdown via pandoc
.
First, we need to make a pandoc
an explicit dependency on our site generator. This is needed because hakyll
does not reexport the necessary pandoc
extensions and options modules.
build-depends: base == 4.*
, hakyll == 4.12.*
-----------------------------------------------
, pandoc
Next we’ll tweak the renderer to enable the literate Haskell pandoc
extension.
...
import Text.Pandoc.Extensions
import Text.Pandoc.Options
...
-- Tweaking the Hakyll defaults to include
-- enabling literate haskell
myWriterOptions :: WriterOptions
myWriterOptions =
let exts = writerExtensions defaultHakyllWriterOptions in
defaultHakyllWriterOptions {
writerExtensions = enableExtension Ext_literate_haskell exts
}
-- A helper custom pandoc renderer so we don't have to lug
-- around our custom options
myRenderPandoc :: Item String -> Compiler (Item String)
myRenderPandoc = renderPandocWith defaultHakyllReaderOptions myWriterOptions
-- Update our blog post rules to use the custom compiler
blogPostRules :: Compiler () -> Rules ()
blogPostRules preProcess = do
route (setExtension "html")
compile (
preProcess -- runs the markdown as code
>> getResourceString
>>= applyAsTemplate postCtx
>>= myRenderPandoc -- renders the post with bird (>) syntax
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls )
Note, I have some extra stuff in there for some of my other blog posts (and elided some of the really unnecessary stuff), all you should need to do is include your myRenderPandoc
that uses your custom WriterOptions
then hakyll
and pandoc
will happily render your HTML in a literate haskell friendly manner.
This post uses this new renderer. When hakyll
builds it will run the following code:
and you, dear reader, can copy-and-paste this file from your browser, save it as a .lhs
file and run it with runghc
.
That’s about it! Just enable that one pandoc
extension then you and your readers can run code together.