Citations and Math in Hakyll
This blog recently started using the Hakyll static site generator. There are many reasons for the change, the main ones being that static generation is a better overall fit and that Hakyll uses Pandoc.
So far, the only thing that has taxed my beginner’s knowledge of Haskell is supporting citations and math at the same time:
-- In the main function of site.hs
"assets/*.bib" $ compile biblioCompiler
match "assets/*.csl" $ compile cslCompiler match
-- Somewhere at the top level of site.hs
customPandocCompiler :: Compiler (Item String)
= do
customPandocCompiler <- load $ fromFilePath "assets/apa.csl"
csl <- load $ fromFilePath "assets/citations.bib"
bib fmap write (getResourceString >>= read csl bib)
where
read = readPandocBiblio defaultHakyllReaderOptions
= writePandocWith writerOptions
write
writerOptions :: WriterOptions
= defaultHakyllWriterOptions
writerOptions = MathJax ""
{ writerHTMLMathMethod }
… and then then use customPandocCompiler
in place of pandocCompiler
.
Doing it only took those few lines of code, but I had to puzzle out some of what’s going on in the Hakyll codebase before I could write them. The Internet had several examples of using those options separately, but it wasn’t obvious how to combine them.
There were two key points to the solution:
- Hakyll source uses “compiler” to mean any stage (of any size) of the compilation process. What would be a rule, a command, a target, or an entire build config in some other build system are all all called “compilers” in Hakyll. In hindsight, that’s part of a pattern: Haskell programmers like to use trees where others would use a hierarchy.
- When the answer isn’t obvious, it usually is obvious to someone who assumes the answer is
fmap
orbind
or whatever the appropriate popular Haskell idiom would be and then looks through type signatures and type class implementations to find out what the operands are.
Overall, I like Hakyll. Static generation has been more flexible, and Pandoc is my favorite way to generate documents. The integration issues of scripting a library layered on top of another library have put me on a crash course of reading other people’s Haskell code, but I was sort of hoping for that.
Updates
- 2016-03-23
- Updated the code to support
link-citations: true
in the YAML metadata and added a conclusion.