hakyll icon indicating copy to clipboard operation
hakyll copied to clipboard

Hakyll, pandoc-crossref filter and bibtex

Open anderflash opened this issue 9 years ago • 4 comments

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

anderflash avatar Aug 12 '15 00:08 anderflash

Could you post a sample site to a gist? It would simplify working on this issue (if it's still an issue).

krsch avatar Oct 12 '15 19:10 krsch

Yes, it would be useful if you could dump a standalone .zip or gist so we can easily reproduce it.

jaspervdj avatar Oct 13 '15 08:10 jaspervdj

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

klpn avatar Dec 28 '17 16:12 klpn

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"]
          []

arrowd avatar Mar 13 '24 10:03 arrowd