    {-# 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.Options
    import Text.Pandoc.Class.PandocMonad (PandocMonad)
    import Text.Pandoc.Definition
    import qualified Data.List as L
    import Text.DocLayout (Doc, brackets, empty, (<+>), text, isEmpty, literal,
                           braces)
    import Text.Pandoc.Walk
    import Text.Pandoc.Writers.LaTeX.Types ( LW, WriterState(stLang, stOptions) )
    import Text.Pandoc.Citeproc.Locator (parseLocator, LocatorInfo(..),
                                         toLocatorMap)
    import Citeproc.Types (Lang(..))
    import Citeproc.Locale (getLocale)
    import Safe (headMay, lastMay)

    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
    noInnerPrefix [Citation]
    cits Bool -> Bool -> Bool
    && [Citation] -> Bool
    noInnerSuffix [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
         noInnerPrefix :: [Citation] -> Bool
    noInnerPrefix []     = Bool
    True
         noInnerPrefix (Citation
    _:[Citation]
    xs) = (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) [Citation]
    xs
         noInnerSuffix :: [Citation] -> Bool
    noInnerSuffix []     = Bool
    True
         noInnerSuffix [Citation
    _]    = Bool
    True
         noInnerSuffix (Citation
    x:[Citation]
    xs) = [Inline] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null (Citation -> [Inline]
    citationSuffix Citation
    x) Bool -> Bool -> Bool
    && [Citation] -> Bool
    noInnerSuffix [Citation]
    xs
         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         = [Inline] -> (Citation -> [Inline]) -> Maybe Citation -> [Inline]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [Inline]
    forall a. Monoid a => a
    mempty Citation -> [Inline]
    citationPrefix (Maybe Citation -> [Inline]) -> Maybe Citation -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ [Citation] -> Maybe Citation
    forall a. [a] -> Maybe a
    headMay [Citation]
    cits
         s :: [Inline]
    s         = [Inline] -> (Citation -> [Inline]) -> Maybe Citation -> [Inline]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe [Inline]
    forall a. Monoid a => a
    mempty Citation -> [Inline]
    citationSuffix (Maybe Citation -> [Inline]) -> Maybe Citation -> [Inline]
    forall a b. (a -> b) -> a -> b
    $ [Citation] -> Maybe Citation
    forall a. [a] -> Maybe a
    lastMay [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
         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)
         cits   <- citationsToNatbib inlineListToLaTeX
                      (c { citationMode = SuppressAuthor } : cs)
         return $ author <+> cits

    citationsToNatbib [Inline] -> LW m (Doc Text)
    inlineListToLaTeX [Citation]
    cits = do
      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
      return $ text "\\citetext{" <> L.foldl' combineTwo empty cits' <> text "}"
      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
      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
      return $ literal ("\\" <> c) <> 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
          opts <- (WriterState -> WriterOptions)
    -> StateT WriterState m WriterOptions
    forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
    gets WriterState -> WriterOptions
    stOptions
          mblang <- gets stLang
          let sfxs' = (case WriterOptions -> CiteMethod
    writerCiteMethod WriterOptions
    opts of
                         -- In biblatex, the label p. or pp. can be omitted;
                         -- ranges are treated as page ranges by default. See #9275.
                         CiteMethod
    Biblatex -> Maybe Lang -> [Inline] -> [Inline]
    removePageLabel Maybe Lang
    mblang
                         CiteMethod
    _ -> [Inline] -> [Inline]
    forall a. a -> a
    id) ([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
    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
          pdoc <- inlineListToLaTeX pfxs
          sdoc <- inlineListToLaTeX sfxs'
          return $ optargs pdoc sdoc <>
                  braces (literal (T.intercalate "," (reverse 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"

          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
    L.foldl' [CiteGroup] -> Citation -> [CiteGroup]
    grouper [] (Citation
    cCitation -> [Citation] -> [Citation]
    forall a. a -> [a] -> [a]
    :[Citation]
    cs)))

          return $ text cmd <> mconcat 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

    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