hakyll
hakyll copied to clipboard
Hakyll, pandoc-crossref filter and bibtex
Hi, I'm trying to put bibtex and pandoc-crossref to work in a Hakyll wiki config. I have this almost default code:
match "posts/*" $ do
route $ setExtension "html"
compile $ do
-- modification begin
item <- getUnderlying
bibFile <- liftM (fromMaybe "") $ getMetadataField item "biblio"
cslFile <- liftM (fromMaybe "chicago") $ getMetadataField item "csl"
let compiler = if bibFile /= ""
then bibtexCompiler cslFile bibFile
else pandocCompilerWithTransformM defaultHakyllReaderOptions pandocOptions (transformer "pandoc-crossref" defaultHakyllReaderOptions pandocOptions)
compiler
-- modification end
>>= loadAndApplyTemplate "templates/post.html" postCtx
>>= loadAndApplyTemplate "templates/default.html" postCtx
>>= relativizeUrls
If the post has a bibtex file attached, process the bibtex, else skip bibtex processing, working only with the pandoc-crossref.
My problem is the bibtexCompiler code. I want to put pandoc-crossref inside it:
bibtexCompiler :: String -> String -> Compiler (Item String)
bibtexCompiler cslFileName bibFileName = do
csl <- load (fromFilePath $ "csl/"++cslFileName)
bib <- load (fromFilePath $ "bib/"++bibFileName)
--liftM (writePandocWith pandocOptions)
-- (getResourceBody >>= readPandocBiblio def csl bib)
writePandocWith pandocOptions <$>
(traverse transformer "pandoc-crossref" def pandocOptions =<< readPandocBiblio def csl bib =<< getResourceBody)
transformer :: Script -> ReaderOptions -> WriterOptions -> (Pandoc -> Compiler Pandoc)
transformer script reader_opts writer_opts pandoc =
do let input_json = writeJSON writer_opts pandoc
output_json <- unixFilter script [] input_json
return $
either (error.show) id $ -- this line needs to be uncommented atm.
readJSON reader_opts output_json
I've seen the code for pandocCompilerWithTransformM:
pandocCompilerWithTransformM :: ReaderOptions -> WriterOptions
-> (Pandoc -> Compiler Pandoc)
-> Compiler (Item String)
pandocCompilerWithTransformM ropt wopt f =
writePandocWith wopt <$>
(traverse f =<< readPandocWith ropt =<< getResourceBody)
That's why I'm trying to use this code, replacing readPandocWith ropt
with readPandocBiblio def csl bib
, which has the same return type. But it doesn't work.
It compiles and runs correctly, and it shows the bibliography and the Figure 1, but the citation shows [@author], even though it shows [1]. The reason I create the issue here is that whether I remove the traverse transformer ...
, the citation works (it shows [1]), but the pandoc-crossref not.
Thanks
Could you post a sample site to a gist? It would simplify working on this issue (if it's still an issue).
Yes, it would be useful if you could dump a standalone .zip
or gist so we can easily reproduce it.
I was looking for the same thing. A perhaps somewhat kludgy solution which, however, gives me correct citations, as well as cross-references, is to use the Pandoc program itself as a filter. From my site program:
bibtexCompiler :: String -> Compiler (Item String)
bibtexCompiler lang = do
csl <- load (fromFilePath $ lang ++ ".csl")
bib <- load "static-dust.bib"
getResourceBody
>>= withItemBody (unixFilter "pandoc" [ "-F"
, "pandoc-crossref"
, "-t"
, "markdown"
, "-M"
, "crossrefYaml=pandoc-crossref-"++lang++".yaml"
])
>>= readPandocBiblio pandocReaderOptions csl bib
>>= return . writePandocWith pandocWriterOptions
For pandocCompiler
users here's the code that solved the problem for me:
pandocCompilerWithTransformM defaultHakyllReaderOptions defaultHakyllWriterOptions plantumlFilter
where
plantumlFilter = recompilingUnsafeCompiler
. runIOorExplode
. applyFilters noEngine def
[JSONFilter "/usr/local/lib/python3.9/site-packages/pandoc_plantuml_filter.py"]
[]