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:
pandocCompiler
pandocCompilerWith
pandocCompilerWithTransform
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
pandocCompilerWith
compiler.
Subsequently, we can use customCompiler
everywhere we were previously using
pandocCompiler
, and without having to repeat our options.