citeproc-0.5: src/Citeproc.hs
{-# LANGUAGE OverloadedStrings #-}
-- | Process citations using the formatting instructions encoded
-- in a CSL stylesheet. The library targets version 1.0.1 of the
-- CSL spec: https://docs.citationstyles.org/en/stable/specification.html
module Citeproc
( module Citeproc.Types
, module Citeproc.Style
, module Citeproc.Locale
, citeproc
, Result(..)
) where
import Data.Bifunctor (second)
import qualified Data.Text as T
import qualified Data.Set as Set
import Citeproc.Types
import Citeproc.Style
import Citeproc.Locale
import Citeproc.Eval
-- | Process a list of 'Citation's, producing formatted citations
-- and a bibliography according to the rules of a CSL 'Style'.
-- If a 'Lang' is specified, override the style's default locale.
-- To obtain a 'Style' from an XML stylesheet, use
-- 'parseStyle' from "Citeproc.Style".
citeproc :: CiteprocOutput a
=> CiteprocOptions -- ^ Rendering options
-> Style a -- ^ Parsed CSL style
-> Maybe Lang -- ^ Overrides default locale for style
-> [Reference a] -- ^ List of references (bibliographic data)
-> [Citation a] -- ^ List of citations to process
-> Result a
citeproc opts style mblang refs citations =
Result{ resultCitations = rCitations
, resultBibliography = rBibliography
, resultWarnings = warnings ++ noPrintedFormWarnings }
where
rCitations = map ( trimR
. localizeQuotes locale
. movePunct
. renderOutput opts
) citationOs
rBibliography = map (second
( trimR
. localizeQuotes locale
. movePunct
. renderOutput opts{ linkCitations = False } ))
bibliographyOs
locale = mergeLocales mblang style
trimR = dropTextWhileEnd (== ' ')
movePunct = case localePunctuationInQuote locale of
Just True -> movePunctuationInsideQuotes
_ -> id
(citationOs, bibliographyOs, warnings) =
evalStyle style mblang refs citations
noPrintedFormWarnings = Set.toList $ mconcat $
zipWith npfCitation citations rCitations ++
map npfBibentry rBibliography
npfBibentry (ident, out) =
if out == mempty
then Set.singleton $ "Bibliography entry with no printed form: " <>
ident
else mempty
npfCitation citation res =
if res == mempty
then Set.singleton $ "Citation with no printed form: " <>
T.intercalate ","
(map (unItemId . citationItemId)
(citationItems citation))
else mempty