on master help sign in
Fix bibliography handling
commit88519fef556deee41a30550420243fc3ca86606b authorJasper Van der Jeugt <m@jaspervdj.be> dateTue 22 Nov 2011, 08:39 (15 years ago) parentd3140f3
3 files changed+50−24
src/Hakyll.hs+2 src/Hakyll/Web/Pandoc.hs+12−4 src/Hakyll/Web/Pandoc/Biblio.hs+36−20
src/Hakyll.hs+2
@@ -25,6 +25,7 @@ module Hakyll
2525 , module Hakyll.Web.Page.Metadata
2626 , module Hakyll.Web.Page.Read
2727 , module Hakyll.Web.Pandoc
28+ , module Hakyll.Web.Pandoc.Biblio
2829 , module Hakyll.Web.Pandoc.FileType
2930 , module Hakyll.Web.Urls
3031 , module Hakyll.Web.Urls.Relativize
@@ -57,6 +58,7 @@ import Hakyll.Web.Page.List
5758import Hakyll.Web.Page.Metadata
5859import Hakyll.Web.Page.Read
5960import Hakyll.Web.Pandoc
61+import Hakyll.Web.Pandoc.Biblio
6062import Hakyll.Web.Pandoc.FileType
6163import Hakyll.Web.Urls
6264import Hakyll.Web.Urls.Relativize
src/Hakyll/Web/Pandoc.hs+12−4
@@ -10,6 +10,7 @@ module Hakyll.Web.Pandoc
1010 -- * Functions working on pages/compilers
1111 , pageReadPandoc
1212 , pageReadPandocWith
13+ , pageReadPandocWithA
1314 , pageRenderPandoc
1415 , pageRenderPandocWith
1516
@@ -20,7 +21,7 @@ module Hakyll.Web.Pandoc
2021
2122import Prelude hiding (id)
2223import Control.Applicative ((<$>))
23−import Control.Arrow ((>>^), (&&&))
24+import Control.Arrow ((>>>), (>>^), (&&&), (***))
2425import Control.Category (id)
2526import Data.Maybe (fromMaybe)
2627
@@ -28,6 +29,7 @@ import Text.Pandoc
2829
2930import Hakyll.Core.Compiler
3031import Hakyll.Core.Identifier
32+import Hakyll.Core.Util.Arrow
3133import Hakyll.Web.Pandoc.FileType
3234import Hakyll.Web.Page.Internal
3335
@@ -78,10 +80,16 @@ pageReadPandoc = pageReadPandocWith defaultHakyllParserState
7880-- | Read the resource using pandoc
7981--
8082pageReadPandocWith :: ParserState -> Compiler (Page String) (Page Pandoc)
81−pageReadPandocWith state =
82− id &&& getIdentifier &&& getFileType >>^ pageReadPandocWith'
83+pageReadPandocWith state = constA state &&& id >>> pageReadPandocWithA
84+
85+-- | Read the resource using pandoc. This is a (rarely needed) variant, which
86+-- comes in very useful when the parser state is the result of some arrow.
87+--
88+pageReadPandocWithA :: Compiler (ParserState, Page String) (Page Pandoc)
89+pageReadPandocWithA =
90+ id *** id &&& getIdentifier &&& getFileType >>^ pageReadPandocWithA'
8391 where
84− pageReadPandocWith' (p, (i, t)) = readPandocWith state t (Just i) <$> p
92+ pageReadPandocWithA' (s, (p, (i, t))) = readPandocWith s t (Just i) <$> p
8593
8694-- | Render the resource using pandoc
8795--
src/Hakyll/Web/Pandoc/Biblio.hs+36−20
@@ -1,11 +1,19 @@
11-- | Wraps pandocs bibiliography handling
2+--
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.
9+--
210{-# LANGUAGE Arrows, DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
311module Hakyll.Web.Pandoc.Biblio
412 ( CSL
513 , cslCompiler
6− , References (..)
7− , referencesCompiler
8− , processBiblioCompiler
14+ , Biblio (..)
15+ , biblioCompiler
16+ , pageReadPandocBiblio
917 ) where
1018
1119import Control.Applicative ((<$>))
@@ -13,7 +21,7 @@ import Control.Arrow (arr, returnA)
1321import Data.Typeable (Typeable)
1422
1523import Data.Binary (Binary (..))
16−import Text.Pandoc (Pandoc)
24+import Text.Pandoc (Pandoc, ParserState (..))
1725import Text.Pandoc.Biblio (processBiblio)
1826import qualified Text.CSL as CSL
1927
@@ -22,6 +30,7 @@ import Hakyll.Core.Identifier
2230import Hakyll.Core.Resource
2331import Hakyll.Core.Writable
2432import Hakyll.Web.Page
33+import Hakyll.Web.Pandoc
2534
2635newtype CSL = CSL FilePath
2736 deriving (Binary, Show, Typeable, Writable)
@@ -29,29 +38,36 @@ newtype CSL = CSL FilePath
2938cslCompiler :: Compiler Resource CSL
3039cslCompiler = arr (CSL . unResource)
3140
32−newtype References = References [CSL.Reference]
41+newtype Biblio = Biblio [CSL.Reference]
3342 deriving (Show, Typeable)
3443
35−instance Binary References where
44+instance Binary Biblio where
3645 -- Ugly.
37− get = References . read <$> get
38− put (References rs) = put $ show rs
46+ get = Biblio . read <$> get
47+ put (Biblio rs) = put $ show rs
3948
40−instance Writable References where
49+instance Writable Biblio where
4150 write _ _ = return ()
4251
43−referencesCompiler :: Compiler Resource References
44−referencesCompiler = unsafeCompiler $
45− fmap References . CSL.readBiblioFile . unResource
52+biblioCompiler :: Compiler Resource Biblio
53+biblioCompiler = unsafeCompiler $
54+ fmap Biblio . CSL.readBiblioFile . unResource
4655
47−processBiblioCompiler :: Identifier CSL
48− -> Identifier References
49− -> Compiler (Page Pandoc) (Page Pandoc)
50−processBiblioCompiler csl refs = proc page -> do
51− let body = pageBody page
56+pageReadPandocBiblio :: ParserState
57+ -> Identifier CSL
58+ -> Identifier Biblio
59+ -> Compiler (Page String) (Page Pandoc)
60+pageReadPandocBiblio state csl refs = proc page -> do
5261 CSL csl' <- require_ csl -< ()
53− References refs' <- require_ refs -< ()
54− body' <- unsafeCompiler (tuc processBiblio) -< (csl', refs', body)
55− returnA -< page {pageBody = body'}
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
65+ -- citations!
66+ let cits = map CSL.refId refs'
67+ state' = state {stateCitations = stateCitations state ++ cits}
68+ pandocPage <- pageReadPandocWithA -< (state', page)
69+ let pandoc = pageBody pandocPage
70+ pandoc' <- unsafeCompiler (tuc processBiblio) -< (csl', refs', pandoc)
71+ returnA -< pandocPage {pageBody = pandoc'}
5672 where
5773 tuc f (x, y, z) = f x y z