Skip to content

Commit

Permalink
Support processing multiple bibliography files (jaspervdj#898)
Browse files Browse the repository at this point in the history
* Support processing multiple bibliography files

Pandoc Citeproc supports taking multiple bibliography files as input by
passing a MetaList to the "bibliography" key instead of a single string.
This keeps the original processPandocBiblio function taking a single
bibliography, and adds a processPandocBiblios taking a list; the
original function now just calls the new one.

* Add tests for readPandocBiblios
  • Loading branch information
benjamineskola authored Oct 25, 2021
1 parent b8df202 commit f7f2cdd
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 15 deletions.
3 changes: 3 additions & 0 deletions hakyll.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,13 @@ Extra-source-files:
CHANGELOG.md
tests/data/biblio/chicago.csl
tests/data/biblio/cites-meijer.golden
tests/data/biblio/cites-multiple.golden
tests/data/biblio/cites-multiple.markdown
tests/data/biblio/default.html
tests/data/biblio/page.markdown
tests/data/biblio/refs.bib
tests/data/biblio/refs.yaml
tests/data/biblio/refs2.yaml
tests/data/embed.html
tests/data/example.md
tests/data/example.md.metadata
Expand Down
51 changes: 36 additions & 15 deletions lib/Hakyll/Web/Pandoc/Biblio.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ module Hakyll.Web.Pandoc.Biblio
, Biblio (..)
, biblioCompiler
, readPandocBiblio
, readPandocBiblios
, processPandocBiblio
, processPandocBiblios
, pandocBiblioCompiler
) where

Expand All @@ -46,7 +48,7 @@ import Text.Pandoc (Extension (..), Pandoc,
enableExtension)
import qualified Text.Pandoc as Pandoc
import qualified Text.Pandoc.Citeproc as Pandoc (processCitations)
import System.FilePath (takeExtension)
import System.FilePath (addExtension, takeExtension)


--------------------------------------------------------------------------------
Expand Down Expand Up @@ -88,17 +90,30 @@ readPandocBiblio :: ReaderOptions
-> Item Biblio
-> (Item String)
-> Compiler (Item Pandoc)
readPandocBiblio ropt csl biblio item = do
readPandocBiblio ropt csl biblio = readPandocBiblios ropt csl [biblio]

readPandocBiblios :: ReaderOptions
-> Item CSL
-> [Item Biblio]
-> (Item String)
-> Compiler (Item Pandoc)
readPandocBiblios ropt csl biblios item = do
pandoc <- readPandocWith ropt item
processPandocBiblio csl biblio pandoc
processPandocBiblios csl biblios pandoc


--------------------------------------------------------------------------------
processPandocBiblio :: Item CSL
-> Item Biblio
-> (Item Pandoc)
-> Compiler (Item Pandoc)
processPandocBiblio csl biblio item = do
processPandocBiblio csl biblio = processPandocBiblios csl [biblio]

processPandocBiblios :: Item CSL
-> [Item Biblio]
-> (Item Pandoc)
-> Compiler (Item Pandoc)
processPandocBiblios csl biblios item = do
-- It's not straightforward to use the Pandoc API as of 2.11 to deal with
-- citations, since it doesn't export many things in 'Text.Pandoc.Citeproc'.
-- The 'citeproc' package is also hard to use.
Expand All @@ -110,19 +125,25 @@ processPandocBiblio csl biblio item = do
-- ersatz filesystem.
let Pandoc.Pandoc (Pandoc.Meta meta) blocks = itemBody item
cslFile = Pandoc.FileInfo zeroTime . unCSL $ itemBody csl
bibFile = Pandoc.FileInfo zeroTime . unBiblio $ itemBody biblio
bibFileType = takeExtension $ toFilePath $ itemIdentifier biblio
internalBibFileName = "_hakyll/refs." ++ bibFileType

addBiblioFiles = \st -> st
{ Pandoc.stFiles =
Pandoc.insertInFileTree "_hakyll/style.csl" cslFile .
Pandoc.insertInFileTree internalBibFileName bibFile $
Pandoc.stFiles st
}
bibFiles = zipWith (\x y ->
( addExtension ("_hakyll/bibliography-" ++ show x)
(takeExtension $ toFilePath $ itemIdentifier y)
, Pandoc.FileInfo zeroTime . unBiblio . itemBody $ y
)
)
[0 ..]
biblios

