{-# LANGUAGE OverloadedStrings #-}
{- |
   Module      : Text.Pandoc.Writers.LaTeX.Citation
   Copyright   : Copyright (C) 2006-2024 John MacFarlane
   License     : GNU GPL, version 2 or above

   Maintainer  : John MacFarlane <jgm@berkeley.edu>
   Stability   : alpha
   Portability : portable
-}
module Text.Pandoc.Writers.LaTeX.Citation
  ( citationsToNatbib,
    citationsToBiblatex
  ) where

import Data.Text (Text)
import Data.Char (isPunctuation)
import Control.Monad.State (gets)
import Data.Maybe (fromMaybe)
import qualified Data.Text as T
import Text.Pandoc.Class.PandocMonad (PandocMonad)
import Text.Pandoc.Definition
import Data.List (foldl')
import Text.DocLayout (Doc, brackets, empty, (<+>), text, isEmpty, literal,
                       braces)
import Text.Pandoc.Walk
import Text.Pandoc.Writers.LaTeX.Types ( LW, WriterState(stLang) )
import Text.Pandoc.Citeproc.Locator (parseLocator, LocatorInfo(..),
                                     toLocatorMap)
import Citeproc.Types (Lang(..))
import Citeproc.Locale (getLocale)

citationsToNatbib :: PandocMonad m
                  => ([Inline] -> LW m (Doc Text))
                  -> [Citation]
                  -> LW m (Doc Text)
citationsToNatbib :: forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> [Citation] -> LW m (Doc Text)
citationsToNatbib [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Citation
one]
  = ([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX Text
c [Inline]
p [Inline]
s Text
k
  where
    Citation { citationId :: Citation -> Text
citationId = Text
k
             , citationPrefix :: Citation -> [Inline]
citationPrefix = [Inline]
p
             , citationSuffix :: Citation -> [Inline]
citationSuffix = [Inline]
s
             , citationMode :: Citation -> CitationMode
citationMode = CitationMode
m
             }
      = Citation
one
    c :: Text
c = case CitationMode
m of
             CitationMode
AuthorInText   -> Text
"citet"
             CitationMode
SuppressAuthor -> Text
"citeyearpar"
             CitationMode
NormalCitation -> Text
"citep"

citationsToNatbib [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Citation]
cits
  | [Citation] -> Bool
noPrefix ([Citation] -> [Citation]
forall a. HasCallStack => [a] -> [a]
tail [Citation]
cits) Bool -> Bool -> Bool
&& [Citation] -> Bool
noSuffix ([Citation] -> [Citation]
forall a. HasCallStack => [a] -> [a]
init [Citation]
cits) Bool -> Bool -> Bool
&& CitationMode -> [Citation] -> Bool
forall {t :: * -> *}.
Foldable t =>
CitationMode -> t Citation -> Bool
ismode CitationMode
NormalCitation [Citation]
cits
  = ([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX Text
"citep" [Inline]
p [Inline]
s Text
ks
  where
     noPrefix :: [Citation] -> Bool
noPrefix  = (Citation -> Bool) -> [Citation] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Inline] -> Bool) -> (Citation -> [Inline]) -> Citation -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> [Inline]
citationPrefix)
     noSuffix :: [Citation] -> Bool
noSuffix  = (Citation -> Bool) -> [Citation] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ([Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Inline] -> Bool) -> (Citation -> [Inline]) -> Citation -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> [Inline]
citationSuffix)
     ismode :: CitationMode -> t Citation -> Bool
ismode CitationMode
m  = (Citation -> Bool) -> t Citation -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CitationMode -> CitationMode -> Bool
forall a. Eq a => a -> a -> Bool
(==) CitationMode
m  (CitationMode -> Bool)
-> (Citation -> CitationMode) -> Citation -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Citation -> CitationMode
citationMode)
     p :: [Inline]
p         = Citation -> [Inline]
citationPrefix  (Citation -> [Inline]) -> Citation -> [Inline]
forall a b. (a -> b) -> a -> b
$
                 [Citation] -> Citation
forall a. HasCallStack => [a] -> a
head [Citation]
cits
     s :: [Inline]
s         = Citation -> [Inline]
citationSuffix  (Citation -> [Inline]) -> Citation -> [Inline]
forall a b. (a -> b) -> a -> b
$
                 [Citation] -> Citation
forall a. HasCallStack => [a] -> a
last [Citation]
cits
     ks :: Text
ks        = Text -> [Text] -> Text
T.intercalate Text
", " ([Text] -> Text) -> [Text] -> Text
forall a b. (a -> b) -> a -> b
$ (Citation -> Text) -> [Citation] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Citation -> Text
citationId [Citation]
cits

citationsToNatbib [Inline] -> LW m (Doc Text)
inlineListToLaTeX (Citation
c:[Citation]
cs)
  | Citation -> CitationMode
citationMode Citation
c CitationMode -> CitationMode -> Bool
forall a. Eq a => a -> a -> Bool
== CitationMode
AuthorInText = do
     Doc Text
author <- ([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX Text
"citeauthor" [] [] (Citation -> Text
citationId Citation
c)
     Doc Text
cits   <- ([Inline] -> LW m (Doc Text)) -> [Citation] -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> [Citation] -> LW m (Doc Text)
citationsToNatbib [Inline] -> LW m (Doc Text)
inlineListToLaTeX
                  (Citation
c { citationMode = SuppressAuthor } Citation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
: [Citation]
cs)
     Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ Doc Text
author Doc Text -> Doc Text -> Doc Text
forall a. Doc a -> Doc a -> Doc a
<+> Doc Text
cits

citationsToNatbib [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Citation]
cits = do
  [Doc Text]
cits' <- (Citation -> LW m (Doc Text))
-> [Citation] -> StateT WriterState m [Doc Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM Citation -> LW m (Doc Text)
convertOne [Citation]
cits
  Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ String -> Doc Text
forall a. HasChars a => String -> Doc a
text String
"\\citetext{" Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> (Doc Text -> Doc Text -> Doc Text)
-> Doc Text -> [Doc Text] -> Doc Text
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Doc Text -> Doc Text -> Doc Text
forall {a}. HasChars a => Doc a -> Doc a -> Doc a
combineTwo Doc Text
forall a. Doc a
empty [Doc Text]
cits' Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> String -> Doc Text
forall a. HasChars a => String -> Doc a
text String
"}"
  where
    citeCommand' :: Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand' = ([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX
    combineTwo :: Doc a -> Doc a -> Doc a
combineTwo Doc a
a Doc a
b | Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
a = Doc a
b
                   | Bool
otherwise = Doc a
a Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> String -> Doc a
forall a. HasChars a => String -> Doc a
text String
"; " Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a
b
    convertOne :: Citation -> LW m (Doc Text)
convertOne Citation { citationId :: Citation -> Text
citationId = Text
k
                        , citationPrefix :: Citation -> [Inline]
citationPrefix = [Inline]
p
                        , citationSuffix :: Citation -> [Inline]
citationSuffix = [Inline]
s
                        , citationMode :: Citation -> CitationMode
citationMode = CitationMode
m
                        }
        = case CitationMode
m of
               CitationMode
AuthorInText   -> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand' Text
"citealt"  [Inline]
p [Inline]
s Text
k
               CitationMode
SuppressAuthor -> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand' Text
"citeyear" [Inline]
p [Inline]
s Text
k
               CitationMode
NormalCitation -> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand' Text
"citealp"  [Inline]
p [Inline]
s Text
k

citeCommand :: PandocMonad m
            => ([Inline] -> LW m (Doc Text))
            -> Text
            -> [Inline]
            -> [Inline]
            -> Text
            -> LW m (Doc Text)
citeCommand :: forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX Text
c [Inline]
p [Inline]
s Text
k = do
  Doc Text
args <- ([Inline] -> LW m (Doc Text))
-> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeArguments [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Inline]
p [Inline]
s Text
k
  Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal (Text
"\\" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
c) Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> Doc Text
args

type Prefix = [Inline]
type Suffix = [Inline]
type CiteId = Text
data CiteGroup = CiteGroup Prefix Suffix [CiteId]

citeArgumentsList :: PandocMonad m
              => ([Inline] -> LW m (Doc Text))
              -> CiteGroup
              -> LW m (Doc Text)
citeArgumentsList :: forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> CiteGroup -> LW m (Doc Text)
citeArgumentsList [Inline] -> LW m (Doc Text)
_inlineListToLaTeX (CiteGroup [Inline]
_ [Inline]
_ []) = Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
forall a. Doc a
empty
citeArgumentsList [Inline] -> LW m (Doc Text)
inlineListToLaTeX (CiteGroup [Inline]
pfxs [Inline]
sfxs [Text]
ids) = do
      Maybe Lang
mblang <- (WriterState -> Maybe Lang) -> StateT WriterState m (Maybe Lang)
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets WriterState -> Maybe Lang
stLang
      let sfxs' :: [Inline]
sfxs' = Maybe Lang -> [Inline] -> [Inline]
removePageLabel Maybe Lang
mblang ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall a b. (a -> b) -> a -> b
$
              [Inline] -> [Inline]
stripLocatorBraces ([Inline] -> [Inline]) -> [Inline] -> [Inline]
forall a b. (a -> b) -> a -> b
$ case [Inline]
sfxs of
                (Str Text
t : [Inline]
r) -> case Text -> Maybe (Char, Text)
T.uncons Text
t of
                  Just (Char
x, Text
xs)
                    | Text -> Bool
T.null Text
xs
                    , Char -> Bool
isPunctuation Char
x -> (Inline -> Bool) -> [Inline] -> [Inline]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Inline -> Inline -> Bool
forall a. Eq a => a -> a -> Bool
== Inline
Space) [Inline]
r
                    | Char -> Bool
isPunctuation Char
x -> Text -> Inline
Str Text
xs Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: [Inline]
r
                  Maybe (Char, Text)
_ -> [Inline]
sfxs
                [Inline]
_   -> [Inline]
sfxs
          optargs :: Doc a -> Doc a -> Doc a
optargs Doc a
pdoc Doc a
sdoc = case (Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
pdoc, Doc a -> Bool
forall a. Doc a -> Bool
isEmpty Doc a
sdoc) of
                 (Bool
True, Bool
True ) -> Doc a
forall a. Doc a
empty
                 (Bool
True, Bool
False) -> Doc a -> Doc a
forall a. HasChars a => Doc a -> Doc a
brackets Doc a
sdoc
                 (Bool
_   , Bool
_    ) -> Doc a -> Doc a
forall a. HasChars a => Doc a -> Doc a
brackets Doc a
pdoc Doc a -> Doc a -> Doc a
forall a. Semigroup a => a -> a -> a
<> Doc a -> Doc a
forall a. HasChars a => Doc a -> Doc a
brackets Doc a
sdoc
      Doc Text
pdoc <- [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Inline]
pfxs
      Doc Text
sdoc <- [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Inline]
sfxs'
      Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ Doc Text -> Doc Text -> Doc Text
forall {a}. HasChars a => Doc a -> Doc a -> Doc a
optargs Doc Text
pdoc Doc Text
sdoc Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
              Doc Text -> Doc Text
forall a. HasChars a => Doc a -> Doc a
braces (Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal (Text -> [Text] -> Text
T.intercalate Text
"," ([Text] -> [Text]
forall a. [a] -> [a]
reverse [Text]
ids)))

citeArguments :: PandocMonad m
              => ([Inline] -> LW m (Doc Text))
              -> [Inline]
              -> [Inline]
              -> Text
              -> LW m (Doc Text)
citeArguments :: forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeArguments [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Inline]
p [Inline]
s Text
k =
  ([Inline] -> LW m (Doc Text)) -> CiteGroup -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> CiteGroup -> LW m (Doc Text)
citeArgumentsList [Inline] -> LW m (Doc Text)
inlineListToLaTeX ([Inline] -> [Inline] -> [Text] -> CiteGroup
CiteGroup [Inline]
p [Inline]
s [Text
k])

-- strip off {} used to define locator in pandoc-citeproc; see #5722
stripLocatorBraces :: [Inline] -> [Inline]
stripLocatorBraces :: [Inline] -> [Inline]
stripLocatorBraces = (Inline -> Inline) -> [Inline] -> [Inline]
forall a b. Walkable a b => (a -> a) -> b -> b
walk Inline -> Inline
go
  where go :: Inline -> Inline
go (Str Text
xs) = Text -> Inline
Str (Text -> Inline) -> Text -> Inline
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> Text -> Text
T.filter (\Char
c -> Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'{' Bool -> Bool -> Bool
&& Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'}') Text
xs
        go Inline
x        = Inline
x

citationsToBiblatex :: PandocMonad m
                    => ([Inline] -> LW m (Doc Text))
                    -> [Citation] -> LW m (Doc Text)
citationsToBiblatex :: forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> [Citation] -> LW m (Doc Text)
citationsToBiblatex [Inline] -> LW m (Doc Text)
inlineListToLaTeX [Citation
one]
  = ([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text))
-> Text -> [Inline] -> [Inline] -> Text -> LW m (Doc Text)
citeCommand [Inline] -> LW m (Doc Text)
inlineListToLaTeX Text
cmd [Inline]
p [Inline]
s Text
k
    where
       Citation { citationId :: Citation -> Text
citationId = Text
k
                , citationPrefix :: Citation -> [Inline]
citationPrefix = [Inline]
p
                , citationSuffix :: Citation -> [Inline]
citationSuffix = [Inline]
s
                , citationMode :: Citation -> CitationMode
citationMode = CitationMode
m
                } = Citation
one
       cmd :: Text
cmd = case CitationMode
m of
                  CitationMode
SuppressAuthor -> Text
"autocite*"
                  CitationMode
AuthorInText   -> Text
"textcite"
                  CitationMode
NormalCitation -> Text
"autocite"

citationsToBiblatex [Inline] -> LW m (Doc Text)
inlineListToLaTeX (Citation
c:[Citation]
cs)
  | (Citation -> Bool) -> [Citation] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\Citation
cit -> [Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Citation -> [Inline]
citationPrefix Citation
cit) Bool -> Bool -> Bool
&& [Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (Citation -> [Inline]
citationSuffix Citation
cit)) (Citation
cCitation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
:[Citation]
cs)
    = do
      let cmd :: String
cmd = case Citation -> CitationMode
citationMode Citation
c of
                    CitationMode
SuppressAuthor -> String
"\\autocite*"
                    CitationMode
AuthorInText   -> String
"\\textcite"
                    CitationMode
NormalCitation -> String
"\\autocite"
      Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ String -> Doc Text
forall a. HasChars a => String -> Doc a
text String
cmd Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<>
               Doc Text -> Doc Text
forall a. HasChars a => Doc a -> Doc a
braces (Text -> Doc Text
forall a. HasChars a => a -> Doc a
literal (Text -> [Text] -> Text
T.intercalate Text
"," ((Citation -> Text) -> [Citation] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Citation -> Text
citationId (Citation
cCitation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
:[Citation]
cs))))
  | Bool
otherwise
    = do
      let cmd :: String
cmd = case Citation -> CitationMode
citationMode Citation
c of
                    CitationMode
SuppressAuthor -> String
"\\autocites*"
                    CitationMode
AuthorInText   -> String
"\\textcites"
                    CitationMode
NormalCitation -> String
"\\autocites"

      [Doc Text]
groups <- (CiteGroup -> LW m (Doc Text))
-> [CiteGroup] -> StateT WriterState m [Doc Text]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (([Inline] -> LW m (Doc Text)) -> CiteGroup -> LW m (Doc Text)
forall (m :: * -> *).
PandocMonad m =>
([Inline] -> LW m (Doc Text)) -> CiteGroup -> LW m (Doc Text)
citeArgumentsList [Inline] -> LW m (Doc Text)
inlineListToLaTeX)
                     ([CiteGroup] -> [CiteGroup]
forall a. [a] -> [a]
reverse (([CiteGroup] -> Citation -> [CiteGroup])
-> [CiteGroup] -> [Citation] -> [CiteGroup]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [CiteGroup] -> Citation -> [CiteGroup]
grouper [] (Citation
cCitation -> [Citation] -> [Citation]
forall a. a -> [a] -> [a]
:[Citation]
cs)))

      Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Doc Text -> LW m (Doc Text)) -> Doc Text -> LW m (Doc Text)
forall a b. (a -> b) -> a -> b
$ String -> Doc Text
forall a. HasChars a => String -> Doc a
text String
cmd Doc Text -> Doc Text -> Doc Text
forall a. Semigroup a => a -> a -> a
<> [Doc Text] -> Doc Text
forall a. Monoid a => [a] -> a
mconcat [Doc Text]
groups

  where grouper :: [CiteGroup] -> Citation -> [CiteGroup]
grouper [CiteGroup]
prev Citation
cit = case [CiteGroup]
prev of
         ((CiteGroup [Inline]
oPfx [] [Text]
ids):[CiteGroup]
rest)
             | [Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
pfx Bool -> Bool -> Bool
&& [Inline] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Inline]
sfx
           -> [Inline] -> [Inline] -> [Text] -> CiteGroup
CiteGroup [Inline]
oPfx [Inline]
sfx (Text
cidText -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:[Text]
ids) CiteGroup -> [CiteGroup] -> [CiteGroup]
forall a. a -> [a] -> [a]
: [CiteGroup]
rest
         [CiteGroup]
_ -> [Inline] -> [Inline] -> [Text] -> CiteGroup
CiteGroup [Inline]
pfx [Inline]
sfx [Text
cid] CiteGroup -> [CiteGroup] -> [CiteGroup]
forall a. a -> [a] -> [a]
: [CiteGroup]
prev
         where pfx :: [Inline]
pfx = Citation -> [Inline]
citationPrefix Citation
cit
               sfx :: [Inline]
sfx = Citation -> [Inline]
citationSuffix Citation
cit
               cid :: Text
cid = Citation -> Text
citationId Citation
cit

citationsToBiblatex [Inline] -> LW m (Doc Text)
_ [Citation]
_ = Doc Text -> LW m (Doc Text)
forall a. a -> StateT WriterState m a
forall (m :: * -> *) a. Monad m => a -> m a
return Doc Text
forall a. Doc a
empty

-- | In natbib and biblatex, the label p. or pp. can be
-- omitted; ranges will be treated as page ranges by default.
-- See #9275.
removePageLabel :: Maybe Lang -> [Inline] -> [Inline]
removePageLabel :: Maybe Lang -> [Inline] -> [Inline]
removePageLabel Maybe Lang
mblang [Inline]
ils =
  case Maybe LocatorInfo
mbLocinfo of
    Just LocatorInfo
locinfo | LocatorInfo -> Text
locatorLabel LocatorInfo
locinfo Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"page"
      -> Text -> Inline
Str (LocatorInfo -> Text
locatorLoc LocatorInfo
locinfo) Inline -> [Inline] -> [Inline]
forall a. a -> [a] -> [a]
: [Inline]
ils'
    Maybe LocatorInfo
_ -> [Inline]
ils
 where
   (Maybe LocatorInfo
mbLocinfo, [Inline]
ils') = LocatorMap -> [Inline] -> (Maybe LocatorInfo, [Inline])
parseLocator (Locale -> LocatorMap
toLocatorMap Locale
locale) [Inline]
ils
   lang :: Lang
lang = Lang -> Maybe Lang -> Lang
forall a. a -> Maybe a -> a
fromMaybe (Text
-> Maybe Text
-> Maybe Text
-> [Text]
-> [(Text, [(Text, Text)])]
-> [Text]
-> Lang
Lang Text
"en" Maybe Text
forall a. Maybe a
Nothing (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"US") [] [] []) Maybe Lang
mblang
   locale :: Locale
locale = (CiteprocError -> Locale)
-> (Locale -> Locale) -> Either CiteprocError Locale -> Locale
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either CiteprocError -> Locale
forall a. Monoid a => a
mempty Locale -> Locale
forall a. a -> a
id (Either CiteprocError Locale -> Locale)
-> Either CiteprocError Locale -> Locale
forall a b. (a -> b) -> a -> b
$ Lang -> Either CiteprocError Locale
getLocale Lang
lang