@@ -1,11 +1,19 @@
1-- | Wraps pandocs bibiliography handling
1-- | Wraps pandocs bibiliography handling
3+-- In order to add a bibliography, you will need a bibliography file (e.g.
4+-- @.bib@) and a CSL file (@.csl@). Both need to be compiled with their
5+-- respective compilers ('biblioCompiler' and 'cslCompiler'). Then, you can
6+-- refer to these files when you use 'pageReadPandocBiblio'. This function also
7+-- takes a parser state for completeness -- you can use
8+-- 'defaultHakyllParserState' if you're unsure.
2{-# LANGUAGE Arrows, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
10{-# LANGUAGE Arrows, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
3module Hakyll.Web.Pandoc.Biblio
11module Hakyll.Web.Pandoc.Biblio
5 , cslCompiler
13 , cslCompiler
6− , References (..)
14+ , Biblio (..)
7− , referencesCompiler
15+ , biblioCompiler
8− , processBiblioCompiler
16+ , pageReadPandocBiblio
11import Control.Applicative ((<$>))
19import Control.Applicative ((<$>))
@@ -13,7 +21,7 @@ import Control.Arrow (arr, returnA)
13import Data.Typeable (Typeable)
21import Data.Typeable (Typeable)
15import Data.Binary (Binary (..))
23import Data.Binary (Binary (..))
16−import Text.Pandoc (Pandoc)
24+import Text.Pandoc (Pandoc, ParserState (..))
17import Text.Pandoc.Biblio (processBiblio)
25import Text.Pandoc.Biblio (processBiblio)
18import qualified Text.CSL as CSL
26import qualified Text.CSL as CSL
@@ -22,6 +30,7 @@ import Hakyll.Core.Identifier
22import Hakyll.Core.Resource
30import Hakyll.Core.Resource
23import Hakyll.Core.Writable
31import Hakyll.Core.Writable
24import Hakyll.Web.Page
32import Hakyll.Web.Page
33+import Hakyll.Web.Pandoc
26newtype CSL = CSL FilePath
35newtype CSL = CSL FilePath
27 deriving (Binary, Show, Typeable, Writable)
36 deriving (Binary, Show, Typeable, Writable)
@@ -29,29 +38,36 @@ newtype CSL = CSL FilePath
29cslCompiler :: Compiler Resource CSL
38cslCompiler :: Compiler Resource CSL
30cslCompiler = arr (CSL . unResource)
39cslCompiler = arr (CSL . unResource)
32−newtype References = References [CSL.Reference]
41+newtype Biblio = Biblio [CSL.Reference]
33 deriving (Show, Typeable)
42 deriving (Show, Typeable)
35−instance Binary References where
44+instance Binary Biblio where
37− get = References . read <$> get
46+ get = Biblio . read <$> get
38− put (References rs) = put $ show rs
47+ put (Biblio rs) = put $ show rs
40−instance Writable References where
49+instance Writable Biblio where
41 write _ _ = return ()
50 write _ _ = return ()
43−referencesCompiler :: Compiler Resource References
52+biblioCompiler :: Compiler Resource Biblio
44−referencesCompiler = unsafeCompiler $
53+biblioCompiler = unsafeCompiler $
45− fmap References . CSL.readBiblioFile . unResource
54+ fmap Biblio . CSL.readBiblioFile . unResource
56+pageReadPandocBiblio :: ParserState
47−processBiblioCompiler :: Identifier CSL
57+ -> Identifier CSL
48− -> Identifier References
58+ -> Identifier Biblio
49− -> Compiler (Page Pandoc) (Page Pandoc)
59+ -> Compiler (Page String) (Page Pandoc)
50−processBiblioCompiler csl refs = proc page -> do
60+pageReadPandocBiblio state csl refs = proc page -> do
51− let body = pageBody page
52 CSL csl' <- require_ csl -< ()
61 CSL csl' <- require_ csl -< ()
53− References refs' <- require_ refs -< ()
62+ Biblio refs' <- require_ refs -< ()
63+ -- We need to know the citation keys, add then *before* actually parsing the
64+ -- actual page. If we don't do this, pandoc won't even consider them
66+ let cits = map CSL.refId refs'
67+ state' = state {stateCitations = stateCitations state ++ cits}
68+ pandocPage <- pageReadPandocWithA -< (state', page)
69+ let pandoc = pageBody pandocPage
54− body' <- unsafeCompiler (tuc processBiblio) -< (csl', refs', body)
70+ pandoc' <- unsafeCompiler (tuc processBiblio) -< (csl', refs', pandoc)
55− returnA -< page {pageBody = body'}
71+ returnA -< pandocPage {pageBody = pandoc'}
57 tuc f (x, y, z) = f x y z
73 tuc f (x, y, z) = f x y z