stFiles = foldr ((.) . uncurry Pandoc.insertInFileTree)
(Pandoc.insertInFileTree "_hakyll/style.csl" cslFile)
bibFiles

addBiblioFiles = \st -> st { Pandoc.stFiles = stFiles $ Pandoc.stFiles st }

biblioMeta = Pandoc.Meta .
Map.insert "csl" (Pandoc.MetaString "_hakyll/style.csl") .
Map.insert "bibliography" (Pandoc.MetaString $ T.pack internalBibFileName) $
Map.insert "bibliography"
(Pandoc.MetaList $ map (Pandoc.MetaString . T.pack . fst) bibFiles) $
meta
errOrPandoc = Pandoc.runPure $ do
Pandoc.modifyPureState addBiblioFiles
Expand Down
36 changes: 36 additions & 0 deletions tests/Hakyll/Web/Pandoc/Biblio/Tests.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ tests :: TestTree
tests = testGroup "Hakyll.Web.Pandoc.Biblio.Tests" $
[ goldenTest01
, goldenTest02
, goldenTest03
]

--------------------------------------------------------------------------------
Expand Down Expand Up @@ -98,3 +99,38 @@ goldenTest02 =
cleanTestEnv

return output)

goldenTest03 :: TestTree
goldenTest03 =
goldenVsString
"biblio03"
(goldenTestsDataDir </> "cites-multiple.golden")
(do
-- Code lifted from https://github.com/jaspervdj/hakyll-citeproc-example.
logger <- Logger.new Logger.Error
let config = testConfiguration { providerDirectory = goldenTestsDataDir }
_ <- run RunModeNormal config logger $ do
let myPandocBiblioCompiler = do
csl <- load "chicago.csl"
bib1 <- load "refs.bib"
bib2 <- load "refs2.yaml"
getResourceBody >>=
readPandocBiblios defaultHakyllReaderOptions csl [bib1, bib2] >>=
return . writePandoc

match "default.html" $ compile templateCompiler
match "chicago.csl" $ compile cslCompiler
match "refs.bib" $ compile biblioCompiler
match "refs2.yaml" $ compile biblioCompiler
match "cites-multiple.markdown" $ do
route $ setExtension "html"
compile $
myPandocBiblioCompiler >>=
loadAndApplyTemplate "default.html" defaultContext

output <- fmap LBS.fromStrict $ B.readFile $
destinationDirectory testConfiguration </> "cites-multiple.html"

cleanTestEnv

return output)
20 changes: 20 additions & 0 deletions tests/data/biblio/cites-multiple.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>This page cites a paper and a book.</title>
</head>
<body>
<h1>This page cites a paper and a book.</h1>
<p>I would like to cite one of my favourite papers <span class="citation" data-cites="meijer1991functional">(Meijer, Fokkinga, and Paterson 1991)</span> here.</p>
<p>And also a book <span class="citation" data-cites="lipovaca2012">(Lipovača 2012)</span>.</p>
<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
<div id="ref-lipovaca2012" class="csl-entry" role="doc-biblioentry">
Lipovača, Miran. 2012. <em>Learn You a Haskell for Great Good! A Beginner’s Guide</em>. San Francisco, CA: No Starch Press.
</div>
<div id="ref-meijer1991functional" class="csl-entry" role="doc-biblioentry">
Meijer, Erik, Maarten Fokkinga, and Ross Paterson. 1991. <span>“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire.”</span> In <em>Conference on Functional Programming Languages and Computer Architecture</em>, 124–44. Springer.
</div>
</div>
</body>
</html>
7 changes: 7 additions & 0 deletions tests/data/biblio/cites-multiple.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: This page cites a paper and a book.
---

I would like to cite one of my favourite papers [@meijer1991functional] here.

And also a book [@lipovaca2012].
18 changes: 18 additions & 0 deletions tests/data/biblio/refs2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
references:
- id: lipovaca2012
author:
- family: Lipovača
given: Miran
call-number: QA76.73.H37 L69 2012
event-place: San Francisco, CA
ISBN: 978-1-59327-283-8
issued:
- year: 2012
number-of-pages: '375'
publisher: No Starch Press
publisher-place: San Francisco, CA
source: Library of Congress ISBN
title: Learn you a Haskell for great good! a beginner's guide
type: book
...

0 comments on commit f7f2cdd

Please sign in to comment.