Skip to content

Commit

Permalink
processPandocBiblio: Honour nocite directives
Browse files Browse the repository at this point in the history
  • Loading branch information
slotThe authored and LaurentRDC committed Jan 11, 2025
1 parent 962613a commit cd7d853
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 14 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ title: Releases
## Hakyll (unreleased)

- GHC 9.12 compatibility: bump `template-haskell` upper bound to include 2.23
- Add support for `nocite` metadata field to `processPandocBiblio` and
`processPandocBiblios` (#1058) (contribution by Tony Zorman)

## Hakyll 4.16.4.0 (2024-12-08)

- Fixed an issue where compressing CSS with `clamp` expressions would
- Fixed an issue where compressing CSS with `clamp` expressions would
result in invalid CSS (#1021) (contribution by Laurent P. René de Cotret)
- Added `boolFieldM` (#1044) (contribution by 0xd34df00d)
- Run HLint as part of GitHub Actions (#1045) (contribution by Yoo Chung)
Expand Down Expand Up @@ -118,7 +120,7 @@ title: Releases
Alexander Batischev)
- Allow `pandoc` 3.0. Note that the behavior of Hakyll's `readPandocBiblios` and
`readPandocBiblio` is different whether pandoc 2 or 3 is installed
(contribution by Laurent P. René de Cotret)
(contribution by Laurent P. René de Cotret)
- Bump `mtl` upper bound to allow 2.3 (contribution by Alexander Batischev)
- Bump `pandoc` upper bound to allow 3.1 (contribution by Laurent P. René de
Cotret)
Expand Down
9 changes: 6 additions & 3 deletions hakyll.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ Library
Other-Modules:
Hakyll.Web.Pandoc.Binary
Build-Depends:
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7,
pandoc-types >= 1.22 && < 1.24
Cpp-options:
-DUSE_PANDOC

Expand Down Expand Up @@ -317,7 +318,8 @@ Test-suite hakyll-tests
Cpp-options:
-DUSE_PANDOC
Build-Depends:
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7,
pandoc-types >= 1.22 && < 1.24


Executable hakyll-init
Expand Down Expand Up @@ -351,4 +353,5 @@ Executable hakyll-website
base >= 4.12 && < 5,
directory >= 1.0 && < 1.4,
filepath >= 1.0 && < 1.6,
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7
pandoc >= 2.11 && < 2.20 || >= 3.0 && < 3.7,
pandoc-types >= 1.22 && < 1.24
39 changes: 30 additions & 9 deletions lib/Hakyll/Web/Pandoc/Biblio.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
{-# LANGUAGE Arrows #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
module Hakyll.Web.Pandoc.Biblio
( CSL (..)
Expand Down Expand Up @@ -44,13 +45,16 @@ import Hakyll.Core.Compiler.Internal
import Hakyll.Core.Identifier
import Hakyll.Core.Identifier.Pattern (fromGlob)
import Hakyll.Core.Item
import Hakyll.Core.Metadata (getMetadataField)
import Hakyll.Core.Writable
import Hakyll.Web.Pandoc
import Text.Pandoc (Extension (..), Pandoc,
ReaderOptions (..),
PandocPure, ReaderOptions (..),
enableExtension)
import qualified Text.Pandoc as Pandoc
import Text.Pandoc.Builder (setMeta)
import qualified Text.Pandoc.Citeproc as Pandoc (processCitations)
import Text.Pandoc.Walk (Walkable (query))
import System.FilePath (addExtension, takeExtension)


Expand Down Expand Up @@ -116,7 +120,7 @@ processPandocBiblios :: Item CSL
-> [Item Biblio]
-> (Item Pandoc)
-> Compiler (Item Pandoc)
processPandocBiblios csl biblios item = do
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 @@ -126,6 +130,12 @@ processPandocBiblios csl biblios item = do
--
-- So we load the CSL and Biblio files and pass them to Pandoc using the
-- ersatz filesystem.

-- Honour nocite metadata fields
item <- getUnderlying >>= (`getMetadataField` "nocite") >>= \case
Nothing -> pure item'
Just x -> withItemBody (pure . setMeta "nocite" x) item'

let Pandoc.Pandoc (Pandoc.Meta meta) blocks = itemBody item
cslFile = Pandoc.FileInfo zeroTime . unCSL $ itemBody csl
bibFiles = zipWith (\x y ->
Expand All @@ -148,19 +158,30 @@ processPandocBiblios csl biblios item = do
Map.insert "bibliography"
(Pandoc.MetaList $ map (Pandoc.MetaString . T.pack . fst) bibFiles) $
meta
errOrPandoc = Pandoc.runPure $ do
Pandoc.modifyPureState addBiblioFiles
Pandoc.processCitations $ Pandoc.Pandoc biblioMeta blocks

pandoc <- case errOrPandoc of
Left e -> compilerThrow ["Error during processCitations: " ++ show e]
Right x -> return x

pandoc <- do
let p = Pandoc.Pandoc biblioMeta blocks
p' <- case Pandoc.lookupMeta "nocite" biblioMeta of
Just (Pandoc.MetaString nocite) -> do
Pandoc.Pandoc _ b <- runPandoc $
Pandoc.readMarkdown defaultHakyllReaderOptions nocite
let nocites = Pandoc.MetaInlines . flip query b $ \case
c@Pandoc.Cite{} -> [c]
_ -> []
return $ setMeta "nocite" nocites p
_ -> return p
runPandoc $ do
Pandoc.modifyPureState addBiblioFiles
Pandoc.processCitations p'
return $ fmap (const pandoc) item

where
zeroTime = Time.UTCTime (toEnum 0) 0

runPandoc :: PandocPure a -> Compiler a
runPandoc with = case Pandoc.runPure with of
Left e -> compilerThrow ["Error during processCitations: " ++ show e]
Right x -> pure x

--------------------------------------------------------------------------------
-- | Compiles a markdown file via Pandoc. Requires the .csl and .bib files to be known to the compiler via match statements.
Expand Down

0 comments on commit cd7d853

Please sign in to comment.