Custom Pandoc Options with Hakyll 4
Pandoc has a huge set of extensions which are not enabled by default and whilst Hakyll does enable quite a few in its own options (like footnotes), I wanted to add support for definition lists.
In Hakyll, the best way to do this seems to be to implement a custom content compiler, as this can then be used everywhere you render content. This is exactly what I did.
The first thing was to look up the reference to the default compilers and see what was already there. Hakyll provides:
pandocCompilerpandocCompilerWithpandocCompilerWithTransform
The second of these allows you to pass in options (ReaderOptions and
WriterOptions) and is actually called by the first but with only the default
options. The implementation of pandocCompiler looks like:
pandocCompiler :: Compiler (Item String)
pandocCompiler =
    pandocCompilerWith defaultHakyllReaderOptions defaultHakyllWriterOptions
Which gives us both the pattern to copy and the type declaration. The next step is to add on custom options to the defaults. Pandoc gives a list of the options that can be passed to it in it’s documentation.
The defaultHakyllWriterOptions are defined as a set, so
we’ll need to add to that set and we’ll also need to be able to access the
Pandoc options, so first import those:
import qualified Data.Set as S
import           Text.Pandoc.Options
Then, we need to build up the custom compiler. That looks like this:
customPandocCompiler :: Compiler (Item String)
customPandocCompiler =
    let customExtensions = [Ext_definition_lists]
        defaultExtensions = writerExtensions defaultHakyllWriterOptions
        newExtensions = foldr S.insert defaultExtensions customExtensions
        writerOptions = defaultHakyllWriterOptions {
                          writerExtensions = newExtensions
                        }
    in pandocCompilerWith defaultHakyllReaderOptions writerOptions
(To see it in place, you can see the version in the repository.)
To walk through the compiler:
- We set the list of extensions we wish to apply.
 - Compute the default set of extensions.
 - Insert our list of extensions into the set.
 - Initialise the writer options.
 - Pass that over to the 
pandocCompilerWithcompiler. 
Subsequently, we can use customCompiler everywhere we were previously using
pandocCompiler, and without having to repeat our options.