-- | Wraps pandocs bibiliography handling -- -- In order to add a bibliography, you will need a bibliography file (e.g. -- @.bib@) and a CSL file (@.csl@). Both need to be compiled with their -- respective compilers ('biblioCompiler' and 'cslCompiler'). Then, you can -- refer to these files when you use 'pageReadPandocBiblio'. This function also -- takes a parser state for completeness -- you can use -- 'defaultHakyllParserState' if you're unsure. -- {-# LANGUAGE Arrows, DeriveDataTypeable, GeneralizedNewtypeDeriving #-} module Hakyll.Web.Pandoc.Biblio ( CSL , cslCompiler , Biblio (..) , biblioCompiler , pageReadPandocBiblio ) where import Control.Applicative ((<$>)) import Control.Arrow (arr, returnA) import Data.Typeable (Typeable) import Data.Binary (Binary (..)) import Text.Pandoc (Pandoc, ParserState (..)) import Text.Pandoc.Biblio (processBiblio) import qualified Text.CSL as CSL import Hakyll.Core.Compiler import Hakyll.Core.Identifier import Hakyll.Core.Resource import Hakyll.Core.Writable import Hakyll.Web.Page import Hakyll.Web.Pandoc newtype CSL = CSL FilePath deriving (Binary, Show, Typeable, Writable) cslCompiler :: Compiler Resource CSL cslCompiler = arr (CSL . unResource) newtype Biblio = Biblio [CSL.Reference] deriving (Show, Typeable) instance Binary Biblio where -- Ugly. get = Biblio . read <$> get put (Biblio rs) = put $ show rs instance Writable Biblio where write _ _ = return () biblioCompiler :: Compiler Resource Biblio biblioCompiler = unsafeCompiler $ fmap Biblio . CSL.readBiblioFile . unResource pageReadPandocBiblio :: ParserState -> Identifier CSL -> Identifier Biblio -> Compiler (Page String) (Page Pandoc) pageReadPandocBiblio state csl refs = proc page -> do CSL csl' <- require_ csl -< () Biblio refs' <- require_ refs -< () -- We need to know the citation keys, add then *before* actually parsing the -- actual page. If we don't do this, pandoc won't even consider them -- citations! let cits = map CSL.refId refs' state' = state {stateCitations = stateCitations state ++ cits} pandocPage <- pageReadPandocWithA -< (state', page) let pandoc = pageBody pandocPage pandoc' <- unsafeCompiler processBiblio' -< (csl', refs', pandoc) returnA -< pandocPage {pageBody = pandoc'} where processBiblio' (c, r, p) = processBiblio c Nothing r p